{"version":3,"file":"vendors.js","sources":["webpack:///./node_modules/@babel/runtime/helpers/assertThisInitialized.js","webpack:///./node_modules/@babel/runtime/helpers/defineProperty.js","webpack:///./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack:///./node_modules/@babel/runtime/helpers/esm/classCallCheck.js","webpack:///./node_modules/@babel/runtime/helpers/esm/createClass.js","webpack:///./node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack:///./node_modules/@babel/runtime/helpers/esm/extends.js","webpack:///./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","webpack:///./node_modules/@babel/runtime/helpers/esm/inherits.js","webpack:///./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack:///./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","webpack:///./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","webpack:///./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack:///./node_modules/@babel/runtime/helpers/esm/typeof.js","webpack:///./node_modules/@babel/runtime/helpers/extends.js","webpack:///./node_modules/@babel/runtime/helpers/inheritsLoose.js","webpack:///./node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js","webpack:///../../../src/v2/convertTokens/index.ts","webpack:///../../src/v2/index.ts","webpack:///../../../src/v2/legacyParse/index.ts","webpack:///../../../src/v2/legacyParseMap/index.ts","webpack:///../src/constants.ts","webpack:///../src/functions.ts","webpack:///../src/logger.ts","webpack:///../src/helpers.ts","webpack:///../src/errors.ts","webpack:///../src/factory.ts","webpack:///../index.ts","webpack:///../src/firebaseApp.ts","webpack:///../src/firebaseNamespaceCore.ts","webpack:///../src/firebaseNamespace.ts","webpack:///../src/platformLoggerService.ts","webpack:///../src/registerCoreComponents.ts","webpack:///../../node_modules/google-closure-library/closure/goog/base.js","webpack:/// [synthetic:util/polyfill] ","webpack:/// [synthetic:es6/promise/promise] ","webpack:///src/error_auth.js","webpack:///src/defines.js","webpack:///../../node_modules/google-closure-library/closure/goog/array/array.js","webpack:///../../node_modules/google-closure-library/closure/goog/dom/asserts.js","webpack:///../../node_modules/google-closure-library/closure/goog/html/trustedresourceurl.js","webpack:///../../node_modules/google-closure-library/closure/goog/html/safeurl.js","webpack:///../../node_modules/google-closure-library/closure/goog/useragent/useragent.js","webpack:///../../node_modules/google-closure-library/closure/goog/dom/dom.js","webpack:///../../node_modules/google-closure-library/closure/goog/async/nexttick.js","webpack:///../../node_modules/google-closure-library/closure/goog/promise/promise.js","webpack:///../../node_modules/google-closure-library/closure/goog/events/browserevent.js","webpack:///../../node_modules/google-closure-library/closure/goog/events/events.js","webpack:///../../node_modules/google-closure-library/closure/goog/events/eventtarget.js","webpack:///../../node_modules/google-closure-library/closure/goog/structs/structs.js","webpack:///../../node_modules/google-closure-library/closure/goog/structs/map.js","webpack:///../../node_modules/google-closure-library/closure/goog/uri/uri.js","webpack:///../../node_modules/google-closure-library/closure/goog/json/json.js","webpack:///src/utils.js","webpack:///../../node_modules/google-closure-library/closure/goog/window/window.js","webpack:///../../node_modules/google-closure-library/closure/goog/dom/safe.js","webpack:///src/object.js","webpack:///src/multifactorinfo.js","webpack:///src/actioncodeinfo.js","webpack:///src/actioncodeurl.js","webpack:///src/actioncodesettings.js","webpack:///../../node_modules/google-closure-library/closure/goog/crypt/base64.js","webpack:///src/idtoken.js","webpack:///src/idp.js","webpack:///src/additionaluserinfo.js","webpack:///src/authcredential.js","webpack:///src/authevent.js","webpack:///src/universallinksubscriber.js","webpack:///src/error_invalidorigin.js","webpack:///src/error_withcredential.js","webpack:///../../node_modules/google-closure-library/closure/goog/net/xmlhttp.js","webpack:///../../node_modules/google-closure-library/closure/goog/net/corsxmlhttpfactory.js","webpack:///../../node_modules/google-closure-library/closure/goog/debug/logger.js","webpack:///../../node_modules/google-closure-library/closure/goog/net/fetchxmlhttpfactory.js","webpack:///../../node_modules/google-closure-library/closure/goog/net/xhrio.js","webpack:///../../node_modules/google-closure-library/closure/goog/uri/utils.js","webpack:///../../node_modules/google-closure-library/third_party/closure/goog/mochikit/async/deferred.js","webpack:///../../node_modules/google-closure-library/closure/goog/net/jsloader.js","webpack:///src/rpchandler.js","webpack:///src/iframeclient/iframewrapper.js","webpack:///src/iframeclient/ifchandler.js","webpack:///src/messagechannel/receiver.js","webpack:///src/messagechannel/sender.js","webpack:///src/storage/indexeddb.js","webpack:///src/storage/hybridindexeddb.js","webpack:///src/storage/localstorage.js","webpack:///src/storage/sessionstorage.js","webpack:///src/authstorage.js","webpack:///../../node_modules/google-closure-library/closure/goog/crypt/sha2.js","webpack:///src/cordovahandler.js","webpack:///src/autheventmanager.js","webpack:///src/multifactorresolver.js","webpack:///src/multifactorassertion.js","webpack:///src/multifactoruser.js","webpack:///src/proactiverefresh.js","webpack:///src/token.js","webpack:///src/authuser.js","webpack:///src/storageusermanager.js","webpack:///src/auth.js","webpack:///src/recaptchaverifier/grecaptchamock.js","webpack:///src/recaptchaverifier/realloader.js","webpack:///src/recaptchaverifier/recaptchaverifier.js","webpack:///src/args.js","webpack:///src/exports_lib.js","webpack:///src/exports_auth.js","webpack:///../src/component.ts","webpack:///../src/provider.ts","webpack:///../src/component_container.ts","webpack:///../src/core/storage/DOMStorageWrapper.ts","webpack:///../src/core/storage/MemoryStorage.ts","webpack:///../src/core/storage/storage.ts","webpack:///../src/core/util/util.ts","webpack:///../src/core/util/Path.ts","webpack:///../src/realtime/Constants.ts","webpack:///../src/core/RepoInfo.ts","webpack:///../src/core/util/libs/parser.ts","webpack:///../src/core/util/validation.ts","webpack:///../src/api/onDisconnect.ts","webpack:///../src/api/TransactionResult.ts","webpack:///../src/core/util/NextPushId.ts","webpack:///../src/core/snap/Node.ts","webpack:///../src/core/snap/indexes/Index.ts","webpack:///../src/core/snap/indexes/KeyIndex.ts","webpack:///../src/core/snap/snap.ts","webpack:///../src/core/snap/LeafNode.ts","webpack:///../src/core/snap/indexes/PriorityIndex.ts","webpack:///../src/core/util/SortedMap.ts","webpack:///../src/core/snap/childSet.ts","webpack:///../src/core/snap/IndexMap.ts","webpack:///../src/core/snap/comparators.ts","webpack:///../src/core/snap/ChildrenNode.ts","webpack:///../src/core/snap/nodeFromJSON.ts","webpack:///../src/core/snap/indexes/ValueIndex.ts","webpack:///../src/core/snap/indexes/PathIndex.ts","webpack:///../src/api/DataSnapshot.ts","webpack:///../src/core/view/Event.ts","webpack:///../src/core/view/EventRegistration.ts","webpack:///../src/api/Query.ts","webpack:///../src/core/util/ServerValues.ts","webpack:///../src/core/SparseSnapshotTree.ts","webpack:///../src/core/operation/Operation.ts","webpack:///../src/core/operation/AckUserWrite.ts","webpack:///../src/core/util/ImmutableTree.ts","webpack:///../src/core/operation/ListenComplete.ts","webpack:///../src/core/operation/Overwrite.ts","webpack:///../src/core/operation/Merge.ts","webpack:///../src/core/view/CacheNode.ts","webpack:///../src/core/view/ViewCache.ts","webpack:///../src/core/view/Change.ts","webpack:///../src/core/view/filter/IndexedFilter.ts","webpack:///../src/core/view/ChildChangeAccumulator.ts","webpack:///../src/core/view/CompleteChildSource.ts","webpack:///../src/core/view/ViewProcessor.ts","webpack:///../src/core/view/EventGenerator.ts","webpack:///../src/core/view/View.ts","webpack:///../src/core/SyncPoint.ts","webpack:///../src/core/CompoundWrite.ts","webpack:///../src/core/WriteTree.ts","webpack:///../src/core/SyncTree.ts","webpack:///../src/core/SnapshotHolder.ts","webpack:///../src/core/stats/StatsCollection.ts","webpack:///../src/core/stats/StatsManager.ts","webpack:///../src/core/stats/StatsListener.ts","webpack:///../src/core/stats/StatsReporter.ts","webpack:///../src/core/view/EventQueue.ts","webpack:///../src/core/util/EventEmitter.ts","webpack:///../src/core/util/VisibilityMonitor.ts","webpack:///../src/core/util/OnlineMonitor.ts","webpack:///../src/realtime/polling/PacketReceiver.ts","webpack:///../src/realtime/BrowserPollConnection.ts","webpack:///../src/core/version.ts","webpack:///../src/realtime/WebSocketConnection.ts","webpack:///../src/realtime/TransportManager.ts","webpack:///../src/realtime/Connection.ts","webpack:///../src/core/ServerActions.ts","webpack:///../src/core/PersistentConnection.ts","webpack:///../src/core/ReadonlyRestClient.ts","webpack:///../src/core/Repo.ts","webpack:///../src/core/view/filter/RangedFilter.ts","webpack:///../src/core/view/filter/LimitedFilter.ts","webpack:///../src/core/view/QueryParams.ts","webpack:///../src/api/Reference.ts","webpack:///../src/core/util/Tree.ts","webpack:///../src/core/Repo_transaction.ts","webpack:///../src/core/AuthTokenProvider.ts","webpack:///../src/core/RepoManager.ts","webpack:///../src/api/Database.ts","webpack:///../src/api/internal.ts","webpack:///../src/api/test_access.ts","webpack:///../src/util/log.ts","webpack:///../src/platform/browser/format_json.ts","webpack:///../src/util/assert.ts","webpack:///../src/platform/browser/random_bytes.ts","webpack:///../src/util/misc.ts","webpack:///../src/core/database_info.ts","webpack:///../src/util/obj.ts","webpack:///../src/util/obj_map.ts","webpack:///../src/util/error.ts","webpack:///../src/api/timestamp.ts","webpack:///../src/core/snapshot_version.ts","webpack:///../src/model/path.ts","webpack:///../src/model/document_key.ts","webpack:///../src/util/types.ts","webpack:///../src/core/target.ts","webpack:///../src/core/query.ts","webpack:///../src/util/byte_string.ts","webpack:///../src/platform/browser/base64.ts","webpack:///../src/remote/rpc_error.ts","webpack:///../src/local/target_data.ts","webpack:///../src/remote/existence_filter.ts","webpack:///../src/util/sorted_map.ts","webpack:///../src/util/sorted_set.ts","webpack:///../src/model/collections.ts","webpack:///../src/model/document_set.ts","webpack:///../src/core/view_snapshot.ts","webpack:///../src/remote/remote_event.ts","webpack:///../src/remote/watch_change.ts","webpack:///../src/model/server_timestamps.ts","webpack:///../src/model/values.ts","webpack:///../src/remote/serializer.ts","webpack:///../src/model/transform_operation.ts","webpack:///../src/model/mutation.ts","webpack:///../src/model/object_value.ts","webpack:///../src/model/document.ts","webpack:///../lite/src/api/util.ts","webpack:///../src/model/mutation_batch.ts","webpack:///../src/local/persistence_promise.ts","webpack:///../src/local/remote_document_change_buffer.ts","webpack:///../src/local/persistence.ts","webpack:///../src/local/local_documents_view.ts","webpack:///../src/local/local_view_changes.ts","webpack:///../src/core/listen_sequence.ts","webpack:///../src/util/promise.ts","webpack:///../src/remote/backoff.ts","webpack:///../src/local/simple_db.ts","webpack:///../src/platform/browser/dom.ts","webpack:///../src/util/async_queue.ts","webpack:///../src/local/lru_garbage_collector.ts","webpack:///../src/local/encoded_resource_path.ts","webpack:///../src/local/local_serializer.ts","webpack:///../src/local/indexeddb_mutation_queue.ts","webpack:///../src/local/indexeddb_remote_document_cache.ts","webpack:///../src/local/memory_index_manager.ts","webpack:///../src/local/indexeddb_schema.ts","webpack:///../src/local/indexeddb_index_manager.ts","webpack:///../src/core/target_id_generator.ts","webpack:///../src/local/indexeddb_target_cache.ts","webpack:///../src/local/indexeddb_persistence.ts","webpack:///../src/local/local_store.ts","webpack:///../src/local/reference_set.ts","webpack:///../src/auth/user.ts","webpack:///../src/api/credentials.ts","webpack:///../src/remote/persistent_stream.ts","webpack:///../src/remote/datastore.ts","webpack:///../src/remote/online_state_tracker.ts","webpack:///../src/remote/remote_store.ts","webpack:///../src/local/shared_client_state_schema.ts","webpack:///../src/local/shared_client_state.ts","webpack:///../src/core/view.ts","webpack:///../src/core/sync_engine.ts","webpack:///../src/core/event_manager.ts","webpack:///../src/local/index_free_query_engine.ts","webpack:///../src/local/memory_mutation_queue.ts","webpack:///../src/local/memory_remote_document_cache.ts","webpack:///../src/local/memory_target_cache.ts","webpack:///../src/local/memory_persistence.ts","webpack:///../src/remote/stream_bridge.ts","webpack:///../src/remote/rest_connection.ts","webpack:///../src/platform/browser/webchannel_connection.ts","webpack:///../src/platform/browser/connectivity_monitor.ts","webpack:///../src/remote/connectivity_monitor_noop.ts","webpack:///../src/platform/browser/serializer.ts","webpack:///../src/core/component_provider.ts","webpack:///../src/platform/browser/connection.ts","webpack:///../src/api/observer.ts","webpack:///../src/util/async_observer.ts","webpack:///../src/util/input_validation.ts","webpack:///../src/api/blob.ts","webpack:///../src/api/field_path.ts","webpack:///../src/api/field_value.ts","webpack:///../src/api/geo_point.ts","webpack:///../src/api/user_data_reader.ts","webpack:///../src/core/transaction.ts","webpack:///../src/core/transaction_runner.ts","webpack:///../src/core/firestore_client.ts","webpack:///../src/api/user_data_writer.ts","webpack:///../src/api/database.ts","webpack:///../src/config.ts","webpack:///../src/api/error.ts","webpack:///../src/context.ts","webpack:///../src/serializer.ts","webpack:///../src/api/service.ts","webpack:///../src/util/constants.ts","webpack:///../src/util/errors.ts","webpack:///../src/api/common.ts","webpack:///../src/api/create-installation-request.ts","webpack:///../src/util/sleep.ts","webpack:///../src/helpers/buffer-to-base64-url-safe.ts","webpack:///../src/helpers/generate-fid.ts","webpack:///../src/util/get-key.ts","webpack:///../src/helpers/fid-changed.ts","webpack:///../src/helpers/idb-manager.ts","webpack:///../src/helpers/get-installation-entry.ts","webpack:///../src/api/generate-auth-token-request.ts","webpack:///../src/helpers/refresh-auth-token.ts","webpack:///../src/functions/get-id.ts","webpack:///../src/functions/get-token.ts","webpack:///../src/api/delete-installation-request.ts","webpack:///../src/functions/delete-installation.ts","webpack:///../src/functions/on-id-change.ts","webpack:///../src/helpers/extract-app-config.ts","webpack:///../src/index.ts","webpack:///../src/interfaces/internal-message-payload.ts","webpack:///../src/helpers/array-base64-translator.ts","webpack:///../src/helpers/migrate-old-database.ts","webpack:///../src/core/api.ts","webpack:///../src/core/token-management.ts","webpack:///../src/helpers/externalizePayload.ts","webpack:///../src/helpers/is-console-message.ts","webpack:///../src/helpers/sleep.ts","webpack:///../src/controllers/sw-controller.ts","webpack:///../src/controllers/window-controller.ts","webpack:///../src/utils/errors.ts","webpack:///../src/services/api_service.ts","webpack:///../src/utils/string_merger.ts","webpack:///../src/services/settings_service.ts","webpack:///../src/services/iid_service.ts","webpack:///../src/utils/attributes_utils.ts","webpack:///../src/utils/console_logger.ts","webpack:///../src/services/remote_config_service.ts","webpack:///../src/services/initialization_service.ts","webpack:///../src/services/transport_service.ts","webpack:///../src/services/perf_logger.ts","webpack:///../src/utils/metric_utils.ts","webpack:///../src/resources/trace.ts","webpack:///../src/resources/network_request.ts","webpack:///../src/services/oob_resources_service.ts","webpack:///../src/controllers/perf.ts","webpack:///../src/client/caching_client.ts","webpack:///../src/language.ts","webpack:///../src/client/rest_client.ts","webpack:///../src/client/remote_config_fetch_client.ts","webpack:///../src/value.ts","webpack:///../src/remote_config.ts","webpack:///../src/storage/storage.ts","webpack:///../src/storage/storage_cache.ts","webpack:///../src/client/exponential_backoff.ts","webpack:///../src/client/retrying_client.ts","webpack:///../src/implementation/constants.ts","webpack:///../src/implementation/error.ts","webpack:///../src/implementation/string.ts","webpack:///../src/implementation/taskenums.ts","webpack:///../src/implementation/type.ts","webpack:///../src/implementation/xhrio.ts","webpack:///../src/implementation/xhrio_network.ts","webpack:///../src/implementation/xhriopool.ts","webpack:///../src/implementation/fs.ts","webpack:///../src/implementation/blob.ts","webpack:///../src/implementation/location.ts","webpack:///../src/implementation/json.ts","webpack:///../src/implementation/path.ts","webpack:///../src/implementation/url.ts","webpack:///../src/implementation/metadata.ts","webpack:///../src/implementation/list.ts","webpack:///../src/implementation/requestinfo.ts","webpack:///../src/implementation/requests.ts","webpack:///../src/implementation/observer.ts","webpack:///../src/tasksnapshot.ts","webpack:///../src/implementation/args.ts","webpack:///../src/implementation/async.ts","webpack:///../src/task.ts","webpack:///../src/reference.ts","webpack:///../src/implementation/failrequest.ts","webpack:///../src/implementation/backoff.ts","webpack:///../src/implementation/request.ts","webpack:///../src/service.ts","webpack:///../src/assert.ts","webpack:///../src/crypt.ts","webpack:///../src/deepCopy.ts","webpack:///../src/deferred.ts","webpack:///../src/environment.ts","webpack:///../src/json.ts","webpack:///../src/jwt.ts","webpack:///../src/obj.ts","webpack:///../src/query.ts","webpack:///../src/sha1.ts","webpack:///../src/subscribe.ts","webpack:///../src/validation.ts","webpack:///../src/utf8.ts","webpack:///temp/node_modules/google-closure-library/closure/goog/base.js","webpack:///temp/node_modules/google-closure-library/closure/goog/disposable/disposable.js","webpack:///temp/node_modules/google-closure-library/closure/goog/array/array.js","webpack:///temp/node_modules/google-closure-library/closure/goog/string/internal.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/useragent/util.js","webpack:///temp/node_modules/google-closure-library/closure/goog/object/object.js","webpack:///temp/node_modules/google-closure-library/closure/goog/reflect/reflect.js","webpack:///temp/node_modules/google-closure-library/closure/goog/useragent/useragent.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/browserfeature.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/event.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/browserevent.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/eventtype.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/listenable.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/listener.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/listenermap.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/events.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/eventtarget.js","webpack:///temp/node_modules/google-closure-library/closure/goog/json/json.js","webpack:///temp/node_modules/google-closure-library/closure/goog/async/workqueue.js","webpack:///temp/node_modules/google-closure-library/closure/goog/async/freelist.js","webpack:///temp/node_modules/google-closure-library/closure/goog/async/nexttick.js","webpack:///temp/node_modules/google-closure-library/closure/goog/async/run.js","webpack:///temp/node_modules/google-closure-library/closure/goog/timer/timer.js","webpack:///temp/node_modules/google-closure-library/closure/goog/async/throttle.js","webpack:///temp/node_modules/google-closure-library/closure/goog/events/eventhandler.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchanneldebug.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/requeststats.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/errorcode.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/eventtype.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/xmlhttpfactory.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/xmlhttp.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/channelrequest.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/xhrio.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchannelbase.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/forwardchannelrequestpool.js","webpack:///temp/node_modules/google-closure-library/closure/goog/structs/structs.js","webpack:///temp/node_modules/google-closure-library/closure/goog/structs/map.js","webpack:///temp/node_modules/google-closure-library/closure/goog/uri/utils.js","webpack:///temp/node_modules/google-closure-library/closure/goog/uri/uri.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/wire.js","webpack:///temp/node_modules/google-closure-library/closure/goog/json/nativejsonprocessor.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/wirev8.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/netutils.js","webpack:///temp/node_modules/google-closure-library/closure/goog/json/hybrid.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/httpstatus.js","webpack:///temp/node_modules/google-closure-library/closure/goog/net/rpc/httpcors.js","webpack:///temp/node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchannelbasetransport.js","webpack:///temp/src/index.js","webpack:///./node_modules/@semantic-ui-react/event-stack/lib/cjs/event-stack.development.js","webpack:///./node_modules/@semantic-ui-react/event-stack/lib/index.js","webpack:///./node_modules/@stardust-ui/react-component-event-listener/dist/es/EventListener.js","webpack:///./node_modules/@stardust-ui/react-component-event-listener/dist/es/index.js","webpack:///./node_modules/@stardust-ui/react-component-event-listener/dist/es/useEventListener.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/Ref.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/RefFindNode.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/RefForward.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/handleRef.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/index.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/isRefObject.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/toRefObject.js","webpack:///./node_modules/@stardust-ui/react-component-ref/dist/es/types.js","webpack:///./node_modules/classnames/index.js","webpack:///./node_modules/clsx/dist/clsx.m.js","webpack:///./node_modules/create-react-context/lib/implementation.js","webpack:///./node_modules/create-react-context/lib/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css","webpack:///./node_modules/semantic-ui-css/semantic.min.css","webpack:///./node_modules/css-loader/dist/runtime/api.js","webpack:///./node_modules/css-loader/dist/runtime/getUrl.js","webpack:///./node_modules/date-fns/esm/_lib/addLeadingZeros/index.js","webpack:///./node_modules/date-fns/esm/_lib/assign/index.js","webpack:///./node_modules/date-fns/esm/_lib/cloneObject/index.js","webpack:///./node_modules/date-fns/esm/_lib/format/formatters/index.js","webpack:///./node_modules/date-fns/esm/_lib/format/lightFormatters/index.js","webpack:///./node_modules/date-fns/esm/_lib/format/longFormatters/index.js","webpack:///./node_modules/date-fns/esm/_lib/getTimezoneOffsetInMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/_lib/getUTCDayOfYear/index.js","webpack:///./node_modules/date-fns/esm/_lib/getUTCISOWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/getUTCISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/_lib/getUTCWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/getUTCWeekYear/index.js","webpack:///./node_modules/date-fns/esm/_lib/protectedTokens/index.js","webpack:///./node_modules/date-fns/esm/_lib/requiredArgs/index.js","webpack:///./node_modules/date-fns/esm/_lib/setUTCDay/index.js","webpack:///./node_modules/date-fns/esm/_lib/setUTCISODay/index.js","webpack:///./node_modules/date-fns/esm/_lib/setUTCISOWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/setUTCWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/startOfUTCISOWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/startOfUTCISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/_lib/startOfUTCWeek/index.js","webpack:///./node_modules/date-fns/esm/_lib/startOfUTCWeekYear/index.js","webpack:///./node_modules/date-fns/esm/_lib/toInteger/index.js","webpack:///./node_modules/date-fns/esm/add/index.js","webpack:///./node_modules/date-fns/esm/addBusinessDays/index.js","webpack:///./node_modules/date-fns/esm/addDays/index.js","webpack:///./node_modules/date-fns/esm/addHours/index.js","webpack:///./node_modules/date-fns/esm/addISOWeekYears/index.js","webpack:///./node_modules/date-fns/esm/addMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/addMinutes/index.js","webpack:///./node_modules/date-fns/esm/addMonths/index.js","webpack:///./node_modules/date-fns/esm/addQuarters/index.js","webpack:///./node_modules/date-fns/esm/addSeconds/index.js","webpack:///./node_modules/date-fns/esm/addWeeks/index.js","webpack:///./node_modules/date-fns/esm/addYears/index.js","webpack:///./node_modules/date-fns/esm/areIntervalsOverlapping/index.js","webpack:///./node_modules/date-fns/esm/closestIndexTo/index.js","webpack:///./node_modules/date-fns/esm/closestTo/index.js","webpack:///./node_modules/date-fns/esm/compareAsc/index.js","webpack:///./node_modules/date-fns/esm/compareDesc/index.js","webpack:///./node_modules/date-fns/esm/constants/index.js","webpack:///./node_modules/date-fns/esm/differenceInBusinessDays/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarDays/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarISOWeekYears/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarISOWeeks/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarMonths/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarQuarters/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarWeeks/index.js","webpack:///./node_modules/date-fns/esm/differenceInCalendarYears/index.js","webpack:///./node_modules/date-fns/esm/differenceInDays/index.js","webpack:///./node_modules/date-fns/esm/differenceInHours/index.js","webpack:///./node_modules/date-fns/esm/differenceInISOWeekYears/index.js","webpack:///./node_modules/date-fns/esm/differenceInMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/differenceInMinutes/index.js","webpack:///./node_modules/date-fns/esm/differenceInMonths/index.js","webpack:///./node_modules/date-fns/esm/differenceInQuarters/index.js","webpack:///./node_modules/date-fns/esm/differenceInSeconds/index.js","webpack:///./node_modules/date-fns/esm/differenceInWeeks/index.js","webpack:///./node_modules/date-fns/esm/differenceInYears/index.js","webpack:///./node_modules/date-fns/esm/eachDayOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachHourOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachMonthOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachQuarterOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachWeekOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachWeekendOfInterval/index.js","webpack:///./node_modules/date-fns/esm/eachWeekendOfMonth/index.js","webpack:///./node_modules/date-fns/esm/eachWeekendOfYear/index.js","webpack:///./node_modules/date-fns/esm/eachYearOfInterval/index.js","webpack:///./node_modules/date-fns/esm/endOfDay/index.js","webpack:///./node_modules/date-fns/esm/endOfDecade/index.js","webpack:///./node_modules/date-fns/esm/endOfHour/index.js","webpack:///./node_modules/date-fns/esm/endOfISOWeek/index.js","webpack:///./node_modules/date-fns/esm/endOfISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/endOfMinute/index.js","webpack:///./node_modules/date-fns/esm/endOfMonth/index.js","webpack:///./node_modules/date-fns/esm/endOfQuarter/index.js","webpack:///./node_modules/date-fns/esm/endOfSecond/index.js","webpack:///./node_modules/date-fns/esm/endOfToday/index.js","webpack:///./node_modules/date-fns/esm/endOfTomorrow/index.js","webpack:///./node_modules/date-fns/esm/endOfWeek/index.js","webpack:///./node_modules/date-fns/esm/endOfYear/index.js","webpack:///./node_modules/date-fns/esm/endOfYesterday/index.js","webpack:///./node_modules/date-fns/esm/format/index.js","webpack:///./node_modules/date-fns/esm/formatDistance/index.js","webpack:///./node_modules/date-fns/esm/formatDistanceStrict/index.js","webpack:///./node_modules/date-fns/esm/formatDistanceToNow/index.js","webpack:///./node_modules/date-fns/esm/formatDistanceToNowStrict/index.js","webpack:///./node_modules/date-fns/esm/formatDuration/index.js","webpack:///./node_modules/date-fns/esm/formatISO/index.js","webpack:///./node_modules/date-fns/esm/formatISO9075/index.js","webpack:///./node_modules/date-fns/esm/formatISODuration/index.js","webpack:///./node_modules/date-fns/esm/formatRFC3339/index.js","webpack:///./node_modules/date-fns/esm/formatRFC7231/index.js","webpack:///./node_modules/date-fns/esm/formatRelative/index.js","webpack:///./node_modules/date-fns/esm/fromUnixTime/index.js","webpack:///./node_modules/date-fns/esm/getDate/index.js","webpack:///./node_modules/date-fns/esm/getDay/index.js","webpack:///./node_modules/date-fns/esm/getDayOfYear/index.js","webpack:///./node_modules/date-fns/esm/getDaysInMonth/index.js","webpack:///./node_modules/date-fns/esm/getDaysInYear/index.js","webpack:///./node_modules/date-fns/esm/getDecade/index.js","webpack:///./node_modules/date-fns/esm/getHours/index.js","webpack:///./node_modules/date-fns/esm/getISODay/index.js","webpack:///./node_modules/date-fns/esm/getISOWeek/index.js","webpack:///./node_modules/date-fns/esm/getISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/getISOWeeksInYear/index.js","webpack:///./node_modules/date-fns/esm/getMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/getMinutes/index.js","webpack:///./node_modules/date-fns/esm/getMonth/index.js","webpack:///./node_modules/date-fns/esm/getOverlappingDaysInIntervals/index.js","webpack:///./node_modules/date-fns/esm/getQuarter/index.js","webpack:///./node_modules/date-fns/esm/getSeconds/index.js","webpack:///./node_modules/date-fns/esm/getTime/index.js","webpack:///./node_modules/date-fns/esm/getUnixTime/index.js","webpack:///./node_modules/date-fns/esm/getWeek/index.js","webpack:///./node_modules/date-fns/esm/getWeekOfMonth/index.js","webpack:///./node_modules/date-fns/esm/getWeekYear/index.js","webpack:///./node_modules/date-fns/esm/getWeeksInMonth/index.js","webpack:///./node_modules/date-fns/esm/getYear/index.js","webpack:///./node_modules/date-fns/esm/index.js","webpack:///./node_modules/date-fns/esm/intervalToDuration/index.js","webpack:///./node_modules/date-fns/esm/isAfter/index.js","webpack:///./node_modules/date-fns/esm/isBefore/index.js","webpack:///./node_modules/date-fns/esm/isDate/index.js","webpack:///./node_modules/date-fns/esm/isEqual/index.js","webpack:///./node_modules/date-fns/esm/isExists/index.js","webpack:///./node_modules/date-fns/esm/isFirstDayOfMonth/index.js","webpack:///./node_modules/date-fns/esm/isFriday/index.js","webpack:///./node_modules/date-fns/esm/isFuture/index.js","webpack:///./node_modules/date-fns/esm/isLastDayOfMonth/index.js","webpack:///./node_modules/date-fns/esm/isLeapYear/index.js","webpack:///./node_modules/date-fns/esm/isMatch/index.js","webpack:///./node_modules/date-fns/esm/isMonday/index.js","webpack:///./node_modules/date-fns/esm/isPast/index.js","webpack:///./node_modules/date-fns/esm/isSameDay/index.js","webpack:///./node_modules/date-fns/esm/isSameHour/index.js","webpack:///./node_modules/date-fns/esm/isSameISOWeek/index.js","webpack:///./node_modules/date-fns/esm/isSameISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/isSameMinute/index.js","webpack:///./node_modules/date-fns/esm/isSameMonth/index.js","webpack:///./node_modules/date-fns/esm/isSameQuarter/index.js","webpack:///./node_modules/date-fns/esm/isSameSecond/index.js","webpack:///./node_modules/date-fns/esm/isSameWeek/index.js","webpack:///./node_modules/date-fns/esm/isSameYear/index.js","webpack:///./node_modules/date-fns/esm/isSaturday/index.js","webpack:///./node_modules/date-fns/esm/isSunday/index.js","webpack:///./node_modules/date-fns/esm/isThisHour/index.js","webpack:///./node_modules/date-fns/esm/isThisISOWeek/index.js","webpack:///./node_modules/date-fns/esm/isThisMinute/index.js","webpack:///./node_modules/date-fns/esm/isThisMonth/index.js","webpack:///./node_modules/date-fns/esm/isThisQuarter/index.js","webpack:///./node_modules/date-fns/esm/isThisSecond/index.js","webpack:///./node_modules/date-fns/esm/isThisWeek/index.js","webpack:///./node_modules/date-fns/esm/isThisYear/index.js","webpack:///./node_modules/date-fns/esm/isThursday/index.js","webpack:///./node_modules/date-fns/esm/isToday/index.js","webpack:///./node_modules/date-fns/esm/isTomorrow/index.js","webpack:///./node_modules/date-fns/esm/isTuesday/index.js","webpack:///./node_modules/date-fns/esm/isValid/index.js","webpack:///./node_modules/date-fns/esm/isWednesday/index.js","webpack:///./node_modules/date-fns/esm/isWeekend/index.js","webpack:///./node_modules/date-fns/esm/isWithinInterval/index.js","webpack:///./node_modules/date-fns/esm/isYesterday/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfDecade/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfISOWeek/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfMonth/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfQuarter/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfWeek/index.js","webpack:///./node_modules/date-fns/esm/lastDayOfYear/index.js","webpack:///./node_modules/date-fns/esm/lightFormat/index.js","webpack:///./node_modules/date-fns/esm/locale/_lib/buildFormatLongFn/index.js","webpack:///./node_modules/date-fns/esm/locale/_lib/buildLocalizeFn/index.js","webpack:///./node_modules/date-fns/esm/locale/_lib/buildMatchFn/index.js","webpack:///./node_modules/date-fns/esm/locale/_lib/buildMatchPatternFn/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/_lib/formatDistance/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/_lib/formatLong/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/_lib/formatRelative/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/_lib/localize/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/_lib/match/index.js","webpack:///./node_modules/date-fns/esm/locale/en-US/index.js","webpack:///./node_modules/date-fns/esm/max/index.js","webpack:///./node_modules/date-fns/esm/min/index.js","webpack:///./node_modules/date-fns/esm/parse/_lib/parsers/index.js","webpack:///./node_modules/date-fns/esm/parse/index.js","webpack:///./node_modules/date-fns/esm/parseISO/index.js","webpack:///./node_modules/date-fns/esm/parseJSON/index.js","webpack:///./node_modules/date-fns/esm/roundToNearestMinutes/index.js","webpack:///./node_modules/date-fns/esm/set/index.js","webpack:///./node_modules/date-fns/esm/setDate/index.js","webpack:///./node_modules/date-fns/esm/setDay/index.js","webpack:///./node_modules/date-fns/esm/setDayOfYear/index.js","webpack:///./node_modules/date-fns/esm/setHours/index.js","webpack:///./node_modules/date-fns/esm/setISODay/index.js","webpack:///./node_modules/date-fns/esm/setISOWeek/index.js","webpack:///./node_modules/date-fns/esm/setISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/setMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/setMinutes/index.js","webpack:///./node_modules/date-fns/esm/setMonth/index.js","webpack:///./node_modules/date-fns/esm/setQuarter/index.js","webpack:///./node_modules/date-fns/esm/setSeconds/index.js","webpack:///./node_modules/date-fns/esm/setWeek/index.js","webpack:///./node_modules/date-fns/esm/setWeekYear/index.js","webpack:///./node_modules/date-fns/esm/setYear/index.js","webpack:///./node_modules/date-fns/esm/startOfDay/index.js","webpack:///./node_modules/date-fns/esm/startOfDecade/index.js","webpack:///./node_modules/date-fns/esm/startOfHour/index.js","webpack:///./node_modules/date-fns/esm/startOfISOWeek/index.js","webpack:///./node_modules/date-fns/esm/startOfISOWeekYear/index.js","webpack:///./node_modules/date-fns/esm/startOfMinute/index.js","webpack:///./node_modules/date-fns/esm/startOfMonth/index.js","webpack:///./node_modules/date-fns/esm/startOfQuarter/index.js","webpack:///./node_modules/date-fns/esm/startOfSecond/index.js","webpack:///./node_modules/date-fns/esm/startOfToday/index.js","webpack:///./node_modules/date-fns/esm/startOfTomorrow/index.js","webpack:///./node_modules/date-fns/esm/startOfWeek/index.js","webpack:///./node_modules/date-fns/esm/startOfWeekYear/index.js","webpack:///./node_modules/date-fns/esm/startOfYear/index.js","webpack:///./node_modules/date-fns/esm/startOfYesterday/index.js","webpack:///./node_modules/date-fns/esm/sub/index.js","webpack:///./node_modules/date-fns/esm/subBusinessDays/index.js","webpack:///./node_modules/date-fns/esm/subDays/index.js","webpack:///./node_modules/date-fns/esm/subHours/index.js","webpack:///./node_modules/date-fns/esm/subISOWeekYears/index.js","webpack:///./node_modules/date-fns/esm/subMilliseconds/index.js","webpack:///./node_modules/date-fns/esm/subMinutes/index.js","webpack:///./node_modules/date-fns/esm/subMonths/index.js","webpack:///./node_modules/date-fns/esm/subQuarters/index.js","webpack:///./node_modules/date-fns/esm/subSeconds/index.js","webpack:///./node_modules/date-fns/esm/subWeeks/index.js","webpack:///./node_modules/date-fns/esm/subYears/index.js","webpack:///./node_modules/date-fns/esm/toDate/index.js","webpack:///./node_modules/dayzed/dist/dayzed.esm.js","webpack:///./node_modules/deep-equal/index.js","webpack:///./node_modules/define-properties/index.js","webpack:///./node_modules/es-abstract/GetIntrinsic.js","webpack:///./node_modules/es-abstract/helpers/callBind.js","webpack:///./node_modules/exenv/index.js","webpack:///../app/index.ts","webpack:///./node_modules/function-bind/implementation.js","webpack:///./node_modules/function-bind/index.js","webpack:///./node_modules/gud/index.js","webpack:///./node_modules/has-symbols/index.js","webpack:///./node_modules/has-symbols/shams.js","webpack:///./node_modules/history/esm/history.js","webpack:///./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","webpack:///./node_modules/idb/build/idb.js","webpack:///./node_modules/is-arguments/index.js","webpack:///./node_modules/is-date-object/index.js","webpack:///./node_modules/is-regex/index.js","webpack:///./node_modules/keyboard-key/src/keyboardKey.js","webpack:///./node_modules/lodash/_DataView.js","webpack:///./node_modules/lodash/_Hash.js","webpack:///./node_modules/lodash/_LazyWrapper.js","webpack:///./node_modules/lodash/_ListCache.js","webpack:///./node_modules/lodash/_LodashWrapper.js","webpack:///./node_modules/lodash/_Map.js","webpack:///./node_modules/lodash/_MapCache.js","webpack:///./node_modules/lodash/_Promise.js","webpack:///./node_modules/lodash/_Set.js","webpack:///./node_modules/lodash/_SetCache.js","webpack:///./node_modules/lodash/_Stack.js","webpack:///./node_modules/lodash/_Symbol.js","webpack:///./node_modules/lodash/_Uint8Array.js","webpack:///./node_modules/lodash/_WeakMap.js","webpack:///./node_modules/lodash/_apply.js","webpack:///./node_modules/lodash/_arrayAggregator.js","webpack:///./node_modules/lodash/_arrayEach.js","webpack:///./node_modules/lodash/_arrayEvery.js","webpack:///./node_modules/lodash/_arrayFilter.js","webpack:///./node_modules/lodash/_arrayIncludes.js","webpack:///./node_modules/lodash/_arrayIncludesWith.js","webpack:///./node_modules/lodash/_arrayLikeKeys.js","webpack:///./node_modules/lodash/_arrayMap.js","webpack:///./node_modules/lodash/_arrayPush.js","webpack:///./node_modules/lodash/_arrayReduce.js","webpack:///./node_modules/lodash/_arraySome.js","webpack:///./node_modules/lodash/_asciiSize.js","webpack:///./node_modules/lodash/_asciiToArray.js","webpack:///./node_modules/lodash/_asciiWords.js","webpack:///./node_modules/lodash/_assignMergeValue.js","webpack:///./node_modules/lodash/_assignValue.js","webpack:///./node_modules/lodash/_assocIndexOf.js","webpack:///./node_modules/lodash/_baseAggregator.js","webpack:///./node_modules/lodash/_baseAssign.js","webpack:///./node_modules/lodash/_baseAssignIn.js","webpack:///./node_modules/lodash/_baseAssignValue.js","webpack:///./node_modules/lodash/_baseClamp.js","webpack:///./node_modules/lodash/_baseClone.js","webpack:///./node_modules/lodash/_baseCreate.js","webpack:///./node_modules/lodash/_baseDifference.js","webpack:///./node_modules/lodash/_baseEach.js","webpack:///./node_modules/lodash/_baseEvery.js","webpack:///./node_modules/lodash/_baseExtremum.js","webpack:///./node_modules/lodash/_baseFilter.js","webpack:///./node_modules/lodash/_baseFindIndex.js","webpack:///./node_modules/lodash/_baseFlatten.js","webpack:///./node_modules/lodash/_baseFor.js","webpack:///./node_modules/lodash/_baseForOwn.js","webpack:///./node_modules/lodash/_baseGet.js","webpack:///./node_modules/lodash/_baseGetAllKeys.js","webpack:///./node_modules/lodash/_baseGetTag.js","webpack:///./node_modules/lodash/_baseHas.js","webpack:///./node_modules/lodash/_baseHasIn.js","webpack:///./node_modules/lodash/_baseInRange.js","webpack:///./node_modules/lodash/_baseIndexOf.js","webpack:///./node_modules/lodash/_baseIntersection.js","webpack:///./node_modules/lodash/_baseInverter.js","webpack:///./node_modules/lodash/_baseInvoke.js","webpack:///./node_modules/lodash/_baseIsArguments.js","webpack:///./node_modules/lodash/_baseIsEqual.js","webpack:///./node_modules/lodash/_baseIsEqualDeep.js","webpack:///./node_modules/lodash/_baseIsMap.js","webpack:///./node_modules/lodash/_baseIsMatch.js","webpack:///./node_modules/lodash/_baseIsNaN.js","webpack:///./node_modules/lodash/_baseIsNative.js","webpack:///./node_modules/lodash/_baseIsSet.js","webpack:///./node_modules/lodash/_baseIsTypedArray.js","webpack:///./node_modules/lodash/_baseIteratee.js","webpack:///./node_modules/lodash/_baseKeys.js","webpack:///./node_modules/lodash/_baseKeysIn.js","webpack:///./node_modules/lodash/_baseLodash.js","webpack:///./node_modules/lodash/_baseLt.js","webpack:///./node_modules/lodash/_baseMap.js","webpack:///./node_modules/lodash/_baseMatches.js","webpack:///./node_modules/lodash/_baseMatchesProperty.js","webpack:///./node_modules/lodash/_baseMerge.js","webpack:///./node_modules/lodash/_baseMergeDeep.js","webpack:///./node_modules/lodash/_baseOrderBy.js","webpack:///./node_modules/lodash/_basePick.js","webpack:///./node_modules/lodash/_basePickBy.js","webpack:///./node_modules/lodash/_baseProperty.js","webpack:///./node_modules/lodash/_basePropertyDeep.js","webpack:///./node_modules/lodash/_basePropertyOf.js","webpack:///./node_modules/lodash/_baseRange.js","webpack:///./node_modules/lodash/_baseReduce.js","webpack:///./node_modules/lodash/_baseRest.js","webpack:///./node_modules/lodash/_baseSet.js","webpack:///./node_modules/lodash/_baseSetData.js","webpack:///./node_modules/lodash/_baseSetToString.js","webpack:///./node_modules/lodash/_baseSlice.js","webpack:///./node_modules/lodash/_baseSome.js","webpack:///./node_modules/lodash/_baseSortBy.js","webpack:///./node_modules/lodash/_baseSum.js","webpack:///./node_modules/lodash/_baseTimes.js","webpack:///./node_modules/lodash/_baseToString.js","webpack:///./node_modules/lodash/_baseUnary.js","webpack:///./node_modules/lodash/_baseUniq.js","webpack:///./node_modules/lodash/_baseValues.js","webpack:///./node_modules/lodash/_cacheHas.js","webpack:///./node_modules/lodash/_castArrayLikeObject.js","webpack:///./node_modules/lodash/_castFunction.js","webpack:///./node_modules/lodash/_castPath.js","webpack:///./node_modules/lodash/_castSlice.js","webpack:///./node_modules/lodash/_charsEndIndex.js","webpack:///./node_modules/lodash/_charsStartIndex.js","webpack:///./node_modules/lodash/_cloneArrayBuffer.js","webpack:///./node_modules/lodash/_cloneBuffer.js","webpack:///./node_modules/lodash/_cloneDataView.js","webpack:///./node_modules/lodash/_cloneRegExp.js","webpack:///./node_modules/lodash/_cloneSymbol.js","webpack:///./node_modules/lodash/_cloneTypedArray.js","webpack:///./node_modules/lodash/_compareAscending.js","webpack:///./node_modules/lodash/_compareMultiple.js","webpack:///./node_modules/lodash/_composeArgs.js","webpack:///./node_modules/lodash/_composeArgsRight.js","webpack:///./node_modules/lodash/_copyArray.js","webpack:///./node_modules/lodash/_copyObject.js","webpack:///./node_modules/lodash/_copySymbols.js","webpack:///./node_modules/lodash/_copySymbolsIn.js","webpack:///./node_modules/lodash/_coreJsData.js","webpack:///./node_modules/lodash/_countHolders.js","webpack:///./node_modules/lodash/_createAggregator.js","webpack:///./node_modules/lodash/_createAssigner.js","webpack:///./node_modules/lodash/_createBaseEach.js","webpack:///./node_modules/lodash/_createBaseFor.js","webpack:///./node_modules/lodash/_createBind.js","webpack:///./node_modules/lodash/_createCaseFirst.js","webpack:///./node_modules/lodash/_createCompounder.js","webpack:///./node_modules/lodash/_createCtor.js","webpack:///./node_modules/lodash/_createCurry.js","webpack:///./node_modules/lodash/_createFind.js","webpack:///./node_modules/lodash/_createFlow.js","webpack:///./node_modules/lodash/_createHybrid.js","webpack:///./node_modules/lodash/_createInverter.js","webpack:///./node_modules/lodash/_createPartial.js","webpack:///./node_modules/lodash/_createRange.js","webpack:///./node_modules/lodash/_createRecurry.js","webpack:///./node_modules/lodash/_createRound.js","webpack:///./node_modules/lodash/_createSet.js","webpack:///./node_modules/lodash/_createWrap.js","webpack:///./node_modules/lodash/_deburrLetter.js","webpack:///./node_modules/lodash/_defineProperty.js","webpack:///./node_modules/lodash/_equalArrays.js","webpack:///./node_modules/lodash/_equalByTag.js","webpack:///./node_modules/lodash/_equalObjects.js","webpack:///./node_modules/lodash/_flatRest.js","webpack:///./node_modules/lodash/_freeGlobal.js","webpack:///./node_modules/lodash/_getAllKeys.js","webpack:///./node_modules/lodash/_getAllKeysIn.js","webpack:///./node_modules/lodash/_getData.js","webpack:///./node_modules/lodash/_getFuncName.js","webpack:///./node_modules/lodash/_getHolder.js","webpack:///./node_modules/lodash/_getMapData.js","webpack:///./node_modules/lodash/_getMatchData.js","webpack:///./node_modules/lodash/_getNative.js","webpack:///./node_modules/lodash/_getPrototype.js","webpack:///./node_modules/lodash/_getRawTag.js","webpack:///./node_modules/lodash/_getSymbols.js","webpack:///./node_modules/lodash/_getSymbolsIn.js","webpack:///./node_modules/lodash/_getTag.js","webpack:///./node_modules/lodash/_getValue.js","webpack:///./node_modules/lodash/_getWrapDetails.js","webpack:///./node_modules/lodash/_hasPath.js","webpack:///./node_modules/lodash/_hasUnicode.js","webpack:///./node_modules/lodash/_hasUnicodeWord.js","webpack:///./node_modules/lodash/_hashClear.js","webpack:///./node_modules/lodash/_hashDelete.js","webpack:///./node_modules/lodash/_hashGet.js","webpack:///./node_modules/lodash/_hashHas.js","webpack:///./node_modules/lodash/_hashSet.js","webpack:///./node_modules/lodash/_initCloneArray.js","webpack:///./node_modules/lodash/_initCloneByTag.js","webpack:///./node_modules/lodash/_initCloneObject.js","webpack:///./node_modules/lodash/_insertWrapDetails.js","webpack:///./node_modules/lodash/_isFlattenable.js","webpack:///./node_modules/lodash/_isIndex.js","webpack:///./node_modules/lodash/_isIterateeCall.js","webpack:///./node_modules/lodash/_isKey.js","webpack:///./node_modules/lodash/_isKeyable.js","webpack:///./node_modules/lodash/_isLaziable.js","webpack:///./node_modules/lodash/_isMasked.js","webpack:///./node_modules/lodash/_isPrototype.js","webpack:///./node_modules/lodash/_isStrictComparable.js","webpack:///./node_modules/lodash/_listCacheClear.js","webpack:///./node_modules/lodash/_listCacheDelete.js","webpack:///./node_modules/lodash/_listCacheGet.js","webpack:///./node_modules/lodash/_listCacheHas.js","webpack:///./node_modules/lodash/_listCacheSet.js","webpack:///./node_modules/lodash/_mapCacheClear.js","webpack:///./node_modules/lodash/_mapCacheDelete.js","webpack:///./node_modules/lodash/_mapCacheGet.js","webpack:///./node_modules/lodash/_mapCacheHas.js","webpack:///./node_modules/lodash/_mapCacheSet.js","webpack:///./node_modules/lodash/_mapToArray.js","webpack:///./node_modules/lodash/_matchesStrictComparable.js","webpack:///./node_modules/lodash/_memoizeCapped.js","webpack:///./node_modules/lodash/_mergeData.js","webpack:///./node_modules/lodash/_metaMap.js","webpack:///./node_modules/lodash/_nativeCreate.js","webpack:///./node_modules/lodash/_nativeKeys.js","webpack:///./node_modules/lodash/_nativeKeysIn.js","webpack:///./node_modules/lodash/_nodeUtil.js","webpack:///./node_modules/lodash/_objectToString.js","webpack:///./node_modules/lodash/_overArg.js","webpack:///./node_modules/lodash/_overRest.js","webpack:///./node_modules/lodash/_parent.js","webpack:///./node_modules/lodash/_realNames.js","webpack:///./node_modules/lodash/_reorder.js","webpack:///./node_modules/lodash/_replaceHolders.js","webpack:///./node_modules/lodash/_root.js","webpack:///./node_modules/lodash/_safeGet.js","webpack:///./node_modules/lodash/_setCacheAdd.js","webpack:///./node_modules/lodash/_setCacheHas.js","webpack:///./node_modules/lodash/_setData.js","webpack:///./node_modules/lodash/_setToArray.js","webpack:///./node_modules/lodash/_setToString.js","webpack:///./node_modules/lodash/_setWrapToString.js","webpack:///./node_modules/lodash/_shortOut.js","webpack:///./node_modules/lodash/_stackClear.js","webpack:///./node_modules/lodash/_stackDelete.js","webpack:///./node_modules/lodash/_stackGet.js","webpack:///./node_modules/lodash/_stackHas.js","webpack:///./node_modules/lodash/_stackSet.js","webpack:///./node_modules/lodash/_strictIndexOf.js","webpack:///./node_modules/lodash/_stringSize.js","webpack:///./node_modules/lodash/_stringToArray.js","webpack:///./node_modules/lodash/_stringToPath.js","webpack:///./node_modules/lodash/_toKey.js","webpack:///./node_modules/lodash/_toSource.js","webpack:///./node_modules/lodash/_unicodeSize.js","webpack:///./node_modules/lodash/_unicodeToArray.js","webpack:///./node_modules/lodash/_unicodeWords.js","webpack:///./node_modules/lodash/_updateWrapDetails.js","webpack:///./node_modules/lodash/_wrapperClone.js","webpack:///./node_modules/lodash/ary.js","webpack:///./node_modules/lodash/clamp.js","webpack:///./node_modules/lodash/clone.js","webpack:///./node_modules/lodash/compact.js","webpack:///./node_modules/lodash/constant.js","webpack:///./node_modules/lodash/curry.js","webpack:///./node_modules/lodash/deburr.js","webpack:///./node_modules/lodash/difference.js","webpack:///./node_modules/lodash/dropRight.js","webpack:///./node_modules/lodash/each.js","webpack:///./node_modules/lodash/eq.js","webpack:///./node_modules/lodash/escapeRegExp.js","webpack:///./node_modules/lodash/every.js","webpack:///./node_modules/lodash/filter.js","webpack:///./node_modules/lodash/find.js","webpack:///./node_modules/lodash/findIndex.js","webpack:///./node_modules/lodash/first.js","webpack:///./node_modules/lodash/flatten.js","webpack:///./node_modules/lodash/flow.js","webpack:///./node_modules/lodash/forEach.js","webpack:///./node_modules/lodash/fp/_baseConvert.js","webpack:///./node_modules/lodash/fp/_falseOptions.js","webpack:///./node_modules/lodash/fp/_mapping.js","webpack:///./node_modules/lodash/fp/_util.js","webpack:///./node_modules/lodash/fp/compact.js","webpack:///./node_modules/lodash/fp/convert.js","webpack:///./node_modules/lodash/fp/difference.js","webpack:///./node_modules/lodash/fp/flow.js","webpack:///./node_modules/lodash/fp/isFunction.js","webpack:///./node_modules/lodash/fp/isNil.js","webpack:///./node_modules/lodash/fp/isObject.js","webpack:///./node_modules/lodash/fp/isPlainObject.js","webpack:///./node_modules/lodash/fp/keys.js","webpack:///./node_modules/lodash/fp/map.js","webpack:///./node_modules/lodash/fp/memoize.js","webpack:///./node_modules/lodash/fp/min.js","webpack:///./node_modules/lodash/fp/pick.js","webpack:///./node_modules/lodash/fp/placeholder.js","webpack:///./node_modules/lodash/fp/sortBy.js","webpack:///./node_modules/lodash/fp/sum.js","webpack:///./node_modules/lodash/fp/take.js","webpack:///./node_modules/lodash/fp/trim.js","webpack:///./node_modules/lodash/get.js","webpack:///./node_modules/lodash/has.js","webpack:///./node_modules/lodash/hasIn.js","webpack:///./node_modules/lodash/head.js","webpack:///./node_modules/lodash/identity.js","webpack:///./node_modules/lodash/inRange.js","webpack:///./node_modules/lodash/includes.js","webpack:///./node_modules/lodash/intersection.js","webpack:///./node_modules/lodash/invert.js","webpack:///./node_modules/lodash/invoke.js","webpack:///./node_modules/lodash/isArguments.js","webpack:///./node_modules/lodash/isArray.js","webpack:///./node_modules/lodash/isArrayLike.js","webpack:///./node_modules/lodash/isArrayLikeObject.js","webpack:///./node_modules/lodash/isBoolean.js","webpack:///./node_modules/lodash/isBuffer.js","webpack:///./node_modules/lodash/isEmpty.js","webpack:///./node_modules/lodash/isEqual.js","webpack:///./node_modules/lodash/isError.js","webpack:///./node_modules/lodash/isFunction.js","webpack:///./node_modules/lodash/isLength.js","webpack:///./node_modules/lodash/isMap.js","webpack:///./node_modules/lodash/isNil.js","webpack:///./node_modules/lodash/isNumber.js","webpack:///./node_modules/lodash/isObject.js","webpack:///./node_modules/lodash/isObjectLike.js","webpack:///./node_modules/lodash/isPlainObject.js","webpack:///./node_modules/lodash/isSet.js","webpack:///./node_modules/lodash/isString.js","webpack:///./node_modules/lodash/isSymbol.js","webpack:///./node_modules/lodash/isTypedArray.js","webpack:///./node_modules/lodash/isUndefined.js","webpack:///./node_modules/lodash/isWeakMap.js","webpack:///./node_modules/lodash/iteratee.js","webpack:///./node_modules/lodash/keyBy.js","webpack:///./node_modules/lodash/keys.js","webpack:///./node_modules/lodash/keysIn.js","webpack:///./node_modules/lodash/last.js","webpack:///./node_modules/lodash/map.js","webpack:///./node_modules/lodash/mapValues.js","webpack:///./node_modules/lodash/memoize.js","webpack:///./node_modules/lodash/merge.js","webpack:///./node_modules/lodash/min.js","webpack:///./node_modules/lodash/noop.js","webpack:///./node_modules/lodash/partialRight.js","webpack:///./node_modules/lodash/pick.js","webpack:///./node_modules/lodash/pickBy.js","webpack:///./node_modules/lodash/property.js","webpack:///./node_modules/lodash/range.js","webpack:///./node_modules/lodash/rearg.js","webpack:///./node_modules/lodash/reduce.js","webpack:///./node_modules/lodash/round.js","webpack:///./node_modules/lodash/set.js","webpack:///./node_modules/lodash/size.js","webpack:///./node_modules/lodash/some.js","webpack:///./node_modules/lodash/sortBy.js","webpack:///./node_modules/lodash/startCase.js","webpack:///./node_modules/lodash/startsWith.js","webpack:///./node_modules/lodash/stubArray.js","webpack:///./node_modules/lodash/stubFalse.js","webpack:///./node_modules/lodash/sum.js","webpack:///./node_modules/lodash/take.js","webpack:///./node_modules/lodash/times.js","webpack:///./node_modules/lodash/toFinite.js","webpack:///./node_modules/lodash/toInteger.js","webpack:///./node_modules/lodash/toNumber.js","webpack:///./node_modules/lodash/toPath.js","webpack:///./node_modules/lodash/toPlainObject.js","webpack:///./node_modules/lodash/toString.js","webpack:///./node_modules/lodash/transform.js","webpack:///./node_modules/lodash/trim.js","webpack:///./node_modules/lodash/union.js","webpack:///./node_modules/lodash/uniq.js","webpack:///./node_modules/lodash/upperFirst.js","webpack:///./node_modules/lodash/values.js","webpack:///./node_modules/lodash/without.js","webpack:///./node_modules/lodash/words.js","webpack:///./node_modules/lodash/wrapperLodash.js","webpack:///./node_modules/mini-create-react-context/dist/esm/index.js","webpack:///./node_modules/object-assign/index.js","webpack:///./node_modules/object-is/implementation.js","webpack:///./node_modules/object-is/index.js","webpack:///./node_modules/object-is/polyfill.js","webpack:///./node_modules/object-is/shim.js","webpack:///./node_modules/object-keys/implementation.js","webpack:///./node_modules/object-keys/index.js","webpack:///./node_modules/object-keys/isArguments.js","webpack:///../../src/utils/isBrowser.js","webpack:///../../src/utils/debounce.js","webpack:///../../src/utils/isFunction.js","webpack:///../../src/utils/getStyleComputedProperty.js","webpack:///../../src/utils/getParentNode.js","webpack:///../../src/utils/getScrollParent.js","webpack:///../../src/utils/getReferenceNode.js","webpack:///../../src/utils/isIE.js","webpack:///../../src/utils/getOffsetParent.js","webpack:///../../src/utils/isOffsetContainer.js","webpack:///../../src/utils/getRoot.js","webpack:///../../src/utils/findCommonOffsetParent.js","webpack:///../../src/utils/getScroll.js","webpack:///../../src/utils/includeScroll.js","webpack:///../../src/utils/getBordersSize.js","webpack:///../../src/utils/getWindowSizes.js","webpack:///../../src/utils/getClientRect.js","webpack:///../../src/utils/getBoundingClientRect.js","webpack:///../../src/utils/getOffsetRectRelativeToArbitraryNode.js","webpack:///../../src/utils/getViewportOffsetRectRelativeToArtbitraryNode.js","webpack:///../../src/utils/isFixed.js","webpack:///../../src/utils/getFixedPositionOffsetParent.js","webpack:///../../src/utils/getBoundaries.js","webpack:///../../src/utils/computeAutoPlacement.js","webpack:///../../src/utils/getReferenceOffsets.js","webpack:///../../src/utils/getOuterSizes.js","webpack:///../../src/utils/getOppositePlacement.js","webpack:///../../src/utils/getPopperOffsets.js","webpack:///../../src/utils/find.js","webpack:///../../src/utils/findIndex.js","webpack:///../../src/utils/runModifiers.js","webpack:///../../src/methods/update.js","webpack:///../../src/utils/isModifierEnabled.js","webpack:///../../src/utils/getSupportedPropertyName.js","webpack:///../../src/methods/destroy.js","webpack:///../../src/utils/getWindow.js","webpack:///../../src/utils/setupEventListeners.js","webpack:///../../src/methods/enableEventListeners.js","webpack:///../../src/utils/removeEventListeners.js","webpack:///../../src/methods/disableEventListeners.js","webpack:///../../src/utils/isNumeric.js","webpack:///../../src/utils/setStyles.js","webpack:///../../src/utils/setAttributes.js","webpack:///../../src/modifiers/applyStyle.js","webpack:///../../src/utils/getRoundedOffsets.js","webpack:///../../src/modifiers/computeStyle.js","webpack:///../../src/utils/isModifierRequired.js","webpack:///../../src/modifiers/arrow.js","webpack:///../../src/utils/getOppositeVariation.js","webpack:///../../src/methods/placements.js","webpack:///../../src/utils/clockwise.js","webpack:///../../src/modifiers/flip.js","webpack:///../../src/modifiers/keepTogether.js","webpack:///../../src/modifiers/offset.js","webpack:///../../src/modifiers/preventOverflow.js","webpack:///../../src/modifiers/shift.js","webpack:///../../src/modifiers/hide.js","webpack:///../../src/modifiers/inner.js","webpack:///../../src/modifiers/index.js","webpack:///../../src/methods/defaults.js","webpack:///../../src/index.js","webpack:///./node_modules/process/browser.js","webpack:///./node_modules/prop-types/checkPropTypes.js","webpack:///./node_modules/prop-types/factoryWithTypeCheckers.js","webpack:///./node_modules/prop-types/index.js","webpack:///./node_modules/prop-types/lib/ReactPropTypesSecret.js","webpack:///./node_modules/react-dom/cjs/react-dom.development.js","webpack:///./node_modules/react-dom/index.js","webpack:///./node_modules/react-fast-compare/index.js","webpack:///../src/FileDrop.tsx","webpack:///./node_modules/react-is/cjs/react-is.development.js","webpack:///./node_modules/react-is/index.js","webpack:///./node_modules/react-popper/lib/esm/Manager.js","webpack:///./node_modules/react-popper/lib/esm/Popper.js","webpack:///./node_modules/react-popper/lib/esm/Reference.js","webpack:///./node_modules/react-popper/lib/esm/index.js","webpack:///./node_modules/react-popper/lib/esm/utils.js","webpack:///../modules/BrowserRouter.js","webpack:///../modules/HashRouter.js","webpack:///../modules/utils/locationUtils.js","webpack:///../modules/Link.js","webpack:///../modules/NavLink.js","webpack:///../modules/createNameContext.js","webpack:///../modules/HistoryContext.js","webpack:///../modules/RouterContext.js","webpack:///../modules/Router.js","webpack:///../modules/MemoryRouter.js","webpack:///../modules/Lifecycle.js","webpack:///../modules/Prompt.js","webpack:///../modules/generatePath.js","webpack:///../modules/Redirect.js","webpack:///../modules/matchPath.js","webpack:///../modules/Route.js","webpack:///../modules/StaticRouter.js","webpack:///../modules/Switch.js","webpack:///../modules/withRouter.js","webpack:///../modules/hooks.js","webpack:///../modules/index.js","webpack:///./node_modules/react-router/node_modules/isarray/index.js","webpack:///./node_modules/react-router/node_modules/path-to-regexp/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css?3887","webpack:///../src/utils.ts","webpack:///../src/pickers/utils.ts","webpack:///../src/pickers/base.tsx","webpack:///../src/pickers/basic.tsx","webpack:///../src/pickers/range.tsx","webpack:///../src/components/button.tsx","webpack:///../node_modules/style-inject/dist/style-inject.es.js","webpack:///../src/components/cell/cell.tsx","webpack:///../src/components/today-button.tsx","webpack:///../src/components/calendar/calendar.tsx","webpack:///../src/components/icon.tsx","webpack:///../src/components/input.tsx","webpack:///../src/index.tsx","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/addLeadingZeros/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/assign/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/cloneObject/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/format/formatters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/format/lightFormatters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/format/longFormatters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getTimezoneOffsetInMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getUTCDayOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getUTCISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getUTCISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getUTCWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/getUTCWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/protectedTokens/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/requiredArgs/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/setUTCDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/setUTCISODay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/setUTCISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/setUTCWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/startOfUTCISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/startOfUTCISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/startOfUTCWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/startOfUTCWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/_lib/toInteger/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/add/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addBusinessDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addHours/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addISOWeekYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addMonths/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addQuarters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addSeconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addWeeks/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/addYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/areIntervalsOverlapping/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/closestIndexTo/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/closestTo/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/compareAsc/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/compareDesc/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/constants/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInBusinessDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarISOWeekYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarISOWeeks/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarMonths/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarQuarters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarWeeks/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInCalendarYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInHours/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInISOWeekYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInMonths/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInQuarters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInSeconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInWeeks/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/differenceInYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachDayOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachHourOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachMonthOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachQuarterOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachWeekOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachWeekendOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachWeekendOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachWeekendOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/eachYearOfInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfDecade/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfHour/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfMinute/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfSecond/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfToday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfTomorrow/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/endOfYesterday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/format/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatDistance/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatDistanceStrict/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatDistanceToNow/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatDistanceToNowStrict/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatDuration/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatISO/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatISO9075/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatISODuration/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatRFC3339/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatRFC7231/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/formatRelative/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/fromUnixTime/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDate/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDayOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDaysInMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDaysInYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getDecade/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getHours/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getISODay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getISOWeeksInYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getOverlappingDaysInIntervals/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getSeconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getTime/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getUnixTime/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getWeekOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getWeeksInMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/getYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/intervalToDuration/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isAfter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isBefore/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isDate/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isEqual/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isExists/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isFirstDayOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isFriday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isFuture/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isLastDayOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isLeapYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isMatch/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isMonday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isPast/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameHour/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameMinute/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameSecond/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSameYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSaturday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isSunday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisHour/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisMinute/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisSecond/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThisYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isThursday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isToday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isTomorrow/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isTuesday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isValid/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isWednesday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isWeekend/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isWithinInterval/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/isYesterday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfDecade/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lastDayOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/lightFormat/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/_lib/buildFormatLongFn/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/_lib/buildLocalizeFn/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/_lib/buildMatchFn/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/_lib/buildMatchPatternFn/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/_lib/formatDistance/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/_lib/formatLong/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/_lib/formatRelative/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/_lib/localize/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/_lib/match/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/locale/en-US/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/max/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/min/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/parse/_lib/parsers/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/parse/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/parseISO/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/parseJSON/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/roundToNearestMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/set/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setDate/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setDayOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setHours/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setISODay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setSeconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/setYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfDay/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfDecade/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfHour/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfISOWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfISOWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfMinute/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfMonth/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfQuarter/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfSecond/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfToday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfTomorrow/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfWeek/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfWeekYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfYear/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/startOfYesterday/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/sub/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subBusinessDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subDays/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subHours/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subISOWeekYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subMilliseconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subMinutes/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subMonths/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subQuarters/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subSeconds/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subWeeks/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/subYears/index.js","webpack:///./node_modules/react-semantic-ui-datepickers/node_modules/date-fns/esm/toDate/index.js","webpack:///./node_modules/react/cjs/react.development.js","webpack:///./node_modules/react/index.js","webpack:///./node_modules/regexp.prototype.flags/implementation.js","webpack:///./node_modules/regexp.prototype.flags/index.js","webpack:///./node_modules/regexp.prototype.flags/polyfill.js","webpack:///./node_modules/regexp.prototype.flags/shim.js","webpack:///./node_modules/resolve-pathname/esm/resolve-pathname.js","webpack:///./node_modules/scheduler/cjs/scheduler-tracing.development.js","webpack:///./node_modules/scheduler/cjs/scheduler.development.js","webpack:///./node_modules/scheduler/index.js","webpack:///./node_modules/scheduler/tracing.js","webpack:///./node_modules/semantic-ui-css/semantic.min.css?4f1f","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/brand-icons.eot","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/brand-icons.svg","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/brand-icons.ttf","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/brand-icons.woff","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/brand-icons.woff2","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/icons.eot","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/icons.svg","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/icons.ttf","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/icons.woff","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/icons.woff2","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/outline-icons.eot","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/outline-icons.svg","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/outline-icons.ttf","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/outline-icons.woff","webpack:///./node_modules/semantic-ui-css/themes/default/assets/fonts/outline-icons.woff2","webpack:///./node_modules/semantic-ui-css/themes/default/assets/images/flags.png","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Confirm/Confirm.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Confirm/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/MountNode/MountNode.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/MountNode/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Pagination/Pagination.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Pagination/PaginationItem.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Pagination/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Portal/Portal.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Portal/PortalInner.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Portal/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Portal/utils/validateTrigger.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Radio/Radio.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Radio/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Responsive/Responsive.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Responsive/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Responsive/lib/isVisible.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Select/Select.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/Select/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/TextArea/TextArea.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/TextArea/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/TransitionablePortal/TransitionablePortal.js","webpack:///./node_modules/semantic-ui-react/dist/es/addons/TransitionablePortal/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/behaviors/Visibility/Visibility.js","webpack:///./node_modules/semantic-ui-react/dist/es/behaviors/Visibility/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Breadcrumb/Breadcrumb.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Breadcrumb/BreadcrumbDivider.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Breadcrumb/BreadcrumbSection.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Breadcrumb/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/Form.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormButton.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormCheckbox.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormDropdown.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormField.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormInput.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormRadio.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormSelect.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/FormTextArea.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Form/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Grid/Grid.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Grid/GridColumn.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Grid/GridRow.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Grid/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Menu/Menu.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Menu/MenuHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Menu/MenuItem.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Menu/MenuMenu.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Menu/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/Message.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/MessageContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/MessageHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/MessageItem.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/MessageList.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Message/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/Table.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableBody.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableCell.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableFooter.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableHeaderCell.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/TableRow.js","webpack:///./node_modules/semantic-ui-react/dist/es/collections/Table/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Button/Button.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Button/ButtonContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Button/ButtonGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Button/ButtonOr.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Button/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Container/Container.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Container/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Divider/Divider.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Divider/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Flag/Flag.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Flag/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Header/Header.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Header/HeaderContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Header/HeaderSubheader.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Header/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Icon/Icon.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Icon/IconGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Icon/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Image/Image.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Image/ImageGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Image/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Input/Input.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Input/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Label/Label.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Label/LabelDetail.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Label/LabelGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Label/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/List.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListDescription.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListIcon.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListItem.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/ListList.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/List/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Loader/Loader.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Loader/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/Placeholder.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/PlaceholderHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/PlaceholderImage.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/PlaceholderLine.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/PlaceholderParagraph.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Placeholder/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Rail/Rail.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Rail/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Reveal/Reveal.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Reveal/RevealContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Reveal/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Segment/Segment.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Segment/SegmentGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Segment/SegmentInline.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Segment/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/Step.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/StepContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/StepDescription.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/StepGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/StepTitle.js","webpack:///./node_modules/semantic-ui-react/dist/es/elements/Step/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/ModernAutoControlledComponent.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/SUI.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/childrenUtils.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/classNameBuilders.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/createPaginationItems.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/itemFactories.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/paginationUtils.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/rangeFactories.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/createPaginationItems/suffixFactories.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/customPropTypes.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/doesNodeContainClick.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/eventStack/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/factories.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/getElementType.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/getUnhandledProps.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/hooks/useClassNamesOnNode.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/hooks/useIsomorphicLayoutEffect.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/htmlPropsUtils.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/isBrowser.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/leven.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/normalizeOffset.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/normalizeTransitionDuration.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/numberToWord.js","webpack:///./node_modules/semantic-ui-react/dist/es/lib/objectDiff.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Accordion/Accordion.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Accordion/AccordionAccordion.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Accordion/AccordionContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Accordion/AccordionPanel.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Accordion/AccordionTitle.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Checkbox/Checkbox.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Checkbox/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dimmer/Dimmer.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dimmer/DimmerDimmable.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dimmer/DimmerInner.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dimmer/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/Dropdown.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownDivider.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownItem.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownMenu.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownSearchInput.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/DropdownText.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/utils/getMenuOptions.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Dropdown/utils/getSelectedIndex.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Embed/Embed.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Embed/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/Modal.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/ModalActions.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/ModalContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/ModalDescription.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/ModalDimmer.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/ModalHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Modal/utils/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/Popup.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/PopupContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/PopupHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/lib/createReferenceProxy.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Popup/lib/positions.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Progress/Progress.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Progress/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Rating/Rating.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Rating/RatingIcon.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Rating/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/Search.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/SearchCategory.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/SearchCategoryLayout.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/SearchResult.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/SearchResults.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Search/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sidebar/Sidebar.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sidebar/SidebarPushable.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sidebar/SidebarPusher.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sidebar/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sticky/Sticky.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Sticky/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Tab/Tab.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Tab/TabPane.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Tab/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/Transition.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/TransitionGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/utils/childMapping.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/utils/computeStatuses.js","webpack:///./node_modules/semantic-ui-react/dist/es/modules/Transition/utils/wrapChild.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Advertisement/Advertisement.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Advertisement/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/Card.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/CardContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/CardDescription.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/CardGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/CardHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Card/CardMeta.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/Comment.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentAction.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentActions.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentAuthor.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentAvatar.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentMetadata.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/CommentText.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Comment/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/Feed.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedDate.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedEvent.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedExtra.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedLabel.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedLike.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedMeta.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedSummary.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/FeedUser.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Feed/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/Item.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemContent.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemDescription.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemExtra.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemHeader.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemImage.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/ItemMeta.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Item/index.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Statistic/Statistic.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Statistic/StatisticGroup.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Statistic/StatisticLabel.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Statistic/StatisticValue.js","webpack:///./node_modules/semantic-ui-react/dist/es/views/Statistic/index.js","webpack:///./node_modules/shallowequal/index.js","webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack:///./node_modules/tiny-invariant/dist/tiny-invariant.esm.js","webpack:///./node_modules/tiny-warning/dist/tiny-warning.esm.js","webpack:///./node_modules/tslib/tslib.es6.js","webpack:///./node_modules/value-equal/esm/value-equal.js","webpack:///./node_modules/warning/warning.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js"],"sourcesContent":["function _assertThisInitialized(self) {\n  if (self === void 0) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return self;\n}\n\nmodule.exports = _assertThisInitialized;","function _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nmodule.exports = _defineProperty;","export default function _assertThisInitialized(self) {\n  if (self === void 0) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return self;\n}","export default function _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}","function _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}","export default function _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}","export default function _extends() {\n  _extends = Object.assign || function (target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i];\n\n      for (var key in source) {\n        if (Object.prototype.hasOwnProperty.call(source, key)) {\n          target[key] = source[key];\n        }\n      }\n    }\n\n    return target;\n  };\n\n  return _extends.apply(this, arguments);\n}","export default function _getPrototypeOf(o) {\n  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n    return o.__proto__ || Object.getPrototypeOf(o);\n  };\n  return _getPrototypeOf(o);\n}","import setPrototypeOf from \"./setPrototypeOf\";\nexport default function _inherits(subClass, superClass) {\n  if (typeof superClass !== \"function\" && superClass !== null) {\n    throw new TypeError(\"Super expression must either be null or a function\");\n  }\n\n  subClass.prototype = Object.create(superClass && superClass.prototype, {\n    constructor: {\n      value: subClass,\n      writable: true,\n      configurable: true\n    }\n  });\n  if (superClass) setPrototypeOf(subClass, superClass);\n}","export default function _inheritsLoose(subClass, superClass) {\n  subClass.prototype = Object.create(superClass.prototype);\n  subClass.prototype.constructor = subClass;\n  subClass.__proto__ = superClass;\n}","export default function _objectWithoutPropertiesLoose(source, excluded) {\n  if (source == null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key, i;\n\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n\n  return target;\n}","import _typeof from \"../../helpers/esm/typeof\";\nimport assertThisInitialized from \"./assertThisInitialized\";\nexport default function _possibleConstructorReturn(self, call) {\n  if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n    return call;\n  }\n\n  return assertThisInitialized(self);\n}","export default function _setPrototypeOf(o, p) {\n  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n    o.__proto__ = p;\n    return o;\n  };\n\n  return _setPrototypeOf(o, p);\n}","export default function _typeof(obj) {\n  \"@babel/helpers - typeof\";\n\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function _typeof(obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function _typeof(obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}","function _extends() {\n  module.exports = _extends = Object.assign || function (target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i];\n\n      for (var key in source) {\n        if (Object.prototype.hasOwnProperty.call(source, key)) {\n          target[key] = source[key];\n        }\n      }\n    }\n\n    return target;\n  };\n\n  return _extends.apply(this, arguments);\n}\n\nmodule.exports = _extends;","function _inheritsLoose(subClass, superClass) {\n  subClass.prototype = Object.create(superClass.prototype);\n  subClass.prototype.constructor = subClass;\n  subClass.__proto__ = superClass;\n}\n\nmodule.exports = _inheritsLoose;","function _objectWithoutPropertiesLoose(source, excluded) {\n  if (source == null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key, i;\n\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n\n  return target;\n}\n\nmodule.exports = _objectWithoutPropertiesLoose;",null,null,null,null,"/**\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 ANALYTICS_ID_FIELD = 'measurementId';\n\n// Key to attach FID to in gtag params.\nexport const GA_FID_KEY = 'firebase_id';\nexport const ORIGIN_KEY = 'origin';\n\nexport const GTAG_URL = 'https://www.googletagmanager.com/gtag/js';\n\nexport enum GtagCommand {\n  EVENT = 'event',\n  SET = 'set',\n  CONFIG = 'config'\n}\n\n/*\n * Officially recommended event names for gtag.js\n * Any other string is also allowed.\n */\nexport enum EventName {\n  ADD_SHIPPING_INFO = 'add_shipping_info',\n  ADD_PAYMENT_INFO = 'add_payment_info',\n  ADD_TO_CART = 'add_to_cart',\n  ADD_TO_WISHLIST = 'add_to_wishlist',\n  BEGIN_CHECKOUT = 'begin_checkout',\n  /** @deprecated */\n  CHECKOUT_PROGRESS = 'checkout_progress',\n  EXCEPTION = 'exception',\n  GENERATE_LEAD = 'generate_lead',\n  LOGIN = 'login',\n  PAGE_VIEW = 'page_view',\n  PURCHASE = 'purchase',\n  REFUND = 'refund',\n  REMOVE_FROM_CART = 'remove_from_cart',\n  SCREEN_VIEW = 'screen_view',\n  SEARCH = 'search',\n  SELECT_CONTENT = 'select_content',\n  SELECT_ITEM = 'select_item',\n  SELECT_PROMOTION = 'select_promotion',\n  /** @deprecated */\n  SET_CHECKOUT_OPTION = 'set_checkout_option',\n  SHARE = 'share',\n  SIGN_UP = 'sign_up',\n  TIMING_COMPLETE = 'timing_complete',\n  VIEW_CART = 'view_cart',\n  VIEW_ITEM = 'view_item',\n  VIEW_ITEM_LIST = 'view_item_list',\n  VIEW_PROMOTION = 'view_promotion',\n  VIEW_SEARCH_RESULTS = 'view_search_results'\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  AnalyticsCallOptions,\n  Gtag,\n  CustomParams,\n  ControlParams,\n  EventParams\n} from '@firebase/analytics-types';\nimport { GtagCommand } from './constants';\n/**\n * Logs an analytics event through the Firebase SDK.\n *\n * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event\n * @param eventName Google Analytics event name, choose from standard list or use a custom string.\n * @param eventParams Analytics event parameters.\n */\nexport function logEvent(\n  gtagFunction: Gtag,\n  analyticsId: string,\n  eventName: string,\n  eventParams?: EventParams,\n  options?: AnalyticsCallOptions\n): void {\n  let params: EventParams | ControlParams = eventParams || {};\n  if (!options || !options.global) {\n    params = { ...eventParams, 'send_to': analyticsId };\n  }\n  // Workaround for http://b/141370449 - third argument cannot be undefined.\n  gtagFunction(GtagCommand.EVENT, eventName, params || {});\n}\n\n// TODO: Brad is going to add `screen_name` to GA Gold config parameter schema\n\n/**\n * Set screen_name parameter for this Google Analytics ID.\n *\n * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event\n * @param screenName Screen name string to set.\n */\nexport function setCurrentScreen(\n  gtagFunction: Gtag,\n  analyticsId: string,\n  screenName: string | null,\n  options?: AnalyticsCallOptions\n): void {\n  if (options && options.global) {\n    gtagFunction(GtagCommand.SET, { 'screen_name': screenName });\n  } else {\n    gtagFunction(GtagCommand.CONFIG, analyticsId, {\n      update: true,\n      'screen_name': screenName\n    });\n  }\n}\n\n/**\n * Set user_id parameter for this Google Analytics ID.\n *\n * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event\n * @param id User ID string to set\n */\nexport function setUserId(\n  gtagFunction: Gtag,\n  analyticsId: string,\n  id: string | null,\n  options?: AnalyticsCallOptions\n): void {\n  if (options && options.global) {\n    gtagFunction(GtagCommand.SET, { 'user_id': id });\n  } else {\n    gtagFunction(GtagCommand.CONFIG, analyticsId, {\n      update: true,\n      'user_id': id\n    });\n  }\n}\n\n/**\n * Set all other user properties other than user_id and screen_name.\n *\n * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event\n * @param properties Map of user properties to set\n */\nexport function setUserProperties(\n  gtagFunction: Gtag,\n  analyticsId: string,\n  properties: CustomParams,\n  options?: AnalyticsCallOptions\n): void {\n  if (options && options.global) {\n    const flatProperties: { [key: string]: unknown } = {};\n    for (const key of Object.keys(properties)) {\n      // use dot notation for merge behavior in gtag.js\n      flatProperties[`user_properties.${key}`] = properties[key];\n    }\n    gtagFunction(GtagCommand.SET, flatProperties);\n  } else {\n    gtagFunction(GtagCommand.CONFIG, analyticsId, {\n      update: true,\n      'user_properties': properties\n    });\n  }\n}\n\n/**\n * Set whether collection is enabled for this ID.\n *\n * @param enabled If true, collection is enabled for this ID.\n */\nexport function setAnalyticsCollectionEnabled(\n  analyticsId: string,\n  enabled: boolean\n): void {\n  window[`ga-disable-${analyticsId}`] = !enabled;\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/analytics');\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 '@firebase/app-types';\nimport {\n  DataLayer,\n  Gtag,\n  CustomParams,\n  ControlParams,\n  EventParams\n} from '@firebase/analytics-types';\nimport {\n  GtagCommand,\n  ANALYTICS_ID_FIELD,\n  GA_FID_KEY,\n  ORIGIN_KEY,\n  GTAG_URL\n} from './constants';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport { logger } from './logger';\n/**\n * Initialize the analytics instance in gtag.js by calling config command with fid.\n *\n * NOTE: We combine analytics initialization and setting fid together because we want fid to be\n * part of the `page_view` event that's sent during the initialization\n * @param app Firebase app\n * @param gtagCore The gtag function that's not wrapped.\n */\nexport async function initializeGAId(\n  app: FirebaseApp,\n  installations: FirebaseInstallations,\n  gtagCore: Gtag\n): Promise<void> {\n  const fid = await installations.getId();\n\n  // This command initializes gtag.js and only needs to be called once for the entire web app,\n  // but since it is idempotent, we can call it multiple times.\n  // We keep it together with other initialization logic for better code structure.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  gtagCore('js' as any, new Date());\n\n  // It should be the first config command called on this GA-ID\n  // Initialize this GA-ID and set FID on it using the gtag config API.\n  gtagCore(GtagCommand.CONFIG, app.options[ANALYTICS_ID_FIELD]!, {\n    [GA_FID_KEY]: fid,\n    // guard against developers accidentally setting properties with prefix `firebase_`\n    [ORIGIN_KEY]: 'firebase',\n    update: true\n  });\n}\n\nexport function insertScriptTag(dataLayerName: string): void {\n  const script = document.createElement('script');\n  // We are not providing an analyticsId in the URL because it would trigger a `page_view`\n  // without fid. We will initialize ga-id using gtag (config) command together with fid.\n  script.src = `${GTAG_URL}?l=${dataLayerName}`;\n  script.async = true;\n  document.head.appendChild(script);\n}\n\n/** Get reference to, or create, global datalayer.\n * @param dataLayerName Name of datalayer (most often the default, \"_dataLayer\")\n */\nexport function getOrCreateDataLayer(dataLayerName: string): DataLayer {\n  // Check for existing dataLayer and create if needed.\n  let dataLayer: DataLayer = [];\n  if (Array.isArray(window[dataLayerName])) {\n    dataLayer = window[dataLayerName] as DataLayer;\n  } else {\n    window[dataLayerName] = dataLayer;\n  }\n  return dataLayer;\n}\n/**\n * Wraps a standard gtag function with extra code to wait for completion of\n * relevant initialization promises before sending requests.\n *\n * @param gtagCore Basic gtag function that just appends to dataLayer\n * @param initializedIdPromisesMap Map of gaIds to their initialization promises\n */\nfunction wrapGtag(\n  gtagCore: Gtag,\n  initializedIdPromisesMap: { [gaId: string]: Promise<void> }\n): Function {\n  return (\n    command: 'config' | 'set' | 'event',\n    idOrNameOrParams: string | ControlParams,\n    gtagParams?: ControlParams & EventParams & CustomParams\n  ) => {\n    // If event, check that relevant initialization promises have completed.\n    if (command === GtagCommand.EVENT) {\n      let initializationPromisesToWaitFor: Array<Promise<void>> = [];\n      // If there's a 'send_to' param, check if any ID specified matches\n      // a FID we have begun a fetch on.\n      if (gtagParams && gtagParams['send_to']) {\n        let gaSendToList: string | string[] = gtagParams['send_to'];\n        // Make it an array if is isn't, so it can be dealt with the same way.\n        if (!Array.isArray(gaSendToList)) {\n          gaSendToList = [gaSendToList];\n        }\n        for (const sendToId of gaSendToList) {\n          const initializationPromise = initializedIdPromisesMap[sendToId];\n          // Groups will not be in the map.\n          if (initializationPromise) {\n            initializationPromisesToWaitFor.push(initializationPromise);\n          } else {\n            // There is an item in 'send_to' that is not associated\n            // directly with an FID, possibly a group.  Empty this array\n            // and let it get populated below.\n            initializationPromisesToWaitFor = [];\n            break;\n          }\n        }\n      }\n\n      // This will be unpopulated if there was no 'send_to' field , or\n      // if not all entries in the 'send_to' field could be mapped to\n      // a FID. In these cases, wait on all pending initialization promises.\n      if (initializationPromisesToWaitFor.length === 0) {\n        for (const idPromise of Object.values(initializedIdPromisesMap)) {\n          initializationPromisesToWaitFor.push(idPromise);\n        }\n      }\n      // Run core gtag function with args after all relevant initialization\n      // promises have been resolved.\n      Promise.all(initializationPromisesToWaitFor)\n        // Workaround for http://b/141370449 - third argument cannot be undefined.\n        .then(() =>\n          gtagCore(\n            GtagCommand.EVENT,\n            idOrNameOrParams as string,\n            gtagParams || {}\n          )\n        )\n        .catch(e => logger.error(e));\n    } else if (command === GtagCommand.CONFIG) {\n      const initializationPromiseToWait =\n        initializedIdPromisesMap[idOrNameOrParams as string] ||\n        Promise.resolve();\n      initializationPromiseToWait\n        .then(() => {\n          gtagCore(GtagCommand.CONFIG, idOrNameOrParams as string, gtagParams);\n        })\n        .catch(e => logger.error(e));\n    } else {\n      // SET command.\n      // Splitting calls for CONFIG and SET to make it clear which signature\n      // Typescript is checking.\n      gtagCore(GtagCommand.SET, idOrNameOrParams as CustomParams);\n    }\n  };\n}\n\n/**\n * Creates global gtag function or wraps existing one if found.\n * This wrapped function attaches Firebase instance ID (FID) to gtag 'config' and\n * 'event' calls that belong to the GAID associated with this Firebase instance.\n *\n * @param initializedIdPromisesMap Map of gaId to initialization promises.\n * @param dataLayerName Name of global GA datalayer array.\n * @param gtagFunctionName Name of global gtag function (\"gtag\" if not user-specified)\n */\nexport function wrapOrCreateGtag(\n  initializedIdPromisesMap: { [gaId: string]: Promise<void> },\n  dataLayerName: string,\n  gtagFunctionName: string\n): {\n  gtagCore: Gtag;\n  wrappedGtag: Gtag;\n} {\n  // Create a basic core gtag function\n  let gtagCore: Gtag = function (..._args: unknown[]) {\n    // Must push IArguments object, not an array.\n    (window[dataLayerName] as DataLayer).push(arguments);\n  };\n\n  // Replace it with existing one if found\n  if (\n    window[gtagFunctionName] &&\n    typeof window[gtagFunctionName] === 'function'\n  ) {\n    // @ts-ignore\n    gtagCore = window[gtagFunctionName];\n  }\n\n  window[gtagFunctionName] = wrapGtag(gtagCore, initializedIdPromisesMap);\n\n  return {\n    gtagCore,\n    wrappedGtag: window[gtagFunctionName] as Gtag\n  };\n}\n\n/**\n * Returns first script tag in DOM matching our gtag url pattern.\n */\nexport function findGtagScriptOnPage(): HTMLScriptElement | null {\n  const scriptTags = window.document.getElementsByTagName('script');\n  for (const tag of Object.values(scriptTags)) {\n    if (tag.src && tag.src.includes(GTAG_URL)) {\n      return tag;\n    }\n  }\n  return null;\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 { ErrorFactory, ErrorMap } from '@firebase/util';\nimport { ANALYTICS_ID_FIELD } from './constants';\n\nexport const enum AnalyticsError {\n  NO_GA_ID = 'no-ga-id',\n  ALREADY_EXISTS = 'already-exists',\n  ALREADY_INITIALIZED = 'already-initialized',\n  INTEROP_COMPONENT_REG_FAILED = 'interop-component-reg-failed',\n  INDEXED_DB_UNSUPPORTED = 'indexedDB-unsupported',\n  INVALID_INDEXED_DB_CONTEXT = 'invalid-indexedDB-context',\n  COOKIES_NOT_ENABLED = 'cookies-not-enabled',\n  INVALID_ANALYTICS_CONTEXT = 'invalid-analytics-context'\n}\n\nconst ERRORS: ErrorMap<AnalyticsError> = {\n  [AnalyticsError.NO_GA_ID]:\n    `\"${ANALYTICS_ID_FIELD}\" field is empty in ` +\n    'Firebase config. Firebase Analytics ' +\n    'requires this field to contain a valid measurement ID.',\n  [AnalyticsError.ALREADY_EXISTS]:\n    'A Firebase Analytics instance with the measurement ID ${id} ' +\n    ' already exists. ' +\n    'Only one Firebase Analytics instance can be created for each measurement ID.',\n  [AnalyticsError.ALREADY_INITIALIZED]:\n    'Firebase Analytics has already been initialized.' +\n    'settings() must be called before initializing any Analytics instance' +\n    'or it will have no effect.',\n  [AnalyticsError.INTEROP_COMPONENT_REG_FAILED]:\n    'Firebase Analytics Interop Component failed to instantiate',\n  [AnalyticsError.INDEXED_DB_UNSUPPORTED]:\n    'IndexedDB is not supported by current browswer',\n  [AnalyticsError.INVALID_INDEXED_DB_CONTEXT]:\n    \"Environment doesn't support IndexedDB: {$errorInfo}. \" +\n    'Wrap initialization of analytics in analytics.isSupported() ' +\n    'to prevent initialization in unsupported environments',\n  [AnalyticsError.COOKIES_NOT_ENABLED]:\n    'Cookies are not enabled in this browser environment. Analytics requires cookies to be enabled.',\n  [AnalyticsError.INVALID_ANALYTICS_CONTEXT]:\n    'Firebase Analytics is not supported in browser extensions.'\n};\n\ninterface ErrorParams {\n  [AnalyticsError.ALREADY_EXISTS]: { id: string };\n  [AnalyticsError.INTEROP_COMPONENT_REG_FAILED]: { reason: Error };\n  [AnalyticsError.INVALID_INDEXED_DB_CONTEXT]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<AnalyticsError, ErrorParams>(\n  'analytics',\n  'Analytics',\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  FirebaseAnalytics,\n  Gtag,\n  SettingsOptions\n} from '@firebase/analytics-types';\nimport {\n  logEvent,\n  setCurrentScreen,\n  setUserId,\n  setUserProperties,\n  setAnalyticsCollectionEnabled\n} from './functions';\nimport {\n  initializeGAId,\n  insertScriptTag,\n  getOrCreateDataLayer,\n  wrapOrCreateGtag,\n  findGtagScriptOnPage\n} from './helpers';\nimport { ANALYTICS_ID_FIELD } from './constants';\nimport { AnalyticsError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport {\n  isIndexedDBAvailable,\n  validateIndexedDBOpenable,\n  areCookiesEnabled,\n  isBrowserExtension\n} from '@firebase/util';\n\n/**\n * Maps gaId to FID fetch promises.\n */\nlet initializedIdPromisesMap: { [gaId: string]: Promise<void> } = {};\n\n/**\n * Name for window global data layer array used by GA: defaults to 'dataLayer'.\n */\nlet dataLayerName: string = 'dataLayer';\n\n/**\n * Name for window global gtag function used by GA: defaults to 'gtag'.\n */\nlet gtagName: string = 'gtag';\n\n/**\n * Reproduction of standard gtag function or reference to existing\n * gtag function on window object.\n */\nlet gtagCoreFunction: Gtag;\n\n/**\n * Wrapper around gtag function that ensures FID is sent with all\n * relevant event and config calls.\n */\nlet wrappedGtagFunction: Gtag;\n\n/**\n * Flag to ensure page initialization steps (creation or wrapping of\n * dataLayer and gtag script) are only run once per page load.\n */\nlet globalInitDone: boolean = false;\n\n/**\n * For testing\n */\nexport function resetGlobalVars(\n  newGlobalInitDone = false,\n  newGaInitializedPromise = {}\n): void {\n  globalInitDone = newGlobalInitDone;\n  initializedIdPromisesMap = newGaInitializedPromise;\n  dataLayerName = 'dataLayer';\n  gtagName = 'gtag';\n}\n\n/**\n * For testing\n */\nexport function getGlobalVars(): {\n  initializedIdPromisesMap: { [gaId: string]: Promise<void> };\n} {\n  return {\n    initializedIdPromisesMap\n  };\n}\n\n/**\n * This must be run before calling firebase.analytics() or it won't\n * have any effect.\n * @param options Custom gtag and dataLayer names.\n */\nexport function settings(options: SettingsOptions): void {\n  if (globalInitDone) {\n    throw ERROR_FACTORY.create(AnalyticsError.ALREADY_INITIALIZED);\n  }\n  if (options.dataLayerName) {\n    dataLayerName = options.dataLayerName;\n  }\n  if (options.gtagName) {\n    gtagName = options.gtagName;\n  }\n}\n\nexport function factory(\n  app: FirebaseApp,\n  installations: FirebaseInstallations\n): FirebaseAnalytics {\n  if (isBrowserExtension()) {\n    throw ERROR_FACTORY.create(AnalyticsError.INVALID_ANALYTICS_CONTEXT);\n  }\n  if (!areCookiesEnabled()) {\n    throw ERROR_FACTORY.create(AnalyticsError.COOKIES_NOT_ENABLED);\n  }\n  if (!isIndexedDBAvailable()) {\n    throw ERROR_FACTORY.create(AnalyticsError.INDEXED_DB_UNSUPPORTED);\n  }\n  // Async but non-blocking.\n  validateIndexedDBOpenable().catch(error => {\n    throw ERROR_FACTORY.create(AnalyticsError.INVALID_INDEXED_DB_CONTEXT, {\n      errorInfo: error\n    });\n  });\n\n  const analyticsId = app.options[ANALYTICS_ID_FIELD];\n  if (!analyticsId) {\n    throw ERROR_FACTORY.create(AnalyticsError.NO_GA_ID);\n  }\n\n  if (initializedIdPromisesMap[analyticsId] != null) {\n    throw ERROR_FACTORY.create(AnalyticsError.ALREADY_EXISTS, {\n      id: analyticsId\n    });\n  }\n\n  if (!globalInitDone) {\n    // Steps here should only be done once per page: creation or wrapping\n    // of dataLayer and global gtag function.\n\n    // Detect if user has already put the gtag <script> tag on this page.\n    if (!findGtagScriptOnPage()) {\n      insertScriptTag(dataLayerName);\n    }\n    getOrCreateDataLayer(dataLayerName);\n\n    const { wrappedGtag, gtagCore } = wrapOrCreateGtag(\n      initializedIdPromisesMap,\n      dataLayerName,\n      gtagName\n    );\n    wrappedGtagFunction = wrappedGtag;\n    gtagCoreFunction = gtagCore;\n\n    globalInitDone = true;\n  }\n  // Async but non-blocking.\n  initializedIdPromisesMap[analyticsId] = initializeGAId(\n    app,\n    installations,\n    gtagCoreFunction\n  );\n\n  const analyticsInstance: FirebaseAnalytics = {\n    app,\n    logEvent: (eventName, eventParams, options) =>\n      logEvent(\n        wrappedGtagFunction,\n        analyticsId,\n        eventName,\n        eventParams,\n        options\n      ),\n    setCurrentScreen: (screenName, options) =>\n      setCurrentScreen(wrappedGtagFunction, analyticsId, screenName, options),\n    setUserId: (id, options) =>\n      setUserId(wrappedGtagFunction, analyticsId, id, options),\n    setUserProperties: (properties, options) =>\n      setUserProperties(wrappedGtagFunction, analyticsId, properties, options),\n    setAnalyticsCollectionEnabled: enabled =>\n      setAnalyticsCollectionEnabled(analyticsId, enabled)\n  };\n\n  return analyticsInstance;\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 firebase from '@firebase/app';\nimport '@firebase/installations';\nimport { FirebaseAnalytics } from '@firebase/analytics-types';\nimport { FirebaseAnalyticsInternal } from '@firebase/analytics-interop-types';\nimport { _FirebaseNamespace } from '@firebase/app-types/private';\nimport {\n  factory,\n  settings,\n  resetGlobalVars,\n  getGlobalVars\n} from './src/factory';\nimport { EventName } from './src/constants';\nimport {\n  Component,\n  ComponentType,\n  ComponentContainer\n} from '@firebase/component';\nimport { ERROR_FACTORY, AnalyticsError } from './src/errors';\nimport {\n  isIndexedDBAvailable,\n  validateIndexedDBOpenable,\n  areCookiesEnabled,\n  isBrowserExtension\n} from '@firebase/util';\nimport { name, version } from './package.json';\n\ndeclare global {\n  interface Window {\n    [key: string]: unknown;\n  }\n}\n\n/**\n * Type constant for Firebase Analytics.\n */\nconst ANALYTICS_TYPE = 'analytics';\n\nexport function registerAnalytics(instance: _FirebaseNamespace): void {\n  instance.INTERNAL.registerComponent(\n    new Component(\n      ANALYTICS_TYPE,\n      container => {\n        // getImmediate for FirebaseApp will always succeed\n        const app = container.getProvider('app').getImmediate();\n        const installations = container\n          .getProvider('installations')\n          .getImmediate();\n        return factory(app, installations);\n      },\n      ComponentType.PUBLIC\n    ).setServiceProps({\n      settings,\n      EventName,\n      isSupported\n    })\n  );\n\n  instance.INTERNAL.registerComponent(\n    new Component('analytics-internal', internalFactory, ComponentType.PRIVATE)\n  );\n\n  instance.registerVersion(name, version);\n\n  function internalFactory(\n    container: ComponentContainer\n  ): FirebaseAnalyticsInternal {\n    try {\n      const analytics = container.getProvider(ANALYTICS_TYPE).getImmediate();\n      return {\n        logEvent: analytics.logEvent\n      };\n    } catch (e) {\n      throw ERROR_FACTORY.create(AnalyticsError.INTEROP_COMPONENT_REG_FAILED, {\n        reason: e\n      });\n    }\n  }\n}\n\nexport { factory, settings, resetGlobalVars, getGlobalVars };\n\nregisterAnalytics(firebase as _FirebaseNamespace);\n\n/**\n * Define extension behavior of `registerAnalytics`\n */\ndeclare module '@firebase/app-types' {\n  interface FirebaseNamespace {\n    analytics(app?: FirebaseApp): FirebaseAnalytics;\n  }\n  interface FirebaseApp {\n    analytics(): FirebaseAnalytics;\n  }\n}\n\n/**\n * this is a public static method provided to users that wraps four different checks:\n *\n * 1. check if it's not a browser extension environment.\n * 1. check if cookie is enabled in current browser.\n * 3. check if IndexedDB is supported by the browser environment.\n * 4. check if the current browser context is valid for using IndexedDB.\n *\n */\nasync function isSupported(): Promise<boolean> {\n  if (isBrowserExtension()) {\n    return false;\n  }\n  if (!areCookiesEnabled()) {\n    return false;\n  }\n  if (!isIndexedDBAvailable()) {\n    return false;\n  }\n\n  try {\n    const isDBOpenable: boolean = await validateIndexedDBOpenable();\n    return isDBOpenable;\n  } catch (error) {\n    return false;\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 {\n  FirebaseApp,\n  FirebaseOptions,\n  FirebaseAppConfig\n} from '@firebase/app-types';\nimport {\n  _FirebaseApp,\n  _FirebaseNamespace,\n  FirebaseService\n} from '@firebase/app-types/private';\nimport { deepCopy } from '@firebase/util';\nimport {\n  ComponentContainer,\n  Component,\n  ComponentType,\n  Name\n} from '@firebase/component';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { logger } from './logger';\n\n/**\n * Global context object for a collection of services using\n * a shared authentication state.\n */\nexport class FirebaseAppImpl implements FirebaseApp {\n  private readonly options_: FirebaseOptions;\n  private readonly name_: string;\n  private isDeleted_ = false;\n  private automaticDataCollectionEnabled_: boolean;\n  private container: ComponentContainer;\n\n  constructor(\n    options: FirebaseOptions,\n    config: FirebaseAppConfig,\n    private readonly firebase_: _FirebaseNamespace\n  ) {\n    this.name_ = config.name!;\n    this.automaticDataCollectionEnabled_ =\n      config.automaticDataCollectionEnabled || false;\n    this.options_ = deepCopy<FirebaseOptions>(options);\n    this.container = new ComponentContainer(config.name!);\n\n    // add itself to container\n    this._addComponent(new Component('app', () => this, ComponentType.PUBLIC));\n    // populate ComponentContainer with existing components\n    for (const component of this.firebase_.INTERNAL.components.values()) {\n      this._addComponent(component);\n    }\n  }\n\n  get automaticDataCollectionEnabled(): boolean {\n    this.checkDestroyed_();\n    return this.automaticDataCollectionEnabled_;\n  }\n\n  set automaticDataCollectionEnabled(val) {\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  delete(): Promise<void> {\n    return new Promise(resolve => {\n      this.checkDestroyed_();\n      resolve();\n    })\n      .then(() => {\n        this.firebase_.INTERNAL.removeApp(this.name_);\n\n        return Promise.all(\n          this.container.getProviders().map(provider => provider.delete())\n        );\n      })\n      .then((): void => {\n        this.isDeleted_ = true;\n      });\n  }\n\n  /**\n   * Return a service instance associated with this app (creating it\n   * on demand), identified by the passed instanceIdentifier.\n   *\n   * NOTE: Currently storage and functions are the only ones that are leveraging this\n   * functionality. They invoke it by calling:\n   *\n   * ```javascript\n   * firebase.app().storage('STORAGE BUCKET ID')\n   * ```\n   *\n   * The service name is passed to this already\n   * @internal\n   */\n  _getService(\n    name: string,\n    instanceIdentifier: string = DEFAULT_ENTRY_NAME\n  ): FirebaseService {\n    this.checkDestroyed_();\n\n    // getImmediate will always succeed because _getService is only called for registered components.\n    return (this.container.getProvider(name as Name).getImmediate({\n      identifier: instanceIdentifier\n    }) as unknown) as FirebaseService;\n  }\n  /**\n   * Remove a service instance from the cache, so we will create a new instance for this service\n   * when people try to get this service again.\n   *\n   * NOTE: currently only firestore is using this functionality to support firestore shutdown.\n   *\n   * @param name The service name\n   * @param instanceIdentifier instance identifier in case multiple instances are allowed\n   * @internal\n   */\n  _removeServiceInstance(\n    name: string,\n    instanceIdentifier: string = DEFAULT_ENTRY_NAME\n  ): void {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    this.container.getProvider(name as any).clearInstance(instanceIdentifier);\n  }\n\n  /**\n   * @param component the component being added to this app's container\n   */\n  _addComponent(component: Component): void {\n    try {\n      this.container.addComponent(component);\n    } catch (e) {\n      logger.debug(\n        `Component ${component.name} failed to register with FirebaseApp ${this.name}`,\n        e\n      );\n    }\n  }\n\n  _addOrOverwriteComponent(component: Component): void {\n    this.container.addOrOverwriteComponent(component);\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// Prevent dead-code elimination of these methods w/o invalid property\n// copying.\n(FirebaseAppImpl.prototype.name && FirebaseAppImpl.prototype.options) ||\n  FirebaseAppImpl.prototype.delete ||\n  console.log('dc');\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  FirebaseNamespace,\n  FirebaseAppConfig\n} from '@firebase/app-types';\nimport {\n  _FirebaseApp,\n  _FirebaseNamespace,\n  FirebaseService,\n  FirebaseServiceNamespace\n} from '@firebase/app-types/private';\nimport { deepExtend, contains } from '@firebase/util';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport { FirebaseAppLiteImpl } from './lite/firebaseAppLite';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { version } from '../../firebase/package.json';\nimport { logger } from './logger';\nimport {\n  setUserLogHandler,\n  setLogLevel,\n  LogCallback,\n  LogOptions\n} from '@firebase/logger';\nimport { Component, ComponentType, Name } from '@firebase/component';\n\n/**\n * Because auth can't share code with other components, we attach the utility functions\n * in an internal namespace to share code.\n * This function return a firebase namespace object without\n * any utility functions, so it can be shared between the regular firebaseNamespace and\n * the lite version.\n */\nexport function createFirebaseNamespaceCore(\n  firebaseAppImpl: typeof FirebaseAppImpl | typeof FirebaseAppLiteImpl\n): FirebaseNamespace {\n  const apps: { [name: string]: FirebaseApp } = {};\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const components = new Map<string, Component<any>>();\n\n  // A namespace is a plain JavaScript Object.\n  const namespace: FirebaseNamespace = {\n    // Hack to prevent Babel from modifying the object returned\n    // as the firebase namespace.\n    // @ts-ignore\n    __esModule: true,\n    initializeApp,\n    // @ts-ignore\n    app,\n    registerVersion,\n    setLogLevel,\n    onLog,\n    // @ts-ignore\n    apps: null,\n    SDK_VERSION: version,\n    INTERNAL: {\n      registerComponent,\n      removeApp,\n      components,\n      useAsService\n    }\n  };\n\n  // Inject a circular default export to allow Babel users who were previously\n  // using:\n  //\n  //   import firebase from 'firebase';\n  //   which becomes: var firebase = require('firebase').default;\n  //\n  // instead of\n  //\n  //   import * as firebase from 'firebase';\n  //   which becomes: var firebase = require('firebase');\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  (namespace as any)['default'] = namespace;\n\n  // firebase.apps is a read-only getter.\n  Object.defineProperty(namespace, 'apps', {\n    get: getApps\n  });\n\n  /**\n   * Called by App.delete() - but before any services associated with the App\n   * are deleted.\n   */\n  function removeApp(name: string): void {\n    delete apps[name];\n  }\n\n  /**\n   * Get the App object for a given name (or DEFAULT).\n   */\n  function app(name?: string): FirebaseApp {\n    name = name || DEFAULT_ENTRY_NAME;\n    if (!contains(apps, name)) {\n      throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n    }\n    return apps[name];\n  }\n\n  // @ts-ignore\n  app['App'] = firebaseAppImpl;\n  /**\n   * Create a new App instance (name must be unique).\n   */\n  function initializeApp(\n    options: FirebaseOptions,\n    config?: FirebaseAppConfig\n  ): FirebaseApp;\n  function initializeApp(options: FirebaseOptions, name?: string): FirebaseApp;\n  function initializeApp(\n    options: FirebaseOptions,\n    rawConfig = {}\n  ): FirebaseApp {\n    if (typeof rawConfig !== 'object' || rawConfig === null) {\n      const name = rawConfig;\n      rawConfig = { name };\n    }\n\n    const config = rawConfig as FirebaseAppConfig;\n\n    if (config.name === undefined) {\n      config.name = DEFAULT_ENTRY_NAME;\n    }\n\n    const { name } = config;\n\n    if (typeof name !== 'string' || !name) {\n      throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n        appName: String(name)\n      });\n    }\n\n    if (contains(apps, name)) {\n      throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n    }\n\n    const app = new firebaseAppImpl(\n      options,\n      config,\n      namespace as _FirebaseNamespace\n    );\n\n    apps[name] = app;\n\n    return app;\n  }\n\n  /*\n   * Return an array of all the non-deleted FirebaseApps.\n   */\n  function getApps(): FirebaseApp[] {\n    // Make a copy so caller cannot mutate the apps list.\n    return Object.keys(apps).map(name => apps[name]);\n  }\n\n  function registerComponent(\n    component: Component\n  ): FirebaseServiceNamespace<FirebaseService> | null {\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 component.type === ComponentType.PUBLIC\n        ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          (namespace as any)[componentName]\n        : null;\n    }\n\n    components.set(componentName, component);\n\n    // create service namespace for public components\n    if (component.type === ComponentType.PUBLIC) {\n      // The Service namespace is an accessor function ...\n      const serviceNamespace = (\n        appArg: FirebaseApp = app()\n      ): FirebaseService => {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        if (typeof (appArg as any)[componentName] !== 'function') {\n          // Invalid argument.\n          // This happens in the following case: firebase.storage('gs:/')\n          throw ERROR_FACTORY.create(AppError.INVALID_APP_ARGUMENT, {\n            appName: componentName\n          });\n        }\n\n        // Forward service instance lookup to the FirebaseApp.\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        return (appArg as any)[componentName]();\n      };\n\n      // ... and a container for service-level properties.\n      if (component.serviceProps !== undefined) {\n        deepExtend(serviceNamespace, component.serviceProps);\n      }\n\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (namespace as any)[componentName] = serviceNamespace;\n\n      // Patch the FirebaseAppImpl prototype\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (firebaseAppImpl.prototype as any)[componentName] =\n        // TODO: The eslint disable can be removed and the 'ignoreRestArgs'\n        // option added to the no-explicit-any rule when ESlint releases it.\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        function (...args: any) {\n          const serviceFxn = this._getService.bind(this, componentName);\n          return serviceFxn.apply(\n            this,\n            component.multipleInstances ? args : []\n          );\n        };\n    }\n\n    // add the component to existing app instances\n    for (const appName of Object.keys(apps)) {\n      (apps[appName] as _FirebaseApp)._addComponent(component);\n    }\n\n    return component.type === ComponentType.PUBLIC\n      ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        (namespace as any)[componentName]\n      : null;\n  }\n\n  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  function onLog(logCallback: LogCallback | null, options?: LogOptions): void {\n    if (logCallback !== null && typeof logCallback !== 'function') {\n      throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT, {\n        appName: name\n      });\n    }\n    setUserLogHandler(logCallback, options);\n  }\n\n  // Map the requested service to a registered service name\n  // (used to map auth to serverAuth service when needed).\n  function useAsService(app: FirebaseApp, name: string): string | null {\n    if (name === 'serverAuth') {\n      return null;\n    }\n\n    const useService = name;\n\n    return useService;\n  }\n\n  return namespace;\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 { FirebaseNamespace } from '@firebase/app-types';\nimport { _FirebaseApp, _FirebaseNamespace } from '@firebase/app-types/private';\nimport { createSubscribe, deepExtend, ErrorFactory } from '@firebase/util';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { createFirebaseNamespaceCore } from './firebaseNamespaceCore';\n\n/**\n * Return a firebase namespace object.\n *\n * In production, this will be called exactly once and the result\n * assigned to the 'firebase' global.  It may be called multiple times\n * in unit tests.\n */\nexport function createFirebaseNamespace(): FirebaseNamespace {\n  const namespace = createFirebaseNamespaceCore(FirebaseAppImpl);\n  (namespace as _FirebaseNamespace).INTERNAL = {\n    ...(namespace as _FirebaseNamespace).INTERNAL,\n    createFirebaseNamespace,\n    extendNamespace,\n    createSubscribe,\n    ErrorFactory,\n    deepExtend\n  };\n\n  /**\n   * Patch the top-level firebase namespace with additional properties.\n   *\n   * firebase.INTERNAL.extendNamespace()\n   */\n  function extendNamespace(props: { [prop: string]: unknown }): void {\n    deepExtend(namespace, props);\n  }\n\n  return namespace;\n}\n\nexport const firebase = createFirebaseNamespace();\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';\n\nexport class 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();\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(\n  provider: Provider<Name>\n): provider is Provider<'app-version'> {\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 { FirebaseNamespace } from '@firebase/app-types';\nimport { _FirebaseNamespace } from '@firebase/app-types/private';\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerService } from './platformLoggerService';\nimport { name, version } from '../package.json';\n\nexport function registerCoreComponents(\n  firebase: FirebaseNamespace,\n  variant?: string\n): void {\n  (firebase as _FirebaseNamespace).INTERNAL.registerComponent(\n    new Component(\n      'platform-logger',\n      container => new PlatformLoggerService(container),\n      ComponentType.PRIVATE\n    )\n  );\n  // Register `app` package.\n  firebase.registerVersion(name, version, variant);\n  // Register platform SDK identifier (no version).\n  firebase.registerVersion('fire-js', '');\n}\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Bootstrap for the Google JS Library (Closure).\n *\n * In uncompiled mode base.js will attempt to load Closure's deps file, unless\n * the global <code>CLOSURE_NO_DEPS</code> is set to true.  This allows projects\n * to include their own deps file(s) from different locations.\n *\n * Avoid including base.js more than once. This is strictly discouraged and not\n * supported. goog.require(...) won't work properly in that case.\n *\n * @provideGoog\n */\n\n\n/**\n * @define {boolean} Overridden to true by the compiler.\n */\nvar COMPILED = false;\n\n\n/**\n * Base namespace for the Closure library.  Checks to see goog is already\n * defined in the current scope before assigning to prevent clobbering if\n * base.js is loaded more than once.\n *\n * @const\n */\nvar goog = goog || {};\n\n/**\n * Reference to the global object.\n * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object\n *\n * More info on this implementation here:\n * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit\n *\n * @const\n * @suppress {undefinedVars} self won't be referenced unless `this` is falsy.\n * @type {!Global}\n */\ngoog.global =\n    // Check `this` first for backwards compatibility.\n    // Valid unless running as an ES module or in a function wrapper called\n    //   without setting `this` properly.\n    // Note that base.js can't usefully be imported as an ES module, but it may\n    // be compiled into bundles that are loadable as ES modules.\n    this ||\n    // https://developer.mozilla.org/en-US/docs/Web/API/Window/self\n    // For in-page browser environments and workers.\n    self;\n\n\n/**\n * A hook for overriding the define values in uncompiled mode.\n *\n * In uncompiled mode, `CLOSURE_UNCOMPILED_DEFINES` may be defined before\n * loading base.js.  If a key is defined in `CLOSURE_UNCOMPILED_DEFINES`,\n * `goog.define` will use the value instead of the default value.  This\n * allows flags to be overwritten without compilation (this is normally\n * accomplished with the compiler's \"define\" flag).\n *\n * Example:\n * <pre>\n *   var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};\n * </pre>\n *\n * @type {Object<string, (string|number|boolean)>|undefined}\n */\ngoog.global.CLOSURE_UNCOMPILED_DEFINES;\n\n\n/**\n * A hook for overriding the define values in uncompiled or compiled mode,\n * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code.  In\n * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.\n *\n * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or\n * string literals or the compiler will emit an error.\n *\n * While any @define value may be set, only those set with goog.define will be\n * effective for uncompiled code.\n *\n * Example:\n * <pre>\n *   var CLOSURE_DEFINES = {'goog.DEBUG': false} ;\n * </pre>\n *\n * @type {Object<string, (string|number|boolean)>|undefined}\n */\ngoog.global.CLOSURE_DEFINES;\n\n\n/**\n * Builds an object structure for the provided namespace path, ensuring that\n * names that already exist are not overwritten. For example:\n * \"a.b.c\" -> a = {};a.b={};a.b.c={};\n * Used by goog.provide and goog.exportSymbol.\n * @param {string} name name of the object that this file defines.\n * @param {*=} opt_object the object to expose at the end of the path.\n * @param {Object=} opt_objectToExportTo The object to add the path to; default\n *     is `goog.global`.\n * @private\n */\ngoog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {\n  var parts = name.split('.');\n  var cur = opt_objectToExportTo || goog.global;\n\n  // Internet Explorer exhibits strange behavior when throwing errors from\n  // methods externed in this manner.  See the testExportSymbolExceptions in\n  // base_test.html for an example.\n  if (!(parts[0] in cur) && typeof cur.execScript != 'undefined') {\n    cur.execScript('var ' + parts[0]);\n  }\n\n  for (var part; parts.length && (part = parts.shift());) {\n    if (!parts.length && opt_object !== undefined) {\n      // last part and we have an object; use it\n      cur[part] = opt_object;\n    } else if (cur[part] && cur[part] !== Object.prototype[part]) {\n      cur = cur[part];\n    } else {\n      cur = cur[part] = {};\n    }\n  }\n};\n\n\n/**\n * Defines a named value. In uncompiled mode, the value is retrieved from\n * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and\n * has the property specified, and otherwise used the defined defaultValue.\n * When compiled the default can be overridden using the compiler options or the\n * value set in the CLOSURE_DEFINES object. Returns the defined value so that it\n * can be used safely in modules. Note that the value type MUST be either\n * boolean, number, or string.\n *\n * @param {string} name The distinguished name to provide.\n * @param {T} defaultValue\n * @return {T} The defined value.\n * @template T\n */\ngoog.define = function(name, defaultValue) {\n  var value = defaultValue;\n  if (!COMPILED) {\n    var uncompiledDefines = goog.global.CLOSURE_UNCOMPILED_DEFINES;\n    var defines = goog.global.CLOSURE_DEFINES;\n    if (uncompiledDefines &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        /** @type {?} */ (uncompiledDefines).nodeType === undefined &&\n        Object.prototype.hasOwnProperty.call(uncompiledDefines, name)) {\n      value = uncompiledDefines[name];\n    } else if (\n        defines &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        /** @type {?} */ (defines).nodeType === undefined &&\n        Object.prototype.hasOwnProperty.call(defines, name)) {\n      value = defines[name];\n    }\n  }\n  return value;\n};\n\n\n/**\n * @define {number} Integer year indicating the set of browser features that are\n * guaranteed to be present.  This is defined to include exactly features that\n * work correctly on all \"modern\" browsers that are stable on January 1 of the\n * specified year.  For example,\n * ```js\n * if (goog.FEATURESET_YEAR >= 2019) {\n *   // use APIs known to be available on all major stable browsers Jan 1, 2019\n * } else {\n *   // polyfill for older browsers\n * }\n * ```\n * This is intended to be the primary define for removing\n * unnecessary browser compatibility code (such as ponyfills and workarounds),\n * and should inform the default value for most other defines:\n * ```js\n * const ASSUME_NATIVE_PROMISE =\n *     goog.define('ASSUME_NATIVE_PROMISE', goog.FEATURESET_YEAR >= 2016);\n * ```\n *\n * The default assumption is that IE9 is the lowest supported browser, which was\n * first available Jan 1, 2012.\n *\n * TODO(user): Reference more thorough documentation when it's available.\n */\ngoog.FEATURESET_YEAR = goog.define('goog.FEATURESET_YEAR', 2012);\n\n\n/**\n * @define {boolean} DEBUG is provided as a convenience so that debugging code\n * that should not be included in a production. It can be easily stripped\n * by specifying --define goog.DEBUG=false to the Closure Compiler aka\n * JSCompiler. For example, most toString() methods should be declared inside an\n * \"if (goog.DEBUG)\" conditional because they are generally used for debugging\n * purposes and it is difficult for the JSCompiler to statically determine\n * whether they are used.\n */\ngoog.DEBUG = goog.define('goog.DEBUG', true);\n\n\n/**\n * @define {string} LOCALE defines the locale being used for compilation. It is\n * used to select locale specific data to be compiled in js binary. BUILD rule\n * can specify this value by \"--define goog.LOCALE=<locale_name>\" as a compiler\n * option.\n *\n * Take into account that the locale code format is important. You should use\n * the canonical Unicode format with hyphen as a delimiter. Language must be\n * lowercase, Language Script - Capitalized, Region - UPPERCASE.\n * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.\n *\n * See more info about locale codes here:\n * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers\n *\n * For language codes you should use values defined by ISO 693-1. See it here\n * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from\n * this rule: the Hebrew language. For legacy reasons the old code (iw) should\n * be used instead of the new code (he).\n *\n */\ngoog.LOCALE = goog.define('goog.LOCALE', 'en');  // default to en\n\n\n/**\n * @define {boolean} Whether this code is running on trusted sites.\n *\n * On untrusted sites, several native functions can be defined or overridden by\n * external libraries like Prototype, Datejs, and JQuery and setting this flag\n * to false forces closure to use its own implementations when possible.\n *\n * If your JavaScript can be loaded by a third party site and you are wary about\n * relying on non-standard implementations, specify\n * \"--define goog.TRUSTED_SITE=false\" to the compiler.\n */\ngoog.TRUSTED_SITE = goog.define('goog.TRUSTED_SITE', true);\n\n\n/**\n * @define {boolean} Whether a project is expected to be running in strict mode.\n *\n * This define can be used to trigger alternate implementations compatible with\n * running in EcmaScript Strict mode or warn about unavailable functionality.\n * @see https://goo.gl/PudQ4y\n *\n */\ngoog.STRICT_MODE_COMPATIBLE = goog.define('goog.STRICT_MODE_COMPATIBLE', false);\n\n\n/**\n * @define {boolean} Whether code that calls {@link goog.setTestOnly} should\n *     be disallowed in the compilation unit.\n */\ngoog.DISALLOW_TEST_ONLY_CODE =\n    goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);\n\n\n/**\n * @define {boolean} Whether to use a Chrome app CSP-compliant method for\n *     loading scripts via goog.require. @see appendScriptSrcNode_.\n */\ngoog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING =\n    goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);\n\n\n/**\n * Defines a namespace in Closure.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * The presence of one or more goog.provide() calls in a file indicates\n * that the file defines the given objects/namespaces.\n * Provided symbols must not be null or undefined.\n *\n * In addition, goog.provide() creates the object stubs for a namespace\n * (for example, goog.provide(\"goog.foo.bar\") will create the object\n * goog.foo.bar if it does not already exist).\n *\n * Build tools also scan for provide/require/module statements\n * to discern dependencies, build dependency files (see deps.js), etc.\n *\n * @see goog.require\n * @see goog.module\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\".\n */\ngoog.provide = function(name) {\n  if (goog.isInModuleLoader_()) {\n    throw new Error('goog.provide cannot be used within a module.');\n  }\n  if (!COMPILED) {\n    // Ensure that the same namespace isn't provided twice.\n    // A goog.module/goog.provide maps a goog.require to a specific file\n    if (goog.isProvided_(name)) {\n      throw new Error('Namespace \"' + name + '\" already declared.');\n    }\n  }\n\n  goog.constructNamespace_(name);\n};\n\n\n/**\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\".\n * @param {Object=} opt_obj The object to embed in the namespace.\n * @private\n */\ngoog.constructNamespace_ = function(name, opt_obj) {\n  if (!COMPILED) {\n    delete goog.implicitNamespaces_[name];\n\n    var namespace = name;\n    while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {\n      if (goog.getObjectByName(namespace)) {\n        break;\n      }\n      goog.implicitNamespaces_[namespace] = true;\n    }\n  }\n\n  goog.exportPath_(name, opt_obj);\n};\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {?Window=} opt_window The window context used to retrieve the nonce.\n *     Defaults to global context.\n * @return {string} CSP nonce or empty string if no nonce is present.\n */\ngoog.getScriptNonce = function(opt_window) {\n  if (opt_window && opt_window != goog.global) {\n    return goog.getScriptNonce_(opt_window.document);\n  }\n  if (goog.cspNonce_ === null) {\n    goog.cspNonce_ = goog.getScriptNonce_(goog.global.document);\n  }\n  return goog.cspNonce_;\n};\n\n\n/**\n * According to the CSP3 spec a nonce must be a valid base64 string.\n * @see https://www.w3.org/TR/CSP3/#grammardef-base64-value\n * @private @const\n */\ngoog.NONCE_PATTERN_ = /^[\\w+/_-]+[=]{0,2}$/;\n\n\n/**\n * @private {?string}\n */\ngoog.cspNonce_ = null;\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {!Document} doc\n * @return {string} CSP nonce or empty string if no nonce is present.\n * @private\n */\ngoog.getScriptNonce_ = function(doc) {\n  var script = doc.querySelector && doc.querySelector('script[nonce]');\n  if (script) {\n    // Try to get the nonce from the IDL property first, because browsers that\n    // implement additional nonce protection features (currently only Chrome) to\n    // prevent nonce stealing via CSS do not expose the nonce via attributes.\n    // See https://github.com/whatwg/html/issues/2369\n    var nonce = script['nonce'] || script.getAttribute('nonce');\n    if (nonce && goog.NONCE_PATTERN_.test(nonce)) {\n      return nonce;\n    }\n  }\n  return '';\n};\n\n\n/**\n * Module identifier validation regexp.\n * Note: This is a conservative check, it is very possible to be more lenient,\n *   the primary exclusion here is \"/\" and \"\\\" and a leading \".\", these\n *   restrictions are intended to leave the door open for using goog.require\n *   with relative file paths rather than module identifiers.\n * @private\n */\ngoog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\n\n\n/**\n * Defines a module in Closure.\n *\n * Marks that this file must be loaded as a module and claims the namespace.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * goog.module() has three requirements:\n * - goog.module may not be used in the same file as goog.provide.\n * - goog.module must be the first statement in the file.\n * - only one goog.module is allowed per file.\n *\n * When a goog.module annotated file is loaded, it is enclosed in\n * a strict function closure. This means that:\n * - any variables declared in a goog.module file are private to the file\n * (not global), though the compiler is expected to inline the module.\n * - The code must obey all the rules of \"strict\" JavaScript.\n * - the file will be marked as \"use strict\"\n *\n * NOTE: unlike goog.provide, goog.module does not declare any symbols by\n * itself. If declared symbols are desired, use\n * goog.module.declareLegacyNamespace().\n *\n *\n * See the public goog.module proposal: http://goo.gl/Va1hin\n *\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\", is expected but not required.\n * @return {void}\n */\ngoog.module = function(name) {\n  if (typeof name !== 'string' || !name ||\n      name.search(goog.VALID_MODULE_RE_) == -1) {\n    throw new Error('Invalid module identifier');\n  }\n  if (!goog.isInGoogModuleLoader_()) {\n    throw new Error(\n        'Module ' + name + ' has been loaded incorrectly. Note, ' +\n        'modules cannot be loaded as normal scripts. They require some kind of ' +\n        'pre-processing step. You\\'re likely trying to load a module via a ' +\n        'script tag or as a part of a concatenated bundle without rewriting the ' +\n        'module. For more info see: ' +\n        'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.');\n  }\n  if (goog.moduleLoaderState_.moduleName) {\n    throw new Error('goog.module may only be called once per module.');\n  }\n\n  // Store the module name for the loader.\n  goog.moduleLoaderState_.moduleName = name;\n  if (!COMPILED) {\n    // Ensure that the same namespace isn't provided twice.\n    // A goog.module/goog.provide maps a goog.require to a specific file\n    if (goog.isProvided_(name)) {\n      throw new Error('Namespace \"' + name + '\" already declared.');\n    }\n    delete goog.implicitNamespaces_[name];\n  }\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n *\n * Note: This is not an alternative to goog.require, it does not\n * indicate a hard dependency, instead it is used to indicate\n * an optional dependency or to access the exports of a module\n * that has already been loaded.\n * @suppress {missingProvide}\n */\ngoog.module.get = function(name) {\n  return goog.module.getInternal_(name);\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n * @private\n */\ngoog.module.getInternal_ = function(name) {\n  if (!COMPILED) {\n    if (name in goog.loadedModules_) {\n      return goog.loadedModules_[name].exports;\n    } else if (!goog.implicitNamespaces_[name]) {\n      var ns = goog.getObjectByName(name);\n      return ns != null ? ns : null;\n    }\n  }\n  return null;\n};\n\n\n/**\n * Types of modules the debug loader can load.\n * @enum {string}\n */\ngoog.ModuleType = {\n  ES6: 'es6',\n  GOOG: 'goog'\n};\n\n\n/**\n * @private {?{\n *   moduleName: (string|undefined),\n *   declareLegacyNamespace:boolean,\n *   type: ?goog.ModuleType\n * }}\n */\ngoog.moduleLoaderState_ = null;\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module or an es6 module is currently being\n *     initialized.\n */\ngoog.isInModuleLoader_ = function() {\n  return goog.isInGoogModuleLoader_() || goog.isInEs6ModuleLoader_();\n};\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module is currently being initialized.\n */\ngoog.isInGoogModuleLoader_ = function() {\n  return !!goog.moduleLoaderState_ &&\n      goog.moduleLoaderState_.type == goog.ModuleType.GOOG;\n};\n\n\n/**\n * @private\n * @return {boolean} Whether an es6 module is currently being initialized.\n */\ngoog.isInEs6ModuleLoader_ = function() {\n  var inLoader = !!goog.moduleLoaderState_ &&\n      goog.moduleLoaderState_.type == goog.ModuleType.ES6;\n\n  if (inLoader) {\n    return true;\n  }\n\n  var jscomp = goog.global['$jscomp'];\n\n  if (jscomp) {\n    // jscomp may not have getCurrentModulePath if this is a compiled bundle\n    // that has some of the runtime, but not all of it. This can happen if\n    // optimizations are turned on so the unused runtime is removed but renaming\n    // and Closure pass are off (so $jscomp is still named $jscomp and the\n    // goog.provide/require calls still exist).\n    if (typeof jscomp.getCurrentModulePath != 'function') {\n      return false;\n    }\n\n    // Bundled ES6 module.\n    return !!jscomp.getCurrentModulePath();\n  }\n\n  return false;\n};\n\n\n/**\n * Provide the module's exports as a globally accessible object under the\n * module's declared name.  This is intended to ease migration to goog.module\n * for files that have existing usages.\n * @suppress {missingProvide}\n */\ngoog.module.declareLegacyNamespace = function() {\n  if (!COMPILED && !goog.isInGoogModuleLoader_()) {\n    throw new Error(\n        'goog.module.declareLegacyNamespace must be called from ' +\n        'within a goog.module');\n  }\n  if (!COMPILED && !goog.moduleLoaderState_.moduleName) {\n    throw new Error(\n        'goog.module must be called prior to ' +\n        'goog.module.declareLegacyNamespace.');\n  }\n  goog.moduleLoaderState_.declareLegacyNamespace = true;\n};\n\n\n/**\n * Associates an ES6 module with a Closure module ID so that is available via\n * goog.require. The associated ID  acts like a goog.module ID - it does not\n * create any global names, it is merely available via goog.require /\n * goog.module.get / goog.forwardDeclare / goog.requireType. goog.require and\n * goog.module.get will return the entire module as if it was import *'d. This\n * allows Closure files to reference ES6 modules for the sake of migration.\n *\n * @param {string} namespace\n * @suppress {missingProvide}\n */\ngoog.declareModuleId = function(namespace) {\n  if (!COMPILED) {\n    if (!goog.isInEs6ModuleLoader_()) {\n      throw new Error(\n          'goog.declareModuleId may only be called from ' +\n          'within an ES6 module');\n    }\n    if (goog.moduleLoaderState_ && goog.moduleLoaderState_.moduleName) {\n      throw new Error(\n          'goog.declareModuleId may only be called once per module.');\n    }\n    if (namespace in goog.loadedModules_) {\n      throw new Error(\n          'Module with namespace \"' + namespace + '\" already exists.');\n    }\n  }\n  if (goog.moduleLoaderState_) {\n    // Not bundled - debug loading.\n    goog.moduleLoaderState_.moduleName = namespace;\n  } else {\n    // Bundled - not debug loading, no module loader state.\n    var jscomp = goog.global['$jscomp'];\n    if (!jscomp || typeof jscomp.getCurrentModulePath != 'function') {\n      throw new Error(\n          'Module with namespace \"' + namespace +\n          '\" has been loaded incorrectly.');\n    }\n    var exports = jscomp.require(jscomp.getCurrentModulePath());\n    goog.loadedModules_[namespace] = {\n      exports: exports,\n      type: goog.ModuleType.ES6,\n      moduleId: namespace\n    };\n  }\n};\n\n\n/**\n * Marks that the current file should only be used for testing, and never for\n * live code in production.\n *\n * In the case of unit tests, the message may optionally be an exact namespace\n * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra\n * provide (if not explicitly defined in the code).\n *\n * @param {string=} opt_message Optional message to add to the error that's\n *     raised when used in production code.\n */\ngoog.setTestOnly = function(opt_message) {\n  if (goog.DISALLOW_TEST_ONLY_CODE) {\n    opt_message = opt_message || '';\n    throw new Error(\n        'Importing test-only code into non-debug environment' +\n        (opt_message ? ': ' + opt_message : '.'));\n  }\n};\n\n\n/**\n * Forward declares a symbol. This is an indication to the compiler that the\n * symbol may be used in the source yet is not required and may not be provided\n * in compilation.\n *\n * The most common usage of forward declaration is code that takes a type as a\n * function parameter but does not need to require it. By forward declaring\n * instead of requiring, no hard dependency is made, and (if not required\n * elsewhere) the namespace may never be required and thus, not be pulled\n * into the JavaScript binary. If it is required elsewhere, it will be type\n * checked as normal.\n *\n * Before using goog.forwardDeclare, please read the documentation at\n * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to\n * understand the options and tradeoffs when working with forward declarations.\n *\n * @param {string} name The namespace to forward declare in the form of\n *     \"goog.package.part\".\n * @deprecated See go/noforwarddeclaration, Use `goog.requireType` instead.\n */\ngoog.forwardDeclare = function(name) {};\n\n\n/**\n * Forward declare type information. Used to assign types to goog.global\n * referenced object that would otherwise result in unknown type references\n * and thus block property disambiguation.\n */\ngoog.forwardDeclare('Document');\ngoog.forwardDeclare('HTMLScriptElement');\ngoog.forwardDeclare('XMLHttpRequest');\n\n\nif (!COMPILED) {\n  /**\n   * Check if the given name has been goog.provided. This will return false for\n   * names that are available only as implicit namespaces.\n   * @param {string} name name of the object to look for.\n   * @return {boolean} Whether the name has been provided.\n   * @private\n   */\n  goog.isProvided_ = function(name) {\n    return (name in goog.loadedModules_) ||\n        (!goog.implicitNamespaces_[name] && goog.getObjectByName(name) != null);\n  };\n\n  /**\n   * Namespaces implicitly defined by goog.provide. For example,\n   * goog.provide('goog.events.Event') implicitly declares that 'goog' and\n   * 'goog.events' must be namespaces.\n   *\n   * @type {!Object<string, (boolean|undefined)>}\n   * @private\n   */\n  goog.implicitNamespaces_ = {'goog.module': true};\n\n  // NOTE: We add goog.module as an implicit namespace as goog.module is defined\n  // here and because the existing module package has not been moved yet out of\n  // the goog.module namespace. This satisifies both the debug loader and\n  // ahead-of-time dependency management.\n}\n\n\n/**\n * Returns an object based on its fully qualified external name.  The object\n * is not found if null or undefined.  If you are using a compilation pass that\n * renames property names beware that using this function will not find renamed\n * properties.\n *\n * @param {string} name The fully qualified name.\n * @param {Object=} opt_obj The object within which to look; default is\n *     |goog.global|.\n * @return {?} The value (object or primitive) or, if not found, null.\n */\ngoog.getObjectByName = function(name, opt_obj) {\n  var parts = name.split('.');\n  var cur = opt_obj || goog.global;\n  for (var i = 0; i < parts.length; i++) {\n    cur = cur[parts[i]];\n    if (cur == null) {\n      return null;\n    }\n  }\n  return cur;\n};\n\n\n/**\n * Globalizes a whole namespace, such as goog or goog.lang.\n *\n * @param {!Object} obj The namespace to globalize.\n * @param {Object=} opt_global The object to add the properties to.\n * @deprecated Properties may be explicitly exported to the global scope, but\n *     this should no longer be done in bulk.\n */\ngoog.globalize = function(obj, opt_global) {\n  var global = opt_global || goog.global;\n  for (var x in obj) {\n    global[x] = obj[x];\n  }\n};\n\n\n/**\n * Adds a dependency from a file to the files it requires.\n * @param {string} relPath The path to the js file.\n * @param {!Array<string>} provides An array of strings with\n *     the names of the objects this file provides.\n * @param {!Array<string>} requires An array of strings with\n *     the names of the objects this file requires.\n * @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating\n *     how the file must be loaded.  The boolean 'true' is equivalent\n *     to {'module': 'goog'} for backwards-compatibility.  Valid properties\n *     and values include {'module': 'goog'} and {'lang': 'es6'}.\n */\ngoog.addDependency = function(relPath, provides, requires, opt_loadFlags) {\n  if (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n    goog.debugLoader_.addDependency(relPath, provides, requires, opt_loadFlags);\n  }\n};\n\n\n// NOTE(nnaze): The debug DOM loader was included in base.js as an original way\n// to do \"debug-mode\" development.  The dependency system can sometimes be\n// confusing, as can the debug DOM loader's asynchronous nature.\n//\n// With the DOM loader, a call to goog.require() is not blocking -- the script\n// will not load until some point after the current script.  If a namespace is\n// needed at runtime, it needs to be defined in a previous script, or loaded via\n// require() with its registered dependencies.\n//\n// User-defined namespaces may need their own deps file. For a reference on\n// creating a deps file, see:\n// Externally: https://developers.google.com/closure/library/docs/depswriter\n//\n// Because of legacy clients, the DOM loader can't be easily removed from\n// base.js.  Work was done to make it disableable or replaceable for\n// different environments (DOM-less JavaScript interpreters like Rhino or V8,\n// for example). See bootstrap/ for more information.\n\n\n/**\n * @define {boolean} Whether to enable the debug loader.\n *\n * If enabled, a call to goog.require() will attempt to load the namespace by\n * appending a script tag to the DOM (if the namespace has been registered).\n *\n * If disabled, goog.require() will simply assert that the namespace has been\n * provided (and depend on the fact that some outside tool correctly ordered\n * the script).\n */\ngoog.ENABLE_DEBUG_LOADER = goog.define('goog.ENABLE_DEBUG_LOADER', true);\n\n\n/**\n * @param {string} msg\n * @private\n */\ngoog.logToConsole_ = function(msg) {\n  if (goog.global.console) {\n    goog.global.console['error'](msg);\n  }\n};\n\n\n/**\n * Implements a system for the dynamic resolution of dependencies that works in\n * parallel with the BUILD system.\n *\n * Note that all calls to goog.require will be stripped by the compiler.\n *\n * @see goog.provide\n * @param {string} namespace Namespace (as was given in goog.provide,\n *     goog.module, or goog.declareModuleId) in the form\n *     \"goog.package.part\".\n * @return {?} If called within a goog.module or ES6 module file, the associated\n *     namespace or module otherwise null.\n */\ngoog.require = function(namespace) {\n  if (!COMPILED) {\n    // Might need to lazy load on old IE.\n    if (goog.ENABLE_DEBUG_LOADER) {\n      goog.debugLoader_.requested(namespace);\n    }\n\n    // If the object already exists we do not need to do anything.\n    if (goog.isProvided_(namespace)) {\n      if (goog.isInModuleLoader_()) {\n        return goog.module.getInternal_(namespace);\n      }\n    } else if (goog.ENABLE_DEBUG_LOADER) {\n      var moduleLoaderState = goog.moduleLoaderState_;\n      goog.moduleLoaderState_ = null;\n      try {\n        goog.debugLoader_.load_(namespace);\n      } finally {\n        goog.moduleLoaderState_ = moduleLoaderState;\n      }\n    }\n\n    return null;\n  }\n};\n\n\n/**\n * Requires a symbol for its type information. This is an indication to the\n * compiler that the symbol may appear in type annotations, yet it is not\n * referenced at runtime.\n *\n * When called within a goog.module or ES6 module file, the return value may be\n * assigned to or destructured into a variable, but it may not be otherwise used\n * in code outside of a type annotation.\n *\n * Note that all calls to goog.requireType will be stripped by the compiler.\n *\n * @param {string} namespace Namespace (as was given in goog.provide,\n *     goog.module, or goog.declareModuleId) in the form\n *     \"goog.package.part\".\n * @return {?}\n */\ngoog.requireType = function(namespace) {\n  // Return an empty object so that single-level destructuring of the return\n  // value doesn't crash at runtime when using the debug loader. Multi-level\n  // destructuring isn't supported.\n  return {};\n};\n\n\n/**\n * Path for included scripts.\n * @type {string}\n */\ngoog.basePath = '';\n\n\n/**\n * A hook for overriding the base path.\n * @type {string|undefined}\n */\ngoog.global.CLOSURE_BASE_PATH;\n\n\n/**\n * Whether to attempt to load Closure's deps file. By default, when uncompiled,\n * deps files will attempt to be loaded.\n * @type {boolean|undefined}\n */\ngoog.global.CLOSURE_NO_DEPS;\n\n\n/**\n * A function to import a single script. This is meant to be overridden when\n * Closure is being run in non-HTML contexts, such as web workers. It's defined\n * in the global scope so that it can be set before base.js is loaded, which\n * allows deps.js to be imported properly.\n *\n * The first parameter the script source, which is a relative URI. The second,\n * optional parameter is the script contents, in the event the script needed\n * transformation. It should return true if the script was imported, false\n * otherwise.\n * @type {(function(string, string=): boolean)|undefined}\n */\ngoog.global.CLOSURE_IMPORT_SCRIPT;\n\n\n/**\n * Null function used for default values of callbacks, etc.\n * @return {void} Nothing.\n */\ngoog.nullFunction = function() {};\n\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = goog.abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @deprecated Use \"@abstract\" annotation instead of goog.abstractMethod in new\n *     code. See\n *     https://github.com/google/closure-compiler/wiki/@abstract-classes-and-methods\n */\ngoog.abstractMethod = function() {\n  throw new Error('unimplemented abstract method');\n};\n\n\n/**\n * Adds a `getInstance` static method that always returns the same\n * instance object.\n * @param {!Function} ctor The constructor for the class to add the static\n *     method to.\n * @suppress {missingProperties} 'instance_' isn't a property on 'Function'\n *     but we don't have a better type to use here.\n */\ngoog.addSingletonGetter = function(ctor) {\n  // instance_ is immediately set to prevent issues with sealed constructors\n  // such as are encountered when a constructor is returned as the export object\n  // of a goog.module in unoptimized code.\n  // Delcare type to avoid conformance violations that ctor.instance_ is unknown\n  /** @type {undefined|!Object} @suppress {underscore} */\n  ctor.instance_ = undefined;\n  ctor.getInstance = function() {\n    if (ctor.instance_) {\n      return ctor.instance_;\n    }\n    if (goog.DEBUG) {\n      // NOTE: JSCompiler can't optimize away Array#push.\n      goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;\n    }\n    // Cast to avoid conformance violations that ctor.instance_ is unknown\n    return /** @type {!Object|undefined} */ (ctor.instance_) = new ctor;\n  };\n};\n\n\n/**\n * All singleton classes that have been instantiated, for testing. Don't read\n * it directly, use the `goog.testing.singleton` module. The compiler\n * removes this variable if unused.\n * @type {!Array<!Function>}\n * @private\n */\ngoog.instantiatedSingletons_ = [];\n\n\n/**\n * @define {boolean} Whether to load goog.modules using `eval` when using\n * the debug loader.  This provides a better debugging experience as the\n * source is unmodified and can be edited using Chrome Workspaces or similar.\n * However in some environments the use of `eval` is banned\n * so we provide an alternative.\n */\ngoog.LOAD_MODULE_USING_EVAL = goog.define('goog.LOAD_MODULE_USING_EVAL', true);\n\n\n/**\n * @define {boolean} Whether the exports of goog.modules should be sealed when\n * possible.\n */\ngoog.SEAL_MODULE_EXPORTS = goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);\n\n\n/**\n * The registry of initialized modules:\n * The module identifier or path to module exports map.\n * @private @const {!Object<string, {exports:?,type:string,moduleId:string}>}\n */\ngoog.loadedModules_ = {};\n\n\n/**\n * True if the debug loader enabled and used.\n * @const {boolean}\n */\ngoog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;\n\n\n/**\n * @define {string} How to decide whether to transpile.  Valid values\n * are 'always', 'never', and 'detect'.  The default ('detect') is to\n * use feature detection to determine which language levels need\n * transpilation.\n */\n// NOTE(sdh): we could expand this to accept a language level to bypass\n// detection: e.g. goog.TRANSPILE == 'es5' would transpile ES6 files but\n// would leave ES3 and ES5 files alone.\ngoog.TRANSPILE = goog.define('goog.TRANSPILE', 'detect');\n\n/**\n * @define {boolean} If true assume that ES modules have already been\n * transpiled by the jscompiler (in the same way that transpile.js would\n * transpile them - to jscomp modules). Useful only for servers that wish to use\n * the debug loader and transpile server side. Thus this is only respected if\n * goog.TRANSPILE is \"never\".\n */\ngoog.ASSUME_ES_MODULES_TRANSPILED =\n    goog.define('goog.ASSUME_ES_MODULES_TRANSPILED', false);\n\n\n/**\n * @define {string} If a file needs to be transpiled what the output language\n * should be. By default this is the highest language level this file detects\n * the current environment supports. Generally this flag should not be set, but\n * it could be useful to override. Example: If the current environment supports\n * ES6 then by default ES7+ files will be transpiled to ES6, unless this is\n * overridden.\n *\n * Valid values include: es3, es5, es6, es7, and es8. Anything not recognized\n * is treated as es3.\n *\n * Note that setting this value does not force transpilation. Just if\n * transpilation occurs this will be the output. So this is most useful when\n * goog.TRANSPILE is set to 'always' and then forcing the language level to be\n * something lower than what the environment detects.\n */\ngoog.TRANSPILE_TO_LANGUAGE = goog.define('goog.TRANSPILE_TO_LANGUAGE', '');\n\n\n/**\n * @define {string} Path to the transpiler.  Executing the script at this\n * path (relative to base.js) should define a function $jscomp.transpile.\n */\ngoog.TRANSPILER = goog.define('goog.TRANSPILER', 'transpile.js');\n\n\n/**\n * @package {?boolean}\n * Visible for testing.\n */\ngoog.hasBadLetScoping = null;\n\n\n/**\n * @return {boolean}\n * @package Visible for testing.\n */\ngoog.useSafari10Workaround = function() {\n  if (goog.hasBadLetScoping == null) {\n    var hasBadLetScoping;\n    try {\n      hasBadLetScoping = !eval(\n          '\"use strict\";' +\n          'let x = 1; function f() { return typeof x; };' +\n          'f() == \"number\";');\n    } catch (e) {\n      // Assume that ES6 syntax isn't supported.\n      hasBadLetScoping = false;\n    }\n    goog.hasBadLetScoping = hasBadLetScoping;\n  }\n  return goog.hasBadLetScoping;\n};\n\n\n/**\n * @param {string} moduleDef\n * @return {string}\n * @package Visible for testing.\n */\ngoog.workaroundSafari10EvalBug = function(moduleDef) {\n  return '(function(){' + moduleDef +\n      '\\n' +  // Terminate any trailing single line comment.\n      ';' +   // Terminate any trailing expression.\n      '})();\\n';\n};\n\n\n/**\n * @param {function(?):?|string} moduleDef The module definition.\n */\ngoog.loadModule = function(moduleDef) {\n  // NOTE: we allow function definitions to be either in the from\n  // of a string to eval (which keeps the original source intact) or\n  // in a eval forbidden environment (CSP) we allow a function definition\n  // which in its body must call `goog.module`, and return the exports\n  // of the module.\n  var previousState = goog.moduleLoaderState_;\n  try {\n    goog.moduleLoaderState_ = {\n      moduleName: '',\n      declareLegacyNamespace: false,\n      type: goog.ModuleType.GOOG\n    };\n    var exports;\n    if (goog.isFunction(moduleDef)) {\n      exports = moduleDef.call(undefined, {});\n    } else if (typeof moduleDef === 'string') {\n      if (goog.useSafari10Workaround()) {\n        moduleDef = goog.workaroundSafari10EvalBug(moduleDef);\n      }\n\n      exports = goog.loadModuleFromSource_.call(undefined, moduleDef);\n    } else {\n      throw new Error('Invalid module definition');\n    }\n\n    var moduleName = goog.moduleLoaderState_.moduleName;\n    if (typeof moduleName === 'string' && moduleName) {\n      // Don't seal legacy namespaces as they may be used as a parent of\n      // another namespace\n      if (goog.moduleLoaderState_.declareLegacyNamespace) {\n        goog.constructNamespace_(moduleName, exports);\n      } else if (\n          goog.SEAL_MODULE_EXPORTS && Object.seal &&\n          typeof exports == 'object' && exports != null) {\n        Object.seal(exports);\n      }\n\n      var data = {\n        exports: exports,\n        type: goog.ModuleType.GOOG,\n        moduleId: goog.moduleLoaderState_.moduleName\n      };\n      goog.loadedModules_[moduleName] = data;\n    } else {\n      throw new Error('Invalid module name \\\"' + moduleName + '\\\"');\n    }\n  } finally {\n    goog.moduleLoaderState_ = previousState;\n  }\n};\n\n\n/**\n * @private @const\n */\ngoog.loadModuleFromSource_ = /** @type {function(string):?} */ (function() {\n  // NOTE: we avoid declaring parameters or local variables here to avoid\n  // masking globals or leaking values into the module definition.\n  'use strict';\n  var exports = {};\n  eval(arguments[0]);\n  return exports;\n});\n\n\n/**\n * Normalize a file path by removing redundant \"..\" and extraneous \".\" file\n * path components.\n * @param {string} path\n * @return {string}\n * @private\n */\ngoog.normalizePath_ = function(path) {\n  var components = path.split('/');\n  var i = 0;\n  while (i < components.length) {\n    if (components[i] == '.') {\n      components.splice(i, 1);\n    } else if (\n        i && components[i] == '..' && components[i - 1] &&\n        components[i - 1] != '..') {\n      components.splice(--i, 2);\n    } else {\n      i++;\n    }\n  }\n  return components.join('/');\n};\n\n\n/**\n * Provides a hook for loading a file when using Closure's goog.require() API\n * with goog.modules.  In particular this hook is provided to support Node.js.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_LOAD_FILE_SYNC;\n\n\n/**\n * Loads file by synchronous XHR. Should not be used in production environments.\n * @param {string} src Source URL.\n * @return {?string} File contents, or null if load failed.\n * @private\n */\ngoog.loadFileSync_ = function(src) {\n  if (goog.global.CLOSURE_LOAD_FILE_SYNC) {\n    return goog.global.CLOSURE_LOAD_FILE_SYNC(src);\n  } else {\n    try {\n      /** @type {XMLHttpRequest} */\n      var xhr = new goog.global['XMLHttpRequest']();\n      xhr.open('get', src, false);\n      xhr.send();\n      // NOTE: Successful http: requests have a status of 200, but successful\n      // file: requests may have a status of zero.  Any other status, or a\n      // thrown exception (particularly in case of file: requests) indicates\n      // some sort of error, which we treat as a missing or unavailable file.\n      return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;\n    } catch (err) {\n      // No need to rethrow or log, since errors should show up on their own.\n      return null;\n    }\n  }\n};\n\n\n/**\n * Lazily retrieves the transpiler and applies it to the source.\n * @param {string} code JS code.\n * @param {string} path Path to the code.\n * @param {string} target Language level output.\n * @return {string} The transpiled code.\n * @private\n */\ngoog.transpile_ = function(code, path, target) {\n  var jscomp = goog.global['$jscomp'];\n  if (!jscomp) {\n    goog.global['$jscomp'] = jscomp = {};\n  }\n  var transpile = jscomp.transpile;\n  if (!transpile) {\n    var transpilerPath = goog.basePath + goog.TRANSPILER;\n    var transpilerCode = goog.loadFileSync_(transpilerPath);\n    if (transpilerCode) {\n      // This must be executed synchronously, since by the time we know we\n      // need it, we're about to load and write the ES6 code synchronously,\n      // so a normal script-tag load will be too slow. Wrapped in a function\n      // so that code is eval'd in the global scope.\n      (function() {\n        (0, eval)(transpilerCode + '\\n//# sourceURL=' + transpilerPath);\n      }).call(goog.global);\n      // Even though the transpiler is optional, if $gwtExport is found, it's\n      // a sign the transpiler was loaded and the $jscomp.transpile *should*\n      // be there.\n      if (goog.global['$gwtExport'] && goog.global['$gwtExport']['$jscomp'] &&\n          !goog.global['$gwtExport']['$jscomp']['transpile']) {\n        throw new Error(\n            'The transpiler did not properly export the \"transpile\" ' +\n            'method. $gwtExport: ' + JSON.stringify(goog.global['$gwtExport']));\n      }\n      // transpile.js only exports a single $jscomp function, transpile. We\n      // grab just that and add it to the existing definition of $jscomp which\n      // contains the polyfills.\n      goog.global['$jscomp'].transpile =\n          goog.global['$gwtExport']['$jscomp']['transpile'];\n      jscomp = goog.global['$jscomp'];\n      transpile = jscomp.transpile;\n    }\n  }\n  if (!transpile) {\n    // The transpiler is an optional component.  If it's not available then\n    // replace it with a pass-through function that simply logs.\n    var suffix = ' requires transpilation but no transpiler was found.';\n    transpile = jscomp.transpile = function(code, path) {\n      // TODO(sdh): figure out some way to get this error to show up\n      // in test results, noting that the failure may occur in many\n      // different ways, including in loadModule() before the test\n      // runner even comes up.\n      goog.logToConsole_(path + suffix);\n      return code;\n    };\n  }\n  // Note: any transpilation errors/warnings will be logged to the console.\n  return transpile(code, path, target);\n};\n\n//==============================================================================\n// Language Enhancements\n//==============================================================================\n\n\n/**\n * This is a \"fixed\" version of the typeof operator.  It differs from the typeof\n * operator in such a way that null returns 'null' and arrays return 'array'.\n * @param {?} value The value to get the type of.\n * @return {string} The name of the type.\n */\ngoog.typeOf = function(value) {\n  var s = typeof value;\n  if (s == 'object') {\n    if (value) {\n      // Check these first, so we can avoid calling Object.prototype.toString if\n      // possible.\n      //\n      // IE improperly marshals typeof across execution contexts, but a\n      // cross-context object will still return false for \"instanceof Object\".\n      if (value instanceof Array) {\n        return 'array';\n      } else if (value instanceof Object) {\n        return s;\n      }\n\n      // HACK: In order to use an Object prototype method on the arbitrary\n      //   value, the compiler requires the value be cast to type Object,\n      //   even though the ECMA spec explicitly allows it.\n      var className = Object.prototype.toString.call(\n          /** @type {!Object} */ (value));\n      // In Firefox 3.6, attempting to access iframe window objects' length\n      // property throws an NS_ERROR_FAILURE, so we need to special-case it\n      // here.\n      if (className == '[object Window]') {\n        return 'object';\n      }\n\n      // We cannot always use constructor == Array or instanceof Array because\n      // different frames have different Array objects. In IE6, if the iframe\n      // where the array was created is destroyed, the array loses its\n      // prototype. Then dereferencing val.splice here throws an exception, so\n      // we can't use goog.isFunction. Calling typeof directly returns 'unknown'\n      // so that will work. In this case, this function will return false and\n      // most array functions will still work because the array is still\n      // array-like (supports length and []) even though it has lost its\n      // prototype.\n      // Mark Miller noticed that Object.prototype.toString\n      // allows access to the unforgeable [[Class]] property.\n      //  15.2.4.2 Object.prototype.toString ( )\n      //  When the toString method is called, the following steps are taken:\n      //      1. Get the [[Class]] property of this object.\n      //      2. Compute a string value by concatenating the three strings\n      //         \"[object \", Result(1), and \"]\".\n      //      3. Return Result(2).\n      // and this behavior survives the destruction of the execution context.\n      if ((className == '[object Array]' ||\n           // In IE all non value types are wrapped as objects across window\n           // boundaries (not iframe though) so we have to do object detection\n           // for this edge case.\n           typeof value.length == 'number' &&\n               typeof value.splice != 'undefined' &&\n               typeof value.propertyIsEnumerable != 'undefined' &&\n               !value.propertyIsEnumerable('splice')\n\n               )) {\n        return 'array';\n      }\n      // HACK: There is still an array case that fails.\n      //     function ArrayImpostor() {}\n      //     ArrayImpostor.prototype = [];\n      //     var impostor = new ArrayImpostor;\n      // this can be fixed by getting rid of the fast path\n      // (value instanceof Array) and solely relying on\n      // (value && Object.prototype.toString.vall(value) === '[object Array]')\n      // but that would require many more function calls and is not warranted\n      // unless closure code is receiving objects from untrusted sources.\n\n      // IE in cross-window calls does not correctly marshal the function type\n      // (it appears just as an object) so we cannot use just typeof val ==\n      // 'function'. However, if the object has a call property, it is a\n      // function.\n      if ((className == '[object Function]' ||\n           typeof value.call != 'undefined' &&\n               typeof value.propertyIsEnumerable != 'undefined' &&\n               !value.propertyIsEnumerable('call'))) {\n        return 'function';\n      }\n\n    } else {\n      return 'null';\n    }\n\n  } else if (s == 'function' && typeof value.call == 'undefined') {\n    // In Safari typeof nodeList returns 'function', and on Firefox typeof\n    // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We\n    // would like to return object for those and we can detect an invalid\n    // function by making sure that the function object has a call method.\n    return 'object';\n  }\n  return s;\n};\n\n\n/**\n * Returns true if the specified value is an array.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArray = function(val) {\n  return goog.typeOf(val) == 'array';\n};\n\n\n/**\n * Returns true if the object looks like an array. To qualify as array like\n * the value needs to be either a NodeList or an object with a Number length\n * property. Note that for this function neither strings nor functions are\n * considered \"array-like\".\n *\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArrayLike = function(val) {\n  var type = goog.typeOf(val);\n  // We do not use goog.isObject here in order to exclude function values.\n  return type == 'array' || type == 'object' && typeof val.length == 'number';\n};\n\n\n/**\n * Returns true if the object looks like a Date. To qualify as Date-like the\n * value needs to be an object and have a getFullYear() function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a like a Date.\n */\ngoog.isDateLike = function(val) {\n  return goog.isObject(val) && typeof val.getFullYear == 'function';\n};\n\n\n/**\n * Returns true if the specified value is a function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a function.\n */\ngoog.isFunction = function(val) {\n  return goog.typeOf(val) == 'function';\n};\n\n\n/**\n * Returns true if the specified value is an object.  This includes arrays and\n * functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\ngoog.isObject = function(val) {\n  var type = typeof val;\n  return type == 'object' && val != null || type == 'function';\n  // return Object(val) === val also works, but is slower, especially if val is\n  // not an object.\n};\n\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. The unique ID is\n * guaranteed to be unique across the current session amongst objects that are\n * passed into `getUid`. There is no guarantee that the ID is unique or\n * consistent across sessions. It is unsafe to generate unique ID for function\n * prototypes.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {number} The unique ID for the object.\n */\ngoog.getUid = function(obj) {\n  // TODO(arv): Make the type stricter, do not accept null.\n  return Object.prototype.hasOwnProperty.call(obj, goog.UID_PROPERTY_) &&\n      obj[goog.UID_PROPERTY_] ||\n      (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);\n};\n\n\n/**\n * Whether the given object is already assigned a unique ID.\n *\n * This does not modify the object.\n *\n * @param {!Object} obj The object to check.\n * @return {boolean} Whether there is an assigned unique id for the object.\n */\ngoog.hasUid = function(obj) {\n  return !!obj[goog.UID_PROPERTY_];\n};\n\n\n/**\n * Removes the unique ID from an object. This is useful if the object was\n * previously mutated using `goog.getUid` in which case the mutation is\n * undone.\n * @param {Object} obj The object to remove the unique ID field from.\n */\ngoog.removeUid = function(obj) {\n  // TODO(arv): Make the type stricter, do not accept null.\n\n  // In IE, DOM nodes are not instances of Object and throw an exception if we\n  // try to delete.  Instead we try to use removeAttribute.\n  if (obj !== null && 'removeAttribute' in obj) {\n    obj.removeAttribute(goog.UID_PROPERTY_);\n  }\n\n  try {\n    delete obj[goog.UID_PROPERTY_];\n  } catch (ex) {\n  }\n};\n\n\n/**\n * Name for unique ID property. Initialized in a way to help avoid collisions\n * with other closure JavaScript on the same page.\n * @type {string}\n * @private\n */\ngoog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * Counter for UID.\n * @type {number}\n * @private\n */\ngoog.uidCounter_ = 0;\n\n\n/**\n * Adds a hash code field to an object. The hash code is unique for the\n * given object.\n * @param {Object} obj The object to get the hash code for.\n * @return {number} The hash code for the object.\n * @deprecated Use goog.getUid instead.\n */\ngoog.getHashCode = goog.getUid;\n\n\n/**\n * Removes the hash code field from an object.\n * @param {Object} obj The object to remove the field from.\n * @deprecated Use goog.removeUid instead.\n */\ngoog.removeHashCode = goog.removeUid;\n\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n *\n * WARNINGS:\n * <code>goog.cloneObject</code> does not detect reference loops. Objects that\n * refer to themselves will cause infinite recursion.\n *\n * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies\n * UIDs created by <code>getUid</code> into cloned results.\n *\n * @param {*} obj The value to clone.\n * @return {*} A clone of the input value.\n * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.\n */\ngoog.cloneObject = function(obj) {\n  var type = goog.typeOf(obj);\n  if (type == 'object' || type == 'array') {\n    if (typeof obj.clone === 'function') {\n      return obj.clone();\n    }\n    var clone = type == 'array' ? [] : {};\n    for (var key in obj) {\n      clone[key] = goog.cloneObject(obj[key]);\n    }\n    return clone;\n  }\n\n  return obj;\n};\n\n\n/**\n * A native implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindNative_ = function(fn, selfObj, var_args) {\n  return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));\n};\n\n\n/**\n * A pure-JS implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindJs_ = function(fn, selfObj, var_args) {\n  if (!fn) {\n    throw new Error();\n  }\n\n  if (arguments.length > 2) {\n    var boundArgs = Array.prototype.slice.call(arguments, 2);\n    return function() {\n      // Prepend the bound arguments to the current arguments.\n      var newArgs = Array.prototype.slice.call(arguments);\n      Array.prototype.unshift.apply(newArgs, boundArgs);\n      return fn.apply(selfObj, newArgs);\n    };\n\n  } else {\n    return function() {\n      return fn.apply(selfObj, arguments);\n    };\n  }\n};\n\n\n/**\n * Partially applies this function to a particular 'this object' and zero or\n * more arguments. The result is a new function with some arguments of the first\n * function pre-filled and the value of this 'pre-specified'.\n *\n * Remaining arguments specified at call-time are appended to the pre-specified\n * ones.\n *\n * Also see: {@link #partial}.\n *\n * Usage:\n * <pre>var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');\n * barMethBound('arg3', 'arg4');</pre>\n *\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @suppress {deprecated} See above.\n */\ngoog.bind = function(fn, selfObj, var_args) {\n  // TODO(nicksantos): narrow the type signature.\n  if (Function.prototype.bind &&\n      // NOTE(nicksantos): Somebody pulled base.js into the default Chrome\n      // extension environment. This means that for Chrome extensions, they get\n      // the implementation of Function.prototype.bind that calls goog.bind\n      // instead of the native one. Even worse, we don't want to introduce a\n      // circular dependency between goog.bind and Function.prototype.bind, so\n      // we have to hack this to make sure it works correctly.\n      Function.prototype.bind.toString().indexOf('native code') != -1) {\n    goog.bind = goog.bindNative_;\n  } else {\n    goog.bind = goog.bindJs_;\n  }\n  return goog.bind.apply(null, arguments);\n};\n\n\n/**\n * Like goog.bind(), except that a 'this object' is not required. Useful when\n * the target function is already bound.\n *\n * Usage:\n * var g = goog.partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function goog.partial()\n *     was invoked as a method of.\n */\ngoog.partial = function(fn, var_args) {\n  var args = Array.prototype.slice.call(arguments, 1);\n  return function() {\n    // Clone the array (with slice()) and append additional arguments\n    // to the existing arguments.\n    var newArgs = args.slice();\n    newArgs.push.apply(newArgs, arguments);\n    return fn.apply(/** @type {?} */ (this), newArgs);\n  };\n};\n\n\n/**\n * Copies all the members of a source object to a target object. This method\n * does not work on all browsers for all objects that contain keys such as\n * toString or hasOwnProperty. Use goog.object.extend for this purpose.\n *\n * NOTE: Some have advocated for the use of goog.mixin to setup classes\n * with multiple inheritence (traits, mixins, etc).  However, as it simply\n * uses \"for in\", this is not compatible with ES6 classes whose methods are\n * non-enumerable.  Changing this, would break cases where non-enumerable\n * properties are not expected.\n *\n * @param {Object} target Target.\n * @param {Object} source Source.\n * @deprecated Prefer Object.assign\n */\ngoog.mixin = function(target, source) {\n  for (var x in source) {\n    target[x] = source[x];\n  }\n\n  // For IE7 or lower, the for-in-loop does not contain any properties that are\n  // not enumerable on the prototype object (for example, isPrototypeOf from\n  // Object.prototype) but also it will not include 'replace' on objects that\n  // extend String and change 'replace' (not that it is common for anyone to\n  // extend anything except Object).\n};\n\n\n/**\n * @return {number} An integer value representing the number of milliseconds\n *     between midnight, January 1, 1970 and the current time.\n * @deprecated Use Date.now\n */\ngoog.now = (goog.TRUSTED_SITE && Date.now) || (function() {\n             // Unary plus operator converts its operand to a number which in\n             // the case of\n             // a date is done by calling getTime().\n             return +new Date();\n           });\n\n\n/**\n * Evals JavaScript in the global scope.  In IE this uses execScript, other\n * browsers use goog.global.eval. If goog.global.eval does not evaluate in the\n * global scope (for example, in Safari), appends a script tag instead.\n * Throws an exception if neither execScript or eval is defined.\n * @param {string} script JavaScript string.\n */\ngoog.globalEval = function(script) {\n  if (goog.global.execScript) {\n    goog.global.execScript(script, 'JavaScript');\n  } else if (goog.global.eval) {\n    // Test to see if eval works\n    if (goog.evalWorksForGlobals_ == null) {\n      try {\n        goog.global.eval('var _evalTest_ = 1;');\n      } catch (ignore) {\n      }\n      if (typeof goog.global['_evalTest_'] != 'undefined') {\n        try {\n          delete goog.global['_evalTest_'];\n        } catch (ignore) {\n          // Microsoft edge fails the deletion above in strict mode.\n        }\n        goog.evalWorksForGlobals_ = true;\n      } else {\n        goog.evalWorksForGlobals_ = false;\n      }\n    }\n\n    if (goog.evalWorksForGlobals_) {\n      goog.global.eval(script);\n    } else {\n      /** @type {!Document} */\n      var doc = goog.global.document;\n      var scriptElt =\n          /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n      scriptElt.type = 'text/javascript';\n      scriptElt.defer = false;\n      // Note(user): can't use .innerHTML since \"t('<test>')\" will fail and\n      // .text doesn't work in Safari 2.  Therefore we append a text node.\n      scriptElt.appendChild(doc.createTextNode(script));\n      doc.head.appendChild(scriptElt);\n      doc.head.removeChild(scriptElt);\n    }\n  } else {\n    throw new Error('goog.globalEval not available');\n  }\n};\n\n\n/**\n * Indicates whether or not we can call 'eval' directly to eval code in the\n * global scope. Set to a Boolean by the first call to goog.globalEval (which\n * empirically tests whether eval works for globals). @see goog.globalEval\n * @type {?boolean}\n * @private\n */\ngoog.evalWorksForGlobals_ = null;\n\n\n/**\n * Optional map of CSS class names to obfuscated names used with\n * goog.getCssName().\n * @private {!Object<string, string>|undefined}\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMapping_;\n\n\n/**\n * Optional obfuscation style for CSS class names. Should be set to either\n * 'BY_WHOLE' or 'BY_PART' if defined.\n * @type {string|undefined}\n * @private\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMappingStyle_;\n\n\n\n/**\n * A hook for modifying the default behavior goog.getCssName. The function\n * if present, will receive the standard output of the goog.getCssName as\n * its input.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAP_FN;\n\n\n/**\n * Handles strings that are intended to be used as CSS class names.\n *\n * This function works in tandem with @see goog.setCssNameMapping.\n *\n * Without any mapping set, the arguments are simple joined with a hyphen and\n * passed through unaltered.\n *\n * When there is a mapping, there are two possible styles in which these\n * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)\n * of the passed in css name is rewritten according to the map. In the BY_WHOLE\n * style, the full css name is looked up in the map directly. If a rewrite is\n * not specified by the map, the compiler will output a warning.\n *\n * When the mapping is passed to the compiler, it will replace calls to\n * goog.getCssName with the strings from the mapping, e.g.\n *     var x = goog.getCssName('foo');\n *     var y = goog.getCssName(this.baseClass, 'active');\n *  becomes:\n *     var x = 'foo';\n *     var y = this.baseClass + '-active';\n *\n * If one argument is passed it will be processed, if two are passed only the\n * modifier will be processed, as it is assumed the first argument was generated\n * as a result of calling goog.getCssName.\n *\n * @param {string} className The class name.\n * @param {string=} opt_modifier A modifier to be appended to the class name.\n * @return {string} The class name or the concatenation of the class name and\n *     the modifier.\n */\ngoog.getCssName = function(className, opt_modifier) {\n  // String() is used for compatibility with compiled soy where the passed\n  // className can be non-string objects.\n  if (String(className).charAt(0) == '.') {\n    throw new Error(\n        'className passed in goog.getCssName must not start with \".\".' +\n        ' You passed: ' + className);\n  }\n\n  var getMapping = function(cssName) {\n    return goog.cssNameMapping_[cssName] || cssName;\n  };\n\n  var renameByParts = function(cssName) {\n    // Remap all the parts individually.\n    var parts = cssName.split('-');\n    var mapped = [];\n    for (var i = 0; i < parts.length; i++) {\n      mapped.push(getMapping(parts[i]));\n    }\n    return mapped.join('-');\n  };\n\n  var rename;\n  if (goog.cssNameMapping_) {\n    rename =\n        goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts;\n  } else {\n    rename = function(a) {\n      return a;\n    };\n  }\n\n  var result =\n      opt_modifier ? className + '-' + rename(opt_modifier) : rename(className);\n\n  // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further\n  // processing of the class name.\n  if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {\n    return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);\n  }\n\n  return result;\n};\n\n\n/**\n * Sets the map to check when returning a value from goog.getCssName(). Example:\n * <pre>\n * goog.setCssNameMapping({\n *   \"goog\": \"a\",\n *   \"disabled\": \"b\",\n * });\n *\n * var x = goog.getCssName('goog');\n * // The following evaluates to: \"a a-b\".\n * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')\n * </pre>\n * When declared as a map of string literals to string literals, the JSCompiler\n * will replace all calls to goog.getCssName() using the supplied map if the\n * --process_closure_primitives flag is set.\n *\n * @param {!Object} mapping A map of strings to strings where keys are possible\n *     arguments to goog.getCssName() and values are the corresponding values\n *     that should be returned.\n * @param {string=} opt_style The style of css name mapping. There are two valid\n *     options: 'BY_PART', and 'BY_WHOLE'.\n * @see goog.getCssName for a description.\n */\ngoog.setCssNameMapping = function(mapping, opt_style) {\n  goog.cssNameMapping_ = mapping;\n  goog.cssNameMappingStyle_ = opt_style;\n};\n\n\n/**\n * To use CSS renaming in compiled mode, one of the input files should have a\n * call to goog.setCssNameMapping() with an object literal that the JSCompiler\n * can extract and use to replace all calls to goog.getCssName(). In uncompiled\n * mode, JavaScript code should be loaded before this base.js file that declares\n * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is\n * to ensure that the mapping is loaded before any calls to goog.getCssName()\n * are made in uncompiled mode.\n *\n * A hook for overriding the CSS name mapping.\n * @type {!Object<string, string>|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAPPING;\n\n\nif (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {\n  // This does not call goog.setCssNameMapping() because the JSCompiler\n  // requires that goog.setCssNameMapping() be called with an object literal.\n  goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;\n}\n\n\n/**\n * Gets a localized message.\n *\n * This function is a compiler primitive. If you give the compiler a localized\n * message bundle, it will replace the string at compile-time with a localized\n * version, and expand goog.getMsg call to a concatenated string.\n *\n * Messages must be initialized in the form:\n * <code>\n * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});\n * </code>\n *\n * This function produces a string which should be treated as plain text. Use\n * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to\n * produce SafeHtml.\n *\n * @param {string} str Translatable string, places holders in the form {$foo}.\n * @param {Object<string, string>=} opt_values Maps place holder name to value.\n * @param {{html: boolean}=} opt_options Options:\n *     html: Escape '<' in str to '&lt;'. Used by Closure Templates where the\n *     generated code size and performance is critical which is why {@link\n *     goog.html.SafeHtmlFormatter} is not used. The value must be literal true\n *     or false.\n * @return {string} message with placeholders filled.\n */\ngoog.getMsg = function(str, opt_values, opt_options) {\n  if (opt_options && opt_options.html) {\n    // Note that '&' is not replaced because the translation can contain HTML\n    // entities.\n    str = str.replace(/</g, '&lt;');\n  }\n  if (opt_values) {\n    str = str.replace(/\\{\\$([^}]+)}/g, function(match, key) {\n      return (opt_values != null && key in opt_values) ? opt_values[key] :\n                                                         match;\n    });\n  }\n  return str;\n};\n\n\n/**\n * Gets a localized message. If the message does not have a translation, gives a\n * fallback message.\n *\n * This is useful when introducing a new message that has not yet been\n * translated into all languages.\n *\n * This function is a compiler primitive. Must be used in the form:\n * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>\n * where MSG_A and MSG_B were initialized with goog.getMsg.\n *\n * @param {string} a The preferred message.\n * @param {string} b The fallback message.\n * @return {string} The best translated message.\n */\ngoog.getMsgWithFallback = function(a, b) {\n  return a;\n};\n\n\n/**\n * Exposes an unobfuscated global namespace path for the given object.\n * Note that fields of the exported object *will* be obfuscated, unless they are\n * exported in turn via this function or goog.exportProperty.\n *\n * Also handy for making public items that are defined in anonymous closures.\n *\n * ex. goog.exportSymbol('public.path.Foo', Foo);\n *\n * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);\n *     public.path.Foo.staticFunction();\n *\n * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',\n *                       Foo.prototype.myMethod);\n *     new public.path.Foo().myMethod();\n *\n * @param {string} publicPath Unobfuscated name to export.\n * @param {*} object Object the name should point to.\n * @param {Object=} opt_objectToExportTo The object to add the path to; default\n *     is goog.global.\n */\ngoog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {\n  goog.exportPath_(publicPath, object, opt_objectToExportTo);\n};\n\n\n/**\n * Exports a property unobfuscated into the object's namespace.\n * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);\n * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);\n * @param {Object} object Object whose static property is being exported.\n * @param {string} publicName Unobfuscated name to export.\n * @param {*} symbol Object the name should point to.\n */\ngoog.exportProperty = function(object, publicName, symbol) {\n  object[publicName] = symbol;\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * Usage:\n * <pre>\n * function ParentClass(a, b) { }\n * ParentClass.prototype.foo = function(a) { };\n *\n * function ChildClass(a, b, c) {\n *   ChildClass.base(this, 'constructor', a, b);\n * }\n * goog.inherits(ChildClass, ParentClass);\n *\n * var child = new ChildClass('a', 'b', 'see');\n * child.foo(); // This works.\n * </pre>\n *\n * @param {!Function} childCtor Child class.\n * @param {!Function} parentCtor Parent class.\n * @suppress {strictMissingProperties} superClass_ and base is not defined on\n *    Function.\n */\ngoog.inherits = function(childCtor, parentCtor) {\n  /** @constructor */\n  function tempCtor() {}\n  tempCtor.prototype = parentCtor.prototype;\n  childCtor.superClass_ = parentCtor.prototype;\n  childCtor.prototype = new tempCtor();\n  /** @override */\n  childCtor.prototype.constructor = childCtor;\n\n  /**\n   * Calls superclass constructor/method.\n   *\n   * This function is only available if you use goog.inherits to\n   * express inheritance relationships between classes.\n   *\n   * NOTE: This is a replacement for goog.base and for superClass_\n   * property defined in childCtor.\n   *\n   * @param {!Object} me Should always be \"this\".\n   * @param {string} methodName The method name to call. Calling\n   *     superclass constructor can be done with the special string\n   *     'constructor'.\n   * @param {...*} var_args The arguments to pass to superclass\n   *     method/constructor.\n   * @return {*} The return value of the superclass method/constructor.\n   */\n  childCtor.base = function(me, methodName, var_args) {\n    // Copying using loop to avoid deop due to passing arguments object to\n    // function. This is faster in many JS engines as of late 2014.\n    var args = new Array(arguments.length - 2);\n    for (var i = 2; i < arguments.length; i++) {\n      args[i - 2] = arguments[i];\n    }\n    return parentCtor.prototype[methodName].apply(me, args);\n  };\n};\n\n\n/**\n * Allow for aliasing within scope functions.  This function exists for\n * uncompiled code - in compiled code the calls will be inlined and the aliases\n * applied.  In uncompiled code the function is simply run since the aliases as\n * written are valid JavaScript.\n *\n *\n * @param {function()} fn Function to call.  This function can contain aliases\n *     to namespaces (e.g. \"var dom = goog.dom\") or classes\n *     (e.g. \"var Timer = goog.Timer\").\n * @deprecated Use goog.module instead.\n */\ngoog.scope = function(fn) {\n  if (goog.isInModuleLoader_()) {\n    throw new Error('goog.scope is not supported within a module.');\n  }\n  fn.call(goog.global);\n};\n\n\n/*\n * To support uncompiled, strict mode bundles that use eval to divide source\n * like so:\n *    eval('someSource;//# sourceUrl sourcefile.js');\n * We need to export the globally defined symbols \"goog\" and \"COMPILED\".\n * Exporting \"goog\" breaks the compiler optimizations, so we required that\n * be defined externally.\n * NOTE: We don't use goog.exportSymbol here because we don't want to trigger\n * extern generation when that compiler option is enabled.\n */\nif (!COMPILED) {\n  goog.global['COMPILED'] = COMPILED;\n}\n\n\n//==============================================================================\n// goog.defineClass implementation\n//==============================================================================\n\n\n/**\n * Creates a restricted form of a Closure \"class\":\n *   - from the compiler's perspective, the instance returned from the\n *     constructor is sealed (no new properties may be added).  This enables\n *     better checks.\n *   - the compiler will rewrite this definition to a form that is optimal\n *     for type checking and optimization (initially this will be a more\n *     traditional form).\n *\n * @param {Function} superClass The superclass, Object or null.\n * @param {goog.defineClass.ClassDescriptor} def\n *     An object literal describing\n *     the class.  It may have the following properties:\n *     \"constructor\": the constructor function\n *     \"statics\": an object literal containing methods to add to the constructor\n *        as \"static\" methods or a function that will receive the constructor\n *        function as its only parameter to which static properties can\n *        be added.\n *     all other properties are added to the prototype.\n * @return {!Function} The class constructor.\n * @deprecated Use ES6 class syntax instead.\n */\ngoog.defineClass = function(superClass, def) {\n  // TODO(johnlenz): consider making the superClass an optional parameter.\n  var constructor = def.constructor;\n  var statics = def.statics;\n  // Wrap the constructor prior to setting up the prototype and static methods.\n  if (!constructor || constructor == Object.prototype.constructor) {\n    constructor = function() {\n      throw new Error(\n          'cannot instantiate an interface (no constructor defined).');\n    };\n  }\n\n  var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);\n  if (superClass) {\n    goog.inherits(cls, superClass);\n  }\n\n  // Remove all the properties that should not be copied to the prototype.\n  delete def.constructor;\n  delete def.statics;\n\n  goog.defineClass.applyProperties_(cls.prototype, def);\n  if (statics != null) {\n    if (statics instanceof Function) {\n      statics(cls);\n    } else {\n      goog.defineClass.applyProperties_(cls, statics);\n    }\n  }\n\n  return cls;\n};\n\n\n/**\n * @typedef {{\n *   constructor: (!Function|undefined),\n *   statics: (Object|undefined|function(Function):void)\n * }}\n */\ngoog.defineClass.ClassDescriptor;\n\n\n/**\n * @define {boolean} Whether the instances returned by goog.defineClass should\n *     be sealed when possible.\n *\n * When sealing is disabled the constructor function will not be wrapped by\n * goog.defineClass, making it incompatible with ES6 class methods.\n */\ngoog.defineClass.SEAL_CLASS_INSTANCES =\n    goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);\n\n\n/**\n * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is\n * defined, this function will wrap the constructor in a function that seals the\n * results of the provided constructor function.\n *\n * @param {!Function} ctr The constructor whose results maybe be sealed.\n * @param {Function} superClass The superclass constructor.\n * @return {!Function} The replacement constructor.\n * @private\n */\ngoog.defineClass.createSealingConstructor_ = function(ctr, superClass) {\n  if (!goog.defineClass.SEAL_CLASS_INSTANCES) {\n    // Do now wrap the constructor when sealing is disabled. Angular code\n    // depends on this for injection to work properly.\n    return ctr;\n  }\n\n  // Compute whether the constructor is sealable at definition time, rather\n  // than when the instance is being constructed.\n  var superclassSealable = !goog.defineClass.isUnsealable_(superClass);\n\n  /**\n   * @this {Object}\n   * @return {?}\n   */\n  var wrappedCtr = function() {\n    // Don't seal an instance of a subclass when it calls the constructor of\n    // its super class as there is most likely still setup to do.\n    var instance = ctr.apply(this, arguments) || this;\n    instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];\n\n    if (this.constructor === wrappedCtr && superclassSealable &&\n        Object.seal instanceof Function) {\n      Object.seal(instance);\n    }\n    return instance;\n  };\n\n  return wrappedCtr;\n};\n\n\n/**\n * @param {Function} ctr The constructor to test.\n * @return {boolean} Whether the constructor has been tagged as unsealable\n *     using goog.tagUnsealableClass.\n * @private\n */\ngoog.defineClass.isUnsealable_ = function(ctr) {\n  return ctr && ctr.prototype &&\n      ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_];\n};\n\n\n// TODO(johnlenz): share these values with the goog.object\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {!Array<string>}\n * @private\n * @const\n */\ngoog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [\n  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n  'toLocaleString', 'toString', 'valueOf'\n];\n\n\n// TODO(johnlenz): share this function with the goog.object\n/**\n * @param {!Object} target The object to add properties to.\n * @param {!Object} source The object to copy properties from.\n * @private\n */\ngoog.defineClass.applyProperties_ = function(target, source) {\n  // TODO(johnlenz): update this to support ES5 getters/setters\n\n  var key;\n  for (key in source) {\n    if (Object.prototype.hasOwnProperty.call(source, key)) {\n      target[key] = source[key];\n    }\n  }\n\n  // For IE the for-in-loop does not contain any properties that are not\n  // enumerable on the prototype object (for example isPrototypeOf from\n  // Object.prototype) and it will also not include 'replace' on objects that\n  // extend String and change 'replace' (not that it is common for anyone to\n  // extend anything except Object).\n  for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {\n    key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];\n    if (Object.prototype.hasOwnProperty.call(source, key)) {\n      target[key] = source[key];\n    }\n  }\n};\n\n\n/**\n * Sealing classes breaks the older idiom of assigning properties on the\n * prototype rather than in the constructor. As such, goog.defineClass\n * must not seal subclasses of these old-style classes until they are fixed.\n * Until then, this marks a class as \"broken\", instructing defineClass\n * not to seal subclasses.\n * @param {!Function} ctr The legacy constructor to tag as unsealable.\n */\ngoog.tagUnsealableClass = function(ctr) {\n  if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {\n    ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;\n  }\n};\n\n\n/**\n * Name for unsealable tag property.\n * @const @private {string}\n */\ngoog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable';\n\n\n// There's a bug in the compiler where without collapse properties the\n// Closure namespace defines do not guard code correctly. To help reduce code\n// size also check for !COMPILED even though it redundant until this is fixed.\nif (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n\n  /**\n   * Tries to detect whether is in the context of an HTML document.\n   * @return {boolean} True if it looks like HTML document.\n   * @private\n   */\n  goog.inHtmlDocument_ = function() {\n    /** @type {!Document} */\n    var doc = goog.global.document;\n    return doc != null && 'write' in doc;  // XULDocument misses write.\n  };\n\n\n  /**\n   * We'd like to check for if the document readyState is 'loading'; however\n   * there are bugs on IE 10 and below where the readyState being anything other\n   * than 'complete' is not reliable.\n   * @return {boolean}\n   * @private\n   */\n  goog.isDocumentLoading_ = function() {\n    // attachEvent is available on IE 6 thru 10 only, and thus can be used to\n    // detect those browsers.\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n    return doc.attachEvent ? doc.readyState != 'complete' :\n                             doc.readyState == 'loading';\n  };\n\n\n  /**\n   * Tries to detect the base path of base.js script that bootstraps Closure.\n   * @private\n   */\n  goog.findBasePath_ = function() {\n    if (goog.global.CLOSURE_BASE_PATH != undefined &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        typeof goog.global.CLOSURE_BASE_PATH === 'string') {\n      goog.basePath = goog.global.CLOSURE_BASE_PATH;\n      return;\n    } else if (!goog.inHtmlDocument_()) {\n      return;\n    }\n    /** @type {!Document} */\n    var doc = goog.global.document;\n    // If we have a currentScript available, use it exclusively.\n    var currentScript = doc.currentScript;\n    if (currentScript) {\n      var scripts = [currentScript];\n    } else {\n      var scripts = doc.getElementsByTagName('SCRIPT');\n    }\n    // Search backwards since the current script is in almost all cases the one\n    // that has base.js.\n    for (var i = scripts.length - 1; i >= 0; --i) {\n      var script = /** @type {!HTMLScriptElement} */ (scripts[i]);\n      var src = script.src;\n      var qmark = src.lastIndexOf('?');\n      var l = qmark == -1 ? src.length : qmark;\n      if (src.substr(l - 7, 7) == 'base.js') {\n        goog.basePath = src.substr(0, l - 7);\n        return;\n      }\n    }\n  };\n\n  goog.findBasePath_();\n\n  /** @struct @constructor @final */\n  goog.Transpiler = function() {\n    /** @private {?Object<string, boolean>} */\n    this.requiresTranspilation_ = null;\n    /** @private {string} */\n    this.transpilationTarget_ = goog.TRANSPILE_TO_LANGUAGE;\n  };\n  /**\n   * Returns a newly created map from language mode string to a boolean\n   * indicating whether transpilation should be done for that mode as well as\n   * the highest level language that this environment supports.\n   *\n   * Guaranteed invariant:\n   * For any two modes, l1 and l2 where l2 is a newer mode than l1,\n   * `map[l1] == true` implies that `map[l2] == true`.\n   *\n   * Note this method is extracted and used elsewhere, so it cannot rely on\n   * anything external (it should easily be able to be transformed into a\n   * standalone, top level function).\n   *\n   * @private\n   * @return {{\n   *   target: string,\n   *   map: !Object<string, boolean>\n   * }}\n   */\n  goog.Transpiler.prototype.createRequiresTranspilation_ = function() {\n    var transpilationTarget = 'es3';\n    var /** !Object<string, boolean> */ requiresTranspilation = {'es3': false};\n    var transpilationRequiredForAllLaterModes = false;\n\n    /**\n     * Adds an entry to requiresTranspliation for the given language mode.\n     *\n     * IMPORTANT: Calls must be made in order from oldest to newest language\n     * mode.\n     * @param {string} modeName\n     * @param {function(): boolean} isSupported Returns true if the JS engine\n     *     supports the given mode.\n     */\n    function addNewerLanguageTranspilationCheck(modeName, isSupported) {\n      if (transpilationRequiredForAllLaterModes) {\n        requiresTranspilation[modeName] = true;\n      } else if (isSupported()) {\n        transpilationTarget = modeName;\n        requiresTranspilation[modeName] = false;\n      } else {\n        requiresTranspilation[modeName] = true;\n        transpilationRequiredForAllLaterModes = true;\n      }\n    }\n\n    /**\n     * Does the given code evaluate without syntax errors and return a truthy\n     * result?\n     */\n    function /** boolean */ evalCheck(/** string */ code) {\n      try {\n        return !!eval(code);\n      } catch (ignored) {\n        return false;\n      }\n    }\n\n    var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?\n        goog.global.navigator.userAgent :\n        '';\n\n    // Identify ES3-only browsers by their incorrect treatment of commas.\n    addNewerLanguageTranspilationCheck('es5', function() {\n      return evalCheck('[1,].length==1');\n    });\n    addNewerLanguageTranspilationCheck('es6', function() {\n      // Edge has a non-deterministic (i.e., not reproducible) bug with ES6:\n      // https://github.com/Microsoft/ChakraCore/issues/1496.\n      var re = /Edge\\/(\\d+)(\\.\\d)*/i;\n      var edgeUserAgent = userAgent.match(re);\n      if (edgeUserAgent) {\n        // The Reflect.construct test below is flaky on Edge. It can sometimes\n        // pass or fail on 40 15.15063, so just exit early for Edge and treat\n        // it as ES5. Until we're on a more up to date version just always use\n        // ES5. See https://github.com/Microsoft/ChakraCore/issues/3217.\n        return false;\n      }\n      // Test es6: [FF50 (?), Edge 14 (?), Chrome 50]\n      //   (a) default params (specifically shadowing locals),\n      //   (b) destructuring, (c) block-scoped functions,\n      //   (d) for-of (const), (e) new.target/Reflect.construct\n      var es6fullTest =\n          'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' +\n          'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' +\n          'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' +\n          'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' +\n          '==3}';\n\n      return evalCheck('(()=>{\"use strict\";' + es6fullTest + '})()');\n    });\n    // ** and **= are the only new features in 'es7'\n    addNewerLanguageTranspilationCheck('es7', function() {\n      return evalCheck('2 ** 2 == 4');\n    });\n    // async functions are the only new features in 'es8'\n    addNewerLanguageTranspilationCheck('es8', function() {\n      return evalCheck('async () => 1, true');\n    });\n    addNewerLanguageTranspilationCheck('es9', function() {\n      return evalCheck('({...rest} = {}), true');\n    });\n    addNewerLanguageTranspilationCheck('es_next', function() {\n      return false;  // assume it always need to transpile\n    });\n    return {target: transpilationTarget, map: requiresTranspilation};\n  };\n\n\n  /**\n   * Determines whether the given language needs to be transpiled.\n   * @param {string} lang\n   * @param {string|undefined} module\n   * @return {boolean}\n   */\n  goog.Transpiler.prototype.needsTranspile = function(lang, module) {\n    if (goog.TRANSPILE == 'always') {\n      return true;\n    } else if (goog.TRANSPILE == 'never') {\n      return false;\n    } else if (!this.requiresTranspilation_) {\n      var obj = this.createRequiresTranspilation_();\n      this.requiresTranspilation_ = obj.map;\n      this.transpilationTarget_ = this.transpilationTarget_ || obj.target;\n    }\n    if (lang in this.requiresTranspilation_) {\n      if (this.requiresTranspilation_[lang]) {\n        return true;\n      } else if (\n          goog.inHtmlDocument_() && module == 'es6' &&\n          !('noModule' in goog.global.document.createElement('script'))) {\n        return true;\n      } else {\n        return false;\n      }\n    } else {\n      throw new Error('Unknown language mode: ' + lang);\n    }\n  };\n\n\n  /**\n   * Lazily retrieves the transpiler and applies it to the source.\n   * @param {string} code JS code.\n   * @param {string} path Path to the code.\n   * @return {string} The transpiled code.\n   */\n  goog.Transpiler.prototype.transpile = function(code, path) {\n    // TODO(johnplaisted): We should delete goog.transpile_ and just have this\n    // function. But there's some compile error atm where goog.global is being\n    // stripped incorrectly without this.\n    return goog.transpile_(code, path, this.transpilationTarget_);\n  };\n\n\n  /** @private @final {!goog.Transpiler} */\n  goog.transpiler_ = new goog.Transpiler();\n\n  /**\n   * Rewrites closing script tags in input to avoid ending an enclosing script\n   * tag.\n   *\n   * @param {string} str\n   * @return {string}\n   * @private\n   */\n  goog.protectScriptTag_ = function(str) {\n    return str.replace(/<\\/(SCRIPT)/ig, '\\\\x3c/$1');\n  };\n\n\n  /**\n   * A debug loader is responsible for downloading and executing javascript\n   * files in an unbundled, uncompiled environment.\n   *\n   * This can be custimized via the setDependencyFactory method, or by\n   * CLOSURE_IMPORT_SCRIPT/CLOSURE_LOAD_FILE_SYNC.\n   *\n   * @struct @constructor @final @private\n   */\n  goog.DebugLoader_ = function() {\n    /** @private @const {!Object<string, !goog.Dependency>} */\n    this.dependencies_ = {};\n    /** @private @const {!Object<string, string>} */\n    this.idToPath_ = {};\n    /** @private @const {!Object<string, boolean>} */\n    this.written_ = {};\n    /** @private @const {!Array<!goog.Dependency>} */\n    this.loadingDeps_ = [];\n    /** @private {!Array<!goog.Dependency>} */\n    this.depsToLoad_ = [];\n    /** @private {boolean} */\n    this.paused_ = false;\n    /** @private {!goog.DependencyFactory} */\n    this.factory_ = new goog.DependencyFactory(goog.transpiler_);\n    /** @private @const {!Object<string, !Function>} */\n    this.deferredCallbacks_ = {};\n    /** @private @const {!Array<string>} */\n    this.deferredQueue_ = [];\n  };\n\n  /**\n   * @param {!Array<string>} namespaces\n   * @param {function(): undefined} callback Function to call once all the\n   *     namespaces have loaded.\n   */\n  goog.DebugLoader_.prototype.bootstrap = function(namespaces, callback) {\n    var cb = callback;\n    function resolve() {\n      if (cb) {\n        goog.global.setTimeout(cb, 0);\n        cb = null;\n      }\n    }\n\n    if (!namespaces.length) {\n      resolve();\n      return;\n    }\n\n    var deps = [];\n    for (var i = 0; i < namespaces.length; i++) {\n      var path = this.getPathFromDeps_(namespaces[i]);\n      if (!path) {\n        throw new Error('Unregonized namespace: ' + namespaces[i]);\n      }\n      deps.push(this.dependencies_[path]);\n    }\n\n    var require = goog.require;\n    var loaded = 0;\n    for (var i = 0; i < namespaces.length; i++) {\n      require(namespaces[i]);\n      deps[i].onLoad(function() {\n        if (++loaded == namespaces.length) {\n          resolve();\n        }\n      });\n    }\n  };\n\n\n  /**\n   * Loads the Closure Dependency file.\n   *\n   * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n   * loaded, setDependencyFactory called, and then this called. i.e. allows\n   * custom loading of the deps file.\n   */\n  goog.DebugLoader_.prototype.loadClosureDeps = function() {\n    // Circumvent addDependency, which would try to transpile deps.js if\n    // transpile is set to always.\n    var relPath = 'deps.js';\n    this.depsToLoad_.push(this.factory_.createDependency(\n        goog.normalizePath_(goog.basePath + relPath), relPath, [], [], {},\n        false));\n    this.loadDeps_();\n  };\n\n\n  /**\n   * Notifies the debug loader when a dependency has been requested.\n   *\n   * @param {string} absPathOrId Path of the dependency or goog id.\n   * @param {boolean=} opt_force\n   */\n  goog.DebugLoader_.prototype.requested = function(absPathOrId, opt_force) {\n    var path = this.getPathFromDeps_(absPathOrId);\n    if (path &&\n        (opt_force || this.areDepsLoaded_(this.dependencies_[path].requires))) {\n      var callback = this.deferredCallbacks_[path];\n      if (callback) {\n        delete this.deferredCallbacks_[path];\n        callback();\n      }\n    }\n  };\n\n\n  /**\n   * Sets the dependency factory, which can be used to create custom\n   * goog.Dependency implementations to control how dependencies are loaded.\n   *\n   * @param {!goog.DependencyFactory} factory\n   */\n  goog.DebugLoader_.prototype.setDependencyFactory = function(factory) {\n    this.factory_ = factory;\n  };\n\n\n  /**\n   * Travserses the dependency graph and queues the given dependency, and all of\n   * its transitive dependencies, for loading and then starts loading if not\n   * paused.\n   *\n   * @param {string} namespace\n   * @private\n   */\n  goog.DebugLoader_.prototype.load_ = function(namespace) {\n    if (!this.getPathFromDeps_(namespace)) {\n      var errorMessage = 'goog.require could not find: ' + namespace;\n\n      goog.logToConsole_(errorMessage);\n      throw Error(errorMessage);\n    } else {\n      var loader = this;\n\n      var deps = [];\n\n      /** @param {string} namespace */\n      var visit = function(namespace) {\n        var path = loader.getPathFromDeps_(namespace);\n\n        if (!path) {\n          throw new Error('Bad dependency path or symbol: ' + namespace);\n        }\n\n        if (loader.written_[path]) {\n          return;\n        }\n\n        loader.written_[path] = true;\n\n        var dep = loader.dependencies_[path];\n        for (var i = 0; i < dep.requires.length; i++) {\n          if (!goog.isProvided_(dep.requires[i])) {\n            visit(dep.requires[i]);\n          }\n        }\n\n        deps.push(dep);\n      };\n\n      visit(namespace);\n\n      var wasLoading = !!this.depsToLoad_.length;\n      this.depsToLoad_ = this.depsToLoad_.concat(deps);\n\n      if (!this.paused_ && !wasLoading) {\n        this.loadDeps_();\n      }\n    }\n  };\n\n\n  /**\n   * Loads any queued dependencies until they are all loaded or paused.\n   *\n   * @private\n   */\n  goog.DebugLoader_.prototype.loadDeps_ = function() {\n    var loader = this;\n    var paused = this.paused_;\n\n    while (this.depsToLoad_.length && !paused) {\n      (function() {\n        var loadCallDone = false;\n        var dep = loader.depsToLoad_.shift();\n\n        var loaded = false;\n        loader.loading_(dep);\n\n        var controller = {\n          pause: function() {\n            if (loadCallDone) {\n              throw new Error('Cannot call pause after the call to load.');\n            } else {\n              paused = true;\n            }\n          },\n          resume: function() {\n            if (loadCallDone) {\n              loader.resume_();\n            } else {\n              // Some dep called pause and then resume in the same load call.\n              // Just keep running this same loop.\n              paused = false;\n            }\n          },\n          loaded: function() {\n            if (loaded) {\n              throw new Error('Double call to loaded.');\n            }\n\n            loaded = true;\n            loader.loaded_(dep);\n          },\n          pending: function() {\n            // Defensive copy.\n            var pending = [];\n            for (var i = 0; i < loader.loadingDeps_.length; i++) {\n              pending.push(loader.loadingDeps_[i]);\n            }\n            return pending;\n          },\n          /**\n           * @param {goog.ModuleType} type\n           */\n          setModuleState: function(type) {\n            goog.moduleLoaderState_ = {\n              type: type,\n              moduleName: '',\n              declareLegacyNamespace: false\n            };\n          },\n          /** @type {function(string, string, string=)} */\n          registerEs6ModuleExports: function(\n              path, exports, opt_closureNamespace) {\n            if (opt_closureNamespace) {\n              goog.loadedModules_[opt_closureNamespace] = {\n                exports: exports,\n                type: goog.ModuleType.ES6,\n                moduleId: opt_closureNamespace || ''\n              };\n            }\n          },\n          /** @type {function(string, ?)} */\n          registerGoogModuleExports: function(moduleId, exports) {\n            goog.loadedModules_[moduleId] = {\n              exports: exports,\n              type: goog.ModuleType.GOOG,\n              moduleId: moduleId\n            };\n          },\n          clearModuleState: function() {\n            goog.moduleLoaderState_ = null;\n          },\n          defer: function(callback) {\n            if (loadCallDone) {\n              throw new Error(\n                  'Cannot register with defer after the call to load.');\n            }\n            loader.defer_(dep, callback);\n          },\n          areDepsLoaded: function() {\n            return loader.areDepsLoaded_(dep.requires);\n          }\n        };\n\n        try {\n          dep.load(controller);\n        } finally {\n          loadCallDone = true;\n        }\n      })();\n    }\n\n    if (paused) {\n      this.pause_();\n    }\n  };\n\n\n  /** @private */\n  goog.DebugLoader_.prototype.pause_ = function() {\n    this.paused_ = true;\n  };\n\n\n  /** @private */\n  goog.DebugLoader_.prototype.resume_ = function() {\n    if (this.paused_) {\n      this.paused_ = false;\n      this.loadDeps_();\n    }\n  };\n\n\n  /**\n   * Marks the given dependency as loading (load has been called but it has not\n   * yet marked itself as finished). Useful for dependencies that want to know\n   * what else is loading. Example: goog.modules cannot eval if there are\n   * loading dependencies.\n   *\n   * @param {!goog.Dependency} dep\n   * @private\n   */\n  goog.DebugLoader_.prototype.loading_ = function(dep) {\n    this.loadingDeps_.push(dep);\n  };\n\n\n  /**\n   * Marks the given dependency as having finished loading and being available\n   * for require.\n   *\n   * @param {!goog.Dependency} dep\n   * @private\n   */\n  goog.DebugLoader_.prototype.loaded_ = function(dep) {\n    for (var i = 0; i < this.loadingDeps_.length; i++) {\n      if (this.loadingDeps_[i] == dep) {\n        this.loadingDeps_.splice(i, 1);\n        break;\n      }\n    }\n\n    for (var i = 0; i < this.deferredQueue_.length; i++) {\n      if (this.deferredQueue_[i] == dep.path) {\n        this.deferredQueue_.splice(i, 1);\n        break;\n      }\n    }\n\n    if (this.loadingDeps_.length == this.deferredQueue_.length &&\n        !this.depsToLoad_.length) {\n      // Something has asked to load these, but they may not be directly\n      // required again later, so load them now that we know we're done loading\n      // everything else. e.g. a goog module entry point.\n      while (this.deferredQueue_.length) {\n        this.requested(this.deferredQueue_.shift(), true);\n      }\n    }\n\n    dep.loaded();\n  };\n\n\n  /**\n   * @param {!Array<string>} pathsOrIds\n   * @return {boolean}\n   * @private\n   */\n  goog.DebugLoader_.prototype.areDepsLoaded_ = function(pathsOrIds) {\n    for (var i = 0; i < pathsOrIds.length; i++) {\n      var path = this.getPathFromDeps_(pathsOrIds[i]);\n      if (!path ||\n          (!(path in this.deferredCallbacks_) &&\n           !goog.isProvided_(pathsOrIds[i]))) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n\n  /**\n   * @param {string} absPathOrId\n   * @return {?string}\n   * @private\n   */\n  goog.DebugLoader_.prototype.getPathFromDeps_ = function(absPathOrId) {\n    if (absPathOrId in this.idToPath_) {\n      return this.idToPath_[absPathOrId];\n    } else if (absPathOrId in this.dependencies_) {\n      return absPathOrId;\n    } else {\n      return null;\n    }\n  };\n\n\n  /**\n   * @param {!goog.Dependency} dependency\n   * @param {!Function} callback\n   * @private\n   */\n  goog.DebugLoader_.prototype.defer_ = function(dependency, callback) {\n    this.deferredCallbacks_[dependency.path] = callback;\n    this.deferredQueue_.push(dependency.path);\n  };\n\n\n  /**\n   * Interface for goog.Dependency implementations to have some control over\n   * loading of dependencies.\n   *\n   * @record\n   */\n  goog.LoadController = function() {};\n\n\n  /**\n   * Tells the controller to halt loading of more dependencies.\n   */\n  goog.LoadController.prototype.pause = function() {};\n\n\n  /**\n   * Tells the controller to resume loading of more dependencies if paused.\n   */\n  goog.LoadController.prototype.resume = function() {};\n\n\n  /**\n   * Tells the controller that this dependency has finished loading.\n   *\n   * This causes this to be removed from pending() and any load callbacks to\n   * fire.\n   */\n  goog.LoadController.prototype.loaded = function() {};\n\n\n  /**\n   * List of dependencies on which load has been called but which have not\n   * called loaded on their controller. This includes the current dependency.\n   *\n   * @return {!Array<!goog.Dependency>}\n   */\n  goog.LoadController.prototype.pending = function() {};\n\n\n  /**\n   * Registers an object as an ES6 module's exports so that goog.modules may\n   * require it by path.\n   *\n   * @param {string} path Full path of the module.\n   * @param {?} exports\n   * @param {string=} opt_closureNamespace Closure namespace to associate with\n   *     this module.\n   */\n  goog.LoadController.prototype.registerEs6ModuleExports = function(\n      path, exports, opt_closureNamespace) {};\n\n\n  /**\n   * Sets the current module state.\n   *\n   * @param {goog.ModuleType} type Type of module.\n   */\n  goog.LoadController.prototype.setModuleState = function(type) {};\n\n\n  /**\n   * Clears the current module state.\n   */\n  goog.LoadController.prototype.clearModuleState = function() {};\n\n\n  /**\n   * Registers a callback to call once the dependency is actually requested\n   * via goog.require + all of the immediate dependencies have been loaded or\n   * all other files have been loaded. Allows for lazy loading until\n   * require'd without pausing dependency loading, which is needed on old IE.\n   *\n   * @param {!Function} callback\n   */\n  goog.LoadController.prototype.defer = function(callback) {};\n\n\n  /**\n   * @return {boolean}\n   */\n  goog.LoadController.prototype.areDepsLoaded = function() {};\n\n\n  /**\n   * Basic super class for all dependencies Closure Library can load.\n   *\n   * This default implementation is designed to load untranspiled, non-module\n   * scripts in a web broswer.\n   *\n   * For transpiled non-goog.module files {@see goog.TranspiledDependency}.\n   * For goog.modules see {@see goog.GoogModuleDependency}.\n   * For untranspiled ES6 modules {@see goog.Es6ModuleDependency}.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   */\n  goog.Dependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    /** @const */\n    this.path = path;\n    /** @const */\n    this.relativePath = relativePath;\n    /** @const */\n    this.provides = provides;\n    /** @const */\n    this.requires = requires;\n    /** @const */\n    this.loadFlags = loadFlags;\n    /** @private {boolean} */\n    this.loaded_ = false;\n    /** @private {!Array<function()>} */\n    this.loadCallbacks_ = [];\n  };\n\n\n  /**\n   * @return {string} The pathname part of this dependency's path if it is a\n   *     URI.\n   */\n  goog.Dependency.prototype.getPathName = function() {\n    var pathName = this.path;\n    var protocolIndex = pathName.indexOf('://');\n    if (protocolIndex >= 0) {\n      pathName = pathName.substring(protocolIndex + 3);\n      var slashIndex = pathName.indexOf('/');\n      if (slashIndex >= 0) {\n        pathName = pathName.substring(slashIndex + 1);\n      }\n    }\n    return pathName;\n  };\n\n\n  /**\n   * @param {function()} callback Callback to fire as soon as this has loaded.\n   * @final\n   */\n  goog.Dependency.prototype.onLoad = function(callback) {\n    if (this.loaded_) {\n      callback();\n    } else {\n      this.loadCallbacks_.push(callback);\n    }\n  };\n\n\n  /**\n   * Marks this dependency as loaded and fires any callbacks registered with\n   * onLoad.\n   * @final\n   */\n  goog.Dependency.prototype.loaded = function() {\n    this.loaded_ = true;\n    var callbacks = this.loadCallbacks_;\n    this.loadCallbacks_ = [];\n    for (var i = 0; i < callbacks.length; i++) {\n      callbacks[i]();\n    }\n  };\n\n\n  /**\n   * Whether or not document.written / appended script tags should be deferred.\n   *\n   * @private {boolean}\n   */\n  goog.Dependency.defer_ = false;\n\n\n  /**\n   * Map of script ready / state change callbacks. Old IE cannot handle putting\n   * these properties on goog.global.\n   *\n   * @private @const {!Object<string, function(?):undefined>}\n   */\n  goog.Dependency.callbackMap_ = {};\n\n\n  /**\n   * @param {function(...?):?} callback\n   * @return {string}\n   * @private\n   */\n  goog.Dependency.registerCallback_ = function(callback) {\n    var key = Math.random().toString(32);\n    goog.Dependency.callbackMap_[key] = callback;\n    return key;\n  };\n\n\n  /**\n   * @param {string} key\n   * @private\n   */\n  goog.Dependency.unregisterCallback_ = function(key) {\n    delete goog.Dependency.callbackMap_[key];\n  };\n\n\n  /**\n   * @param {string} key\n   * @param {...?} var_args\n   * @private\n   * @suppress {unusedPrivateMembers}\n   */\n  goog.Dependency.callback_ = function(key, var_args) {\n    if (key in goog.Dependency.callbackMap_) {\n      var callback = goog.Dependency.callbackMap_[key];\n      var args = [];\n      for (var i = 1; i < arguments.length; i++) {\n        args.push(arguments[i]);\n      }\n      callback.apply(undefined, args);\n    } else {\n      var errorMessage = 'Callback key ' + key +\n          ' does not exist (was base.js loaded more than once?).';\n      throw Error(errorMessage);\n    }\n  };\n\n\n  /**\n   * Starts loading this dependency. This dependency can pause loading if it\n   * needs to and resume it later via the controller interface.\n   *\n   * When this is loaded it should call controller.loaded(). Note that this will\n   * end up calling the loaded method of this dependency; there is no need to\n   * call it explicitly.\n   *\n   * @param {!goog.LoadController} controller\n   */\n  goog.Dependency.prototype.load = function(controller) {\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    if (!goog.inHtmlDocument_()) {\n      goog.logToConsole_(\n          'Cannot use default debug loader outside of HTML documents.');\n      if (this.relativePath == 'deps.js') {\n        // Some old code is relying on base.js auto loading deps.js failing with\n        // no error before later setting CLOSURE_IMPORT_SCRIPT.\n        // CLOSURE_IMPORT_SCRIPT should be set *before* base.js is loaded, or\n        // CLOSURE_NO_DEPS set to true.\n        goog.logToConsole_(\n            'Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, ' +\n            'or setting CLOSURE_NO_DEPS to true.');\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n\n    // If the user tries to require a new symbol after document load,\n    // something has gone terribly wrong. Doing a document.write would\n    // wipe out the page. This does not apply to the CSP-compliant method\n    // of writing script tags.\n    if (doc.readyState == 'complete' &&\n        !goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {\n      // Certain test frameworks load base.js multiple times, which tries\n      // to write deps.js each time. If that happens, just fail silently.\n      // These frameworks wipe the page between each load of base.js, so this\n      // is OK.\n      var isDeps = /\\bdeps.js$/.test(this.path);\n      if (isDeps) {\n        controller.loaded();\n        return;\n      } else {\n        throw Error('Cannot write \"' + this.path + '\" after document load');\n      }\n    }\n\n    if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&\n        goog.isDocumentLoading_()) {\n      var key = goog.Dependency.registerCallback_(function(script) {\n        if (!goog.DebugLoader_.IS_OLD_IE_ || script.readyState == 'complete') {\n          goog.Dependency.unregisterCallback_(key);\n          controller.loaded();\n        }\n      });\n      var nonceAttr = !goog.DebugLoader_.IS_OLD_IE_ && goog.getScriptNonce() ?\n          ' nonce=\"' + goog.getScriptNonce() + '\"' :\n          '';\n      var event =\n          goog.DebugLoader_.IS_OLD_IE_ ? 'onreadystatechange' : 'onload';\n      var defer = goog.Dependency.defer_ ? 'defer' : '';\n      var script = '<script src=\"' + this.path + '\" ' + event +\n          '=\"goog.Dependency.callback_(\\'' + key +\n          '\\', this)\" type=\"text/javascript\" ' + defer + nonceAttr + '><' +\n          '/script>';\n      doc.write(\n          goog.TRUSTED_TYPES_POLICY_ ?\n              goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n              script);\n    } else {\n      var scriptEl =\n          /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n      scriptEl.defer = goog.Dependency.defer_;\n      scriptEl.async = false;\n      scriptEl.type = 'text/javascript';\n\n      // If CSP nonces are used, propagate them to dynamically created scripts.\n      // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n      var nonce = goog.getScriptNonce();\n      if (nonce) {\n        scriptEl.setAttribute('nonce', nonce);\n      }\n\n      if (goog.DebugLoader_.IS_OLD_IE_) {\n        // Execution order is not guaranteed on old IE, halt loading and write\n        // these scripts one at a time, after each loads.\n        controller.pause();\n        scriptEl.onreadystatechange = function() {\n          if (scriptEl.readyState == 'loaded' ||\n              scriptEl.readyState == 'complete') {\n            controller.loaded();\n            controller.resume();\n          }\n        };\n      } else {\n        scriptEl.onload = function() {\n          scriptEl.onload = null;\n          controller.loaded();\n        };\n      }\n\n      scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n          goog.TRUSTED_TYPES_POLICY_.createScriptURL(this.path) :\n          this.path;\n      doc.head.appendChild(scriptEl);\n    }\n  };\n\n\n  /**\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides Should be an empty array.\n   *     TODO(johnplaisted) add support for adding closure namespaces to ES6\n   *     modules for interop purposes.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   * @extends {goog.Dependency}\n   */\n  goog.Es6ModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.Es6ModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n  };\n  goog.inherits(goog.Es6ModuleDependency, goog.Dependency);\n\n\n  /** @override */\n  goog.Es6ModuleDependency.prototype.load = function(controller) {\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    if (!goog.inHtmlDocument_()) {\n      goog.logToConsole_(\n          'Cannot use default debug loader outside of HTML documents.');\n      controller.pause();\n      return;\n    }\n\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n\n    var dep = this;\n\n    // TODO(johnplaisted): Does document.writing really speed up anything? Any\n    // difference between this and just waiting for interactive mode and then\n    // appending?\n    function write(src, contents) {\n      if (contents) {\n        var script = '<script type=\"module\" crossorigin>' + contents + '</' +\n            'script>';\n        doc.write(\n            goog.TRUSTED_TYPES_POLICY_ ?\n                goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n                script);\n      } else {\n        var script = '<script type=\"module\" crossorigin src=\"' + src + '\"></' +\n            'script>';\n        doc.write(\n            goog.TRUSTED_TYPES_POLICY_ ?\n                goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n                script);\n      }\n    }\n\n    function append(src, contents) {\n      var scriptEl =\n          /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n      scriptEl.defer = true;\n      scriptEl.async = false;\n      scriptEl.type = 'module';\n      scriptEl.setAttribute('crossorigin', true);\n\n      // If CSP nonces are used, propagate them to dynamically created scripts.\n      // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n      var nonce = goog.getScriptNonce();\n      if (nonce) {\n        scriptEl.setAttribute('nonce', nonce);\n      }\n\n      if (contents) {\n        scriptEl.textContent = goog.TRUSTED_TYPES_POLICY_ ?\n            goog.TRUSTED_TYPES_POLICY_.createScript(contents) :\n            contents;\n      } else {\n        scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n            goog.TRUSTED_TYPES_POLICY_.createScriptURL(src) :\n            src;\n      }\n\n      doc.head.appendChild(scriptEl);\n    }\n\n    var create;\n\n    if (goog.isDocumentLoading_()) {\n      create = write;\n      // We can ONLY call document.write if we are guaranteed that any\n      // non-module script tags document.written after this are deferred.\n      // Small optimization, in theory document.writing is faster.\n      goog.Dependency.defer_ = true;\n    } else {\n      create = append;\n    }\n\n    // Write 4 separate tags here:\n    // 1) Sets the module state at the correct time (just before execution).\n    // 2) A src node for this, which just hopefully lets the browser load it a\n    //    little early (no need to parse #3).\n    // 3) Import the module and register it.\n    // 4) Clear the module state at the correct time. Guaranteed to run even\n    //    if there is an error in the module (#3 will not run if there is an\n    //    error in the module).\n    var beforeKey = goog.Dependency.registerCallback_(function() {\n      goog.Dependency.unregisterCallback_(beforeKey);\n      controller.setModuleState(goog.ModuleType.ES6);\n    });\n    create(undefined, 'goog.Dependency.callback_(\"' + beforeKey + '\")');\n\n    // TODO(johnplaisted): Does this really speed up anything?\n    create(this.path, undefined);\n\n    var registerKey = goog.Dependency.registerCallback_(function(exports) {\n      goog.Dependency.unregisterCallback_(registerKey);\n      controller.registerEs6ModuleExports(\n          dep.path, exports, goog.moduleLoaderState_.moduleName);\n    });\n    create(\n        undefined,\n        'import * as m from \"' + this.path + '\"; goog.Dependency.callback_(\"' +\n            registerKey + '\", m)');\n\n    var afterKey = goog.Dependency.registerCallback_(function() {\n      goog.Dependency.unregisterCallback_(afterKey);\n      controller.clearModuleState();\n      controller.loaded();\n    });\n    create(undefined, 'goog.Dependency.callback_(\"' + afterKey + '\")');\n  };\n\n\n  /**\n   * Superclass of any dependency that needs to be loaded into memory,\n   * transformed, and then eval'd (goog.modules and transpiled files).\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor @abstract\n   * @extends {goog.Dependency}\n   */\n  goog.TransformedDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.TransformedDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @private {?string} */\n    this.contents_ = null;\n\n    /**\n     * Whether to lazily make the synchronous XHR (when goog.require'd) or make\n     * the synchronous XHR when initially loading. On FireFox 61 there is a bug\n     * where an ES6 module cannot make a synchronous XHR (rather, it can, but if\n     * it does then no other ES6 modules will load after).\n     *\n     * tl;dr we lazy load due to bugs on older browsers and eager load due to\n     * bugs on newer ones.\n     *\n     * https://bugzilla.mozilla.org/show_bug.cgi?id=1477090\n     *\n     * @private @const {boolean}\n     */\n    this.lazyFetch_ = !goog.inHtmlDocument_() ||\n        !('noModule' in goog.global.document.createElement('script'));\n  };\n  goog.inherits(goog.TransformedDependency, goog.Dependency);\n\n\n  /** @override */\n  goog.TransformedDependency.prototype.load = function(controller) {\n    var dep = this;\n\n    function fetch() {\n      dep.contents_ = goog.loadFileSync_(dep.path);\n\n      if (dep.contents_) {\n        dep.contents_ = dep.transform(dep.contents_);\n        if (dep.contents_) {\n          dep.contents_ += '\\n//# sourceURL=' + dep.path;\n        }\n      }\n    }\n\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      fetch();\n      if (this.contents_ &&\n          goog.global.CLOSURE_IMPORT_SCRIPT('', this.contents_)) {\n        this.contents_ = null;\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n\n    var isEs6 = this.loadFlags['module'] == goog.ModuleType.ES6;\n\n    if (!this.lazyFetch_) {\n      fetch();\n    }\n\n    function load() {\n      if (dep.lazyFetch_) {\n        fetch();\n      }\n\n      if (!dep.contents_) {\n        // loadFileSync_ or transform are responsible. Assume they logged an\n        // error.\n        return;\n      }\n\n      if (isEs6) {\n        controller.setModuleState(goog.ModuleType.ES6);\n      }\n\n      var namespace;\n\n      try {\n        var contents = dep.contents_;\n        dep.contents_ = null;\n        goog.globalEval(contents);\n        if (isEs6) {\n          namespace = goog.moduleLoaderState_.moduleName;\n        }\n      } finally {\n        if (isEs6) {\n          controller.clearModuleState();\n        }\n      }\n\n      if (isEs6) {\n        // Due to circular dependencies this may not be available for require\n        // right now.\n        goog.global['$jscomp']['require']['ensure'](\n            [dep.getPathName()], function() {\n              controller.registerEs6ModuleExports(\n                  dep.path,\n                  goog.global['$jscomp']['require'](dep.getPathName()),\n                  namespace);\n            });\n      }\n\n      controller.loaded();\n    }\n\n    // Do not fetch now; in FireFox 47 the synchronous XHR doesn't block all\n    // events. If we fetched now and then document.write'd the contents the\n    // document.write would be an eval and would execute too soon! Instead write\n    // a script tag to fetch and eval synchronously at the correct time.\n    function fetchInOwnScriptThenLoad() {\n      /** @type {!HTMLDocument} */\n      var doc = goog.global.document;\n\n      var key = goog.Dependency.registerCallback_(function() {\n        goog.Dependency.unregisterCallback_(key);\n        load();\n      });\n\n      var script = '<script type=\"text/javascript\">' +\n          goog.protectScriptTag_('goog.Dependency.callback_(\"' + key + '\");') +\n          '</' +\n          'script>';\n      doc.write(\n          goog.TRUSTED_TYPES_POLICY_ ?\n              goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n              script);\n    }\n\n    // If one thing is pending it is this.\n    var anythingElsePending = controller.pending().length > 1;\n\n    // If anything else is loading we need to lazy load due to bugs in old IE.\n    // Specifically script tags with src and script tags with contents could\n    // execute out of order if document.write is used, so we cannot use\n    // document.write. Do not pause here; it breaks old IE as well.\n    var useOldIeWorkAround =\n        anythingElsePending && goog.DebugLoader_.IS_OLD_IE_;\n\n    // Additionally if we are meant to defer scripts but the page is still\n    // loading (e.g. an ES6 module is loading) then also defer. Or if we are\n    // meant to defer and anything else is pending then defer (those may be\n    // scripts that did not need transformation and are just script tags with\n    // defer set to true, and we need to evaluate after that deferred script).\n    var needsAsyncLoading = goog.Dependency.defer_ &&\n        (anythingElsePending || goog.isDocumentLoading_());\n\n    if (useOldIeWorkAround || needsAsyncLoading) {\n      // Note that we only defer when we have to rather than 100% of the time.\n      // Always defering would work, but then in theory the order of\n      // goog.require calls would then matter. We want to enforce that most of\n      // the time the order of the require calls does not matter.\n      controller.defer(function() {\n        load();\n      });\n      return;\n    }\n    // TODO(johnplaisted): Externs are missing onreadystatechange for\n    // HTMLDocument.\n    /** @type {?} */\n    var doc = goog.global.document;\n\n    var isInternetExplorer =\n        goog.inHtmlDocument_() && 'ActiveXObject' in goog.global;\n\n    // Don't delay in any version of IE. There's bug around this that will\n    // cause out of order script execution. This means that on older IE ES6\n    // modules will load too early (while the document is still loading + the\n    // dom is not available). The other option is to load too late (when the\n    // document is complete and the onload even will never fire). This seems\n    // to be the lesser of two evils as scripts already act like the former.\n    if (isEs6 && goog.inHtmlDocument_() && goog.isDocumentLoading_() &&\n        !isInternetExplorer) {\n      goog.Dependency.defer_ = true;\n      // Transpiled ES6 modules still need to load like regular ES6 modules,\n      // aka only after the document is interactive.\n      controller.pause();\n      var oldCallback = doc.onreadystatechange;\n      doc.onreadystatechange = function() {\n        if (doc.readyState == 'interactive') {\n          doc.onreadystatechange = oldCallback;\n          load();\n          controller.resume();\n        }\n        if (goog.isFunction(oldCallback)) {\n          oldCallback.apply(undefined, arguments);\n        }\n      };\n    } else {\n      // Always eval on old IE.\n      if (goog.DebugLoader_.IS_OLD_IE_ || !goog.inHtmlDocument_() ||\n          !goog.isDocumentLoading_()) {\n        load();\n      } else {\n        fetchInOwnScriptThenLoad();\n      }\n    }\n  };\n\n\n  /**\n   * @param {string} contents\n   * @return {string}\n   * @abstract\n   */\n  goog.TransformedDependency.prototype.transform = function(contents) {};\n\n\n  /**\n   * Any non-goog.module dependency which needs to be transpiled before eval.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.TranspiledDependency = function(\n      path, relativePath, provides, requires, loadFlags, transpiler) {\n    goog.TranspiledDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @protected @const*/\n    this.transpiler = transpiler;\n  };\n  goog.inherits(goog.TranspiledDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.TranspiledDependency.prototype.transform = function(contents) {\n    // Transpile with the pathname so that ES6 modules are domain agnostic.\n    return this.transpiler.transpile(contents, this.getPathName());\n  };\n\n\n  /**\n   * An ES6 module dependency that was transpiled to a jscomp module outside\n   * of the debug loader, e.g. server side.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.PreTranspiledEs6ModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.PreTranspiledEs6ModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n  };\n  goog.inherits(\n      goog.PreTranspiledEs6ModuleDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.PreTranspiledEs6ModuleDependency.prototype.transform = function(\n      contents) {\n    return contents;\n  };\n\n\n  /**\n   * A goog.module, transpiled or not. Will always perform some minimal\n   * transformation even when not transpiled to wrap in a goog.loadModule\n   * statement.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @param {boolean} needsTranspile\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.GoogModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags, needsTranspile,\n      transpiler) {\n    goog.GoogModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @private @const */\n    this.needsTranspile_ = needsTranspile;\n    /** @private @const */\n    this.transpiler_ = transpiler;\n  };\n  goog.inherits(goog.GoogModuleDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.GoogModuleDependency.prototype.transform = function(contents) {\n    if (this.needsTranspile_) {\n      contents = this.transpiler_.transpile(contents, this.getPathName());\n    }\n\n    if (!goog.LOAD_MODULE_USING_EVAL || goog.global.JSON === undefined) {\n      return '' +\n          'goog.loadModule(function(exports) {' +\n          '\"use strict\";' + contents +\n          '\\n' +  // terminate any trailing single line comment.\n          ';return exports' +\n          '});' +\n          '\\n//# sourceURL=' + this.path + '\\n';\n    } else {\n      return '' +\n          'goog.loadModule(' +\n          goog.global.JSON.stringify(\n              contents + '\\n//# sourceURL=' + this.path + '\\n') +\n          ');';\n    }\n  };\n\n\n  /**\n   * Whether the browser is IE9 or earlier, which needs special handling\n   * for deferred modules.\n   * @const @private {boolean}\n   */\n  goog.DebugLoader_.IS_OLD_IE_ = !!(\n      !goog.global.atob && goog.global.document && goog.global.document['all']);\n\n\n  /**\n   * @param {string} relPath\n   * @param {!Array<string>|undefined} provides\n   * @param {!Array<string>} requires\n   * @param {boolean|!Object<string>=} opt_loadFlags\n   * @see goog.addDependency\n   */\n  goog.DebugLoader_.prototype.addDependency = function(\n      relPath, provides, requires, opt_loadFlags) {\n    provides = provides || [];\n    relPath = relPath.replace(/\\\\/g, '/');\n    var path = goog.normalizePath_(goog.basePath + relPath);\n    if (!opt_loadFlags || typeof opt_loadFlags === 'boolean') {\n      opt_loadFlags = opt_loadFlags ? {'module': goog.ModuleType.GOOG} : {};\n    }\n    var dep = this.factory_.createDependency(\n        path, relPath, provides, requires, opt_loadFlags,\n        goog.transpiler_.needsTranspile(\n            opt_loadFlags['lang'] || 'es3', opt_loadFlags['module']));\n    this.dependencies_[path] = dep;\n    for (var i = 0; i < provides.length; i++) {\n      this.idToPath_[provides[i]] = path;\n    }\n    this.idToPath_[relPath] = path;\n  };\n\n\n  /**\n   * Creates goog.Dependency instances for the debug loader to load.\n   *\n   * Should be overridden to have the debug loader use custom subclasses of\n   * goog.Dependency.\n   *\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   */\n  goog.DependencyFactory = function(transpiler) {\n    /** @protected @const */\n    this.transpiler = transpiler;\n  };\n\n\n  /**\n   * @param {string} path Absolute path of the file.\n   * @param {string} relativePath Path relative to closure’s base.js.\n   * @param {!Array<string>} provides Array of provided goog.provide/module ids.\n   * @param {!Array<string>} requires Array of required goog.provide/module /\n   *     relative ES6 module paths.\n   * @param {!Object<string, string>} loadFlags\n   * @param {boolean} needsTranspile True if the file needs to be transpiled\n   *     per the goog.Transpiler.\n   * @return {!goog.Dependency}\n   */\n  goog.DependencyFactory.prototype.createDependency = function(\n      path, relativePath, provides, requires, loadFlags, needsTranspile) {\n\n    if (loadFlags['module'] == goog.ModuleType.GOOG) {\n      return new goog.GoogModuleDependency(\n          path, relativePath, provides, requires, loadFlags, needsTranspile,\n          this.transpiler);\n    } else if (needsTranspile) {\n      return new goog.TranspiledDependency(\n          path, relativePath, provides, requires, loadFlags, this.transpiler);\n    } else {\n      if (loadFlags['module'] == goog.ModuleType.ES6) {\n        if (goog.TRANSPILE == 'never' && goog.ASSUME_ES_MODULES_TRANSPILED) {\n          return new goog.PreTranspiledEs6ModuleDependency(\n              path, relativePath, provides, requires, loadFlags);\n        } else {\n          return new goog.Es6ModuleDependency(\n              path, relativePath, provides, requires, loadFlags);\n        }\n      } else {\n        return new goog.Dependency(\n            path, relativePath, provides, requires, loadFlags);\n      }\n    }\n  };\n\n\n  /** @private @const */\n  goog.debugLoader_ = new goog.DebugLoader_();\n\n\n  /**\n   * Loads the Closure Dependency file.\n   *\n   * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n   * loaded, setDependencyFactory called, and then this called. i.e. allows\n   * custom loading of the deps file.\n   */\n  goog.loadClosureDeps = function() {\n    goog.debugLoader_.loadClosureDeps();\n  };\n\n\n  /**\n   * Sets the dependency factory, which can be used to create custom\n   * goog.Dependency implementations to control how dependencies are loaded.\n   *\n   * Note: if you wish to call this function and provide your own implemnetation\n   * it is a wise idea to set CLOSURE_NO_DEPS to true, otherwise the dependency\n   * file and all of its goog.addDependency calls will use the default factory.\n   * You can call goog.loadClosureDeps to load the Closure dependency file\n   * later, after your factory is injected.\n   *\n   * @param {!goog.DependencyFactory} factory\n   */\n  goog.setDependencyFactory = function(factory) {\n    goog.debugLoader_.setDependencyFactory(factory);\n  };\n\n\n  if (!goog.global.CLOSURE_NO_DEPS) {\n    goog.debugLoader_.loadClosureDeps();\n  }\n\n\n  /**\n   * Bootstraps the given namespaces and calls the callback once they are\n   * available either via goog.require. This is a replacement for using\n   * `goog.require` to bootstrap Closure JavaScript. Previously a `goog.require`\n   * in an HTML file would guarantee that the require'd namespace was available\n   * in the next immediate script tag. With ES6 modules this no longer a\n   * guarantee.\n   *\n   * @param {!Array<string>} namespaces\n   * @param {function(): ?} callback Function to call once all the namespaces\n   *     have loaded. Always called asynchronously.\n   */\n  goog.bootstrap = function(namespaces, callback) {\n    goog.debugLoader_.bootstrap(namespaces, callback);\n  };\n}\n\n\n/**\n * @define {string} Trusted Types policy name. If non-empty then Closure will\n * use Trusted Types.\n */\ngoog.TRUSTED_TYPES_POLICY_NAME =\n    goog.define('goog.TRUSTED_TYPES_POLICY_NAME', '');\n\n\n/**\n * Returns the parameter.\n * @param {string} s\n * @return {string}\n * @private\n */\ngoog.identity_ = function(s) {\n  return s;\n};\n\n\n/**\n * Creates Trusted Types policy if Trusted Types are supported by the browser.\n * The policy just blesses any string as a Trusted Type. It is not visibility\n * restricted because anyone can also call TrustedTypes.createPolicy directly.\n * However, the allowed names should be restricted by a HTTP header and the\n * reference to the created policy should be visibility restricted.\n * @param {string} name\n * @return {?TrustedTypePolicy}\n */\ngoog.createTrustedTypesPolicy = function(name) {\n  var policy = null;\n  // TODO(koto): Remove window.TrustedTypes variant when the newer API ships.\n  var policyFactory = goog.global.trustedTypes || goog.global.TrustedTypes;\n  if (!policyFactory || !policyFactory.createPolicy) {\n    return policy;\n  }\n  // TrustedTypes.createPolicy throws if called with a name that is already\n  // registered, even in report-only mode. Until the API changes, catch the\n  // error not to break the applications functionally. In such case, the code\n  // will fall back to using regular Safe Types.\n  // TODO(koto): Remove catching once createPolicy API stops throwing.\n  try {\n    policy = policyFactory.createPolicy(name, {\n      createHTML: goog.identity_,\n      createScript: goog.identity_,\n      createScriptURL: goog.identity_,\n      createURL: goog.identity_\n    });\n  } catch (e) {\n    goog.logToConsole_(e.message);\n  }\n  return policy;\n};\n\n\n/** @private @const {?TrustedTypePolicy} */\ngoog.TRUSTED_TYPES_POLICY_ = goog.TRUSTED_TYPES_POLICY_NAME ?\n    goog.createTrustedTypesPolicy(goog.TRUSTED_TYPES_POLICY_NAME + '#base') :\n    null;\n",null,null,"/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines developer-visible errors for Firebase Auth APIs.\n */\n\n\ngoog.provide('fireauth.AuthError');\ngoog.provide('fireauth.authenum');\ngoog.provide('fireauth.authenum.Error');\n\n\n\n/**\n * Error that can be returned to the developer.\n * @param {!fireauth.authenum.Error} code The short error code.\n * @param {?string=} message The human-readable message.\n * @param {?Object=} serverResponse The raw server response.\n * @constructor\n * @extends {Error}\n */\nfireauth.AuthError = function(code, message, serverResponse) {\n  this['code'] = fireauth.AuthError.ERROR_CODE_PREFIX + code;\n  this.message = message || fireauth.AuthError.MESSAGES_[code] || '';\n  this.serverResponse = serverResponse || null;\n};\ngoog.inherits(fireauth.AuthError, Error);\n\n\n/**\n * @return {!Object} The plain object form of the error.\n */\nfireauth.AuthError.prototype.toPlainObject = function() {\n  var obj = {\n    'code': this['code'],\n    'message': this.message\n  };\n  if (this.serverResponse) {\n    obj['serverResponse'] = this.serverResponse;\n  }\n  return obj;\n};\n\n\n/**\n * @return {!Object} The plain object form of the error. This is used by\n *     JSON.toStringify() to return the stringified representation of the error;\n * @override\n */\nfireauth.AuthError.prototype.toJSON = function() {\n  // Return the plain object representation in case JSON.stringify is called on\n  // an auth error instance.\n  return this.toPlainObject();\n};\n\n\n/**\n * @param {?Object|undefined} response The object response to convert to a\n *     fireauth.AuthError.\n * @return {?fireauth.AuthError} The error representation of the response.\n */\nfireauth.AuthError.fromPlainObject = function(response) {\n  var fullCode = response && response['code'];\n  if (fullCode) {\n    // Remove prefix from name.\n    var code = fullCode.substring(\n        fireauth.AuthError.ERROR_CODE_PREFIX.length);\n    return new fireauth.AuthError(\n        /** @type {!fireauth.authenum.Error} */ (code),\n        response['message'],\n        response['serverResponse']);\n  }\n  return null;\n};\n\n\n/**\n * Takes in an error and translates a specific error code to another one if\n * found in the current error.\n * @param {*} error The error thrown.\n * @param {!fireauth.authenum.Error} fromCode The error code to translate from.\n * @param {!fireauth.authenum.Error} toCode The error code to translate to.\n * @return {*} The mapped error message.\n */\nfireauth.AuthError.translateError = function(error, fromCode, toCode) {\n  if (error &&\n      error['code'] &&\n      error['code'] == fireauth.AuthError.ERROR_CODE_PREFIX + fromCode) {\n    // Translate the error to the new one.\n    return new fireauth.AuthError(toCode);\n  }\n  // Return the same error if the fromCode is not found.\n  return error;\n};\n\n\n/**\n * The error prefix for fireauth.Auth errors.\n * @protected {string}\n */\nfireauth.AuthError.ERROR_CODE_PREFIX = 'auth/';\n\n\n/**\n * Developer facing Firebase Auth error codes.\n * @enum {string}\n */\nfireauth.authenum.Error = {\n  ADMIN_ONLY_OPERATION: 'admin-restricted-operation',\n  ARGUMENT_ERROR: 'argument-error',\n  APP_NOT_AUTHORIZED: 'app-not-authorized',\n  APP_NOT_INSTALLED: 'app-not-installed',\n  CAPTCHA_CHECK_FAILED: 'captcha-check-failed',\n  CODE_EXPIRED: 'code-expired',\n  CORDOVA_NOT_READY: 'cordova-not-ready',\n  CORS_UNSUPPORTED: 'cors-unsupported',\n  CREDENTIAL_ALREADY_IN_USE: 'credential-already-in-use',\n  CREDENTIAL_MISMATCH: 'custom-token-mismatch',\n  CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'requires-recent-login',\n  DYNAMIC_LINK_NOT_ACTIVATED: 'dynamic-link-not-activated',\n  EMAIL_CHANGE_NEEDS_VERIFICATION: 'email-change-needs-verification',\n  EMAIL_EXISTS: 'email-already-in-use',\n  EXPIRED_OOB_CODE: 'expired-action-code',\n  EXPIRED_POPUP_REQUEST: 'cancelled-popup-request',\n  INTERNAL_ERROR: 'internal-error',\n  INVALID_API_KEY: 'invalid-api-key',\n  INVALID_APP_CREDENTIAL: 'invalid-app-credential',\n  INVALID_APP_ID: 'invalid-app-id',\n  INVALID_AUTH: 'invalid-user-token',\n  INVALID_AUTH_EVENT: 'invalid-auth-event',\n  INVALID_CERT_HASH: 'invalid-cert-hash',\n  INVALID_CODE: 'invalid-verification-code',\n  INVALID_CONTINUE_URI: 'invalid-continue-uri',\n  INVALID_CORDOVA_CONFIGURATION: 'invalid-cordova-configuration',\n  INVALID_CUSTOM_TOKEN: 'invalid-custom-token',\n  INVALID_DYNAMIC_LINK_DOMAIN: 'invalid-dynamic-link-domain',\n  INVALID_EMAIL: 'invalid-email',\n  INVALID_IDP_RESPONSE: 'invalid-credential',\n  INVALID_MESSAGE_PAYLOAD: 'invalid-message-payload',\n  INVALID_MFA_PENDING_CREDENTIAL: 'invalid-multi-factor-session',\n  INVALID_OAUTH_CLIENT_ID: 'invalid-oauth-client-id',\n  INVALID_OAUTH_PROVIDER: 'invalid-oauth-provider',\n  INVALID_OOB_CODE: 'invalid-action-code',\n  INVALID_ORIGIN: 'unauthorized-domain',\n  INVALID_PASSWORD: 'wrong-password',\n  INVALID_PERSISTENCE: 'invalid-persistence-type',\n  INVALID_PHONE_NUMBER: 'invalid-phone-number',\n  INVALID_PROVIDER_ID: 'invalid-provider-id',\n  INVALID_RECIPIENT_EMAIL: 'invalid-recipient-email',\n  INVALID_SENDER: 'invalid-sender',\n  INVALID_SESSION_INFO: 'invalid-verification-id',\n  INVALID_TENANT_ID: 'invalid-tenant-id',\n  MFA_ENROLLMENT_NOT_FOUND: 'multi-factor-info-not-found',\n  MFA_REQUIRED: 'multi-factor-auth-required',\n  MISSING_ANDROID_PACKAGE_NAME: 'missing-android-pkg-name',\n  MISSING_APP_CREDENTIAL: 'missing-app-credential',\n  MISSING_AUTH_DOMAIN: 'auth-domain-config-required',\n  MISSING_CODE: 'missing-verification-code',\n  MISSING_CONTINUE_URI: 'missing-continue-uri',\n  MISSING_IFRAME_START: 'missing-iframe-start',\n  MISSING_IOS_BUNDLE_ID: 'missing-ios-bundle-id',\n  MISSING_MFA_ENROLLMENT_ID: 'missing-multi-factor-info',\n  MISSING_MFA_PENDING_CREDENTIAL: 'missing-multi-factor-session',\n  MISSING_OR_INVALID_NONCE: 'missing-or-invalid-nonce',\n  MISSING_PHONE_NUMBER: 'missing-phone-number',\n  MISSING_SESSION_INFO: 'missing-verification-id',\n  MODULE_DESTROYED: 'app-deleted',\n  NEED_CONFIRMATION: 'account-exists-with-different-credential',\n  NETWORK_REQUEST_FAILED: 'network-request-failed',\n  NULL_USER: 'null-user',\n  NO_AUTH_EVENT: 'no-auth-event',\n  NO_SUCH_PROVIDER: 'no-such-provider',\n  OPERATION_NOT_ALLOWED: 'operation-not-allowed',\n  OPERATION_NOT_SUPPORTED: 'operation-not-supported-in-this-environment',\n  POPUP_BLOCKED: 'popup-blocked',\n  POPUP_CLOSED_BY_USER: 'popup-closed-by-user',\n  PROVIDER_ALREADY_LINKED: 'provider-already-linked',\n  QUOTA_EXCEEDED: 'quota-exceeded',\n  REDIRECT_CANCELLED_BY_USER: 'redirect-cancelled-by-user',\n  REDIRECT_OPERATION_PENDING: 'redirect-operation-pending',\n  REJECTED_CREDENTIAL: 'rejected-credential',\n  SECOND_FACTOR_EXISTS: 'second-factor-already-in-use',\n  SECOND_FACTOR_LIMIT_EXCEEDED: 'maximum-second-factor-count-exceeded',\n  TENANT_ID_MISMATCH: 'tenant-id-mismatch',\n  TIMEOUT: 'timeout',\n  TOKEN_EXPIRED: 'user-token-expired',\n  TOO_MANY_ATTEMPTS_TRY_LATER: 'too-many-requests',\n  UNAUTHORIZED_DOMAIN: 'unauthorized-continue-uri',\n  UNSUPPORTED_FIRST_FACTOR: 'unsupported-first-factor',\n  UNSUPPORTED_PERSISTENCE: 'unsupported-persistence-type',\n  UNSUPPORTED_TENANT_OPERATION: 'unsupported-tenant-operation',\n  UNVERIFIED_EMAIL: 'unverified-email',\n  USER_CANCELLED: 'user-cancelled',\n  USER_DELETED: 'user-not-found',\n  USER_DISABLED: 'user-disabled',\n  USER_MISMATCH: 'user-mismatch',\n  USER_SIGNED_OUT: 'user-signed-out',\n  WEAK_PASSWORD: 'weak-password',\n  WEB_STORAGE_UNSUPPORTED: 'web-storage-unsupported'\n};\n\n\n/**\n * Map from developer error codes to human-readable error messages.\n * @private {!Object<string, string>}\n */\nfireauth.AuthError.MESSAGES_ = {};\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.ADMIN_ONLY_OPERATION] =\n    'This operation is restricted to administrators only.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.ARGUMENT_ERROR] = '';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.APP_NOT_AUTHORIZED] =\n    'This app, identified by the domain where it\\'s hosted, is not ' +\n    'authorized to use Firebase Authentication with the provided API key. ' +\n    'Review your key configuration in the Google API console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.APP_NOT_INSTALLED] =\n    'The requested mobile application corresponding to the identifier (' +\n    'Android package name or iOS bundle ID) provided is not installed on ' +\n    'this device.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CAPTCHA_CHECK_FAILED] =\n    'The reCAPTCHA response token provided is either invalid, expired, ' +\n    'already used or the domain associated with it does not match the list ' +\n    'of whitelisted domains.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CODE_EXPIRED] =\n    'The SMS code has expired. Please re-send the verification code to try ' +\n    'again.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CORDOVA_NOT_READY] =\n    'Cordova framework is not ready.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CORS_UNSUPPORTED] =\n    'This browser is not supported.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE] =\n    'This credential is already associated with a different user account.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CREDENTIAL_MISMATCH] =\n    'The custom token corresponds to a different audience.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.CREDENTIAL_TOO_OLD_LOGIN_AGAIN] =\n    'This operation is sensitive and requires recent authentication. Log in ' +\n    'again before retrying this request.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.DYNAMIC_LINK_NOT_ACTIVATED] = 'Please activate ' +\n    'Dynamic Links in the Firebase Console and agree to the terms and ' +\n    'conditions.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.EMAIL_CHANGE_NEEDS_VERIFICATION] =\n    'Multi-factor users must always have a verified email.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EMAIL_EXISTS] =\n    'The email address is already in use by another account.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EXPIRED_OOB_CODE] =\n    'The action code has expired. ';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EXPIRED_POPUP_REQUEST] =\n    'This operation has been cancelled due to another conflicting popup ' +\n    'being opened.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INTERNAL_ERROR] =\n    'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_CREDENTIAL] =\n    'The phone verification request contains an invalid application verifier.' +\n    ' The reCAPTCHA token response is either invalid or expired.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_ID] =\n    'The mobile app identifier is not registed for the current project.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH] =\n    'This user\\'s credential isn\\'t valid for this project. This can happen ' +\n    'if the user\\'s token has been tampered with, or if the user isn\\'t for ' +\n    'the project associated with this API key.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH_EVENT] =\n    'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CODE] =\n    'The SMS verification code used to create the phone auth credential is ' +\n    'invalid. Please resend the verification code sms and be sure use the ' +\n    'verification code provided by the user.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CONTINUE_URI] =\n    'The continue URL provided in the request is invalid.';\nfireauth.AuthError.MESSAGES_[\n     fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION] = 'The following' +\n    ' Cordova plugins must be installed to enable OAuth sign-in: ' +\n    'cordova-plugin-buildinfo, cordova-universal-links-plugin, ' +\n    'cordova-plugin-browsertab, cordova-plugin-inappbrowser and ' +\n    'cordova-plugin-customurlscheme.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CUSTOM_TOKEN] =\n    'The custom token format is incorrect. Please check the documentation.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN] = 'The provided ' +\n    'dynamic link domain is not configured or authorized for the current ' +\n    'project.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_EMAIL] =\n    'The email address is badly formatted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_API_KEY] =\n    'Your API key is invalid, please check you have copied it correctly.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CERT_HASH] =\n    'The SHA-1 certificate hash provided is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_IDP_RESPONSE] =\n    'The supplied auth credential is malformed or has expired.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_MESSAGE_PAYLOAD] =\n    'The email template corresponding to this action contains invalid charac' +\n    'ters in its message. Please fix by going to the Auth email templates se' +\n    'ction in the Firebase Console.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.INVALID_MFA_PENDING_CREDENTIAL] =\n    'The request does not contain a valid proof of first factor successful ' +\n    'sign-in.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OAUTH_PROVIDER] =\n    'EmailAuthProvider is not supported for this operation. This operation ' +\n    'only supports OAuth providers.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OAUTH_CLIENT_ID] =\n    'The OAuth client ID provided is either invalid or does not match the ' +\n    'specified API key.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_ORIGIN] =\n    'This domain is not authorized for OAuth operations for your Firebase ' +\n    'project. Edit the list of authorized domains from the Firebase console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OOB_CODE] =\n    'The action code is invalid. This can happen if the code is malformed, ' +\n    'expired, or has already been used.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PASSWORD] =\n    'The password is invalid or the user does not have a password.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PERSISTENCE] =\n    'The specified persistence type is invalid. It can only be local, ' +\n    'session or none.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PHONE_NUMBER] =\n    'The format of the phone number provided is incorrect. Please enter the ' +\n    'phone number in a format that can be parsed into E.164 format. E.164 ' +\n    'phone numbers are written in the format [+][country code][subscriber ' +\n    'number including area code].';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PROVIDER_ID] =\n    'The specified provider ID is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_RECIPIENT_EMAIL] =\n    'The email corresponding to this action failed to send as the provided ' +\n    'recipient email address is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_SENDER] =\n    'The email template corresponding to this action contains an invalid sen' +\n    'der email or name. Please fix by going to the Auth email templates sect' +\n    'ion in the Firebase Console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_SESSION_INFO] =\n    'The verification ID used to create the phone auth credential is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_TENANT_ID] =\n    'The Auth instance\\'s tenant ID is invalid.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.MFA_ENROLLMENT_NOT_FOUND] = 'The user does not ' +\n    'have a second factor matching the identifier provided.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MFA_REQUIRED] =\n    'Proof of ownership of a second factor is required to complete sign-in.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME] = 'An Android ' +\n    'Package Name must be provided if the Android App is required to be ' +\n    'installed.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_AUTH_DOMAIN] =\n    'Be sure to include authDomain when calling firebase.initializeApp(), ' +\n    'by following the instructions in the Firebase console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_APP_CREDENTIAL] =\n    'The phone verification request is missing an application verifier ' +\n    'assertion. A reCAPTCHA response token needs to be provided.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_CODE] =\n    'The phone auth credential was created with an empty SMS verification ' +\n    'code.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_CONTINUE_URI] =\n    'A continue URL must be provided in the request.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_IFRAME_START] =\n    'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID] =\n    'An iOS Bundle ID must be provided if an App Store ID is provided.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.MISSING_MFA_ENROLLMENT_ID] =\n    'No second factor identifier is provided.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.MISSING_MFA_PENDING_CREDENTIAL] =\n    'The request is missing proof of first factor successful sign-in.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_OR_INVALID_NONCE] =\n    'The request does not contain a valid nonce. This can occur if the ' +\n    'SHA-256 hash of the provided raw nonce does not match the hashed nonce ' +\n    'in the ID token payload.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_PHONE_NUMBER] =\n    'To send verification codes, provide a phone number for the recipient.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_SESSION_INFO] =\n    'The phone auth credential was created with an empty verification ID.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MODULE_DESTROYED] =\n    'This instance of FirebaseApp has been deleted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NEED_CONFIRMATION] =\n    'An account already exists with the same email address but different ' +\n    'sign-in credentials. Sign in using a provider associated with this ' +\n    'email address.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NETWORK_REQUEST_FAILED] =\n    'A network error (such as timeout, interrupted connection or ' +\n    'unreachable host) has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NO_AUTH_EVENT] =\n    'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NO_SUCH_PROVIDER] =\n    'User was not linked to an account with the given provider.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NULL_USER] =\n    'A null user object was provided as the argument for an operation which ' +\n    'requires a non-null user object.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.OPERATION_NOT_ALLOWED] =\n    'The given sign-in provider is disabled for this Firebase project. ' +\n    'Enable it in the Firebase console, under the sign-in method tab of the ' +\n    'Auth section.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.OPERATION_NOT_SUPPORTED] =\n    'This operation is not supported in the environment this application is ' +\n    'running on. \"location.protocol\" must be http, https or chrome-extension' +\n    ' and web storage must be enabled.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.POPUP_BLOCKED] =\n    'Unable to establish a connection with the popup. It may have been ' +\n    'blocked by the browser.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.POPUP_CLOSED_BY_USER] =\n    'The popup has been closed by the user before finalizing the operation.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.PROVIDER_ALREADY_LINKED] =\n    'User can only be linked to one identity for the given provider.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.QUOTA_EXCEEDED] =\n    'The project\\'s quota for this operation has been exceeded.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.REDIRECT_CANCELLED_BY_USER] =\n    'The redirect operation has been cancelled by the user before finalizing.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.REDIRECT_OPERATION_PENDING] =\n    'A redirect sign-in operation is already pending.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.REJECTED_CREDENTIAL] =\n    'The request contains malformed or mismatching credentials.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.SECOND_FACTOR_EXISTS] =\n    'The second factor is already enrolled on this account.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.SECOND_FACTOR_LIMIT_EXCEEDED] =\n    'The maximum allowed number of second factors on a user has been exceeded.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.TENANT_ID_MISMATCH] =\n    'The provided tenant ID does not match the Auth instance\\'s tenant ID';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.TIMEOUT] =\n    'The operation has timed out.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.TOKEN_EXPIRED] =\n    'The user\\'s credential is no longer valid. The user must sign in again.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER] =\n    'We have blocked all requests from this device due to unusual activity. ' +\n    'Try again later.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNAUTHORIZED_DOMAIN] =\n    'The domain of the continue URL is not whitelisted.  Please whitelist ' +\n    'the domain in the Firebase console.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.UNSUPPORTED_FIRST_FACTOR] = 'Enrolling a second ' +\n    'factor or signing in with a multi-factor account requires sign-in with ' +\n    'a supported first factor.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNSUPPORTED_PERSISTENCE] =\n    'The current environment does not support the specified persistence type.';\nfireauth.AuthError.MESSAGES_[\n    fireauth.authenum.Error.UNSUPPORTED_TENANT_OPERATION] =\n    'This operation is not supported in a multi-tenant context.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNVERIFIED_EMAIL] =\n    'The operation requires a verified email.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_CANCELLED] =\n    'The user did not grant your application the permissions it requested.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_DELETED] =\n    'There is no user record corresponding to this identifier. The user may ' +\n    'have been deleted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_DISABLED] =\n    'The user account has been disabled by an administrator.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_MISMATCH] =\n    'The supplied credentials do not correspond to the previously signed in ' +\n    'user.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_SIGNED_OUT] = '';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.WEAK_PASSWORD] =\n    'The password must be 6 characters long or more.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED] =\n    'This browser is not supported or 3rd party cookies and data may be ' +\n    'disabled.';\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines all common constants and enums used by firebase-auth.\n */\n\ngoog.provide('fireauth.constants');\ngoog.provide('fireauth.constants.AuthEventType');\n\n\n/**\n * Enums for authentication operation types.\n * @enum {string}\n */\nfireauth.constants.OperationType = {\n  LINK: 'link',\n  REAUTHENTICATE: 'reauthenticate',\n  SIGN_IN: 'signIn'\n};\n\n\n/**\n * Events dispatched firebase.auth.Auth.\n * @enum {string}\n */\nfireauth.constants.AuthEventType = {\n  /** Dispatched when Firebase framework is changed. */\n  FRAMEWORK_CHANGED: 'frameworkChanged',\n  /** Dispatched when language code is changed. */\n  LANGUAGE_CODE_CHANGED: 'languageCodeChanged'\n};\n\n\n/**\n * Enums for all second factor types.\n * @enum {string}\n */\nfireauth.constants.SecondFactorType = {\n  PHONE: 'phone'\n};\n\n\n/**\n * The settings of an Auth endpoint. The fields are:\n * <ul>\n * <li>firebaseAuthEndpoint: defines the Firebase Auth backend endpoint for\n *     specified endpoint type.</li>\n * <li>secureTokenEndpoint: defines the secure token backend endpoint for\n *     specified endpoint type.</li>\n * <li>identityPlatformEndpoint: defines the Identity Platform backend endpoint\n *     for specified endpoint type.</li>\n * <li>id: defines the endpoint identifier.</li>\n * </ul>\n * @typedef {{\n *   firebaseAuthEndpoint: string,\n *   secureTokenEndpoint: string,\n *   identityPlatformEndpoint: string,\n *   id: string\n * }}\n */\nfireauth.constants.EndpointSettings;\n\n\n/**\n * The different endpoints for Firebase Auth backend.\n * @enum {!fireauth.constants.EndpointSettings}\n */\nfireauth.constants.Endpoint = {\n  // TODO: this is no longer needed now that client endpoint migration is\n  // completed.\n  BOQ: {\n    firebaseAuthEndpoint: 'https://staging-identitytoolkit.sandbox.googleapi' +\n        's.com/identitytoolkit/v3/relyingparty/',\n    secureTokenEndpoint: 'https://staging-securetoken.sandbox.googleapis.com' +\n        '/v1/token',\n    identityPlatformEndpoint:\n        'https://staging-identitytoolkit.sandbox.googleapis.com/v2/',\n    id: 'b'\n  },\n  PRODUCTION: {\n    firebaseAuthEndpoint: 'https://www.googleapis.com/identitytoolkit/v3/' +\n        'relyingparty/',\n    secureTokenEndpoint: 'https://securetoken.googleapis.com/v1/token',\n    identityPlatformEndpoint:\n        'https://identitytoolkit.googleapis.com/v2/',\n    id: 'p'\n  },\n  STAGING: {\n    firebaseAuthEndpoint: 'https://staging-www.sandbox.googleapis.com/' +\n        'identitytoolkit/v3/relyingparty/',\n    secureTokenEndpoint: 'https://staging-securetoken.sandbox.googleapis.com' +\n        '/v1/token',\n    identityPlatformEndpoint:\n        'https://staging-identitytoolkit.sandbox.googleapis.com/v2/',\n    id: 's'\n  },\n  TEST: {\n    firebaseAuthEndpoint: 'https://www-googleapis-test.sandbox.google.com/' +\n        'identitytoolkit/v3/relyingparty/',\n    secureTokenEndpoint: 'https://test-securetoken.sandbox.googleapis.com/v1' +\n        '/token',\n    identityPlatformEndpoint:\n        'https://test-identitytoolkit.sandbox.googleapis.com/v2/',\n    id: 't'\n  }\n};\n\n\n/**\n * Returns the endpoint specific RpcHandler configuration.\n * @param {?string=} opt_id The identifier of the endpoint type if available.\n * @return {?Object|undefined} The RpcHandler endpoint configuration object.\n */\nfireauth.constants.getEndpointConfig = function(opt_id) {\n  for (var endpointKey in fireauth.constants.Endpoint) {\n    if (fireauth.constants.Endpoint[endpointKey].id === opt_id) {\n      var endpoint = fireauth.constants.Endpoint[endpointKey];\n      return {\n        'firebaseEndpoint': endpoint.firebaseAuthEndpoint,\n        'secureTokenEndpoint': endpoint.secureTokenEndpoint,\n        'identityPlatformEndpoint': endpoint.identityPlatformEndpoint\n      };\n    }\n  }\n  return null;\n};\n\n\n/**\n * Returns the validated endpoint identifier. Undefined if the provided one is\n * invalid.\n * @param {?string=} opt_id The identifier of the endpoint type if available.\n * @return {string|undefined} The validated endpoint ID. If not valid,\n *     undefined.\n */\nfireauth.constants.getEndpointId = function(opt_id) {\n  if (opt_id && fireauth.constants.getEndpointConfig(opt_id)) {\n    return opt_id;\n  }\n  return undefined;\n};\n\n\n/** @const {string|undefined} The current client endpoint. */\nfireauth.constants.clientEndpoint = fireauth.constants.getEndpointId('__EID__');\n\n\n/** @const {string} The required SAML provider ID prefix. */\nfireauth.constants.SAML_PREFIX = 'saml.';\n\n\n/** @const {string} The required OIDC provider ID prefix. */\nfireauth.constants.OIDC_PREFIX = 'oidc.';\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating arrays.\n */\n\n\ngoog.provide('goog.array');\n\ngoog.require('goog.asserts');\n\n\n/**\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\n * rely on Array.prototype functions, if available.\n *\n * The Array.prototype functions can be defined by external libraries like\n * Prototype and setting this flag to false forces closure to use its own\n * goog.array implementation.\n *\n * If your javascript can be loaded by a third party site and you are wary about\n * relying on the prototype functions, specify\n * \"--define goog.NATIVE_ARRAY_PROTOTYPES=false\" to the JSCompiler.\n *\n * Setting goog.TRUSTED_SITE to false will automatically set\n * NATIVE_ARRAY_PROTOTYPES to false.\n */\ngoog.NATIVE_ARRAY_PROTOTYPES =\n    goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\n\n\n/**\n * @define {boolean} If true, JSCompiler will use the native implementation of\n * array functions where appropriate (e.g., `Array#filter`) and remove the\n * unused pure JS implementation.\n */\ngoog.array.ASSUME_NATIVE_FUNCTIONS = goog.define(\n    'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.last.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.peek = function(array) {\n  return array[array.length - 1];\n};\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.peek.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.last = goog.array.peek;\n\n// NOTE(arv): Since most of the array functions are generic it allows you to\n// pass an array-like object. Strings have a length and are considered array-\n// like. However, the 'in' operator does not work on strings so we cannot just\n// use the array path even if the browser supports indexing into strings. We\n// therefore end up splitting the string.\n\n\n/**\n * Returns the index of the first element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\n *\n * @param {IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {number=} opt_fromIndex The index at which to start the search. If\n *     omitted the search starts at index 0.\n * @return {number} The index of the first matching array element.\n * @template T\n */\ngoog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n    function(arr, obj, opt_fromIndex) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n    } :\n    function(arr, obj, opt_fromIndex) {\n      var fromIndex = opt_fromIndex == null ?\n          0 :\n          (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\n                               opt_fromIndex);\n\n      if (typeof arr === 'string') {\n        // Array.prototype.indexOf uses === so only strings should be found.\n        if (typeof obj !== 'string' || obj.length != 1) {\n          return -1;\n        }\n        return arr.indexOf(obj, fromIndex);\n      }\n\n      for (var i = fromIndex; i < arr.length; i++) {\n        if (i in arr && arr[i] === obj) return i;\n      }\n      return -1;\n    };\n\n\n/**\n * Returns the index of the last element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\n *\n * @param {!IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {?number=} opt_fromIndex The index at which to start the search. If\n *     omitted the search starts at the end of the array.\n * @return {number} The index of the last matching array element.\n * @template T\n */\ngoog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n    function(arr, obj, opt_fromIndex) {\n      goog.asserts.assert(arr.length != null);\n\n      // Firefox treats undefined and null as 0 in the fromIndex argument which\n      // leads it to always return -1\n      var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n      return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n    } :\n    function(arr, obj, opt_fromIndex) {\n      var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n\n      if (fromIndex < 0) {\n        fromIndex = Math.max(0, arr.length + fromIndex);\n      }\n\n      if (typeof arr === 'string') {\n        // Array.prototype.lastIndexOf uses === so only strings should be found.\n        if (typeof obj !== 'string' || obj.length != 1) {\n          return -1;\n        }\n        return arr.lastIndexOf(obj, fromIndex);\n      }\n\n      for (var i = fromIndex; i >= 0; i--) {\n        if (i in arr && arr[i] === obj) return i;\n      }\n      return -1;\n    };\n\n\n/**\n * Calls a function for each element in an array. Skips holes in the array.\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\n *\n * @param {IArrayLike<T>|string} arr Array or array like object over\n *     which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n *     element. This function takes 3 arguments (the element, the index and the\n *     array). The return value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @template T,S\n */\ngoog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      Array.prototype.forEach.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n        }\n      }\n    };\n\n\n/**\n * Calls a function for each element in an array, starting from the last\n * element rather than the first.\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n *     element. This function\n *     takes 3 arguments (the element, the index and the array). The return\n *     value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @template T,S\n */\ngoog.array.forEachRight = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = l - 1; i >= 0; --i) {\n    if (i in arr2) {\n      f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n    }\n  }\n};\n\n\n/**\n * Calls a function for each element in an array, and if the function returns\n * true adds the element to a new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\n *     every element. This function\n *     takes 3 arguments (the element, the index and the array) and must\n *     return a Boolean. If the return value is true the element is added to the\n *     result array. If it is false the element is not included.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {!Array<T>} a new array in which only elements that passed the test\n *     are present.\n * @template T,S\n */\ngoog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.filter.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var res = [];\n      var resLength = 0;\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          var val = arr2[i];  // in case f mutates arr2\n          if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\n            res[resLength++] = val;\n          }\n        }\n      }\n      return res;\n    };\n\n\n/**\n * Calls a function for each element in an array and inserts the result into a\n * new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\n *\n * @param {IArrayLike<VALUE>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\n *     for every element. This function takes 3 arguments (the element,\n *     the index and the array) and should return something. The result will be\n *     inserted into a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the results from f.\n * @template THIS, VALUE, RESULT\n */\ngoog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.map.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var res = new Array(l);\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n        }\n      }\n      return res;\n    };\n\n\n/**\n * Passes every element of an array into a function and accumulates the result.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\n *\n * For example:\n * var a = [1, 2, 3, 4];\n * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);\n * returns 10\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\n *     every element. This function\n *     takes 4 arguments (the function's previous result or the initial value,\n *     the value of the current array element, the current array index, and the\n *     array itself)\n *     function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj  The object to be used as the value of 'this'\n *     within f.\n * @return {R} Result of evaluating f repeatedly across the values of the array.\n * @template T,S,R\n */\ngoog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n    function(arr, f, val, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n      if (opt_obj) {\n        f = goog.bind(f, opt_obj);\n      }\n      return Array.prototype.reduce.call(arr, f, val);\n    } :\n    function(arr, f, val, opt_obj) {\n      var rval = val;\n      goog.array.forEach(arr, function(val, index) {\n        rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n      });\n      return rval;\n    };\n\n\n/**\n * Passes every element of an array into a function and accumulates the result,\n * starting from the last element and working towards the first.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\n *\n * For example:\n * var a = ['a', 'b', 'c'];\n * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\n * returns 'cba'\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\n *     every element. This function\n *     takes 4 arguments (the function's previous result or the initial value,\n *     the value of the current array element, the current array index, and the\n *     array itself)\n *     function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {R} Object returned as a result of evaluating f repeatedly across the\n *     values of the array.\n * @template T,S,R\n */\ngoog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n    function(arr, f, val, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n      goog.asserts.assert(f != null);\n      if (opt_obj) {\n        f = goog.bind(f, opt_obj);\n      }\n      return Array.prototype.reduceRight.call(arr, f, val);\n    } :\n    function(arr, f, val, opt_obj) {\n      var rval = val;\n      goog.array.forEachRight(arr, function(val, index) {\n        rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n      });\n      return rval;\n    };\n\n\n/**\n * Calls f for each element of an array. If any call returns true, some()\n * returns true (without checking the remaining elements). If all calls\n * return false, some() returns false.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj  The object to be used as the value of 'this'\n *     within f.\n * @return {boolean} true if any element passes the test.\n * @template T,S\n */\ngoog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.some.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n          return true;\n        }\n      }\n      return false;\n    };\n\n\n/**\n * Call f for each element of an array. If all calls return true, every()\n * returns true. If any call returns false, every() returns false and\n * does not continue to check the remaining elements.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {boolean} false if any element fails the test.\n * @template T,S\n */\ngoog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.every.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n          return false;\n        }\n      }\n      return true;\n    };\n\n\n/**\n * Counts the array elements that fulfill the predicate, i.e. for which the\n * callback function returns true. Skips holes in the array.\n *\n * @param {!IArrayLike<T>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\n *     every element. Takes 3 arguments (the element, the index and the array).\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @return {number} The number of the matching elements.\n * @template T,S\n */\ngoog.array.count = function(arr, f, opt_obj) {\n  var count = 0;\n  goog.array.forEach(arr, function(element, index, arr) {\n    if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\n      ++count;\n    }\n  }, opt_obj);\n  return count;\n};\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The first array element that passes the test, or null if no\n *     element is found.\n * @template T,S\n */\ngoog.array.find = function(arr, f, opt_obj) {\n  var i = goog.array.findIndex(arr, f, opt_obj);\n  return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the first array element that passes the test,\n *     or -1 if no element is found.\n * @template T,S\n */\ngoog.array.findIndex = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = 0; i < l; i++) {\n    if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The last array element that passes the test, or null if no\n *     element is found.\n * @template T,S\n */\ngoog.array.findRight = function(arr, f, opt_obj) {\n  var i = goog.array.findIndexRight(arr, f, opt_obj);\n  return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the last array element that passes the test,\n *     or -1 if no element is found.\n * @template T,S\n */\ngoog.array.findIndexRight = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = l - 1; i >= 0; i--) {\n    if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n\n/**\n * Whether the array contains the given object.\n * @param {IArrayLike<?>|string} arr The array to test for the presence of the\n *     element.\n * @param {*} obj The object for which to test.\n * @return {boolean} true if obj is present.\n */\ngoog.array.contains = function(arr, obj) {\n  return goog.array.indexOf(arr, obj) >= 0;\n};\n\n\n/**\n * Whether the array is empty.\n * @param {IArrayLike<?>|string} arr The array to test.\n * @return {boolean} true if empty.\n */\ngoog.array.isEmpty = function(arr) {\n  return arr.length == 0;\n};\n\n\n/**\n * Clears the array.\n * @param {IArrayLike<?>} arr Array or array like object to clear.\n */\ngoog.array.clear = function(arr) {\n  // For non real arrays we don't have the magic length so we delete the\n  // indices.\n  if (!Array.isArray(arr)) {\n    for (var i = arr.length - 1; i >= 0; i--) {\n      delete arr[i];\n    }\n  }\n  arr.length = 0;\n};\n\n\n/**\n * Pushes an item into an array, if it's not already in the array.\n * @param {Array<T>} arr Array into which to insert the item.\n * @param {T} obj Value to add.\n * @template T\n */\ngoog.array.insert = function(arr, obj) {\n  if (!goog.array.contains(arr, obj)) {\n    arr.push(obj);\n  }\n};\n\n\n/**\n * Inserts an object at the given index of the array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {*} obj The object to insert.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n *      treated as 0. A negative index is counted from the end of the array.\n */\ngoog.array.insertAt = function(arr, obj, opt_i) {\n  goog.array.splice(arr, opt_i, 0, obj);\n};\n\n\n/**\n * Inserts at the given index of the array, all elements of another array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {IArrayLike<?>} elementsToAdd The array of elements to add.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n *      treated as 0. A negative index is counted from the end of the array.\n */\ngoog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {\n  goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);\n};\n\n\n/**\n * Inserts an object into an array before a specified object.\n * @param {Array<T>} arr The array to modify.\n * @param {T} obj The object to insert.\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\n *     is omitted or not found, obj is inserted at the end of the array.\n * @template T\n */\ngoog.array.insertBefore = function(arr, obj, opt_obj2) {\n  var i;\n  if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {\n    arr.push(obj);\n  } else {\n    goog.array.insertAt(arr, obj, i);\n  }\n};\n\n\n/**\n * Removes the first occurrence of a particular value from an array.\n * @param {IArrayLike<T>} arr Array from which to remove\n *     value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\ngoog.array.remove = function(arr, obj) {\n  var i = goog.array.indexOf(arr, obj);\n  var rv;\n  if ((rv = i >= 0)) {\n    goog.array.removeAt(arr, i);\n  }\n  return rv;\n};\n\n\n/**\n * Removes the last occurrence of a particular value from an array.\n * @param {!IArrayLike<T>} arr Array from which to remove value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\ngoog.array.removeLast = function(arr, obj) {\n  var i = goog.array.lastIndexOf(arr, obj);\n  if (i >= 0) {\n    goog.array.removeAt(arr, i);\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes from an array the element at index i\n * @param {IArrayLike<?>} arr Array or array like object from which to\n *     remove value.\n * @param {number} i The index to remove.\n * @return {boolean} True if an element was removed.\n */\ngoog.array.removeAt = function(arr, i) {\n  goog.asserts.assert(arr.length != null);\n\n  // use generic form of splice\n  // splice returns the removed items and if successful the length of that\n  // will be 1\n  return Array.prototype.splice.call(arr, i, 1).length == 1;\n};\n\n\n/**\n * Removes the first value that satisfies the given condition.\n * @param {IArrayLike<T>} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {boolean} True if an element was removed.\n * @template T,S\n */\ngoog.array.removeIf = function(arr, f, opt_obj) {\n  var i = goog.array.findIndex(arr, f, opt_obj);\n  if (i >= 0) {\n    goog.array.removeAt(arr, i);\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes all values that satisfy the given condition.\n * @param {IArrayLike<T>} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The number of items removed\n * @template T,S\n */\ngoog.array.removeAllIf = function(arr, f, opt_obj) {\n  var removedCount = 0;\n  goog.array.forEachRight(arr, function(val, index) {\n    if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n      if (goog.array.removeAt(arr, index)) {\n        removedCount++;\n      }\n    }\n  });\n  return removedCount;\n};\n\n\n/**\n * Returns a new array that is the result of joining the arguments.  If arrays\n * are passed then their items are added, however, if non-arrays are passed they\n * will be added to the return array as is.\n *\n * Note that ArrayLike objects will be added as is, rather than having their\n * items added.\n *\n * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * goog.array.concat(0, [1, 2]) -> [0, 1, 2]\n * goog.array.concat([1, 2], null) -> [1, 2, null]\n *\n * There is bug in all current versions of IE (6, 7 and 8) where arrays created\n * in an iframe become corrupted soon (not immediately) after the iframe is\n * destroyed. This is common if loading data via goog.net.IframeIo, for example.\n * This corruption only affects the concat method which will start throwing\n * Catastrophic Errors (#-2147418113).\n *\n * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.\n *\n * Internally goog.array should use this, so that all methods will continue to\n * work on these broken array objects.\n *\n * @param {...*} var_args Items to concatenate.  Arrays will have each item\n *     added, while primitives and objects will be added as is.\n * @return {!Array<?>} The new resultant array.\n */\ngoog.array.concat = function(var_args) {\n  return Array.prototype.concat.apply([], arguments);\n};\n\n\n/**\n * Returns a new array that contains the contents of all the arrays passed.\n * @param {...!Array<T>} var_args\n * @return {!Array<T>}\n * @template T\n */\ngoog.array.join = function(var_args) {\n  return Array.prototype.concat.apply([], arguments);\n};\n\n\n/**\n * Converts an object to an array.\n * @param {IArrayLike<T>|string} object  The object to convert to an\n *     array.\n * @return {!Array<T>} The object converted into an array. If object has a\n *     length property, every property indexed with a non-negative number\n *     less than length will be included in the result. If object does not\n *     have a length property, an empty array will be returned.\n * @template T\n */\ngoog.array.toArray = function(object) {\n  var length = object.length;\n\n  // If length is not a number the following is false. This case is kept for\n  // backwards compatibility since there are callers that pass objects that are\n  // not array like.\n  if (length > 0) {\n    var rv = new Array(length);\n    for (var i = 0; i < length; i++) {\n      rv[i] = object[i];\n    }\n    return rv;\n  }\n  return [];\n};\n\n\n/**\n * Does a shallow copy of an array.\n * @param {IArrayLike<T>|string} arr  Array or array-like object to\n *     clone.\n * @return {!Array<T>} Clone of the input array.\n * @template T\n */\ngoog.array.clone = goog.array.toArray;\n\n\n/**\n * Extends an array with another array, element, or \"array like\" object.\n * This function operates 'in-place', it does not create a new Array.\n *\n * Example:\n * var a = [];\n * goog.array.extend(a, [0, 1]);\n * a; // [0, 1]\n * goog.array.extend(a, 2);\n * a; // [0, 1, 2]\n *\n * @param {Array<VALUE>} arr1  The array to modify.\n * @param {...(IArrayLike<VALUE>|VALUE)} var_args The elements or arrays of\n *     elements to add to arr1.\n * @template VALUE\n */\ngoog.array.extend = function(arr1, var_args) {\n  for (var i = 1; i < arguments.length; i++) {\n    var arr2 = arguments[i];\n    if (goog.isArrayLike(arr2)) {\n      var len1 = arr1.length || 0;\n      var len2 = arr2.length || 0;\n      arr1.length = len1 + len2;\n      for (var j = 0; j < len2; j++) {\n        arr1[len1 + j] = arr2[j];\n      }\n    } else {\n      arr1.push(arr2);\n    }\n  }\n};\n\n\n/**\n * Adds or removes elements from an array. This is a generic version of Array\n * splice. This means that it might work on other objects similar to arrays,\n * such as the arguments object.\n *\n * @param {IArrayLike<T>} arr The array to modify.\n * @param {number|undefined} index The index at which to start changing the\n *     array. If not defined, treated as 0.\n * @param {number} howMany How many elements to remove (0 means no removal. A\n *     value below 0 is treated as zero and so is any other non number. Numbers\n *     are floored).\n * @param {...T} var_args Optional, additional elements to insert into the\n *     array.\n * @return {!Array<T>} the removed elements.\n * @template T\n */\ngoog.array.splice = function(arr, index, howMany, var_args) {\n  goog.asserts.assert(arr.length != null);\n\n  return Array.prototype.splice.apply(arr, goog.array.slice(arguments, 1));\n};\n\n\n/**\n * Returns a new array from a segment of an array. This is a generic version of\n * Array slice. This means that it might work on other objects similar to\n * arrays, such as the arguments object.\n *\n * @param {IArrayLike<T>|string} arr The array from\n * which to copy a segment.\n * @param {number} start The index of the first element to copy.\n * @param {number=} opt_end The index after the last element to copy.\n * @return {!Array<T>} A new array containing the specified segment of the\n *     original array.\n * @template T\n */\ngoog.array.slice = function(arr, start, opt_end) {\n  goog.asserts.assert(arr.length != null);\n\n  // passing 1 arg to slice is not the same as passing 2 where the second is\n  // null or undefined (in that case the second argument is treated as 0).\n  // we could use slice on the arguments object and then use apply instead of\n  // testing the length\n  if (arguments.length <= 2) {\n    return Array.prototype.slice.call(arr, start);\n  } else {\n    return Array.prototype.slice.call(arr, start, opt_end);\n  }\n};\n\n\n/**\n * Removes all duplicates from an array (retaining only the first\n * occurrence of each array element).  This function modifies the\n * array in place and doesn't change the order of the non-duplicate items.\n *\n * For objects, duplicates are identified as having the same unique ID as\n * defined by {@link goog.getUid}.\n *\n * Alternatively you can specify a custom hash function that returns a unique\n * value for each item in the array it should consider unique.\n *\n * Runtime: N,\n * Worstcase space: 2N (no dupes)\n *\n * @param {IArrayLike<T>} arr The array from which to remove\n *     duplicates.\n * @param {Array=} opt_rv An optional array in which to return the results,\n *     instead of performing the removal inplace.  If specified, the original\n *     array will remain unchanged.\n * @param {function(T):string=} opt_hashFn An optional function to use to\n *     apply to every item in the array. This function should return a unique\n *     value for each item in the array it should consider unique.\n * @template T\n */\ngoog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {\n  var returnArray = opt_rv || arr;\n  var defaultHashFn = function(item) {\n    // Prefix each type with a single character representing the type to\n    // prevent conflicting keys (e.g. true and 'true').\n    return goog.isObject(item) ? 'o' + goog.getUid(item) :\n                                 (typeof item).charAt(0) + item;\n  };\n  var hashFn = opt_hashFn || defaultHashFn;\n\n  var seen = {}, cursorInsert = 0, cursorRead = 0;\n  while (cursorRead < arr.length) {\n    var current = arr[cursorRead++];\n    var key = hashFn(current);\n    if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n      seen[key] = true;\n      returnArray[cursorInsert++] = current;\n    }\n  }\n  returnArray.length = cursorInsert;\n};\n\n\n/**\n * Searches the specified array for the specified target using the binary\n * search algorithm.  If no opt_compareFn is specified, elements are compared\n * using <code>goog.array.defaultCompare</code>, which compares the elements\n * using the built in < and > operators.  This will produce the expected\n * behavior for homogeneous arrays of String(s) and Number(s). The array\n * specified <b>must</b> be sorted in ascending order (as defined by the\n * comparison function).  If the array is not sorted, results are undefined.\n * If the array contains multiple instances of the specified target value, the\n * left-most instance will be found.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {TARGET} target The sought value.\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, the target value and an element from your array, and return a\n *     negative number, zero, or a positive number depending on whether the\n *     first argument is less than, equal to, or greater than the second.\n * @return {number} Lowest index of the target value if found, otherwise\n *     (-(insertion point) - 1). The insertion point is where the value should\n *     be inserted into arr to preserve the sorted property.  Return value >= 0\n *     iff target is found.\n * @template TARGET, VALUE\n */\ngoog.array.binarySearch = function(arr, target, opt_compareFn) {\n  return goog.array.binarySearch_(\n      arr, opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,\n      target);\n};\n\n\n/**\n * Selects an index in the specified array using the binary search algorithm.\n * The evaluator receives an element and determines whether the desired index\n * is before, at, or after it.  The evaluator must be consistent (formally,\n * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)\n * must be monotonically non-increasing).\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\n *     Evaluator function that receives 3 arguments (the element, the index and\n *     the array). Should return a negative number, zero, or a positive number\n *     depending on whether the desired index is before, at, or after the\n *     element passed to it.\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\n *     within evaluator.\n * @return {number} Index of the leftmost element matched by the evaluator, if\n *     such exists; otherwise (-(insertion point) - 1). The insertion point is\n *     the index of the first element for which the evaluator returns negative,\n *     or arr.length if no such element exists. The return value is non-negative\n *     iff a match is found.\n * @template THIS, VALUE\n */\ngoog.array.binarySelect = function(arr, evaluator, opt_obj) {\n  return goog.array.binarySearch_(\n      arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n      opt_obj);\n};\n\n\n/**\n * Implementation of a binary search algorithm which knows how to use both\n * comparison functions and evaluators. If an evaluator is provided, will call\n * the evaluator with the given optional data object, conforming to the\n * interface defined in binarySelect. Otherwise, if a comparison function is\n * provided, will call the comparison function against the given data object.\n *\n * This implementation purposefully does not use goog.bind or goog.partial for\n * performance reasons.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<?>} arr The array to be searched.\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\n *     Either an evaluator or a comparison function, as defined by binarySearch\n *     and binarySelect above.\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\n *     comparison function.\n * @param {?=} opt_target If the function is a comparison function, then\n *     this is the target to binary search for.\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\n *     optional this object for the evaluator.\n * @return {number} Lowest index of the target value if found, otherwise\n *     (-(insertion point) - 1). The insertion point is where the value should\n *     be inserted into arr to preserve the sorted property.  Return value >= 0\n *     iff target is found.\n * @private\n */\ngoog.array.binarySearch_ = function(\n    arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n  var left = 0;            // inclusive\n  var right = arr.length;  // exclusive\n  var found;\n  while (left < right) {\n    var middle = left + ((right - left) >>> 1);\n    var compareResult;\n    if (isEvaluator) {\n      compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n    } else {\n      // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\n      // for the type of binarySearch_, which the type system can't express yet.\n      compareResult = /** @type {function(?, ?): number} */ (compareFn)(\n          opt_target, arr[middle]);\n    }\n    if (compareResult > 0) {\n      left = middle + 1;\n    } else {\n      right = middle;\n      // We are looking for the lowest index so we can't return immediately.\n      found = !compareResult;\n    }\n  }\n  // left is the index if found, or the insertion point otherwise.\n  // Avoiding bitwise not operator, as that causes a loss in precision for array\n  // indexes outside the bounds of a 32-bit signed integer.  Array indexes have\n  // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\n  return found ? left : -left - 1;\n};\n\n\n/**\n * Sorts the specified array into ascending order.  If no opt_compareFn is\n * specified, elements are compared using\n * <code>goog.array.defaultCompare</code>, which compares the elements using\n * the built in < and > operators.  This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\n * but will give unpredictable results for heterogeneous lists of strings and\n * numbers with different numbers of digits.\n *\n * This sort is not guaranteed to be stable.\n *\n * Runtime: Same as <code>Array.prototype.sort</code>\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\n *     function by which the\n *     array is to be ordered. Should take 2 arguments to compare, and return a\n *     negative number, zero, or a positive number depending on whether the\n *     first argument is less than, equal to, or greater than the second.\n * @template T\n */\ngoog.array.sort = function(arr, opt_compareFn) {\n  // TODO(arv): Update type annotation since null is not accepted.\n  arr.sort(opt_compareFn || goog.array.defaultCompare);\n};\n\n\n/**\n * Sorts the specified array into ascending order in a stable way.  If no\n * opt_compareFn is specified, elements are compared using\n * <code>goog.array.defaultCompare</code>, which compares the elements using\n * the built in < and > operators.  This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s).\n *\n * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional\n * O(n) overhead of copying the array twice.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\n *     by which the array is to be ordered. Should take 2 arguments to compare,\n *     and return a negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template T\n */\ngoog.array.stableSort = function(arr, opt_compareFn) {\n  var compArr = new Array(arr.length);\n  for (var i = 0; i < arr.length; i++) {\n    compArr[i] = {index: i, value: arr[i]};\n  }\n  var valueCompareFn = opt_compareFn || goog.array.defaultCompare;\n  function stableCompareFn(obj1, obj2) {\n    return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n  }\n  goog.array.sort(compArr, stableCompareFn);\n  for (var i = 0; i < arr.length; i++) {\n    arr[i] = compArr[i].value;\n  }\n};\n\n\n/**\n * Sort the specified array into ascending order based on item keys\n * returned by the specified key function.\n * If no opt_compareFn is specified, the keys are compared in ascending order\n * using <code>goog.array.defaultCompare</code>.\n *\n * Runtime: O(S(f(n)), where S is runtime of <code>goog.array.sort</code>\n * and f(n) is runtime of the key function.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {function(T): K} keyFn Function taking array element and returning\n *     a key used for sorting this element.\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\n *     by which the keys are to be ordered. Should take 2 arguments to compare,\n *     and return a negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template T,K\n */\ngoog.array.sortByKey = function(arr, keyFn, opt_compareFn) {\n  var keyCompareFn = opt_compareFn || goog.array.defaultCompare;\n  goog.array.sort(\n      arr, function(a, b) { return keyCompareFn(keyFn(a), keyFn(b)); });\n};\n\n\n/**\n * Sorts an array of objects by the specified object key and compare\n * function. If no compare function is provided, the key values are\n * compared in ascending order using <code>goog.array.defaultCompare</code>.\n * This won't work for keys that get renamed by the compiler. So use\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\n * @param {Array<Object>} arr An array of objects to sort.\n * @param {string} key The object key to sort by.\n * @param {Function=} opt_compareFn The function to use to compare key\n *     values.\n */\ngoog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {\n  goog.array.sortByKey(arr, function(obj) { return obj[key]; }, opt_compareFn);\n};\n\n\n/**\n * Tells if the array is sorted.\n * @param {!IArrayLike<T>} arr The array.\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\n *     array elements.\n *     Should take 2 arguments to compare, and return a negative number, zero,\n *     or a positive number depending on whether the first argument is less\n *     than, equal to, or greater than the second.\n * @param {boolean=} opt_strict If true no equal elements are allowed.\n * @return {boolean} Whether the array is sorted.\n * @template T\n */\ngoog.array.isSorted = function(arr, opt_compareFn, opt_strict) {\n  var compare = opt_compareFn || goog.array.defaultCompare;\n  for (var i = 1; i < arr.length; i++) {\n    var compareResult = compare(arr[i - 1], arr[i]);\n    if (compareResult > 0 || compareResult == 0 && opt_strict) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * Compares two arrays for equality. Two arrays are considered equal if they\n * have the same length and their corresponding elements are equal according to\n * the comparison function.\n *\n * @param {IArrayLike<?>} arr1 The first array to compare.\n * @param {IArrayLike<?>} arr2 The second array to compare.\n * @param {Function=} opt_equalsFn Optional comparison function.\n *     Should take 2 arguments to compare, and return true if the arguments\n *     are equal. Defaults to {@link goog.array.defaultCompareEquality} which\n *     compares the elements using the built-in '===' operator.\n * @return {boolean} Whether the two arrays are equal.\n */\ngoog.array.equals = function(arr1, arr2, opt_equalsFn) {\n  if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n      arr1.length != arr2.length) {\n    return false;\n  }\n  var l = arr1.length;\n  var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;\n  for (var i = 0; i < l; i++) {\n    if (!equalsFn(arr1[i], arr2[i])) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * 3-way array compare function.\n * @param {!IArrayLike<VALUE>} arr1 The first array to\n *     compare.\n * @param {!IArrayLike<VALUE>} arr2 The second array to\n *     compare.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is to be ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {number} Negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template VALUE\n */\ngoog.array.compare3 = function(arr1, arr2, opt_compareFn) {\n  var compare = opt_compareFn || goog.array.defaultCompare;\n  var l = Math.min(arr1.length, arr2.length);\n  for (var i = 0; i < l; i++) {\n    var result = compare(arr1[i], arr2[i]);\n    if (result != 0) {\n      return result;\n    }\n  }\n  return goog.array.defaultCompare(arr1.length, arr2.length);\n};\n\n\n/**\n * Compares its two arguments for order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n *     argument is less than, equal to, or greater than the second,\n *     respectively.\n * @template VALUE\n */\ngoog.array.defaultCompare = function(a, b) {\n  return a > b ? 1 : a < b ? -1 : 0;\n};\n\n\n/**\n * Compares its two arguments for inverse order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n *     argument is greater than, equal to, or less than the second,\n *     respectively.\n * @template VALUE\n */\ngoog.array.inverseDefaultCompare = function(a, b) {\n  return -goog.array.defaultCompare(a, b);\n};\n\n\n/**\n * Compares its two arguments for equality, using the built in === operator.\n * @param {*} a The first object to compare.\n * @param {*} b The second object to compare.\n * @return {boolean} True if the two arguments are equal, false otherwise.\n */\ngoog.array.defaultCompareEquality = function(a, b) {\n  return a === b;\n};\n\n\n/**\n * Inserts a value into a sorted array. The array is not modified if the\n * value is already present.\n * @param {IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to insert.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {boolean} True if an element was inserted.\n * @template VALUE\n */\ngoog.array.binaryInsert = function(array, value, opt_compareFn) {\n  var index = goog.array.binarySearch(array, value, opt_compareFn);\n  if (index < 0) {\n    goog.array.insertAt(array, value, -(index + 1));\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes a value from a sorted array.\n * @param {!IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to remove.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {boolean} True if an element was removed.\n * @template VALUE\n */\ngoog.array.binaryRemove = function(array, value, opt_compareFn) {\n  var index = goog.array.binarySearch(array, value, opt_compareFn);\n  return (index >= 0) ? goog.array.removeAt(array, index) : false;\n};\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {IArrayLike<T>} array The array.\n * @param {function(this:S, T, number, !IArrayLike<T>):?} sorter Function to\n *     call for every element.  This takes 3 arguments (the element, the index\n *     and the array) and must return a valid object key (a string, number,\n *     etc), or undefined, if that object should not be placed in a bucket.\n * @param {S=} opt_obj The object to be used as the value of 'this' within\n *     sorter.\n * @return {!Object<!Array<T>>} An object, with keys being all of the unique\n *     return values of sorter, and values being arrays containing the items for\n *     which the splitter returned that key.\n * @template T,S\n */\ngoog.array.bucket = function(array, sorter, opt_obj) {\n  var buckets = {};\n\n  for (var i = 0; i < array.length; i++) {\n    var value = array[i];\n    var key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\n    if (key !== undefined) {\n      // Push the value to the right bucket, creating it if necessary.\n      var bucket = buckets[key] || (buckets[key] = []);\n      bucket.push(value);\n    }\n  }\n\n  return buckets;\n};\n\n\n/**\n * Creates a new object built from the provided array and the key-generation\n * function.\n * @param {IArrayLike<T>} arr Array or array like object over\n *     which to iterate whose elements will be the values in the new object.\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\n *     call for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a string that will be used as the\n *     key for the element in the new object. If the function returns the same\n *     key for more than one element, the value for that key is\n *     implementation-defined.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within keyFunc.\n * @return {!Object<T>} The new object.\n * @template T,S\n */\ngoog.array.toObject = function(arr, keyFunc, opt_obj) {\n  var ret = {};\n  goog.array.forEach(arr, function(element, index) {\n    ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n        element;\n  });\n  return ret;\n};\n\n\n/**\n * Creates a range of numbers in an arithmetic progression.\n *\n * Range takes 1, 2, or 3 arguments:\n * <pre>\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\n * range(-2, -5, -1) produces [-2, -3, -4]\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\n * </pre>\n *\n * @param {number} startOrEnd The starting value of the range if an end argument\n *     is provided. Otherwise, the start value is 0, and this is the end value.\n * @param {number=} opt_end The optional end value of the range.\n * @param {number=} opt_step The step size between range values. Defaults to 1\n *     if opt_step is undefined or 0.\n * @return {!Array<number>} An array of numbers for the requested range. May be\n *     an empty array if adding the step would not converge toward the end\n *     value.\n */\ngoog.array.range = function(startOrEnd, opt_end, opt_step) {\n  var array = [];\n  var start = 0;\n  var end = startOrEnd;\n  var step = opt_step || 1;\n  if (opt_end !== undefined) {\n    start = startOrEnd;\n    end = opt_end;\n  }\n\n  if (step * (end - start) < 0) {\n    // Sign mismatch: start + step will never reach the end value.\n    return [];\n  }\n\n  if (step > 0) {\n    for (var i = start; i < end; i += step) {\n      array.push(i);\n    }\n  } else {\n    for (var i = start; i > end; i += step) {\n      array.push(i);\n    }\n  }\n  return array;\n};\n\n\n/**\n * Returns an array consisting of the given value repeated N times.\n *\n * @param {VALUE} value The value to repeat.\n * @param {number} n The repeat count.\n * @return {!Array<VALUE>} An array with the repeated value.\n * @template VALUE\n */\ngoog.array.repeat = function(value, n) {\n  var array = [];\n  for (var i = 0; i < n; i++) {\n    array[i] = value;\n  }\n  return array;\n};\n\n\n/**\n * Returns an array consisting of every argument with all arrays\n * expanded in-place recursively.\n *\n * @param {...*} var_args The values to flatten.\n * @return {!Array<?>} An array containing the flattened values.\n */\ngoog.array.flatten = function(var_args) {\n  var CHUNK_SIZE = 8192;\n\n  var result = [];\n  for (var i = 0; i < arguments.length; i++) {\n    var element = arguments[i];\n    if (Array.isArray(element)) {\n      for (var c = 0; c < element.length; c += CHUNK_SIZE) {\n        var chunk = goog.array.slice(element, c, c + CHUNK_SIZE);\n        var recurseResult = goog.array.flatten.apply(null, chunk);\n        for (var r = 0; r < recurseResult.length; r++) {\n          result.push(recurseResult[r]);\n        }\n      }\n    } else {\n      result.push(element);\n    }\n  }\n  return result;\n};\n\n\n/**\n * Rotates an array in-place. After calling this method, the element at\n * index i will be the element previously at index (i - n) %\n * array.length, for all values of i between 0 and array.length - 1,\n * inclusive.\n *\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\n *\n * @param {!Array<T>} array The array to rotate.\n * @param {number} n The amount to rotate.\n * @return {!Array<T>} The array.\n * @template T\n */\ngoog.array.rotate = function(array, n) {\n  goog.asserts.assert(array.length != null);\n\n  if (array.length) {\n    n %= array.length;\n    if (n > 0) {\n      Array.prototype.unshift.apply(array, array.splice(-n, n));\n    } else if (n < 0) {\n      Array.prototype.push.apply(array, array.splice(0, -n));\n    }\n  }\n  return array;\n};\n\n\n/**\n * Moves one item of an array to a new position keeping the order of the rest\n * of the items. Example use case: keeping a list of JavaScript objects\n * synchronized with the corresponding list of DOM elements after one of the\n * elements has been dragged to a new position.\n * @param {!IArrayLike<?>} arr The array to modify.\n * @param {number} fromIndex Index of the item to move between 0 and\n *     {@code arr.length - 1}.\n * @param {number} toIndex Target index between 0 and {@code arr.length - 1}.\n */\ngoog.array.moveItem = function(arr, fromIndex, toIndex) {\n  goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n  goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);\n  // Remove 1 item at fromIndex.\n  var removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n  // Insert the removed item at toIndex.\n  Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n  // We don't use goog.array.insertAt and goog.array.removeAt, because they're\n  // significantly slower than splice.\n};\n\n\n/**\n * Creates a new array for which the element at position i is an array of the\n * ith element of the provided arrays.  The returned array will only be as long\n * as the shortest array provided; additional values are ignored.  For example,\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\n *\n * This is similar to the zip() function in Python.  See {@link\n * http://docs.python.org/library/functions.html#zip}\n *\n * @param {...!IArrayLike<?>} var_args Arrays to be combined.\n * @return {!Array<!Array<?>>} A new array of arrays created from\n *     provided arrays.\n */\ngoog.array.zip = function(var_args) {\n  if (!arguments.length) {\n    return [];\n  }\n  var result = [];\n  var minLen = arguments[0].length;\n  for (var i = 1; i < arguments.length; i++) {\n    if (arguments[i].length < minLen) {\n      minLen = arguments[i].length;\n    }\n  }\n  for (var i = 0; i < minLen; i++) {\n    var value = [];\n    for (var j = 0; j < arguments.length; j++) {\n      value.push(arguments[j][i]);\n    }\n    result.push(value);\n  }\n  return result;\n};\n\n\n/**\n * Shuffles the values in the specified array using the Fisher-Yates in-place\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\n * and so resets the state of that random number generator. Similarly, may reset\n * the state of any other specified random number generator.\n *\n * Runtime: O(n)\n *\n * @param {!Array<?>} arr The array to be shuffled.\n * @param {function():number=} opt_randFn Optional random function to use for\n *     shuffling.\n *     Takes no arguments, and returns a random number on the interval [0, 1).\n *     Defaults to Math.random() using JavaScript's built-in Math library.\n */\ngoog.array.shuffle = function(arr, opt_randFn) {\n  var randFn = opt_randFn || Math.random;\n\n  for (var i = arr.length - 1; i > 0; i--) {\n    // Choose a random array index in [0, i] (inclusive with i).\n    var j = Math.floor(randFn() * (i + 1));\n\n    var tmp = arr[i];\n    arr[i] = arr[j];\n    arr[j] = tmp;\n  }\n};\n\n\n/**\n * Returns a new array of elements from arr, based on the indexes of elements\n * provided by index_arr. For example, the result of index copying\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\n *\n * @param {!IArrayLike<T>} arr The array to get a indexed copy from.\n * @param {!IArrayLike<number>} index_arr An array of indexes to get from arr.\n * @return {!Array<T>} A new array of elements from arr in index_arr order.\n * @template T\n */\ngoog.array.copyByIndex = function(arr, index_arr) {\n  var result = [];\n  goog.array.forEach(index_arr, function(index) { result.push(arr[index]); });\n  return result;\n};\n\n\n/**\n * Maps each element of the input array into zero or more elements of the output\n * array.\n *\n * @param {!IArrayLike<VALUE>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): !Array<RESULT>} f The function\n *     to call for every element. This function takes 3 arguments (the element,\n *     the index and the array) and should return an array. The result will be\n *     used to extend a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the concatenation of all arrays\n *     returned from f.\n * @template THIS, VALUE, RESULT\n */\ngoog.array.concatMap = function(arr, f, opt_obj) {\n  return goog.array.concat.apply([], goog.array.map(arr, f, opt_obj));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.dom.asserts');\n\ngoog.require('goog.asserts');\n\n/**\n * @fileoverview Custom assertions to ensure that an element has the appropriate\n * type.\n *\n * Using a goog.dom.safe wrapper on an object on the incorrect type (via an\n * incorrect static type cast) can result in security bugs: For instance,\n * g.d.s.setAnchorHref ensures that the URL assigned to the .href attribute\n * satisfies the SafeUrl contract, i.e., is safe to dereference as a hyperlink.\n * However, the value assigned to a HTMLLinkElement's .href property requires\n * the stronger TrustedResourceUrl contract, since it can refer to a stylesheet.\n * Thus, using g.d.s.setAnchorHref on an (incorrectly statically typed) object\n * of type HTMLLinkElement can result in a security vulnerability.\n * Assertions of the correct run-time type help prevent such incorrect use.\n *\n * In some cases, code using the DOM API is tested using mock objects (e.g., a\n * plain object such as {'href': url} instead of an actual Location object).\n * To allow such mocking, the assertions permit objects of types that are not\n * relevant DOM API objects at all (for instance, not Element or Location).\n *\n * Note that instanceof checks don't work straightforwardly in older versions of\n * IE, or across frames (see,\n * http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object,\n * http://stackoverflow.com/questions/26248599/instanceof-htmlelement-in-iframe-is-not-element-or-object).\n *\n * Hence, these assertions may pass vacuously in such scenarios. The resulting\n * risk of security bugs is limited by the following factors:\n *  - A bug can only arise in scenarios involving incorrect static typing (the\n *    wrapper methods are statically typed to demand objects of the appropriate,\n *    precise type).\n *  - Typically, code is tested and exercised in multiple browsers.\n */\n\n/**\n * Asserts that a given object is a Location.\n *\n * To permit this assertion to pass in the context of tests where DOM APIs might\n * be mocked, also accepts any other type except for subtypes of {!Element}.\n * This is to ensure that, for instance, HTMLLinkElement is not being used in\n * place of a Location, since this could result in security bugs due to stronger\n * contracts required for assignments to the href property of the latter.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!Location}\n */\ngoog.dom.asserts.assertIsLocation = function(o) {\n  if (goog.asserts.ENABLE_ASSERTS) {\n    var win = goog.dom.asserts.getWindow_(o);\n    if (win) {\n      if (!o || (!(o instanceof win.Location) && o instanceof win.Element)) {\n        goog.asserts.fail(\n            'Argument is not a Location (or a non-Element mock); got: %s',\n            goog.dom.asserts.debugStringForType_(o));\n      }\n    }\n  }\n  return /** @type {!Location} */ (o);\n};\n\n\n/**\n * Asserts that a given object is either the given subtype of Element\n * or a non-Element, non-Location Mock.\n *\n * To permit this assertion to pass in the context of tests where DOM\n * APIs might be mocked, also accepts any other type except for\n * subtypes of {!Element}.  This is to ensure that, for instance,\n * HTMLScriptElement is not being used in place of a HTMLImageElement,\n * since this could result in security bugs due to stronger contracts\n * required for assignments to the src property of the latter.\n *\n * The DOM type is looked up in the window the object belongs to.  In\n * some contexts, this might not be possible (e.g. when running tests\n * outside a browser, cross-domain lookup). In this case, the\n * assertions are skipped.\n *\n * @param {?Object} o The object whose type to assert.\n * @param {string} typename The name of the DOM type.\n * @return {!Element} The object.\n * @private\n */\n// TODO(bangert): Make an analog of goog.dom.TagName to correctly handle casts?\ngoog.dom.asserts.assertIsElementType_ = function(o, typename) {\n  if (goog.asserts.ENABLE_ASSERTS) {\n    var win = goog.dom.asserts.getWindow_(o);\n    if (win && typeof win[typename] != 'undefined') {\n      if (!o ||\n          (!(o instanceof win[typename]) &&\n           (o instanceof win.Location || o instanceof win.Element))) {\n        goog.asserts.fail(\n            'Argument is not a %s (or a non-Element, non-Location mock); ' +\n                'got: %s',\n            typename, goog.dom.asserts.debugStringForType_(o));\n      }\n    }\n  }\n  return /** @type {!Element} */ (o);\n};\n\n/**\n * Asserts that a given object is a HTMLAnchorElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not of type Location nor a subtype\n * of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLAnchorElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlAnchorElement instead.\n */\ngoog.dom.asserts.assertIsHTMLAnchorElement = function(o) {\n  return /** @type {!HTMLAnchorElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLAnchorElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLButtonElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLButtonElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlButtonElement instead.\n */\ngoog.dom.asserts.assertIsHTMLButtonElement = function(o) {\n  return /** @type {!HTMLButtonElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLButtonElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLLinkElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLLinkElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlLinkElement instead.\n */\ngoog.dom.asserts.assertIsHTMLLinkElement = function(o) {\n  return /** @type {!HTMLLinkElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLLinkElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLImageElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLImageElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlImageElement instead.\n */\ngoog.dom.asserts.assertIsHTMLImageElement = function(o) {\n  return /** @type {!HTMLImageElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLImageElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLAudioElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLAudioElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlAudioElement instead.\n */\ngoog.dom.asserts.assertIsHTMLAudioElement = function(o) {\n  return /** @type {!HTMLAudioElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLAudioElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLVideoElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLVideoElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlVideoElement instead.\n */\ngoog.dom.asserts.assertIsHTMLVideoElement = function(o) {\n  return /** @type {!HTMLVideoElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLVideoElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLInputElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLInputElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlInputElement instead.\n */\ngoog.dom.asserts.assertIsHTMLInputElement = function(o) {\n  return /** @type {!HTMLInputElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLInputElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLTextAreaElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLTextAreaElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlTextAreaElement instead.\n */\ngoog.dom.asserts.assertIsHTMLTextAreaElement = function(o) {\n  return /** @type {!HTMLTextAreaElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLTextAreaElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLCanvasElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLCanvasElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlCanvasElement instead.\n */\ngoog.dom.asserts.assertIsHTMLCanvasElement = function(o) {\n  return /** @type {!HTMLCanvasElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLCanvasElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLEmbedElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLEmbedElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlEmbedElement instead.\n */\ngoog.dom.asserts.assertIsHTMLEmbedElement = function(o) {\n  return /** @type {!HTMLEmbedElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLEmbedElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLFormElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLFormElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlFormElement instead.\n */\ngoog.dom.asserts.assertIsHTMLFormElement = function(o) {\n  return /** @type {!HTMLFormElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLFormElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLFrameElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLFrameElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlFrameElement instead.\n */\ngoog.dom.asserts.assertIsHTMLFrameElement = function(o) {\n  return /** @type {!HTMLFrameElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLFrameElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLIFrameElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLIFrameElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlIFrameElement instead.\n */\ngoog.dom.asserts.assertIsHTMLIFrameElement = function(o) {\n  return /** @type {!HTMLIFrameElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLIFrameElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLObjectElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLObjectElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlObjectElement instead.\n */\ngoog.dom.asserts.assertIsHTMLObjectElement = function(o) {\n  return /** @type {!HTMLObjectElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLObjectElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLScriptElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLScriptElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlScriptElement instead.\n */\ngoog.dom.asserts.assertIsHTMLScriptElement = function(o) {\n  return /** @type {!HTMLScriptElement} */ (\n      goog.dom.asserts.assertIsElementType_(o, 'HTMLScriptElement'));\n};\n\n/**\n * Returns a string representation of a value's type.\n *\n * @param {*} value An object, or primitive.\n * @return {string} The best display name for the value.\n * @private\n */\ngoog.dom.asserts.debugStringForType_ = function(value) {\n  if (goog.isObject(value)) {\n    try {\n      return /** @type {string|undefined} */ (value.constructor.displayName) ||\n          value.constructor.name || Object.prototype.toString.call(value);\n    } catch (e) {\n      return '<object could not be stringified>';\n    }\n  } else {\n    return value === undefined ? 'undefined' :\n                                 value === null ? 'null' : typeof value;\n  }\n};\n\n/**\n * Gets window of element.\n * @param {?Object} o\n * @return {?Window}\n * @private\n * @suppress {strictMissingProperties} ownerDocument not defined on Object\n */\ngoog.dom.asserts.getWindow_ = function(o) {\n  try {\n    var doc = o && o.ownerDocument;\n    // This can throw “Blocked a frame with origin \"chrome-extension://...\" from\n    // accessing a cross-origin frame” in Chrome extension.\n    var win =\n        doc && /** @type {?Window} */ (doc.defaultView || doc.parentWindow);\n    win = win || /** @type {!Window} */ (goog.global);\n    // This can throw “Permission denied to access property \"Element\" on\n    // cross-origin object”.\n    if (win.Element && win.Location) {\n      return win;\n    }\n  } catch (ex) {\n  }\n  return null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The TrustedResourceUrl type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.TrustedResourceUrl');\n\ngoog.require('goog.asserts');\ngoog.require('goog.fs.blob');\ngoog.require('goog.fs.url');\ngoog.require('goog.html.SafeScript');\ngoog.require('goog.html.trustedtypes');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\n\n\n\n/**\n * A URL which is under application control and from which script, CSS, and\n * other resources that represent executable code, can be fetched.\n *\n * Given that the URL can only be constructed from strings under application\n * control and is used to load resources, bugs resulting in a malformed URL\n * should not have a security impact and are likely to be easily detectable\n * during testing. Given the wide number of non-RFC compliant URLs in use,\n * stricter validation could prevent some applications from being able to use\n * this type.\n *\n * Instances of this type must be created via the factory method,\n * (`fromConstant`, `fromConstants`, `format` or\n * `formatWithParams`), and not by invoking its constructor. The constructor\n * is organized in a way that only methods from that file can call it and\n * initialize with non-empty values. Anyone else calling constructor will\n * get default instance with empty value.\n *\n * @see goog.html.TrustedResourceUrl#fromConstant\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token package-internal implementation detail.\n * @param {!TrustedScriptURL|string=} opt_content package-internal\n *     implementation detail.\n */\ngoog.html.TrustedResourceUrl = function(opt_token, opt_content) {\n  /**\n   * The contained value of this TrustedResourceUrl.  The field has a purposely\n   * ugly name to make (non-compiled) code that attempts to directly access this\n   * field stand out.\n   * @const\n   * @private {!TrustedScriptURL|string}\n   */\n  this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ =\n      ((opt_token ===\n        goog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_) &&\n       opt_content) ||\n      '';\n\n  /**\n   * A type marker used to implement additional run-time type checking.\n   * @see goog.html.TrustedResourceUrl#unwrap\n   * @const {!Object}\n   * @private\n   */\n  this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n      goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this TrustedResourceUrl's value as a string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `TrustedResourceUrl`, use\n * `goog.html.TrustedResourceUrl.unwrap` instead of this method. If in\n * doubt, assume that it's security relevant. In particular, note that\n * goog.html functions which return a goog.html type do not guarantee that\n * the returned instance is of the right type. For example:\n *\n * <pre>\n * var fakeSafeHtml = new String('fake');\n * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;\n * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);\n * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\n * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof\n * // goog.html.SafeHtml.\n * </pre>\n *\n * @see goog.html.TrustedResourceUrl#unwrap\n * @override\n */\ngoog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {\n  return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_\n      .toString();\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString =\n    true;\n\n\n/**\n * Returns this URLs directionality, which is always `LTR`.\n * @override\n */\ngoog.html.TrustedResourceUrl.prototype.getDirection = function() {\n  return goog.i18n.bidi.Dir.LTR;\n};\n\n\n/**\n * Creates a new TrustedResourceUrl with params added to URL. Both search and\n * hash params can be specified.\n *\n * @param {string|?Object<string, *>|undefined} searchParams Search parameters\n *     to add to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for\n *     exact format definition.\n * @param {(string|?Object<string, *>)=} opt_hashParams Hash parameters to add\n *     to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n *     format definition.\n * @return {!goog.html.TrustedResourceUrl} New TrustedResourceUrl with params.\n */\ngoog.html.TrustedResourceUrl.prototype.cloneWithParams = function(\n    searchParams, opt_hashParams) {\n  var url = goog.html.TrustedResourceUrl.unwrap(this);\n  var parts = goog.html.TrustedResourceUrl.URL_PARAM_PARSER_.exec(url);\n  var urlBase = parts[1];\n  var urlSearch = parts[2] || '';\n  var urlHash = parts[3] || '';\n\n  return goog.html.TrustedResourceUrl\n      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(\n          urlBase +\n          goog.html.TrustedResourceUrl.stringifyParams_(\n              '?', urlSearch, searchParams) +\n          goog.html.TrustedResourceUrl.stringifyParams_(\n              '#', urlHash, opt_hashParams));\n};\n\n\nif (goog.DEBUG) {\n  /**\n   * Returns a debug string-representation of this value.\n   *\n   * To obtain the actual string value wrapped in a TrustedResourceUrl, use\n   * `goog.html.TrustedResourceUrl.unwrap`.\n   *\n   * @see goog.html.TrustedResourceUrl#unwrap\n   * @override\n   */\n  goog.html.TrustedResourceUrl.prototype.toString = function() {\n    return 'TrustedResourceUrl{' +\n        this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + '}';\n  };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a\n * TrustedResourceUrl object, and returns its value.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl The object to\n *     extract from.\n * @return {string} The trustedResourceUrl object's contained string, unless\n *     the run-time type check fails. In that case, `unwrap` returns an\n *     innocuous string, or, if assertions are enabled, throws\n *     `goog.asserts.AssertionError`.\n */\ngoog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {\n  return goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(trustedResourceUrl)\n      .toString();\n};\n\n\n/**\n * Unwraps value as TrustedScriptURL if supported or as a string if not.\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!TrustedScriptURL|string}\n * @see goog.html.TrustedResourceUrl.unwrap\n */\ngoog.html.TrustedResourceUrl.unwrapTrustedScriptURL = function(\n    trustedResourceUrl) {\n  // Perform additional Run-time type-checking to ensure that\n  // trustedResourceUrl is indeed an instance of the expected type.  This\n  // provides some additional protection against security bugs due to\n  // application code that disables type checks.\n  // Specifically, the following checks are performed:\n  // 1. The object is an instance of the expected type.\n  // 2. The object is not an instance of a subclass.\n  // 3. The object carries a type marker for the expected type. \"Faking\" an\n  // object requires a reference to the type marker, which has names intended\n  // to stand out in code reviews.\n  if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl &&\n      trustedResourceUrl.constructor === goog.html.TrustedResourceUrl &&\n      trustedResourceUrl\n              .TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n          goog.html.TrustedResourceUrl\n              .TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n    return trustedResourceUrl\n        .privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;\n  } else {\n    goog.asserts.fail('expected object of type TrustedResourceUrl, got \\'' +\n        trustedResourceUrl + '\\' of type ' + goog.typeOf(trustedResourceUrl));\n    return 'type_error:TrustedResourceUrl';\n  }\n};\n\n\n/**\n * Creates a TrustedResourceUrl from a format string and arguments.\n *\n * The arguments for interpolation into the format string map labels to values.\n * Values of type `goog.string.Const` are interpolated without modifcation.\n * Values of other types are cast to string and encoded with\n * encodeURIComponent.\n *\n * `%{<label>}` markers are used in the format string to indicate locations\n * to be interpolated with the valued mapped to the given label. `<label>`\n * must contain only alphanumeric and `_` characters.\n *\n * The format string must match goog.html.TrustedResourceUrl.BASE_URL_.\n *\n * Example usage:\n *\n *    var url = goog.html.TrustedResourceUrl.format(goog.string.Const.from(\n *        'https://www.google.com/search?q=%{query}'), {'query': searchTerm});\n *\n *    var url = goog.html.TrustedResourceUrl.format(goog.string.Const.from(\n *        '//www.youtube.com/v/%{videoId}?hl=en&fs=1%{autoplay}'), {\n *        'videoId': videoId,\n *        'autoplay': opt_autoplay ?\n *            goog.string.Const.from('&autoplay=1') : goog.string.Const.EMPTY\n *    });\n *\n * While this function can be used to create a TrustedResourceUrl from only\n * constants, fromConstant() and fromConstants() are generally preferable for\n * that purpose.\n *\n * @param {!goog.string.Const} format The format string.\n * @param {!Object<string, (string|number|!goog.string.Const)>} args Mapping\n *     of labels to values to be interpolated into the format string.\n *     goog.string.Const values are interpolated without encoding.\n * @return {!goog.html.TrustedResourceUrl}\n * @throws {!Error} On an invalid format string or if a label used in the\n *     the format string is not present in args.\n */\ngoog.html.TrustedResourceUrl.format = function(format, args) {\n  var formatStr = goog.string.Const.unwrap(format);\n  if (!goog.html.TrustedResourceUrl.BASE_URL_.test(formatStr)) {\n    throw new Error('Invalid TrustedResourceUrl format: ' + formatStr);\n  }\n  var result = formatStr.replace(\n      goog.html.TrustedResourceUrl.FORMAT_MARKER_, function(match, id) {\n        if (!Object.prototype.hasOwnProperty.call(args, id)) {\n          throw new Error(\n              'Found marker, \"' + id + '\", in format string, \"' + formatStr +\n              '\", but no valid label mapping found ' +\n              'in args: ' + JSON.stringify(args));\n        }\n        var arg = args[id];\n        if (arg instanceof goog.string.Const) {\n          return goog.string.Const.unwrap(arg);\n        } else {\n          return encodeURIComponent(String(arg));\n        }\n      });\n  return goog.html.TrustedResourceUrl\n      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(result);\n};\n\n\n/**\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.FORMAT_MARKER_ = /%{(\\w+)}/g;\n\n\n/**\n * The URL must be absolute, scheme-relative or path-absolute. So it must\n * start with:\n * - https:// followed by allowed origin characters.\n * - // followed by allowed origin characters.\n * - Any absolute or relative path.\n *\n * Based on\n * https://url.spec.whatwg.org/commit-snapshots/56b74ce7cca8883eab62e9a12666e2fac665d03d/#url-parsing\n * an initial / which is not followed by another / or \\ will end up in the \"path\n * state\" and from there it can only go to \"fragment state\" and \"query state\".\n *\n * We don't enforce a well-formed domain name. So '.' or '1.2' are valid.\n * That's ok because the origin comes from a compile-time constant.\n *\n * A regular expression is used instead of goog.uri for several reasons:\n * - Strictness. E.g. we don't want any userinfo component and we don't\n *   want '/./, nor \\' in the first path component.\n * - Small trusted base. goog.uri is generic and might need to change,\n *   reasoning about all the ways it can parse a URL now and in the future\n *   is error-prone.\n * - Code size. We expect many calls to .format(), many of which might\n *   not be using goog.uri.\n * - Simplicity. Using goog.uri would likely not result in simpler nor shorter\n *   code.\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.BASE_URL_ = new RegExp(\n    '^((https:)?//[0-9a-z.:[\\\\]-]+/'  // Origin.\n        + '|/[^/\\\\\\\\]'                // Absolute path.\n        + '|[^:/\\\\\\\\%]+/'             // Relative path.\n        + '|[^:/\\\\\\\\%]*[?#]'          // Query string or fragment.\n        + '|about:blank#'             // about:blank with fragment.\n        + ')',\n    'i');\n\n/**\n * RegExp for splitting a URL into the base, search field, and hash field.\n *\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.URL_PARAM_PARSER_ =\n    /^([^?#]*)(\\?[^#]*)?(#[\\s\\S]*)?/;\n\n\n/**\n * Formats the URL same as TrustedResourceUrl.format and then adds extra URL\n * parameters.\n *\n * Example usage:\n *\n *     // Creates '//www.youtube.com/v/abc?autoplay=1' for videoId='abc' and\n *     // opt_autoplay=1. Creates '//www.youtube.com/v/abc' for videoId='abc'\n *     // and opt_autoplay=undefined.\n *     var url = goog.html.TrustedResourceUrl.formatWithParams(\n *         goog.string.Const.from('//www.youtube.com/v/%{videoId}'),\n *         {'videoId': videoId},\n *         {'autoplay': opt_autoplay});\n *\n * @param {!goog.string.Const} format The format string.\n * @param {!Object<string, (string|number|!goog.string.Const)>} args Mapping\n *     of labels to values to be interpolated into the format string.\n *     goog.string.Const values are interpolated without encoding.\n * @param {string|?Object<string, *>|undefined} searchParams Parameters to add\n *     to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n *     format definition.\n * @param {(string|?Object<string, *>)=} opt_hashParams Hash parameters to add\n *     to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n *     format definition.\n * @return {!goog.html.TrustedResourceUrl}\n * @throws {!Error} On an invalid format string or if a label used in the\n *     the format string is not present in args.\n */\ngoog.html.TrustedResourceUrl.formatWithParams = function(\n    format, args, searchParams, opt_hashParams) {\n  var url = goog.html.TrustedResourceUrl.format(format, args);\n  return url.cloneWithParams(searchParams, opt_hashParams);\n};\n\n\n/**\n * Creates a TrustedResourceUrl object from a compile-time constant string.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!goog.string.Const} url A compile-time-constant string from which to\n *     create a TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n *     initialized to `url`.\n */\ngoog.html.TrustedResourceUrl.fromConstant = function(url) {\n  return goog.html.TrustedResourceUrl\n      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(\n          goog.string.Const.unwrap(url));\n};\n\n\n/**\n * Creates a TrustedResourceUrl object from a compile-time constant strings.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!Array<!goog.string.Const>} parts Compile-time-constant strings from\n *     which to create a TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n *     initialized to concatenation of `parts`.\n */\ngoog.html.TrustedResourceUrl.fromConstants = function(parts) {\n  var unwrapped = '';\n  for (var i = 0; i < parts.length; i++) {\n    unwrapped += goog.string.Const.unwrap(parts[i]);\n  }\n  return goog.html.TrustedResourceUrl\n      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped);\n};\n\n/**\n * Creates a TrustedResourceUrl object by generating a Blob from a SafeScript\n * object and then calling createObjectURL with that blob.\n *\n * SafeScript objects are trusted to contain executable JavaScript code.\n *\n * Caller must call goog.fs.url.revokeObjectUrl() on the unwrapped url to\n * release the underlying blob.\n *\n * Throws if browser doesn't support blob construction.\n *\n * @param {!goog.html.SafeScript} safeScript A script from which to create a\n *     TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n *     initialized to a new blob URL.\n */\ngoog.html.TrustedResourceUrl.fromSafeScript = function(safeScript) {\n  var blob = goog.fs.blob.getBlobWithProperties(\n      [goog.html.SafeScript.unwrap(safeScript)], 'text/javascript');\n  var url = goog.fs.url.createObjectUrl(blob);\n  return goog.html.TrustedResourceUrl\n      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Type marker for the TrustedResourceUrl type, used to implement additional\n * run-time type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create TrustedResourceUrl instances.\n *\n * @param {string} url The string to initialize the TrustedResourceUrl object\n *     with.\n * @return {!goog.html.TrustedResourceUrl} The initialized TrustedResourceUrl\n *     object.\n * @package\n */\ngoog.html.TrustedResourceUrl\n    .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {\n  var value = goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY ?\n      goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY\n          .createScriptURL(url) :\n      url;\n  return new goog.html.TrustedResourceUrl(\n      goog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_, value);\n};\n\n\n/**\n * Stringifies the passed params to be used as either a search or hash field of\n * a URL.\n *\n * @param {string} prefix The prefix character for the given field ('?' or '#').\n * @param {string} currentString The existing field value (including the prefix\n *     character, if the field is present).\n * @param {string|?Object<string, *>|undefined} params The params to set or\n *     append to the field.\n * - If `undefined` or `null`, the field remains unchanged.\n * - If a string, then the string will be escaped and the field will be\n *   overwritten with that value.\n * - If an Object, that object is treated as a set of key-value pairs to be\n *   appended to the current field. Note that JavaScript doesn't guarantee the\n *   order of values in an object which might result in non-deterministic order\n *   of the parameters. However, browsers currently preserve the order. The\n *   rules for each entry:\n *   - If an array, it will be processed as if each entry were an additional\n *     parameter with exactly the same key, following the same logic below.\n *   - If `undefined` or `null`, it will be skipped.\n *   - Otherwise, it will be turned into a string, escaped, and appended.\n * @return {string}\n * @private\n */\ngoog.html.TrustedResourceUrl.stringifyParams_ = function(\n    prefix, currentString, params) {\n  if (params == null) {\n    // Do not modify the field.\n    return currentString;\n  }\n  if (typeof params === 'string') {\n    // Set field to the passed string.\n    return params ? prefix + encodeURIComponent(params) : '';\n  }\n  // Add on parameters to field from key-value object.\n  for (var key in params) {\n    var value = params[key];\n    var outputValues = Array.isArray(value) ? value : [value];\n    for (var i = 0; i < outputValues.length; i++) {\n      var outputValue = outputValues[i];\n      if (outputValue != null) {\n        if (!currentString) {\n          currentString = prefix;\n        }\n        currentString += (currentString.length > prefix.length ? '&' : '') +\n            encodeURIComponent(key) + '=' +\n            encodeURIComponent(String(outputValue));\n      }\n    }\n  }\n  return currentString;\n};\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @private {!Object}\n * @const\n */\ngoog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The SafeUrl type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.SafeUrl');\n\ngoog.require('goog.asserts');\ngoog.require('goog.fs.url');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\ngoog.require('goog.string.internal');\n\n\n\n/**\n * A string that is safe to use in URL context in DOM APIs and HTML documents.\n *\n * A SafeUrl is a string-like object that carries the security type contract\n * that its value as a string will not cause untrusted script execution\n * when evaluated as a hyperlink URL in a browser.\n *\n * Values of this type are guaranteed to be safe to use in URL/hyperlink\n * contexts, such as assignment to URL-valued DOM properties, in the sense that\n * the use will not result in a Cross-Site-Scripting vulnerability. Similarly,\n * SafeUrls can be interpolated into the URL context of an HTML template (e.g.,\n * inside a href attribute). However, appropriate HTML-escaping must still be\n * applied.\n *\n * Note that, as documented in `goog.html.SafeUrl.unwrap`, this type's\n * contract does not guarantee that instances are safe to interpolate into HTML\n * without appropriate escaping.\n *\n * Note also that this type's contract does not imply any guarantees regarding\n * the resource the URL refers to.  In particular, SafeUrls are <b>not</b>\n * safe to use in a context where the referred-to resource is interpreted as\n * trusted code, e.g., as the src of a script tag.\n *\n * Instances of this type must be created via the factory methods\n * (`goog.html.SafeUrl.fromConstant`, `goog.html.SafeUrl.sanitize`),\n * etc and not by invoking its constructor. The constructor is organized in a\n * way that only methods from that file can call it and initialize with\n * non-empty values. Anyone else calling constructor will get default instance\n * with empty value.\n *\n * @see goog.html.SafeUrl#fromConstant\n * @see goog.html.SafeUrl#from\n * @see goog.html.SafeUrl#sanitize\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token package-internal implementation detail.\n * @param {string=} opt_content package-internal implementation detail.\n */\ngoog.html.SafeUrl = function(opt_token, opt_content) {\n  /**\n   * The contained value of this SafeUrl.  The field has a purposely ugly\n   * name to make (non-compiled) code that attempts to directly access this\n   * field stand out.\n   * @private {string}\n   */\n  this.privateDoNotAccessOrElseSafeUrlWrappedValue_ =\n      ((opt_token === goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_) &&\n       opt_content) ||\n      '';\n\n  /**\n   * A type marker used to implement additional run-time type checking.\n   * @see goog.html.SafeUrl#unwrap\n   * @const {!Object}\n   * @private\n   */\n  this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n      goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n\n\n/**\n * The innocuous string generated by goog.html.SafeUrl.sanitize when passed\n * an unsafe URL.\n *\n * about:invalid is registered in\n * http://www.w3.org/TR/css3-values/#about-invalid.\n * http://tools.ietf.org/html/rfc6694#section-2.2.1 permits about URLs to\n * contain a fragment, which is not to be considered when determining if an\n * about URL is well-known.\n *\n * Using about:invalid seems preferable to using a fixed data URL, since\n * browsers might choose to not report CSP violations on it, as legitimate\n * CSS function calls to attr() can result in this URL being produced. It is\n * also a standard URL which matches exactly the semantics we need:\n * \"The about:invalid URI references a non-existent document with a generic\n * error condition. It can be used when a URI is necessary, but the default\n * value shouldn't be resolveable as any type of document\".\n *\n * @const {string}\n */\ngoog.html.SafeUrl.INNOCUOUS_STRING = 'about:invalid#zClosurez';\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this SafeUrl's value a string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `SafeUrl`, use `goog.html.SafeUrl.unwrap` instead of this\n * method. If in doubt, assume that it's security relevant. In particular, note\n * that goog.html functions which return a goog.html type do not guarantee that\n * the returned instance is of the right type.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @see goog.html.SafeUrl#unwrap\n * @override\n */\ngoog.html.SafeUrl.prototype.getTypedStringValue = function() {\n  return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;\n\n\n/**\n * Returns this URLs directionality, which is always `LTR`.\n * @override\n */\ngoog.html.SafeUrl.prototype.getDirection = function() {\n  return goog.i18n.bidi.Dir.LTR;\n};\n\n\nif (goog.DEBUG) {\n  /**\n   * Returns a debug string-representation of this value.\n   *\n   * To obtain the actual string value wrapped in a SafeUrl, use\n   * `goog.html.SafeUrl.unwrap`.\n   *\n   * @see goog.html.SafeUrl#unwrap\n   * @override\n   */\n  goog.html.SafeUrl.prototype.toString = function() {\n    return 'SafeUrl{' + this.privateDoNotAccessOrElseSafeUrlWrappedValue_ + '}';\n  };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a SafeUrl\n * object, and returns its value.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of  browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @param {!goog.html.SafeUrl} safeUrl The object to extract from.\n * @return {string} The SafeUrl object's contained string, unless the run-time\n *     type check fails. In that case, `unwrap` returns an innocuous\n *     string, or, if assertions are enabled, throws\n *     `goog.asserts.AssertionError`.\n */\ngoog.html.SafeUrl.unwrap = function(safeUrl) {\n  // Perform additional Run-time type-checking to ensure that safeUrl is indeed\n  // an instance of the expected type.  This provides some additional protection\n  // against security bugs due to application code that disables type checks.\n  // Specifically, the following checks are performed:\n  // 1. The object is an instance of the expected type.\n  // 2. The object is not an instance of a subclass.\n  // 3. The object carries a type marker for the expected type. \"Faking\" an\n  // object requires a reference to the type marker, which has names intended\n  // to stand out in code reviews.\n  if (safeUrl instanceof goog.html.SafeUrl &&\n      safeUrl.constructor === goog.html.SafeUrl &&\n      safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n          goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n    return safeUrl.privateDoNotAccessOrElseSafeUrlWrappedValue_;\n  } else {\n    goog.asserts.fail('expected object of type SafeUrl, got \\'' +\n        safeUrl + '\\' of type ' + goog.typeOf(safeUrl));\n    return 'type_error:SafeUrl';\n  }\n};\n\n\n/**\n * Creates a SafeUrl object from a compile-time constant string.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!goog.string.Const} url A compile-time-constant string from which to\n *         create a SafeUrl.\n * @return {!goog.html.SafeUrl} A SafeUrl object initialized to `url`.\n */\ngoog.html.SafeUrl.fromConstant = function(url) {\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      goog.string.Const.unwrap(url));\n};\n\n\n/**\n * A pattern that matches Blob or data types that can have SafeUrls created\n * from URL.createObjectURL(blob) or via a data: URI.\n *\n * This has some parameter support (most notably, we haven't implemented the\n * more complex parts like %-encoded characters or non-alphanumerical ones for\n * simplicity's sake). The specs are fairly complex, and they don't\n * always match Chrome's behavior: we settled on a subset where we're confident\n * all parties involved agree.\n *\n * The spec is available at https://mimesniff.spec.whatwg.org/ (and see\n * https://tools.ietf.org/html/rfc2397 for data: urls, which override some of\n * it).\n * @const\n * @private\n */\ngoog.html.SAFE_MIME_TYPE_PATTERN_ = new RegExp(\n    // Note: Due to content-sniffing concerns, only add MIME types for\n    // media formats.\n    '^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-wav|wav|webm)|' +\n        'image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|' +\n        // TODO(user): Due to content-sniffing concerns, text/csv should\n        // be removed from the whitelist.\n        'text/csv|' +\n        'video/(?:mpeg|mp4|ogg|webm|quicktime))' +\n        '(?:;\\\\w+=(?:\\\\w+|\"[\\\\w;=]+\"))*$',  // MIME type parameters\n    'i');\n\n\n/**\n * @param {string} mimeType The MIME type to check if safe.\n * @return {boolean} True if the MIME type is safe and creating a Blob via\n *   `SafeUrl.fromBlob()` with that type will not fail due to the type. False\n *   otherwise.\n */\ngoog.html.SafeUrl.isSafeMimeType = function(mimeType) {\n  return goog.html.SAFE_MIME_TYPE_PATTERN_.test(mimeType);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a blob URL for the given `blob`.\n *\n * The blob URL is created with `URL.createObjectURL`. If the MIME type\n * for `blob` is not of a known safe audio, image or video MIME type,\n * then the SafeUrl will wrap {@link #INNOCUOUS_STRING}.\n *\n * @see http://www.w3.org/TR/FileAPI/#url\n * @param {!Blob} blob\n * @return {!goog.html.SafeUrl} The blob URL, or an innocuous string wrapped\n *   as a SafeUrl.\n */\ngoog.html.SafeUrl.fromBlob = function(blob) {\n  var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ?\n      goog.fs.url.createObjectUrl(blob) :\n      goog.html.SafeUrl.INNOCUOUS_STRING;\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Matches a base-64 data URL, with the first match group being the MIME type.\n * @const\n * @private\n */\ngoog.html.DATA_URL_PATTERN_ = /^data:([^,]*);base64,[a-z0-9+\\/]+=*$/i;\n\n\n/**\n * Creates a SafeUrl wrapping a data: URL, after validating it matches a\n * known-safe audio, image or video MIME type.\n *\n * @param {string} dataUrl A valid base64 data URL with one of the whitelisted\n *     audio, image or video MIME types.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromDataUrl = function(dataUrl) {\n  // RFC4648 suggest to ignore CRLF in base64 encoding.\n  // See https://tools.ietf.org/html/rfc4648.\n  // Remove the CR (%0D) and LF (%0A) from the dataUrl.\n  var filteredDataUrl = dataUrl.replace(/(%0A|%0D)/g, '');\n  // There's a slight risk here that a browser sniffs the content type if it\n  // doesn't know the MIME type and executes HTML within the data: URL. For this\n  // to cause XSS it would also have to execute the HTML in the same origin\n  // of the page with the link. It seems unlikely that both of these will\n  // happen, particularly in not really old IEs.\n  var match = filteredDataUrl.match(goog.html.DATA_URL_PATTERN_);\n  var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      valid ? filteredDataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a tel: URL.\n *\n * @param {string} telUrl A tel URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromTelUrl = function(telUrl) {\n  // There's a risk that a tel: URL could immediately place a call once\n  // clicked, without requiring user confirmation. For that reason it is\n  // handled in this separate function.\n  if (!goog.string.internal.caseInsensitiveStartsWith(telUrl, 'tel:')) {\n    telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      telUrl);\n};\n\n\n/**\n * Matches a sip/sips URL. We only allow urls that consist of an email address.\n * The characters '?' and '#' are not allowed in the local part of the email\n * address.\n * @const\n * @private\n */\ngoog.html.SIP_URL_PATTERN_ = new RegExp(\n    '^sip[s]?:[+a-z0-9_.!$%&\\'*\\\\/=^`{|}~-]+@([a-z0-9-]+\\\\.)+[a-z0-9]{2,63}$',\n    'i');\n\n\n/**\n * Creates a SafeUrl wrapping a sip: URL. We only allow urls that consist of an\n * email address. The characters '?' and '#' are not allowed in the local part\n * of the email address.\n *\n * @param {string} sipUrl A sip URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSipUrl = function(sipUrl) {\n  if (!goog.html.SIP_URL_PATTERN_.test(decodeURIComponent(sipUrl))) {\n    sipUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      sipUrl);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a fb-messenger://share URL.\n *\n * @param {string} facebookMessengerUrl A facebook messenger URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromFacebookMessengerUrl = function(facebookMessengerUrl) {\n  if (!goog.string.internal.caseInsensitiveStartsWith(\n          facebookMessengerUrl, 'fb-messenger://share')) {\n    facebookMessengerUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      facebookMessengerUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a whatsapp://send URL.\n *\n * @param {string} whatsAppUrl A WhatsApp URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromWhatsAppUrl = function(whatsAppUrl) {\n  if (!goog.string.internal.caseInsensitiveStartsWith(\n          whatsAppUrl, 'whatsapp://send')) {\n    whatsAppUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      whatsAppUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a sms: URL.\n *\n * @param {string} smsUrl A sms URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSmsUrl = function(smsUrl) {\n  if (!goog.string.internal.caseInsensitiveStartsWith(smsUrl, 'sms:') ||\n      !goog.html.SafeUrl.isSmsUrlBodyValid_(smsUrl)) {\n    smsUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      smsUrl);\n};\n\n\n/**\n * Validates SMS URL `body` parameter, which is optional and should appear at\n * most once and should be percent-encoded if present. Rejects many malformed\n * bodies, but may spuriously reject some URLs and does not reject all malformed\n * sms: URLs.\n *\n * @param {string} smsUrl A sms URL.\n * @return {boolean} Whether SMS URL has a valid `body` parameter if it exists.\n * @private\n */\ngoog.html.SafeUrl.isSmsUrlBodyValid_ = function(smsUrl) {\n  var hash = smsUrl.indexOf('#');\n  if (hash > 0) {\n    smsUrl = smsUrl.substring(0, hash);\n  }\n  var bodyParams = smsUrl.match(/[?&]body=/gi);\n  // \"body\" param is optional\n  if (!bodyParams) {\n    return true;\n  }\n  // \"body\" MUST only appear once\n  if (bodyParams.length > 1) {\n    return false;\n  }\n  // Get the encoded `body` parameter value.\n  var bodyValue = smsUrl.match(/[?&]body=([^&]*)/)[1];\n  if (!bodyValue) {\n    return true;\n  }\n  try {\n    decodeURIComponent(bodyValue);\n  } catch (error) {\n    return false;\n  }\n  return /^(?:[a-z0-9\\-_.~]|%[0-9a-f]{2})+$/i.test(bodyValue);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a ssh: URL.\n *\n * @param {string} sshUrl A ssh URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n *     wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSshUrl = function(sshUrl) {\n  if (!goog.string.internal.caseInsensitiveStartsWith(sshUrl, 'ssh://')) {\n    sshUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      sshUrl);\n};\n\n/**\n * Sanitizes a Chrome extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n *     scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n *     extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n *     `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeChromeExtensionUrl = function(url, extensionId) {\n  return goog.html.SafeUrl.sanitizeExtensionUrl_(\n      /^chrome-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Firefox extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n *     scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n *     extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n *     `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeFirefoxExtensionUrl = function(url, extensionId) {\n  return goog.html.SafeUrl.sanitizeExtensionUrl_(\n      /^moz-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Edge extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n *     scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n *     extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n *     `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeEdgeExtensionUrl = function(url, extensionId) {\n  return goog.html.SafeUrl.sanitizeExtensionUrl_(\n      /^ms-browser-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Private helper for converting extension URLs to SafeUrl, given the scheme for\n * that particular extension type. Use the sanitizeFirefoxExtensionUrl,\n * sanitizeChromeExtensionUrl or sanitizeEdgeExtensionUrl unless you're building\n * new helpers.\n *\n * @private\n * @param {!RegExp} scheme The scheme to accept as a RegExp extracting the\n *     extension identifier.\n * @param {string} url The url to sanitize. Should start with the extension\n *     scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n *     extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n *     `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeExtensionUrl_ = function(scheme, url, extensionId) {\n  var matches = scheme.exec(url);\n  if (!matches) {\n    url = goog.html.SafeUrl.INNOCUOUS_STRING;\n  } else {\n    var extractedExtensionId = matches[1];\n    var acceptedExtensionIds;\n    if (extensionId instanceof goog.string.Const) {\n      acceptedExtensionIds = [goog.string.Const.unwrap(extensionId)];\n    } else {\n      acceptedExtensionIds = extensionId.map(function unwrap(x) {\n        return goog.string.Const.unwrap(x);\n      });\n    }\n    if (acceptedExtensionIds.indexOf(extractedExtensionId) == -1) {\n      url = goog.html.SafeUrl.INNOCUOUS_STRING;\n    }\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Creates a SafeUrl from TrustedResourceUrl. This is safe because\n * TrustedResourceUrl is more tightly restricted than SafeUrl.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n      goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));\n};\n\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that satisfy\n * the SafeUrl contract.\n *\n * This regular expression matches a subset of URLs that will not cause script\n * execution if used in URL context within a HTML document. Specifically, this\n * regular expression matches if (comment from here on and regex copied from\n * Soy's EscapingConventions):\n * (1) Either a protocol in a whitelist (http, https, mailto or ftp).\n * (2) or no protocol.  A protocol must be followed by a colon. The below\n *     allows that by allowing colons only after one of the characters [/?#].\n *     A colon after a hash (#) must be in the fragment.\n *     Otherwise, a colon after a (?) must be in a query.\n *     Otherwise, a colon after a single solidus (/) must be in a path.\n *     Otherwise, a colon after a double solidus (//) must be in the authority\n *     (before port).\n *\n * @private\n * @const {!RegExp}\n */\ngoog.html.SAFE_URL_PATTERN_ =\n    /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;\n\n/**\n * Public version of goog.html.SAFE_URL_PATTERN_. Updating\n * goog.html.SAFE_URL_PATTERN_ doesn't seem to be backward compatible.\n * Namespace is also changed to goog.html.SafeUrl so it can be imported using\n * goog.require('goog.dom.SafeUrl').\n *\n * TODO(bangert): Remove SAFE_URL_PATTERN_\n * @const {!RegExp}\n */\ngoog.html.SafeUrl.SAFE_URL_PATTERN = goog.html.SAFE_URL_PATTERN_;\n\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitize = function(url) {\n  if (url instanceof goog.html.SafeUrl) {\n    return url;\n  } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n    url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n  } else {\n    url = String(url);\n  }\n  if (!goog.html.SAFE_URL_PATTERN_.test(url)) {\n    url = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * This function asserts (using goog.asserts) that the URL matches this pattern.\n * If it does not, in addition to failing the assert, an innocous URL will be\n * returned.\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @param {boolean=} opt_allowDataUrl Whether to allow valid data: URLs.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitizeAssertUnchanged = function(url, opt_allowDataUrl) {\n  if (url instanceof goog.html.SafeUrl) {\n    return url;\n  } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n    url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n  } else {\n    url = String(url);\n  }\n  if (opt_allowDataUrl && /^data:/i.test(url)) {\n    var safeUrl = goog.html.SafeUrl.fromDataUrl(url);\n    if (safeUrl.getTypedStringValue() == url) {\n      return safeUrl;\n    }\n  }\n  if (!goog.asserts.assert(\n          goog.html.SAFE_URL_PATTERN_.test(url),\n          '%s does not match the safe URL pattern', url)) {\n    url = goog.html.SafeUrl.INNOCUOUS_STRING;\n  }\n  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n\n/**\n * Type marker for the SafeUrl type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create SafeUrl instances.\n *\n * @param {string} url The string to initialize the SafeUrl object with.\n * @return {!goog.html.SafeUrl} The initialized SafeUrl object.\n * @package\n */\ngoog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(\n    url) {\n  return new goog.html.SafeUrl(\n      goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_, url);\n};\n\n\n/**\n * A SafeUrl corresponding to the special about:blank url.\n * @const {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.ABOUT_BLANK =\n    goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n        'about:blank');\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @private {!Object}\n * @const\n */\ngoog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Rendering engine detection.\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For information on the browser brand (such as Safari versus Chrome), see\n * goog.userAgent.product.\n * @see ../demos/useragent.html\n */\n\ngoog.provide('goog.userAgent');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.reflect');\ngoog.require('goog.string');\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is IE.\n */\ngoog.userAgent.ASSUME_IE = goog.define('goog.userAgent.ASSUME_IE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is EDGE,\n * referring to EdgeHTML based Edge.\n */\ngoog.userAgent.ASSUME_EDGE = goog.define('goog.userAgent.ASSUME_EDGE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is GECKO.\n */\ngoog.userAgent.ASSUME_GECKO = goog.define('goog.userAgent.ASSUME_GECKO', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is WEBKIT.\n */\ngoog.userAgent.ASSUME_WEBKIT =\n    goog.define('goog.userAgent.ASSUME_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is a\n *     mobile device running WebKit e.g. iPhone or Android.\n */\ngoog.userAgent.ASSUME_MOBILE_WEBKIT =\n    goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is OPERA,\n * referring to Presto-based Opera.\n */\ngoog.userAgent.ASSUME_OPERA = goog.define('goog.userAgent.ASSUME_OPERA', false);\n\n\n/**\n * @define {boolean} Whether the\n *     `goog.userAgent.isVersionOrHigher`\n *     function will return true for any version.\n */\ngoog.userAgent.ASSUME_ANY_VERSION =\n    goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);\n\n\n/**\n * Whether we know the browser engine at compile-time.\n * @type {boolean}\n * @private\n */\ngoog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||\n    goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||\n    goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||\n    goog.userAgent.ASSUME_OPERA;\n\n\n/**\n * Returns the userAgent string for the current browser.\n *\n * @return {string} The userAgent string.\n */\ngoog.userAgent.getUserAgentString = function() {\n  return goog.labs.userAgent.util.getUserAgent();\n};\n\n\n/**\n * @return {?Navigator} The native navigator object.\n */\ngoog.userAgent.getNavigatorTyped = function() {\n  // Need a local navigator reference instead of using the global one,\n  // to avoid the rare case where they reference different objects.\n  // (in a WorkerPool, for example).\n  return goog.global['navigator'] || null;\n};\n\n\n/**\n * TODO(nnaze): Change type to \"Navigator\" and update compilation targets.\n * @return {?Object} The native navigator object.\n */\ngoog.userAgent.getNavigator = function() {\n  return goog.userAgent.getNavigatorTyped();\n};\n\n\n/**\n * Whether the user agent is Presto-based Opera.\n * @type {boolean}\n */\ngoog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_OPERA :\n    goog.labs.userAgent.browser.isOpera();\n\n\n/**\n * Whether the user agent is Internet Explorer.\n * @type {boolean}\n */\ngoog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_IE :\n    goog.labs.userAgent.browser.isIE();\n\n\n/**\n * Whether the user agent is Microsoft Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_EDGE :\n    goog.labs.userAgent.engine.isEdge();\n\n\n/**\n * Whether the user agent is MS Internet Explorer or MS Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;\n\n\n/**\n * Whether the user agent is Gecko. Gecko is the rendering engine used by\n * Mozilla, Firefox, and others.\n * @type {boolean}\n */\ngoog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_GECKO :\n    goog.labs.userAgent.engine.isGecko();\n\n\n/**\n * Whether the user agent is WebKit. WebKit is the rendering engine that\n * Safari, Edge Chromium, Opera Chromium, Android and others use.\n * @type {boolean}\n */\ngoog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :\n    goog.labs.userAgent.engine.isWebKit();\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * This is a separate function so that the logic can be tested.\n *\n * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().\n *\n * @return {boolean} Whether the user agent is running on a mobile device.\n * @private\n */\ngoog.userAgent.isMobile_ = function() {\n  return goog.userAgent.WEBKIT &&\n      goog.labs.userAgent.util.matchUserAgent('Mobile');\n};\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent\n *   is promoted as the gecko/webkit logic is likely inaccurate.\n *\n * @type {boolean}\n */\ngoog.userAgent.MOBILE =\n    goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();\n\n\n/**\n * Used while transitioning code to use WEBKIT instead.\n * @type {boolean}\n * @deprecated Use {@link goog.userAgent.product.SAFARI} instead.\n * TODO(nicksantos): Delete this from goog.userAgent.\n */\ngoog.userAgent.SAFARI = goog.userAgent.WEBKIT;\n\n\n/**\n * @return {string} the platform (operating system) the user agent is running\n *     on. Default to empty string because navigator.platform may not be defined\n *     (on Rhino, for example).\n * @private\n */\ngoog.userAgent.determinePlatform_ = function() {\n  var navigator = goog.userAgent.getNavigatorTyped();\n  return navigator && navigator.platform || '';\n};\n\n\n/**\n * The platform (operating system) the user agent is running on. Default to\n * empty string because navigator.platform may not be defined (on Rhino, for\n * example).\n * @type {string}\n */\ngoog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Macintosh operating\n *     system.\n */\ngoog.userAgent.ASSUME_MAC = goog.define('goog.userAgent.ASSUME_MAC', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Windows operating\n *     system.\n */\ngoog.userAgent.ASSUME_WINDOWS =\n    goog.define('goog.userAgent.ASSUME_WINDOWS', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Linux operating\n *     system.\n */\ngoog.userAgent.ASSUME_LINUX = goog.define('goog.userAgent.ASSUME_LINUX', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a X11 windowing\n *     system.\n */\ngoog.userAgent.ASSUME_X11 = goog.define('goog.userAgent.ASSUME_X11', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on Android.\n */\ngoog.userAgent.ASSUME_ANDROID =\n    goog.define('goog.userAgent.ASSUME_ANDROID', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPhone.\n */\ngoog.userAgent.ASSUME_IPHONE =\n    goog.define('goog.userAgent.ASSUME_IPHONE', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPad.\n */\ngoog.userAgent.ASSUME_IPAD = goog.define('goog.userAgent.ASSUME_IPAD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPod.\n */\ngoog.userAgent.ASSUME_IPOD = goog.define('goog.userAgent.ASSUME_IPOD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on KaiOS.\n */\ngoog.userAgent.ASSUME_KAIOS = goog.define('goog.userAgent.ASSUME_KAIOS', false);\n\n\n/**\n * @type {boolean}\n * @private\n */\ngoog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||\n    goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||\n    goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||\n    goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n    goog.userAgent.ASSUME_IPOD;\n\n\n/**\n * Whether the user agent is running on a Macintosh operating system.\n * @type {boolean}\n */\ngoog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_MAC :\n    goog.labs.userAgent.platform.isMacintosh();\n\n\n/**\n * Whether the user agent is running on a Windows operating system.\n * @type {boolean}\n */\ngoog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_WINDOWS :\n    goog.labs.userAgent.platform.isWindows();\n\n\n/**\n * Whether the user agent is Linux per the legacy behavior of\n * goog.userAgent.LINUX, which considered ChromeOS to also be\n * Linux.\n * @return {boolean}\n * @private\n */\ngoog.userAgent.isLegacyLinux_ = function() {\n  return goog.labs.userAgent.platform.isLinux() ||\n      goog.labs.userAgent.platform.isChromeOS();\n};\n\n\n/**\n * Whether the user agent is running on a Linux operating system.\n *\n * Note that goog.userAgent.LINUX considers ChromeOS to be Linux,\n * while goog.labs.userAgent.platform considers ChromeOS and\n * Linux to be different OSes.\n *\n * @type {boolean}\n */\ngoog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_LINUX :\n    goog.userAgent.isLegacyLinux_();\n\n\n/**\n * @return {boolean} Whether the user agent is an X11 windowing system.\n * @private\n */\ngoog.userAgent.isX11_ = function() {\n  var navigator = goog.userAgent.getNavigatorTyped();\n  return !!navigator &&\n      goog.string.contains(navigator['appVersion'] || '', 'X11');\n};\n\n\n/**\n * Whether the user agent is running on a X11 windowing system.\n * @type {boolean}\n */\ngoog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_X11 :\n    goog.userAgent.isX11_();\n\n\n/**\n * Whether the user agent is running on Android.\n * @type {boolean}\n */\ngoog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_ANDROID :\n    goog.labs.userAgent.platform.isAndroid();\n\n\n/**\n * Whether the user agent is running on an iPhone.\n * @type {boolean}\n */\ngoog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPHONE :\n    goog.labs.userAgent.platform.isIphone();\n\n\n/**\n * Whether the user agent is running on an iPad.\n * @type {boolean}\n */\ngoog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPAD :\n    goog.labs.userAgent.platform.isIpad();\n\n\n/**\n * Whether the user agent is running on an iPod.\n * @type {boolean}\n */\ngoog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPOD :\n    goog.labs.userAgent.platform.isIpod();\n\n\n/**\n * Whether the user agent is running on iOS.\n * @type {boolean}\n */\ngoog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ?\n    (goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n     goog.userAgent.ASSUME_IPOD) :\n    goog.labs.userAgent.platform.isIos();\n\n/**\n * Whether the user agent is running on KaiOS.\n * @type {boolean}\n */\ngoog.userAgent.KAIOS = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_KAIOS :\n    goog.labs.userAgent.platform.isKaiOS();\n\n\n/**\n * @return {string} The string that describes the version number of the user\n *     agent.\n * @private\n */\ngoog.userAgent.determineVersion_ = function() {\n  // All browsers have different ways to detect the version and they all have\n  // different naming schemes.\n  // version is a string rather than a number because it may contain 'b', 'a',\n  // and so on.\n  var version = '';\n  var arr = goog.userAgent.getVersionRegexResult_();\n  if (arr) {\n    version = arr ? arr[1] : '';\n  }\n\n  if (goog.userAgent.IE) {\n    // IE9 can be in document mode 9 but be reporting an inconsistent user agent\n    // version.  If it is identifying as a version lower than 9 we take the\n    // documentMode as the version instead.  IE8 has similar behavior.\n    // It is recommended to set the X-UA-Compatible header to ensure that IE9\n    // uses documentMode 9.\n    var docMode = goog.userAgent.getDocumentMode_();\n    if (docMode != null && docMode > parseFloat(version)) {\n      return String(docMode);\n    }\n  }\n\n  return version;\n};\n\n\n/**\n * @return {?IArrayLike<string>|undefined} The version regex matches from\n *     parsing the user\n *     agent string. These regex statements must be executed inline so they can\n *     be compiled out by the closure compiler with the rest of the useragent\n *     detection logic when ASSUME_* is specified.\n * @private\n */\ngoog.userAgent.getVersionRegexResult_ = function() {\n  var userAgent = goog.userAgent.getUserAgentString();\n  if (goog.userAgent.GECKO) {\n    return /rv\\:([^\\);]+)(\\)|;)/.exec(userAgent);\n  }\n  if (goog.userAgent.EDGE) {\n    return /Edge\\/([\\d\\.]+)/.exec(userAgent);\n  }\n  if (goog.userAgent.IE) {\n    return /\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(userAgent);\n  }\n  if (goog.userAgent.WEBKIT) {\n    // WebKit/125.4\n    return /WebKit\\/(\\S+)/.exec(userAgent);\n  }\n  if (goog.userAgent.OPERA) {\n    // If none of the above browsers were detected but the browser is Opera, the\n    // only string that is of interest is 'Version/<number>'.\n    return /(?:Version)[ \\/]?(\\S+)/.exec(userAgent);\n  }\n  return undefined;\n};\n\n\n/**\n * @return {number|undefined} Returns the document mode (for testing).\n * @private\n */\ngoog.userAgent.getDocumentMode_ = function() {\n  // NOTE(user): goog.userAgent may be used in context where there is no DOM.\n  var doc = goog.global['document'];\n  return doc ? doc['documentMode'] : undefined;\n};\n\n\n/**\n * The version of the user agent. This is a string because it might contain\n * 'b' (as in beta) as well as multiple dots.\n * @type {string}\n */\ngoog.userAgent.VERSION = goog.userAgent.determineVersion_();\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string} v1 Version of first item.\n * @param {string} v2 Version of second item.\n *\n * @return {number}  1 if first argument is higher\n *                   0 if arguments are equal\n *                  -1 if second argument is higher.\n * @deprecated Use goog.string.compareVersions.\n */\ngoog.userAgent.compare = function(v1, v2) {\n  return goog.string.compareVersions(v1, v2);\n};\n\n\n/**\n * Cache for {@link goog.userAgent.isVersionOrHigher}.\n * Calls to compareVersions are surprisingly expensive and, as a browser's\n * version number is unlikely to change during a session, we cache the results.\n * @const\n * @private\n */\ngoog.userAgent.isVersionOrHigherCache_ = {};\n\n\n/**\n * Whether the user agent version is higher or the same as the given version.\n * NOTE: When checking the version numbers for Firefox and Safari, be sure to\n * use the engine's version, not the browser's version number.  For example,\n * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.\n * Opera and Internet Explorer versions match the product release number.<br>\n * @see <a href=\"http://en.wikipedia.org/wiki/Safari_version_history\">\n *     Webkit</a>\n * @see <a href=\"http://en.wikipedia.org/wiki/Gecko_engine\">Gecko</a>\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n *     the given version.\n */\ngoog.userAgent.isVersionOrHigher = function(version) {\n  return goog.userAgent.ASSUME_ANY_VERSION ||\n      goog.reflect.cache(\n          goog.userAgent.isVersionOrHigherCache_, version, function() {\n            return goog.string.compareVersions(\n                       goog.userAgent.VERSION, version) >= 0;\n          });\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isVersionOrHigher`.\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n *     the given version.\n * @deprecated Use goog.userAgent.isVersionOrHigher().\n */\ngoog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;\n\n\n/**\n * Whether the IE effective document mode is higher or the same as the given\n * document mode version.\n * NOTE: Only for IE, return false for another browser.\n *\n * @param {number} documentMode The document mode version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n *     same as the given version.\n */\ngoog.userAgent.isDocumentModeOrHigher = function(documentMode) {\n  return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isDocumentModeOrHigher`.\n * @param {number} version The version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n *      same as the given version.\n * @deprecated Use goog.userAgent.isDocumentModeOrHigher().\n */\ngoog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;\n\n\n/**\n * For IE version < 7, documentMode is undefined, so attempt to use the\n * CSS1Compat property to see if we are in standards mode. If we are in\n * standards mode, treat the browser version as the document mode. Otherwise,\n * IE is emulating version 5.\n *\n * NOTE(user): Support for IE < 7 is long gone, so this is now simplified.\n * It returns document.documentMode for IE and undefined for everything else.\n *\n * @type {number|undefined}\n * @const\n */\ngoog.userAgent.DOCUMENT_MODE = (function() {\n  var doc = goog.global['document'];\n  if (!doc || !goog.userAgent.IE) {\n    return undefined;\n  }\n  return goog.userAgent.getDocumentMode_();\n})();\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating the browser's Document Object Model\n * Inspiration taken *heavily* from mochikit (http://mochikit.com/).\n *\n * You can use {@link goog.dom.DomHelper} to create new dom helpers that refer\n * to a different document object.  This is useful if you are working with\n * frames or multiple windows.\n *\n * @suppress {strictMissingProperties}\n */\n\n\n// TODO(arv): Rename/refactor getTextContent and getRawTextContent. The problem\n// is that getTextContent should mimic the DOM3 textContent. We should add a\n// getInnerText (or getText) which tries to return the visible text, innerText.\n\n\ngoog.provide('goog.dom');\ngoog.provide('goog.dom.Appendable');\ngoog.provide('goog.dom.DomHelper');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.dom.BrowserFeature');\ngoog.require('goog.dom.NodeType');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.math.Coordinate');\ngoog.require('goog.math.Size');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.string.Unicode');\ngoog.require('goog.userAgent');\n\n\n/**\n * @define {boolean} Whether we know at compile time that the browser is in\n * quirks mode.\n */\ngoog.dom.ASSUME_QUIRKS_MODE = goog.define('goog.dom.ASSUME_QUIRKS_MODE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile time that the browser is in\n * standards compliance mode.\n */\ngoog.dom.ASSUME_STANDARDS_MODE =\n    goog.define('goog.dom.ASSUME_STANDARDS_MODE', false);\n\n\n/**\n * Whether we know the compatibility mode at compile time.\n * @type {boolean}\n * @private\n */\ngoog.dom.COMPAT_MODE_KNOWN_ =\n    goog.dom.ASSUME_QUIRKS_MODE || goog.dom.ASSUME_STANDARDS_MODE;\n\n\n/**\n * Gets the DomHelper object for the document where the element resides.\n * @param {(Node|Window)=} opt_element If present, gets the DomHelper for this\n *     element.\n * @return {!goog.dom.DomHelper} The DomHelper.\n */\ngoog.dom.getDomHelper = function(opt_element) {\n  return opt_element ?\n      new goog.dom.DomHelper(goog.dom.getOwnerDocument(opt_element)) :\n      (goog.dom.defaultDomHelper_ ||\n       (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper()));\n};\n\n\n/**\n * Cached default DOM helper.\n * @type {!goog.dom.DomHelper|undefined}\n * @private\n */\ngoog.dom.defaultDomHelper_;\n\n\n/**\n * Gets the document object being used by the dom library.\n * @return {!Document} Document object.\n */\ngoog.dom.getDocument = function() {\n  return document;\n};\n\n\n/**\n * Gets an element from the current document by element id.\n *\n * If an Element is passed in, it is returned.\n *\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n */\ngoog.dom.getElement = function(element) {\n  return goog.dom.getElementHelper_(document, element);\n};\n\n\n/**\n * Gets an element by id from the given document (if present).\n * If an element is given, it is returned.\n * @param {!Document} doc\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The resulting element.\n * @private\n */\ngoog.dom.getElementHelper_ = function(doc, element) {\n  return typeof element === 'string' ? doc.getElementById(element) : element;\n};\n\n\n/**\n * Gets an element by id, asserting that the element is found.\n *\n * This is used when an element is expected to exist, and should fail with\n * an assertion error if it does not (if assertions are enabled).\n *\n * @param {string} id Element ID.\n * @return {!Element} The element with the given ID, if it exists.\n */\ngoog.dom.getRequiredElement = function(id) {\n  return goog.dom.getRequiredElementHelper_(document, id);\n};\n\n\n/**\n * Helper function for getRequiredElementHelper functions, both static and\n * on DomHelper.  Asserts the element with the given id exists.\n * @param {!Document} doc\n * @param {string} id\n * @return {!Element} The element with the given ID, if it exists.\n * @private\n */\ngoog.dom.getRequiredElementHelper_ = function(doc, id) {\n  // To prevent users passing in Elements as is permitted in getElement().\n  goog.asserts.assertString(id);\n  var element = goog.dom.getElementHelper_(doc, id);\n  element =\n      goog.asserts.assertElement(element, 'No element found with id: ' + id);\n  return element;\n};\n\n\n/**\n * Alias for getElement.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n * @deprecated Use {@link goog.dom.getElement} instead.\n */\ngoog.dom.$ = goog.dom.getElement;\n\n\n/**\n * Gets elements by tag name.\n * @param {!goog.dom.TagName<T>} tagName\n * @param {(!Document|!Element)=} opt_parent Parent element or document where to\n *     look for elements. Defaults to document.\n * @return {!NodeList<R>} List of elements. The members of the list are\n *     {!Element} if tagName is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementsByTagName = function(tagName, opt_parent) {\n  var parent = opt_parent || document;\n  return parent.getElementsByTagName(String(tagName));\n};\n\n\n/**\n * Looks up elements by both tag and class name, using browser native functions\n * (`querySelectorAll`, `getElementsByTagName` or\n * `getElementsByClassName`) where possible. This function\n * is a useful, if limited, way of collecting a list of DOM elements\n * with certain characteristics.  `querySelectorAll` offers a\n * more powerful and general solution which allows matching on CSS3\n * selector expressions.\n *\n * Note that tag names are case sensitive in the SVG namespace, and this\n * function converts opt_tag to uppercase for comparisons. For queries in the\n * SVG namespace you should use querySelector or querySelectorAll instead.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=963870\n * https://bugs.webkit.org/show_bug.cgi?id=83438\n *\n * @see {https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll}\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n *     and numerical indices are guaranteed to exist). The members of the array\n *     are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {\n  return goog.dom.getElementsByTagNameAndClass_(\n      document, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Gets the first element matching the tag and the class.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n *     tagName is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementByTagNameAndClass = function(opt_tag, opt_class, opt_el) {\n  return goog.dom.getElementByTagNameAndClass_(\n      document, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Returns a static, array-like list of the elements with the provided\n * className.\n *\n * @param {string} className the name of the class to look for.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<!Element>} The items found with the class name provided.\n */\ngoog.dom.getElementsByClass = function(className, opt_el) {\n  var parent = opt_el || document;\n  if (goog.dom.canUseQuerySelector_(parent)) {\n    return parent.querySelectorAll('.' + className);\n  }\n  return goog.dom.getElementsByTagNameAndClass_(\n      document, '*', className, opt_el);\n};\n\n\n/**\n * Returns the first element with the provided className.\n *\n * @param {string} className the name of the class to look for.\n * @param {Element|Document=} opt_el Optional element to look in.\n * @return {Element} The first item with the class name provided.\n */\ngoog.dom.getElementByClass = function(className, opt_el) {\n  var parent = opt_el || document;\n  var retVal = null;\n  if (parent.getElementsByClassName) {\n    retVal = parent.getElementsByClassName(className)[0];\n  } else {\n    retVal =\n        goog.dom.getElementByTagNameAndClass_(document, '*', className, opt_el);\n  }\n  return retVal || null;\n};\n\n\n/**\n * Ensures an element with the given className exists, and then returns the\n * first element with the provided className.\n *\n * @param {string} className the name of the class to look for.\n * @param {!Element|!Document=} opt_root Optional element or document to look\n *     in.\n * @return {!Element} The first item with the class name provided.\n * @throws {goog.asserts.AssertionError} Thrown if no element is found.\n */\ngoog.dom.getRequiredElementByClass = function(className, opt_root) {\n  var retValue = goog.dom.getElementByClass(className, opt_root);\n  return goog.asserts.assert(\n      retValue, 'No element found with className: ' + className);\n};\n\n\n/**\n * Prefer the standardized (http://www.w3.org/TR/selectors-api/), native and\n * fast W3C Selectors API.\n * @param {!(Element|Document)} parent The parent document object.\n * @return {boolean} whether or not we can use parent.querySelector* APIs.\n * @private\n */\ngoog.dom.canUseQuerySelector_ = function(parent) {\n  return !!(parent.querySelectorAll && parent.querySelector);\n};\n\n\n/**\n * Helper for `getElementsByTagNameAndClass`.\n * @param {!Document} doc The document to get the elements in.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n *     and numerical indices are guaranteed to exist). The members of the array\n *     are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.getElementsByTagNameAndClass_ = function(\n    doc, opt_tag, opt_class, opt_el) {\n  var parent = opt_el || doc;\n  var tagName =\n      (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : '';\n\n  if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) {\n    var query = tagName + (opt_class ? '.' + opt_class : '');\n    return parent.querySelectorAll(query);\n  }\n\n  // Use the native getElementsByClassName if available, under the assumption\n  // that even when the tag name is specified, there will be fewer elements to\n  // filter through when going by class than by tag name\n  if (opt_class && parent.getElementsByClassName) {\n    var els = parent.getElementsByClassName(opt_class);\n\n    if (tagName) {\n      var arrayLike = {};\n      var len = 0;\n\n      // Filter for specific tags if requested.\n      for (var i = 0, el; el = els[i]; i++) {\n        if (tagName == el.nodeName) {\n          arrayLike[len++] = el;\n        }\n      }\n      arrayLike.length = len;\n\n      return /** @type {!IArrayLike<!Element>} */ (arrayLike);\n    } else {\n      return els;\n    }\n  }\n\n  var els = parent.getElementsByTagName(tagName || '*');\n\n  if (opt_class) {\n    var arrayLike = {};\n    var len = 0;\n    for (var i = 0, el; el = els[i]; i++) {\n      var className = el.className;\n      // Check if className has a split function since SVG className does not.\n      if (typeof className.split == 'function' &&\n          goog.array.contains(className.split(/\\s+/), opt_class)) {\n        arrayLike[len++] = el;\n      }\n    }\n    arrayLike.length = len;\n    return /** @type {!IArrayLike<!Element>} */ (arrayLike);\n  } else {\n    return els;\n  }\n};\n\n\n/**\n * Helper for goog.dom.getElementByTagNameAndClass.\n *\n * @param {!Document} doc The document to get the elements in.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n *     tagName is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.getElementByTagNameAndClass_ = function(\n    doc, opt_tag, opt_class, opt_el) {\n  var parent = opt_el || doc;\n  var tag = (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : '';\n  if (goog.dom.canUseQuerySelector_(parent) && (tag || opt_class)) {\n    return parent.querySelector(tag + (opt_class ? '.' + opt_class : ''));\n  }\n  var elements =\n      goog.dom.getElementsByTagNameAndClass_(doc, opt_tag, opt_class, opt_el);\n  return elements[0] || null;\n};\n\n\n\n/**\n * Alias for `getElementsByTagNameAndClass`.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {Element=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n *     and numerical indices are guaranteed to exist). The members of the array\n *     are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.getElementsByTagNameAndClass} instead.\n */\ngoog.dom.$$ = goog.dom.getElementsByTagNameAndClass;\n\n\n/**\n * Sets multiple properties, and sometimes attributes, on an element. Note that\n * properties are simply object properties on the element instance, while\n * attributes are visible in the DOM. Many properties map to attributes with the\n * same names, some with different names, and there are also unmappable cases.\n *\n * This method sets properties by default (which means that custom attributes\n * are not supported). These are the exeptions (some of which is legacy):\n * - \"style\": Even though this is an attribute name, it is translated to a\n *   property, \"style.cssText\". Note that this property sanitizes and formats\n *   its value, unlike the attribute.\n * - \"class\": This is an attribute name, it is translated to the \"className\"\n *   property.\n * - \"for\": This is an attribute name, it is translated to the \"htmlFor\"\n *   property.\n * - Entries in {@see goog.dom.DIRECT_ATTRIBUTE_MAP_} are set as attributes,\n *   this is probably due to browser quirks.\n * - \"aria-*\", \"data-*\": Always set as attributes, they have no property\n *   counterparts.\n *\n * @param {Element} element DOM node to set properties on.\n * @param {Object} properties Hash of property:value pairs.\n *     Property values can be strings or goog.string.TypedString values (such as\n *     goog.html.SafeUrl).\n */\ngoog.dom.setProperties = function(element, properties) {\n  goog.object.forEach(properties, function(val, key) {\n    if (val && typeof val == 'object' && val.implementsGoogStringTypedString) {\n      val = val.getTypedStringValue();\n    }\n    if (key == 'style') {\n      element.style.cssText = val;\n    } else if (key == 'class') {\n      element.className = val;\n    } else if (key == 'for') {\n      element.htmlFor = val;\n    } else if (goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(key)) {\n      element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val);\n    } else if (\n        goog.string.startsWith(key, 'aria-') ||\n        goog.string.startsWith(key, 'data-')) {\n      element.setAttribute(key, val);\n    } else {\n      element[key] = val;\n    }\n  });\n};\n\n\n/**\n * Map of attributes that should be set using\n * element.setAttribute(key, val) instead of element[key] = val.  Used\n * by goog.dom.setProperties.\n *\n * @private {!Object<string, string>}\n * @const\n */\ngoog.dom.DIRECT_ATTRIBUTE_MAP_ = {\n  'cellpadding': 'cellPadding',\n  'cellspacing': 'cellSpacing',\n  'colspan': 'colSpan',\n  'frameborder': 'frameBorder',\n  'height': 'height',\n  'maxlength': 'maxLength',\n  'nonce': 'nonce',\n  'role': 'role',\n  'rowspan': 'rowSpan',\n  'type': 'type',\n  'usemap': 'useMap',\n  'valign': 'vAlign',\n  'width': 'width'\n};\n\n\n/**\n * Gets the dimensions of the viewport.\n *\n * Gecko Standards mode:\n * docEl.clientWidth  Width of viewport excluding scrollbar.\n * win.innerWidth     Width of viewport including scrollbar.\n * body.clientWidth   Width of body element.\n *\n * docEl.clientHeight Height of viewport excluding scrollbar.\n * win.innerHeight    Height of viewport including scrollbar.\n * body.clientHeight  Height of document.\n *\n * Gecko Backwards compatible mode:\n * docEl.clientWidth  Width of viewport excluding scrollbar.\n * win.innerWidth     Width of viewport including scrollbar.\n * body.clientWidth   Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight Height of document.\n * win.innerHeight    Height of viewport including scrollbar.\n * body.clientHeight  Height of viewport excluding scrollbar.\n *\n * IE6/7 Standards mode:\n * docEl.clientWidth  Width of viewport excluding scrollbar.\n * win.innerWidth     Undefined.\n * body.clientWidth   Width of body element.\n *\n * docEl.clientHeight Height of viewport excluding scrollbar.\n * win.innerHeight    Undefined.\n * body.clientHeight  Height of document element.\n *\n * IE5 + IE6/7 Backwards compatible mode:\n * docEl.clientWidth  0.\n * win.innerWidth     Undefined.\n * body.clientWidth   Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight 0.\n * win.innerHeight    Undefined.\n * body.clientHeight  Height of viewport excluding scrollbar.\n *\n * Opera 9 Standards and backwards compatible mode:\n * docEl.clientWidth  Width of viewport excluding scrollbar.\n * win.innerWidth     Width of viewport including scrollbar.\n * body.clientWidth   Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight Height of document.\n * win.innerHeight    Height of viewport including scrollbar.\n * body.clientHeight  Height of viewport excluding scrollbar.\n *\n * WebKit:\n * Safari 2\n * docEl.clientHeight Same as scrollHeight.\n * docEl.clientWidth  Same as innerWidth.\n * win.innerWidth     Width of viewport excluding scrollbar.\n * win.innerHeight    Height of the viewport including scrollbar.\n * frame.innerHeight  Height of the viewport exluding scrollbar.\n *\n * Safari 3 (tested in 522)\n *\n * docEl.clientWidth  Width of viewport excluding scrollbar.\n * docEl.clientHeight Height of viewport excluding scrollbar in strict mode.\n * body.clientHeight  Height of viewport excluding scrollbar in quirks mode.\n *\n * @param {Window=} opt_window Optional window element to test.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n */\ngoog.dom.getViewportSize = function(opt_window) {\n  // TODO(arv): This should not take an argument\n  return goog.dom.getViewportSize_(opt_window || window);\n};\n\n\n/**\n * Helper for `getViewportSize`.\n * @param {Window} win The window to get the view port size for.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n * @private\n */\ngoog.dom.getViewportSize_ = function(win) {\n  var doc = win.document;\n  var el = goog.dom.isCss1CompatMode_(doc) ? doc.documentElement : doc.body;\n  return new goog.math.Size(el.clientWidth, el.clientHeight);\n};\n\n\n/**\n * Calculates the height of the document.\n *\n * @return {number} The height of the current document.\n */\ngoog.dom.getDocumentHeight = function() {\n  return goog.dom.getDocumentHeight_(window);\n};\n\n/**\n * Calculates the height of the document of the given window.\n *\n * @param {!Window} win The window whose document height to retrieve.\n * @return {number} The height of the document of the given window.\n */\ngoog.dom.getDocumentHeightForWindow = function(win) {\n  return goog.dom.getDocumentHeight_(win);\n};\n\n/**\n * Calculates the height of the document of the given window.\n *\n * Function code copied from the opensocial gadget api:\n *   gadgets.window.adjustHeight(opt_height)\n *\n * @private\n * @param {!Window} win The window whose document height to retrieve.\n * @return {number} The height of the document of the given window.\n */\ngoog.dom.getDocumentHeight_ = function(win) {\n  // NOTE(eae): This method will return the window size rather than the document\n  // size in webkit quirks mode.\n  var doc = win.document;\n  var height = 0;\n\n  if (doc) {\n    // Calculating inner content height is hard and different between\n    // browsers rendering in Strict vs. Quirks mode.  We use a combination of\n    // three properties within document.body and document.documentElement:\n    // - scrollHeight\n    // - offsetHeight\n    // - clientHeight\n    // These values differ significantly between browsers and rendering modes.\n    // But there are patterns.  It just takes a lot of time and persistence\n    // to figure out.\n\n    var body = doc.body;\n    var docEl = /** @type {!HTMLElement} */ (doc.documentElement);\n    if (!(docEl && body)) {\n      return 0;\n    }\n\n    // Get the height of the viewport\n    var vh = goog.dom.getViewportSize_(win).height;\n    if (goog.dom.isCss1CompatMode_(doc) && docEl.scrollHeight) {\n      // In Strict mode:\n      // The inner content height is contained in either:\n      //    document.documentElement.scrollHeight\n      //    document.documentElement.offsetHeight\n      // Based on studying the values output by different browsers,\n      // use the value that's NOT equal to the viewport height found above.\n      height =\n          docEl.scrollHeight != vh ? docEl.scrollHeight : docEl.offsetHeight;\n    } else {\n      // In Quirks mode:\n      // documentElement.clientHeight is equal to documentElement.offsetHeight\n      // except in IE.  In most browsers, document.documentElement can be used\n      // to calculate the inner content height.\n      // However, in other browsers (e.g. IE), document.body must be used\n      // instead.  How do we know which one to use?\n      // If document.documentElement.clientHeight does NOT equal\n      // document.documentElement.offsetHeight, then use document.body.\n      var sh = docEl.scrollHeight;\n      var oh = docEl.offsetHeight;\n      if (docEl.clientHeight != oh) {\n        sh = body.scrollHeight;\n        oh = body.offsetHeight;\n      }\n\n      // Detect whether the inner content height is bigger or smaller\n      // than the bounding box (viewport).  If bigger, take the larger\n      // value.  If smaller, take the smaller value.\n      if (sh > vh) {\n        // Content is larger\n        height = sh > oh ? sh : oh;\n      } else {\n        // Content is smaller\n        height = sh < oh ? sh : oh;\n      }\n    }\n  }\n\n  return height;\n};\n\n\n/**\n * Gets the page scroll distance as a coordinate object.\n *\n * @param {Window=} opt_window Optional window element to test.\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n * @deprecated Use {@link goog.dom.getDocumentScroll} instead.\n */\ngoog.dom.getPageScroll = function(opt_window) {\n  var win = opt_window || goog.global || window;\n  return goog.dom.getDomHelper(win.document).getDocumentScroll();\n};\n\n\n/**\n * Gets the document scroll distance as a coordinate object.\n *\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n */\ngoog.dom.getDocumentScroll = function() {\n  return goog.dom.getDocumentScroll_(document);\n};\n\n\n/**\n * Helper for `getDocumentScroll`.\n *\n * @param {!Document} doc The document to get the scroll for.\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n * @private\n */\ngoog.dom.getDocumentScroll_ = function(doc) {\n  var el = goog.dom.getDocumentScrollElement_(doc);\n  var win = goog.dom.getWindow_(doc);\n  if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher('10') &&\n      win.pageYOffset != el.scrollTop) {\n    // The keyboard on IE10 touch devices shifts the page using the pageYOffset\n    // without modifying scrollTop. For this case, we want the body scroll\n    // offsets.\n    return new goog.math.Coordinate(el.scrollLeft, el.scrollTop);\n  }\n  return new goog.math.Coordinate(\n      win.pageXOffset || el.scrollLeft, win.pageYOffset || el.scrollTop);\n};\n\n\n/**\n * Gets the document scroll element.\n * @return {!Element} Scrolling element.\n */\ngoog.dom.getDocumentScrollElement = function() {\n  return goog.dom.getDocumentScrollElement_(document);\n};\n\n\n/**\n * Helper for `getDocumentScrollElement`.\n * @param {!Document} doc The document to get the scroll element for.\n * @return {!Element} Scrolling element.\n * @private\n */\ngoog.dom.getDocumentScrollElement_ = function(doc) {\n  // Old WebKit needs body.scrollLeft in both quirks mode and strict mode. We\n  // also default to the documentElement if the document does not have a body\n  // (e.g. a SVG document).\n  // Uses http://dev.w3.org/csswg/cssom-view/#dom-document-scrollingelement to\n  // avoid trying to guess about browser behavior from the UA string.\n  if (doc.scrollingElement) {\n    return doc.scrollingElement;\n  }\n  if (!goog.userAgent.WEBKIT && goog.dom.isCss1CompatMode_(doc)) {\n    return doc.documentElement;\n  }\n  return doc.body || doc.documentElement;\n};\n\n\n/**\n * Gets the window object associated with the given document.\n *\n * @param {Document=} opt_doc  Document object to get window for.\n * @return {!Window} The window associated with the given document.\n */\ngoog.dom.getWindow = function(opt_doc) {\n  // TODO(arv): This should not take an argument.\n  return opt_doc ? goog.dom.getWindow_(opt_doc) : window;\n};\n\n\n/**\n * Helper for `getWindow`.\n *\n * @param {!Document} doc  Document object to get window for.\n * @return {!Window} The window associated with the given document.\n * @private\n */\ngoog.dom.getWindow_ = function(doc) {\n  return /** @type {!Window} */ (doc.parentWindow || doc.defaultView);\n};\n\n\n/**\n * Returns a dom node with a set of attributes.  This function accepts varargs\n * for subsequent nodes to be added.  Subsequent nodes will be added to the\n * first node as childNodes.\n *\n * So:\n * <code>createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P),\n * createDom(goog.dom.TagName.P));</code> would return a div with two child\n * paragraphs\n *\n * This function uses {@link goog.dom.setProperties} to set attributes: the\n * `opt_attributes` parameter follows the same rules.\n *\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n *     of name-value pairs for attributes. If a string, then this is the\n *     className of the new element. If an array, the elements will be joined\n *     together as the className of the new element.\n * @param {...(Object|string|Array|NodeList|null|undefined)} var_args Further\n *     DOM nodes or strings for text nodes. If one of the var_args is an array\n *     or NodeList, its elements will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n *     is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.createDom = function(tagName, opt_attributes, var_args) {\n  return goog.dom.createDom_(document, arguments);\n};\n\n\n/**\n * Helper for `createDom`.\n * @param {!Document} doc The document to create the DOM in.\n * @param {!Arguments} args Argument object passed from the callers. See\n *     `goog.dom.createDom` for details.\n * @return {!Element} Reference to a DOM node.\n * @private\n */\ngoog.dom.createDom_ = function(doc, args) {\n  var tagName = String(args[0]);\n  var attributes = args[1];\n\n  // Internet Explorer is dumb:\n  // name: https://msdn.microsoft.com/en-us/library/ms534184(v=vs.85).aspx\n  // type: https://msdn.microsoft.com/en-us/library/ms534700(v=vs.85).aspx\n  // Also does not allow setting of 'type' attribute on 'input' or 'button'.\n  if (!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES && attributes &&\n      (attributes.name || attributes.type)) {\n    var tagNameArr = ['<', tagName];\n    if (attributes.name) {\n      tagNameArr.push(' name=\"', goog.string.htmlEscape(attributes.name), '\"');\n    }\n    if (attributes.type) {\n      tagNameArr.push(' type=\"', goog.string.htmlEscape(attributes.type), '\"');\n\n      // Clone attributes map to remove 'type' without mutating the input.\n      var clone = {};\n      goog.object.extend(clone, attributes);\n\n      // JSCompiler can't see how goog.object.extend added this property,\n      // because it was essentially added by reflection.\n      // So it needs to be quoted.\n      delete clone['type'];\n\n      attributes = clone;\n    }\n    tagNameArr.push('>');\n    tagName = tagNameArr.join('');\n  }\n\n  var element = goog.dom.createElement_(doc, tagName);\n\n  if (attributes) {\n    if (typeof attributes === 'string') {\n      element.className = attributes;\n    } else if (Array.isArray(attributes)) {\n      element.className = attributes.join(' ');\n    } else {\n      goog.dom.setProperties(element, attributes);\n    }\n  }\n\n  if (args.length > 2) {\n    goog.dom.append_(doc, element, args, 2);\n  }\n\n  return element;\n};\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Document} doc The document to create new nodes in.\n * @param {!Node} parent The node to append nodes to.\n * @param {!Arguments} args The values to add. See `goog.dom.append`.\n * @param {number} startIndex The index of the array to start from.\n * @private\n */\ngoog.dom.append_ = function(doc, parent, args, startIndex) {\n  function childHandler(child) {\n    // TODO(user): More coercion, ala MochiKit?\n    if (child) {\n      parent.appendChild(\n          typeof child === 'string' ? doc.createTextNode(child) : child);\n    }\n  }\n\n  for (var i = startIndex; i < args.length; i++) {\n    var arg = args[i];\n    // TODO(attila): Fix isArrayLike to return false for a text node.\n    if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {\n      // If the argument is a node list, not a real array, use a clone,\n      // because forEach can't be used to mutate a NodeList.\n      goog.array.forEach(\n          goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg,\n          childHandler);\n    } else {\n      childHandler(arg);\n    }\n  }\n};\n\n\n/**\n * Alias for `createDom`.\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n *     of name-value pairs for attributes. If a string, then this is the\n *     className of the new element. If an array, the elements will be joined\n *     together as the className of the new element.\n * @param {...(Object|string|Array|NodeList|null|undefined)} var_args Further\n *     DOM nodes or strings for text nodes. If one of the var_args is an array,\n *     its children will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n *     is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.createDom} instead.\n */\ngoog.dom.$dom = goog.dom.createDom;\n\n\n/**\n * Creates a new element.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n *     a string or a more specific type if it is a member of goog.dom.TagName\n *     (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.createElement = function(name) {\n  return goog.dom.createElement_(document, name);\n};\n\n\n/**\n * Creates a new element.\n * @param {!Document} doc The document to create the element in.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n *     a string or a more specific type if it is a member of goog.dom.TagName\n *     (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.createElement_ = function(doc, name) {\n  name = String(name);\n  if (doc.contentType === 'application/xhtml+xml') name = name.toLowerCase();\n  return doc.createElement(name);\n};\n\n\n/**\n * Creates a new text node.\n * @param {number|string} content Content.\n * @return {!Text} The new text node.\n */\ngoog.dom.createTextNode = function(content) {\n  return document.createTextNode(String(content));\n};\n\n\n/**\n * Create a table.\n * @param {number} rows The number of rows in the table.  Must be >= 1.\n * @param {number} columns The number of columns in the table.  Must be >= 1.\n * @param {boolean=} opt_fillWithNbsp If true, fills table entries with\n *     `goog.string.Unicode.NBSP` characters.\n * @return {!Element} The created table.\n */\ngoog.dom.createTable = function(rows, columns, opt_fillWithNbsp) {\n  // TODO(mlourenco): Return HTMLTableElement, also in prototype function.\n  // Callers need to be updated to e.g. not assign numbers to table.cellSpacing.\n  return goog.dom.createTable_(document, rows, columns, !!opt_fillWithNbsp);\n};\n\n\n/**\n * Create a table.\n * @param {!Document} doc Document object to use to create the table.\n * @param {number} rows The number of rows in the table.  Must be >= 1.\n * @param {number} columns The number of columns in the table.  Must be >= 1.\n * @param {boolean} fillWithNbsp If true, fills table entries with\n *     `goog.string.Unicode.NBSP` characters.\n * @return {!HTMLTableElement} The created table.\n * @private\n */\ngoog.dom.createTable_ = function(doc, rows, columns, fillWithNbsp) {\n  var table = goog.dom.createElement_(doc, goog.dom.TagName.TABLE);\n  var tbody =\n      table.appendChild(goog.dom.createElement_(doc, goog.dom.TagName.TBODY));\n  for (var i = 0; i < rows; i++) {\n    var tr = goog.dom.createElement_(doc, goog.dom.TagName.TR);\n    for (var j = 0; j < columns; j++) {\n      var td = goog.dom.createElement_(doc, goog.dom.TagName.TD);\n      // IE <= 9 will create a text node if we set text content to the empty\n      // string, so we avoid doing it unless necessary. This ensures that the\n      // same DOM tree is returned on all browsers.\n      if (fillWithNbsp) {\n        goog.dom.setTextContent(td, goog.string.Unicode.NBSP);\n      }\n      tr.appendChild(td);\n    }\n    tbody.appendChild(tr);\n  }\n  return table;\n};\n\n\n\n/**\n * Creates a new Node from constant strings of HTML markup.\n * @param {...!goog.string.Const} var_args The HTML strings to concatenate then\n *     convert into a node.\n * @return {!Node}\n */\ngoog.dom.constHtmlToNode = function(var_args) {\n  var stringArray = goog.array.map(arguments, goog.string.Const.unwrap);\n  var safeHtml =\n      goog.html.uncheckedconversions\n          .safeHtmlFromStringKnownToSatisfyTypeContract(\n              goog.string.Const.from(\n                  'Constant HTML string, that gets turned into a ' +\n                  'Node later, so it will be automatically balanced.'),\n              stringArray.join(''));\n  return goog.dom.safeHtmlToNode(safeHtml);\n};\n\n\n/**\n * Converts HTML markup into a node. This is a safe version of\n * `goog.dom.htmlToDocumentFragment` which is now deleted.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n */\ngoog.dom.safeHtmlToNode = function(html) {\n  return goog.dom.safeHtmlToNode_(document, html);\n};\n\n\n/**\n * Helper for `safeHtmlToNode`.\n * @param {!Document} doc The document.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n * @private\n */\ngoog.dom.safeHtmlToNode_ = function(doc, html) {\n  var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV);\n  if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) {\n    goog.dom.safe.setInnerHtml(\n        tempDiv, goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, html));\n    tempDiv.removeChild(goog.asserts.assert(tempDiv.firstChild));\n  } else {\n    goog.dom.safe.setInnerHtml(tempDiv, html);\n  }\n  return goog.dom.childrenToNode_(doc, tempDiv);\n};\n\n\n/**\n * Helper for `safeHtmlToNode_`.\n * @param {!Document} doc The document.\n * @param {!Node} tempDiv The input node.\n * @return {!Node} The resulting node.\n * @private\n */\ngoog.dom.childrenToNode_ = function(doc, tempDiv) {\n  if (tempDiv.childNodes.length == 1) {\n    return tempDiv.removeChild(goog.asserts.assert(tempDiv.firstChild));\n  } else {\n    var fragment = doc.createDocumentFragment();\n    while (tempDiv.firstChild) {\n      fragment.appendChild(tempDiv.firstChild);\n    }\n    return fragment;\n  }\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @return {boolean} True if in CSS1-compatible mode.\n */\ngoog.dom.isCss1CompatMode = function() {\n  return goog.dom.isCss1CompatMode_(document);\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @param {!Document} doc The document to check.\n * @return {boolean} True if in CSS1-compatible mode.\n * @private\n */\ngoog.dom.isCss1CompatMode_ = function(doc) {\n  if (goog.dom.COMPAT_MODE_KNOWN_) {\n    return goog.dom.ASSUME_STANDARDS_MODE;\n  }\n\n  return doc.compatMode == 'CSS1Compat';\n};\n\n\n/**\n * Determines if the given node can contain children, intended to be used for\n * HTML generation.\n *\n * IE natively supports node.canHaveChildren but has inconsistent behavior.\n * Prior to IE8 the base tag allows children and in IE9 all nodes return true\n * for canHaveChildren.\n *\n * In practice all non-IE browsers allow you to add children to any node, but\n * the behavior is inconsistent:\n *\n * <pre>\n *   var a = goog.dom.createElement(goog.dom.TagName.BR);\n *   a.appendChild(document.createTextNode('foo'));\n *   a.appendChild(document.createTextNode('bar'));\n *   console.log(a.childNodes.length);  // 2\n *   console.log(a.innerHTML);  // Chrome: \"\", IE9: \"foobar\", FF3.5: \"foobar\"\n * </pre>\n *\n * For more information, see:\n * http://dev.w3.org/html5/markup/syntax.html#syntax-elements\n *\n * TODO(user): Rename shouldAllowChildren() ?\n *\n * @param {Node} node The node to check.\n * @return {boolean} Whether the node can contain children.\n */\ngoog.dom.canHaveChildren = function(node) {\n  if (node.nodeType != goog.dom.NodeType.ELEMENT) {\n    return false;\n  }\n  switch (/** @type {!Element} */ (node).tagName) {\n    case String(goog.dom.TagName.APPLET):\n    case String(goog.dom.TagName.AREA):\n    case String(goog.dom.TagName.BASE):\n    case String(goog.dom.TagName.BR):\n    case String(goog.dom.TagName.COL):\n    case String(goog.dom.TagName.COMMAND):\n    case String(goog.dom.TagName.EMBED):\n    case String(goog.dom.TagName.FRAME):\n    case String(goog.dom.TagName.HR):\n    case String(goog.dom.TagName.IMG):\n    case String(goog.dom.TagName.INPUT):\n    case String(goog.dom.TagName.IFRAME):\n    case String(goog.dom.TagName.ISINDEX):\n    case String(goog.dom.TagName.KEYGEN):\n    case String(goog.dom.TagName.LINK):\n    case String(goog.dom.TagName.NOFRAMES):\n    case String(goog.dom.TagName.NOSCRIPT):\n    case String(goog.dom.TagName.META):\n    case String(goog.dom.TagName.OBJECT):\n    case String(goog.dom.TagName.PARAM):\n    case String(goog.dom.TagName.SCRIPT):\n    case String(goog.dom.TagName.SOURCE):\n    case String(goog.dom.TagName.STYLE):\n    case String(goog.dom.TagName.TRACK):\n    case String(goog.dom.TagName.WBR):\n      return false;\n  }\n  return true;\n};\n\n\n/**\n * Appends a child to a node.\n * @param {Node} parent Parent.\n * @param {Node} child Child.\n */\ngoog.dom.appendChild = function(parent, child) {\n  goog.asserts.assert(\n      parent != null && child != null,\n      'goog.dom.appendChild expects non-null arguments');\n  parent.appendChild(child);\n};\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Node} parent The node to append nodes to.\n * @param {...goog.dom.Appendable} var_args The things to append to the node.\n *     If this is a Node it is appended as is.\n *     If this is a string then a text node is appended.\n *     If this is an array like object then fields 0 to length - 1 are appended.\n */\ngoog.dom.append = function(parent, var_args) {\n  goog.dom.append_(goog.dom.getOwnerDocument(parent), parent, arguments, 1);\n};\n\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Node} node Node to remove children from.\n */\ngoog.dom.removeChildren = function(node) {\n  // Note: Iterations over live collections can be slow, this is the fastest\n  // we could find. The double parenthesis are used to prevent JsCompiler and\n  // strict warnings.\n  var child;\n  while ((child = node.firstChild)) {\n    node.removeChild(child);\n  }\n};\n\n\n/**\n * Inserts a new node before an existing reference node (i.e. as the previous\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert before.\n */\ngoog.dom.insertSiblingBefore = function(newNode, refNode) {\n  goog.asserts.assert(\n      newNode != null && refNode != null,\n      'goog.dom.insertSiblingBefore expects non-null arguments');\n  if (refNode.parentNode) {\n    refNode.parentNode.insertBefore(newNode, refNode);\n  }\n};\n\n\n/**\n * Inserts a new node after an existing reference node (i.e. as the next\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert after.\n */\ngoog.dom.insertSiblingAfter = function(newNode, refNode) {\n  goog.asserts.assert(\n      newNode != null && refNode != null,\n      'goog.dom.insertSiblingAfter expects non-null arguments');\n  if (refNode.parentNode) {\n    refNode.parentNode.insertBefore(newNode, refNode.nextSibling);\n  }\n};\n\n\n/**\n * Insert a child at a given index. If index is larger than the number of child\n * nodes that the parent currently has, the node is inserted as the last child\n * node.\n * @param {Element} parent The element into which to insert the child.\n * @param {Node} child The element to insert.\n * @param {number} index The index at which to insert the new child node. Must\n *     not be negative.\n */\ngoog.dom.insertChildAt = function(parent, child, index) {\n  // Note that if the second argument is null, insertBefore\n  // will append the child at the end of the list of children.\n  goog.asserts.assert(\n      parent != null, 'goog.dom.insertChildAt expects a non-null parent');\n  parent.insertBefore(\n      /** @type {!Node} */ (child), parent.childNodes[index] || null);\n};\n\n\n/**\n * Removes a node from its parent.\n * @param {Node} node The node to remove.\n * @return {Node} The node removed if removed; else, null.\n */\ngoog.dom.removeNode = function(node) {\n  return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n};\n\n\n/**\n * Replaces a node in the DOM tree. Will do nothing if `oldNode` has no\n * parent.\n * @param {Node} newNode Node to insert.\n * @param {Node} oldNode Node to replace.\n */\ngoog.dom.replaceNode = function(newNode, oldNode) {\n  goog.asserts.assert(\n      newNode != null && oldNode != null,\n      'goog.dom.replaceNode expects non-null arguments');\n  var parent = oldNode.parentNode;\n  if (parent) {\n    parent.replaceChild(newNode, oldNode);\n  }\n};\n\n\n/**\n * Flattens an element. That is, removes it and replace it with its children.\n * Does nothing if the element is not in the document.\n * @param {Element} element The element to flatten.\n * @return {Element|undefined} The original element, detached from the document\n *     tree, sans children; or undefined, if the element was not in the document\n *     to begin with.\n */\ngoog.dom.flattenElement = function(element) {\n  var child, parent = element.parentNode;\n  if (parent && parent.nodeType != goog.dom.NodeType.DOCUMENT_FRAGMENT) {\n    // Use IE DOM method (supported by Opera too) if available\n    if (element.removeNode) {\n      return /** @type {Element} */ (element.removeNode(false));\n    } else {\n      // Move all children of the original node up one level.\n      while ((child = element.firstChild)) {\n        parent.insertBefore(child, element);\n      }\n\n      // Detach the original element.\n      return /** @type {Element} */ (goog.dom.removeNode(element));\n    }\n  }\n};\n\n\n/**\n * Returns an array containing just the element children of the given element.\n * @param {Element} element The element whose element children we want.\n * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list\n *     of just the element children of the given element.\n */\ngoog.dom.getChildren = function(element) {\n  // We check if the children attribute is supported for child elements\n  // since IE8 misuses the attribute by also including comments.\n  if (goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE &&\n      element.children != undefined) {\n    return element.children;\n  }\n  // Fall back to manually filtering the element's child nodes.\n  return goog.array.filter(element.childNodes, function(node) {\n    return node.nodeType == goog.dom.NodeType.ELEMENT;\n  });\n};\n\n\n/**\n * Returns the first child node that is an element.\n * @param {Node} node The node to get the first child element of.\n * @return {Element} The first child node of `node` that is an element.\n */\ngoog.dom.getFirstElementChild = function(node) {\n  if (node.firstElementChild !== undefined) {\n    return /** @type {!Element} */ (node).firstElementChild;\n  }\n  return goog.dom.getNextElementNode_(node.firstChild, true);\n};\n\n\n/**\n * Returns the last child node that is an element.\n * @param {Node} node The node to get the last child element of.\n * @return {Element} The last child node of `node` that is an element.\n */\ngoog.dom.getLastElementChild = function(node) {\n  if (node.lastElementChild !== undefined) {\n    return /** @type {!Element} */ (node).lastElementChild;\n  }\n  return goog.dom.getNextElementNode_(node.lastChild, false);\n};\n\n\n/**\n * Returns the first next sibling that is an element.\n * @param {Node} node The node to get the next sibling element of.\n * @return {Element} The next sibling of `node` that is an element.\n */\ngoog.dom.getNextElementSibling = function(node) {\n  if (node.nextElementSibling !== undefined) {\n    return /** @type {!Element} */ (node).nextElementSibling;\n  }\n  return goog.dom.getNextElementNode_(node.nextSibling, true);\n};\n\n\n/**\n * Returns the first previous sibling that is an element.\n * @param {Node} node The node to get the previous sibling element of.\n * @return {Element} The first previous sibling of `node` that is\n *     an element.\n */\ngoog.dom.getPreviousElementSibling = function(node) {\n  if (node.previousElementSibling !== undefined) {\n    return /** @type {!Element} */ (node).previousElementSibling;\n  }\n  return goog.dom.getNextElementNode_(node.previousSibling, false);\n};\n\n\n/**\n * Returns the first node that is an element in the specified direction,\n * starting with `node`.\n * @param {Node} node The node to get the next element from.\n * @param {boolean} forward Whether to look forwards or backwards.\n * @return {Element} The first element.\n * @private\n */\ngoog.dom.getNextElementNode_ = function(node, forward) {\n  while (node && node.nodeType != goog.dom.NodeType.ELEMENT) {\n    node = forward ? node.nextSibling : node.previousSibling;\n  }\n\n  return /** @type {Element} */ (node);\n};\n\n\n/**\n * Returns the next node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The next node in the DOM tree, or null if this was the last\n *     node.\n */\ngoog.dom.getNextNode = function(node) {\n  if (!node) {\n    return null;\n  }\n\n  if (node.firstChild) {\n    return node.firstChild;\n  }\n\n  while (node && !node.nextSibling) {\n    node = node.parentNode;\n  }\n\n  return node ? node.nextSibling : null;\n};\n\n\n/**\n * Returns the previous node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The previous node in the DOM tree, or null if this was the\n *     first node.\n */\ngoog.dom.getPreviousNode = function(node) {\n  if (!node) {\n    return null;\n  }\n\n  if (!node.previousSibling) {\n    return node.parentNode;\n  }\n\n  node = node.previousSibling;\n  while (node && node.lastChild) {\n    node = node.lastChild;\n  }\n\n  return node;\n};\n\n\n/**\n * Whether the object looks like a DOM node.\n * @param {?} obj The object being tested for node likeness.\n * @return {boolean} Whether the object looks like a DOM node.\n */\ngoog.dom.isNodeLike = function(obj) {\n  return goog.isObject(obj) && obj.nodeType > 0;\n};\n\n\n/**\n * Whether the object looks like an Element.\n * @param {?} obj The object being tested for Element likeness.\n * @return {boolean} Whether the object looks like an Element.\n */\ngoog.dom.isElement = function(obj) {\n  return goog.isObject(obj) && obj.nodeType == goog.dom.NodeType.ELEMENT;\n};\n\n\n/**\n * Returns true if the specified value is a Window object. This includes the\n * global window for HTML pages, and iframe windows.\n * @param {?} obj Variable to test.\n * @return {boolean} Whether the variable is a window.\n */\ngoog.dom.isWindow = function(obj) {\n  return goog.isObject(obj) && obj['window'] == obj;\n};\n\n\n/**\n * Returns an element's parent, if it's an Element.\n * @param {Element} element The DOM element.\n * @return {Element} The parent, or null if not an Element.\n */\ngoog.dom.getParentElement = function(element) {\n  var parent;\n  if (goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY) {\n    var isIe9 = goog.userAgent.IE && goog.userAgent.isVersionOrHigher('9') &&\n        !goog.userAgent.isVersionOrHigher('10');\n    // SVG elements in IE9 can't use the parentElement property.\n    // goog.global['SVGElement'] is not defined in IE9 quirks mode.\n    if (!(isIe9 && goog.global['SVGElement'] &&\n          element instanceof goog.global['SVGElement'])) {\n      parent = element.parentElement;\n      if (parent) {\n        return parent;\n      }\n    }\n  }\n  parent = element.parentNode;\n  return goog.dom.isElement(parent) ? /** @type {!Element} */ (parent) : null;\n};\n\n\n/**\n * Whether a node contains another node.\n * @param {?Node|undefined} parent The node that should contain the other node.\n * @param {?Node|undefined} descendant The node to test presence of.\n * @return {boolean} Whether the parent node contains the descendant node.\n */\ngoog.dom.contains = function(parent, descendant) {\n  if (!parent || !descendant) {\n    return false;\n  }\n  // We use browser specific methods for this if available since it is faster\n  // that way.\n\n  // IE DOM\n  if (parent.contains && descendant.nodeType == goog.dom.NodeType.ELEMENT) {\n    return parent == descendant || parent.contains(descendant);\n  }\n\n  // W3C DOM Level 3\n  if (typeof parent.compareDocumentPosition != 'undefined') {\n    return parent == descendant ||\n        Boolean(parent.compareDocumentPosition(descendant) & 16);\n  }\n\n  // W3C DOM Level 1\n  while (descendant && parent != descendant) {\n    descendant = descendant.parentNode;\n  }\n  return descendant == parent;\n};\n\n\n/**\n * Compares the document order of two nodes, returning 0 if they are the same\n * node, a negative number if node1 is before node2, and a positive number if\n * node2 is before node1.  Note that we compare the order the tags appear in the\n * document so in the tree <b><i>text</i></b> the B node is considered to be\n * before the I node.\n *\n * @param {Node} node1 The first node to compare.\n * @param {Node} node2 The second node to compare.\n * @return {number} 0 if the nodes are the same node, a negative number if node1\n *     is before node2, and a positive number if node2 is before node1.\n */\ngoog.dom.compareNodeOrder = function(node1, node2) {\n  // Fall out quickly for equality.\n  if (node1 == node2) {\n    return 0;\n  }\n\n  // Use compareDocumentPosition where available\n  if (node1.compareDocumentPosition) {\n    // 4 is the bitmask for FOLLOWS.\n    return node1.compareDocumentPosition(node2) & 2 ? 1 : -1;\n  }\n\n  // Special case for document nodes on IE 7 and 8.\n  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {\n    if (node1.nodeType == goog.dom.NodeType.DOCUMENT) {\n      return -1;\n    }\n    if (node2.nodeType == goog.dom.NodeType.DOCUMENT) {\n      return 1;\n    }\n  }\n\n  // Process in IE using sourceIndex - we check to see if the first node has\n  // a source index or if its parent has one.\n  if ('sourceIndex' in node1 ||\n      (node1.parentNode && 'sourceIndex' in node1.parentNode)) {\n    var isElement1 = node1.nodeType == goog.dom.NodeType.ELEMENT;\n    var isElement2 = node2.nodeType == goog.dom.NodeType.ELEMENT;\n\n    if (isElement1 && isElement2) {\n      return node1.sourceIndex - node2.sourceIndex;\n    } else {\n      var parent1 = node1.parentNode;\n      var parent2 = node2.parentNode;\n\n      if (parent1 == parent2) {\n        return goog.dom.compareSiblingOrder_(node1, node2);\n      }\n\n      if (!isElement1 && goog.dom.contains(parent1, node2)) {\n        return -1 * goog.dom.compareParentsDescendantNodeIe_(node1, node2);\n      }\n\n\n      if (!isElement2 && goog.dom.contains(parent2, node1)) {\n        return goog.dom.compareParentsDescendantNodeIe_(node2, node1);\n      }\n\n      return (isElement1 ? node1.sourceIndex : parent1.sourceIndex) -\n          (isElement2 ? node2.sourceIndex : parent2.sourceIndex);\n    }\n  }\n\n  // For Safari, we compare ranges.\n  var doc = goog.dom.getOwnerDocument(node1);\n\n  var range1, range2;\n  range1 = doc.createRange();\n  range1.selectNode(node1);\n  range1.collapse(true);\n\n  range2 = doc.createRange();\n  range2.selectNode(node2);\n  range2.collapse(true);\n\n  return range1.compareBoundaryPoints(\n      goog.global['Range'].START_TO_END, range2);\n};\n\n\n/**\n * Utility function to compare the position of two nodes, when\n * `textNode`'s parent is an ancestor of `node`.  If this entry\n * condition is not met, this function will attempt to reference a null object.\n * @param {!Node} textNode The textNode to compare.\n * @param {Node} node The node to compare.\n * @return {number} -1 if node is before textNode, +1 otherwise.\n * @private\n */\ngoog.dom.compareParentsDescendantNodeIe_ = function(textNode, node) {\n  var parent = textNode.parentNode;\n  if (parent == node) {\n    // If textNode is a child of node, then node comes first.\n    return -1;\n  }\n  var sibling = node;\n  while (sibling.parentNode != parent) {\n    sibling = sibling.parentNode;\n  }\n  return goog.dom.compareSiblingOrder_(sibling, textNode);\n};\n\n\n/**\n * Utility function to compare the position of two nodes known to be non-equal\n * siblings.\n * @param {Node} node1 The first node to compare.\n * @param {!Node} node2 The second node to compare.\n * @return {number} -1 if node1 is before node2, +1 otherwise.\n * @private\n */\ngoog.dom.compareSiblingOrder_ = function(node1, node2) {\n  var s = node2;\n  while ((s = s.previousSibling)) {\n    if (s == node1) {\n      // We just found node1 before node2.\n      return -1;\n    }\n  }\n\n  // Since we didn't find it, node1 must be after node2.\n  return 1;\n};\n\n\n/**\n * Find the deepest common ancestor of the given nodes.\n * @param {...Node} var_args The nodes to find a common ancestor of.\n * @return {Node} The common ancestor of the nodes, or null if there is none.\n *     null will only be returned if two or more of the nodes are from different\n *     documents.\n */\ngoog.dom.findCommonAncestor = function(var_args) {\n  var i, count = arguments.length;\n  if (!count) {\n    return null;\n  } else if (count == 1) {\n    return arguments[0];\n  }\n\n  var paths = [];\n  var minLength = Infinity;\n  for (i = 0; i < count; i++) {\n    // Compute the list of ancestors.\n    var ancestors = [];\n    var node = arguments[i];\n    while (node) {\n      ancestors.unshift(node);\n      node = node.parentNode;\n    }\n\n    // Save the list for comparison.\n    paths.push(ancestors);\n    minLength = Math.min(minLength, ancestors.length);\n  }\n  var output = null;\n  for (i = 0; i < minLength; i++) {\n    var first = paths[0][i];\n    for (var j = 1; j < count; j++) {\n      if (first != paths[j][i]) {\n        return output;\n      }\n    }\n    output = first;\n  }\n  return output;\n};\n\n\n/**\n * Returns whether node is in a document or detached. Throws an error if node\n * itself is a document. This specifically handles two cases beyond naive use of\n * builtins: (1) it works correctly in IE, and (2) it works for elements from\n * different documents/iframes. If neither of these considerations are relevant\n * then a simple `document.contains(node)` may be used instead.\n * @param {!Node} node\n * @return {boolean}\n */\ngoog.dom.isInDocument = function(node) {\n  return (node.ownerDocument.compareDocumentPosition(node) & 16) == 16;\n};\n\n\n/**\n * Returns the owner document for a node.\n * @param {Node|Window} node The node to get the document for.\n * @return {!Document} The document owning the node.\n */\ngoog.dom.getOwnerDocument = function(node) {\n  // TODO(nnaze): Update param signature to be non-nullable.\n  goog.asserts.assert(node, 'Node cannot be null or undefined.');\n  return /** @type {!Document} */ (\n      node.nodeType == goog.dom.NodeType.DOCUMENT ? node : node.ownerDocument ||\n              node.document);\n};\n\n\n/**\n * Cross-browser function for getting the document element of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {!Document} The frame content document.\n */\ngoog.dom.getFrameContentDocument = function(frame) {\n  return frame.contentDocument ||\n      /** @type {!HTMLFrameElement} */ (frame).contentWindow.document;\n};\n\n\n/**\n * Cross-browser function for getting the window of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {Window} The window associated with the given frame, or null if none\n *     exists.\n */\ngoog.dom.getFrameContentWindow = function(frame) {\n  try {\n    return frame.contentWindow ||\n        (frame.contentDocument ? goog.dom.getWindow(frame.contentDocument) :\n                                 null);\n  } catch (e) {\n    // NOTE(user): In IE8, checking the contentWindow or contentDocument\n    // properties will throw a \"Unspecified Error\" exception if the iframe is\n    // not inserted in the DOM. If we get this we can be sure that no window\n    // exists, so return null.\n  }\n  return null;\n};\n\n\n/**\n * Sets the text content of a node, with cross-browser support.\n * @param {Node} node The node to change the text content of.\n * @param {string|number} text The value that should replace the node's content.\n */\ngoog.dom.setTextContent = function(node, text) {\n  goog.asserts.assert(\n      node != null,\n      'goog.dom.setTextContent expects a non-null value for node');\n\n  if ('textContent' in node) {\n    node.textContent = text;\n  } else if (node.nodeType == goog.dom.NodeType.TEXT) {\n    /** @type {!Text} */ (node).data = String(text);\n  } else if (\n      node.firstChild && node.firstChild.nodeType == goog.dom.NodeType.TEXT) {\n    // If the first child is a text node we just change its data and remove the\n    // rest of the children.\n    while (node.lastChild != node.firstChild) {\n      node.removeChild(goog.asserts.assert(node.lastChild));\n    }\n    /** @type {!Text} */ (node.firstChild).data = String(text);\n  } else {\n    goog.dom.removeChildren(node);\n    var doc = goog.dom.getOwnerDocument(node);\n    node.appendChild(doc.createTextNode(String(text)));\n  }\n};\n\n\n/**\n * Gets the outerHTML of a node, which is like innerHTML, except that it\n * actually contains the HTML of the node itself.\n * @param {Element} element The element to get the HTML of.\n * @return {string} The outerHTML of the given element.\n */\ngoog.dom.getOuterHtml = function(element) {\n  goog.asserts.assert(\n      element !== null,\n      'goog.dom.getOuterHtml expects a non-null value for element');\n  // IE, Opera and WebKit all have outerHTML.\n  if ('outerHTML' in element) {\n    return element.outerHTML;\n  } else {\n    var doc = goog.dom.getOwnerDocument(element);\n    var div = goog.dom.createElement_(doc, goog.dom.TagName.DIV);\n    div.appendChild(element.cloneNode(true));\n    return div.innerHTML;\n  }\n};\n\n\n/**\n * Finds the first descendant node that matches the filter function, using depth\n * first search. This function offers the most general purpose way of finding a\n * matching element.\n *\n * Prefer using `querySelector` if the matching criteria can be expressed as a\n * CSS selector, or `goog.dom.findElement` if you would filter for `nodeType ==\n * Node.ELEMENT_NODE`.\n *\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Node|undefined} The found node or undefined if none is found.\n */\ngoog.dom.findNode = function(root, p) {\n  var rv = [];\n  var found = goog.dom.findNodes_(root, p, rv, true);\n  return found ? rv[0] : undefined;\n};\n\n\n/**\n * Finds all the descendant nodes that match the filter function, using depth\n * first search. This function offers the most general-purpose way\n * of finding a set of matching elements.\n *\n * Prefer using `querySelectorAll` if the matching criteria can be expressed as\n * a CSS selector, or `goog.dom.findElements` if you would filter for\n * `nodeType == Node.ELEMENT_NODE`.\n *\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {!Array<!Node>} The found nodes or an empty array if none are found.\n */\ngoog.dom.findNodes = function(root, p) {\n  var rv = [];\n  goog.dom.findNodes_(root, p, rv, false);\n  return rv;\n};\n\n\n/**\n * Finds the first or all the descendant nodes that match the filter function,\n * using a depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @param {!Array<!Node>} rv The found nodes are added to this array.\n * @param {boolean} findOne If true we exit after the first found node.\n * @return {boolean} Whether the search is complete or not. True in case findOne\n *     is true and the node is found. False otherwise.\n * @private\n */\ngoog.dom.findNodes_ = function(root, p, rv, findOne) {\n  if (root != null) {\n    var child = root.firstChild;\n    while (child) {\n      if (p(child)) {\n        rv.push(child);\n        if (findOne) {\n          return true;\n        }\n      }\n      if (goog.dom.findNodes_(child, p, rv, findOne)) {\n        return true;\n      }\n      child = child.nextSibling;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Finds the first descendant element (excluding `root`) that matches the filter\n * function, using depth first search. Prefer using `querySelector` if the\n * matching criteria can be expressed as a CSS selector.\n *\n * @param {!Element | !Document} root\n * @param {function(!Element): boolean} pred Filter function.\n * @return {?Element} First matching element or null if there is none.\n */\ngoog.dom.findElement = function(root, pred) {\n  var stack = goog.dom.getChildrenReverse_(root);\n  while (stack.length > 0) {\n    var next = stack.pop();\n    if (pred(next)) return next;\n    for (var c = next.lastElementChild; c; c = c.previousElementSibling) {\n      stack.push(c);\n    }\n  }\n  return null;\n};\n\n\n/**\n * Finds all the descendant elements (excluding `root`) that match the filter\n * function, using depth first search. Prefer using `querySelectorAll` if the\n * matching criteria can be expressed as a CSS selector.\n *\n * @param {!Element | !Document} root\n * @param {function(!Element): boolean} pred Filter function.\n * @return {!Array<!Element>}\n */\ngoog.dom.findElements = function(root, pred) {\n  var result = [], stack = goog.dom.getChildrenReverse_(root);\n  while (stack.length > 0) {\n    var next = stack.pop();\n    if (pred(next)) result.push(next);\n    for (var c = next.lastElementChild; c; c = c.previousElementSibling) {\n      stack.push(c);\n    }\n  }\n  return result;\n};\n\n\n/**\n * @param {!Element | !Document} node\n * @return {!Array<!Element>} node's child elements in reverse order.\n * @private\n */\ngoog.dom.getChildrenReverse_ = function(node) {\n  // document.lastElementChild doesn't exist in IE9; fall back to\n  // documentElement.\n  if (node.nodeType == goog.dom.NodeType.DOCUMENT) {\n    return [node.documentElement];\n  } else {\n    var children = [];\n    for (var c = node.lastElementChild; c; c = c.previousElementSibling) {\n      children.push(c);\n    }\n    return children;\n  }\n};\n\n\n/**\n * Map of tags whose content to ignore when calculating text length.\n * @private {!Object<string, number>}\n * @const\n */\ngoog.dom.TAGS_TO_IGNORE_ = {\n  'SCRIPT': 1,\n  'STYLE': 1,\n  'HEAD': 1,\n  'IFRAME': 1,\n  'OBJECT': 1\n};\n\n\n/**\n * Map of tags which have predefined values with regard to whitespace.\n * @private {!Object<string, string>}\n * @const\n */\ngoog.dom.PREDEFINED_TAG_VALUES_ = {\n  'IMG': ' ',\n  'BR': '\\n'\n};\n\n\n/**\n * Returns true if the element has a tab index that allows it to receive\n * keyboard focus (tabIndex >= 0), false otherwise.  Note that some elements\n * natively support keyboard focus, even if they have no tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a tab index that allows keyboard\n *     focus.\n */\ngoog.dom.isFocusableTabIndex = function(element) {\n  return goog.dom.hasSpecifiedTabIndex_(element) &&\n      goog.dom.isTabIndexFocusable_(element);\n};\n\n\n/**\n * Enables or disables keyboard focus support on the element via its tab index.\n * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true\n * (or elements that natively support keyboard focus, like form elements) can\n * receive keyboard focus.  See http://go/tabindex for more info.\n * @param {Element} element Element whose tab index is to be changed.\n * @param {boolean} enable Whether to set or remove a tab index on the element\n *     that supports keyboard focus.\n */\ngoog.dom.setFocusableTabIndex = function(element, enable) {\n  if (enable) {\n    element.tabIndex = 0;\n  } else {\n    // Set tabIndex to -1 first, then remove it. This is a workaround for\n    // Safari (confirmed in version 4 on Windows). When removing the attribute\n    // without setting it to -1 first, the element remains keyboard focusable\n    // despite not having a tabIndex attribute anymore.\n    element.tabIndex = -1;\n    element.removeAttribute('tabIndex');  // Must be camelCase!\n  }\n};\n\n\n/**\n * Returns true if the element can be focused, i.e. it has a tab index that\n * allows it to receive keyboard focus (tabIndex >= 0), or it is an element\n * that natively supports keyboard focus.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element allows keyboard focus.\n */\ngoog.dom.isFocusable = function(element) {\n  var focusable;\n  // Some elements can have unspecified tab index and still receive focus.\n  if (goog.dom.nativelySupportsFocus_(element)) {\n    // Make sure the element is not disabled ...\n    focusable = !element.disabled &&\n        // ... and if a tab index is specified, it allows focus.\n        (!goog.dom.hasSpecifiedTabIndex_(element) ||\n         goog.dom.isTabIndexFocusable_(element));\n  } else {\n    focusable = goog.dom.isFocusableTabIndex(element);\n  }\n\n  // IE requires elements to be visible in order to focus them.\n  return focusable && goog.userAgent.IE ?\n      goog.dom.hasNonZeroBoundingRect_(/** @type {!HTMLElement} */ (element)) :\n      focusable;\n};\n\n\n/**\n * Returns true if the element has a specified tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a specified tab index.\n * @private\n */\ngoog.dom.hasSpecifiedTabIndex_ = function(element) {\n  // IE8 and below don't support hasAttribute(), instead check whether the\n  // 'tabindex' attributeNode is specified. Otherwise check hasAttribute().\n  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) {\n    var attrNode = element.getAttributeNode('tabindex');  // Must be lowercase!\n    return attrNode != null && attrNode.specified;\n  } else {\n    return element.hasAttribute('tabindex');\n  }\n};\n\n\n/**\n * Returns true if the element's tab index allows the element to be focused.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element's tab index allows focus.\n * @private\n */\ngoog.dom.isTabIndexFocusable_ = function(element) {\n  var index = /** @type {!HTMLElement} */ (element).tabIndex;\n  // NOTE: IE9 puts tabIndex in 16-bit int, e.g. -2 is 65534.\n  return typeof (index) === 'number' && index >= 0 && index < 32768;\n};\n\n\n/**\n * Returns true if the element is focusable even when tabIndex is not set.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element natively supports focus.\n * @private\n */\ngoog.dom.nativelySupportsFocus_ = function(element) {\n  return (\n      element.tagName == goog.dom.TagName.A && element.hasAttribute('href') ||\n      element.tagName == goog.dom.TagName.INPUT ||\n      element.tagName == goog.dom.TagName.TEXTAREA ||\n      element.tagName == goog.dom.TagName.SELECT ||\n      element.tagName == goog.dom.TagName.BUTTON);\n};\n\n\n/**\n * Returns true if the element has a bounding rectangle that would be visible\n * (i.e. its width and height are greater than zero).\n * @param {!HTMLElement} element Element to check.\n * @return {boolean} Whether the element has a non-zero bounding rectangle.\n * @private\n */\ngoog.dom.hasNonZeroBoundingRect_ = function(element) {\n  var rect;\n  if (!goog.isFunction(element['getBoundingClientRect']) ||\n      // In IE, getBoundingClientRect throws on detached nodes.\n      (goog.userAgent.IE && element.parentElement == null)) {\n    rect = {'height': element.offsetHeight, 'width': element.offsetWidth};\n  } else {\n    rect = element.getBoundingClientRect();\n  }\n  return rect != null && rect.height > 0 && rect.width > 0;\n};\n\n\n/**\n * Returns the text content of the current node, without markup and invisible\n * symbols. New lines are stripped and whitespace is collapsed,\n * such that each character would be visible.\n *\n * In browsers that support it, innerText is used.  Other browsers attempt to\n * simulate it via node traversal.  Line breaks are canonicalized in IE.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The text content.\n */\ngoog.dom.getTextContent = function(node) {\n  var textContent;\n  // Note(arv): IE9, Opera, and Safari 3 support innerText but they include\n  // text nodes in script tags. So we revert to use a user agent test here.\n  if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && node !== null &&\n      ('innerText' in node)) {\n    textContent = goog.string.canonicalizeNewlines(node.innerText);\n    // Unfortunately .innerText() returns text with &shy; symbols\n    // We need to filter it out and then remove duplicate whitespaces\n  } else {\n    var buf = [];\n    goog.dom.getTextContent_(node, buf, true);\n    textContent = buf.join('');\n  }\n\n  // Strip &shy; entities. goog.format.insertWordBreaks inserts them in Opera.\n  textContent = textContent.replace(/ \\xAD /g, ' ').replace(/\\xAD/g, '');\n  // Strip &#8203; entities. goog.format.insertWordBreaks inserts them in IE8.\n  textContent = textContent.replace(/\\u200B/g, '');\n\n  // Skip this replacement on old browsers with working innerText, which\n  // automatically turns &nbsp; into ' ' and / +/ into ' ' when reading\n  // innerText.\n  if (!goog.dom.BrowserFeature.CAN_USE_INNER_TEXT) {\n    textContent = textContent.replace(/ +/g, ' ');\n  }\n  if (textContent != ' ') {\n    textContent = textContent.replace(/^\\s*/, '');\n  }\n\n  return textContent;\n};\n\n\n/**\n * Returns the text content of the current node, without markup.\n *\n * Unlike `getTextContent` this method does not collapse whitespaces\n * or normalize lines breaks.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The raw text content.\n */\ngoog.dom.getRawTextContent = function(node) {\n  var buf = [];\n  goog.dom.getTextContent_(node, buf, false);\n\n  return buf.join('');\n};\n\n\n/**\n * Recursive support function for text content retrieval.\n *\n * @param {Node} node The node from which we are getting content.\n * @param {Array<string>} buf string buffer.\n * @param {boolean} normalizeWhitespace Whether to normalize whitespace.\n * @private\n */\ngoog.dom.getTextContent_ = function(node, buf, normalizeWhitespace) {\n  if (node.nodeName in goog.dom.TAGS_TO_IGNORE_) {\n    // ignore certain tags\n  } else if (node.nodeType == goog.dom.NodeType.TEXT) {\n    if (normalizeWhitespace) {\n      buf.push(String(node.nodeValue).replace(/(\\r\\n|\\r|\\n)/g, ''));\n    } else {\n      buf.push(node.nodeValue);\n    }\n  } else if (node.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {\n    buf.push(goog.dom.PREDEFINED_TAG_VALUES_[node.nodeName]);\n  } else {\n    var child = node.firstChild;\n    while (child) {\n      goog.dom.getTextContent_(child, buf, normalizeWhitespace);\n      child = child.nextSibling;\n    }\n  }\n};\n\n\n/**\n * Returns the text length of the text contained in a node, without markup. This\n * is equivalent to the selection length if the node was selected, or the number\n * of cursor movements to traverse the node. Images & BRs take one space.  New\n * lines are ignored.\n *\n * @param {Node} node The node whose text content length is being calculated.\n * @return {number} The length of `node`'s text content.\n */\ngoog.dom.getNodeTextLength = function(node) {\n  return goog.dom.getTextContent(node).length;\n};\n\n\n/**\n * Returns the text offset of a node relative to one of its ancestors. The text\n * length is the same as the length calculated by goog.dom.getNodeTextLength.\n *\n * @param {Node} node The node whose offset is being calculated.\n * @param {Node=} opt_offsetParent The node relative to which the offset will\n *     be calculated. Defaults to the node's owner document's body.\n * @return {number} The text offset.\n */\ngoog.dom.getNodeTextOffset = function(node, opt_offsetParent) {\n  var root = opt_offsetParent || goog.dom.getOwnerDocument(node).body;\n  var buf = [];\n  while (node && node != root) {\n    var cur = node;\n    while ((cur = cur.previousSibling)) {\n      buf.unshift(goog.dom.getTextContent(cur));\n    }\n    node = node.parentNode;\n  }\n  // Trim left to deal with FF cases when there might be line breaks and empty\n  // nodes at the front of the text\n  return goog.string.trimLeft(buf.join('')).replace(/ +/g, ' ').length;\n};\n\n\n/**\n * Returns the node at a given offset in a parent node.  If an object is\n * provided for the optional third parameter, the node and the remainder of the\n * offset will stored as properties of this object.\n * @param {Node} parent The parent node.\n * @param {number} offset The offset into the parent node.\n * @param {Object=} opt_result Object to be used to store the return value. The\n *     return value will be stored in the form {node: Node, remainder: number}\n *     if this object is provided.\n * @return {Node} The node at the given offset.\n */\ngoog.dom.getNodeAtOffset = function(parent, offset, opt_result) {\n  var stack = [parent], pos = 0, cur = null;\n  while (stack.length > 0 && pos < offset) {\n    cur = stack.pop();\n    if (cur.nodeName in goog.dom.TAGS_TO_IGNORE_) {\n      // ignore certain tags\n    } else if (cur.nodeType == goog.dom.NodeType.TEXT) {\n      var text = cur.nodeValue.replace(/(\\r\\n|\\r|\\n)/g, '').replace(/ +/g, ' ');\n      pos += text.length;\n    } else if (cur.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {\n      pos += goog.dom.PREDEFINED_TAG_VALUES_[cur.nodeName].length;\n    } else {\n      for (var i = cur.childNodes.length - 1; i >= 0; i--) {\n        stack.push(cur.childNodes[i]);\n      }\n    }\n  }\n  if (goog.isObject(opt_result)) {\n    opt_result.remainder = cur ? cur.nodeValue.length + offset - pos - 1 : 0;\n    opt_result.node = cur;\n  }\n\n  return cur;\n};\n\n\n/**\n * Returns true if the object is a `NodeList`.  To qualify as a NodeList,\n * the object must have a numeric length property and an item function (which\n * has type 'string' on IE for some reason).\n * @param {Object} val Object to test.\n * @return {boolean} Whether the object is a NodeList.\n */\ngoog.dom.isNodeList = function(val) {\n  // TODO(attila): Now the isNodeList is part of goog.dom we can use\n  // goog.userAgent to make this simpler.\n  // A NodeList must have a length property of type 'number' on all platforms.\n  if (val && typeof val.length == 'number') {\n    // A NodeList is an object everywhere except Safari, where it's a function.\n    if (goog.isObject(val)) {\n      // A NodeList must have an item function (on non-IE platforms) or an item\n      // property of type 'string' (on IE).\n      return typeof val.item == 'function' || typeof val.item == 'string';\n    } else if (goog.isFunction(val)) {\n      // On Safari, a NodeList is a function with an item property that is also\n      // a function.\n      return typeof /** @type {?} */ (val.item) == 'function';\n    }\n  }\n\n  // Not a NodeList.\n  return false;\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * tag name and/or class name. If the passed element matches the specified\n * criteria, the element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {?(goog.dom.TagName<T>|string)=} opt_tag The tag name to match (or\n *     null/undefined to match only based on class name).\n * @param {?string=} opt_class The class name to match (or null/undefined to\n *     match only based on tag name).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {?R} The first ancestor that matches the passed criteria, or\n *     null if no match is found. The return type is {?Element} if opt_tag is\n *     not a member of goog.dom.TagName or a more specific type if it is (e.g.\n *     {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getAncestorByTagNameAndClass = function(\n    element, opt_tag, opt_class, opt_maxSearchSteps) {\n  if (!opt_tag && !opt_class) {\n    return null;\n  }\n  var tagName = opt_tag ? String(opt_tag).toUpperCase() : null;\n  return /** @type {Element} */ (goog.dom.getAncestor(element, function(node) {\n    return (!tagName || node.nodeName == tagName) &&\n        (!opt_class ||\n         typeof node.className === 'string' &&\n             goog.array.contains(node.className.split(/\\s+/), opt_class));\n  }, true, opt_maxSearchSteps));\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * class name. If the passed element matches the specified criteria, the\n * element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {string} className The class name to match.\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {Element} The first ancestor that matches the passed criteria, or\n *     null if none match.\n */\ngoog.dom.getAncestorByClass = function(element, className, opt_maxSearchSteps) {\n  return goog.dom.getAncestorByTagNameAndClass(\n      element, null, className, opt_maxSearchSteps);\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that passes the\n * matcher function.\n * @param {Node} element The DOM node to start with.\n * @param {function(Node) : boolean} matcher A function that returns true if the\n *     passed node matches the desired criteria.\n * @param {boolean=} opt_includeNode If true, the node itself is included in\n *     the search (the first call to the matcher will pass startElement as\n *     the node to test).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {Node} DOM node that matched the matcher, or null if there was\n *     no match.\n */\ngoog.dom.getAncestor = function(\n    element, matcher, opt_includeNode, opt_maxSearchSteps) {\n  if (element && !opt_includeNode) {\n    element = element.parentNode;\n  }\n  var steps = 0;\n  while (element &&\n         (opt_maxSearchSteps == null || steps <= opt_maxSearchSteps)) {\n    goog.asserts.assert(element.name != 'parentNode');\n    if (matcher(element)) {\n      return element;\n    }\n    element = element.parentNode;\n    steps++;\n  }\n  // Reached the root of the DOM without a match\n  return null;\n};\n\n\n/**\n * Determines the active element in the given document.\n * @param {Document} doc The document to look in.\n * @return {Element} The active element.\n */\ngoog.dom.getActiveElement = function(doc) {\n  // While in an iframe, IE9 will throw \"Unspecified error\" when accessing\n  // activeElement.\n  try {\n    var activeElement = doc && doc.activeElement;\n    // While not in an iframe, IE9-11 sometimes gives null.\n    // While in an iframe, IE11 sometimes returns an empty object.\n    return activeElement && activeElement.nodeName ? activeElement : null;\n  } catch (e) {\n    return null;\n  }\n};\n\n\n/**\n * Gives the current devicePixelRatio.\n *\n * By default, this is the value of window.devicePixelRatio (which should be\n * preferred if present).\n *\n * If window.devicePixelRatio is not present, the ratio is calculated with\n * window.matchMedia, if present. Otherwise, gives 1.0.\n *\n * Some browsers (including Chrome) consider the browser zoom level in the pixel\n * ratio, so the value may change across multiple calls.\n *\n * @return {number} The number of actual pixels per virtual pixel.\n */\ngoog.dom.getPixelRatio = function() {\n  var win = goog.dom.getWindow();\n  if (win.devicePixelRatio !== undefined) {\n    return win.devicePixelRatio;\n  } else if (win.matchMedia) {\n    // Should be for IE10 and FF6-17 (this basically clamps to lower)\n    // Note that the order of these statements is important\n    return goog.dom.matchesPixelRatio_(3) || goog.dom.matchesPixelRatio_(2) ||\n           goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(1) ||\n           .75;\n  }\n  return 1;\n};\n\n\n/**\n * Calculates a mediaQuery to check if the current device supports the\n * given actual to virtual pixel ratio.\n * @param {number} pixelRatio The ratio of actual pixels to virtual pixels.\n * @return {number} pixelRatio if applicable, otherwise 0.\n * @private\n */\ngoog.dom.matchesPixelRatio_ = function(pixelRatio) {\n  var win = goog.dom.getWindow();\n  /**\n   * Due to the 1:96 fixed ratio of CSS in to CSS px, 1dppx is equivalent to\n   * 96dpi.\n   * @const {number}\n   */\n  var dpiPerDppx = 96;\n  var query =\n      // FF16-17\n      '(min-resolution: ' + pixelRatio + 'dppx),' +\n      // FF6-15\n      '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' +\n      // IE10 (this works for the two browsers above too but I don't want to\n      // trust the 1:96 fixed ratio magic)\n      '(min-resolution: ' + (pixelRatio * dpiPerDppx) + 'dpi)';\n  return win.matchMedia(query).matches ? pixelRatio : 0;\n};\n\n\n/**\n * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a\n * type information.\n * @param {!HTMLCanvasElement|!OffscreenCanvas} canvas\n * @return {!CanvasRenderingContext2D}\n */\ngoog.dom.getCanvasContext2D = function(canvas) {\n  return /** @type {!CanvasRenderingContext2D} */ (canvas.getContext('2d'));\n};\n\n\n\n/**\n * Create an instance of a DOM helper with a new document object.\n * @param {Document=} opt_document Document object to associate with this\n *     DOM helper.\n * @constructor\n */\ngoog.dom.DomHelper = function(opt_document) {\n  /**\n   * Reference to the document object to use\n   * @type {!Document}\n   * @private\n   */\n  this.document_ = opt_document || goog.global.document || document;\n};\n\n\n/**\n * Gets the dom helper object for the document where the element resides.\n * @param {Node=} opt_node If present, gets the DomHelper for this node.\n * @return {!goog.dom.DomHelper} The DomHelper.\n */\ngoog.dom.DomHelper.prototype.getDomHelper = goog.dom.getDomHelper;\n\n\n/**\n * Sets the document object.\n * @param {!Document} document Document object.\n */\ngoog.dom.DomHelper.prototype.setDocument = function(document) {\n  this.document_ = document;\n};\n\n\n/**\n * Gets the document object being used by the dom library.\n * @return {!Document} Document object.\n */\ngoog.dom.DomHelper.prototype.getDocument = function() {\n  return this.document_;\n};\n\n\n/**\n * Alias for `getElementById`. If a DOM node is passed in then we just\n * return that.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n */\ngoog.dom.DomHelper.prototype.getElement = function(element) {\n  return goog.dom.getElementHelper_(this.document_, element);\n};\n\n\n/**\n * Gets an element by id, asserting that the element is found.\n *\n * This is used when an element is expected to exist, and should fail with\n * an assertion error if it does not (if assertions are enabled).\n *\n * @param {string} id Element ID.\n * @return {!Element} The element with the given ID, if it exists.\n */\ngoog.dom.DomHelper.prototype.getRequiredElement = function(id) {\n  return goog.dom.getRequiredElementHelper_(this.document_, id);\n};\n\n\n/**\n * Alias for `getElement`.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n * @deprecated Use {@link goog.dom.DomHelper.prototype.getElement} instead.\n */\ngoog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;\n\n\n/**\n * Gets elements by tag name.\n * @param {!goog.dom.TagName<T>} tagName\n * @param {(!Document|!Element)=} opt_parent Parent element or document where to\n *     look for elements. Defaults to document of this DomHelper.\n * @return {!NodeList<R>} List of elements. The members of the list are\n *     {!Element} if tagName is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementsByTagName =\n    function(tagName, opt_parent) {\n  var parent = opt_parent || this.document_;\n  return parent.getElementsByTagName(String(tagName));\n};\n\n\n/**\n * Looks up elements by both tag and class name, using browser native functions\n * (`querySelectorAll`, `getElementsByTagName` or\n * `getElementsByClassName`) where possible. The returned array is a live\n * NodeList or a static list depending on the code path taken.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name or * for all\n *     tags.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n *     and numerical indices are guaranteed to exist). The members of the array\n *     are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n *     specific types if it is (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(\n    opt_tag, opt_class, opt_el) {\n  return goog.dom.getElementsByTagNameAndClass_(\n      this.document_, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Gets the first element matching the tag and the class.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n *     tagName is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementByTagNameAndClass = function(\n    opt_tag, opt_class, opt_el) {\n  return goog.dom.getElementByTagNameAndClass_(\n      this.document_, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Returns an array of all the elements with the provided className.\n * @param {string} className the name of the class to look for.\n * @param {Element|Document=} opt_el Optional element to look in.\n * @return {!IArrayLike<!Element>} The items found with the class name provided.\n */\ngoog.dom.DomHelper.prototype.getElementsByClass = function(className, opt_el) {\n  var doc = opt_el || this.document_;\n  return goog.dom.getElementsByClass(className, doc);\n};\n\n\n/**\n * Returns the first element we find matching the provided class name.\n * @param {string} className the name of the class to look for.\n * @param {(Element|Document)=} opt_el Optional element to look in.\n * @return {Element} The first item found with the class name provided.\n */\ngoog.dom.DomHelper.prototype.getElementByClass = function(className, opt_el) {\n  var doc = opt_el || this.document_;\n  return goog.dom.getElementByClass(className, doc);\n};\n\n\n/**\n * Ensures an element with the given className exists, and then returns the\n * first element with the provided className.\n * @param {string} className the name of the class to look for.\n * @param {(!Element|!Document)=} opt_root Optional element or document to look\n *     in.\n * @return {!Element} The first item found with the class name provided.\n * @throws {goog.asserts.AssertionError} Thrown if no element is found.\n */\ngoog.dom.DomHelper.prototype.getRequiredElementByClass = function(\n    className, opt_root) {\n  var root = opt_root || this.document_;\n  return goog.dom.getRequiredElementByClass(className, root);\n};\n\n\n/**\n * Alias for `getElementsByTagNameAndClass`.\n * @deprecated Use DomHelper getElementsByTagNameAndClass.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {Element=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n *     and numerical indices are guaranteed to exist). The members of the array\n *     are {!Element} if opt_tag is a string or more specific types if it is\n *     a member of goog.dom.TagName (e.g. {!HTMLAnchorElement} for\n *     goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.$$ =\n    goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;\n\n\n/**\n * Sets a number of properties on a node.\n * @param {Element} element DOM node to set properties on.\n * @param {Object} properties Hash of property:value pairs.\n */\ngoog.dom.DomHelper.prototype.setProperties = goog.dom.setProperties;\n\n\n/**\n * Gets the dimensions of the viewport.\n * @param {Window=} opt_window Optional window element to test. Defaults to\n *     the window of the Dom Helper.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n */\ngoog.dom.DomHelper.prototype.getViewportSize = function(opt_window) {\n  // TODO(arv): This should not take an argument. That breaks the rule of a\n  // a DomHelper representing a single frame/window/document.\n  return goog.dom.getViewportSize(opt_window || this.getWindow());\n};\n\n\n/**\n * Calculates the height of the document.\n *\n * @return {number} The height of the document.\n */\ngoog.dom.DomHelper.prototype.getDocumentHeight = function() {\n  return goog.dom.getDocumentHeight_(this.getWindow());\n};\n\n\n/**\n * Typedef for use with goog.dom.createDom and goog.dom.append.\n * @typedef {Object|string|Array|NodeList}\n */\ngoog.dom.Appendable;\n\n\n/**\n * Returns a dom node with a set of attributes.  This function accepts varargs\n * for subsequent nodes to be added.  Subsequent nodes will be added to the\n * first node as childNodes.\n *\n * So:\n * <code>createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P),\n * createDom(goog.dom.TagName.P));</code> would return a div with two child\n * paragraphs\n *\n * An easy way to move all child nodes of an existing element to a new parent\n * element is:\n * <code>createDom(goog.dom.TagName.DIV, null, oldElement.childNodes);</code>\n * which will remove all child nodes from the old element and add them as\n * child nodes of the new DIV.\n *\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n *     of name-value pairs for attributes. If a string, then this is the\n *     className of the new element. If an array, the elements will be joined\n *     together as the className of the new element.\n * @param {...(goog.dom.Appendable|undefined)} var_args Further DOM nodes or\n *     strings for text nodes. If one of the var_args is an array or\n *     NodeList, its elements will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n *     is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.createDom = function(\n    tagName, opt_attributes, var_args) {\n  return goog.dom.createDom_(this.document_, arguments);\n};\n\n\n/**\n * Alias for `createDom`.\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n *     of name-value pairs for attributes. If a string, then this is the\n *     className of the new element. If an array, the elements will be joined\n *     together as the className of the new element.\n * @param {...(goog.dom.Appendable|undefined)} var_args Further DOM nodes or\n *     strings for text nodes.  If one of the var_args is an array, its children\n *     will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n *     is a string or a more specific type if it is a member of\n *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.DomHelper.prototype.createDom} instead.\n */\ngoog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;\n\n\n/**\n * Creates a new element.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n *     a string or a more specific type if it is a member of goog.dom.TagName\n *     (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.createElement = function(name) {\n  return goog.dom.createElement_(this.document_, name);\n};\n\n\n/**\n * Creates a new text node.\n * @param {number|string} content Content.\n * @return {!Text} The new text node.\n */\ngoog.dom.DomHelper.prototype.createTextNode = function(content) {\n  return this.document_.createTextNode(String(content));\n};\n\n\n/**\n * Create a table.\n * @param {number} rows The number of rows in the table.  Must be >= 1.\n * @param {number} columns The number of columns in the table.  Must be >= 1.\n * @param {boolean=} opt_fillWithNbsp If true, fills table entries with\n *     `goog.string.Unicode.NBSP` characters.\n * @return {!HTMLElement} The created table.\n */\ngoog.dom.DomHelper.prototype.createTable = function(\n    rows, columns, opt_fillWithNbsp) {\n  return goog.dom.createTable_(\n      this.document_, rows, columns, !!opt_fillWithNbsp);\n};\n\n\n/**\n * Converts an HTML into a node or a document fragment. A single Node is used if\n * `html` only generates a single node. If `html` generates multiple\n * nodes then these are put inside a `DocumentFragment`. This is a safe\n * version of `goog.dom.DomHelper#htmlToDocumentFragment` which is now\n * deleted.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n */\ngoog.dom.DomHelper.prototype.safeHtmlToNode = function(html) {\n  return goog.dom.safeHtmlToNode_(this.document_, html);\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @return {boolean} True if in CSS1-compatible mode.\n */\ngoog.dom.DomHelper.prototype.isCss1CompatMode = function() {\n  return goog.dom.isCss1CompatMode_(this.document_);\n};\n\n\n/**\n * Gets the window object associated with the document.\n * @return {!Window} The window associated with the given document.\n */\ngoog.dom.DomHelper.prototype.getWindow = function() {\n  return goog.dom.getWindow_(this.document_);\n};\n\n\n/**\n * Gets the document scroll element.\n * @return {!Element} Scrolling element.\n */\ngoog.dom.DomHelper.prototype.getDocumentScrollElement = function() {\n  return goog.dom.getDocumentScrollElement_(this.document_);\n};\n\n\n/**\n * Gets the document scroll distance as a coordinate object.\n * @return {!goog.math.Coordinate} Object with properties 'x' and 'y'.\n */\ngoog.dom.DomHelper.prototype.getDocumentScroll = function() {\n  return goog.dom.getDocumentScroll_(this.document_);\n};\n\n\n/**\n * Determines the active element in the given document.\n * @param {Document=} opt_doc The document to look in.\n * @return {Element} The active element.\n */\ngoog.dom.DomHelper.prototype.getActiveElement = function(opt_doc) {\n  return goog.dom.getActiveElement(opt_doc || this.document_);\n};\n\n\n/**\n * Appends a child to a node.\n * @param {Node} parent Parent.\n * @param {Node} child Child.\n */\ngoog.dom.DomHelper.prototype.appendChild = goog.dom.appendChild;\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Node} parent The node to append nodes to.\n * @param {...goog.dom.Appendable} var_args The things to append to the node.\n *     If this is a Node it is appended as is.\n *     If this is a string then a text node is appended.\n *     If this is an array like object then fields 0 to length - 1 are appended.\n */\ngoog.dom.DomHelper.prototype.append = goog.dom.append;\n\n\n/**\n * Determines if the given node can contain children, intended to be used for\n * HTML generation.\n *\n * @param {Node} node The node to check.\n * @return {boolean} Whether the node can contain children.\n */\ngoog.dom.DomHelper.prototype.canHaveChildren = goog.dom.canHaveChildren;\n\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Node} node Node to remove children from.\n */\ngoog.dom.DomHelper.prototype.removeChildren = goog.dom.removeChildren;\n\n\n/**\n * Inserts a new node before an existing reference node (i.e., as the previous\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert before.\n */\ngoog.dom.DomHelper.prototype.insertSiblingBefore = goog.dom.insertSiblingBefore;\n\n\n/**\n * Inserts a new node after an existing reference node (i.e., as the next\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert after.\n */\ngoog.dom.DomHelper.prototype.insertSiblingAfter = goog.dom.insertSiblingAfter;\n\n\n/**\n * Insert a child at a given index. If index is larger than the number of child\n * nodes that the parent currently has, the node is inserted as the last child\n * node.\n * @param {Element} parent The element into which to insert the child.\n * @param {Node} child The element to insert.\n * @param {number} index The index at which to insert the new child node. Must\n *     not be negative.\n */\ngoog.dom.DomHelper.prototype.insertChildAt = goog.dom.insertChildAt;\n\n\n/**\n * Removes a node from its parent.\n * @param {Node} node The node to remove.\n * @return {Node} The node removed if removed; else, null.\n */\ngoog.dom.DomHelper.prototype.removeNode = goog.dom.removeNode;\n\n\n/**\n * Replaces a node in the DOM tree. Will do nothing if `oldNode` has no\n * parent.\n * @param {Node} newNode Node to insert.\n * @param {Node} oldNode Node to replace.\n */\ngoog.dom.DomHelper.prototype.replaceNode = goog.dom.replaceNode;\n\n\n/**\n * Flattens an element. That is, removes it and replace it with its children.\n * @param {Element} element The element to flatten.\n * @return {Element|undefined} The original element, detached from the document\n *     tree, sans children, or undefined if the element was already not in the\n *     document.\n */\ngoog.dom.DomHelper.prototype.flattenElement = goog.dom.flattenElement;\n\n\n/**\n * Returns an array containing just the element children of the given element.\n * @param {Element} element The element whose element children we want.\n * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list\n *     of just the element children of the given element.\n */\ngoog.dom.DomHelper.prototype.getChildren = goog.dom.getChildren;\n\n\n/**\n * Returns the first child node that is an element.\n * @param {Node} node The node to get the first child element of.\n * @return {Element} The first child node of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getFirstElementChild =\n    goog.dom.getFirstElementChild;\n\n\n/**\n * Returns the last child node that is an element.\n * @param {Node} node The node to get the last child element of.\n * @return {Element} The last child node of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getLastElementChild = goog.dom.getLastElementChild;\n\n\n/**\n * Returns the first next sibling that is an element.\n * @param {Node} node The node to get the next sibling element of.\n * @return {Element} The next sibling of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getNextElementSibling =\n    goog.dom.getNextElementSibling;\n\n\n/**\n * Returns the first previous sibling that is an element.\n * @param {Node} node The node to get the previous sibling element of.\n * @return {Element} The first previous sibling of `node` that is\n *     an element.\n */\ngoog.dom.DomHelper.prototype.getPreviousElementSibling =\n    goog.dom.getPreviousElementSibling;\n\n\n/**\n * Returns the next node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The next node in the DOM tree, or null if this was the last\n *     node.\n */\ngoog.dom.DomHelper.prototype.getNextNode = goog.dom.getNextNode;\n\n\n/**\n * Returns the previous node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The previous node in the DOM tree, or null if this was the\n *     first node.\n */\ngoog.dom.DomHelper.prototype.getPreviousNode = goog.dom.getPreviousNode;\n\n\n/**\n * Whether the object looks like a DOM node.\n * @param {?} obj The object being tested for node likeness.\n * @return {boolean} Whether the object looks like a DOM node.\n */\ngoog.dom.DomHelper.prototype.isNodeLike = goog.dom.isNodeLike;\n\n\n/**\n * Whether the object looks like an Element.\n * @param {?} obj The object being tested for Element likeness.\n * @return {boolean} Whether the object looks like an Element.\n */\ngoog.dom.DomHelper.prototype.isElement = goog.dom.isElement;\n\n\n/**\n * Returns true if the specified value is a Window object. This includes the\n * global window for HTML pages, and iframe windows.\n * @param {?} obj Variable to test.\n * @return {boolean} Whether the variable is a window.\n */\ngoog.dom.DomHelper.prototype.isWindow = goog.dom.isWindow;\n\n\n/**\n * Returns an element's parent, if it's an Element.\n * @param {Element} element The DOM element.\n * @return {Element} The parent, or null if not an Element.\n */\ngoog.dom.DomHelper.prototype.getParentElement = goog.dom.getParentElement;\n\n\n/**\n * Whether a node contains another node.\n * @param {Node} parent The node that should contain the other node.\n * @param {Node} descendant The node to test presence of.\n * @return {boolean} Whether the parent node contains the descendant node.\n */\ngoog.dom.DomHelper.prototype.contains = goog.dom.contains;\n\n\n/**\n * Compares the document order of two nodes, returning 0 if they are the same\n * node, a negative number if node1 is before node2, and a positive number if\n * node2 is before node1.  Note that we compare the order the tags appear in the\n * document so in the tree <b><i>text</i></b> the B node is considered to be\n * before the I node.\n *\n * @param {Node} node1 The first node to compare.\n * @param {Node} node2 The second node to compare.\n * @return {number} 0 if the nodes are the same node, a negative number if node1\n *     is before node2, and a positive number if node2 is before node1.\n */\ngoog.dom.DomHelper.prototype.compareNodeOrder = goog.dom.compareNodeOrder;\n\n\n/**\n * Find the deepest common ancestor of the given nodes.\n * @param {...Node} var_args The nodes to find a common ancestor of.\n * @return {Node} The common ancestor of the nodes, or null if there is none.\n *     null will only be returned if two or more of the nodes are from different\n *     documents.\n */\ngoog.dom.DomHelper.prototype.findCommonAncestor = goog.dom.findCommonAncestor;\n\n\n/**\n * Returns the owner document for a node.\n * @param {Node} node The node to get the document for.\n * @return {!Document} The document owning the node.\n */\ngoog.dom.DomHelper.prototype.getOwnerDocument = goog.dom.getOwnerDocument;\n\n\n/**\n * Cross browser function for getting the document element of an iframe.\n * @param {Element} iframe Iframe element.\n * @return {!Document} The frame content document.\n */\ngoog.dom.DomHelper.prototype.getFrameContentDocument =\n    goog.dom.getFrameContentDocument;\n\n\n/**\n * Cross browser function for getting the window of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {Window} The window associated with the given frame.\n */\ngoog.dom.DomHelper.prototype.getFrameContentWindow =\n    goog.dom.getFrameContentWindow;\n\n\n/**\n * Sets the text content of a node, with cross-browser support.\n * @param {Node} node The node to change the text content of.\n * @param {string|number} text The value that should replace the node's content.\n */\ngoog.dom.DomHelper.prototype.setTextContent = goog.dom.setTextContent;\n\n\n/**\n * Gets the outerHTML of a node, which islike innerHTML, except that it\n * actually contains the HTML of the node itself.\n * @param {Element} element The element to get the HTML of.\n * @return {string} The outerHTML of the given element.\n */\ngoog.dom.DomHelper.prototype.getOuterHtml = goog.dom.getOuterHtml;\n\n\n/**\n * Finds the first descendant node that matches the filter function. This does\n * a depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Node|undefined} The found node or undefined if none is found.\n */\ngoog.dom.DomHelper.prototype.findNode = goog.dom.findNode;\n\n\n/**\n * Finds all the descendant nodes that matches the filter function. This does a\n * depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Array<Node>} The found nodes or an empty array if none are found.\n */\ngoog.dom.DomHelper.prototype.findNodes = goog.dom.findNodes;\n\n\n/**\n * Returns true if the element has a tab index that allows it to receive\n * keyboard focus (tabIndex >= 0), false otherwise.  Note that some elements\n * natively support keyboard focus, even if they have no tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a tab index that allows keyboard\n *     focus.\n */\ngoog.dom.DomHelper.prototype.isFocusableTabIndex = goog.dom.isFocusableTabIndex;\n\n\n/**\n * Enables or disables keyboard focus support on the element via its tab index.\n * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true\n * (or elements that natively support keyboard focus, like form elements) can\n * receive keyboard focus.  See http://go/tabindex for more info.\n * @param {Element} element Element whose tab index is to be changed.\n * @param {boolean} enable Whether to set or remove a tab index on the element\n *     that supports keyboard focus.\n */\ngoog.dom.DomHelper.prototype.setFocusableTabIndex =\n    goog.dom.setFocusableTabIndex;\n\n\n/**\n * Returns true if the element can be focused, i.e. it has a tab index that\n * allows it to receive keyboard focus (tabIndex >= 0), or it is an element\n * that natively supports keyboard focus.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element allows keyboard focus.\n */\ngoog.dom.DomHelper.prototype.isFocusable = goog.dom.isFocusable;\n\n\n/**\n * Returns the text contents of the current node, without markup. New lines are\n * stripped and whitespace is collapsed, such that each character would be\n * visible.\n *\n * In browsers that support it, innerText is used.  Other browsers attempt to\n * simulate it via node traversal.  Line breaks are canonicalized in IE.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The text content.\n */\ngoog.dom.DomHelper.prototype.getTextContent = goog.dom.getTextContent;\n\n\n/**\n * Returns the text length of the text contained in a node, without markup. This\n * is equivalent to the selection length if the node was selected, or the number\n * of cursor movements to traverse the node. Images & BRs take one space.  New\n * lines are ignored.\n *\n * @param {Node} node The node whose text content length is being calculated.\n * @return {number} The length of `node`'s text content.\n */\ngoog.dom.DomHelper.prototype.getNodeTextLength = goog.dom.getNodeTextLength;\n\n\n/**\n * Returns the text offset of a node relative to one of its ancestors. The text\n * length is the same as the length calculated by\n * `goog.dom.getNodeTextLength`.\n *\n * @param {Node} node The node whose offset is being calculated.\n * @param {Node=} opt_offsetParent Defaults to the node's owner document's body.\n * @return {number} The text offset.\n */\ngoog.dom.DomHelper.prototype.getNodeTextOffset = goog.dom.getNodeTextOffset;\n\n\n/**\n * Returns the node at a given offset in a parent node.  If an object is\n * provided for the optional third parameter, the node and the remainder of the\n * offset will stored as properties of this object.\n * @param {Node} parent The parent node.\n * @param {number} offset The offset into the parent node.\n * @param {Object=} opt_result Object to be used to store the return value. The\n *     return value will be stored in the form {node: Node, remainder: number}\n *     if this object is provided.\n * @return {Node} The node at the given offset.\n */\ngoog.dom.DomHelper.prototype.getNodeAtOffset = goog.dom.getNodeAtOffset;\n\n\n/**\n * Returns true if the object is a `NodeList`.  To qualify as a NodeList,\n * the object must have a numeric length property and an item function (which\n * has type 'string' on IE for some reason).\n * @param {Object} val Object to test.\n * @return {boolean} Whether the object is a NodeList.\n */\ngoog.dom.DomHelper.prototype.isNodeList = goog.dom.isNodeList;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * tag name and/or class name. If the passed element matches the specified\n * criteria, the element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {?(goog.dom.TagName<T>|string)=} opt_tag The tag name to match (or\n *     null/undefined to match only based on class name).\n * @param {?string=} opt_class The class name to match (or null/undefined to\n *     match only based on tag name).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {?R} The first ancestor that matches the passed criteria, or\n *     null if no match is found. The return type is {?Element} if opt_tag is\n *     not a member of goog.dom.TagName or a more specific type if it is (e.g.\n *     {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getAncestorByTagNameAndClass =\n    goog.dom.getAncestorByTagNameAndClass;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * class name. If the passed element matches the specified criteria, the\n * element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {string} class The class name to match.\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {Element} The first ancestor that matches the passed criteria, or\n *     null if none match.\n */\ngoog.dom.DomHelper.prototype.getAncestorByClass = goog.dom.getAncestorByClass;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that passes the\n * matcher function.\n * @param {Node} element The DOM node to start with.\n * @param {function(Node) : boolean} matcher A function that returns true if the\n *     passed node matches the desired criteria.\n * @param {boolean=} opt_includeNode If true, the node itself is included in\n *     the search (the first call to the matcher will pass startElement as\n *     the node to test).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n *     dom.\n * @return {Node} DOM node that matched the matcher, or null if there was\n *     no match.\n */\ngoog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor;\n\n\n/**\n * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a\n * type information.\n * @param {!HTMLCanvasElement} canvas\n * @return {!CanvasRenderingContext2D}\n */\ngoog.dom.DomHelper.prototype.getCanvasContext2D = goog.dom.getCanvasContext2D;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a function to schedule running a function as soon\n * as possible after the current JS execution stops and yields to the event\n * loop.\n */\n\ngoog.provide('goog.async.nextTick');\ngoog.provide('goog.async.throwException');\n\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.functions');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.string.Const');\n\n\n/**\n * Throw an item without interrupting the current execution context.  For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\ngoog.async.throwException = function(exception) {\n  // Each throw needs to be in its own context.\n  goog.global.setTimeout(function() { throw exception; }, 0);\n};\n\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) takes at least 4ms when called from\n * within another setTimeout(…, 0) for legacy reasons.\n *\n * This will not schedule the callback as a microtask (i.e. a task that can\n * preempt user input or networking callbacks). It is meant to emulate what\n * setTimeout(_, 0) would do if it were not throttled. If you desire microtask\n * behavior, use {@see goog.Promise} instead.\n *\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n *     possible.\n * @param {SCOPE=} opt_context Object in whose scope to call the listener.\n * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that\n *     ensures correctness at the cost of speed. See comments for details.\n * @template SCOPE\n */\ngoog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {\n  var cb = callback;\n  if (opt_context) {\n    cb = goog.bind(callback, opt_context);\n  }\n  cb = goog.async.nextTick.wrapCallback_(cb);\n  // Note we do allow callers to also request setImmediate if they are willing\n  // to accept the possible tradeoffs of incorrectness in exchange for speed.\n  // The IE fallback of readystate change is much slower. See useSetImmediate_\n  // for details.\n  if (goog.isFunction(goog.global.setImmediate) &&\n      (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {\n    goog.global.setImmediate(cb);\n    return;\n  }\n\n  // Look for and cache the custom fallback version of setImmediate.\n  if (!goog.async.nextTick.setImmediate_) {\n    goog.async.nextTick.setImmediate_ =\n        goog.async.nextTick.getSetImmediateEmulator_();\n  }\n  goog.async.nextTick.setImmediate_(cb);\n};\n\n\n/**\n * Returns whether should use setImmediate implementation currently on window.\n *\n * window.setImmediate was introduced and currently only supported by IE10+,\n * but due to a bug in the implementation it is not guaranteed that\n * setImmediate is faster than setTimeout nor that setImmediate N is before\n * setImmediate N+1. That is why we do not use the native version if\n * available. We do, however, call setImmediate if it is a non-native function\n * because that indicates that it has been replaced by goog.testing.MockClock\n * which we do want to support.\n * See\n * http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10\n *\n * @return {boolean} Whether to use the implementation of setImmediate defined\n *     on Window.\n * @private\n * @suppress {missingProperties} For \"Window.prototype.setImmediate\"\n */\ngoog.async.nextTick.useSetImmediate_ = function() {\n  // Not a browser environment.\n  if (!goog.global.Window || !goog.global.Window.prototype) {\n    return true;\n  }\n\n  // MS Edge has window.setImmediate natively, but it's not on Window.prototype.\n  // Also, there's no clean way to detect if the goog.global.setImmediate has\n  // been replaced by mockClock as its replacement also shows up as \"[native\n  // code]\" when using toString. Therefore, just always use\n  // goog.global.setImmediate for Edge. It's unclear if it suffers the same\n  // issues as IE10/11, but based on\n  // https://dev.modern.ie/testdrive/demos/setimmediatesorting/\n  // it seems they've been working to ensure it's WAI.\n  if (goog.labs.userAgent.browser.isEdge() ||\n      goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {\n    // Something redefined setImmediate in which case we decide to use it (This\n    // is so that we use the mockClock setImmediate).\n    return true;\n  }\n\n  return false;\n};\n\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\ngoog.async.nextTick.setImmediate_;\n\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\ngoog.async.nextTick.getSetImmediateEmulator_ = function() {\n  // Create a private message channel and use it to postMessage empty messages\n  // to ourselves.\n  /** @type {!Function|undefined} */\n  var Channel = goog.global['MessageChannel'];\n  // If MessageChannel is not available and we are in a browser, implement\n  // an iframe based polyfill in browsers that have postMessage and\n  // document.addEventListener. The latter excludes IE8 because it has a\n  // synchronous postMessage implementation.\n  if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&\n      window.postMessage && window.addEventListener &&\n      // Presto (The old pre-blink Opera engine) has problems with iframes\n      // and contentWindow.\n      !goog.labs.userAgent.engine.isPresto()) {\n    /** @constructor */\n    Channel = function() {\n      // Make an empty, invisible iframe.\n      var iframe = goog.dom.createElement(goog.dom.TagName.IFRAME);\n      iframe.style.display = 'none';\n      goog.dom.safe.setIframeSrc(\n          iframe,\n          goog.html.TrustedResourceUrl.fromConstant(goog.string.Const.EMPTY));\n      document.documentElement.appendChild(iframe);\n      var win = iframe.contentWindow;\n      var doc = win.document;\n      doc.open();\n      goog.dom.safe.documentWrite(doc, goog.html.SafeHtml.EMPTY);\n      doc.close();\n      // Do not post anything sensitive over this channel, as the workaround for\n      // pages with file: origin could allow that information to be modified or\n      // intercepted.\n      var message = 'callImmediate' + Math.random();\n      // The same origin policy rejects attempts to postMessage from file: urls\n      // unless the origin is '*'.\n      var origin = win.location.protocol == 'file:' ?\n          '*' :\n          win.location.protocol + '//' + win.location.host;\n      var onmessage = goog.bind(function(e) {\n        // Validate origin and message to make sure that this message was\n        // intended for us. If the origin is set to '*' (see above) only the\n        // message needs to match since, for example, '*' != 'file://'. Allowing\n        // the wildcard is ok, as we are not concerned with security here.\n        if ((origin != '*' && e.origin != origin) || e.data != message) {\n          return;\n        }\n        this['port1'].onmessage();\n      }, this);\n      win.addEventListener('message', onmessage, false);\n      this['port1'] = {};\n      this['port2'] = {\n        postMessage: function() { win.postMessage(message, origin); }\n      };\n    };\n  }\n  if (typeof Channel !== 'undefined' && !goog.labs.userAgent.browser.isIE()) {\n    // Exclude all of IE due to\n    // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/\n    // which allows starving postMessage with a busy setTimeout loop.\n    // This currently affects IE10 and IE11 which would otherwise be able\n    // to use the postMessage based fallbacks.\n    var channel = new Channel();\n    // Use a fifo linked list to call callbacks in the right order.\n    var head = {};\n    var tail = head;\n    channel['port1'].onmessage = function() {\n      if (head.next !== undefined) {\n        head = head.next;\n        var cb = head.cb;\n        head.cb = null;\n        cb();\n      }\n    };\n    return function(cb) {\n      tail.next = {cb: cb};\n      tail = tail.next;\n      channel['port2'].postMessage(0);\n    };\n  }\n  // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n  // or more.\n  // NOTE(user): This fallback is used for IE.\n  return function(cb) {\n    goog.global.setTimeout(/** @type {function()} */ (cb), 0);\n  };\n};\n\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\ngoog.async.nextTick.wrapCallback_ = goog.functions.identity;\n\n\n// Register the callback function as an entry point, so that it can be\n// monitored for exception handling, etc. This has to be done in this file\n// since it requires special code to handle all browsers.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) { goog.async.nextTick.wrapCallback_ = transformer; });\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.Promise');\n\ngoog.require('goog.Thenable');\ngoog.require('goog.asserts');\ngoog.require('goog.async.FreeList');\ngoog.require('goog.async.run');\ngoog.require('goog.async.throwException');\ngoog.require('goog.debug.Error');\ngoog.require('goog.promise.Resolver');\n\n\n\n/**\n * NOTE: This class was created in anticipation of the built-in Promise type\n * being standardized and implemented across browsers. Now that Promise is\n * available in modern browsers, and is automatically polyfilled by the Closure\n * Compiler, by default, most new code should use native `Promise`\n * instead of `goog.Promise`. However, `goog.Promise` has the\n * concept of cancellation which native Promises do not yet have. So code\n * needing cancellation may still want to use `goog.Promise`.\n *\n * Promises provide a result that may be resolved asynchronously. A Promise may\n * be resolved by being fulfilled with a fulfillment value, rejected with a\n * rejection reason, or blocked by another Promise. A Promise is said to be\n * settled if it is either fulfilled or rejected. Once settled, the Promise\n * result is immutable.\n *\n * Promises may represent results of any type, including undefined. Rejection\n * reasons are typically Errors, but may also be of any type. Closure Promises\n * allow for optional type annotations that enforce that fulfillment values are\n * of the appropriate types at compile time.\n *\n * The result of a Promise is accessible by calling `then` and registering\n * `onFulfilled` and `onRejected` callbacks. Once the Promise\n * is settled, the relevant callbacks are invoked with the fulfillment value or\n * rejection reason as argument. Callbacks are always invoked in the order they\n * were registered, even when additional `then` calls are made from inside\n * another callback. A callback is always run asynchronously sometime after the\n * scope containing the registering `then` invocation has returned.\n *\n * If a Promise is resolved with another Promise, the first Promise will block\n * until the second is settled, and then assumes the same result as the second\n * Promise. This allows Promises to depend on the results of other Promises,\n * linking together multiple asynchronous operations.\n *\n * This implementation is compatible with the Promises/A+ specification and\n * passes that specification's conformance test suite. A Closure Promise may be\n * resolved with a Promise instance (or sufficiently compatible Promise-like\n * object) created by other Promise implementations. From the specification,\n * Promise-like objects are known as \"Thenables\".\n *\n * @see http://promisesaplus.com/\n *\n * @param {function(\n *             this:RESOLVER_CONTEXT,\n *             function((TYPE|IThenable<TYPE>|Thenable)=),\n *             function(*=)): void} resolver\n *     Initialization function that is invoked immediately with `resolve`\n *     and `reject` functions as arguments. The Promise is resolved or\n *     rejected with the first argument passed to either function.\n * @param {RESOLVER_CONTEXT=} opt_context An optional context for executing the\n *     resolver function. If unspecified, the resolver function will be executed\n *     in the default scope.\n * @constructor\n * @struct\n * @final\n * @implements {goog.Thenable<TYPE>}\n * @template TYPE,RESOLVER_CONTEXT\n */\ngoog.Promise = function(resolver, opt_context) {\n  /**\n   * The internal state of this Promise. Either PENDING, FULFILLED, REJECTED, or\n   * BLOCKED.\n   * @private {goog.Promise.State_}\n   */\n  this.state_ = goog.Promise.State_.PENDING;\n\n  /**\n   * The settled result of the Promise. Immutable once set with either a\n   * fulfillment value or rejection reason.\n   * @private {*}\n   */\n  this.result_ = undefined;\n\n  /**\n   * For Promises created by calling `then()`, the originating parent.\n   * @private {?goog.Promise}\n   */\n  this.parent_ = null;\n\n  /**\n   * The linked list of `onFulfilled` and `onRejected` callbacks\n   * added to this Promise by calls to `then()`.\n   * @private {?goog.Promise.CallbackEntry_}\n   */\n  this.callbackEntries_ = null;\n\n  /**\n   * The tail of the linked list of `onFulfilled` and `onRejected`\n   * callbacks added to this Promise by calls to `then()`.\n   * @private {?goog.Promise.CallbackEntry_}\n   */\n  this.callbackEntriesTail_ = null;\n\n  /**\n   * Whether the Promise is in the queue of Promises to execute.\n   * @private {boolean}\n   */\n  this.executing_ = false;\n\n  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n    /**\n     * A timeout ID used when the `UNHANDLED_REJECTION_DELAY` is greater\n     * than 0 milliseconds. The ID is set when the Promise is rejected, and\n     * cleared only if an `onRejected` callback is invoked for the\n     * Promise (or one of its descendants) before the delay is exceeded.\n     *\n     * If the rejection is not handled before the timeout completes, the\n     * rejection reason is passed to the unhandled rejection handler.\n     * @private {number}\n     */\n    this.unhandledRejectionId_ = 0;\n  } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n    /**\n     * When the `UNHANDLED_REJECTION_DELAY` is set to 0 milliseconds, a\n     * boolean that is set if the Promise is rejected, and reset to false if an\n     * `onRejected` callback is invoked for the Promise (or one of its\n     * descendants). If the rejection is not handled before the next timestep,\n     * the rejection reason is passed to the unhandled rejection handler.\n     * @private {boolean}\n     */\n    this.hadUnhandledRejection_ = false;\n  }\n\n  if (goog.Promise.LONG_STACK_TRACES) {\n    /**\n     * A list of stack trace frames pointing to the locations where this Promise\n     * was created or had callbacks added to it. Saved to add additional context\n     * to stack traces when an exception is thrown.\n     * @private {!Array<string>}\n     */\n    this.stack_ = [];\n    this.addStackTrace_(new Error('created'));\n\n    /**\n     * Index of the most recently executed stack frame entry.\n     * @private {number}\n     */\n    this.currentStep_ = 0;\n  }\n\n  // As an optimization, we can skip this if resolver is goog.nullFunction.\n  // This value is passed internally when creating a promise which will be\n  // resolved through a more optimized path.\n  if (resolver != goog.nullFunction) {\n    try {\n      var self = this;\n      resolver.call(\n          opt_context,\n          function(value) {\n            self.resolve_(goog.Promise.State_.FULFILLED, value);\n          },\n          function(reason) {\n            if (goog.DEBUG &&\n                !(reason instanceof goog.Promise.CancellationError)) {\n              try {\n                // Promise was rejected. Step up one call frame to see why.\n                if (reason instanceof Error) {\n                  throw reason;\n                } else {\n                  throw new Error('Promise rejected.');\n                }\n              } catch (e) {\n                // Only thrown so browser dev tools can catch rejections of\n                // promises when the option to break on caught exceptions is\n                // activated.\n              }\n            }\n            self.resolve_(goog.Promise.State_.REJECTED, reason);\n          });\n    } catch (e) {\n      this.resolve_(goog.Promise.State_.REJECTED, e);\n    }\n  }\n};\n\n\n/**\n * @define {boolean} Whether traces of `then` calls should be included in\n * exceptions thrown\n */\ngoog.Promise.LONG_STACK_TRACES =\n    goog.define('goog.Promise.LONG_STACK_TRACES', false);\n\n\n/**\n * @define {number} The delay in milliseconds before a rejected Promise's reason\n * is passed to the rejection handler. By default, the rejection handler\n * rethrows the rejection reason so that it appears in the developer console or\n * `window.onerror` handler.\n *\n * Rejections are rethrown as quickly as possible by default. A negative value\n * disables rejection handling entirely.\n */\ngoog.Promise.UNHANDLED_REJECTION_DELAY =\n    goog.define('goog.Promise.UNHANDLED_REJECTION_DELAY', 0);\n\n\n/**\n * The possible internal states for a Promise. These states are not directly\n * observable to external callers.\n * @enum {number}\n * @private\n */\ngoog.Promise.State_ = {\n  /** The Promise is waiting for resolution. */\n  PENDING: 0,\n\n  /** The Promise is blocked waiting for the result of another Thenable. */\n  BLOCKED: 1,\n\n  /** The Promise has been resolved with a fulfillment value. */\n  FULFILLED: 2,\n\n  /** The Promise has been resolved with a rejection reason. */\n  REJECTED: 3\n};\n\n\n\n/**\n * Entries in the callback chain. Each call to `then`,\n * `thenCatch`, or `thenAlways` creates an entry containing the\n * functions that may be invoked once the Promise is settled.\n *\n * @private @final @struct @constructor\n */\ngoog.Promise.CallbackEntry_ = function() {\n  /** @type {?goog.Promise} */\n  this.child = null;\n  /** @type {?Function} */\n  this.onFulfilled = null;\n  /** @type {?Function} */\n  this.onRejected = null;\n  /** @type {?} */\n  this.context = null;\n  /** @type {?goog.Promise.CallbackEntry_} */\n  this.next = null;\n\n  /**\n   * A boolean value to indicate this is a \"thenAlways\" callback entry.\n   * Unlike a normal \"then/thenVoid\" a \"thenAlways doesn't participate\n   * in \"cancel\" considerations but is simply an observer and requires\n   * special handling.\n   * @type {boolean}\n   */\n  this.always = false;\n};\n\n\n/** clear the object prior to reuse */\ngoog.Promise.CallbackEntry_.prototype.reset = function() {\n  this.child = null;\n  this.onFulfilled = null;\n  this.onRejected = null;\n  this.context = null;\n  this.always = false;\n};\n\n\n/**\n * @define {number} The number of currently unused objects to keep around for\n *    reuse.\n */\ngoog.Promise.DEFAULT_MAX_UNUSED =\n    goog.define('goog.Promise.DEFAULT_MAX_UNUSED', 100);\n\n\n/** @const @private {goog.async.FreeList<!goog.Promise.CallbackEntry_>} */\ngoog.Promise.freelist_ = new goog.async.FreeList(\n    function() { return new goog.Promise.CallbackEntry_(); },\n    function(item) { item.reset(); }, goog.Promise.DEFAULT_MAX_UNUSED);\n\n\n/**\n * @param {Function} onFulfilled\n * @param {Function} onRejected\n * @param {?} context\n * @return {!goog.Promise.CallbackEntry_}\n * @private\n */\ngoog.Promise.getCallbackEntry_ = function(onFulfilled, onRejected, context) {\n  var entry = goog.Promise.freelist_.get();\n  entry.onFulfilled = onFulfilled;\n  entry.onRejected = onRejected;\n  entry.context = context;\n  return entry;\n};\n\n\n/**\n * @param {!goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.returnEntry_ = function(entry) {\n  goog.Promise.freelist_.put(entry);\n};\n\n\n// NOTE: this is the same template expression as is used for\n// goog.IThenable.prototype.then\n\n\n/**\n * @param {VALUE=} opt_value\n * @return {RESULT} A new Promise that is immediately resolved\n *     with the given value. If the input value is already a goog.Promise, it\n *     will be returned immediately without creating a new instance.\n * @template VALUE\n * @template RESULT := type('goog.Promise',\n *     cond(isUnknown(VALUE), unknown(),\n *       mapunion(VALUE, (V) =>\n *         cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'),\n *           templateTypeOf(V, 0),\n *           cond(sub(V, 'Thenable'),\n *              unknown(),\n *              V)))))\n * =:\n */\ngoog.Promise.resolve = function(opt_value) {\n  if (opt_value instanceof goog.Promise) {\n    // Avoid creating a new object if we already have a promise object\n    // of the correct type.\n    return opt_value;\n  }\n\n  // Passing goog.nullFunction will cause the constructor to take an optimized\n  // path that skips calling the resolver function.\n  var promise = new goog.Promise(goog.nullFunction);\n  promise.resolve_(goog.Promise.State_.FULFILLED, opt_value);\n  return promise;\n};\n\n\n/**\n * @param {*=} opt_reason\n * @return {!goog.Promise} A new Promise that is immediately rejected with the\n *     given reason.\n */\ngoog.Promise.reject = function(opt_reason) {\n  return new goog.Promise(function(resolve, reject) { reject(opt_reason); });\n};\n\n\n/**\n * This is identical to\n * {@code goog.Promise.resolve(value).then(onFulfilled, onRejected)}, but it\n * avoids creating an unnecessary wrapper Promise when `value` is already\n * thenable.\n *\n * @param {?(goog.Thenable<TYPE>|Thenable|TYPE)} value\n * @param {function(TYPE): ?} onFulfilled\n * @param {function(*): *} onRejected\n * @template TYPE\n * @private\n */\ngoog.Promise.resolveThen_ = function(value, onFulfilled, onRejected) {\n  var isThenable =\n      goog.Promise.maybeThen_(value, onFulfilled, onRejected, null);\n  if (!isThenable) {\n    goog.async.run(goog.partial(onFulfilled, value));\n  }\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n *     promises\n * @return {!goog.Promise<TYPE>} A Promise that receives the result of the\n *     first Promise (or Promise-like) input to settle immediately after it\n *     settles.\n * @template TYPE\n */\ngoog.Promise.race = function(promises) {\n  return new goog.Promise(function(resolve, reject) {\n    if (!promises.length) {\n      resolve(undefined);\n    }\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n      goog.Promise.resolveThen_(promise, resolve, reject);\n    }\n  });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n *     promises\n * @return {!goog.Promise<!Array<TYPE>>} A Promise that receives a list of\n *     every fulfilled value once every input Promise (or Promise-like) is\n *     successfully fulfilled, or is rejected with the first rejection reason\n *     immediately after it is rejected.\n * @template TYPE\n */\ngoog.Promise.all = function(promises) {\n  return new goog.Promise(function(resolve, reject) {\n    var toFulfill = promises.length;\n    var values = [];\n\n    if (!toFulfill) {\n      resolve(values);\n      return;\n    }\n\n    var onFulfill = function(index, value) {\n      toFulfill--;\n      values[index] = value;\n      if (toFulfill == 0) {\n        resolve(values);\n      }\n    };\n\n    var onReject = function(reason) { reject(reason); };\n\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n      goog.Promise.resolveThen_(promise, goog.partial(onFulfill, i), onReject);\n    }\n  });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n *     promises\n * @return {!goog.Promise<!Array<{\n *     fulfilled: boolean,\n *     value: (TYPE|undefined),\n *     reason: (*|undefined)}>>} A Promise that resolves with a list of\n *         result objects once all input Promises (or Promise-like) have\n *         settled. Each result object contains a 'fulfilled' boolean indicating\n *         whether an input Promise was fulfilled or rejected. For fulfilled\n *         Promises, the resulting value is stored in the 'value' field. For\n *         rejected Promises, the rejection reason is stored in the 'reason'\n *         field.\n * @template TYPE\n */\ngoog.Promise.allSettled = function(promises) {\n  return new goog.Promise(function(resolve, reject) {\n    var toSettle = promises.length;\n    var results = [];\n\n    if (!toSettle) {\n      resolve(results);\n      return;\n    }\n\n    var onSettled = function(index, fulfilled, result) {\n      toSettle--;\n      results[index] = fulfilled ? {fulfilled: true, value: result} :\n                                   {fulfilled: false, reason: result};\n      if (toSettle == 0) {\n        resolve(results);\n      }\n    };\n\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n      goog.Promise.resolveThen_(\n          promise, goog.partial(onSettled, i, true /* fulfilled */),\n          goog.partial(onSettled, i, false /* fulfilled */));\n    }\n  });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n *     promises\n * @return {!goog.Promise<TYPE>} A Promise that receives the value of the first\n *     input to be fulfilled, or is rejected with a list of every rejection\n *     reason if all inputs are rejected.\n * @template TYPE\n */\ngoog.Promise.firstFulfilled = function(promises) {\n  return new goog.Promise(function(resolve, reject) {\n    var toReject = promises.length;\n    var reasons = [];\n\n    if (!toReject) {\n      resolve(undefined);\n      return;\n    }\n\n    var onFulfill = function(value) { resolve(value); };\n\n    var onReject = function(index, reason) {\n      toReject--;\n      reasons[index] = reason;\n      if (toReject == 0) {\n        reject(reasons);\n      }\n    };\n\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n      goog.Promise.resolveThen_(promise, onFulfill, goog.partial(onReject, i));\n    }\n  });\n};\n\n\n/**\n * @return {!goog.promise.Resolver<TYPE>} Resolver wrapping the promise and its\n *     resolve / reject functions. Resolving or rejecting the resolver\n *     resolves or rejects the promise.\n * @template TYPE\n */\ngoog.Promise.withResolver = function() {\n  var resolve, reject;\n  var promise = new goog.Promise(function(rs, rj) {\n    resolve = rs;\n    reject = rj;\n  });\n  return new goog.Promise.Resolver_(promise, resolve, reject);\n};\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise, returning a\n * new child Promise.\n *\n * If the Promise is fulfilled, the `onFulfilled` callback will be invoked\n * with the fulfillment value as argument, and the child Promise will be\n * fulfilled with the return value of the callback. If the callback throws an\n * exception, the child Promise will be rejected with the thrown value instead.\n *\n * If the Promise is rejected, the `onRejected` callback will be invoked\n * with the rejection reason as argument, and the child Promise will be resolved\n * with the return value or rejected with the thrown value of the callback.\n *\n * @override\n */\ngoog.Promise.prototype.then = function(\n    opt_onFulfilled, opt_onRejected, opt_context) {\n\n  if (opt_onFulfilled != null) {\n    goog.asserts.assertFunction(\n        opt_onFulfilled, 'opt_onFulfilled should be a function.');\n  }\n  if (opt_onRejected != null) {\n    goog.asserts.assertFunction(\n        opt_onRejected,\n        'opt_onRejected should be a function. Did you pass opt_context ' +\n            'as the second argument instead of the third?');\n  }\n\n  if (goog.Promise.LONG_STACK_TRACES) {\n    this.addStackTrace_(new Error('then'));\n  }\n\n  return this.addChildPromise_(\n      goog.isFunction(opt_onFulfilled) ? opt_onFulfilled : null,\n      goog.isFunction(opt_onRejected) ? opt_onRejected : null, opt_context);\n};\ngoog.Thenable.addImplementation(goog.Promise);\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise without\n * returning a child Promise (unlike \"then\").\n *\n * If the Promise is fulfilled, the `onFulfilled` callback will be invoked\n * with the fulfillment value as argument.\n *\n * If the Promise is rejected, the `onRejected` callback will be invoked\n * with the rejection reason as argument.\n *\n * @param {?(function(this:THIS, TYPE):?)=} opt_onFulfilled A\n *     function that will be invoked with the fulfillment value if the Promise\n *     is fulfilled.\n * @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will\n *     be invoked with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n *     execution context for the callbacks. By default, functions are executed\n *     with the default this.\n * @package\n * @template THIS\n */\ngoog.Promise.prototype.thenVoid = function(\n    opt_onFulfilled, opt_onRejected, opt_context) {\n\n  if (opt_onFulfilled != null) {\n    goog.asserts.assertFunction(\n        opt_onFulfilled, 'opt_onFulfilled should be a function.');\n  }\n  if (opt_onRejected != null) {\n    goog.asserts.assertFunction(\n        opt_onRejected,\n        'opt_onRejected should be a function. Did you pass opt_context ' +\n            'as the second argument instead of the third?');\n  }\n\n  if (goog.Promise.LONG_STACK_TRACES) {\n    this.addStackTrace_(new Error('then'));\n  }\n\n  // Note: no default rejection handler is provided here as we need to\n  // distinguish unhandled rejections.\n  this.addCallbackEntry_(\n      goog.Promise.getCallbackEntry_(\n          opt_onFulfilled || goog.nullFunction, opt_onRejected || null,\n          opt_context));\n};\n\n\n/**\n * Adds a callback that will be invoked when the Promise is settled (fulfilled\n * or rejected). The callback receives no argument, and no new child Promise is\n * created. This is useful for ensuring that cleanup takes place after certain\n * asynchronous operations. Callbacks added with `thenAlways` will be\n * executed in the same order with other calls to `then`,\n * `thenAlways`, or `thenCatch`.\n *\n * Since it does not produce a new child Promise, cancellation propagation is\n * not prevented by adding callbacks with `thenAlways`. A Promise that has\n * a cleanup handler added with `thenAlways` will be canceled if all of\n * its children created by `then` (or `thenCatch`) are canceled.\n * Additionally, since any rejections are not passed to the callback, it does\n * not stop the unhandled rejection handler from running.\n *\n * @param {function(this:THIS): void} onSettled A function that will be invoked\n *     when the Promise is settled (fulfilled or rejected).\n * @param {THIS=} opt_context An optional context object that will be the\n *     execution context for the callbacks. By default, functions are executed\n *     in the global scope.\n * @return {!goog.Promise<TYPE>} This Promise, for chaining additional calls.\n * @template THIS\n */\ngoog.Promise.prototype.thenAlways = function(onSettled, opt_context) {\n  if (goog.Promise.LONG_STACK_TRACES) {\n    this.addStackTrace_(new Error('thenAlways'));\n  }\n\n  var entry = goog.Promise.getCallbackEntry_(onSettled, onSettled, opt_context);\n  entry.always = true;\n  this.addCallbackEntry_(entry);\n  return this;\n};\n\n\n/**\n * Adds a callback that will be invoked only if the Promise is rejected. This\n * is equivalent to `then(null, onRejected)`.\n *\n * @param {function(this:THIS, *): *} onRejected A function that will be\n *     invoked with the rejection reason if this Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n *     execution context for the callbacks. By default, functions are executed\n *     in the global scope.\n * @return {!goog.Promise} A new Promise that will resolve either to the\n *     value of this promise, or if this promise is rejected, the result of\n *     `onRejected`. The returned Promise will reject if `onRejected` throws.\n * @template THIS\n */\ngoog.Promise.prototype.thenCatch = function(onRejected, opt_context) {\n  if (goog.Promise.LONG_STACK_TRACES) {\n    this.addStackTrace_(new Error('thenCatch'));\n  }\n  return this.addChildPromise_(null, onRejected, opt_context);\n};\n\n\n/**\n * Cancels the Promise if it is still pending by rejecting it with a cancel\n * Error. No action is performed if the Promise is already resolved.\n *\n * All child Promises of the canceled Promise will be rejected with the same\n * cancel error, as with normal Promise rejection. If the Promise to be canceled\n * is the only child of a pending Promise, the parent Promise will also be\n * canceled. Cancellation may propagate upward through multiple generations.\n *\n * @param {string=} opt_message An optional debugging message for describing the\n *     cancellation reason.\n */\ngoog.Promise.prototype.cancel = function(opt_message) {\n  if (this.state_ == goog.Promise.State_.PENDING) {\n    // Instantiate Error object synchronously. This ensures Error::stack points\n    // to the cancel() callsite.\n    var err = new goog.Promise.CancellationError(opt_message);\n    goog.async.run(function() {\n      this.cancelInternal_(err);\n    }, this);\n  }\n};\n\n\n/**\n * Cancels this Promise with the given error.\n *\n * @param {!Error} err The cancellation error.\n * @private\n */\ngoog.Promise.prototype.cancelInternal_ = function(err) {\n  if (this.state_ == goog.Promise.State_.PENDING) {\n    if (this.parent_) {\n      // Cancel the Promise and remove it from the parent's child list.\n      this.parent_.cancelChild_(this, err);\n      this.parent_ = null;\n    } else {\n      this.resolve_(goog.Promise.State_.REJECTED, err);\n    }\n  }\n};\n\n\n/**\n * Cancels a child Promise from the list of callback entries. If the Promise has\n * not already been resolved, reject it with a cancel error. If there are no\n * other children in the list of callback entries, propagate the cancellation\n * by canceling this Promise as well.\n *\n * @param {!goog.Promise} childPromise The Promise to cancel.\n * @param {!Error} err The cancel error to use for rejecting the Promise.\n * @private\n */\ngoog.Promise.prototype.cancelChild_ = function(childPromise, err) {\n  if (!this.callbackEntries_) {\n    return;\n  }\n  var childCount = 0;\n  var childEntry = null;\n  var beforeChildEntry = null;\n\n  // Find the callback entry for the childPromise, and count whether there are\n  // additional child Promises.\n  for (var entry = this.callbackEntries_; entry; entry = entry.next) {\n    if (!entry.always) {\n      childCount++;\n      if (entry.child == childPromise) {\n        childEntry = entry;\n      }\n      if (childEntry && childCount > 1) {\n        break;\n      }\n    }\n    if (!childEntry) {\n      beforeChildEntry = entry;\n    }\n  }\n\n  // Can a child entry be missing?\n\n  // If the child Promise was the only child, cancel this Promise as well.\n  // Otherwise, reject only the child Promise with the cancel error.\n  if (childEntry) {\n    if (this.state_ == goog.Promise.State_.PENDING && childCount == 1) {\n      this.cancelInternal_(err);\n    } else {\n      if (beforeChildEntry) {\n        this.removeEntryAfter_(beforeChildEntry);\n      } else {\n        this.popEntry_();\n      }\n\n      this.executeCallback_(childEntry, goog.Promise.State_.REJECTED, err);\n    }\n  }\n};\n\n\n/**\n * Adds a callback entry to the current Promise, and schedules callback\n * execution if the Promise has already been settled.\n *\n * @param {goog.Promise.CallbackEntry_} callbackEntry Record containing\n *     `onFulfilled` and `onRejected` callbacks to execute after\n *     the Promise is settled.\n * @private\n */\ngoog.Promise.prototype.addCallbackEntry_ = function(callbackEntry) {\n  if (!this.hasEntry_() && (this.state_ == goog.Promise.State_.FULFILLED ||\n                            this.state_ == goog.Promise.State_.REJECTED)) {\n    this.scheduleCallbacks_();\n  }\n  this.queueEntry_(callbackEntry);\n};\n\n\n/**\n * Creates a child Promise and adds it to the callback entry list. The result of\n * the child Promise is determined by the state of the parent Promise and the\n * result of the `onFulfilled` or `onRejected` callbacks as\n * specified in the Promise resolution procedure.\n *\n * @see http://promisesaplus.com/#the__method\n *\n * @param {?function(this:THIS, TYPE):\n *          (RESULT|goog.Promise<RESULT>|Thenable)} onFulfilled A callback that\n *     will be invoked if the Promise is fulfilled, or null.\n * @param {?function(this:THIS, *): *} onRejected A callback that will be\n *     invoked if the Promise is rejected, or null.\n * @param {THIS=} opt_context An optional execution context for the callbacks.\n *     in the default calling context.\n * @return {!goog.Promise} The child Promise.\n * @template RESULT,THIS\n * @private\n */\ngoog.Promise.prototype.addChildPromise_ = function(\n    onFulfilled, onRejected, opt_context) {\n\n  /** @type {goog.Promise.CallbackEntry_} */\n  var callbackEntry = goog.Promise.getCallbackEntry_(null, null, null);\n\n  callbackEntry.child = new goog.Promise(function(resolve, reject) {\n    // Invoke onFulfilled, or resolve with the parent's value if absent.\n    callbackEntry.onFulfilled = onFulfilled ? function(value) {\n      try {\n        var result = onFulfilled.call(opt_context, value);\n        resolve(result);\n      } catch (err) {\n        reject(err);\n      }\n    } : resolve;\n\n    // Invoke onRejected, or reject with the parent's reason if absent.\n    callbackEntry.onRejected = onRejected ? function(reason) {\n      try {\n        var result = onRejected.call(opt_context, reason);\n        if (result === undefined &&\n            reason instanceof goog.Promise.CancellationError) {\n          // Propagate cancellation to children if no other result is returned.\n          reject(reason);\n        } else {\n          resolve(result);\n        }\n      } catch (err) {\n        reject(err);\n      }\n    } : reject;\n  });\n\n  callbackEntry.child.parent_ = this;\n  this.addCallbackEntry_(callbackEntry);\n  return callbackEntry.child;\n};\n\n\n/**\n * Unblocks the Promise and fulfills it with the given value.\n *\n * @param {TYPE} value\n * @private\n */\ngoog.Promise.prototype.unblockAndFulfill_ = function(value) {\n  goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);\n  this.state_ = goog.Promise.State_.PENDING;\n  this.resolve_(goog.Promise.State_.FULFILLED, value);\n};\n\n\n/**\n * Unblocks the Promise and rejects it with the given rejection reason.\n *\n * @param {*} reason\n * @private\n */\ngoog.Promise.prototype.unblockAndReject_ = function(reason) {\n  goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);\n  this.state_ = goog.Promise.State_.PENDING;\n  this.resolve_(goog.Promise.State_.REJECTED, reason);\n};\n\n\n/**\n * Attempts to resolve a Promise with a given resolution state and value. This\n * is a no-op if the given Promise has already been resolved.\n *\n * If the given result is a Thenable (such as another Promise), the Promise will\n * be settled with the same state and result as the Thenable once it is itself\n * settled.\n *\n * If the given result is not a Thenable, the Promise will be settled (fulfilled\n * or rejected) with that result based on the given state.\n *\n * @see http://promisesaplus.com/#the_promise_resolution_procedure\n *\n * @param {goog.Promise.State_} state\n * @param {*} x The result to apply to the Promise.\n * @private\n */\ngoog.Promise.prototype.resolve_ = function(state, x) {\n  if (this.state_ != goog.Promise.State_.PENDING) {\n    return;\n  }\n\n  if (this === x) {\n    state = goog.Promise.State_.REJECTED;\n    x = new TypeError('Promise cannot resolve to itself');\n  }\n\n  this.state_ = goog.Promise.State_.BLOCKED;\n  var isThenable = goog.Promise.maybeThen_(\n      x, this.unblockAndFulfill_, this.unblockAndReject_, this);\n  if (isThenable) {\n    return;\n  }\n\n  this.result_ = x;\n  this.state_ = state;\n  // Since we can no longer be canceled, remove link to parent, so that the\n  // child promise does not keep the parent promise alive.\n  this.parent_ = null;\n  this.scheduleCallbacks_();\n\n  if (state == goog.Promise.State_.REJECTED &&\n      !(x instanceof goog.Promise.CancellationError)) {\n    goog.Promise.addUnhandledRejection_(this, x);\n  }\n};\n\n\n/**\n * Invokes the \"then\" method of an input value if that value is a Thenable. This\n * is a no-op if the value is not thenable.\n *\n * @param {?} value A potentially thenable value.\n * @param {!Function} onFulfilled\n * @param {!Function} onRejected\n * @param {?} context\n * @return {boolean} Whether the input value was thenable.\n * @private\n */\ngoog.Promise.maybeThen_ = function(value, onFulfilled, onRejected, context) {\n  if (value instanceof goog.Promise) {\n    value.thenVoid(onFulfilled, onRejected, context);\n    return true;\n  } else if (goog.Thenable.isImplementedBy(value)) {\n    value = /** @type {!goog.Thenable} */ (value);\n    value.then(onFulfilled, onRejected, context);\n    return true;\n  } else if (goog.isObject(value)) {\n    const thenable = /** @type {!Thenable} */ (value);\n    try {\n      var then = thenable.then;\n      if (goog.isFunction(then)) {\n        goog.Promise.tryThen_(thenable, then, onFulfilled, onRejected, context);\n        return true;\n      }\n    } catch (e) {\n      onRejected.call(context, e);\n      return true;\n    }\n  }\n\n  return false;\n};\n\n\n/**\n * Attempts to call the `then` method on an object in the hopes that it is\n * a Promise-compatible instance. This allows interoperation between different\n * Promise implementations, however a non-compliant object may cause a Promise\n * to hang indefinitely. If the `then` method throws an exception, the\n * dependent Promise will be rejected with the thrown value.\n *\n * @see http://promisesaplus.com/#point-70\n *\n * @param {Thenable} thenable An object with a `then` method that may be\n *     compatible with the Promise/A+ specification.\n * @param {!Function} then The `then` method of the Thenable object.\n * @param {!Function} onFulfilled\n * @param {!Function} onRejected\n * @param {*} context\n * @private\n */\ngoog.Promise.tryThen_ = function(\n    thenable, then, onFulfilled, onRejected, context) {\n\n  var called = false;\n  var resolve = function(value) {\n    if (!called) {\n      called = true;\n      onFulfilled.call(context, value);\n    }\n  };\n\n  var reject = function(reason) {\n    if (!called) {\n      called = true;\n      onRejected.call(context, reason);\n    }\n  };\n\n  try {\n    then.call(thenable, resolve, reject);\n  } catch (e) {\n    reject(e);\n  }\n};\n\n\n/**\n * Executes the pending callbacks of a settled Promise after a timeout.\n *\n * Section 2.2.4 of the Promises/A+ specification requires that Promise\n * callbacks must only be invoked from a call stack that only contains Promise\n * implementation code, which we accomplish by invoking callback execution after\n * a timeout. If `startExecution_` is called multiple times for the same\n * Promise, the callback chain will be evaluated only once. Additional callbacks\n * may be added during the evaluation phase, and will be executed in the same\n * event loop.\n *\n * All Promises added to the waiting list during the same browser event loop\n * will be executed in one batch to avoid using a separate timeout per Promise.\n *\n * @private\n */\ngoog.Promise.prototype.scheduleCallbacks_ = function() {\n  if (!this.executing_) {\n    this.executing_ = true;\n    goog.async.run(this.executeCallbacks_, this);\n  }\n};\n\n\n/**\n * @return {boolean} Whether there are any pending callbacks queued.\n * @private\n */\ngoog.Promise.prototype.hasEntry_ = function() {\n  return !!this.callbackEntries_;\n};\n\n\n/**\n * @param {goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.prototype.queueEntry_ = function(entry) {\n  goog.asserts.assert(entry.onFulfilled != null);\n\n  if (this.callbackEntriesTail_) {\n    this.callbackEntriesTail_.next = entry;\n    this.callbackEntriesTail_ = entry;\n  } else {\n    // It the work queue was empty set the head too.\n    this.callbackEntries_ = entry;\n    this.callbackEntriesTail_ = entry;\n  }\n};\n\n\n/**\n * @return {goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.prototype.popEntry_ = function() {\n  var entry = null;\n  if (this.callbackEntries_) {\n    entry = this.callbackEntries_;\n    this.callbackEntries_ = entry.next;\n    entry.next = null;\n  }\n  // It the work queue is empty clear the tail too.\n  if (!this.callbackEntries_) {\n    this.callbackEntriesTail_ = null;\n  }\n\n  if (entry != null) {\n    goog.asserts.assert(entry.onFulfilled != null);\n  }\n  return entry;\n};\n\n\n/**\n * @param {goog.Promise.CallbackEntry_} previous\n * @private\n */\ngoog.Promise.prototype.removeEntryAfter_ = function(previous) {\n  goog.asserts.assert(this.callbackEntries_);\n  goog.asserts.assert(previous != null);\n  // If the last entry is being removed, update the tail\n  if (previous.next == this.callbackEntriesTail_) {\n    this.callbackEntriesTail_ = previous;\n  }\n\n  previous.next = previous.next.next;\n};\n\n\n/**\n * Executes all pending callbacks for this Promise.\n *\n * @private\n */\ngoog.Promise.prototype.executeCallbacks_ = function() {\n  var entry = null;\n  while (entry = this.popEntry_()) {\n    if (goog.Promise.LONG_STACK_TRACES) {\n      this.currentStep_++;\n    }\n    this.executeCallback_(entry, this.state_, this.result_);\n  }\n  this.executing_ = false;\n};\n\n\n/**\n * Executes a pending callback for this Promise. Invokes an `onFulfilled`\n * or `onRejected` callback based on the settled state of the Promise.\n *\n * @param {!goog.Promise.CallbackEntry_} callbackEntry An entry containing the\n *     onFulfilled and/or onRejected callbacks for this step.\n * @param {goog.Promise.State_} state The resolution status of the Promise,\n *     either FULFILLED or REJECTED.\n * @param {*} result The settled result of the Promise.\n * @private\n */\ngoog.Promise.prototype.executeCallback_ = function(\n    callbackEntry, state, result) {\n  // Cancel an unhandled rejection if the then/thenVoid call had an onRejected.\n  if (state == goog.Promise.State_.REJECTED && callbackEntry.onRejected &&\n      !callbackEntry.always) {\n    this.removeUnhandledRejection_();\n  }\n\n  if (callbackEntry.child) {\n    // When the parent is settled, the child no longer needs to hold on to it,\n    // as the parent can no longer be canceled.\n    callbackEntry.child.parent_ = null;\n    goog.Promise.invokeCallback_(callbackEntry, state, result);\n  } else {\n    // Callbacks created with thenAlways or thenVoid do not have the rejection\n    // handling code normally set up in the child Promise.\n    try {\n      callbackEntry.always ?\n          callbackEntry.onFulfilled.call(callbackEntry.context) :\n          goog.Promise.invokeCallback_(callbackEntry, state, result);\n    } catch (err) {\n      goog.Promise.handleRejection_.call(null, err);\n    }\n  }\n  goog.Promise.returnEntry_(callbackEntry);\n};\n\n\n/**\n * Executes the onFulfilled or onRejected callback for a callbackEntry.\n *\n * @param {!goog.Promise.CallbackEntry_} callbackEntry\n * @param {goog.Promise.State_} state\n * @param {*} result\n * @private\n */\ngoog.Promise.invokeCallback_ = function(callbackEntry, state, result) {\n  if (state == goog.Promise.State_.FULFILLED) {\n    callbackEntry.onFulfilled.call(callbackEntry.context, result);\n  } else if (callbackEntry.onRejected) {\n    callbackEntry.onRejected.call(callbackEntry.context, result);\n  }\n};\n\n\n/**\n * Records a stack trace entry for functions that call `then` or the\n * Promise constructor. May be disabled by unsetting `LONG_STACK_TRACES`.\n *\n * @param {!Error} err An Error object created by the calling function for\n *     providing a stack trace.\n * @private\n */\ngoog.Promise.prototype.addStackTrace_ = function(err) {\n  if (goog.Promise.LONG_STACK_TRACES && typeof err.stack === 'string') {\n    // Extract the third line of the stack trace, which is the entry for the\n    // user function that called into Promise code.\n    var trace = err.stack.split('\\n', 4)[3];\n    var message = err.message;\n\n    // Pad the message to align the traces.\n    message += Array(11 - message.length).join(' ');\n    this.stack_.push(message + trace);\n  }\n};\n\n\n/**\n * Adds extra stack trace information to an exception for the list of\n * asynchronous `then` calls that have been run for this Promise. Stack\n * trace information is recorded in {@see #addStackTrace_}, and appended to\n * rethrown errors when `LONG_STACK_TRACES` is enabled.\n *\n * @param {?} err An unhandled exception captured during callback execution.\n * @private\n */\ngoog.Promise.prototype.appendLongStack_ = function(err) {\n  if (goog.Promise.LONG_STACK_TRACES && err && typeof err.stack === 'string' &&\n      this.stack_.length) {\n    var longTrace = ['Promise trace:'];\n\n    for (var promise = this; promise; promise = promise.parent_) {\n      for (var i = this.currentStep_; i >= 0; i--) {\n        longTrace.push(promise.stack_[i]);\n      }\n      longTrace.push(\n          'Value: ' +\n          '[' + (promise.state_ == goog.Promise.State_.REJECTED ? 'REJECTED' :\n                                                                  'FULFILLED') +\n          '] ' +\n          '<' + String(promise.result_) + '>');\n    }\n    err.stack += '\\n\\n' + longTrace.join('\\n');\n  }\n};\n\n\n/**\n * Marks this rejected Promise as having being handled. Also marks any parent\n * Promises in the rejected state as handled. The rejection handler will no\n * longer be invoked for this Promise (if it has not been called already).\n *\n * @private\n */\ngoog.Promise.prototype.removeUnhandledRejection_ = function() {\n  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n    for (var p = this; p && p.unhandledRejectionId_; p = p.parent_) {\n      goog.global.clearTimeout(p.unhandledRejectionId_);\n      p.unhandledRejectionId_ = 0;\n    }\n  } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n    for (var p = this; p && p.hadUnhandledRejection_; p = p.parent_) {\n      p.hadUnhandledRejection_ = false;\n    }\n  }\n};\n\n\n/**\n * Marks this rejected Promise as unhandled. If no `onRejected` callback\n * is called for this Promise before the `UNHANDLED_REJECTION_DELAY`\n * expires, the reason will be passed to the unhandled rejection handler. The\n * handler typically rethrows the rejection reason so that it becomes visible in\n * the developer console.\n *\n * @param {!goog.Promise} promise The rejected Promise.\n * @param {*} reason The Promise rejection reason.\n * @private\n */\ngoog.Promise.addUnhandledRejection_ = function(promise, reason) {\n  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n    promise.unhandledRejectionId_ = goog.global.setTimeout(function() {\n      promise.appendLongStack_(reason);\n      goog.Promise.handleRejection_.call(null, reason);\n    }, goog.Promise.UNHANDLED_REJECTION_DELAY);\n\n  } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n    promise.hadUnhandledRejection_ = true;\n    goog.async.run(function() {\n      if (promise.hadUnhandledRejection_) {\n        promise.appendLongStack_(reason);\n        goog.Promise.handleRejection_.call(null, reason);\n      }\n    });\n  }\n};\n\n\n/**\n * A method that is invoked with the rejection reasons for Promises that are\n * rejected but have no `onRejected` callbacks registered yet.\n * @type {function(*)}\n * @private\n */\ngoog.Promise.handleRejection_ = goog.async.throwException;\n\n\n/**\n * Sets a handler that will be called with reasons from unhandled rejected\n * Promises. If the rejected Promise (or one of its descendants) has an\n * `onRejected` callback registered, the rejection will be considered\n * handled, and the rejection handler will not be called.\n *\n * By default, unhandled rejections are rethrown so that the error may be\n * captured by the developer console or a `window.onerror` handler.\n *\n * @param {function(*)} handler A function that will be called with reasons from\n *     rejected Promises. Defaults to `goog.async.throwException`.\n */\ngoog.Promise.setUnhandledRejectionHandler = function(handler) {\n  goog.Promise.handleRejection_ = handler;\n};\n\n\n\n/**\n * Error used as a rejection reason for canceled Promises.\n *\n * @param {string=} opt_message\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.Promise.CancellationError = function(opt_message) {\n  goog.Promise.CancellationError.base(this, 'constructor', opt_message);\n};\ngoog.inherits(goog.Promise.CancellationError, goog.debug.Error);\n\n\n/** @override */\ngoog.Promise.CancellationError.prototype.name = 'cancel';\n\n\n\n/**\n * Internal implementation of the resolver interface.\n *\n * @param {!goog.Promise<TYPE>} promise\n * @param {function((TYPE|goog.Promise<TYPE>|Thenable)=)} resolve\n * @param {function(*=): void} reject\n * @implements {goog.promise.Resolver<TYPE>}\n * @final @struct\n * @constructor\n * @private\n * @template TYPE\n */\ngoog.Promise.Resolver_ = function(promise, resolve, reject) {\n  /** @const */\n  this.promise = promise;\n\n  /** @const */\n  this.resolve = resolve;\n\n  /** @const */\n  this.reject = reject;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A patched, standardized event object for browser events.\n *\n * <pre>\n * The patched event object contains the following members:\n * - type           {string}    Event type, e.g. 'click'\n * - target         {Object}    The element that actually triggered the event\n * - currentTarget  {Object}    The element the listener is attached to\n * - relatedTarget  {Object}    For mouseover and mouseout, the previous object\n * - offsetX        {number}    X-coordinate relative to target\n * - offsetY        {number}    Y-coordinate relative to target\n * - clientX        {number}    X-coordinate relative to viewport\n * - clientY        {number}    Y-coordinate relative to viewport\n * - screenX        {number}    X-coordinate relative to the edge of the screen\n * - screenY        {number}    Y-coordinate relative to the edge of the screen\n * - button         {number}    Mouse button. Use isButton() to test.\n * - keyCode        {number}    Key-code\n * - ctrlKey        {boolean}   Was ctrl key depressed\n * - altKey         {boolean}   Was alt key depressed\n * - shiftKey       {boolean}   Was shift key depressed\n * - metaKey        {boolean}   Was meta key depressed\n * - pointerId      {number}    Pointer ID\n * - pointerType    {string}    Pointer type, e.g. 'mouse', 'pen', or 'touch'\n * - defaultPrevented {boolean} Whether the default action has been prevented\n * - state          {Object}    History state object\n *\n * NOTE: The keyCode member contains the raw browser keyCode. For normalized\n * key and character code use {@link goog.events.KeyHandler}.\n * </pre>\n */\n\ngoog.provide('goog.events.BrowserEvent');\ngoog.provide('goog.events.BrowserEvent.MouseButton');\ngoog.provide('goog.events.BrowserEvent.PointerType');\n\ngoog.require('goog.debug');\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventType');\ngoog.require('goog.reflect');\ngoog.require('goog.userAgent');\n\n/**\n * @define {boolean} If true, use the layerX and layerY properties of a native\n * browser event over the offsetX and offsetY properties, which cause expensive\n * reflow. If layerX or layerY is not defined, offsetX and offsetY will be used\n * as usual.\n */\ngoog.events.USE_LAYER_XY_AS_OFFSET_XY =\n    goog.define('goog.events.USE_LAYER_XY_AS_OFFSET_XY', false);\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * The content of this object will not be initialized if no event object is\n * provided. If this is the case, init() needs to be invoked separately.\n * @param {Event=} opt_e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.events.BrowserEvent = function(opt_e, opt_currentTarget) {\n  goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : '');\n\n  /**\n   * Target that fired the event.\n   * @override\n   * @type {?Node}\n   */\n  this.target = null;\n\n  /**\n   * Node that had the listener attached.\n   * @override\n   * @type {?Node|undefined}\n   */\n  this.currentTarget = null;\n\n  /**\n   * For mouseover and mouseout events, the related object for the event.\n   * @type {?Node}\n   */\n  this.relatedTarget = null;\n\n  /**\n   * X-coordinate relative to target.\n   * @type {number}\n   */\n  this.offsetX = 0;\n\n  /**\n   * Y-coordinate relative to target.\n   * @type {number}\n   */\n  this.offsetY = 0;\n\n  /**\n   * X-coordinate relative to the window.\n   * @type {number}\n   */\n  this.clientX = 0;\n\n  /**\n   * Y-coordinate relative to the window.\n   * @type {number}\n   */\n  this.clientY = 0;\n\n  /**\n   * X-coordinate relative to the monitor.\n   * @type {number}\n   */\n  this.screenX = 0;\n\n  /**\n   * Y-coordinate relative to the monitor.\n   * @type {number}\n   */\n  this.screenY = 0;\n\n  /**\n   * Which mouse button was pressed.\n   * @type {number}\n   */\n  this.button = 0;\n\n  /**\n   * Key of key press.\n   * @type {string}\n   */\n  this.key = '';\n\n  /**\n   * Keycode of key press.\n   * @type {number}\n   */\n  this.keyCode = 0;\n\n  /**\n   * Keycode of key press.\n   * @type {number}\n   */\n  this.charCode = 0;\n\n  /**\n   * Whether control was pressed at time of event.\n   * @type {boolean}\n   */\n  this.ctrlKey = false;\n\n  /**\n   * Whether alt was pressed at time of event.\n   * @type {boolean}\n   */\n  this.altKey = false;\n\n  /**\n   * Whether shift was pressed at time of event.\n   * @type {boolean}\n   */\n  this.shiftKey = false;\n\n  /**\n   * Whether the meta key was pressed at time of event.\n   * @type {boolean}\n   */\n  this.metaKey = false;\n\n  /**\n   * History state object, only set for PopState events where it's a copy of the\n   * state object provided to pushState or replaceState.\n   * @type {?Object}\n   */\n  this.state = null;\n\n  /**\n   * Whether the default platform modifier key was pressed at time of event.\n   * (This is control for all platforms except Mac, where it's Meta.)\n   * @type {boolean}\n   */\n  this.platformModifierKey = false;\n\n  /**\n   * @type {number}\n   */\n  this.pointerId = 0;\n\n  /**\n   * @type {string}\n   */\n  this.pointerType = '';\n\n  /**\n   * The browser event object.\n   * @private {?Event}\n   */\n  this.event_ = null;\n\n  if (opt_e) {\n    this.init(opt_e, opt_currentTarget);\n  }\n};\ngoog.inherits(goog.events.BrowserEvent, goog.events.Event);\n\n\n/**\n * Normalized button constants for the mouse.\n * @enum {number}\n */\ngoog.events.BrowserEvent.MouseButton = {\n  LEFT: 0,\n  MIDDLE: 1,\n  RIGHT: 2\n};\n\n\n/**\n * Normalized pointer type constants for pointer events.\n * @enum {string}\n */\ngoog.events.BrowserEvent.PointerType = {\n  MOUSE: 'mouse',\n  PEN: 'pen',\n  TOUCH: 'touch'\n};\n\n\n/**\n * Static data for mapping mouse buttons.\n * @type {!Array<number>}\n * @deprecated Use `goog.events.BrowserEvent.IE_BUTTON_MAP` instead.\n */\ngoog.events.BrowserEvent.IEButtonMap = goog.debug.freeze([\n  1,  // LEFT\n  4,  // MIDDLE\n  2   // RIGHT\n]);\n\n\n/**\n * Static data for mapping mouse buttons.\n * @const {!Array<number>}\n */\ngoog.events.BrowserEvent.IE_BUTTON_MAP = goog.events.BrowserEvent.IEButtonMap;\n\n\n/**\n * Static data for mapping MSPointerEvent types to PointerEvent types.\n * @const {!Object<number, goog.events.BrowserEvent.PointerType>}\n */\ngoog.events.BrowserEvent.IE_POINTER_TYPE_MAP = goog.debug.freeze({\n  2: goog.events.BrowserEvent.PointerType.TOUCH,\n  3: goog.events.BrowserEvent.PointerType.PEN,\n  4: goog.events.BrowserEvent.PointerType.MOUSE\n});\n\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * @param {Event} e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n */\ngoog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {\n  var type = this.type = e.type;\n\n  /**\n   * On touch devices use the first \"changed touch\" as the relevant touch.\n   * @type {?Touch}\n   */\n  var relevantTouch =\n      e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : null;\n\n  // TODO(nicksantos): Change this.target to type EventTarget.\n  this.target = /** @type {Node} */ (e.target) || e.srcElement;\n\n  // TODO(nicksantos): Change this.currentTarget to type EventTarget.\n  this.currentTarget = /** @type {Node} */ (opt_currentTarget);\n\n  var relatedTarget = /** @type {Node} */ (e.relatedTarget);\n  if (relatedTarget) {\n    // There's a bug in FireFox where sometimes, relatedTarget will be a\n    // chrome element, and accessing any property of it will get a permission\n    // denied exception. See:\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=497780\n    if (goog.userAgent.GECKO) {\n      if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) {\n        relatedTarget = null;\n      }\n    }\n  } else if (type == goog.events.EventType.MOUSEOVER) {\n    relatedTarget = e.fromElement;\n  } else if (type == goog.events.EventType.MOUSEOUT) {\n    relatedTarget = e.toElement;\n  }\n\n  this.relatedTarget = relatedTarget;\n\n  if (relevantTouch) {\n    this.clientX = relevantTouch.clientX !== undefined ? relevantTouch.clientX :\n                                                         relevantTouch.pageX;\n    this.clientY = relevantTouch.clientY !== undefined ? relevantTouch.clientY :\n                                                         relevantTouch.pageY;\n    this.screenX = relevantTouch.screenX || 0;\n    this.screenY = relevantTouch.screenY || 0;\n  } else {\n    if (goog.events.USE_LAYER_XY_AS_OFFSET_XY) {\n      this.offsetX = (e.layerX !== undefined) ? e.layerX : e.offsetX;\n      this.offsetY = (e.layerY !== undefined) ? e.layerY : e.offsetY;\n    } else {\n      // Webkit emits a lame warning whenever layerX/layerY is accessed.\n      // http://code.google.com/p/chromium/issues/detail?id=101733\n      this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ?\n          e.offsetX :\n          e.layerX;\n      this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ?\n          e.offsetY :\n          e.layerY;\n    }\n    this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;\n    this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;\n    this.screenX = e.screenX || 0;\n    this.screenY = e.screenY || 0;\n  }\n\n  this.button = e.button;\n\n  this.keyCode = e.keyCode || 0;\n  this.key = e.key || '';\n  this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0);\n  this.ctrlKey = e.ctrlKey;\n  this.altKey = e.altKey;\n  this.shiftKey = e.shiftKey;\n  this.metaKey = e.metaKey;\n  this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;\n  this.pointerId = e.pointerId || 0;\n  this.pointerType = goog.events.BrowserEvent.getPointerType_(e);\n  this.state = e.state;\n  this.event_ = e;\n  if (e.defaultPrevented) {\n    this.preventDefault();\n  }\n};\n\n\n/**\n * Tests to see which button was pressed during the event. This is really only\n * useful in IE and Gecko browsers. And in IE, it's only useful for\n * mousedown/mouseup events, because click only fires for the left mouse button.\n *\n * Safari 2 only reports the left button being clicked, and uses the value '1'\n * instead of 0. Opera only reports a mousedown event for the middle button, and\n * no mouse events for the right button. Opera has default behavior for left and\n * middle click that can only be overridden via a configuration setting.\n *\n * There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.\n *\n * @param {goog.events.BrowserEvent.MouseButton} button The button\n *     to test for.\n * @return {boolean} True if button was pressed.\n */\ngoog.events.BrowserEvent.prototype.isButton = function(button) {\n  if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {\n    if (this.type == 'click') {\n      return button == goog.events.BrowserEvent.MouseButton.LEFT;\n    } else {\n      return !!(\n          this.event_.button & goog.events.BrowserEvent.IE_BUTTON_MAP[button]);\n    }\n  } else {\n    return this.event_.button == button;\n  }\n};\n\n\n/**\n * Whether this has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @return {boolean} The result.\n */\ngoog.events.BrowserEvent.prototype.isMouseActionButton = function() {\n  // Webkit does not ctrl+click to be a right-click, so we\n  // normalize it to behave like Gecko and Opera.\n  return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&\n      !(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey);\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.stopPropagation = function() {\n  goog.events.BrowserEvent.superClass_.stopPropagation.call(this);\n  if (this.event_.stopPropagation) {\n    this.event_.stopPropagation();\n  } else {\n    this.event_.cancelBubble = true;\n  }\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.preventDefault = function() {\n  goog.events.BrowserEvent.superClass_.preventDefault.call(this);\n  var be = this.event_;\n  if (!be.preventDefault) {\n    be.returnValue = false;\n    if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {\n\n      try {\n        // Most keys can be prevented using returnValue. Some special keys\n        // require setting the keyCode to -1 as well:\n        //\n        // In IE7:\n        // F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6)\n        //\n        // In IE8:\n        // Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event)\n        //\n        // We therefore do this for all function keys as well as when Ctrl key\n        // is pressed.\n        var VK_F1 = 112;\n        var VK_F12 = 123;\n        if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {\n          be.keyCode = -1;\n        }\n      } catch (ex) {\n        // IE throws an 'access denied' exception when trying to change\n        // keyCode in some situations (e.g. srcElement is input[type=file],\n        // or srcElement is an anchor tag rewritten by parent's innerHTML).\n        // Do nothing in this case.\n      }\n    }\n  } else {\n    be.preventDefault();\n  }\n};\n\n\n/**\n * @return {Event} The underlying browser event object.\n */\ngoog.events.BrowserEvent.prototype.getBrowserEvent = function() {\n  return this.event_;\n};\n\n\n/**\n * Extracts the pointer type from the given event.\n * @param {!Event} e\n * @return {string} The pointer type, e.g. 'mouse', 'pen', or 'touch'.\n * @private\n */\ngoog.events.BrowserEvent.getPointerType_ = function(e) {\n  if (typeof (e.pointerType) === 'string') {\n    return e.pointerType;\n  }\n  // IE10 uses integer codes for pointer type.\n  // https://msdn.microsoft.com/en-us/library/hh772359(v=vs.85).aspx\n  return goog.events.BrowserEvent.IE_POINTER_TYPE_MAP[e.pointerType] || '';\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An event manager for both native browser event\n * targets and custom JavaScript event targets\n * (`goog.events.Listenable`). This provides an abstraction\n * over browsers' event systems.\n *\n * It also provides a simulation of W3C event model's capture phase in\n * Internet Explorer (IE 8 and below). Caveat: the simulation does not\n * interact well with listeners registered directly on the elements\n * (bypassing goog.events) or even with listeners registered via\n * goog.events in a separate JS binary. In these cases, we provide\n * no ordering guarantees.\n *\n * The listeners will receive a \"patched\" event object. Such event object\n * contains normalized values for certain event properties that differs in\n * different browsers.\n *\n * Example usage:\n * <pre>\n * goog.events.listen(myNode, 'click', function(e) { alert('woo') });\n * goog.events.listen(myNode, 'mouseover', mouseHandler, true);\n * goog.events.unlisten(myNode, 'mouseover', mouseHandler, true);\n * goog.events.removeAll(myNode);\n * </pre>\n *\n *                                            in IE and event object patching]\n *\n * @see ../demos/events.html\n * @see ../demos/event-propagation.html\n * @see ../demos/stopevent.html\n */\n\n// IMPLEMENTATION NOTES:\n// goog.events stores an auxiliary data structure on each EventTarget\n// source being listened on. This allows us to take advantage of GC,\n// having the data structure GC'd when the EventTarget is GC'd. This\n// GC behavior is equivalent to using W3C DOM Events directly.\n\ngoog.provide('goog.events');\ngoog.provide('goog.events.CaptureSimulationMode');\ngoog.provide('goog.events.Key');\ngoog.provide('goog.events.ListenableType');\n\ngoog.forwardDeclare('goog.debug.ErrorHandler');\ngoog.forwardDeclare('goog.events.EventWrapper');\ngoog.require('goog.asserts');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.BrowserEvent');\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\n\n\n/**\n * @typedef {number|goog.events.ListenableKey}\n */\ngoog.events.Key;\n\n\n/**\n * @typedef {EventTarget|goog.events.Listenable}\n */\ngoog.events.ListenableType;\n\n\n/**\n * Property name on a native event target for the listener map\n * associated with the event target.\n * @private @const {string}\n */\ngoog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0);\n\n\n/**\n * String used to prepend to IE event types.\n * @const\n * @private\n */\ngoog.events.onString_ = 'on';\n\n\n/**\n * Map of computed \"on<eventname>\" strings for IE event types. Caching\n * this removes an extra object allocation in goog.events.listen which\n * improves IE6 performance.\n * @const\n * @dict\n * @private\n */\ngoog.events.onStringMap_ = {};\n\n\n/**\n * @enum {number} Different capture simulation mode for IE8-.\n */\ngoog.events.CaptureSimulationMode = {\n  /**\n   * Does not perform capture simulation. Will asserts in IE8- when you\n   * add capture listeners.\n   */\n  OFF_AND_FAIL: 0,\n\n  /**\n   * Does not perform capture simulation, silently ignore capture\n   * listeners.\n   */\n  OFF_AND_SILENT: 1,\n\n  /**\n   * Performs capture simulation.\n   */\n  ON: 2\n};\n\n\n/**\n * @define {number} The capture simulation mode for IE8-. By default,\n *     this is ON.\n */\ngoog.events.CAPTURE_SIMULATION_MODE =\n    goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2);\n\n\n/**\n * Estimated count of total native listeners.\n * @private {number}\n */\ngoog.events.listenerCountEstimate_ = 0;\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. A listener can only be added once\n * to an object and if it is added again the key for the listener is\n * returned. Note that if the existing listener is a one-off listener\n * (registered via listenOnce), it will no longer be a one-off\n * listener after a call to listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n *     to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n *     listener Callback method, or an object with a handleEvent function.\n *     WARNING: passing an Object is now softly deprecated.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n */\ngoog.events.listen = function(src, type, listener, opt_options, opt_handler) {\n  if (opt_options && opt_options.once) {\n    return goog.events.listenOnce(\n        src, type, listener, opt_options, opt_handler);\n  }\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.listen(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    var capture =\n        goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n    return src.listen(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  } else {\n    return goog.events.listen_(\n        /** @type {!EventTarget} */ (src), type, listener,\n        /* callOnce */ false, opt_options, opt_handler);\n  }\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target. A listener can only be added once to an object and if it\n * is added again the key for the listener is returned.\n *\n * Note that a one-off listener will not change an existing listener,\n * if any. On the other hand a normal listener will change existing\n * one-off listener to become a normal listener.\n *\n * @param {EventTarget} src The node to listen to events on.\n * @param {string|?goog.events.EventId<EVENTOBJ>} type Event type.\n * @param {!Function} listener Callback function.\n * @param {boolean} callOnce Whether the listener is a one-off\n *     listener or otherwise.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} Unique key for the listener.\n * @template EVENTOBJ\n * @private\n */\ngoog.events.listen_ = function(\n    src, type, listener, callOnce, opt_options, opt_handler) {\n  if (!type) {\n    throw new Error('Invalid event type');\n  }\n\n  var capture =\n      goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n  if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n    if (goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.OFF_AND_FAIL) {\n      goog.asserts.fail('Can not register capture listener in IE8-.');\n      return null;\n    } else if (\n        goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.OFF_AND_SILENT) {\n      return null;\n    }\n  }\n\n  var listenerMap = goog.events.getListenerMap_(src);\n  if (!listenerMap) {\n    src[goog.events.LISTENER_MAP_PROP_] = listenerMap =\n        new goog.events.ListenerMap(src);\n  }\n\n  var listenerObj = /** @type {goog.events.Listener} */ (\n      listenerMap.add(type, listener, callOnce, capture, opt_handler));\n\n  // If the listenerObj already has a proxy, it has been set up\n  // previously. We simply return.\n  if (listenerObj.proxy) {\n    return listenerObj;\n  }\n\n  var proxy = goog.events.getProxy();\n  listenerObj.proxy = proxy;\n\n  proxy.src = src;\n  proxy.listener = listenerObj;\n\n  // Attach the proxy through the browser's API\n  if (src.addEventListener) {\n    // Don't pass an object as `capture` if the browser doesn't support that.\n    if (!goog.events.BrowserFeature.PASSIVE_EVENTS) {\n      opt_options = capture;\n    }\n    // Don't break tests that expect a boolean.\n    if (opt_options === undefined) opt_options = false;\n    src.addEventListener(type.toString(), proxy, opt_options);\n  } else if (src.attachEvent) {\n    // The else if above used to be an unconditional else. It would call\n    // attachEvent come gws or high water. This would sometimes throw an\n    // exception on IE11, spoiling the day of some callers. The previous\n    // incarnation of this code, from 2007, indicates that it replaced an\n    // earlier still version that caused excess allocations on IE6.\n    src.attachEvent(goog.events.getOnString_(type.toString()), proxy);\n  } else if (src.addListener && src.removeListener) {\n    // In IE, MediaQueryList uses addListener() insteadd of addEventListener. In\n    // Safari, there is no global for the MediaQueryList constructor, so we just\n    // check whether the object \"looks like\" MediaQueryList.\n    goog.asserts.assert(\n        type === 'change', 'MediaQueryList only has a change event');\n    src.addListener(proxy);\n  } else {\n    throw new Error('addEventListener and attachEvent are unavailable.');\n  }\n\n  goog.events.listenerCountEstimate_++;\n  return listenerObj;\n};\n\n\n/**\n * Helper function for returning a proxy function.\n * @return {!Function} A new or reused function object.\n */\ngoog.events.getProxy = function() {\n  var proxyCallbackFunction = goog.events.handleBrowserEvent_;\n  // Use a local var f to prevent one allocation.\n  var f =\n      goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) {\n        return proxyCallbackFunction.call(f.src, f.listener, eventObject);\n      } : function(eventObject) {\n        var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);\n        // NOTE(chrishenry): In IE, we hack in a capture phase. However, if\n        // there is inline event handler which tries to prevent default (for\n        // example <a href=\"...\" onclick=\"return false\">...</a>) in a\n        // descendant element, the prevent default will be overridden\n        // by this listener if this listener were to return true. Hence, we\n        // return undefined.\n        if (!v) return v;\n      };\n  return f;\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. After the event has fired the event\n * listener is removed from the target.\n *\n * If an existing listener already exists, listenOnce will do\n * nothing. In particular, if the listener was previously registered\n * via listen(), listenOnce() will not turn the listener into a\n * one-off listener. Similarly, if there is already an existing\n * one-off listener, listenOnce does not modify the listeners (it is\n * still a once listener).\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n *     to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n *     listener Callback method.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n */\ngoog.events.listenOnce = function(\n    src, type, listener, opt_options, opt_handler) {\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.listenOnce(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    var capture =\n        goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n    return src.listenOnce(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  } else {\n    return goog.events.listen_(\n        /** @type {!EventTarget} */ (src), type, listener,\n        /* callOnce */ true, opt_options, opt_handler);\n  }\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.Listenable}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.Listenable} src The target to\n *     listen to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener\n *     Callback method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n *     false).\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @template T\n */\ngoog.events.listenWithWrapper = function(\n    src, wrapper, listener, opt_capt, opt_handler) {\n  wrapper.listen(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes an event listener which was added with listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n *     listening to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types to unlisten to.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to remove.\n * @param {(boolean|!EventListenerOptions)=} opt_options\n *     whether the listener is fired during the capture or bubble phase of the\n *     event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {?boolean} indicating whether the listener was there to remove.\n * @template EVENTOBJ\n */\ngoog.events.unlisten = function(src, type, listener, opt_options, opt_handler) {\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.unlisten(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n  var capture =\n      goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return src.unlisten(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  }\n\n  if (!src) {\n    // TODO(chrishenry): We should tighten the API to only accept\n    // non-null objects, or add an assertion here.\n    return false;\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  if (listenerMap) {\n    var listenerObj = listenerMap.getListener(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n    if (listenerObj) {\n      return goog.events.unlistenByKey(listenerObj);\n    }\n  }\n\n  return false;\n};\n\n\n/**\n * Removes an event listener which was added with listen() by the key\n * returned by listen().\n *\n * @param {goog.events.Key} key The key returned by listen() for this\n *     event listener.\n * @return {boolean} indicating whether the listener was there to remove.\n */\ngoog.events.unlistenByKey = function(key) {\n  // TODO(chrishenry): Remove this check when tests that rely on this\n  // are fixed.\n  if (typeof key === 'number') {\n    return false;\n  }\n\n  var listener = key;\n  if (!listener || listener.removed) {\n    return false;\n  }\n\n  var src = listener.src;\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return /** @type {!goog.events.Listenable} */ (src).unlistenByKey(listener);\n  }\n\n  var type = listener.type;\n  var proxy = listener.proxy;\n  if (src.removeEventListener) {\n    src.removeEventListener(type, proxy, listener.capture);\n  } else if (src.detachEvent) {\n    src.detachEvent(goog.events.getOnString_(type), proxy);\n  } else if (src.addListener && src.removeListener) {\n    src.removeListener(proxy);\n  }\n  goog.events.listenerCountEstimate_--;\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  // TODO(chrishenry): Try to remove this conditional and execute the\n  // first branch always. This should be safe.\n  if (listenerMap) {\n    listenerMap.removeByKey(listener);\n    if (listenerMap.getTypeCount() == 0) {\n      // Null the src, just because this is simple to do (and useful\n      // for IE <= 7).\n      listenerMap.src = null;\n      // We don't use delete here because IE does not allow delete\n      // on a window object.\n      src[goog.events.LISTENER_MAP_PROP_] = null;\n    }\n  } else {\n    /** @type {!goog.events.Listener} */ (listener).markAsRemoved();\n  }\n\n  return true;\n};\n\n\n/**\n * Removes an event listener which was added with listenWithWrapper().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n *     listening to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to remove.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase of the\n *     event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n */\ngoog.events.unlistenWithWrapper = function(\n    src, wrapper, listener, opt_capt, opt_handler) {\n  wrapper.unlisten(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes all listeners from an object. You can also optionally\n * remove listeners of a particular type.\n *\n * @param {Object|undefined} obj Object to remove listeners from. Must be an\n *     EventTarget or a goog.events.Listenable.\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove.\n *     Default is all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.removeAll = function(obj, opt_type) {\n  // TODO(chrishenry): Change the type of obj to\n  // (!EventTarget|!goog.events.Listenable).\n\n  if (!obj) {\n    return 0;\n  }\n\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {?} */ (obj).removeAllListeners(opt_type);\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (obj));\n  if (!listenerMap) {\n    return 0;\n  }\n\n  var count = 0;\n  var typeStr = opt_type && opt_type.toString();\n  for (var type in listenerMap.listeners) {\n    if (!typeStr || type == typeStr) {\n      // Clone so that we don't need to worry about unlistenByKey\n      // changing the content of the ListenerMap.\n      var listeners = listenerMap.listeners[type].concat();\n      for (var i = 0; i < listeners.length; ++i) {\n        if (goog.events.unlistenByKey(listeners[i])) {\n          ++count;\n        }\n      }\n    }\n  }\n  return count;\n};\n\n\n/**\n * Gets the listeners for a given object, type and capture phase.\n *\n * @param {Object} obj Object to get listeners for.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Capture phase?.\n * @return {Array<!goog.events.Listener>} Array of listener objects.\n */\ngoog.events.getListeners = function(obj, type, capture) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {!goog.events.Listenable} */ (obj).getListeners(\n        type, capture);\n  } else {\n    if (!obj) {\n      // TODO(chrishenry): We should tighten the API to accept\n      // !EventTarget|goog.events.Listenable, and add an assertion here.\n      return [];\n    }\n\n    var listenerMap = goog.events.getListenerMap_(\n        /** @type {!EventTarget} */ (obj));\n    return listenerMap ? listenerMap.getListeners(type, capture) : [];\n  }\n};\n\n\n/**\n * Gets the goog.events.Listener for the event or null if no such listener is\n * in use.\n *\n * @param {EventTarget|goog.events.Listenable} src The target from\n *     which to get listeners.\n * @param {?string|!goog.events.EventId<EVENTOBJ>} type The type of the event.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to get.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n *                            whether the listener is fired during the\n *                            capture or bubble phase of the event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n * @template EVENTOBJ\n */\ngoog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {\n  // TODO(chrishenry): Change type from ?string to string, or add assertion.\n  type = /** @type {string} */ (type);\n  listener = goog.events.wrapListener(listener);\n  var capture = !!opt_capt;\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return src.getListener(type, listener, capture, opt_handler);\n  }\n\n  if (!src) {\n    // TODO(chrishenry): We should tighten the API to only accept\n    // non-null objects, or add an assertion here.\n    return null;\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  if (listenerMap) {\n    return listenerMap.getListener(type, listener, capture, opt_handler);\n  }\n  return null;\n};\n\n\n/**\n * Returns whether an event target has any active listeners matching the\n * specified signature. If either the type or capture parameters are\n * unspecified, the function will match on the remaining criteria.\n *\n * @param {EventTarget|goog.events.Listenable} obj Target to get\n *     listeners for.\n * @param {string|!goog.events.EventId=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble-phase\n *     listeners.\n * @return {boolean} Whether an event target has one or more listeners matching\n *     the requested type and/or capture phase.\n */\ngoog.events.hasListener = function(obj, opt_type, opt_capture) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return obj.hasListener(opt_type, opt_capture);\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (obj));\n  return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);\n};\n\n\n/**\n * Provides a nice string showing the normalized event objects public members\n * @param {Object} e Event Object.\n * @return {string} String of the public members of the normalized event object.\n */\ngoog.events.expose = function(e) {\n  var str = [];\n  for (var key in e) {\n    if (e[key] && e[key].id) {\n      str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')');\n    } else {\n      str.push(key + ' = ' + e[key]);\n    }\n  }\n  return str.join('\\n');\n};\n\n\n/**\n * Returns a string with on prepended to the specified type. This is used for IE\n * which expects \"on\" to be prepended. This function caches the string in order\n * to avoid extra allocations in steady state.\n * @param {string} type Event type.\n * @return {string} The type string with 'on' prepended.\n * @private\n */\ngoog.events.getOnString_ = function(type) {\n  if (type in goog.events.onStringMap_) {\n    return goog.events.onStringMap_[type];\n  }\n  return goog.events.onStringMap_[type] = goog.events.onString_ + type;\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase\n *\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n */\ngoog.events.fireListeners = function(obj, type, capture, eventObject) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {!goog.events.Listenable} */ (obj).fireListeners(\n        type, capture, eventObject);\n  }\n\n  return goog.events.fireListeners_(obj, type, capture, eventObject);\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase.\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n * @private\n */\ngoog.events.fireListeners_ = function(obj, type, capture, eventObject) {\n  /** @type {boolean} */\n  var retval = true;\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {EventTarget} */ (obj));\n  if (listenerMap) {\n    // TODO(chrishenry): Original code avoids array creation when there\n    // is no listener, so we do the same. If this optimization turns\n    // out to be not required, we can replace this with\n    // listenerMap.getListeners(type, capture) instead, which is simpler.\n    var listenerArray = listenerMap.listeners[type.toString()];\n    if (listenerArray) {\n      listenerArray = listenerArray.concat();\n      for (var i = 0; i < listenerArray.length; i++) {\n        var listener = listenerArray[i];\n        // We might not have a listener if the listener was removed.\n        if (listener && listener.capture == capture && !listener.removed) {\n          var result = goog.events.fireListener(listener, eventObject);\n          retval = retval && (result !== false);\n        }\n      }\n    }\n  }\n  return retval;\n};\n\n\n/**\n * Fires a listener with a set of arguments\n *\n * @param {goog.events.Listener} listener The listener object to call.\n * @param {Object} eventObject The event object to pass to the listener.\n * @return {*} Result of listener.\n */\ngoog.events.fireListener = function(listener, eventObject) {\n  var listenerFn = listener.listener;\n  var listenerHandler = listener.handler || listener.src;\n\n  if (listener.callOnce) {\n    goog.events.unlistenByKey(listener);\n  }\n  return listenerFn.call(listenerHandler, eventObject);\n};\n\n\n/**\n * Gets the total number of listeners currently in the system.\n * @return {number} Number of listeners.\n * @deprecated This returns estimated count, now that Closure no longer\n * stores a central listener registry. We still return an estimation\n * to keep existing listener-related tests passing. In the near future,\n * this function will be removed.\n */\ngoog.events.getTotalListenerCount = function() {\n  return goog.events.listenerCountEstimate_;\n};\n\n\n/**\n * Dispatches an event (or event like object) and calls all listeners\n * listening for events of this type. The type of the event is decided by the\n * type property on the event object.\n *\n * If any of the listeners returns false OR calls preventDefault then this\n * function will return false.  If one of the capture listeners calls\n * stopPropagation, then the bubble listeners won't fire.\n *\n * @param {goog.events.Listenable} src The event target.\n * @param {goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n *     if any of the handlers returns false) this will also return false.\n *     If there are no handlers, or if all handlers return true, this returns\n *     true.\n */\ngoog.events.dispatchEvent = function(src, e) {\n  goog.asserts.assert(\n      goog.events.Listenable.isImplementedBy(src),\n      'Can not use goog.events.dispatchEvent with ' +\n          'non-goog.events.Listenable instance.');\n  return src.dispatchEvent(e);\n};\n\n\n/**\n * Installs exception protection for the browser event entry point using the\n * given error handler.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n *     protect the entry point.\n */\ngoog.events.protectBrowserEventEntryPoint = function(errorHandler) {\n  goog.events.handleBrowserEvent_ =\n      errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_);\n};\n\n\n/**\n * Handles an event and dispatches it to the correct listeners. This\n * function is a proxy for the real listener the user specified.\n *\n * @param {goog.events.Listener} listener The listener object.\n * @param {Event=} opt_evt Optional event object that gets passed in via the\n *     native event handlers.\n * @return {*} Result of the event handler.\n * @this {EventTarget} The object or Element that fired the event.\n * @private\n */\ngoog.events.handleBrowserEvent_ = function(listener, opt_evt) {\n  if (listener.removed) {\n    return true;\n  }\n\n  // Synthesize event propagation if the browser does not support W3C\n  // event model.\n  if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n    var ieEvent = opt_evt ||\n        /** @type {Event} */ (goog.getObjectByName('window.event'));\n    var evt = new goog.events.BrowserEvent(ieEvent, this);\n    /** @type {*} */\n    var retval = true;\n\n    if (goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.ON) {\n      // If we have not marked this event yet, we should perform capture\n      // simulation.\n      if (!goog.events.isMarkedIeEvent_(ieEvent)) {\n        goog.events.markIeEvent_(ieEvent);\n\n        var ancestors = [];\n        for (var parent = evt.currentTarget; parent;\n             parent = parent.parentNode) {\n          ancestors.push(parent);\n        }\n\n        // Fire capture listeners.\n        var type = listener.type;\n        for (var i = ancestors.length - 1;\n             !evt.hasPropagationStopped() && i >= 0; i--) {\n          evt.currentTarget = ancestors[i];\n          var result =\n              goog.events.fireListeners_(ancestors[i], type, true, evt);\n          retval = retval && result;\n        }\n\n        // Fire bubble listeners.\n        //\n        // We can technically rely on IE to perform bubble event\n        // propagation. However, it turns out that IE fires events in\n        // opposite order of attachEvent registration, which broke\n        // some code and tests that rely on the order. (While W3C DOM\n        // Level 2 Events TR leaves the event ordering unspecified,\n        // modern browsers and W3C DOM Level 3 Events Working Draft\n        // actually specify the order as the registration order.)\n        for (var i = 0; !evt.hasPropagationStopped() && i < ancestors.length;\n             i++) {\n          evt.currentTarget = ancestors[i];\n          var result =\n              goog.events.fireListeners_(ancestors[i], type, false, evt);\n          retval = retval && result;\n        }\n      }\n    } else {\n      retval = goog.events.fireListener(listener, evt);\n    }\n    return retval;\n  }\n\n  // Otherwise, simply fire the listener.\n  return goog.events.fireListener(\n      listener, new goog.events.BrowserEvent(opt_evt, this));\n};\n\n\n/**\n * This is used to mark the IE event object so we do not do the Closure pass\n * twice for a bubbling event.\n * @param {Event} e The IE browser event.\n * @private\n */\ngoog.events.markIeEvent_ = function(e) {\n  // Only the keyCode and the returnValue can be changed. We use keyCode for\n  // non keyboard events.\n  // event.returnValue is a bit more tricky. It is undefined by default. A\n  // boolean false prevents the default action. In a window.onbeforeunload and\n  // the returnValue is non undefined it will be alerted. However, we will only\n  // modify the returnValue for keyboard events. We can get a problem if non\n  // closure events sets the keyCode or the returnValue\n\n  var useReturnValue = false;\n\n  if (e.keyCode == 0) {\n    // We cannot change the keyCode in case that srcElement is input[type=file].\n    // We could test that that is the case but that would allocate 3 objects.\n    // If we use try/catch we will only allocate extra objects in the case of a\n    // failure.\n\n    try {\n      e.keyCode = -1;\n      return;\n    } catch (ex) {\n      useReturnValue = true;\n    }\n  }\n\n  if (useReturnValue ||\n      /** @type {boolean|undefined} */ (e.returnValue) == undefined) {\n    e.returnValue = true;\n  }\n};\n\n\n/**\n * This is used to check if an IE event has already been handled by the Closure\n * system so we do not do the Closure pass twice for a bubbling event.\n * @param {Event} e  The IE browser event.\n * @return {boolean} True if the event object has been marked.\n * @private\n */\ngoog.events.isMarkedIeEvent_ = function(e) {\n  return e.keyCode < 0 || e.returnValue != undefined;\n};\n\n\n/**\n * Counter to create unique event ids.\n * @private {number}\n */\ngoog.events.uniqueIdCounter_ = 0;\n\n\n/**\n * Creates a unique event id.\n *\n * @param {string} identifier The identifier.\n * @return {string} A unique identifier.\n * @idGenerator {unique}\n */\ngoog.events.getUniqueId = function(identifier) {\n  return identifier + '_' + goog.events.uniqueIdCounter_++;\n};\n\n\n/**\n * @param {EventTarget} src The source object.\n * @return {goog.events.ListenerMap} A listener map for the given\n *     source object, or null if none exists.\n * @private\n */\ngoog.events.getListenerMap_ = function(src) {\n  var listenerMap = src[goog.events.LISTENER_MAP_PROP_];\n  // IE serializes the property as well (e.g. when serializing outer\n  // HTML). So we must check that the value is of the correct type.\n  return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;\n};\n\n\n/**\n * Expando property for listener function wrapper for Object with\n * handleEvent.\n * @private @const {string}\n */\ngoog.events.LISTENER_WRAPPER_PROP_ =\n    '__closure_events_fn_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * @param {Object|Function} listener The listener function or an\n *     object that contains handleEvent method.\n * @return {!Function} Either the original function or a function that\n *     calls obj.handleEvent. If the same listener is passed to this\n *     function more than once, the same function is guaranteed to be\n *     returned.\n */\ngoog.events.wrapListener = function(listener) {\n  goog.asserts.assert(listener, 'Listener can not be null.');\n\n  if (goog.isFunction(listener)) {\n    return listener;\n  }\n\n  goog.asserts.assert(\n      listener.handleEvent, 'An object listener must have handleEvent method.');\n  if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {\n    listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {\n      return /** @type {?} */ (listener).handleEvent(e);\n    };\n  }\n  return listener[goog.events.LISTENER_WRAPPER_PROP_];\n};\n\n\n// Register the browser event handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) {\n      goog.events.handleBrowserEvent_ =\n          transformer(goog.events.handleBrowserEvent_);\n    });\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A disposable implementation of a custom\n * listenable/event target. See also: documentation for\n * `goog.events.Listenable`.\n *\n * @see ../demos/eventtarget.html\n * @see goog.events.Listenable\n */\n\ngoog.provide('goog.events.EventTarget');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.asserts');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\ngoog.require('goog.object');\n\n\n\n/**\n * An implementation of `goog.events.Listenable` with full W3C\n * EventTarget-like support (capture/bubble mechanism, stopping event\n * propagation, preventing default actions).\n *\n * You may subclass this class to turn your class into a Listenable.\n *\n * Unless propagation is stopped, an event dispatched by an\n * EventTarget will bubble to the parent returned by\n * `getParentEventTarget`. To set the parent, call\n * `setParentEventTarget`. Subclasses that don't support\n * changing the parent can override the setter to throw an error.\n *\n * Example usage:\n * <pre>\n *   var source = new goog.events.EventTarget();\n *   function handleEvent(e) {\n *     alert('Type: ' + e.type + '; Target: ' + e.target);\n *   }\n *   source.listen('foo', handleEvent);\n *   // Or: goog.events.listen(source, 'foo', handleEvent);\n *   ...\n *   source.dispatchEvent('foo');  // will call handleEvent\n *   ...\n *   source.unlisten('foo', handleEvent);\n *   // Or: goog.events.unlisten(source, 'foo', handleEvent);\n * </pre>\n *\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.events.Listenable}\n */\ngoog.events.EventTarget = function() {\n  goog.Disposable.call(this);\n\n  /**\n   * Maps of event type to an array of listeners.\n   * @private {!goog.events.ListenerMap}\n   */\n  this.eventTargetListeners_ = new goog.events.ListenerMap(this);\n\n  /**\n   * The object to use for event.target. Useful when mixing in an\n   * EventTarget to another object.\n   * @private {!Object}\n   */\n  this.actualEventTarget_ = this;\n\n  /**\n   * Parent event target, used during event bubbling.\n   *\n   * TODO(chrishenry): Change this to goog.events.Listenable. This\n   * currently breaks people who expect getParentEventTarget to return\n   * goog.events.EventTarget.\n   *\n   * @private {?goog.events.EventTarget}\n   */\n  this.parentEventTarget_ = null;\n};\ngoog.inherits(goog.events.EventTarget, goog.Disposable);\ngoog.events.Listenable.addImplementation(goog.events.EventTarget);\n\n\n/**\n * An artificial cap on the number of ancestors you can have. This is mainly\n * for loop detection.\n * @const {number}\n * @private\n */\ngoog.events.EventTarget.MAX_ANCESTORS_ = 1000;\n\n\n/**\n * Returns the parent of this event target to use for bubbling.\n *\n * @return {goog.events.EventTarget} The parent EventTarget or null if\n *     there is no parent.\n * @override\n */\ngoog.events.EventTarget.prototype.getParentEventTarget = function() {\n  return this.parentEventTarget_;\n};\n\n\n/**\n * Sets the parent of this event target to use for capture/bubble\n * mechanism.\n * @param {goog.events.EventTarget} parent Parent listenable (null if none).\n */\ngoog.events.EventTarget.prototype.setParentEventTarget = function(parent) {\n  this.parentEventTarget_ = parent;\n};\n\n\n/**\n * Adds an event listener to the event target. The same handler can only be\n * added once per the type. Even if you add the same handler multiple times\n * using the same type then it will only be called once when the event is\n * dispatched.\n *\n * @param {string|!goog.events.EventId} type The type of the event to listen for\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n *     to handle the event. The handler can also be an object that implements\n *     the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase\n *     of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n *     the listener.\n * @deprecated Use `#listen` instead, when possible. Otherwise, use\n *     `goog.events.listen` if you are passing Object\n *     (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.addEventListener = function(\n    type, handler, opt_capture, opt_handlerScope) {\n  goog.events.listen(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/**\n * Removes an event listener from the event target. The handler must be the\n * same object as the one added. If the handler has not been added then\n * nothing is done.\n *\n * @param {string} type The type of the event to listen for.\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n *     to handle the event. The handler can also be an object that implements\n *     the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase\n *     of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n *     the listener.\n * @deprecated Use `#unlisten` instead, when possible. Otherwise, use\n *     `goog.events.unlisten` if you are passing Object\n *     (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.removeEventListener = function(\n    type, handler, opt_capture, opt_handlerScope) {\n  goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.dispatchEvent = function(e) {\n  this.assertInitialized_();\n\n  var ancestorsTree, ancestor = this.getParentEventTarget();\n  if (ancestor) {\n    ancestorsTree = [];\n    var ancestorCount = 1;\n    for (; ancestor; ancestor = ancestor.getParentEventTarget()) {\n      ancestorsTree.push(ancestor);\n      goog.asserts.assert(\n          (++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_),\n          'infinite loop');\n    }\n  }\n\n  return goog.events.EventTarget.dispatchEventInternal_(\n      this.actualEventTarget_, e, ancestorsTree);\n};\n\n\n/**\n * Removes listeners from this object.  Classes that extend EventTarget may\n * need to override this method in order to remove references to DOM Elements\n * and additional listeners.\n * @override\n * @protected\n */\ngoog.events.EventTarget.prototype.disposeInternal = function() {\n  goog.events.EventTarget.superClass_.disposeInternal.call(this);\n\n  this.removeAllListeners();\n  this.parentEventTarget_ = null;\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listen = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  this.assertInitialized_();\n  return this.eventTargetListeners_.add(\n      String(type), listener, false /* callOnce */, opt_useCapture,\n      opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listenOnce = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  return this.eventTargetListeners_.add(\n      String(type), listener, true /* callOnce */, opt_useCapture,\n      opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlisten = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  return this.eventTargetListeners_.remove(\n      String(type), listener, opt_useCapture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlistenByKey = function(key) {\n  return this.eventTargetListeners_.removeByKey(key);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {\n  // TODO(chrishenry): Previously, removeAllListeners can be called on\n  // uninitialized EventTarget, so we preserve that behavior. We\n  // should remove this when usages that rely on that fact are purged.\n  if (!this.eventTargetListeners_) {\n    return 0;\n  }\n  return this.eventTargetListeners_.removeAll(opt_type);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.fireListeners = function(\n    type, capture, eventObject) {\n  // TODO(chrishenry): Original code avoids array creation when there\n  // is no listener, so we do the same. If this optimization turns\n  // out to be not required, we can replace this with\n  // getListeners(type, capture) instead, which is simpler.\n  var listenerArray = this.eventTargetListeners_.listeners[String(type)];\n  if (!listenerArray) {\n    return true;\n  }\n  listenerArray = listenerArray.concat();\n\n  var rv = true;\n  for (var i = 0; i < listenerArray.length; ++i) {\n    var listener = listenerArray[i];\n    // We might not have a listener if the listener was removed.\n    if (listener && !listener.removed && listener.capture == capture) {\n      var listenerFn = listener.listener;\n      var listenerHandler = listener.handler || listener.src;\n\n      if (listener.callOnce) {\n        this.unlistenByKey(listener);\n      }\n      rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;\n    }\n  }\n\n  return rv && !eventObject.defaultPrevented;\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.getListeners = function(type, capture) {\n  return this.eventTargetListeners_.getListeners(String(type), capture);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.getListener = function(\n    type, listener, capture, opt_listenerScope) {\n  return this.eventTargetListeners_.getListener(\n      String(type), listener, capture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.hasListener = function(\n    opt_type, opt_capture) {\n  var id = (opt_type !== undefined) ? String(opt_type) : undefined;\n  return this.eventTargetListeners_.hasListener(id, opt_capture);\n};\n\n\n/**\n * Sets the target to be used for `event.target` when firing\n * event. Mainly used for testing. For example, see\n * `goog.testing.events.mixinListenable`.\n * @param {!Object} target The target.\n */\ngoog.events.EventTarget.prototype.setTargetForTesting = function(target) {\n  this.actualEventTarget_ = target;\n};\n\n\n/**\n * Asserts that the event target instance is initialized properly.\n * @private\n */\ngoog.events.EventTarget.prototype.assertInitialized_ = function() {\n  goog.asserts.assert(\n      this.eventTargetListeners_,\n      'Event target is not initialized. Did you call the superclass ' +\n          '(goog.events.EventTarget) constructor?');\n};\n\n\n/**\n * Dispatches the given event on the ancestorsTree.\n *\n * @param {!Object} target The target to dispatch on.\n * @param {goog.events.Event|Object|string} e The event object.\n * @param {Array<goog.events.Listenable>=} opt_ancestorsTree The ancestors\n *     tree of the target, in reverse order from the closest ancestor\n *     to the root event target. May be null if the target has no ancestor.\n * @return {boolean} If anyone called preventDefault on the event object (or\n *     if any of the listeners returns false) this will also return false.\n * @private\n */\ngoog.events.EventTarget.dispatchEventInternal_ = function(\n    target, e, opt_ancestorsTree) {\n  /** @suppress {missingProperties} */\n  var type = e.type || /** @type {string} */ (e);\n\n  // If accepting a string or object, create a custom event object so that\n  // preventDefault and stopPropagation work with the event.\n  if (typeof e === 'string') {\n    e = new goog.events.Event(e, target);\n  } else if (!(e instanceof goog.events.Event)) {\n    var oldEvent = e;\n    e = new goog.events.Event(type, target);\n    goog.object.extend(e, oldEvent);\n  } else {\n    e.target = e.target || target;\n  }\n\n  var rv = true, currentTarget;\n\n  // Executes all capture listeners on the ancestors, if any.\n  if (opt_ancestorsTree) {\n    for (var i = opt_ancestorsTree.length - 1;\n         !e.hasPropagationStopped() && i >= 0; i--) {\n      currentTarget = e.currentTarget = opt_ancestorsTree[i];\n      rv = currentTarget.fireListeners(type, true, e) && rv;\n    }\n  }\n\n  // Executes capture and bubble listeners on the target.\n  if (!e.hasPropagationStopped()) {\n    currentTarget = /** @type {?} */ (e.currentTarget = target);\n    rv = currentTarget.fireListeners(type, true, e) && rv;\n    if (!e.hasPropagationStopped()) {\n      rv = currentTarget.fireListeners(type, false, e) && rv;\n    }\n  }\n\n  // Executes all bubble listeners on the ancestors, if any.\n  if (opt_ancestorsTree) {\n    for (i = 0; !e.hasPropagationStopped() && i < opt_ancestorsTree.length;\n         i++) {\n      currentTarget = e.currentTarget = opt_ancestorsTree[i];\n      rv = currentTarget.fireListeners(type, false, e) && rv;\n    }\n  }\n\n  return rv;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Generics method for collection-like classes and objects.\n *\n *\n * This file contains functions to work with collections. It supports using\n * Map, Set, Array and Object and other classes that implement collection-like\n * methods.\n * @suppress {strictMissingProperties}\n */\n\n\ngoog.provide('goog.structs');\n\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n// We treat an object as a dictionary if it has getKeys or it is an object that\n// isn't arrayLike.\n\n\n/**\n * Returns the number of values in the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {number} The number of values in the collection-like object.\n */\ngoog.structs.getCount = function(col) {\n  if (col.getCount && typeof col.getCount == 'function') {\n    return col.getCount();\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return col.length;\n  }\n  return goog.object.getCount(col);\n};\n\n\n/**\n * Returns the values of the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {!Array<?>} The values in the collection-like object.\n */\ngoog.structs.getValues = function(col) {\n  if (col.getValues && typeof col.getValues == 'function') {\n    return col.getValues();\n  }\n  if (typeof col === 'string') {\n    return col.split('');\n  }\n  if (goog.isArrayLike(col)) {\n    var rv = [];\n    var l = col.length;\n    for (var i = 0; i < l; i++) {\n      rv.push(col[i]);\n    }\n    return rv;\n  }\n  return goog.object.getValues(col);\n};\n\n\n/**\n * Returns the keys of the collection. Some collections have no notion of\n * keys/indexes and this function will return undefined in those cases.\n * @param {Object} col The collection-like object.\n * @return {!Array|undefined} The keys in the collection.\n */\ngoog.structs.getKeys = function(col) {\n  if (col.getKeys && typeof col.getKeys == 'function') {\n    return col.getKeys();\n  }\n  // if we have getValues but no getKeys we know this is a key-less collection\n  if (col.getValues && typeof col.getValues == 'function') {\n    return undefined;\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    var rv = [];\n    var l = col.length;\n    for (var i = 0; i < l; i++) {\n      rv.push(i);\n    }\n    return rv;\n  }\n\n  return goog.object.getKeys(col);\n};\n\n\n/**\n * Whether the collection contains the given value. This is O(n) and uses\n * equals (==) to test the existence.\n * @param {Object} col The collection-like object.\n * @param {*} val The value to check for.\n * @return {boolean} True if the map contains the value.\n */\ngoog.structs.contains = function(col, val) {\n  if (col.contains && typeof col.contains == 'function') {\n    return col.contains(val);\n  }\n  if (col.containsValue && typeof col.containsValue == 'function') {\n    return col.containsValue(val);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.contains(/** @type {!Array<?>} */ (col), val);\n  }\n  return goog.object.containsValue(col, val);\n};\n\n\n/**\n * Whether the collection is empty.\n * @param {Object} col The collection-like object.\n * @return {boolean} True if empty.\n */\ngoog.structs.isEmpty = function(col) {\n  if (col.isEmpty && typeof col.isEmpty == 'function') {\n    return col.isEmpty();\n  }\n\n  // We do not use goog.string.isEmptyOrWhitespace because here we treat the\n  // string as\n  // collection and as such even whitespace matters\n\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.isEmpty(/** @type {!Array<?>} */ (col));\n  }\n  return goog.object.isEmpty(col);\n};\n\n\n/**\n * Removes all the elements from the collection.\n * @param {Object} col The collection-like object.\n */\ngoog.structs.clear = function(col) {\n  // NOTE(arv): This should not contain strings because strings are immutable\n  if (col.clear && typeof col.clear == 'function') {\n    col.clear();\n  } else if (goog.isArrayLike(col)) {\n    goog.array.clear(/** @type {IArrayLike<?>} */ (col));\n  } else {\n    goog.object.clear(col);\n  }\n};\n\n\n/**\n * Calls a function for each value in a collection. The function takes\n * three arguments; the value, the key and the collection.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):?} f The function to call for every value.\n *     This function takes\n *     3 arguments (the value, the key or undefined if the collection has no\n *     notion of keys, and the collection) and the return value is irrelevant.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n *     within `f`.\n * @template T,S\n * @deprecated Use a more specific method, e.g. goog.array.forEach,\n *     goog.object.forEach, or for-of.\n */\ngoog.structs.forEach = function(col, f, opt_obj) {\n  if (col.forEach && typeof col.forEach == 'function') {\n    col.forEach(f, opt_obj);\n  } else if (goog.isArrayLike(col) || typeof col === 'string') {\n    goog.array.forEach(/** @type {!Array<?>} */ (col), f, opt_obj);\n  } else {\n    var keys = goog.structs.getKeys(col);\n    var values = goog.structs.getValues(col);\n    var l = values.length;\n    for (var i = 0; i < l; i++) {\n      f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col);\n    }\n  }\n};\n\n\n/**\n * Calls a function for every value in the collection. When a call returns true,\n * adds the value to a new collection (Array is returned by default).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes\n *     3 arguments (the value, the key or undefined if the collection has no\n *     notion of keys, and the collection) and should return a Boolean. If the\n *     return value is true the value is added to the result collection. If it\n *     is false the value is not included.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n *     within `f`.\n * @return {!Object|!Array<?>} A new collection where the passed values are\n *     present. If col is a key-less collection an array is returned.  If col\n *     has keys and values a plain old JS object is returned.\n * @template T,S\n */\ngoog.structs.filter = function(col, f, opt_obj) {\n  if (typeof col.filter == 'function') {\n    return col.filter(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.filter(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n\n  var rv;\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  if (keys) {\n    rv = {};\n    for (var i = 0; i < l; i++) {\n      if (f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col)) {\n        rv[keys[i]] = values[i];\n      }\n    }\n  } else {\n    // We should not use goog.array.filter here since we want to make sure that\n    // the index is undefined as well as make sure that col is passed to the\n    // function.\n    rv = [];\n    for (var i = 0; i < l; i++) {\n      if (f.call(opt_obj, values[i], undefined, col)) {\n        rv.push(values[i]);\n      }\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Calls a function for every value in the collection and adds the result into a\n * new collection (defaults to creating a new Array).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):V} f The function to call for every value.\n *     This function takes 3 arguments (the value, the key or undefined if the\n *     collection has no notion of keys, and the collection) and should return\n *     something. The result will be used as the value in the new collection.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {!Object<V>|!Array<V>} A new collection with the new values.  If\n *     col is a key-less collection an array is returned.  If col has keys and\n *     values a plain old JS object is returned.\n * @template T,S,V\n */\ngoog.structs.map = function(col, f, opt_obj) {\n  if (typeof col.map == 'function') {\n    return col.map(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.map(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n\n  var rv;\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  if (keys) {\n    rv = {};\n    for (var i = 0; i < l; i++) {\n      rv[keys[i]] = f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col);\n    }\n  } else {\n    // We should not use goog.array.map here since we want to make sure that\n    // the index is undefined as well as make sure that col is passed to the\n    // function.\n    rv = [];\n    for (var i = 0; i < l; i++) {\n      rv[i] = f.call(/** @type {?} */ (opt_obj), values[i], undefined, col);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Calls f for each value in a collection. If any call returns true this returns\n * true (without checking the rest). If all returns false this returns false.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes 3 arguments (the value, the key or undefined\n *     if the collection has no notion of keys, and the collection) and should\n *     return a boolean.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {boolean} True if any value passes the test.\n * @template T,S\n */\ngoog.structs.some = function(col, f, opt_obj) {\n  if (typeof col.some == 'function') {\n    return col.some(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.some(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  for (var i = 0; i < l; i++) {\n    if (f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Calls f for each value in a collection. If all calls return true this return\n * true this returns true. If any returns false this returns false at this point\n *  and does not continue to check the remaining values.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes 3 arguments (the value, the key or\n *     undefined if the collection has no notion of keys, and the collection)\n *     and should return a boolean.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {boolean} True if all key-value pairs pass the test.\n * @template T,S\n */\ngoog.structs.every = function(col, f, opt_obj) {\n  if (typeof col.every == 'function') {\n    return col.every(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.every(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  for (var i = 0; i < l; i++) {\n    if (!f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n      return false;\n    }\n  }\n  return true;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Datastructure: Hash Map.\n *\n *\n * This file contains an implementation of a Map structure. It implements a lot\n * of the methods used in goog.structs so those functions work on hashes. This\n * is best suited for complex key types. For simple keys such as numbers and\n * strings consider using the lighter-weight utilities in goog.object.\n */\n\n\ngoog.provide('goog.structs.Map');\n\ngoog.require('goog.iter.Iterator');\ngoog.require('goog.iter.StopIteration');\n\n\n\n/**\n * Class for Hash Map datastructure.\n * @param {*=} opt_map Map or Object to initialize the map with.\n * @param {...*} var_args If 2 or more arguments are present then they\n *     will be used as key-value pairs.\n * @constructor\n * @template K, V\n * @deprecated This type is misleading: use ES6 Map instead.\n */\ngoog.structs.Map = function(opt_map, var_args) {\n\n  /**\n   * Underlying JS object used to implement the map.\n   * @private {!Object}\n   */\n  this.map_ = {};\n\n  /**\n   * An array of keys. This is necessary for two reasons:\n   *   1. Iterating the keys using for (var key in this.map_) allocates an\n   *      object for every key in IE which is really bad for IE6 GC perf.\n   *   2. Without a side data structure, we would need to escape all the keys\n   *      as that would be the only way we could tell during iteration if the\n   *      key was an internal key or a property of the object.\n   *\n   * This array can contain deleted keys so it's necessary to check the map\n   * as well to see if the key is still in the map (this doesn't require a\n   * memory allocation in IE).\n   * @private {!Array<string>}\n   */\n  this.keys_ = [];\n\n  /**\n   * The number of key value pairs in the map.\n   * @private {number}\n   */\n  this.count_ = 0;\n\n  /**\n   * Version used to detect changes while iterating.\n   * @private {number}\n   */\n  this.version_ = 0;\n\n  var argLength = arguments.length;\n\n  if (argLength > 1) {\n    if (argLength % 2) {\n      throw new Error('Uneven number of arguments');\n    }\n    for (var i = 0; i < argLength; i += 2) {\n      this.set(arguments[i], arguments[i + 1]);\n    }\n  } else if (opt_map) {\n    this.addAll(/** @type {!Object} */ (opt_map));\n  }\n};\n\n\n/**\n * @return {number} The number of key-value pairs in the map.\n */\ngoog.structs.Map.prototype.getCount = function() {\n  return this.count_;\n};\n\n\n/**\n * Returns the values of the map.\n * @return {!Array<V>} The values in the map.\n */\ngoog.structs.Map.prototype.getValues = function() {\n  this.cleanupKeysArray_();\n\n  var rv = [];\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    rv.push(this.map_[key]);\n  }\n  return rv;\n};\n\n\n/**\n * Returns the keys of the map.\n * @return {!Array<string>} Array of string values.\n */\ngoog.structs.Map.prototype.getKeys = function() {\n  this.cleanupKeysArray_();\n  return /** @type {!Array<string>} */ (this.keys_.concat());\n};\n\n\n/**\n * Whether the map contains the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the map contains the key.\n */\ngoog.structs.Map.prototype.containsKey = function(key) {\n  return goog.structs.Map.hasKey_(this.map_, key);\n};\n\n\n/**\n * Whether the map contains the given value. This is O(n).\n * @param {V} val The value to check for.\n * @return {boolean} Whether the map contains the value.\n */\ngoog.structs.Map.prototype.containsValue = function(val) {\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Whether this map is equal to the argument map.\n * @param {goog.structs.Map} otherMap The map against which to test equality.\n * @param {function(V, V): boolean=} opt_equalityFn Optional equality function\n *     to test equality of values. If not specified, this will test whether\n *     the values contained in each map are identical objects.\n * @return {boolean} Whether the maps are equal.\n */\ngoog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {\n  if (this === otherMap) {\n    return true;\n  }\n\n  if (this.count_ != otherMap.getCount()) {\n    return false;\n  }\n\n  var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;\n\n  this.cleanupKeysArray_();\n  for (var key, i = 0; key = this.keys_[i]; i++) {\n    if (!equalityFn(this.get(key), otherMap.get(key))) {\n      return false;\n    }\n  }\n\n  return true;\n};\n\n\n/**\n * Default equality test for values.\n * @param {*} a The first value.\n * @param {*} b The second value.\n * @return {boolean} Whether a and b reference the same object.\n */\ngoog.structs.Map.defaultEquals = function(a, b) {\n  return a === b;\n};\n\n\n/**\n * @return {boolean} Whether the map is empty.\n */\ngoog.structs.Map.prototype.isEmpty = function() {\n  return this.count_ == 0;\n};\n\n\n/**\n * Removes all key-value pairs from the map.\n */\ngoog.structs.Map.prototype.clear = function() {\n  this.map_ = {};\n  this.keys_.length = 0;\n  this.count_ = 0;\n  this.version_ = 0;\n};\n\n\n/**\n * Removes a key-value pair based on the key. This is O(logN) amortized due to\n * updating the keys array whenever the count becomes half the size of the keys\n * in the keys array.\n * @param {*} key  The key to remove.\n * @return {boolean} Whether object was removed.\n */\ngoog.structs.Map.prototype.remove = function(key) {\n  if (goog.structs.Map.hasKey_(this.map_, key)) {\n    delete this.map_[key];\n    this.count_--;\n    this.version_++;\n\n    // clean up the keys array if the threshold is hit\n    if (this.keys_.length > 2 * this.count_) {\n      this.cleanupKeysArray_();\n    }\n\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Cleans up the temp keys array by removing entries that are no longer in the\n * map.\n * @private\n */\ngoog.structs.Map.prototype.cleanupKeysArray_ = function() {\n  if (this.count_ != this.keys_.length) {\n    // First remove keys that are no longer in the map.\n    var srcIndex = 0;\n    var destIndex = 0;\n    while (srcIndex < this.keys_.length) {\n      var key = this.keys_[srcIndex];\n      if (goog.structs.Map.hasKey_(this.map_, key)) {\n        this.keys_[destIndex++] = key;\n      }\n      srcIndex++;\n    }\n    this.keys_.length = destIndex;\n  }\n\n  if (this.count_ != this.keys_.length) {\n    // If the count still isn't correct, that means we have duplicates. This can\n    // happen when the same key is added and removed multiple times. Now we have\n    // to allocate one extra Object to remove the duplicates. This could have\n    // been done in the first pass, but in the common case, we can avoid\n    // allocating an extra object by only doing this when necessary.\n    var seen = {};\n    var srcIndex = 0;\n    var destIndex = 0;\n    while (srcIndex < this.keys_.length) {\n      var key = this.keys_[srcIndex];\n      if (!(goog.structs.Map.hasKey_(seen, key))) {\n        this.keys_[destIndex++] = key;\n        seen[key] = 1;\n      }\n      srcIndex++;\n    }\n    this.keys_.length = destIndex;\n  }\n};\n\n\n/**\n * Returns the value for the given key.  If the key is not found and the default\n * value is not given this will return `undefined`.\n * @param {*} key The key to get the value for.\n * @param {DEFAULT=} opt_val The value to return if no item is found for the\n *     given key, defaults to undefined.\n * @return {V|DEFAULT} The value for the given key.\n * @template DEFAULT\n */\ngoog.structs.Map.prototype.get = function(key, opt_val) {\n  if (goog.structs.Map.hasKey_(this.map_, key)) {\n    return this.map_[key];\n  }\n  return opt_val;\n};\n\n\n/**\n * Adds a key-value pair to the map.\n * @param {*} key The key.\n * @param {V} value The value to add.\n * @return {*} Some subclasses return a value.\n */\ngoog.structs.Map.prototype.set = function(key, value) {\n  if (!(goog.structs.Map.hasKey_(this.map_, key))) {\n    this.count_++;\n    // TODO(johnlenz): This class lies, it claims to return an array of string\n    // keys, but instead returns the original object used.\n    this.keys_.push(/** @type {?} */ (key));\n    // Only change the version if we add a new key.\n    this.version_++;\n  }\n  this.map_[key] = value;\n};\n\n\n/**\n * Adds multiple key-value pairs from another goog.structs.Map or Object.\n * @param {?Object} map Object containing the data to add.\n */\ngoog.structs.Map.prototype.addAll = function(map) {\n  if (map instanceof goog.structs.Map) {\n    var keys = map.getKeys();\n    for (var i = 0; i < keys.length; i++) {\n      this.set(keys[i], map.get(keys[i]));\n    }\n  } else {\n    for (var key in map) {\n      this.set(key, map[key]);\n    }\n  }\n};\n\n\n/**\n * Calls the given function on each entry in the map.\n * @param {function(this:T, V, K, goog.structs.Map<K,V>)} f\n * @param {T=} opt_obj The value of \"this\" inside f.\n * @template T\n */\ngoog.structs.Map.prototype.forEach = function(f, opt_obj) {\n  var keys = this.getKeys();\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var value = this.get(key);\n    f.call(opt_obj, value, key, this);\n  }\n};\n\n\n/**\n * Clones a map and returns a new map.\n * @return {!goog.structs.Map} A new map with the same key-value pairs.\n */\ngoog.structs.Map.prototype.clone = function() {\n  return new goog.structs.Map(this);\n};\n\n\n/**\n * Returns a new map in which all the keys and values are interchanged\n * (keys become values and values become keys). If multiple keys map to the\n * same value, the chosen transposed value is implementation-dependent.\n *\n * It acts very similarly to {goog.object.transpose(Object)}.\n *\n * @return {!goog.structs.Map} The transposed map.\n */\ngoog.structs.Map.prototype.transpose = function() {\n  var transposed = new goog.structs.Map();\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    var value = this.map_[key];\n    transposed.set(value, key);\n  }\n\n  return transposed;\n};\n\n\n/**\n * @return {!Object} Object representation of the map.\n */\ngoog.structs.Map.prototype.toObject = function() {\n  this.cleanupKeysArray_();\n  var obj = {};\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    obj[key] = this.map_[key];\n  }\n  return obj;\n};\n\n\n/**\n * Returns an iterator that iterates over the keys in the map.  Removal of keys\n * while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the keys in the map.\n */\ngoog.structs.Map.prototype.getKeyIterator = function() {\n  return this.__iterator__(true);\n};\n\n\n/**\n * Returns an iterator that iterates over the values in the map.  Removal of\n * keys while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the values in the map.\n */\ngoog.structs.Map.prototype.getValueIterator = function() {\n  return this.__iterator__(false);\n};\n\n\n/**\n * Returns an iterator that iterates over the values or the keys in the map.\n * This throws an exception if the map was mutated since the iterator was\n * created.\n * @param {boolean=} opt_keys True to iterate over the keys. False to iterate\n *     over the values.  The default value is false.\n * @return {!goog.iter.Iterator} An iterator over the values or keys in the map.\n */\ngoog.structs.Map.prototype.__iterator__ = function(opt_keys) {\n  // Clean up keys to minimize the risk of iterating over dead keys.\n  this.cleanupKeysArray_();\n\n  var i = 0;\n  var version = this.version_;\n  var selfObj = this;\n\n  var newIter = new goog.iter.Iterator;\n  newIter.next = function() {\n    if (version != selfObj.version_) {\n      throw new Error('The map has changed since the iterator was created');\n    }\n    if (i >= selfObj.keys_.length) {\n      throw goog.iter.StopIteration;\n    }\n    var key = selfObj.keys_[i++];\n    return opt_keys ? key : selfObj.map_[key];\n  };\n  return newIter;\n};\n\n\n/**\n * Safe way to test for hasOwnProperty.  It even allows testing for\n * 'hasOwnProperty'.\n * @param {!Object} obj The object to test for presence of the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the object has the key.\n * @private\n */\ngoog.structs.Map.hasKey_ = function(obj, key) {\n  return Object.prototype.hasOwnProperty.call(obj, key);\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class for parsing and formatting URIs.\n *\n * Use goog.Uri(string) to parse a URI string.  Use goog.Uri.create(...) to\n * create a new instance of the goog.Uri object from Uri parts.\n *\n * e.g: <code>var myUri = new goog.Uri(window.location);</code>\n *\n * Implements RFC 3986 for parsing/formatting URIs.\n * http://www.ietf.org/rfc/rfc3986.txt\n *\n * Some changes have been made to the interface (more like .NETs), though the\n * internal representation is now of un-encoded parts, this will change the\n * behavior slightly.\n */\n\ngoog.provide('goog.Uri');\ngoog.provide('goog.Uri.QueryData');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.structs.Map');\ngoog.require('goog.uri.utils');\ngoog.require('goog.uri.utils.ComponentIndex');\ngoog.require('goog.uri.utils.StandardQueryParam');\n\n\n\n/**\n * This class contains setters and getters for the parts of the URI.\n * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part\n * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the\n * decoded path, <code>/foo bar</code>.\n *\n * Reserved characters (see RFC 3986 section 2.2) can be present in\n * their percent-encoded form in scheme, domain, and path URI components and\n * will not be auto-decoded. For example:\n * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will\n * return <code>relative/path%2fto/resource</code>.\n *\n * The constructor accepts an optional unparsed, raw URI string.  The parser\n * is relaxed, so special characters that aren't escaped but don't cause\n * ambiguities will not cause parse failures.\n *\n * All setters return <code>this</code> and so may be chained, a la\n * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.\n *\n * @param {*=} opt_uri Optional string URI to parse\n *        (use goog.Uri.create() to create a URI from parts), or if\n *        a goog.Uri is passed, a clone is created.\n * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore\n * the case of the parameter name.\n *\n * @throws URIError If opt_uri is provided and URI is malformed (that is,\n *     if decodeURIComponent fails on any of the URI components).\n * @constructor\n * @struct\n */\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\n  /**\n   * Scheme such as \"http\".\n   * @private {string}\n   */\n  this.scheme_ = '';\n\n  /**\n   * User credentials in the form \"username:password\".\n   * @private {string}\n   */\n  this.userInfo_ = '';\n\n  /**\n   * Domain part, e.g. \"www.google.com\".\n   * @private {string}\n   */\n  this.domain_ = '';\n\n  /**\n   * Port, e.g. 8080.\n   * @private {?number}\n   */\n  this.port_ = null;\n\n  /**\n   * Path, e.g. \"/tests/img.png\".\n   * @private {string}\n   */\n  this.path_ = '';\n\n  /**\n   * The fragment without the #.\n   * @private {string}\n   */\n  this.fragment_ = '';\n\n  /**\n   * Whether or not this Uri should be treated as Read Only.\n   * @private {boolean}\n   */\n  this.isReadOnly_ = false;\n\n  /**\n   * Whether or not to ignore case when comparing query params.\n   * @private {boolean}\n   */\n  this.ignoreCase_ = false;\n\n  /**\n   * Object representing query data.\n   * @private {!goog.Uri.QueryData}\n   */\n  this.queryData_;\n\n  // Parse in the uri string\n  var m;\n  if (opt_uri instanceof goog.Uri) {\n    this.ignoreCase_ = (opt_ignoreCase !== undefined) ? opt_ignoreCase :\n                                                        opt_uri.getIgnoreCase();\n    this.setScheme(opt_uri.getScheme());\n    this.setUserInfo(opt_uri.getUserInfo());\n    this.setDomain(opt_uri.getDomain());\n    this.setPort(opt_uri.getPort());\n    this.setPath(opt_uri.getPath());\n    this.setQueryData(opt_uri.getQueryData().clone());\n    this.setFragment(opt_uri.getFragment());\n  } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\n    this.ignoreCase_ = !!opt_ignoreCase;\n\n    // Set the parts -- decoding as we do so.\n    // COMPATIBILITY NOTE - In IE, unmatched fields may be empty strings,\n    // whereas in other browsers they will be undefined.\n    this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);\n    this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);\n    this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);\n    this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\n    this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);\n    this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);\n    this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);\n\n  } else {\n    this.ignoreCase_ = !!opt_ignoreCase;\n    this.queryData_ = new goog.Uri.QueryData(null, null, this.ignoreCase_);\n  }\n};\n\n\n/**\n * Parameter name added to stop caching.\n * @type {string}\n */\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\n\n\n/**\n * @return {string} The string form of the url.\n * @override\n */\ngoog.Uri.prototype.toString = function() {\n  var out = [];\n\n  var scheme = this.getScheme();\n  if (scheme) {\n    out.push(\n        goog.Uri.encodeSpecialChars_(\n            scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n        ':');\n  }\n\n  var domain = this.getDomain();\n  if (domain || scheme == 'file') {\n    out.push('//');\n\n    var userInfo = this.getUserInfo();\n    if (userInfo) {\n      out.push(\n          goog.Uri.encodeSpecialChars_(\n              userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n          '@');\n    }\n\n    out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\n\n    var port = this.getPort();\n    if (port != null) {\n      out.push(':', String(port));\n    }\n  }\n\n  var path = this.getPath();\n  if (path) {\n    if (this.hasDomain() && path.charAt(0) != '/') {\n      out.push('/');\n    }\n    out.push(\n        goog.Uri.encodeSpecialChars_(\n            path, path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ :\n                                          goog.Uri.reDisallowedInRelativePath_,\n            true));\n  }\n\n  var query = this.getEncodedQuery();\n  if (query) {\n    out.push('?', query);\n  }\n\n  var fragment = this.getFragment();\n  if (fragment) {\n    out.push(\n        '#', goog.Uri.encodeSpecialChars_(\n                 fragment, goog.Uri.reDisallowedInFragment_));\n  }\n  return out.join('');\n};\n\n\n/**\n * Resolves the given relative URI (a goog.Uri object), using the URI\n * represented by this instance as the base URI.\n *\n * There are several kinds of relative URIs:<br>\n * 1. foo - replaces the last part of the path, the whole query and fragment<br>\n * 2. /foo - replaces the path, the query and fragment<br>\n * 3. //foo - replaces everything from the domain on.  foo is a domain name<br>\n * 4. ?foo - replace the query and fragment<br>\n * 5. #foo - replace the fragment only\n *\n * Additionally, if relative URI has a non-empty path, all \"..\" and \".\"\n * segments will be resolved, as described in RFC 3986.\n *\n * @param {!goog.Uri} relativeUri The relative URI to resolve.\n * @return {!goog.Uri} The resolved URI.\n */\ngoog.Uri.prototype.resolve = function(relativeUri) {\n\n  var absoluteUri = this.clone();\n\n  // we satisfy these conditions by looking for the first part of relativeUri\n  // that is not blank and applying defaults to the rest\n\n  var overridden = relativeUri.hasScheme();\n\n  if (overridden) {\n    absoluteUri.setScheme(relativeUri.getScheme());\n  } else {\n    overridden = relativeUri.hasUserInfo();\n  }\n\n  if (overridden) {\n    absoluteUri.setUserInfo(relativeUri.getUserInfo());\n  } else {\n    overridden = relativeUri.hasDomain();\n  }\n\n  if (overridden) {\n    absoluteUri.setDomain(relativeUri.getDomain());\n  } else {\n    overridden = relativeUri.hasPort();\n  }\n\n  var path = relativeUri.getPath();\n  if (overridden) {\n    absoluteUri.setPort(relativeUri.getPort());\n  } else {\n    overridden = relativeUri.hasPath();\n    if (overridden) {\n      // resolve path properly\n      if (path.charAt(0) != '/') {\n        // path is relative\n        if (this.hasDomain() && !this.hasPath()) {\n          // RFC 3986, section 5.2.3, case 1\n          path = '/' + path;\n        } else {\n          // RFC 3986, section 5.2.3, case 2\n          var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');\n          if (lastSlashIndex != -1) {\n            path = absoluteUri.getPath().substr(0, lastSlashIndex + 1) + path;\n          }\n        }\n      }\n      path = goog.Uri.removeDotSegments(path);\n    }\n  }\n\n  if (overridden) {\n    absoluteUri.setPath(path);\n  } else {\n    overridden = relativeUri.hasQuery();\n  }\n\n  if (overridden) {\n    absoluteUri.setQueryData(relativeUri.getQueryData().clone());\n  } else {\n    overridden = relativeUri.hasFragment();\n  }\n\n  if (overridden) {\n    absoluteUri.setFragment(relativeUri.getFragment());\n  }\n\n  return absoluteUri;\n};\n\n\n/**\n * Clones the URI instance.\n * @return {!goog.Uri} New instance of the URI object.\n */\ngoog.Uri.prototype.clone = function() {\n  return new goog.Uri(this);\n};\n\n\n/**\n * @return {string} The encoded scheme/protocol for the URI.\n */\ngoog.Uri.prototype.getScheme = function() {\n  return this.scheme_;\n};\n\n\n/**\n * Sets the scheme/protocol.\n * @throws URIError If opt_decode is true and newScheme is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newScheme New scheme value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\n  this.enforceReadOnly();\n  this.scheme_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\n\n  // remove an : at the end of the scheme so somebody can pass in\n  // window.location.protocol\n  if (this.scheme_) {\n    this.scheme_ = this.scheme_.replace(/:$/, '');\n  }\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the scheme has been set.\n */\ngoog.Uri.prototype.hasScheme = function() {\n  return !!this.scheme_;\n};\n\n\n/**\n * @return {string} The decoded user info.\n */\ngoog.Uri.prototype.getUserInfo = function() {\n  return this.userInfo_;\n};\n\n\n/**\n * Sets the userInfo.\n * @throws URIError If opt_decode is true and newUserInfo is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newUserInfo New userInfo value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\n  this.enforceReadOnly();\n  this.userInfo_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the user info has been set.\n */\ngoog.Uri.prototype.hasUserInfo = function() {\n  return !!this.userInfo_;\n};\n\n\n/**\n * @return {string} The decoded domain.\n */\ngoog.Uri.prototype.getDomain = function() {\n  return this.domain_;\n};\n\n\n/**\n * Sets the domain.\n * @throws URIError If opt_decode is true and newDomain is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newDomain New domain value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\n  this.enforceReadOnly();\n  this.domain_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the domain has been set.\n */\ngoog.Uri.prototype.hasDomain = function() {\n  return !!this.domain_;\n};\n\n\n/**\n * @return {?number} The port number.\n */\ngoog.Uri.prototype.getPort = function() {\n  return this.port_;\n};\n\n\n/**\n * Sets the port number.\n * @param {*} newPort Port number. Will be explicitly casted to a number.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPort = function(newPort) {\n  this.enforceReadOnly();\n\n  if (newPort) {\n    newPort = Number(newPort);\n    if (isNaN(newPort) || newPort < 0) {\n      throw new Error('Bad port number ' + newPort);\n    }\n    this.port_ = newPort;\n  } else {\n    this.port_ = null;\n  }\n\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the port has been set.\n */\ngoog.Uri.prototype.hasPort = function() {\n  return this.port_ != null;\n};\n\n\n/**\n  * @return {string} The decoded path.\n */\ngoog.Uri.prototype.getPath = function() {\n  return this.path_;\n};\n\n\n/**\n * Sets the path.\n * @throws URIError If opt_decode is true and newPath is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newPath New path value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\n  this.enforceReadOnly();\n  this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the path has been set.\n */\ngoog.Uri.prototype.hasPath = function() {\n  return !!this.path_;\n};\n\n\n/**\n * @return {boolean} Whether the query string has been set.\n */\ngoog.Uri.prototype.hasQuery = function() {\n  return this.queryData_.toString() !== '';\n};\n\n\n/**\n * Sets the query data.\n * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n *     Applies only if queryData is a string.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\n  this.enforceReadOnly();\n\n  if (queryData instanceof goog.Uri.QueryData) {\n    this.queryData_ = queryData;\n    this.queryData_.setIgnoreCase(this.ignoreCase_);\n  } else {\n    if (!opt_decode) {\n      // QueryData accepts encoded query string, so encode it if\n      // opt_decode flag is not true.\n      queryData = goog.Uri.encodeSpecialChars_(\n          queryData, goog.Uri.reDisallowedInQuery_);\n    }\n    this.queryData_ = new goog.Uri.QueryData(queryData, null, this.ignoreCase_);\n  }\n\n  return this;\n};\n\n\n/**\n * Sets the URI query.\n * @param {string} newQuery New query value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\n  return this.setQueryData(newQuery, opt_decode);\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getEncodedQuery = function() {\n  return this.queryData_.toString();\n};\n\n\n/**\n * @return {string} The decoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getDecodedQuery = function() {\n  return this.queryData_.toDecodedString();\n};\n\n\n/**\n * Returns the query data.\n * @return {!goog.Uri.QueryData} QueryData object.\n */\ngoog.Uri.prototype.getQueryData = function() {\n  return this.queryData_;\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n *\n * Warning: This method, unlike other getter methods, returns encoded\n * value, instead of decoded one.\n */\ngoog.Uri.prototype.getQuery = function() {\n  return this.getEncodedQuery();\n};\n\n\n/**\n * Sets the value of the named query parameters, clearing previous values for\n * that key.\n *\n * @param {string} key The parameter to set.\n * @param {*} value The new value. Value does not need to be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValue = function(key, value) {\n  this.enforceReadOnly();\n  this.queryData_.set(key, value);\n  return this;\n};\n\n\n/**\n * Sets the values of the named query parameters, clearing previous values for\n * that key.  Not new values will currently be moved to the end of the query\n * string.\n *\n * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])\n * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>\n *\n * @param {string} key The parameter to set.\n * @param {*} values The new values. If values is a single\n *     string then it will be treated as the sole value. Values do not need to\n *     be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValues = function(key, values) {\n  this.enforceReadOnly();\n\n  if (!Array.isArray(values)) {\n    values = [String(values)];\n  }\n\n  this.queryData_.setValues(key, values);\n\n  return this;\n};\n\n\n/**\n * Returns the value<b>s</b> for a given cgi parameter as a list of decoded\n * query parameter values.\n * @param {string} name The parameter to get values for.\n * @return {!Array<?>} The values for a given cgi parameter as a list of\n *     decoded query parameter values.\n */\ngoog.Uri.prototype.getParameterValues = function(name) {\n  return this.queryData_.getValues(name);\n};\n\n\n/**\n * Returns the first value for a given cgi parameter or undefined if the given\n * parameter name does not appear in the query string.\n * @param {string} paramName Unescaped parameter name.\n * @return {string|undefined} The first value for a given cgi parameter or\n *     undefined if the given parameter name does not appear in the query\n *     string.\n */\ngoog.Uri.prototype.getParameterValue = function(paramName) {\n  return /** @type {string|undefined} */ (this.queryData_.get(paramName));\n};\n\n\n/**\n * @return {string} The URI fragment, not including the #.\n */\ngoog.Uri.prototype.getFragment = function() {\n  return this.fragment_;\n};\n\n\n/**\n * Sets the URI fragment.\n * @throws URIError If opt_decode is true and newFragment is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newFragment New fragment value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\n  this.enforceReadOnly();\n  this.fragment_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI has a fragment set.\n */\ngoog.Uri.prototype.hasFragment = function() {\n  return !!this.fragment_;\n};\n\n\n/**\n * Returns true if this has the same domain as that of uri2.\n * @param {!goog.Uri} uri2 The URI object to compare to.\n * @return {boolean} true if same domain; false otherwise.\n */\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\n  return ((!this.hasDomain() && !uri2.hasDomain()) ||\n          this.getDomain() == uri2.getDomain()) &&\n      ((!this.hasPort() && !uri2.hasPort()) ||\n       this.getPort() == uri2.getPort());\n};\n\n\n/**\n * Adds a random parameter to the Uri.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.makeUnique = function() {\n  this.enforceReadOnly();\n  this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\n\n  return this;\n};\n\n\n/**\n * Removes the named query parameter.\n *\n * @param {string} key The parameter to remove.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.removeParameter = function(key) {\n  this.enforceReadOnly();\n  this.queryData_.remove(key);\n  return this;\n};\n\n\n/**\n * Sets whether Uri is read only. If this goog.Uri is read-only,\n * enforceReadOnly_ will be called at the start of any function that may modify\n * this Uri.\n * @param {boolean} isReadOnly whether this goog.Uri should be read only.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\n  this.isReadOnly_ = isReadOnly;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI is read only.\n */\ngoog.Uri.prototype.isReadOnly = function() {\n  return this.isReadOnly_;\n};\n\n\n/**\n * Checks if this Uri has been marked as read only, and if so, throws an error.\n * This should be called whenever any modifying function is called.\n */\ngoog.Uri.prototype.enforceReadOnly = function() {\n  if (this.isReadOnly_) {\n    throw new Error('Tried to modify a read-only Uri');\n  }\n};\n\n\n/**\n * Sets whether to ignore case.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\n  this.ignoreCase_ = ignoreCase;\n  if (this.queryData_) {\n    this.queryData_.setIgnoreCase(ignoreCase);\n  }\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether to ignore case.\n */\ngoog.Uri.prototype.getIgnoreCase = function() {\n  return this.ignoreCase_;\n};\n\n\n//==============================================================================\n// Static members\n//==============================================================================\n\n\n/**\n * Creates a uri from the string form.  Basically an alias of new goog.Uri().\n * If a Uri object is passed to parse then it will return a clone of the object.\n *\n * @throws URIError If parsing the URI is malformed. The passed URI components\n *     should all be parseable by decodeURIComponent.\n * @param {*} uri Raw URI string or instance of Uri\n *     object.\n * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter\n * names in #getParameterValue.\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\n  return uri instanceof goog.Uri ? uri.clone() :\n                                   new goog.Uri(uri, opt_ignoreCase);\n};\n\n\n/**\n * Creates a new goog.Uri object from unencoded parts.\n *\n * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.\n * @param {?string=} opt_userInfo username:password.\n * @param {?string=} opt_domain www.google.com.\n * @param {?number=} opt_port 9830.\n * @param {?string=} opt_path /some/path/to/a/file.html.\n * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.\n * @param {?string=} opt_fragment The fragment without the #.\n * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in\n *     #getParameterValue.\n *\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.create = function(\n    opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query,\n    opt_fragment, opt_ignoreCase) {\n\n  var uri = new goog.Uri(null, opt_ignoreCase);\n\n  // Only set the parts if they are defined and not empty strings.\n  opt_scheme && uri.setScheme(opt_scheme);\n  opt_userInfo && uri.setUserInfo(opt_userInfo);\n  opt_domain && uri.setDomain(opt_domain);\n  opt_port && uri.setPort(opt_port);\n  opt_path && uri.setPath(opt_path);\n  opt_query && uri.setQueryData(opt_query);\n  opt_fragment && uri.setFragment(opt_fragment);\n\n  return uri;\n};\n\n\n/**\n * Resolves a relative Uri against a base Uri, accepting both strings and\n * Uri objects.\n *\n * @param {*} base Base Uri.\n * @param {*} rel Relative Uri.\n * @return {!goog.Uri} Resolved uri.\n */\ngoog.Uri.resolve = function(base, rel) {\n  if (!(base instanceof goog.Uri)) {\n    base = goog.Uri.parse(base);\n  }\n\n  if (!(rel instanceof goog.Uri)) {\n    rel = goog.Uri.parse(rel);\n  }\n\n  return base.resolve(rel);\n};\n\n\n/**\n * Removes dot segments in given path component, as described in\n * RFC 3986, section 5.2.4.\n *\n * @param {string} path A non-empty path component.\n * @return {string} Path component with removed dot segments.\n */\ngoog.Uri.removeDotSegments = function(path) {\n  if (path == '..' || path == '.') {\n    return '';\n\n  } else if (\n      !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) {\n    // This optimization detects uris which do not contain dot-segments,\n    // and as a consequence do not require any processing.\n    return path;\n\n  } else {\n    var leadingSlash = goog.string.startsWith(path, '/');\n    var segments = path.split('/');\n    var out = [];\n\n    for (var pos = 0; pos < segments.length;) {\n      var segment = segments[pos++];\n\n      if (segment == '.') {\n        if (leadingSlash && pos == segments.length) {\n          out.push('');\n        }\n      } else if (segment == '..') {\n        if (out.length > 1 || out.length == 1 && out[0] != '') {\n          out.pop();\n        }\n        if (leadingSlash && pos == segments.length) {\n          out.push('');\n        }\n      } else {\n        out.push(segment);\n        leadingSlash = true;\n      }\n    }\n\n    return out.join('/');\n  }\n};\n\n\n/**\n * Decodes a value or returns the empty string if it isn't defined or empty.\n * @throws URIError If decodeURIComponent fails to decode val.\n * @param {string|undefined} val Value to decode.\n * @param {boolean=} opt_preserveReserved If true, restricted characters will\n *     not be decoded.\n * @return {string} Decoded value.\n * @private\n */\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\n  // Don't use UrlDecode() here because val is not a query parameter.\n  if (!val) {\n    return '';\n  }\n\n  // decodeURI has the same output for '%2f' and '%252f'. We double encode %25\n  // so that we can distinguish between the 2 inputs. This is later undone by\n  // removeDoubleEncoding_.\n  return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) :\n                                decodeURIComponent(val);\n};\n\n\n/**\n * If unescapedPart is non null, then escapes any characters in it that aren't\n * valid characters in a url and also escapes any special characters that\n * appear in extra.\n *\n * @param {*} unescapedPart The string to encode.\n * @param {RegExp} extra A character set of characters in [\\01-\\177].\n * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent\n *     encoding.\n * @return {?string} null iff unescapedPart == null.\n * @private\n */\ngoog.Uri.encodeSpecialChars_ = function(\n    unescapedPart, extra, opt_removeDoubleEncoding) {\n  if (typeof unescapedPart === 'string') {\n    var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\n    if (opt_removeDoubleEncoding) {\n      // encodeURI double-escapes %XX sequences used to represent restricted\n      // characters in some URI components, remove the double escaping here.\n      encoded = goog.Uri.removeDoubleEncoding_(encoded);\n    }\n    return encoded;\n  }\n  return null;\n};\n\n\n/**\n * Converts a character in [\\01-\\177] to its unicode character equivalent.\n * @param {string} ch One character string.\n * @return {string} Encoded string.\n * @private\n */\ngoog.Uri.encodeChar_ = function(ch) {\n  var n = ch.charCodeAt(0);\n  return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);\n};\n\n\n/**\n * Removes double percent-encoding from a string.\n * @param  {string} doubleEncodedString String\n * @return {string} String with double encoding removed.\n * @private\n */\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\n  return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');\n};\n\n\n/**\n * Regular expression for characters that are disallowed in the scheme or\n * userInfo part of the URI.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\/\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in a relative path.\n * Colon is included due to RFC 3986 3.3.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInRelativePath_ = /[\\#\\?:]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in an absolute path.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInAbsolutePath_ = /[\\#\\?]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the query.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInQuery_ = /[\\#\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the fragment.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInFragment_ = /#/g;\n\n\n/**\n * Checks whether two URIs have the same domain.\n * @param {string} uri1String First URI string.\n * @param {string} uri2String Second URI string.\n * @return {boolean} true if the two URIs have the same domain; false otherwise.\n */\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\n  // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.\n  // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.\n  var pieces1 = goog.uri.utils.split(uri1String);\n  var pieces2 = goog.uri.utils.split(uri2String);\n  return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n      pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n      pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n      pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n\n/**\n * Class used to represent URI query parameters.  It is essentially a hash of\n * name-value pairs, though a name can be present more than once.\n *\n * Has the same interface as the collections in goog.structs.\n *\n * @param {?string=} opt_query Optional encoded query string to parse into\n *     the object.\n * @param {goog.Uri=} opt_uri Optional uri object that should have its\n *     cache invalidated when this object updates. Deprecated -- this\n *     is no longer required.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @constructor\n * @struct\n * @final\n */\ngoog.Uri.QueryData = function(opt_query, opt_uri, opt_ignoreCase) {\n  /**\n   * The map containing name/value or name/array-of-values pairs.\n   * May be null if it requires parsing from the query string.\n   *\n   * We need to use a Map because we cannot guarantee that the key names will\n   * not be problematic for IE.\n   *\n   * @private {?goog.structs.Map<string, !Array<*>>}\n   */\n  this.keyMap_ = null;\n\n  /**\n   * The number of params, or null if it requires computing.\n   * @private {?number}\n   */\n  this.count_ = null;\n\n  /**\n   * Encoded query string, or null if it requires computing from the key map.\n   * @private {?string}\n   */\n  this.encodedQuery_ = opt_query || null;\n\n  /**\n   * If true, ignore the case of the parameter name in #get.\n   * @private {boolean}\n   */\n  this.ignoreCase_ = !!opt_ignoreCase;\n};\n\n\n/**\n * If the underlying key map is not yet initialized, it parses the\n * query string and fills the map with parsed data.\n * @private\n */\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\n  if (!this.keyMap_) {\n    this.keyMap_ = new goog.structs.Map();\n    this.count_ = 0;\n    if (this.encodedQuery_) {\n      var self = this;\n      goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\n        self.add(goog.string.urlDecode(name), value);\n      });\n    }\n  }\n};\n\n\n/**\n * Creates a new query data instance from a map of names and values.\n *\n * @param {!goog.structs.Map<string, ?>|!Object} map Map of string parameter\n *     names to parameter value. If parameter value is an array, it is\n *     treated as if the key maps to each individual value in the\n *     array.\n * @param {goog.Uri=} opt_uri URI object that should have its cache\n *     invalidated when this object updates.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromMap = function(map, opt_uri, opt_ignoreCase) {\n  var keys = goog.structs.getKeys(map);\n  if (typeof keys == 'undefined') {\n    throw new Error('Keys are undefined');\n  }\n\n  var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);\n  var values = goog.structs.getValues(map);\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var value = values[i];\n    if (!Array.isArray(value)) {\n      queryData.add(key, value);\n    } else {\n      queryData.setValues(key, value);\n    }\n  }\n  return queryData;\n};\n\n\n/**\n * Creates a new query data instance from parallel arrays of parameter names\n * and values. Allows for duplicate parameter names. Throws an error if the\n * lengths of the arrays differ.\n *\n * @param {!Array<string>} keys Parameter names.\n * @param {!Array<?>} values Parameter values.\n * @param {goog.Uri=} opt_uri URI object that should have its cache\n *     invalidated when this object updates.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromKeysValues = function(\n    keys, values, opt_uri, opt_ignoreCase) {\n  if (keys.length != values.length) {\n    throw new Error('Mismatched lengths for keys/values');\n  }\n  var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);\n  for (var i = 0; i < keys.length; i++) {\n    queryData.add(keys[i], values[i]);\n  }\n  return queryData;\n};\n\n\n/**\n * @return {?number} The number of parameters.\n */\ngoog.Uri.QueryData.prototype.getCount = function() {\n  this.ensureKeyMapInitialized_();\n  return this.count_;\n};\n\n\n/**\n * Adds a key value pair.\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.add = function(key, value) {\n  this.ensureKeyMapInitialized_();\n  this.invalidateCache_();\n\n  key = this.getKeyName_(key);\n  var values = this.keyMap_.get(key);\n  if (!values) {\n    this.keyMap_.set(key, (values = []));\n  }\n  values.push(value);\n  this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n  return this;\n};\n\n\n/**\n * Removes all the params with the given key.\n * @param {string} key Name.\n * @return {boolean} Whether any parameter was removed.\n */\ngoog.Uri.QueryData.prototype.remove = function(key) {\n  this.ensureKeyMapInitialized_();\n\n  key = this.getKeyName_(key);\n  if (this.keyMap_.containsKey(key)) {\n    this.invalidateCache_();\n\n    // Decrement parameter count.\n    this.count_ =\n        goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n    return this.keyMap_.remove(key);\n  }\n  return false;\n};\n\n\n/**\n * Clears the parameters.\n */\ngoog.Uri.QueryData.prototype.clear = function() {\n  this.invalidateCache_();\n  this.keyMap_ = null;\n  this.count_ = 0;\n};\n\n\n/**\n * @return {boolean} Whether we have any parameters.\n */\ngoog.Uri.QueryData.prototype.isEmpty = function() {\n  this.ensureKeyMapInitialized_();\n  return this.count_ == 0;\n};\n\n\n/**\n * Whether there is a parameter with the given name\n * @param {string} key The parameter name to check for.\n * @return {boolean} Whether there is a parameter with the given name.\n */\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\n  this.ensureKeyMapInitialized_();\n  key = this.getKeyName_(key);\n  return this.keyMap_.containsKey(key);\n};\n\n\n/**\n * Whether there is a parameter with the given value.\n * @param {*} value The value to check for.\n * @return {boolean} Whether there is a parameter with the given value.\n */\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\n  // NOTE(arv): This solution goes through all the params even if it was the\n  // first param. We can get around this by not reusing code or by switching to\n  // iterators.\n  var vals = this.getValues();\n  return goog.array.contains(vals, value);\n};\n\n\n/**\n * Runs a callback on every key-value pair in the map, including duplicate keys.\n * This won't maintain original order when duplicate keys are interspersed (like\n * getKeys() / getValues()).\n * @param {function(this:SCOPE, ?, string, !goog.Uri.QueryData)} f\n * @param {SCOPE=} opt_scope The value of \"this\" inside f.\n * @template SCOPE\n */\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\n  this.ensureKeyMapInitialized_();\n  this.keyMap_.forEach(function(values, key) {\n    goog.array.forEach(values, function(value) {\n      f.call(opt_scope, value, key, this);\n    }, this);\n  }, this);\n};\n\n\n/**\n * Returns all the keys of the parameters. If a key is used multiple times\n * it will be included multiple times in the returned array\n * @return {!Array<string>} All the keys of the parameters.\n */\ngoog.Uri.QueryData.prototype.getKeys = function() {\n  this.ensureKeyMapInitialized_();\n  // We need to get the values to know how many keys to add.\n  var vals = this.keyMap_.getValues();\n  var keys = this.keyMap_.getKeys();\n  var rv = [];\n  for (var i = 0; i < keys.length; i++) {\n    var val = vals[i];\n    for (var j = 0; j < val.length; j++) {\n      rv.push(keys[i]);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Returns all the values of the parameters with the given name. If the query\n * data has no such key this will return an empty array. If no key is given\n * all values wil be returned.\n * @param {string=} opt_key The name of the parameter to get the values for.\n * @return {!Array<?>} All the values of the parameters with the given name.\n */\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\n  this.ensureKeyMapInitialized_();\n  var rv = [];\n  if (typeof opt_key === 'string') {\n    if (this.containsKey(opt_key)) {\n      rv = goog.array.concat(rv, this.keyMap_.get(this.getKeyName_(opt_key)));\n    }\n  } else {\n    // Return all values.\n    var values = this.keyMap_.getValues();\n    for (var i = 0; i < values.length; i++) {\n      rv = goog.array.concat(rv, values[i]);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Sets a key value pair and removes all other keys with the same value.\n *\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.set = function(key, value) {\n  this.ensureKeyMapInitialized_();\n  this.invalidateCache_();\n\n  // TODO(chrishenry): This could be better written as\n  // this.remove(key), this.add(key, value), but that would reorder\n  // the key (since the key is first removed and then added at the\n  // end) and we would have to fix unit tests that depend on key\n  // ordering.\n  key = this.getKeyName_(key);\n  if (this.containsKey(key)) {\n    this.count_ =\n        goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n  }\n  this.keyMap_.set(key, [value]);\n  this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n  return this;\n};\n\n\n/**\n * Returns the first value associated with the key. If the query data has no\n * such key this will return undefined or the optional default.\n * @param {string} key The name of the parameter to get the value for.\n * @param {*=} opt_default The default value to return if the query data\n *     has no such key.\n * @return {*} The first string value associated with the key, or opt_default\n *     if there's no value.\n */\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\n  if (!key) {\n    return opt_default;\n  }\n  var values = this.getValues(key);\n  return values.length > 0 ? String(values[0]) : opt_default;\n};\n\n\n/**\n * Sets the values for a key. If the key already exists, this will\n * override all of the existing values that correspond to the key.\n * @param {string} key The key to set values for.\n * @param {!Array<?>} values The values to set.\n */\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\n  this.remove(key);\n\n  if (values.length > 0) {\n    this.invalidateCache_();\n    this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\n    this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\n  }\n};\n\n\n/**\n * @return {string} Encoded query string.\n * @override\n */\ngoog.Uri.QueryData.prototype.toString = function() {\n  if (this.encodedQuery_) {\n    return this.encodedQuery_;\n  }\n\n  if (!this.keyMap_) {\n    return '';\n  }\n\n  var sb = [];\n\n  // In the past, we use this.getKeys() and this.getVals(), but that\n  // generates a lot of allocations as compared to simply iterating\n  // over the keys.\n  var keys = this.keyMap_.getKeys();\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var encodedKey = goog.string.urlEncode(key);\n    var val = this.getValues(key);\n    for (var j = 0; j < val.length; j++) {\n      var param = encodedKey;\n      // Ensure that null and undefined are encoded into the url as\n      // literal strings.\n      if (val[j] !== '') {\n        param += '=' + goog.string.urlEncode(val[j]);\n      }\n      sb.push(param);\n    }\n  }\n\n  return this.encodedQuery_ = sb.join('&');\n};\n\n\n/**\n * @throws URIError If URI is malformed (that is, if decodeURIComponent fails on\n *     any of the URI components).\n * @return {string} Decoded query string.\n */\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\n  return goog.Uri.decodeOrEmpty_(this.toString());\n};\n\n\n/**\n * Invalidate the cache.\n * @private\n */\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\n  this.encodedQuery_ = null;\n};\n\n\n/**\n * Removes all keys that are not in the provided list. (Modifies this object.)\n * @param {Array<string>} keys The desired keys.\n * @return {!goog.Uri.QueryData} a reference to this object.\n */\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\n  this.ensureKeyMapInitialized_();\n  this.keyMap_.forEach(function(value, key) {\n    if (!goog.array.contains(keys, key)) {\n      this.remove(key);\n    }\n  }, this);\n  return this;\n};\n\n\n/**\n * Clone the query data instance.\n * @return {!goog.Uri.QueryData} New instance of the QueryData object.\n */\ngoog.Uri.QueryData.prototype.clone = function() {\n  var rv = new goog.Uri.QueryData();\n  rv.encodedQuery_ = this.encodedQuery_;\n  if (this.keyMap_) {\n    rv.keyMap_ = this.keyMap_.clone();\n    rv.count_ = this.count_;\n  }\n  return rv;\n};\n\n\n/**\n * Helper function to get the key name from a JavaScript object. Converts\n * the object to a string, and to lower case if necessary.\n * @private\n * @param {*} arg The object to get a key name from.\n * @return {string} valid key name which can be looked up in #keyMap_.\n */\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\n  var keyName = String(arg);\n  if (this.ignoreCase_) {\n    keyName = keyName.toLowerCase();\n  }\n  return keyName;\n};\n\n\n/**\n * Ignore case in parameter names.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n */\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\n  var resetKeys = ignoreCase && !this.ignoreCase_;\n  if (resetKeys) {\n    this.ensureKeyMapInitialized_();\n    this.invalidateCache_();\n    this.keyMap_.forEach(function(value, key) {\n      var lowerCase = key.toLowerCase();\n      if (key != lowerCase) {\n        this.remove(key);\n        this.setValues(lowerCase, value);\n      }\n    }, this);\n  }\n  this.ignoreCase_ = ignoreCase;\n};\n\n\n/**\n * Extends a query data object with another query data or map like object. This\n * operates 'in-place', it does not create a new QueryData object.\n *\n * @param {...(?goog.Uri.QueryData|?goog.structs.Map<?, ?>|?Object)} var_args\n *     The object from which key value pairs will be copied. Note: does not\n *     accept null.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters.\n */\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\n  for (var i = 0; i < arguments.length; i++) {\n    var data = arguments[i];\n    goog.structs.forEach(\n        data, function(value, key) { this.add(key, value); }, this);\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview JSON utility functions.\n */\n\n\ngoog.provide('goog.json');\ngoog.provide('goog.json.Replacer');\ngoog.provide('goog.json.Reviver');\ngoog.provide('goog.json.Serializer');\n\n\n/**\n * @define {boolean} If true, use the native JSON parsing API.\n * NOTE: The default `goog.json.parse` implementation is able to handle\n * invalid JSON. JSPB used to produce invalid JSON which is not the case\n * anymore so this is safe to enable for parsing JSPB. Using native JSON is\n * faster and safer than the default implementation using `eval`.\n */\ngoog.json.USE_NATIVE_JSON = goog.define('goog.json.USE_NATIVE_JSON', false);\n\n/**\n * @define {boolean} If true, try the native JSON parsing API first. If it\n * fails, log an error and use `eval` instead. This is useful when\n * transitioning to `goog.json.USE_NATIVE_JSON`. The error logger needs to\n * be set by `goog.json.setErrorLogger`. If it is not set then the error\n * is ignored.\n */\ngoog.json.TRY_NATIVE_JSON = goog.define('goog.json.TRY_NATIVE_JSON', false);\n\n\n/**\n * Tests if a string is an invalid JSON string. This only ensures that we are\n * not using any invalid characters\n * @param {string} s The string to test.\n * @return {boolean} True if the input is a valid JSON string.\n */\ngoog.json.isValid = function(s) {\n  // All empty whitespace is not valid.\n  if (/^\\s*$/.test(s)) {\n    return false;\n  }\n\n  // This is taken from http://www.json.org/json2.js which is released to the\n  // public domain.\n  // Changes: We dissallow \\u2028 Line separator and \\u2029 Paragraph separator\n  // inside strings.  We also treat \\u2028 and \\u2029 as whitespace which they\n  // are in the RFC but IE and Safari does not match \\s to these so we need to\n  // include them in the reg exps in all places where whitespace is allowed.\n  // We allowed \\x7f inside strings because some tools don't escape it,\n  // e.g. http://www.json.org/java/org/json/JSONObject.java\n\n  // Parsing happens in three stages. In the first stage, we run the text\n  // against regular expressions that look for non-JSON patterns. We are\n  // especially concerned with '()' and 'new' because they can cause invocation,\n  // and '=' because it can cause mutation. But just to be safe, we want to\n  // reject all unexpected forms.\n\n  // We split the first stage into 4 regexp operations in order to work around\n  // crippling inefficiencies in IE's and Safari's regexp engines. First we\n  // replace all backslash pairs with '@' (a non-JSON character). Second, we\n  // replace all simple value tokens with ']' characters, but only when followed\n  // by a colon, comma, closing bracket or end of string. Third, we delete all\n  // open brackets that follow a colon or comma or that begin the text. Finally,\n  // we look to see that the remaining characters are only whitespace or ']' or\n  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n  // Don't make these static since they have the global flag.\n  const backslashesRe = /\\\\[\"\\\\\\/bfnrtu]/g;\n  const simpleValuesRe =\n      /(?:\"[^\"\\\\\\n\\r\\u2028\\u2029\\x00-\\x08\\x0a-\\x1f]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)[\\s\\u2028\\u2029]*(?=:|,|]|}|$)/g;\n  const openBracketsRe = /(?:^|:|,)(?:[\\s\\u2028\\u2029]*\\[)+/g;\n  const remainderRe = /^[\\],:{}\\s\\u2028\\u2029]*$/;\n\n  return remainderRe.test(\n      s.replace(backslashesRe, '@')\n          .replace(simpleValuesRe, ']')\n          .replace(openBracketsRe, ''));\n};\n\n/**\n * Logs a parsing error in `JSON.parse` solvable by using `eval`\n * if `goog.json.TRY_NATIVE_JSON` is enabled.\n * @private {function(string, !Error)} The first parameter is the error message,\n *     the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.errorLogger_ = goog.nullFunction;\n\n\n/**\n * Sets an error logger to use if there's a recoverable parsing error and\n * `goog.json.TRY_NATIVE_JSON` is enabled.\n * @param {function(string, !Error)} errorLogger The first parameter is the\n *     error message, the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.setErrorLogger = function(errorLogger) {\n  goog.json.errorLogger_ = errorLogger;\n};\n\n\n/**\n * Parses a JSON string and returns the result. This throws an exception if\n * the string is an invalid JSON string.\n *\n * Note that this is very slow on large strings. Use JSON.parse if possible.\n *\n * @param {*} s The JSON string to parse.\n * @throws Error if s is invalid JSON.\n * @return {Object} The object generated from the JSON string, or null.\n * @deprecated Use JSON.parse.\n */\ngoog.json.parse = goog.json.USE_NATIVE_JSON ?\n    /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :\n    function(s) {\n      let error;\n      if (goog.json.TRY_NATIVE_JSON) {\n        try {\n          return goog.global['JSON']['parse'](s);\n        } catch (ex) {\n          error = ex;\n        }\n      }\n      const o = String(s);\n      if (goog.json.isValid(o)) {\n\n        try {\n          const result = /** @type {?Object} */ (eval('(' + o + ')'));\n          if (error) {\n            goog.json.errorLogger_('Invalid JSON: ' + o, error);\n          }\n          return result;\n        } catch (ex) {\n        }\n      }\n      throw new Error('Invalid JSON string: ' + o);\n    };\n\n\n/**\n * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * TODO(nicksantos): Array should also be a valid replacer.\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Replacer;\n\n\n/**\n * JSON reviver, as defined in Section 15.12.2 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Reviver;\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @param {?goog.json.Replacer=} opt_replacer A replacer function\n *     called for each (key, value) pair that determines how the value\n *     should be serialized. By defult, this just returns the value\n *     and allows default serialization to kick in.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.serialize = goog.json.USE_NATIVE_JSON ?\n    /** @type {function(*, ?goog.json.Replacer=):string} */\n    (goog.global['JSON']['stringify']) :\n    function(object, opt_replacer) {\n      // NOTE(nicksantos): Currently, we never use JSON.stringify.\n      //\n      // The last time I evaluated this, JSON.stringify had subtle bugs and\n      // behavior differences on all browsers, and the performance win was not\n      // large enough to justify all the issues. This may change in the future\n      // as browser implementations get better.\n      //\n      // assertSerialize in json_test contains if branches for the cases\n      // that fail.\n      return new goog.json.Serializer(opt_replacer).serialize(object);\n    };\n\n\n\n/**\n * Class that is used to serialize JSON objects to a string.\n * @param {?goog.json.Replacer=} opt_replacer Replacer.\n * @constructor\n */\ngoog.json.Serializer = function(opt_replacer) {\n  /**\n   * @type {goog.json.Replacer|null|undefined}\n   * @private\n   */\n  this.replacer_ = opt_replacer;\n};\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.Serializer.prototype.serialize = function(object) {\n  const sb = [];\n  this.serializeInternal(object, sb);\n  return sb.join('');\n};\n\n\n/**\n * Serializes a generic value to a JSON string\n * @protected\n * @param {*} object The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @throws Error if there are loops in the object graph.\n */\ngoog.json.Serializer.prototype.serializeInternal = function(object, sb) {\n  if (object == null) {\n    // undefined == null so this branch covers undefined as well as null\n    sb.push('null');\n    return;\n  }\n\n  if (typeof object == 'object') {\n    if (Array.isArray(object)) {\n      this.serializeArray(object, sb);\n      return;\n    } else if (\n        object instanceof String || object instanceof Number ||\n        object instanceof Boolean) {\n      object = object.valueOf();\n      // Fall through to switch below.\n    } else {\n      this.serializeObject_(/** @type {!Object} */ (object), sb);\n      return;\n    }\n  }\n\n  switch (typeof object) {\n    case 'string':\n      this.serializeString_(object, sb);\n      break;\n    case 'number':\n      this.serializeNumber_(object, sb);\n      break;\n    case 'boolean':\n      sb.push(String(object));\n      break;\n    case 'function':\n      sb.push('null');\n      break;\n    default:\n      throw new Error('Unknown type: ' + typeof object);\n  }\n};\n\n\n/**\n * Character mappings used internally for goog.string.quote\n * @private\n * @type {!Object}\n */\ngoog.json.Serializer.charToJsonCharCache_ = {\n  '\\\"': '\\\\\"',\n  '\\\\': '\\\\\\\\',\n  '/': '\\\\/',\n  '\\b': '\\\\b',\n  '\\f': '\\\\f',\n  '\\n': '\\\\n',\n  '\\r': '\\\\r',\n  '\\t': '\\\\t',\n\n  '\\x0B': '\\\\u000b'  // '\\v' is not supported in JScript\n};\n\n\n/**\n * Regular expression used to match characters that need to be replaced.\n * The S60 browser has a bug where unicode characters are not matched by\n * regular expressions. The condition below detects such behaviour and\n * adjusts the regular expression accordingly.\n * @private\n * @type {!RegExp}\n */\ngoog.json.Serializer.charsToReplace_ = /\\uffff/.test('\\uffff') ?\n    /[\\\\\\\"\\x00-\\x1f\\x7f-\\uffff]/g :\n    /[\\\\\\\"\\x00-\\x1f\\x7f-\\xff]/g;\n\n\n/**\n * Serializes a string to a JSON string\n * @private\n * @param {string} s The string to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeString_ = function(s, sb) {\n  // The official JSON implementation does not work with international\n  // characters.\n  sb.push('\"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {\n    // caching the result improves performance by a factor 2-3\n    let rv = goog.json.Serializer.charToJsonCharCache_[c];\n    if (!rv) {\n      rv = '\\\\u' + (c.charCodeAt(0) | 0x10000).toString(16).substr(1);\n      goog.json.Serializer.charToJsonCharCache_[c] = rv;\n    }\n    return rv;\n  }), '\"');\n};\n\n\n/**\n * Serializes a number to a JSON string\n * @private\n * @param {number} n The number to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {\n  sb.push(isFinite(n) && !isNaN(n) ? String(n) : 'null');\n};\n\n\n/**\n * Serializes an array to a JSON string\n * @param {Array<string>} arr The array to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @protected\n */\ngoog.json.Serializer.prototype.serializeArray = function(arr, sb) {\n  const l = arr.length;\n  sb.push('[');\n  let sep = '';\n  for (let i = 0; i < l; i++) {\n    sb.push(sep);\n\n    const value = arr[i];\n    this.serializeInternal(\n        this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,\n        sb);\n\n    sep = ',';\n  }\n  sb.push(']');\n};\n\n\n/**\n * Serializes an object to a JSON string\n * @private\n * @param {!Object} obj The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {\n  sb.push('{');\n  let sep = '';\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      const value = obj[key];\n      // Skip functions.\n      if (typeof value != 'function') {\n        sb.push(sep);\n        this.serializeString_(key, sb);\n        sb.push(':');\n\n        this.serializeInternal(\n            this.replacer_ ? this.replacer_.call(obj, key, value) : value, sb);\n\n        sep = ',';\n      }\n    }\n  }\n  sb.push('}');\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines utility and helper functions.\n */\n\ngoog.provide('fireauth.util');\n\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.dom');\ngoog.require('goog.events');\ngoog.require('goog.events.EventType');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.json');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.require('goog.window');\n\n\n/** @suppress {duplicate} Suppress variable 'angular' first declared. */\nvar angular;\n\n/**\n * Checks whether the user agent is IE11.\n * @return {boolean} True if it is IE11.\n */\nfireauth.util.isIe11 = function() {\n  return goog.userAgent.IE &&\n      !!goog.userAgent.DOCUMENT_MODE &&\n      goog.userAgent.DOCUMENT_MODE == 11;\n};\n\n\n/**\n * Checks whether the user agent is IE10.\n * @return {boolean} True if it is IE10.\n */\nfireauth.util.isIe10 = function() {\n  return goog.userAgent.IE &&\n      !!goog.userAgent.DOCUMENT_MODE &&\n      goog.userAgent.DOCUMENT_MODE == 10;\n};\n\n\n/**\n * Checks whether the user agent is Edge.\n * @param {string} userAgent The browser user agent string.\n * @return {boolean} True if it is Edge.\n */\nfireauth.util.isEdge = function(userAgent) {\n  return /Edge\\/\\d+/.test(userAgent);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} Whether local storage is not synchronized between an iframe\n *     and a popup of the same domain.\n */\nfireauth.util.isLocalStorageNotSynchronized = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  return fireauth.util.isIe11() || fireauth.util.isEdge(ua);\n};\n\n\n/** @return {string} The current URL. */\nfireauth.util.getCurrentUrl = function() {\n  return (goog.global['window'] && goog.global['window']['location']['href']) ||\n      // Check for worker environments.\n      (self && self['location'] && self['location']['href']) || '';\n};\n\n\n/**\n * @param {string} requestUri The request URI to send in verifyAssertion\n *     request.\n * @return {string} The sanitized URI, in this case it undoes the hashbang\n *     angularJs routing changes to request URI.\n */\nfireauth.util.sanitizeRequestUri = function(requestUri) {\n  // If AngularJS is included.\n  if (typeof angular != 'undefined') {\n    // Remove hashbang modifications from URL.\n    requestUri = requestUri.replace('#/', '#').replace('#!/', '#');\n  }\n  return requestUri;\n};\n\n\n/**\n * @param {?string} url The target URL. When !url, redirects to a blank page.\n * @param {!Window=} opt_window The optional window to redirect to target URL.\n * @param {boolean=} opt_bypassCheck Whether to bypass check. Used for custom\n *     scheme redirects.\n */\nfireauth.util.goTo = function(url, opt_window, opt_bypassCheck) {\n  var win = opt_window || goog.global['window'];\n  // No URL, redirect to blank page.\n  var finalUrl = 'about:blank';\n  // Popping up a window and then assigning its URL seems to cause some weird\n  // error. Fixed by setting win.location.href for now in IE browsers.\n  // Bug was detected in Edge and IE9.\n  if (url && !opt_bypassCheck) {\n    // We cannot use goog.dom.safe.setLocationHref since it tries to read\n    // popup.location from a different origin, which is an error in IE.\n    // (In Chrome, popup.location is just an empty Location object)\n    finalUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));\n  }\n  win.location.href = finalUrl;\n};\n\n\n/**\n * @param {string} url The target URL.\n * @param {!Window=} opt_window The optional window to replace with target URL.\n * @param {boolean=} opt_bypassCheck Whether to bypass check. Used for custom\n *     scheme redirects.\n */\nfireauth.util.replaceCurrentUrl = function(url, opt_window, opt_bypassCheck) {\n  var win = opt_window || goog.global['window'];\n  if (!opt_bypassCheck) {\n    win.location.replace(\n        goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url)));\n  } else {\n    win.location.replace(url);\n  }\n};\n\n\n/**\n * Deep comparison of two objects.\n * @param {!Object} a The first object.\n * @param {!Object} b The second object.\n * @return {!Array<string>} The list of keys that are different between both\n *     objects provided.\n */\nfireauth.util.getKeyDiff = function(a, b) {\n  var diff = [];\n  for (var k in a) {\n    if (!(k in b)) {\n      diff.push(k);\n    } else if (typeof a[k] != typeof b[k]) {\n      diff.push(k);\n    } else if (typeof a[k] == 'object' && a[k] != null && b[k] != null) {\n      if (fireauth.util.getKeyDiff(\n          a[k], b[k]).length > 0) {\n        diff.push(k);\n      }\n    } else if (a[k] !== b[k]) {\n      diff.push(k);\n    }\n  }\n  for (var k in b) {\n    if (!(k in a)) {\n      diff.push(k);\n    }\n  }\n  return diff;\n};\n\n\n/**\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {?number} The Chrome version, null if the user agent is not Chrome.\n */\nfireauth.util.getChromeVersion = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  var browserName = fireauth.util.getBrowserName(ua);\n  // Confirm current browser is Chrome.\n  if (browserName != fireauth.util.BrowserName.CHROME) {\n    return null;\n  }\n  var matches = ua.match(/\\sChrome\\/(\\d+)/i);\n  if (matches && matches.length == 2) {\n    return parseInt(matches[1], 10);\n  }\n  return null;\n};\n\n\n/**\n * Detects CORS support.\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} True if the browser supports CORS.\n */\nfireauth.util.supportsCors = function(opt_userAgent) {\n  // Chrome 7 has CORS issues, pick 30 as upper limit.\n  var chromeVersion = fireauth.util.getChromeVersion(opt_userAgent);\n  if (chromeVersion && chromeVersion < 30) {\n    return false;\n  }\n  // Among all other supported browsers, only IE8 and IE9 don't support CORS.\n  return !goog.userAgent.IE || // Not IE.\n      !goog.userAgent.DOCUMENT_MODE || // No document mode == IE Edge.\n      goog.userAgent.DOCUMENT_MODE > 9;\n};\n\n\n/**\n * Detects whether browser is running on a mobile device.\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} True if the browser is running on a mobile device.\n */\nfireauth.util.isMobileBrowser = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  var uaLower = ua.toLowerCase();\n  // TODO: implement getBrowserName equivalent for OS.\n  if (uaLower.match(/android/) ||\n      uaLower.match(/webos/) ||\n      uaLower.match(/iphone|ipad|ipod/) ||\n      uaLower.match(/blackberry/) ||\n      uaLower.match(/windows phone/) ||\n      uaLower.match(/iemobile/)) {\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Closes the provided window.\n * @param {?Window=} opt_window The optional window to close. The current window\n *     is used if none is provided.\n */\nfireauth.util.closeWindow = function(opt_window) {\n  var win = opt_window || goog.global['window'];\n  // In some browsers, in certain cases after the window closes, as seen in\n  // Samsung Galaxy S3 Android 4.4.2 stock browser, the win object here is an\n  // empty object {}. Try to catch the failure and ignore it.\n  try {\n    win.close();\n  } catch(e) {}\n};\n\n\n/**\n * Opens a popup window.\n * @param {?string=} opt_url initial URL of the popup window\n * @param {string=} opt_name title of the popup\n * @param {?number=} opt_width width of the popup\n * @param {?number=} opt_height height of the popup\n * @return {?Window} Returns the window object that was opened. This returns\n *                   null if a popup blocker prevented the window from being\n *                   opened.\n */\nfireauth.util.popup = function(opt_url, opt_name, opt_width, opt_height) {\n  var width = opt_width || 500;\n  var height = opt_height || 600;\n  var top = (window.screen.availHeight - height) / 2;\n  var left = (window.screen.availWidth - width) / 2;\n  var options = {\n    'width': width,\n    'height': height,\n    'top': top > 0 ? top : 0,\n    'left': left > 0 ? left : 0,\n    'location': true,\n    'resizable': true,\n    'statusbar': true,\n    'toolbar': false\n  };\n  // Chrome iOS 7 and 8 is returning an undefined popup win when target is\n  // specified, even though the popup is not necessarily blocked.\n  var ua = fireauth.util.getUserAgentString().toLowerCase();\n  if (opt_name) {\n    options['target'] = opt_name;\n    // This will force a new window on each call, achieving the same effect as\n    // passing a random name on each call.\n    if (goog.string.contains(ua, 'crios/')) {\n      options['target'] = '_blank';\n    }\n  }\n  var browserName = fireauth.util.getBrowserName(\n      fireauth.util.getUserAgentString());\n  if (browserName == fireauth.util.BrowserName.FIREFOX) {\n    // Firefox complains when invalid URLs are popped out. Hacky way to bypass.\n    opt_url = opt_url || 'http://localhost';\n    // Firefox disables by default scrolling on popup windows, which can create\n    // issues when the user has many Google accounts, for instance.\n    options['scrollbars'] = true;\n  }\n  // about:blank getting sanitized causing browsers like IE/Edge to display\n  // brief error message before redirecting to handler.\n  var newWin = goog.window.open(opt_url || '', options);\n  if (newWin) {\n    // Flaky on IE edge, encapsulate with a try and catch.\n    try {\n      newWin.focus();\n    } catch (e) {}\n  }\n  return newWin;\n};\n\n\n/**\n * The default value for the popup wait cycle in ms.\n * @const {number}\n * @private\n */\nfireauth.util.POPUP_WAIT_CYCLE_MS_ = 2000;\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the popup requires a delay before closing itself.\n */\nfireauth.util.requiresPopupDelay = function(opt_userAgent) {\n  // TODO: remove this hack when CriOS behavior is fixed in iOS.\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  // Was observed in iOS 10.2 Chrome version 55.0.2883.79.\n  // Apply to Chrome 55+ iOS 10+ to ensure future Chrome versions or iOS 10\n  // minor updates do not suddenly resurface this bug. Revisit this check on\n  // next CriOS update.\n  var matches = ua.match(/OS (\\d+)_.*CriOS\\/(\\d+)\\./i);\n  if (matches && matches.length > 2) {\n    // iOS 10+ && chrome 55+.\n    return parseInt(matches[1], 10) >= 10 && parseInt(matches[2], 10) >= 55;\n  }\n  return false;\n};\n\n\n/**\n * @param {?Window} win The popup window to check.\n * @param {number=} opt_stepDuration The duration of each wait cycle before\n *     checking that window is closed.\n * @return {!goog.Promise<undefined>} The promise to resolve when window is\n *     closed.\n */\nfireauth.util.onPopupClose = function(win, opt_stepDuration) {\n  var stepDuration = opt_stepDuration || fireauth.util.POPUP_WAIT_CYCLE_MS_;\n  return new goog.Promise(function(resolve, reject) {\n    // Function to repeat each stepDuration.\n    var repeat = function() {\n      goog.Timer.promise(stepDuration).then(function() {\n        // After wait, check if window is closed.\n        if (!win || win.closed) {\n          // If so, resolve.\n          resolve();\n        } else {\n          // Call repeat again.\n          return repeat();\n        }\n      });\n    };\n    return repeat();\n  });\n};\n\n\n/**\n * @param {!Array<string>} authorizedDomains List of authorized domains.\n * @param {string} url The URL to check.\n * @return {boolean} Whether the passed domain is an authorized one.\n */\nfireauth.util.isAuthorizedDomain = function(authorizedDomains, url) {\n  var uri = goog.Uri.parse(url);\n  var scheme = uri.getScheme();\n  var domain = uri.getDomain();\n  for (var i = 0; i < authorizedDomains.length; i++) {\n    // Currently this corresponds to: domain.com = *://*.domain.com:* or\n    // exact domain match.\n    // In the case of Chrome extensions, the authorizedDomain will be formatted\n    // as 'chrome-extension://abcdefghijklmnopqrstuvwxyz123456'.\n    // The URL to check must have a chrome extension scheme and the domain\n    // must be an exact match domain == 'abcdefghijklmnopqrstuvwxyz123456'.\n    if (fireauth.util.matchDomain(authorizedDomains[i], domain, scheme)) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Represents the dimensions of an entity (width and height).\n * @typedef {{\n *   width: number,\n *   height: number\n * }}\n */\nfireauth.util.Dimensions;\n\n\n/**\n * @param {?Window=} opt_window The optional window whose dimensions are to be\n *     returned. The current window is used if not found.\n * @return {?fireauth.util.Dimensions} The requested window dimensions if\n *     available.\n */\nfireauth.util.getWindowDimensions = function(opt_window) {\n  var win = opt_window || goog.global['window'];\n  if (win && win['innerWidth'] && win['innerHeight']) {\n    return {\n      'width': parseFloat(win['innerWidth']),\n      'height': parseFloat(win['innerHeight'])\n    };\n  }\n  return null;\n};\n\n\n/**\n * RegExp to detect if the domain given is an IP address. This is only used\n * for validating http and https schemes.\n *\n * It does not strictly validate if the IP is a real IP address, but as the\n * matchDomain method tests against a set of valid domains (extracted from the\n * window's current URL), it is sufficient.\n *\n * @const {!RegExp}\n * @private\n */\nfireauth.util.IP_ADDRESS_REGEXP_ = /^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/;\n\n\n/**\n * @param {string} domainPattern The domain pattern to match.\n * @param {string} domain The domain to check. It is assumed that it is a valid\n *     domain, not a user provided one.\n * @param {string} scheme The scheme of the domain to check.\n * @return {boolean} Whether the provided domain matches the domain pattern.\n */\nfireauth.util.matchDomain = function(domainPattern, domain, scheme) {\n  // Chrome extension matching.\n  if (domainPattern.indexOf('chrome-extension://') == 0) {\n    var chromeExtUri = goog.Uri.parse(domainPattern);\n    // Domain must match and the current scheme must be a Chrome extension.\n    return chromeExtUri.getDomain() == domain && scheme == 'chrome-extension';\n  } else if (scheme != 'http' && scheme != 'https') {\n    // Any other scheme that is not http or https cannot be whitelisted.\n    return false;\n  } else {\n    // domainPattern must not contain a scheme and the current scheme must be\n    // either http or https.\n    // Check if authorized domain pattern is an IP address.\n    if (fireauth.util.IP_ADDRESS_REGEXP_.test(domainPattern)) {\n      // The domain has to be exactly equal to the pattern, as an IP domain will\n      // only contain the IP, no extra character.\n      return domain == domainPattern;\n    }\n    // Dots in pattern should be escaped.\n    var escapedDomainPattern = domainPattern.split('.').join('\\\\.');\n    // Non ip address domains.\n    // domain.com = *.domain.com OR domain.com\n    var re = new RegExp(\n        '^(.+\\\\.' + escapedDomainPattern + '|' +\n        escapedDomainPattern + ')$', 'i');\n    return re.test(domain);\n  }\n};\n\n\n/**\n * RegExp to detect if the email address given is valid.\n * @const {!RegExp}\n * @private\n */\nfireauth.util.EMAIL_ADDRESS_REGEXP_ = /^[^@]+@[^@]+$/;\n\n\n/**\n * Determines if it is a valid email address.\n * @param {*} email The email address.\n * @return {boolean} Whether the email address is valid.\n */\nfireauth.util.isValidEmailAddress = function(email) {\n  return typeof email === 'string' &&\n      fireauth.util.EMAIL_ADDRESS_REGEXP_.test(email);\n};\n\n\n/**\n * @return {!goog.Promise<void>} A promise that resolves when DOM is ready.\n */\nfireauth.util.onDomReady = function() {\n  var resolver = null;\n  return new goog.Promise(function(resolve, reject) {\n    var doc = goog.global.document;\n    // If document already loaded, resolve immediately.\n    if (doc.readyState == 'complete') {\n      resolve();\n    } else {\n      // Document not ready, wait for load before resolving.\n      // Save resolver, so we can remove listener in case it was externally\n      // cancelled.\n      resolver = function() {\n        resolve();\n      };\n      goog.events.listenOnce(window, goog.events.EventType.LOAD, resolver);\n    }\n  }).thenCatch(function(error) {\n    // In case this promise was cancelled, make sure it unlistens to load.\n    goog.events.unlisten(window, goog.events.EventType.LOAD, resolver);\n    throw error;\n  });\n};\n\n\n/** @return {boolean} Whether environment supports DOM. */\nfireauth.util.isDOMSupported = function() {\n  return !!goog.global.document;\n};\n\n\n/**\n * The default ondeviceready Cordova timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.util.CORDOVA_ONDEVICEREADY_TIMEOUT_MS_ = 1000;\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @param {number=} opt_timeout The optional timeout in ms for deviceready\n *     event to resolve.\n * @return {!goog.Promise} A promise that resolves if the current environment is\n *     a Cordova environment.\n */\nfireauth.util.checkIfCordova = function(opt_userAgent, opt_timeout) {\n  // Errors generated are internal and should be converted if needed to\n  // developer facing Firebase errors.\n  // Only supported in Android/iOS environment.\n  if (fireauth.util.isAndroidOrIosCordovaScheme(opt_userAgent)) {\n    return fireauth.util.onDomReady().then(function() {\n      return new goog.Promise(function(resolve, reject) {\n        var doc = goog.global.document;\n        var timeoutId = setTimeout(function() {\n          reject(new Error('Cordova framework is not ready.'));\n        }, opt_timeout || fireauth.util.CORDOVA_ONDEVICEREADY_TIMEOUT_MS_);\n        // This should resolve immediately after DOM ready.\n        doc.addEventListener('deviceready', function() {\n          clearTimeout(timeoutId);\n          resolve();\n        }, false);\n      });\n    });\n  }\n  return goog.Promise.reject(\n      new Error('Cordova must run in an Android or iOS file scheme.'));\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the app is rendered in a mobile iOS or Android\n *     Cordova environment.\n */\nfireauth.util.isAndroidOrIosCordovaScheme = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  return !!((fireauth.util.getCurrentScheme() === 'file:' ||\n             fireauth.util.getCurrentScheme() === 'ionic:') &&\n            ua.toLowerCase().match(/iphone|ipad|ipod|android/));\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the app is rendered in a mobile iOS 7 or 8 browser.\n */\nfireauth.util.isIOS7Or8 = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  return !!(ua.match(/(iPad|iPhone|iPod).*OS 7_\\d/i) ||\n            ua.match(/(iPad|iPhone|iPod).*OS 8_\\d/i));\n};\n\n\n/**\n * @return {boolean} Whether browser is Safari or an iOS browser and page is\n *     embedded in an iframe. Local Storage does not synchronize with an iframe\n *     embedded on a page in a different domain but will still trigger storage\n *     event with storage changes.\n */\nfireauth.util.isSafariLocalStorageNotSynced = function() {\n  var ua = fireauth.util.getUserAgentString();\n  // Safari or iOS browser and embedded in an iframe.\n  if (!fireauth.util.iframeCanSyncWebStorage(ua) && fireauth.util.isIframe()) {\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * @param {?Window=} opt_win Optional window to check whether it is an iframe.\n *     If not provided, the current window is checked.\n * @return {boolean} Whether web page is running in an iframe.\n */\nfireauth.util.isIframe = function(opt_win) {\n  var win = opt_win || goog.global['window'];\n  try {\n    // Check that the current window is not the top window.\n    // If so, return true.\n    return !!(win && win != win['top']);\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * @param {?Window=} opt_win Optional window to check whether it has an opener\n *     that is an iframe.\n * @return {boolean} Whether the web page was opened from an iframe.\n */\nfireauth.util.isOpenerAnIframe = function(opt_win) {\n  var win = opt_win || goog.global['window'];\n  try {\n    // Get the opener if available.\n    var opener = win && win['opener'];\n    // Check if the opener is an iframe. If so, return true.\n    // Confirm opener is available, otherwise the current window is checked\n    // instead.\n    return !!(opener && fireauth.util.isIframe(opener));\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * @param {?Object=} global The optional global scope.\n * @return {boolean} Whether current environment is a worker.\n */\nfireauth.util.isWorker = function(global) {\n  var scope = global || goog.global;\n  // WorkerGlobalScope only defined in worker environment.\n  return typeof scope['WorkerGlobalScope'] !== 'undefined' &&\n         typeof scope['importScripts'] === 'function';\n};\n\n\n/**\n * @param {?Object=} opt_global The optional global scope.\n * @return {boolean} Whether current environment supports fetch API and other\n *     APIs it depends on.\n */\nfireauth.util.isFetchSupported = function(opt_global) {\n  // Required by fetch API calls.\n  var scope = opt_global || goog.global;\n  return typeof scope['fetch'] !== 'undefined' &&\n         typeof scope['Headers'] !== 'undefined' &&\n         typeof scope['Request'] !== 'undefined';\n};\n\n\n/**\n * Enum for the runtime environment.\n * @enum {string}\n */\nfireauth.util.Env = {\n  BROWSER: 'Browser',\n  NODE: 'Node',\n  REACT_NATIVE: 'ReactNative',\n  WORKER: 'Worker'\n};\n\n\n/**\n * @return {!fireauth.util.Env} The current runtime environment.\n */\nfireauth.util.getEnvironment = function() {\n  if (firebase.INTERNAL.hasOwnProperty('reactNative')) {\n    return fireauth.util.Env.REACT_NATIVE;\n  } else if (firebase.INTERNAL.hasOwnProperty('node')) {\n    // browserify seems to keep the process property in some cases even though\n    // the library is browser only. Use this check instead to reliably detect\n    // a Node.js environment.\n    return fireauth.util.Env.NODE;\n  } else if (fireauth.util.isWorker()) {\n    // Worker environment.\n    return fireauth.util.Env.WORKER;\n  }\n  // The default is a browser environment.\n  return fireauth.util.Env.BROWSER;\n};\n\n\n/**\n * @return {boolean} Whether the environment is a native environment, where\n *     CORS checks do not apply.\n */\nfireauth.util.isNativeEnvironment = function() {\n  var environment = fireauth.util.getEnvironment();\n  return environment === fireauth.util.Env.REACT_NATIVE ||\n      environment === fireauth.util.Env.NODE;\n};\n\n\n/**\n * The separator for storage keys to concatenate App name and API key.\n * @const {string}\n * @private\n */\nfireauth.util.STORAGE_KEY_SEPARATOR_ = ':';\n\n\n/**\n * @param {string} apiKey The API Key of the app.\n * @param {string} appName The App name.\n * @return {string} The key used for identifying the app owner of the user.\n */\nfireauth.util.createStorageKey = function(apiKey, appName) {\n  return apiKey + fireauth.util.STORAGE_KEY_SEPARATOR_ + appName;\n};\n\n\n/** @return {string} a long random character string. */\nfireauth.util.generateRandomString = function() {\n  return Math.floor(Math.random() * 1000000000).toString();\n};\n\n\n/**\n * Generates a random alpha numeric string.\n * @param {number} numOfChars The number of random characters within the string.\n * @return {string} A string with a specific number of random characters.\n */\nfireauth.util.generateRandomAlphaNumericString = function(numOfChars) {\n  var chars = [];\n  var allowedChars =\n      '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  while (numOfChars > 0) {\n    chars.push(\n        allowedChars.charAt(\n            Math.floor(Math.random() * allowedChars.length)));\n    numOfChars--;\n  }\n  return chars.join('');\n};\n\n\n/**\n * Enums for Browser name.\n * @enum {string}\n */\nfireauth.util.BrowserName = {\n  ANDROID: 'Android',\n  BLACKBERRY: 'Blackberry',\n  EDGE: 'Edge',\n  FIREFOX: 'Firefox',\n  IE: 'IE',\n  IEMOBILE: 'IEMobile',\n  OPERA: 'Opera',\n  OTHER: 'Other',\n  CHROME: 'Chrome',\n  SAFARI: 'Safari',\n  SILK: 'Silk',\n  WEBOS: 'Webos'\n};\n\n\n/**\n * @param {string} userAgent The navigator user agent string.\n * @return {string} The browser name, eg Safari, Firefox, etc.\n */\nfireauth.util.getBrowserName = function(userAgent) {\n  var ua = userAgent.toLowerCase();\n  if (goog.string.contains(ua, 'opera/') ||\n      goog.string.contains(ua, 'opr/') ||\n      goog.string.contains(ua, 'opios/')) {\n    return fireauth.util.BrowserName.OPERA;\n  } else if (goog.string.contains(ua, 'iemobile')) {\n    // Windows phone IEMobile browser.\n    return fireauth.util.BrowserName.IEMOBILE;\n  } else if (goog.string.contains(ua, 'msie') ||\n             goog.string.contains(ua, 'trident/')) {\n    return fireauth.util.BrowserName.IE;\n  } else if (goog.string.contains(ua, 'edge/')) {\n    return fireauth.util.BrowserName.EDGE;\n  } else if (goog.string.contains(ua, 'firefox/')) {\n    return fireauth.util.BrowserName.FIREFOX;\n  } else if (goog.string.contains(ua, 'silk/')) {\n    return fireauth.util.BrowserName.SILK;\n  } else if (goog.string.contains(ua, 'blackberry')) {\n    // Blackberry browser.\n    return fireauth.util.BrowserName.BLACKBERRY;\n  } else if (goog.string.contains(ua, 'webos')) {\n    // WebOS default browser.\n    return fireauth.util.BrowserName.WEBOS;\n  } else if (goog.string.contains(ua, 'safari/') &&\n             !goog.string.contains(ua, 'chrome/') &&\n             !goog.string.contains(ua, 'crios/') &&\n             !goog.string.contains(ua, 'android')) {\n    return fireauth.util.BrowserName.SAFARI;\n  } else if ((goog.string.contains(ua, 'chrome/') ||\n              goog.string.contains(ua, 'crios/')) &&\n             !goog.string.contains(ua, 'edge/')) {\n    return fireauth.util.BrowserName.CHROME;\n  } else if (goog.string.contains(ua, 'android')) {\n    // Android stock browser.\n    return fireauth.util.BrowserName.ANDROID;\n  } else {\n    // Most modern browsers have name/version at end of user agent string.\n    var re = new RegExp('([a-zA-Z\\\\d\\\\.]+)\\/[a-zA-Z\\\\d\\\\.]*$');\n    var matches = userAgent.match(re);\n    if (matches && matches.length == 2) {\n      return matches[1];\n    }\n  }\n  return fireauth.util.BrowserName.OTHER;\n};\n\n\n/**\n * Enums for client implementation name.\n * @enum {string}\n */\nfireauth.util.ClientImplementation = {\n  JSCORE: 'JsCore',\n  OAUTH_HANDLER: 'Handler',\n  OAUTH_IFRAME: 'Iframe'\n};\n\n\n/**\n * Enums for the framework ID to be logged in RPC header.\n * Future frameworks to possibly add: angularfire, polymerfire, reactfire, etc.\n * @enum {string}.\n */\nfireauth.util.Framework = {\n  // No other framework used.\n  DEFAULT: 'FirebaseCore-web',\n  // Firebase Auth used with FirebaseUI-web.\n  FIREBASEUI: 'FirebaseUI-web'\n};\n\n\n/**\n * @param {!Array<string>} providedFrameworks List of framework ID strings.\n * @return {!Array<!fireauth.util.Framework>} List of supported framework IDs\n *     with no duplicates.\n */\nfireauth.util.getFrameworkIds = function(providedFrameworks) {\n  var frameworkVersion = [];\n  var frameworkSet = {};\n  for (var key in fireauth.util.Framework) {\n    frameworkSet[fireauth.util.Framework[key]] = true;\n  }\n  for (var i = 0; i < providedFrameworks.length; i++) {\n    if (typeof frameworkSet[providedFrameworks[i]] !== 'undefined') {\n      // Delete it from set to prevent duplications.\n      delete frameworkSet[providedFrameworks[i]];\n      frameworkVersion.push(providedFrameworks[i]);\n    }\n  }\n  // Sort alphabetically so that \"FirebaseCore-web,FirebaseUI-web\" and\n  // \"FirebaseUI-web,FirebaseCore-web\" aren't viewed as different.\n  frameworkVersion.sort();\n  return frameworkVersion;\n};\n\n\n/**\n * @param {!fireauth.util.ClientImplementation} clientImplementation The client\n *     implementation.\n * @param {string} clientVersion The client version.\n * @param {?Array<string>=} opt_frameworkVersion The framework version.\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {string} The full client SDK version.\n */\nfireauth.util.getClientVersion = function(clientImplementation, clientVersion,\n    opt_frameworkVersion, opt_userAgent) {\n  var frameworkVersion = fireauth.util.getFrameworkIds(\n      opt_frameworkVersion || []);\n  if (!frameworkVersion.length) {\n    frameworkVersion = [fireauth.util.Framework.DEFAULT];\n  }\n  var environment = fireauth.util.getEnvironment();\n  var reportedEnvironment = '';\n  if (environment === fireauth.util.Env.BROWSER) {\n    // In a browser environment, report the browser name.\n    var userAgent = opt_userAgent || fireauth.util.getUserAgentString();\n    reportedEnvironment = fireauth.util.getBrowserName(userAgent);\n  } else if (environment === fireauth.util.Env.WORKER) {\n    // Technically a worker runs from a browser but we need to differentiate a\n    // worker from a browser.\n    // For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web.\n    var userAgent = opt_userAgent || fireauth.util.getUserAgentString();\n    reportedEnvironment = fireauth.util.getBrowserName(userAgent) + '-' +\n        environment;\n  } else {\n    // Otherwise, just report the environment name.\n    reportedEnvironment = environment;\n  }\n  // The format to be followed:\n  // ${browserName}/${clientImplementation}/${clientVersion}/${frameworkVersion}\n  // As multiple Firebase frameworks/libraries can be used, join their IDs with\n  // a comma.\n  return reportedEnvironment + '/' + clientImplementation +\n      '/' + clientVersion + '/' + frameworkVersion.join(',');\n};\n\n\n/**\n * @return {string} The user agent string reported by the environment, or the\n *     empty string if not available.\n */\nfireauth.util.getUserAgentString = function() {\n  return (goog.global['navigator'] && goog.global['navigator']['userAgent']) ||\n      '';\n};\n\n\n/**\n * @param {string} varStrName The variable string name.\n * @param {?Object=} opt_scope The optional scope where to look in. The default\n *     is window.\n * @return {*} The reference if found.\n */\nfireauth.util.getObjectRef = function(varStrName, opt_scope) {\n  var pieces = varStrName.split('.');\n  var last = opt_scope || goog.global;\n  for (var i = 0;\n       i < pieces.length && typeof last == 'object' && last != null;\n       i++) {\n    last = last[pieces[i]];\n  }\n  // Last hasn't reached the end yet, return undefined.\n  if (i != pieces.length) {\n    last = undefined;\n  }\n  return last;\n};\n\n\n/** @return {boolean} Whether web storage is supported. */\nfireauth.util.isWebStorageSupported = function() {\n  try {\n    var storage = goog.global['localStorage'];\n    var key = fireauth.util.generateEventId();\n    if (storage) {\n      // setItem will throw an exception if we cannot access WebStorage (e.g.,\n      // Safari in private mode).\n      storage['setItem'](key, '1');\n      storage['removeItem'](key);\n      // For browsers where iframe web storage does not synchronize with a popup\n      // of the same domain, indexedDB is used for persistent storage. These\n      // browsers include IE11 and Edge.\n      // Make sure it is supported (IE11 and Edge private mode does not support\n      // that).\n      if (fireauth.util.isLocalStorageNotSynchronized()) {\n        // In such browsers, if indexedDB is not supported, an iframe cannot be\n        // notified of the popup sign in result.\n        return !!goog.global['indexedDB'];\n      }\n      return true;\n    }\n  } catch (e) {\n    // localStorage is not available from a worker. Test availability of\n    // indexedDB.\n    return fireauth.util.isWorker() && !!goog.global['indexedDB'];\n  }\n  return false;\n};\n\n\n/**\n * This guards against leaking Cordova support before official launch.\n * This field will be removed or updated to return true when the new feature is\n * ready for launch.\n * @return {boolean} Whether Cordova OAuth support is enabled.\n */\nfireauth.util.isCordovaOAuthEnabled = function() {\n  return false;\n};\n\n\n/**\n * @return {boolean} Whether popup and redirect operations are supported in the\n *     current environment.\n */\nfireauth.util.isPopupRedirectSupported = function() {\n  // Popup and redirect are supported in an environment where the container\n  // origin can be securely whitelisted.\n  return (fireauth.util.isHttpOrHttps() ||\n          fireauth.util.isChromeExtension() ||\n          fireauth.util.isAndroidOrIosCordovaScheme()) &&\n         // React Native with remote debugging reports its location.protocol as\n         // http.\n         !fireauth.util.isNativeEnvironment() &&\n         // Local storage has to be supported for browser popup and redirect\n         // operations to work.\n         fireauth.util.isWebStorageSupported() &&\n         // DOM, popups and redirects are not supported within a worker.\n         !fireauth.util.isWorker();\n};\n\n\n/**\n * @return {boolean} Whether the current environment is http or https.\n */\nfireauth.util.isHttpOrHttps = function() {\n  return fireauth.util.getCurrentScheme() === 'http:' ||\n       fireauth.util.getCurrentScheme() === 'https:';\n};\n\n\n/** @return {?string} The current URL scheme. */\nfireauth.util.getCurrentScheme = function() {\n  return (goog.global['location'] && goog.global['location']['protocol']) ||\n      null;\n};\n\n\n/**\n * Checks whether the current page is a Chrome extension.\n * @return {boolean} Whether the current page is a Chrome extension.\n */\nfireauth.util.isChromeExtension = function() {\n  return fireauth.util.getCurrentScheme() === 'chrome-extension:';\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the current browser is running in an iOS\n *     environment.\n */\nfireauth.util.isIOS = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  return !!ua.toLowerCase().match(/iphone|ipad|ipod/);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the current browser is running in an Android\n *     environment.\n */\nfireauth.util.isAndroid = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  return !!ua.toLowerCase().match(/android/);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the opener of a popup cannot communicate with the\n *     popup while it is in the foreground.\n */\nfireauth.util.runsInBackground = function(opt_userAgent) {\n  // TODO: split this check into 2, one check that opener can access\n  // popup, another check that storage synchronizes between popup and opener.\n  // Popup events fail in iOS version 7 (lowest version we currently support)\n  // browsers. When the popup is triggered, the opener is unable to redirect\n  // the popup url, close the popup and in some cases will miss the storage\n  // event triggered when localStorage is changed.\n  // Extend this to all mobile devices. This behavior is more likely to work\n  // cross mobile platforms.\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  if (fireauth.util.isMobileBrowser(ua)) {\n    return false;\n  } else if (fireauth.util.getBrowserName(ua) ==\n             fireauth.util.BrowserName.FIREFOX) {\n    // Latest version of Firefox 47.0 does not allow you to access properties on\n    // the popup window from the opener.\n    return false;\n  }\n  return true;\n};\n\n\n/**\n * Stringifies an object, retuning null if the object is not defined.\n * @param {*} obj The raw object.\n * @return {?string} The JSON-serialized object.\n */\nfireauth.util.stringifyJSON = function(obj) {\n  if (typeof obj === 'undefined') {\n    return null;\n  }\n  return goog.json.serialize(obj);\n};\n\n\n/**\n * @param {!Object} obj The original object.\n * @return {!Object} A copy of the original object with all entries that are\n *     null or undefined removed.\n */\nfireauth.util.copyWithoutNullsOrUndefined = function(obj) {\n  // The processed copy to return.\n  var trimmedObj = {};\n  // Remove all empty fields from data, allow zero and false booleans.\n  for (var key in obj) {\n    if (obj.hasOwnProperty(key) &&\n        obj[key] !== null &&\n        obj[key] !== undefined) {\n      trimmedObj[key] = obj[key];\n    }\n  }\n  return trimmedObj;\n};\n\n\n/**\n * Removes all key/pairs with the specified keys from the given object.\n * @param {!Object} obj The object to process.\n * @param {!Array<string>} keys The list of keys to remove.\n * @return {!Object} The object with the keys removed.\n */\nfireauth.util.removeEntriesWithKeys = function(obj, keys) {\n  // Clone object.\n  var copy = goog.object.clone(obj);\n  // Traverse keys.\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    // If key found in object, remove it.\n    if (key in copy) {\n      delete copy[key];\n    }\n  }\n  // Returned filtered copy.\n  return copy;\n};\n\n\n/**\n * Parses a JSON string, returning undefined if null is passed.\n * @param {?string} json The JSON-serialized object.\n * @return {*} The raw object.\n */\nfireauth.util.parseJSON = function(json) {\n  if (json === null) {\n    return undefined;\n  }\n\n  // Do not use goog.json.parse since it uses eval underneath to support old\n  // browsers that do not provide JSON.parse. The recommended Content Security\n  // Policy does not allow unsafe-eval in some environments like Chrome\n  // extensions. Usage of eval is not recommend in Chrome in general.\n  // Use native parsing instead via JSON.parse. This is provided in our list\n  // of supported browsers.\n  return JSON.parse(json);\n};\n\n\n/**\n * @param {?string=} opt_prefix An optional prefix string to prepend to ID.\n * @return {string} The generated event ID used to identify a generic event.\n */\nfireauth.util.generateEventId = function(opt_prefix) {\n  return opt_prefix ? opt_prefix : '' +\n      Math.floor(Math.random() * 1000000000).toString();\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether an embedded iframe can sync to web storage changes.\n *     Web storage sync fails in Safari desktop browsers and iOS mobile\n *     browsers.\n */\nfireauth.util.iframeCanSyncWebStorage = function(opt_userAgent) {\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  if (fireauth.util.getBrowserName(ua) == fireauth.util.BrowserName.SAFARI ||\n      ua.toLowerCase().match(/iphone|ipad|ipod/)) {\n    return false;\n  }\n  return true;\n};\n\n\n/**\n * Reset unlaoded GApi modules. If gapi.load fails due to a network error,\n * it will stop working after a retrial. This is a hack to fix this issue.\n */\nfireauth.util.resetUnloadedGapiModules = function() {\n  // Clear last failed gapi.load state to force next gapi.load to first\n  // load the failed gapi.iframes module.\n  // Get gapix.beacon context.\n  var beacon = goog.global['___jsl'];\n  // Get current hint.\n  if (beacon && beacon['H']) {\n    // Get gapi hint.\n    for (var hint in beacon['H']) {\n      // Requested modules.\n      beacon['H'][hint]['r'] = beacon['H'][hint]['r'] || [];\n      // Loaded modules.\n      beacon['H'][hint]['L'] = beacon['H'][hint]['L'] || [];\n      // Set requested modules to a copy of the loaded modules.\n      beacon['H'][hint]['r'] = beacon['H'][hint]['L'].concat();\n      // Clear pending callbacks.\n      if (beacon['CP']) {\n        for (var i = 0; i < beacon['CP'].length; i++) {\n          // Remove all failed pending callbacks.\n          beacon['CP'][i] = null;\n        }\n      }\n    }\n  }\n};\n\n\n/**\n * Returns whether the current device is a mobile device. Mobile browsers and\n * React-Native environments are considered mobile devices.\n * @param {?string=} opt_userAgent The optional navigator user agent.\n * @param {?fireauth.util.Env=} opt_env The optional environment.\n * @return {boolean} Whether the current device is a mobile device or not.\n */\nfireauth.util.isMobileDevice = function(opt_userAgent, opt_env) {\n  // Get user agent.\n  var ua = opt_userAgent || fireauth.util.getUserAgentString();\n  // Get environment.\n  var environment = opt_env || fireauth.util.getEnvironment();\n  return fireauth.util.isMobileBrowser(ua) ||\n      environment === fireauth.util.Env.REACT_NATIVE;\n};\n\n\n/**\n * @param {?Object=} opt_navigator The optional navigator object typically used\n *     for testing.\n * @return {boolean} Whether the app is currently online. If offline, false is\n *     returned. If this cannot be determined, true is returned.\n */\nfireauth.util.isOnline = function(opt_navigator) {\n  var navigator = opt_navigator || goog.global['navigator'];\n  if (navigator &&\n      typeof navigator['onLine'] === 'boolean' &&\n      // Apply only for traditional web apps and Chrome extensions.\n      // This is especially true for Cordova apps which have unreliable\n      // navigator.onLine behavior unless cordova-plugin-network-information is\n      // installed which overwrites the native navigator.onLine value and\n      // defines navigator.connection.\n      (fireauth.util.isHttpOrHttps() ||\n       fireauth.util.isChromeExtension() ||\n       typeof navigator['connection'] !== 'undefined')) {\n    return navigator['onLine'];\n  }\n  // If we can't determine the state, assume it is online.\n  return true;\n};\n\n\n/**\n * @param {?Object=} opt_navigator The object with navigator data, defaulting\n *     to window.navigator if unspecified.\n * @return {?string} The user's preferred language. Returns null if\n */\nfireauth.util.getUserLanguage = function(opt_navigator) {\n  var navigator = opt_navigator || goog.global['navigator'];\n  if (!navigator) {\n    return null;\n  }\n  return (\n      // Most reliable, but only supported in Chrome/Firefox.\n      navigator['languages'] && navigator['languages'][0] ||\n      // Supported in most browsers, but returns the language of the browser\n      // UI, not the language set in browser settings.\n      navigator['language'] ||\n      // IE <= 10.\n      navigator['userLanguage'] ||\n      // Couldn't determine language.\n      null\n  );\n};\n\n\n/**\n * A structure to help pick between a range of long and short delay durations\n * depending on the current environment. In general, the long delay is used for\n * mobile environments whereas short delays are used for desktop environments.\n * @param {number} shortDelay The short delay duration.\n * @param {number} longDelay The long delay duration.\n * @param {?string=} opt_userAgent The optional navigator user agent.\n * @param {?fireauth.util.Env=} opt_env The optional environment.\n * @constructor\n */\nfireauth.util.Delay = function(shortDelay, longDelay, opt_userAgent, opt_env) {\n  // Internal error when improperly initialized.\n  if (shortDelay > longDelay) {\n    throw new Error('Short delay should be less than long delay!');\n  }\n  /**\n   * @private @const {number} The short duration delay used for desktop\n   *     environments.\n   */\n  this.shortDelay_ = shortDelay;\n  /**\n   * @private @const {number} The long duration delay used for mobile\n   *     environments.\n   */\n  this.longDelay_ = longDelay;\n  /** @private @const {boolean} Whether the environment is a mobile one. */\n  this.isMobile_ = fireauth.util.isMobileDevice(opt_userAgent, opt_env);\n};\n\n\n/**\n * The default value for the offline delay timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.util.Delay.OFFLINE_DELAY_MS_ = 5000;\n\n\n/**\n * @return {number} The delay that matches with the current environment.\n */\nfireauth.util.Delay.prototype.get = function() {\n  // navigator.onLine is unreliable in some cases.\n  // Failing hard in those cases may make it impossible to recover for end user.\n  // Waiting for the regular full duration when there is no network can result\n  // in a bad experience.\n  // Instead return a short timeout duration. If there is no network connection,\n  // the user would wait 5 seconds to detect that. If there is a connection\n  // (false alert case), the user still has the ability to try to send the\n  // request. If it fails (timeout too short), they can still retry.\n  if (!fireauth.util.isOnline()) {\n    // Pick the shorter timeout.\n    return Math.min(fireauth.util.Delay.OFFLINE_DELAY_MS_, this.shortDelay_);\n  }\n  // If running in a mobile environment, return the long delay, otherwise\n  // return the short delay.\n  // This could be improved in the future to dynamically change based on other\n  // variables instead of just reading the current environment.\n  return this.isMobile_ ? this.longDelay_ : this.shortDelay_;\n};\n\n\n/**\n * @return {boolean} Whether the app is visible in the foreground. This uses\n *     document.visibilityState. For browsers that do not support it, this is\n *     always true.\n */\nfireauth.util.isAppVisible = function() {\n  // https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityState\n  var doc = goog.global.document;\n  // Check if supported.\n  if (doc && typeof doc['visibilityState'] !== 'undefined') {\n    // Check if visible.\n    return doc['visibilityState'] == 'visible';\n  }\n  // API not supported in current browser, default to true.\n  return true;\n};\n\n\n/**\n * @return {!goog.Promise} A promise that resolves when the app is visible in\n *     the foreground.\n */\nfireauth.util.onAppVisible = function() {\n  var doc = goog.global.document;\n  // Visibility change listener reference.\n  var onVisibilityChange = null;\n  if (fireauth.util.isAppVisible() || !doc) {\n    // Visible or non browser environment.\n    return goog.Promise.resolve();\n  } else {\n    // Invisible and in browser environment.\n    return new goog.Promise(function(resolve, reject) {\n      // On visibility change listener.\n      onVisibilityChange = function(event) {\n        // App is visible.\n        if (fireauth.util.isAppVisible()) {\n          // Unregister event listener.\n          doc.removeEventListener(\n              'visibilitychange', onVisibilityChange, false);\n          // Resolve promise.\n          resolve();\n        }\n      };\n      // Listen to visibility change.\n      doc.addEventListener('visibilitychange', onVisibilityChange, false);\n    }).thenCatch(function(error) {\n      // In case this promise was cancelled, make sure it unlistens to\n      // visibilitychange event.\n      doc.removeEventListener('visibilitychange', onVisibilityChange, false);\n      // Rethrow the same error.\n      throw error;\n    });\n  }\n};\n\n\n/**\n * Logs a warning message to the console, if the console is available.\n * @param {string} message\n */\nfireauth.util.consoleWarn = function(message) {\n  if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n    console.warn(message);\n  }\n};\n\n\n/**\n * Parses a UTC time stamp string or number and returns the corresponding UTC\n * date string if valid. Otherwise, returns null.\n * @param {?string|number} utcTimestamp The UTC timestamp number or string.\n * @return {?string} The corresponding UTC date string. Null if invalid.\n */\nfireauth.util.utcTimestampToDateString = function(utcTimestamp) {\n  try {\n    // Convert to date object.\n    var date = new Date(parseInt(utcTimestamp, 10));\n    // Test date is valid.\n    if (!isNaN(date.getTime()) &&\n        // Confirm that utcTimestamp is numeric.\n        goog.string.isNumeric(utcTimestamp)) {\n      // Convert to UTC date string.\n      return date.toUTCString();\n    }\n  } catch (e) {\n    // Do nothing. null will be returned.\n  }\n  return null;\n};\n\n\n/** @return {boolean} Whether indexedDB is available. */\nfireauth.util.isIndexedDBAvailable = function() {\n  return !!goog.global['indexedDB'];\n};\n\n\n/** @return {boolean} Whether current mode is Auth handler or iframe. */\nfireauth.util.isAuthHandlerOrIframe = function() {\n  return !!(fireauth.util.getObjectRef('fireauth.oauthhelper', goog.global) ||\n            fireauth.util.getObjectRef('fireauth.iframe', goog.global));\n};\n\n\n/** @return {boolean} Whether indexedDB is used to persist storage. */\nfireauth.util.persistsStorageWithIndexedDB = function() {\n  // This will cover:\n  // IE11, Edge when indexedDB is available (this is unavailable in InPrivate\n  // mode). (SDK, OAuth handler and iframe)\n  // Any environment where indexedDB is available (SDK only).\n\n  // In a browser environment, when an iframe and a popup web storage are not\n  // synchronized, use the indexedDB fireauth.storage.Storage implementation.\n  return (fireauth.util.isLocalStorageNotSynchronized() ||\n          !fireauth.util.isAuthHandlerOrIframe()) &&\n         fireauth.util.isIndexedDBAvailable();\n};\n\n\n/** Sets the no-referrer meta tag in the document head if applicable. */\nfireauth.util.setNoReferrer = function() {\n  var doc = goog.global.document;\n  if (doc) {\n    try {\n      var meta = goog.dom.createDom(goog.dom.TagName.META, {\n        'name': 'referrer',\n        'content': 'no-referrer'\n      });\n      var headCollection = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD);\n      // Append meta tag to head.\n      if (headCollection.length) {\n        headCollection[0].appendChild(meta);\n      }\n    } catch (e) {\n      // Best effort approach.\n    }\n  }\n};\n\n\n/** @return {?ServiceWorker} The servicerWorker controller if available. */\nfireauth.util.getServiceWorkerController = function() {\n  var navigator = goog.global['navigator'];\n  return (navigator &&\n          navigator.serviceWorker &&\n          navigator.serviceWorker.controller) || null;\n};\n\n\n/** @return {?WorkerGlobalScope} The worker global scope if available. */\nfireauth.util.getWorkerGlobalScope = function() {\n  return fireauth.util.isWorker() ? /** @type {!WorkerGlobalScope} */ (self) :\n      null;\n};\n\n/**\n * @return {!goog.Promise<?ServiceWorker>} A promise that resolves with the\n *     service worker. This will resolve only when a service worker becomes\n *     available. If no service worker is supported, it will resolve with null.\n */\nfireauth.util.getActiveServiceWorker = function() {\n  var navigator = goog.global['navigator'];\n  if (navigator && navigator.serviceWorker) {\n    return goog.Promise.resolve()\n        .then(function() {\n          return navigator.serviceWorker.ready;\n        })\n        .then(function(registration) {\n          return /** @type {?ServiceWorker} */ (registration.active || null);\n        })\n        .thenCatch(function(error) {\n          return null;\n        });\n  }\n  return goog.Promise.resolve(/** @type {?ServiceWorker} */ (null));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for window manipulation.\n */\n\n\ngoog.provide('goog.window');\n\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.string');\ngoog.require('goog.string.Const');\ngoog.require('goog.userAgent');\n\n\n/**\n * Default height for popup windows\n * @type {number}\n */\ngoog.window.DEFAULT_POPUP_HEIGHT = 500;\n\n\n/**\n * Default width for popup windows\n * @type {number}\n */\ngoog.window.DEFAULT_POPUP_WIDTH = 690;\n\n\n/**\n * Default target for popup windows\n * @type {string}\n */\ngoog.window.DEFAULT_POPUP_TARGET = 'google_popup';\n\n\n/**\n * @return {!Window}\n * @suppress {checkTypes}\n * @private\n */\ngoog.window.createFakeWindow_ = function() {\n  return /** @type {!Window} */ ({});\n};\n\n/**\n * Opens a new window.\n *\n * @param {!goog.html.SafeUrl|string|!Object|null} linkRef If an Object with an\n *     'href' attribute (such as HTMLAnchorElement) is passed then the value of\n *     'href' is used, otherwise its toString method is called. Note that if a\n *     string|Object is used, it will be sanitized with SafeUrl.sanitize().\n *\n * @param {?Object=} opt_options supports the following options:\n *  'target': (string) target (window name). If null, linkRef.target will\n *      be used.\n *  'width': (number) window width.\n *  'height': (number) window height.\n *  'top': (number) distance from top of screen\n *  'left': (number) distance from left of screen\n *  'toolbar': (boolean) show toolbar\n *  'scrollbars': (boolean) show scrollbars\n *  'location': (boolean) show location\n *  'statusbar': (boolean) show statusbar\n *  'menubar': (boolean) show menubar\n *  'resizable': (boolean) resizable\n *  'noreferrer': (boolean) whether to attempt to remove the referrer header\n *      from the request headers. Does this by opening a blank window that\n *      then redirects to the target url, so users may see some flickering.\n *  'noopener': (boolean) whether to remove the `opener` property from the\n *      window object of the newly created window. The property contains a\n *      reference to the original window, and can be used to launch a\n *      reverse tabnabbing attack.\n *\n * @param {?Window=} opt_parentWin Parent window that should be used to open the\n *                 new window.\n *\n * @return {?Window} Returns the window object that was opened. This returns\n *                  null if a popup blocker prevented the window from being\n *                  opened. In case when a new window is opened in a different\n *                  browser sandbox (such as iOS standalone mode), the returned\n *                  object is a emulated Window object that functions as if\n *                  a cross-origin window has been opened.\n */\ngoog.window.open = function(linkRef, opt_options, opt_parentWin) {\n  if (!opt_options) {\n    opt_options = {};\n  }\n  var parentWin = opt_parentWin || window;\n\n  /** @type {!goog.html.SafeUrl} */\n  var safeLinkRef;\n\n  if (linkRef instanceof goog.html.SafeUrl) {\n    safeLinkRef = linkRef;\n  } else {\n    // HTMLAnchorElement has a toString() method with the same behavior as\n    // goog.Uri in all browsers except for Safari, which returns\n    // '[object HTMLAnchorElement]'.  We check for the href first, then\n    // assume that it's a goog.Uri or String otherwise.\n    /**\n     * @type {string|!goog.string.TypedString}\n     * @suppress {missingProperties}\n     */\n    var url =\n        typeof linkRef.href != 'undefined' ? linkRef.href : String(linkRef);\n    safeLinkRef = goog.html.SafeUrl.sanitize(url);\n  }\n\n  /** @suppress {missingProperties} loose references to 'target' */\n  /** @suppress {strictMissingProperties} */\n  var target = opt_options.target || linkRef.target;\n\n  var sb = [];\n  for (var option in opt_options) {\n    switch (option) {\n      case 'width':\n      case 'height':\n      case 'top':\n      case 'left':\n        sb.push(option + '=' + opt_options[option]);\n        break;\n      case 'target':\n      case 'noopener':\n      case 'noreferrer':\n        break;\n      default:\n        sb.push(option + '=' + (opt_options[option] ? 1 : 0));\n    }\n  }\n  var optionString = sb.join(',');\n\n  var newWin;\n  if (goog.labs.userAgent.platform.isIos() && parentWin.navigator &&\n      parentWin.navigator['standalone'] && target && target != '_self') {\n    // iOS in standalone mode disregards \"target\" in window.open and always\n    // opens new URL in the same window. The workaround is to create an \"A\"\n    // element and send a click event to it.\n    // Notice that the \"A\" tag does NOT have to be added to the DOM.\n\n    var a = goog.dom.createElement(goog.dom.TagName.A);\n    goog.dom.safe.setAnchorHref(a, safeLinkRef);\n\n    a.setAttribute('target', target);\n    if (opt_options['noreferrer']) {\n      a.setAttribute('rel', 'noreferrer');\n    }\n\n    var click = /** @type {!MouseEvent} */ (document.createEvent('MouseEvent'));\n    click.initMouseEvent(\n        'click',\n        true,  // canBubble\n        true,  // cancelable\n        parentWin,\n        1);  // detail = mousebutton\n    a.dispatchEvent(click);\n    // New window is not available in this case. Instead, a fake Window object\n    // is returned. In particular, it will have window.document undefined. In\n    // general, it will appear to most of clients as a Window for a different\n    // origin. Since iOS standalone web apps are run in their own sandbox, this\n    // is the most appropriate return value.\n    newWin = goog.window.createFakeWindow_();\n  } else if (opt_options['noreferrer']) {\n    // This code used to use meta-refresh to stop the referrer from being\n    // included in the request headers. This was the only cross-browser way\n    // to remove the referrer circa 2009. However, this never worked in Chrome,\n    // and, instead newWin.opener had to be set to null on this browser. This\n    // behavior is slated to be removed in Chrome and should not be relied\n    // upon. Referrer Policy is the only spec'd and supported way of stripping\n    // referrers and works across all current browsers. This is used in\n    // addition to the aforementioned tricks.\n    //\n    // We also set the opener to be set to null in the new window, thus\n    // disallowing the opened window from navigating its opener.\n    //\n    // Detecting user agent and then using a different strategy per browser\n    // would allow the referrer to leak in case of an incorrect/missing user\n    // agent.\n    //\n    // Also note that we can't use goog.dom.safe.openInWindow here, as it\n    // requires a goog.string.Const 'name' parameter, while we're using plain\n    // strings here for target.\n    newWin = parentWin.open('', target, optionString);\n\n    var sanitizedLinkRef = goog.html.SafeUrl.unwrap(safeLinkRef);\n    if (newWin) {\n      if (goog.userAgent.EDGE_OR_IE) {\n        // IE/EDGE can't parse the content attribute if the url contains\n        // a semicolon. We can fix this by adding quotes around the url, but\n        // then we can't parse quotes in the URL correctly. We take a\n        // best-effort approach.\n        //\n        // If the URL has semicolons, wrap it in single quotes to protect\n        // the semicolons.\n        // If the URL has semicolons and single quotes, url-encode the single\n        // quotes as well.\n        //\n        // This is imperfect. Notice that both ' and ; are reserved characters\n        // in URIs, so this could do the wrong thing, but at least it will\n        // do the wrong thing in only rare cases.\n        // ugh.\n        if (goog.string.contains(sanitizedLinkRef, ';')) {\n          sanitizedLinkRef = \"'\" + sanitizedLinkRef.replace(/'/g, '%27') + \"'\";\n        }\n      }\n      newWin.opener = null;\n\n      // TODO(rjamet): Building proper SafeHtml with SafeHtml.createMetaRefresh\n      // pulls in a lot of compiled code, which is composed of various unneeded\n      // goog.html parts such as SafeStyle.create among others. So, for now,\n      // keep the unchecked conversion until we figure out how to make the\n      // dependencies of createSafeHtmlTagSecurityPrivateDoNotAccessOrElse less\n      // heavy.\n      var safeHtml =\n          goog.html.uncheckedconversions\n              .safeHtmlFromStringKnownToSatisfyTypeContract(\n                  goog.string.Const.from(\n                      'b/12014412, meta tag with sanitized URL'),\n                  '<meta name=\"referrer\" content=\"no-referrer\">' +\n                      '<meta http-equiv=\"refresh\" content=\"0; url=' +\n                      goog.string.htmlEscape(sanitizedLinkRef) + '\">');\n\n      // During window loading `newWin.document` may be unset in some browsers.\n      // Storing and checking a reference to the document prevents NPEs.\n      var newDoc = newWin.document;\n      if (newDoc) {\n        goog.dom.safe.documentWrite(newDoc, safeHtml);\n        newDoc.close();\n      }\n    }\n  } else {\n    newWin = parentWin.open(\n        goog.html.SafeUrl.unwrap(safeLinkRef), target, optionString);\n    // Passing in 'noopener' into the 'windowFeatures' param of window.open(...)\n    // will yield a feature-deprived browser. This is an known issue, tracked\n    // here: https://github.com/whatwg/html/issues/1902\n    if (newWin && opt_options['noopener']) {\n      newWin.opener = null;\n    }\n  }\n  // newWin is null if a popup blocker prevented the window open.\n  return newWin;\n};\n\n\n/**\n * Opens a new window without any real content in it.\n *\n * This can be used to get around popup blockers if you need to open a window\n * in response to a user event, but need to do asynchronous work to determine\n * the URL to open, and then set the URL later.\n *\n * Example usage:\n *\n * var newWin = goog.window.openBlank('Loading...');\n * setTimeout(\n *     function() {\n *       newWin.location.href = 'http://www.google.com';\n *     }, 100);\n *\n * @param {string=} opt_message String to show in the new window. This string\n *     will be HTML-escaped to avoid XSS issues.\n * @param {?Object=} opt_options Options to open window with.\n *     {@see goog.window.open for exact option semantics}.\n * @param {?Window=} opt_parentWin Parent window that should be used to open the\n *                 new window.\n * @return {?Window} Returns the window object that was opened. This returns\n *                  null if a popup blocker prevented the window from being\n *                  opened.\n */\ngoog.window.openBlank = function(opt_message, opt_options, opt_parentWin) {\n  // Open up a window with the loading message and nothing else.\n  // This will be interpreted as HTML content type with a missing doctype\n  // and html/body tags, but is otherwise acceptable.\n  //\n  // IMPORTANT: The order of escaping is crucial here in order to avoid XSS.\n  // First, HTML-escaping is needed because the result of the JS expression\n  // is evaluated as HTML. Second, JS-string escaping is needed; this avoids\n  // \\u escaping from inserting HTML tags and \\ from escaping the final \".\n  // Finally, URL percent-encoding is done with encodeURI(); this\n  // avoids percent-encoding from bypassing HTML and JS escaping.\n  //\n  // Note: There are other ways the same result could be achieved but the\n  // current behavior was preserved when this code was refactored to use\n  // SafeUrl, in order to avoid breakage.\n  var loadingMessage;\n  if (!opt_message) {\n    loadingMessage = '';\n  } else {\n    loadingMessage =\n        goog.string.escapeString(goog.string.htmlEscape(opt_message));\n  }\n  var url = goog.html.uncheckedconversions\n                .safeUrlFromStringKnownToSatisfyTypeContract(\n                    goog.string.Const.from(\n                        'b/12014412, encoded string in javascript: URL'),\n                    'javascript:\"' + encodeURI(loadingMessage) + '\"');\n  return /** @type {?Window} */ (\n      goog.window.open(url, opt_options, opt_parentWin));\n};\n\n\n/**\n * Raise a help popup window, defaulting to \"Google standard\" size and name.\n *\n * (If your project is using GXPs, consider using {@link PopUpLink.gxp}.)\n *\n* @param {?goog.html.SafeUrl|string|?Object} linkRef If an Object with an 'href'\n *     attribute (such as HTMLAnchorElement) is passed then the value of 'href'\n *     is used, otherwise  otherwise its toString method is called. Note that\n *     if a string|Object is used, it will be sanitized with SafeUrl.sanitize().\n *\n * @param {?Object=} opt_options Options to open window with.\n *     {@see goog.window.open for exact option semantics}\n *     Additional wrinkles to the options:\n *     - if 'target' field is null, linkRef.target will be used. If *that's*\n *     null, the default is \"google_popup\".\n *     - if 'width' field is not specified, the default is 690.\n *     - if 'height' field is not specified, the default is 500.\n *\n * @return {boolean} true if the window was not popped up, false if it was.\n */\ngoog.window.popup = function(linkRef, opt_options) {\n  if (!opt_options) {\n    opt_options = {};\n  }\n\n  // set default properties\n  opt_options['target'] = opt_options['target'] || linkRef['target'] ||\n      goog.window.DEFAULT_POPUP_TARGET;\n  opt_options['width'] =\n      opt_options['width'] || goog.window.DEFAULT_POPUP_WIDTH;\n  opt_options['height'] =\n      opt_options['height'] || goog.window.DEFAULT_POPUP_HEIGHT;\n\n  var newWin = goog.window.open(linkRef, opt_options);\n  if (!newWin) {\n    return true;\n  }\n  newWin.focus();\n\n  return false;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Type-safe wrappers for unsafe DOM APIs.\n *\n * This file provides type-safe wrappers for DOM APIs that can result in\n * cross-site scripting (XSS) vulnerabilities, if the API is supplied with\n * untrusted (attacker-controlled) input.  Instead of plain strings, the type\n * safe wrappers consume values of types from the goog.html package whose\n * contract promises that values are safe to use in the corresponding context.\n *\n * Hence, a program that exclusively uses the wrappers in this file (i.e., whose\n * only reference to security-sensitive raw DOM APIs are in this file) is\n * guaranteed to be free of XSS due to incorrect use of such DOM APIs (modulo\n * correctness of code that produces values of the respective goog.html types,\n * and absent code that violates type safety).\n *\n * For example, assigning to an element's .innerHTML property a string that is\n * derived (even partially) from untrusted input typically results in an XSS\n * vulnerability. The type-safe wrapper goog.dom.safe.setInnerHtml consumes a\n * value of type goog.html.SafeHtml, whose contract states that using its values\n * in a HTML context will not result in XSS. Hence a program that is free of\n * direct assignments to any element's innerHTML property (with the exception of\n * the assignment to .innerHTML in this file) is guaranteed to be free of XSS\n * due to assignment of untrusted strings to the innerHTML property.\n */\n\ngoog.provide('goog.dom.safe');\ngoog.provide('goog.dom.safe.InsertAdjacentHtmlPosition');\n\ngoog.require('goog.asserts');\ngoog.require('goog.dom.asserts');\ngoog.require('goog.functions');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.SafeScript');\ngoog.require('goog.html.SafeStyle');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.internal');\n\n\n/** @enum {string} */\ngoog.dom.safe.InsertAdjacentHtmlPosition = {\n  AFTERBEGIN: 'afterbegin',\n  AFTEREND: 'afterend',\n  BEFOREBEGIN: 'beforebegin',\n  BEFOREEND: 'beforeend'\n};\n\n\n/**\n * Inserts known-safe HTML into a Node, at the specified position.\n * @param {!Node} node The node on which to call insertAdjacentHTML.\n * @param {!goog.dom.safe.InsertAdjacentHtmlPosition} position Position where\n *     to insert the HTML.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to insert.\n */\ngoog.dom.safe.insertAdjacentHtml = function(node, position, html) {\n  node.insertAdjacentHTML(position, goog.html.SafeHtml.unwrapTrustedHTML(html));\n};\n\n\n/**\n * Tags not allowed in goog.dom.safe.setInnerHtml.\n * @private @const {!Object<string, boolean>}\n */\ngoog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_ = {\n  'MATH': true,\n  'SCRIPT': true,\n  'STYLE': true,\n  'SVG': true,\n  'TEMPLATE': true\n};\n\n\n/**\n * Whether assigning to innerHTML results in a non-spec-compliant clean-up. Used\n * to define goog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse.\n *\n * <p>As mentioned in https://stackoverflow.com/questions/28741528, re-rendering\n * an element in IE by setting innerHTML causes IE to recursively disconnect all\n * parent/children connections that were in the previous contents of the\n * element. Unfortunately, this can unexpectedly result in confusing cases where\n * a function is run (typically asynchronously) on element that has since\n * disconnected from the DOM but assumes the presence of its children. A simple\n * workaround is to remove all children first. Testing on IE11 via\n * https://jsperf.com/innerhtml-vs-removechild/239, removeChild seems to be\n * ~10x faster than innerHTML='' for a large number of children (perhaps due\n * to the latter's recursive behavior), implying that this workaround would\n * not hurt performance and might actually improve it.\n * @return {boolean}\n * @private\n */\ngoog.dom.safe.isInnerHtmlCleanupRecursive_ =\n    goog.functions.cacheReturnValue(function() {\n      // `document` missing in some test frameworks.\n      if (goog.DEBUG && typeof document === 'undefined') {\n        return false;\n      }\n      // Create 3 nested <div>s without using innerHTML.\n      // We're not chaining the appendChilds in one call,  as this breaks\n      // in a DocumentFragment.\n      var div = document.createElement('div');\n      var childDiv = document.createElement('div');\n      childDiv.appendChild(document.createElement('div'));\n      div.appendChild(childDiv);\n      // `firstChild` is null in Google Js Test.\n      if (goog.DEBUG && !div.firstChild) {\n        return false;\n      }\n      var innerChild = div.firstChild.firstChild;\n      div.innerHTML =\n          goog.html.SafeHtml.unwrapTrustedHTML(goog.html.SafeHtml.EMPTY);\n      return !innerChild.parentElement;\n    });\n\n\n/**\n * Assigns HTML to an element's innerHTML property. Helper to use only here and\n * in soy.js.\n * @param {?Element} elem The element whose innerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html\n */\ngoog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse = function(elem, html) {\n  // See comment above goog.dom.safe.isInnerHtmlCleanupRecursive_.\n  if (goog.dom.safe.isInnerHtmlCleanupRecursive_()) {\n    while (elem.lastChild) {\n      elem.removeChild(elem.lastChild);\n    }\n  }\n  elem.innerHTML = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Assigns known-safe HTML to an element's innerHTML property.\n * @param {!Element} elem The element whose innerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n * @throws {Error} If called with one of these tags: math, script, style, svg,\n *     template.\n */\ngoog.dom.safe.setInnerHtml = function(elem, html) {\n  if (goog.asserts.ENABLE_ASSERTS) {\n    var tagName = elem.tagName.toUpperCase();\n    if (goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[tagName]) {\n      throw new Error(\n          'goog.dom.safe.setInnerHtml cannot be used to set content of ' +\n          elem.tagName + '.');\n    }\n  }\n\n  goog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse(elem, html);\n};\n\n\n/**\n * Assigns known-safe HTML to an element's outerHTML property.\n * @param {!Element} elem The element whose outerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n */\ngoog.dom.safe.setOuterHtml = function(elem, html) {\n  elem.outerHTML = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Safely assigns a URL a form element's action property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * form's action property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.setFormElementAction(formEl, url);\n * which is a safe alternative to\n *   formEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} form The form element whose action property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setFormElementAction = function(form, url) {\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  goog.dom.asserts.assertIsHTMLFormElement(form).action =\n      goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a button element's formaction property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * button's formaction property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.setButtonFormAction(buttonEl, url);\n * which is a safe alternative to\n *   buttonEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} button The button element whose action property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setButtonFormAction = function(button, url) {\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  goog.dom.asserts.assertIsHTMLButtonElement(button).formAction =\n      goog.html.SafeUrl.unwrap(safeUrl);\n};\n/**\n * Safely assigns a URL to an input element's formaction property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * input's formaction property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.setInputFormAction(inputEl, url);\n * which is a safe alternative to\n *   inputEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} input The input element whose action property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setInputFormAction = function(input, url) {\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  goog.dom.asserts.assertIsHTMLInputElement(input).formAction =\n      goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Sets the given element's style property to the contents of the provided\n * SafeStyle object.\n * @param {!Element} elem\n * @param {!goog.html.SafeStyle} style\n */\ngoog.dom.safe.setStyle = function(elem, style) {\n  elem.style.cssText = goog.html.SafeStyle.unwrap(style);\n};\n\n\n/**\n * Writes known-safe HTML to a document.\n * @param {!Document} doc The document to be written to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n */\ngoog.dom.safe.documentWrite = function(doc, html) {\n  doc.write(goog.html.SafeHtml.unwrapTrustedHTML(html));\n};\n\n\n/**\n * Safely assigns a URL to an anchor element's href property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * anchor's href property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.setAnchorHref(anchorEl, url);\n * which is a safe alternative to\n *   anchorEl.href = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!HTMLAnchorElement} anchor The anchor element whose href property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setAnchorHref = function(anchor, url) {\n  goog.dom.asserts.assertIsHTMLAnchorElement(anchor);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  anchor.href = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n\n/**\n * Safely assigns a URL to an image element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * image's src property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLImageElement} imageElement The image element whose src property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setImageSrc = function(imageElement, url) {\n  goog.dom.asserts.assertIsHTMLImageElement(imageElement);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    var allowDataUrl = /^data:image\\//i.test(url);\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n  }\n  imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a audio element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * audio's src property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLAudioElement} audioElement The audio element whose src property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setAudioSrc = function(audioElement, url) {\n  goog.dom.asserts.assertIsHTMLAudioElement(audioElement);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    var allowDataUrl = /^data:audio\\//i.test(url);\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n  }\n  audioElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a video element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * video's src property.  If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLVideoElement} videoElement The video element whose src property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setVideoSrc = function(videoElement, url) {\n  goog.dom.asserts.assertIsHTMLVideoElement(videoElement);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    var allowDataUrl = /^data:video\\//i.test(url);\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n  }\n  videoElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to an embed element's src property.\n *\n * Example usage:\n *   goog.dom.safe.setEmbedSrc(embedEl, url);\n * which is a safe alternative to\n *   embedEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLEmbedElement} embed The embed element whose src property\n *     is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setEmbedSrc = function(embed, url) {\n  goog.dom.asserts.assertIsHTMLEmbedElement(embed);\n  embed.src = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\n};\n\n\n/**\n * Safely assigns a URL to a frame element's src property.\n *\n * Example usage:\n *   goog.dom.safe.setFrameSrc(frameEl, url);\n * which is a safe alternative to\n *   frameEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLFrameElement} frame The frame element whose src property\n *     is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setFrameSrc = function(frame, url) {\n  goog.dom.asserts.assertIsHTMLFrameElement(frame);\n  frame.src = goog.html.TrustedResourceUrl.unwrap(url);\n};\n\n\n/**\n * Safely assigns a URL to an iframe element's src property.\n *\n * Example usage:\n *   goog.dom.safe.setIframeSrc(iframeEl, url);\n * which is a safe alternative to\n *   iframeEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLIFrameElement} iframe The iframe element whose src property\n *     is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setIframeSrc = function(iframe, url) {\n  goog.dom.asserts.assertIsHTMLIFrameElement(iframe);\n  iframe.src = goog.html.TrustedResourceUrl.unwrap(url);\n};\n\n\n/**\n * Safely assigns HTML to an iframe element's srcdoc property.\n *\n * Example usage:\n *   goog.dom.safe.setIframeSrcdoc(iframeEl, safeHtml);\n * which is a safe alternative to\n *   iframeEl.srcdoc = html;\n * The latter can result in loading untrusted code.\n *\n * @param {!HTMLIFrameElement} iframe The iframe element whose srcdoc property\n *     is to be assigned to.\n * @param {!goog.html.SafeHtml} html The HTML to assign.\n */\ngoog.dom.safe.setIframeSrcdoc = function(iframe, html) {\n  goog.dom.asserts.assertIsHTMLIFrameElement(iframe);\n  iframe.srcdoc = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Safely sets a link element's href and rel properties. Whether or not\n * the URL assigned to href has to be a goog.html.TrustedResourceUrl\n * depends on the value of the rel property. If rel contains \"stylesheet\"\n * then a TrustedResourceUrl is required.\n *\n * Example usage:\n *   goog.dom.safe.setLinkHrefAndRel(linkEl, url, 'stylesheet');\n * which is a safe alternative to\n *   linkEl.rel = 'stylesheet';\n *   linkEl.href = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLLinkElement} link The link element whose href property\n *     is to be assigned to.\n * @param {string|!goog.html.SafeUrl|!goog.html.TrustedResourceUrl} url The URL\n *     to assign to the href property. Must be a TrustedResourceUrl if the\n *     value assigned to rel contains \"stylesheet\". A string value is\n *     sanitized with goog.html.SafeUrl.sanitize.\n * @param {string} rel The value to assign to the rel property.\n * @throws {Error} if rel contains \"stylesheet\" and url is not a\n *     TrustedResourceUrl\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {\n  goog.dom.asserts.assertIsHTMLLinkElement(link);\n  link.rel = rel;\n  if (goog.string.internal.caseInsensitiveContains(rel, 'stylesheet')) {\n    goog.asserts.assert(\n        url instanceof goog.html.TrustedResourceUrl,\n        'URL must be TrustedResourceUrl because \"rel\" contains \"stylesheet\"');\n    link.href = goog.html.TrustedResourceUrl.unwrap(url);\n  } else if (url instanceof goog.html.TrustedResourceUrl) {\n    link.href = goog.html.TrustedResourceUrl.unwrap(url);\n  } else if (url instanceof goog.html.SafeUrl) {\n    link.href = goog.html.SafeUrl.unwrap(url);\n  } else {  // string\n    // SafeUrl.sanitize must return legitimate SafeUrl when passed a string.\n    link.href = goog.html.SafeUrl.unwrap(\n        goog.html.SafeUrl.sanitizeAssertUnchanged(url));\n  }\n};\n\n\n/**\n * Safely assigns a URL to an object element's data property.\n *\n * Example usage:\n *   goog.dom.safe.setObjectData(objectEl, url);\n * which is a safe alternative to\n *   objectEl.data = url;\n * The latter can result in loading untrusted code unless setit is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLObjectElement} object The object element whose data property\n *     is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setObjectData = function(object, url) {\n  goog.dom.asserts.assertIsHTMLObjectElement(object);\n  object.data = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\n};\n\n\n/**\n * Safely assigns a URL to a script element's src property.\n *\n * Example usage:\n *   goog.dom.safe.setScriptSrc(scriptEl, url);\n * which is a safe alternative to\n *   scriptEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLScriptElement} script The script element whose src property\n *     is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setScriptSrc = function(script, url) {\n  goog.dom.asserts.assertIsHTMLScriptElement(script);\n  script.src = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\n\n  // If CSP nonces are used, propagate them to dynamically created scripts.\n  // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n  var nonce = goog.getScriptNonce();\n  if (nonce) {\n    script.setAttribute('nonce', nonce);\n  }\n};\n\n\n/**\n * Safely assigns a value to a script element's content.\n *\n * Example usage:\n *   goog.dom.safe.setScriptContent(scriptEl, content);\n * which is a safe alternative to\n *   scriptEl.text = content;\n * The latter can result in executing untrusted code unless it is ensured that\n * the code is loaded from a trustworthy resource.\n *\n * @param {!HTMLScriptElement} script The script element whose content is being\n *     set.\n * @param {!goog.html.SafeScript} content The content to assign.\n */\ngoog.dom.safe.setScriptContent = function(script, content) {\n  goog.dom.asserts.assertIsHTMLScriptElement(script);\n  script.text = goog.html.SafeScript.unwrapTrustedScript(content);\n\n  // If CSP nonces are used, propagate them to dynamically created scripts.\n  // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n  var nonce = goog.getScriptNonce();\n  if (nonce) {\n    script.setAttribute('nonce', nonce);\n  }\n};\n\n\n/**\n * Safely assigns a URL to a Location object's href property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * loc's href property.  If url is of type string however, it is first sanitized\n * using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.setLocationHref(document.location, redirectUrl);\n * which is a safe alternative to\n *   document.location.href = redirectUrl;\n * The latter can result in XSS vulnerabilities if redirectUrl is a\n * user-/attacker-controlled value.\n *\n * @param {!Location} loc The Location object whose href property is to be\n *     assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setLocationHref = function(loc, url) {\n  goog.dom.asserts.assertIsLocation(loc);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  loc.href = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns the URL of a Location object.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and\n * passed to Location#assign. If url is of type string however, it is\n * first sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.assignLocation(document.location, newUrl);\n * which is a safe alternative to\n *   document.location.assign(newUrl);\n * The latter can result in XSS vulnerabilities if newUrl is a\n * user-/attacker-controlled value.\n *\n * This has the same behaviour as setLocationHref, however some test\n * mock Location.assign instead of a property assignment.\n *\n * @param {!Location} loc The Location object which is to be assigned.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.assignLocation = function(loc, url) {\n  goog.dom.asserts.assertIsLocation(loc);\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  loc.assign(goog.html.SafeUrl.unwrap(safeUrl));\n};\n\n\n/**\n * Safely replaces the URL of a Location object.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and\n * passed to Location#replace. If url is of type string however, it is\n * first sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n *   goog.dom.safe.replaceLocation(document.location, newUrl);\n * which is a safe alternative to\n *   document.location.replace(newUrl);\n * The latter can result in XSS vulnerabilities if newUrl is a\n * user-/attacker-controlled value.\n *\n * @param {!Location} loc The Location object which is to be replaced.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.replaceLocation = function(loc, url) {\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  loc.replace(goog.html.SafeUrl.unwrap(safeUrl));\n};\n\n\n/**\n * Safely opens a URL in a new window (via window.open).\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and passed in to\n * window.open.  If url is of type string however, it is first sanitized\n * using goog.html.SafeUrl.sanitize.\n *\n * Note that this function does not prevent leakages via the referer that is\n * sent by window.open. It is advised to only use this to open 1st party URLs.\n *\n * Example usage:\n *   goog.dom.safe.openInWindow(url);\n * which is a safe alternative to\n *   window.open(url);\n * The latter can result in XSS vulnerabilities if redirectUrl is a\n * user-/attacker-controlled value.\n *\n * @param {string|!goog.html.SafeUrl} url The URL to open.\n * @param {Window=} opt_openerWin Window of which to call the .open() method.\n *     Defaults to the global window.\n * @param {!goog.string.Const=} opt_name Name of the window to open in. Can be\n *     _top, etc as allowed by window.open().\n * @param {string=} opt_specs Comma-separated list of specifications, same as\n *     in window.open().\n * @param {boolean=} opt_replace Whether to replace the current entry in browser\n *     history, same as in window.open().\n * @return {Window} Window the url was opened in.\n */\ngoog.dom.safe.openInWindow = function(\n    url, opt_openerWin, opt_name, opt_specs, opt_replace) {\n  /** @type {!goog.html.SafeUrl} */\n  var safeUrl;\n  if (url instanceof goog.html.SafeUrl) {\n    safeUrl = url;\n  } else {\n    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n  }\n  var win = opt_openerWin || goog.global;\n  return win.open(\n      goog.html.SafeUrl.unwrap(safeUrl),\n      // If opt_name is undefined, simply passing that in to open() causes IE to\n      // reuse the current window instead of opening a new one. Thus we pass ''\n      // in instead, which according to spec opens a new window. See\n      // https://html.spec.whatwg.org/multipage/browsers.html#dom-open .\n      opt_name ? goog.string.Const.unwrap(opt_name) : '', opt_specs,\n      opt_replace);\n};\n\n\n/**\n * Parses the HTML as 'text/html'.\n * @param {!DOMParser} parser\n * @param {!goog.html.SafeHtml} html The HTML to be parsed.\n * @return {?Document}\n */\ngoog.dom.safe.parseFromStringHtml = function(parser, html) {\n  return goog.dom.safe.parseFromString(parser, html, 'text/html');\n};\n\n\n/**\n * Parses the string.\n * @param {!DOMParser} parser\n * @param {!goog.html.SafeHtml} content Note: We don't have a special type for\n *     XML od SVG supported by this function so we use SafeHtml.\n * @param {string} type\n * @return {?Document}\n */\ngoog.dom.safe.parseFromString = function(parser, content, type) {\n  return parser.parseFromString(\n      goog.html.SafeHtml.unwrapTrustedHTML(content), type);\n};\n\n\n/**\n * Safely creates an HTMLImageElement from a Blob.\n *\n * Example usage:\n *     goog.dom.safe.createImageFromBlob(blob);\n * which is a safe alternative to\n *     image.src = createObjectUrl(blob)\n * The latter can result in executing malicious same-origin scripts from a bad\n * Blob.\n * @param {!Blob} blob The blob to create the image from.\n * @return {!HTMLImageElement} The image element created from the blob.\n * @throws {!Error} If called with a Blob with a MIME type other than image/.*.\n */\ngoog.dom.safe.createImageFromBlob = function(blob) {\n  // Any image/* MIME type is accepted as safe.\n  if (!/^image\\/.*/g.test(blob.type)) {\n    throw new Error(\n        'goog.dom.safe.createImageFromBlob only accepts MIME type image/.*.');\n  }\n  var objectUrl = goog.global.URL.createObjectURL(blob);\n  var image = new goog.global.Image();\n  image.onload = function() {\n    goog.global.URL.revokeObjectURL(objectUrl);\n  };\n  goog.dom.safe.setImageSrc(\n      image,\n      goog.html.uncheckedconversions\n          .safeUrlFromStringKnownToSatisfyTypeContract(\n              goog.string.Const.from('Image blob URL.'), objectUrl));\n  return image;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Provides methods for manipulating objects.\n */\n\ngoog.provide('fireauth.object');\n\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.deprecation.Deprecations');\n\n\n/**\n * Checks whether the defineProperty method allows to change the value of\n * the property.\n * @return {boolean} Whether the defineProperty method allows to change the\n *    value of the property.\n * @private\n */\nfireauth.object.isReadonlyConfigurable_ = function() {\n  // Android 2.3 stock browser doesn't allow to change the value of\n  // a read-only property once defined.\n  try {\n    var obj = {};\n    Object.defineProperty(obj, 'abcd', {\n      configurable: true,\n      enumerable: true,\n      value: 1\n    });\n    Object.defineProperty(obj, 'abcd', {\n      configurable: true,\n      enumerable: true,\n      value: 2\n    });\n    return obj['abcd'] == 2;\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * @private {boolean} Whether the defineProperty method allows to change the\n *     value of the property.\n */\nfireauth.object.readonlyConfigurable_ =\n    fireauth.object.isReadonlyConfigurable_();\n\n\n/**\n * Defines a property on an object that is not writable by clients. However, the\n * property can be overwritten within the Firebase library through subsequent\n * calls to setReadonlyProperty.\n *\n * In browsers that do not support read-only properties (notably IE8 and below),\n * fall back to writable properties.\n *\n * @param {!Object} obj The object to which we add the property.\n * @param {string} key The name of the property.\n * @param {*} value The desired value.\n */\nfireauth.object.setReadonlyProperty = function(obj, key, value) {\n  if (fireauth.object.readonlyConfigurable_) {\n    Object.defineProperty(obj, key, {\n      configurable: true,\n      enumerable: true,\n      value: value\n    });\n  } else {\n    obj[key] = value;\n  }\n};\n\n\n/**\n * Defines a deprecated property, which emits a warning if the developer tries\n * to use it.\n *\n * In browsers that do not support getters, we fall back to a normal property\n * with no message.\n *\n * @param {!Object} obj The object to which we add the property.\n * @param {string} key The name of the deprecated property.\n * @param {*} value The desired value.\n * @param {!fireauth.deprecation.Deprecations} deprecationMessage The\n *     deprecation warning to display.\n */\nfireauth.object.setDeprecatedReadonlyProperty = function(obj, key, value,\n    deprecationMessage) {\n  if (fireauth.object.readonlyConfigurable_) {\n    Object.defineProperty(obj, key, {\n      configurable: true,\n      enumerable: true,\n      get: function() {\n        fireauth.deprecation.log(deprecationMessage);\n        return value;\n      }\n    });\n  } else {\n    obj[key] = value;\n  }\n};\n\n\n/**\n * Defines properties on an object that are not writable by clients, equivalent\n * to many calls to setReadonlyProperty.\n * @param {!Object} obj The object to which we add the properties.\n * @param {?Object<string, *>} props An object that maps the keys and values\n *     that we wish to add.\n */\nfireauth.object.setReadonlyProperties = function(obj, props) {\n  if (!props) {\n    return;\n  }\n\n  for (var key in props) {\n    if (props.hasOwnProperty(key)) {\n      fireauth.object.setReadonlyProperty(obj, key, props[key]);\n    }\n  }\n};\n\n\n/**\n * Makes a shallow read-only copy of an object. The writability of any child\n * objects will not be affected.\n * @param {?Object} obj The object that we wish to copy.\n * @return {!Object}\n */\nfireauth.object.makeReadonlyCopy = function(obj) {\n  var output = {};\n  fireauth.object.setReadonlyProperties(output, obj);\n  return output;\n};\n\n\n/**\n * Makes a shallow writable copy of a read-only object. The writability of any\n * child objects will not be affected.\n * @param {?Object} obj The object that we wish to copy.\n * @return {!Object}\n */\nfireauth.object.makeWritableCopy = function(obj) {\n  var output = {};\n  for (var key in obj) {\n    if (obj.hasOwnProperty(key)) {\n      output[key] = obj[key];\n    }\n  }\n  return output;\n};\n\n\n/**\n * Returns true if the all the specified fields are present in obj and are not\n * null, undefined, or the empty string. If the field list is empty, returns\n * true regardless of the value of obj.\n * @param {?Object=} opt_obj The object.\n * @param {?Array<string>=} opt_fields The desired fields of the object.\n * @return {boolean} True if obj has all the specified fields.\n */\nfireauth.object.hasNonEmptyFields = function(opt_obj, opt_fields) {\n  if (!opt_fields || !opt_fields.length) {\n    return true;\n  }\n  if (!opt_obj) {\n    return false;\n  }\n  for (var i = 0; i < opt_fields.length; i++) {\n    var field = opt_obj[opt_fields[i]];\n    if (field === undefined || field === null || field === '') {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * Traverses the specified object and creates a read-only deep copy of it.\n * This will fail when circular references are contained within the object.\n * @param {*} obj The object to make a read-only copy from.\n * @return {*} A Read-only copy of the obj specified.\n */\nfireauth.object.unsafeCreateReadOnlyCopy = function(obj) {\n  var copy = obj;\n  if (typeof obj == 'object' && obj != null) {\n    // Make the right type of copy.\n    copy = 'length' in obj ? [] : {};\n    // Make a deep copy.\n    for (var key in obj) {\n      fireauth.object.setReadonlyProperty(\n          copy, key, fireauth.object.unsafeCreateReadOnlyCopy(obj[key]));\n    }\n  }\n  // Return the copy.\n  return copy;\n};\n\n","/**\n * @license\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the multi-factor enrollment information.\n */\n\ngoog.provide('fireauth.MultiFactorInfo');\ngoog.provide('fireauth.PhoneMultiFactorInfo');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.object');\n\n\n/**\n * Abstract class representing a `firebase.auth.MultiFactorInfo` interface.\n * This is typically parsed from a server response.\n * @param {?Object} resp The server response.\n * @abstract\n * @constructor\n */\nfireauth.MultiFactorInfo = function(resp) {\n  var factorId = resp && this.getFactorId(resp);\n  if (factorId && resp &&\n      resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID]) {\n    fireauth.object.setReadonlyProperty(\n        this,\n        'uid',\n        resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID]);\n    fireauth.object.setReadonlyProperty(\n        this,\n        'displayName',\n        resp[fireauth.MultiFactorInfo.MfaEnrollmentField.DISPLAY_NAME] || null);\n    var enrollmentTime = null;\n    // Encoded using [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format.\n    // For example, \"2017-01-15T01:30:15.01Z\".\n    // This can be parsed directly in modern browsers via Date constructor.\n    // This can be computed using Data.prototype.toISOString.\n    if (resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT]) {\n      enrollmentTime = new Date(\n            resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT])\n                .toUTCString();\n    }\n    fireauth.object.setReadonlyProperty(\n        this,\n        'enrollmentTime',\n        enrollmentTime);\n    fireauth.object.setReadonlyProperty(\n        this,\n        'factorId',\n        factorId);\n  } else {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INTERNAL_ERROR,\n        'Internal assert: invalid MultiFactorInfo object');\n  }\n};\n\n\n/** @return {!Object} The plain object representation. */\nfireauth.MultiFactorInfo.prototype.toPlainObject = function() {\n  return {\n    'uid': this['uid'],\n    'displayName': this['displayName'],\n    'factorId': this['factorId'],\n    'enrollmentTime': this['enrollmentTime']\n  };\n};\n\n\n/**\n * Returns the factor ID based on the server response. This function needs to be\n * implemented by the subclass.\n * @param {!Object} resp The server response.\n * @return {?fireauth.constants.SecondFactorType} The factor ID based on the\n *     response type.\n * @protected\n */\nfireauth.MultiFactorInfo.prototype.getFactorId = goog.abstractMethod;\n\n\n/**\n * Returns the corresponding `firebase.auth.MultiFactor` instance if the\n * server response maps to one. Otherwise, null is returned.\n * @param {?Object} resp The server response.\n * @return {?fireauth.MultiFactorInfo} The corresponding\n *     `firebase.auth.MultiFactorInfo` instance, null otherwise.\n */\nfireauth.MultiFactorInfo.fromServerResponse = function(resp) {\n  var multiFactorInfo;\n  // Only PhoneMultiFactorInfo currently available.\n  try {\n    multiFactorInfo = new fireauth.PhoneMultiFactorInfo(resp);\n  } catch (e) {\n    multiFactorInfo = null;\n  }\n  return multiFactorInfo;\n};\n\n\n/**\n * Returns the corresponding `firebase.auth.MultiFactor` instance if the\n * plain object maps to one. Otherwise, null is returned.\n * @param {?Object} obj The plain object representation.\n * @return {?fireauth.MultiFactorInfo} The corresponding\n *     `firebase.auth.MultiFactorInfo` instance, null otherwise.\n */\nfireauth.MultiFactorInfo.fromPlainObject = function(obj) {\n  var multiFactorInfo = null;\n  var resp = {};\n  if (!obj) {\n    return null;\n  }\n  if (obj['uid']) {\n    resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID] =\n        obj['uid'];\n  }\n  if (obj['displayName']) {\n    resp[fireauth.MultiFactorInfo.MfaEnrollmentField.DISPLAY_NAME] =\n        obj['displayName'];\n  }\n  if (obj['enrollmentTime']) {\n    resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT] =\n        new Date(obj['enrollmentTime']).toISOString();\n  }\n  if (obj['phoneNumber']) {\n    resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO] =\n        obj['phoneNumber'];\n  }\n\n  // Only PhoneMultiFactorInfo currently available.\n  try {\n    multiFactorInfo = new fireauth.PhoneMultiFactorInfo(resp);\n  } catch (e) {\n    // Ignore error.\n  }\n  return multiFactorInfo;\n};\n\n\n/**\n * MfaEnrollment server side response fields.\n * @enum {string}\n */\nfireauth.MultiFactorInfo.MfaEnrollmentField = {\n  DISPLAY_NAME: 'displayName',\n  ENROLLED_AT: 'enrolledAt',\n  MFA_ENROLLMENT_ID: 'mfaEnrollmentId',\n  PHONE_INFO: 'phoneInfo'\n};\n\n\n/**\n * Initializes a `firebase.auth.PhoneMultiFactorInfo` instance from the provided\n * server response.\n * @param {?Object} resp The server response.\n * @constructor\n * @extends {fireauth.MultiFactorInfo}\n */\nfireauth.PhoneMultiFactorInfo = function(resp) {\n  fireauth.PhoneMultiFactorInfo.base(this, 'constructor', resp);\n  fireauth.object.setReadonlyProperty(\n      this,\n      'phoneNumber',\n      // PhoneInfo may be masked for security reasons for sign-in flows after\n      // the user signs in with the first factor but hasn't yet proven ownership\n      // of the second factor yet.\n      // For enrollment flows or for a user already signed in with a second\n      // factor, this field should not be masked.\n      resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO]);\n};\ngoog.inherits(\n    fireauth.PhoneMultiFactorInfo, fireauth.MultiFactorInfo);\n\n\n/**\n * Implements the factor ID getter based on the response. If the response is an\n * invalid PhoneMultiFactorInfo, null is returned.\n * @param {!Object} resp The server response.\n * @return {?fireauth.constants.SecondFactorType} The phone factor ID.\n * @protected\n * @override\n */\nfireauth.PhoneMultiFactorInfo.prototype.getFactorId = function(resp) {\n  return !!resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO] ?\n      fireauth.constants.SecondFactorType.PHONE : null;\n};\n\n\n/**\n * @return {!Object} The plain object representation.\n * @override\n */\nfireauth.PhoneMultiFactorInfo.prototype.toPlainObject = function() {\n  var obj = fireauth.PhoneMultiFactorInfo.base(this, 'toPlainObject');\n  obj['phoneNumber'] = this['phoneNumber'];\n  return obj;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the firebase.auth.ActionCodeInfo class that is returned\n * when calling checkActionCode API and is populated from the server response\n * directly.\n */\n\ngoog.provide('fireauth.ActionCodeInfo');\n\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.object');\n\n\n/**\n * Constructs the action code info object which provides metadata corresponding\n * to action codes. This includes the type of operation (RESET_PASSWORD,\n * VERIFY_EMAIL and RECOVER_EMAIL), the email corresponding to the operation\n * and in case of the recover email flow, the old and new email.\n * @param {!Object} response The server response for checkActionCode.\n * @constructor\n */\nfireauth.ActionCodeInfo = function(response) {\n  var data = {};\n  // Original email for email change revocation.\n  var email = response[fireauth.ActionCodeInfo.ServerFieldName.EMAIL];\n  // The new email.\n  var newEmail = response[fireauth.ActionCodeInfo.ServerFieldName.NEW_EMAIL];\n  var operation =\n      response[fireauth.ActionCodeInfo.ServerFieldName.REQUEST_TYPE];\n  // The multi-factor info for revert second factor addition.\n  var mfaInfo =\n      fireauth.MultiFactorInfo.fromServerResponse(\n          response[fireauth.ActionCodeInfo.ServerFieldName.MFA_INFO]);\n  // Email could be empty only if the request type is EMAIL_SIGNIN or\n  // VERIFY_AND_CHANGE_EMAIL.\n  // New email should not be empty if the request type is\n  // VERIFY_AND_CHANGE_EMAIL.\n  // Multi-factor info could not be empty if the request type is\n  // REVERT_SECOND_FACTOR_ADDITION.\n  if (!operation ||\n      (operation != fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN &&\n       operation != fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL &&\n       !email) ||\n      (operation == fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL &&\n       !newEmail) ||\n      (operation ==\n       fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION &&\n       !mfaInfo)) {\n    // This is internal only.\n    throw new Error('Invalid checkActionCode response!');\n  }\n  if (operation == fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL) {\n    data[fireauth.ActionCodeInfo.DataField.FROM_EMAIL] = email || null;\n    data[fireauth.ActionCodeInfo.DataField.PREVIOUS_EMAIL] = email || null;\n    data[fireauth.ActionCodeInfo.DataField.EMAIL] = newEmail;\n  } else {\n    data[fireauth.ActionCodeInfo.DataField.FROM_EMAIL] = newEmail || null;\n    data[fireauth.ActionCodeInfo.DataField.PREVIOUS_EMAIL] = newEmail || null;\n    data[fireauth.ActionCodeInfo.DataField.EMAIL] = email || null;\n  }\n  data[fireauth.ActionCodeInfo.DataField.MULTI_FACTOR_INFO] = mfaInfo || null;\n  fireauth.object.setReadonlyProperty(\n      this,\n      fireauth.ActionCodeInfo.PropertyName.OPERATION,\n      operation);\n  fireauth.object.setReadonlyProperty(\n      this,\n      fireauth.ActionCodeInfo.PropertyName.DATA,\n      fireauth.object.unsafeCreateReadOnlyCopy(data));\n};\n\n\n/**\n * Firebase Auth Action Code Info operation possible values.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.Operation = {\n  PASSWORD_RESET: 'PASSWORD_RESET',\n  RECOVER_EMAIL: 'RECOVER_EMAIL',\n  REVERT_SECOND_FACTOR_ADDITION: 'REVERT_SECOND_FACTOR_ADDITION',\n  EMAIL_SIGNIN: 'EMAIL_SIGNIN',\n  VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',\n  VERIFY_EMAIL: 'VERIFY_EMAIL'\n};\n\n\n/**\n * The checkActionCode endpoint server response field names.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.ServerFieldName = {\n  // This is the current email of the account and in email recovery, the email\n  // to revert to.\n  EMAIL: 'email',\n  // The multi-factor info to unenroll for revert second factor addition action.\n  MFA_INFO: 'mfaInfo',\n  // For email recovery, this is the new email.\n  NEW_EMAIL: 'newEmail',\n  // The action code request type.\n  REQUEST_TYPE: 'requestType'\n};\n\n\n/**\n * The ActionCodeInfo data object field names.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.DataField = {\n  EMAIL: 'email',\n  // This field will be deprecated in favor of PREVIOUS_EMAIL.\n  FROM_EMAIL: 'fromEmail',\n  MULTI_FACTOR_INFO: 'multiFactorInfo',\n  PREVIOUS_EMAIL: 'previousEmail'\n};\n\n\n/**\n * The ActionCodeInfo main property names\n * @enum {string}\n */\nfireauth.ActionCodeInfo.PropertyName = {\n  DATA: 'data',\n  OPERATION: 'operation'\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines firebase.auth.ActionCodeURL class which is the utility\n * to parse action code URLs.\n */\n\ngoog.provide('fireauth.ActionCodeURL');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('goog.Uri');\n\n\n/**\n * The utility class to help parse action code URLs used for out of band email\n * flows such as password reset, email verification, email link sign in, etc.\n * @param {string} actionLink The action link string.\n * @constructor\n */\nfireauth.ActionCodeURL = function(actionLink) {\n  var uri = goog.Uri.parse(actionLink);\n  var apiKey = uri.getParameterValue(\n      fireauth.ActionCodeURL.QueryField.API_KEY) || null;\n  var code = uri.getParameterValue(\n      fireauth.ActionCodeURL.QueryField.CODE) || null;\n  var mode = uri.getParameterValue(\n      fireauth.ActionCodeURL.QueryField.MODE) || null;\n  var operation = fireauth.ActionCodeURL.getOperation(mode);\n  // Validate API key, code and mode.\n  if (!apiKey || !code || !operation) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        fireauth.ActionCodeURL.QueryField.API_KEY + ', ' +\n        fireauth.ActionCodeURL.QueryField.CODE + 'and ' +\n        fireauth.ActionCodeURL.QueryField.MODE +\n        ' are required in a valid action code URL.');\n  }\n  fireauth.object.setReadonlyProperties(this, {\n    'apiKey': apiKey,\n    'operation': operation,\n    'code': code,\n    'continueUrl': uri.getParameterValue(\n        fireauth.ActionCodeURL.QueryField.CONTINUE_URL) || null,\n    'languageCode': uri.getParameterValue(\n        fireauth.ActionCodeURL.QueryField.LANGUAGE_CODE) || null,\n    'tenantId': uri.getParameterValue(\n        fireauth.ActionCodeURL.QueryField.TENANT_ID) || null\n  });\n};\n\n/**\n * Enums for fields in URL query string.\n * @enum {string}\n */\nfireauth.ActionCodeURL.QueryField = {\n  API_KEY: 'apiKey',\n  CODE: 'oobCode',\n  CONTINUE_URL: 'continueUrl',\n  LANGUAGE_CODE: 'languageCode',\n  MODE: 'mode',\n  TENANT_ID: 'tenantId'\n};\n\n\n/**\n * Map of mode string to Action Code Info operation.\n * @const @private {!Object<string, !fireauth.ActionCodeInfo.Operation>}\n */\nfireauth.ActionCodeURL.ModeToOperationMap_ = {\n  'recoverEmail': fireauth.ActionCodeInfo.Operation.RECOVER_EMAIL,\n  'resetPassword': fireauth.ActionCodeInfo.Operation.PASSWORD_RESET,\n  'revertSecondFactorAddition':\n      fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION,\n  'signIn': fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN,\n  'verifyAndChangeEmail':\n      fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL,\n  'verifyEmail': fireauth.ActionCodeInfo.Operation.VERIFY_EMAIL\n};\n\n\n/**\n * Maps the mode string in action code URL to Action Code Info operation.\n * @param {?string} mode The mode string in the URL.\n * @return {?fireauth.ActionCodeInfo.Operation}\n */\nfireauth.ActionCodeURL.getOperation = function(mode) {\n  if (!mode) {\n    return null;\n  }\n  return fireauth.ActionCodeURL.ModeToOperationMap_[mode] || null;\n\n};\n\n\n/**\n * Returns an ActionCodeURL instance if the link is valid, otherwise null.\n * @param {string} actionLink The action code link string.\n * @return {?fireauth.ActionCodeURL}\n */\nfireauth.ActionCodeURL.parseLink = function(actionLink) {\n  try {\n    return new fireauth.ActionCodeURL(actionLink);\n  } catch(e) {\n    return null;\n  }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Utility for firebase.auth.ActionCodeSettings and its helper\n * functions.\n */\n\ngoog.provide('fireauth.ActionCodeSettings');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Defines the action code settings structure used to specify how email action\n * links are handled.\n * @param {!Object} settingsObj The action code settings object used to\n *     construct the action code link.\n * @constructor @struct @final\n */\nfireauth.ActionCodeSettings = function(settingsObj) {\n  // Validate the settings object passed.\n  this.initialize_(settingsObj);\n};\n\n\n/**\n * Validate the action code settings object.\n * @param {!Object} settingsObj The action code settings object to validate.\n * @private\n */\nfireauth.ActionCodeSettings.prototype.initialize_ = function(settingsObj) {\n  // URL should be required.\n  var continueUrl = settingsObj[fireauth.ActionCodeSettings.RawField.URL];\n  if (typeof continueUrl === 'undefined') {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CONTINUE_URI);\n  } else if (typeof continueUrl !== 'string' ||\n             (typeof continueUrl === 'string' && !continueUrl.length)) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_CONTINUE_URI);\n  }\n  /** @const @private {string} The continue URL. */\n  this.continueUrl_ = /** @type {string} */ (continueUrl);\n\n  // Validate Android parameters.\n  /** @private {?string} The Android package name. */\n  this.apn_ = null;\n  /** @private {?string} The Android minimum version. */\n  this.amv_ = null;\n  /** @private {boolean} Whether to install the Android app. */\n  this.installApp_ = false;\n  var androidSettings =\n      settingsObj[fireauth.ActionCodeSettings.RawField.ANDROID];\n  if (androidSettings && typeof androidSettings === 'object') {\n    var apn = androidSettings[\n      fireauth.ActionCodeSettings.AndroidRawField.PACKAGE_NAME];\n    var installApp = androidSettings[\n      fireauth.ActionCodeSettings.AndroidRawField.INSTALL_APP];\n    var amv = androidSettings[\n      fireauth.ActionCodeSettings.AndroidRawField.MINIMUM_VERSION];\n    if (typeof apn === 'string' && apn.length) {\n      this.apn_ = /** @type {string} */ (apn);\n      if (typeof installApp !== 'undefined' &&\n          typeof installApp !== 'boolean') {\n        throw new fireauth.AuthError(\n            fireauth.authenum.Error.ARGUMENT_ERROR,\n            fireauth.ActionCodeSettings.AndroidRawField.INSTALL_APP +\n            ' property must be a boolean when specified.');\n      }\n      this.installApp_ = !!installApp;\n      if (typeof amv !== 'undefined' &&\n          (typeof amv !== 'string' ||\n           (typeof amv === 'string' && !amv.length))) {\n        throw new fireauth.AuthError(\n            fireauth.authenum.Error.ARGUMENT_ERROR,\n            fireauth.ActionCodeSettings.AndroidRawField.MINIMUM_VERSION +\n            ' property must be a non empty string when specified.');\n      }\n      this.amv_ = /** @type {?string}*/ (amv || null);\n    } else if (typeof apn !== 'undefined') {\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.ARGUMENT_ERROR,\n          fireauth.ActionCodeSettings.AndroidRawField.PACKAGE_NAME +\n          ' property must be a non empty string when specified.');\n    } else if (typeof installApp !== 'undefined' ||\n               typeof amv !== 'undefined') {\n      // If installApp or amv specified with no valid APN, fail quickly.\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME);\n    }\n  } else if (typeof androidSettings !== 'undefined') {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        fireauth.ActionCodeSettings.RawField.ANDROID +\n        ' property must be a non null object when specified.');\n  }\n\n  // Validate iOS parameters.\n  /** @private {?string} The iOS bundle ID. */\n  this.ibi_ = null;\n  var iosSettings = settingsObj[fireauth.ActionCodeSettings.RawField.IOS];\n  if (iosSettings && typeof iosSettings === 'object') {\n    var ibi = iosSettings[\n      fireauth.ActionCodeSettings.IosRawField.BUNDLE_ID];\n    if (typeof ibi === 'string' && ibi.length) {\n      this.ibi_ = /** @type {string}*/ (ibi);\n    } else if (typeof ibi !== 'undefined') {\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.ARGUMENT_ERROR,\n          fireauth.ActionCodeSettings.IosRawField.BUNDLE_ID +\n          ' property must be a non empty string when specified.');\n    }\n  } else if (typeof iosSettings !== 'undefined') {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        fireauth.ActionCodeSettings.RawField.IOS +\n        ' property must be a non null object when specified.');\n  }\n\n  // Validate canHandleCodeInApp.\n  var canHandleCodeInApp =\n      settingsObj[fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP];\n  if (typeof canHandleCodeInApp !== 'undefined' &&\n      typeof canHandleCodeInApp !== 'boolean') {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP +\n        ' property must be a boolean when specified.');\n  }\n  /** @const @private {boolean} Whether the code can be handled in app. */\n  this.canHandleCodeInApp_ = !!canHandleCodeInApp;\n\n  // Validate dynamicLinkDomain.\n  var dynamicLinkDomain = settingsObj[\n      fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN];\n  if (typeof dynamicLinkDomain !== 'undefined' &&\n      (typeof dynamicLinkDomain !== 'string' ||\n       (typeof dynamicLinkDomain === 'string' &&\n        !dynamicLinkDomain.length))) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN +\n        ' property must be a non empty string when specified.');\n  }\n  /** @const @private {?string} The FDL domain. */\n  this.dynamicLinkDomain_ = dynamicLinkDomain || null;\n};\n\n\n/**\n * Action code settings backend request field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.RequestField = {\n  ANDROID_INSTALL_APP: 'androidInstallApp',\n  ANDROID_MINIMUM_VERSION: 'androidMinimumVersion',\n  ANDROID_PACKAGE_NAME: 'androidPackageName',\n  CAN_HANDLE_CODE_IN_APP: 'canHandleCodeInApp',\n  CONTINUE_URL: 'continueUrl',\n  DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',\n  IOS_BUNDLE_ID: 'iOSBundleId'\n};\n\n\n/**\n * Action code settings raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.RawField = {\n  ANDROID: 'android',\n  DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',\n  HANDLE_CODE_IN_APP: 'handleCodeInApp',\n  IOS: 'iOS',\n  URL: 'url'\n};\n\n\n/**\n * Action code settings raw Android raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.AndroidRawField = {\n  INSTALL_APP: 'installApp',\n  MINIMUM_VERSION: 'minimumVersion',\n  PACKAGE_NAME: 'packageName'\n};\n\n\n/**\n * Action code settings raw iOS raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.IosRawField = {\n  BUNDLE_ID: 'bundleId'\n};\n\n\n/**\n * Builds and returns the backend request for the passed action code settings.\n * @return {!Object} The constructed backend request populated with the action\n *     code settings parameters.\n */\nfireauth.ActionCodeSettings.prototype.buildRequest = function() {\n  // Construct backend request.\n  var request = {};\n  request[fireauth.ActionCodeSettings.RequestField.CONTINUE_URL] =\n      this.continueUrl_;\n  request[fireauth.ActionCodeSettings.RequestField.CAN_HANDLE_CODE_IN_APP] =\n      this.canHandleCodeInApp_;\n  request[fireauth.ActionCodeSettings.RequestField.ANDROID_PACKAGE_NAME] =\n      this.apn_;\n  if (this.apn_) {\n    request[fireauth.ActionCodeSettings.RequestField.ANDROID_MINIMUM_VERSION] =\n        this.amv_;\n    request[fireauth.ActionCodeSettings.RequestField.ANDROID_INSTALL_APP] =\n        this.installApp_;\n  }\n  request[fireauth.ActionCodeSettings.RequestField.IOS_BUNDLE_ID] = this.ibi_;\n  request[fireauth.ActionCodeSettings.RequestField.DYNAMIC_LINK_DOMAIN] =\n      this.dynamicLinkDomain_;\n  // Remove null fields.\n  for (var key in request) {\n    if (request[key] === null) {\n      delete request[key];\n    }\n  }\n  return request;\n};\n\n\n/**\n * Returns the canHandleCodeInApp setting of ActionCodeSettings.\n * @return {boolean} Whether the code can be handled in app.\n */\nfireauth.ActionCodeSettings.prototype.canHandleCodeInApp = function() {\n  return this.canHandleCodeInApp_;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Base64 en/decoding. Not much to say here except that we\n * work with decoded values in arrays of bytes. By \"byte\" I mean a number\n * in [0, 255].\n */\n\ngoog.provide('goog.crypt.base64');\n\ngoog.require('goog.asserts');\ngoog.require('goog.crypt');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.require('goog.userAgent.product');\n\n/**\n * Default alphabet, shared between alphabets. Only 62 characters.\n * @private {string}\n */\ngoog.crypt.base64.DEFAULT_ALPHABET_COMMON_ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n    'abcdefghijklmnopqrstuvwxyz' +\n    '0123456789';\n\n\n/**\n * Alphabet characters for Alphabet.DEFAULT encoding.\n * For characters without padding, please consider using\n * `goog.crypt.baseN.BASE_64` instead.\n *\n * @type {string}\n */\ngoog.crypt.base64.ENCODED_VALS =\n    goog.crypt.base64.DEFAULT_ALPHABET_COMMON_ + '+/=';\n\n\n/**\n * Alphabet characters for Alphabet.WEBSAFE_DOT_PADDING encoding.\n * The dot padding is no Internet Standard, according to RFC 4686.\n * https://tools.ietf.org/html/rfc4648\n * For characters without padding, please consider using\n * `goog.crypt.baseN.BASE_64_URL_SAFE` instead.\n *\n * @type {string}\n */\ngoog.crypt.base64.ENCODED_VALS_WEBSAFE =\n    goog.crypt.base64.DEFAULT_ALPHABET_COMMON_ + '-_.';\n\n\n/**\n * Alphabets for Base64 encoding\n * Alphabets with no padding character are for encoding without padding.\n * About the alphabets, please refer to RFC 4686.\n * https://tools.ietf.org/html/rfc4648\n * @enum {number}\n */\ngoog.crypt.base64.Alphabet = {\n  DEFAULT: 0,\n  NO_PADDING: 1,\n  WEBSAFE: 2,\n  WEBSAFE_DOT_PADDING: 3,\n  WEBSAFE_NO_PADDING: 4,\n};\n\n\n/**\n * Padding chars for Base64 encoding\n * @const {string}\n * @private\n */\ngoog.crypt.base64.paddingChars_ = '=.';\n\n\n/**\n * Check if a character is a padding character\n *\n * @param {string} char\n * @return {boolean}\n * @private\n */\ngoog.crypt.base64.isPadding_ = function(char) {\n  return goog.string.contains(goog.crypt.base64.paddingChars_, char);\n};\n\n\n// Static lookup maps, lazily populated by init_()\n\n/**\n * For each `Alphabet`, maps from bytes to characters.\n *\n * @see https://jsperf.com/char-lookups\n * @type {!Object<!goog.crypt.base64.Alphabet, !Array<string>>}\n * @private\n */\ngoog.crypt.base64.byteToCharMaps_ = {};\n\n/**\n * Maps characters to bytes.\n *\n * This map is used for all alphabets since, across alphabets, common chars\n * always map to the same byte.\n *\n * `null` indicates `init` has not yet been called.\n *\n * @type {?Object<string, number>}\n * @private\n */\ngoog.crypt.base64.charToByteMap_ = null;\n\n\n/**\n * White list of implementations with known-good native atob and btoa functions.\n * Listing these explicitly (via the ASSUME_* wrappers) benefits dead-code\n * removal in per-browser compilations.\n * @private {boolean}\n */\ngoog.crypt.base64.ASSUME_NATIVE_SUPPORT_ = goog.userAgent.GECKO ||\n    (goog.userAgent.WEBKIT && !goog.userAgent.product.SAFARI) ||\n    goog.userAgent.OPERA;\n\n\n/**\n * Does this browser have a working btoa function?\n * @private {boolean}\n */\ngoog.crypt.base64.HAS_NATIVE_ENCODE_ =\n    goog.crypt.base64.ASSUME_NATIVE_SUPPORT_ ||\n    typeof(goog.global.btoa) == 'function';\n\n\n/**\n * Does this browser have a working atob function?\n * We blacklist known-bad implementations:\n *  - IE (10+) added atob() but it does not tolerate whitespace on the input.\n * @private {boolean}\n */\ngoog.crypt.base64.HAS_NATIVE_DECODE_ =\n    goog.crypt.base64.ASSUME_NATIVE_SUPPORT_ ||\n    (!goog.userAgent.product.SAFARI && !goog.userAgent.IE &&\n     typeof(goog.global.atob) == 'function');\n\n\n/**\n * Base64-encode an array of bytes.\n *\n * @param {Array<number>|Uint8Array} input An array of bytes (numbers with\n *     value in [0, 255]) to encode.\n * @param {!goog.crypt.base64.Alphabet=} alphabet Base 64 alphabet to\n *     use in encoding. Alphabet.DEFAULT is used by default.\n * @return {string} The base64 encoded string.\n */\ngoog.crypt.base64.encodeByteArray = function(input, alphabet) {\n  // Assert avoids runtime dependency on goog.isArrayLike, which helps reduce\n  // size of jscompiler output, and which yields slight performance increase.\n  goog.asserts.assert(\n      goog.isArrayLike(input), 'encodeByteArray takes an array as a parameter');\n\n  if (alphabet === undefined) {\n    alphabet = goog.crypt.base64.Alphabet.DEFAULT;\n  }\n\n  goog.crypt.base64.init_();\n\n  var byteToCharMap = goog.crypt.base64.byteToCharMaps_[alphabet];\n\n  var output = [];\n\n  for (var i = 0; i < input.length; i += 3) {\n    var byte1 = input[i];\n    var haveByte2 = i + 1 < input.length;\n    var byte2 = haveByte2 ? input[i + 1] : 0;\n    var haveByte3 = i + 2 < input.length;\n    var byte3 = haveByte3 ? input[i + 2] : 0;\n\n    var outByte1 = byte1 >> 2;\n    var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n    var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);\n    var 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], byteToCharMap[outByte2],\n        byteToCharMap[outByte3] || '', byteToCharMap[outByte4] || '');\n  }\n\n  return output.join('');\n};\n\n\n/**\n * Base64-encode a string.\n *\n * @param {string} input A string to encode.\n * @param {!goog.crypt.base64.Alphabet=} alphabet Base 64 alphabet to\n *     use in encoding. Alphabet.DEFAULT is used by default.\n * @return {string} The base64 encoded string.\n */\ngoog.crypt.base64.encodeString = function(input, alphabet) {\n  // Shortcut for browsers that implement\n  // a native base64 encoder in the form of \"btoa/atob\"\n  if (goog.crypt.base64.HAS_NATIVE_ENCODE_ && !alphabet) {\n    return goog.global.btoa(input);\n  }\n  return goog.crypt.base64.encodeByteArray(\n      goog.crypt.stringToByteArray(input), alphabet);\n};\n\n\n/**\n * Base64-decode a string.\n *\n * @param {string} input Input to decode. Any whitespace is ignored, and the\n *     input maybe encoded with either supported alphabet (or a mix thereof).\n * @param {boolean=} useCustomDecoder True indicates the custom decoder is used,\n *     which supports alternative alphabets. Note that passing false may still\n *     use the custom decoder on browsers without native support.\n * @return {string} string representing the decoded value.\n */\ngoog.crypt.base64.decodeString = function(input, useCustomDecoder) {\n  // Shortcut for browsers that implement\n  // a native base64 encoder in the form of \"btoa/atob\"\n  if (goog.crypt.base64.HAS_NATIVE_DECODE_ && !useCustomDecoder) {\n    return goog.global.atob(input);\n  }\n  var output = '';\n  function pushByte(b) {\n    output += String.fromCharCode(b);\n  }\n\n  goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n  return output;\n};\n\n\n/**\n * Base64-decode a string to an Array of numbers.\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 {string} input Input to decode. Any whitespace is ignored, and the\n *     input maybe encoded with either supported alphabet (or a mix thereof).\n * @param {boolean=} opt_ignored Unused parameter, retained for compatibility.\n * @return {!Array<number>} bytes representing the decoded value.\n */\ngoog.crypt.base64.decodeStringToByteArray = function(input, opt_ignored) {\n  var output = [];\n  function pushByte(b) { output.push(b); }\n\n  goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n  return output;\n};\n\n\n/**\n * Base64-decode a string to a Uint8Array.\n *\n * Note that Uint8Array is not supported on older browsers, e.g. IE < 10.\n * @see http://caniuse.com/uint8array\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 {string} input Input to decode. Any whitespace is ignored, and the\n *     input maybe encoded with either supported alphabet (or a mix thereof).\n * @return {!Uint8Array} bytes representing the decoded value.\n */\ngoog.crypt.base64.decodeStringToUint8Array = function(input) {\n  goog.asserts.assert(\n      !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'),\n      'Browser does not support typed arrays');\n  var len = input.length;\n  // Approximate the length of the array needed for output.\n  // Our method varies according to the format of the input, which we can\n  // consider in three categories:\n  //   A) well-formed with proper padding\n  //   B) well-formed without any padding\n  //   C) not-well-formed, either with extra whitespace in the middle or with\n  //      extra padding characters.\n  //\n  //  In the case of (A), (length * 3 / 4) will result in an integer number of\n  //  bytes evenly divisible by 3, and we need only subtract bytes according to\n  //  the padding observed.\n  //\n  //  In the case of (B), (length * 3 / 4) will result in a non-integer number\n  //  of bytes, or not evenly divisible by 3. (If the result is evenly divisible\n  //  by 3, it's well-formed with the proper amount of padding [0 padding]).\n  //  This approximation can become exact by rounding down.\n  //\n  //  In the case of (C), the only way to get the length is to walk the full\n  //  length of the string to consider each character. This is handled by\n  //  tracking the number of bytes added to the array and using subarray to\n  //  trim the array back down to size.\n  var approxByteLength = len * 3 / 4;\n  if (approxByteLength % 3) {\n    // The string isn't complete, either because it didn't include padding, or\n    // because it has extra white space.\n    // In either case, we won't generate more bytes than are completely encoded,\n    // so rounding down is appropriate to have a buffer at least as large as\n    // output.\n    approxByteLength = Math.floor(approxByteLength);\n  } else if (goog.crypt.base64.isPadding_(input[len - 1])) {\n    // The string has a round length, and has some padding.\n    // Reduce the byte length according to the quantity of padding.\n    if (goog.crypt.base64.isPadding_(input[len - 2])) {\n      approxByteLength -= 2;\n    } else {\n      approxByteLength -= 1;\n    }\n  }\n  var output = new Uint8Array(approxByteLength);\n  var outLen = 0;\n  function pushByte(b) {\n    output[outLen++] = b;\n  }\n\n  goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n  // Return a subarray to handle the case that input included extra whitespace\n  // or extra padding and approxByteLength was incorrect.\n  return output.subarray(0, outLen);\n};\n\n\n/**\n * @param {string} input Input to decode.\n * @param {function(number):void} pushByte result accumulator.\n * @private\n */\ngoog.crypt.base64.decodeStringInternal_ = function(input, pushByte) {\n  goog.crypt.base64.init_();\n\n  var nextCharIndex = 0;\n  /**\n   * @param {number} default_val Used for end-of-input.\n   * @return {number} The next 6-bit value, or the default for end-of-input.\n   */\n  function getByte(default_val) {\n    while (nextCharIndex < input.length) {\n      var ch = input.charAt(nextCharIndex++);\n      var b = goog.crypt.base64.charToByteMap_[ch];\n      if (b != null) {\n        return b;  // Common case: decoded the char.\n      }\n      if (!goog.string.isEmptyOrWhitespace(ch)) {\n        throw new Error('Unknown base64 encoding at char: ' + ch);\n      }\n      // We encountered whitespace: loop around to the next input char.\n    }\n    return default_val;  // No more input remaining.\n  }\n\n  while (true) {\n    var byte1 = getByte(-1);\n    var byte2 = getByte(0);\n    var byte3 = getByte(64);\n    var byte4 = getByte(64);\n\n    // The common case is that all four bytes are present, so if we have byte4\n    // we can skip over the truncated input special case handling.\n    if (byte4 === 64) {\n      if (byte1 === -1) {\n        return;  // Terminal case: no input left to decode.\n      }\n      // Here we know an intermediate number of bytes are missing.\n      // The defaults for byte2, byte3 and byte4 apply the inferred padding\n      // rules per the public API documentation. i.e: 1 byte\n      // missing should yield 2 bytes of output, but 2 or 3 missing bytes yield\n      // a single byte of output. (Recall that 64 corresponds the padding char).\n    }\n\n    var outByte1 = (byte1 << 2) | (byte2 >> 4);\n    pushByte(outByte1);\n\n    if (byte3 != 64) {\n      var outByte2 = ((byte2 << 4) & 0xF0) | (byte3 >> 2);\n      pushByte(outByte2);\n\n      if (byte4 != 64) {\n        var outByte3 = ((byte3 << 6) & 0xC0) | byte4;\n        pushByte(outByte3);\n      }\n    }\n  }\n};\n\n\n/**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\ngoog.crypt.base64.init_ = function() {\n  if (goog.crypt.base64.charToByteMap_) {\n    return;\n  }\n  goog.crypt.base64.charToByteMap_ = {};\n\n  // We want quick mappings back and forth, so we precompute encoding maps.\n\n  /** @type {!Array<string>} */\n  var commonChars = goog.crypt.base64.DEFAULT_ALPHABET_COMMON_.split('');\n  var specialChars = [\n    '+/=',  // DEFAULT\n    '+/',   // NO_PADDING\n    '-_=',  // WEBSAFE\n    '-_.',  // WEBSAFE_DOT_PADDING\n    '-_',   // WEBSAFE_NO_PADDING\n  ];\n\n  for (var i = 0; i < 5; i++) {\n    // `i` is each value of the `goog.crypt.base64.Alphabet` enum\n    var chars = commonChars.concat(specialChars[i].split(''));\n\n    // Sets byte-to-char map\n    goog.crypt.base64\n        .byteToCharMaps_[/** @type {!goog.crypt.base64.Alphabet} */ (i)] =\n        chars;\n\n    // Sets char-to-byte map\n    for (var j = 0; j < chars.length; j++) {\n      var char = chars[j];\n\n      var existingByte = goog.crypt.base64.charToByteMap_[char];\n      if (existingByte === undefined) {\n        goog.crypt.base64.charToByteMap_[char] = j;\n      } else {\n        goog.asserts.assert(existingByte === j);\n      }\n    }\n  }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Utility functions to handle Firebase Auth ID tokens.\n */\n\ngoog.provide('fireauth.IdToken');\n\ngoog.require('goog.crypt.base64');\n\n\n/**\n * Parses the token string into a {@code Token} object.\n * @param {?string} tokenString The JWT token string.\n * @constructor\n */\nfireauth.IdToken = function(tokenString) {\n  var token = fireauth.IdToken.parseIdTokenClaims(tokenString);\n  if (!(token && token['sub'] && token['iss'] &&\n        token['aud'] && token['exp'])) {\n    throw new Error('Invalid JWT');\n  }\n  /** @const @private {string} The plain JWT string. */\n  this.jwt_ = /** @type {string} */ (tokenString);\n  /** @const @private {string} The issuer of the token. */\n  this.iss_ = token['iss'];\n  /** @const @private {string} The audience of the token. */\n  this.aud_ = token['aud'];\n  /** @const @private {number} The expire time in seconds of the token. */\n  this.exp_ = token['exp'];\n  /** @const @private {string} The local user ID of the token. */\n  this.localId_ = token['sub'];\n  var now = goog.now() / 1000;\n  /** @const @private {number} The issue time in seconds of the token. */\n  this.iat_ = token['iat'] || (now > this.exp_ ? this.exp_ : now);\n  /** @const @private {?string} The email address of the token. */\n  this.email_ = token['email'] || null;\n  /** @const @private {boolean} Whether the user is verified. */\n  this.verified_ = !!token['verified'];\n  /** @const @private {?string} The provider ID of the token. */\n  this.providerId_ = token['provider_id'] ||\n      (token['firebase'] && token['firebase']['sign_in_provider']) ||\n      null;\n  /** @const @private {?string} The tenant ID of the token. */\n  this.tenantId_ = (token['firebase'] && token['firebase']['tenant']) || null;\n  /** @const @private {boolean} Whether the user is anonymous. */\n  this.anonymous_ = !!token['is_anonymous'] || this.providerId_ == 'anonymous';\n  /** @const @private {?string} The federated ID of the token. */\n  this.federatedId_ = token['federated_id'] || null;\n  /** @const @private {?string} The display name of the token. */\n  this.displayName_ = token['display_name'] || null;\n  /** @const @private {?string} The photo URL of the token. */\n  this.photoURL_ = token['photo_url'] || null;\n  /**\n   * @const @private {?string} The phone number of the user identified by the\n   *     token.\n   */\n  this.phoneNumber_ = token['phone_number'] || null;\n};\n\n\n/**\n * @typedef {{\n *   identities: (?Object|undefined),\n *   sign_in_provider: (?string|undefined),\n *   tenant: (string|undefined)\n * }}\n */\nfireauth.IdToken.Firebase;\n\n\n/**\n * @typedef {{\n *   iss: string,\n *   aud: string,\n *   exp: number,\n *   sub: string,\n *   iat: (?number|undefined),\n *   email: (?string|undefined),\n *   verified: (?boolean|undefined),\n *   provider_id: (?string|undefined),\n *   is_anonymous: (?boolean|undefined),\n *   federated_id: (?string|undefined),\n *   display_name: (?string|undefined),\n *   photo_url: (?string|undefined),\n *   phone_number: (?string|undefined),\n *   firebase: (?fireauth.IdToken.Firebase|undefined)\n * }}\n */\nfireauth.IdToken.JsonToken;\n\n\n/** @return {?string} The email address of the account. */\nfireauth.IdToken.prototype.getEmail = function() {\n  return this.email_;\n};\n\n\n/** @return {number} The expire time in seconds. */\nfireauth.IdToken.prototype.getExp = function() {\n  return this.exp_;\n};\n\n\n/** @return {?string} The ID of the identity provider. */\nfireauth.IdToken.prototype.getProviderId = function() {\n  return this.providerId_;\n};\n\n\n/** @return {?string} The tenant ID. */\nfireauth.IdToken.prototype.getTenantId = function() {\n  return this.tenantId_;\n};\n\n\n/** @return {?string} The display name of the account. */\nfireauth.IdToken.prototype.getDisplayName = function() {\n  return this.displayName_;\n};\n\n\n/** @return {?string} The photo URL of the account. */\nfireauth.IdToken.prototype.getPhotoUrl = function() {\n  return this.photoURL_;\n};\n\n\n/** @return {string} The user ID of the account. */\nfireauth.IdToken.prototype.getLocalId = function() {\n  return this.localId_;\n};\n\n\n/** @return {?string} The federated ID of the account. */\nfireauth.IdToken.prototype.getFederatedId = function() {\n  return this.federatedId_;\n};\n\n\n/** @return {boolean} Whether the user is anonymous. */\nfireauth.IdToken.prototype.isAnonymous = function() {\n  return this.anonymous_;\n};\n\n\n/** @return {boolean} Whether the user email is verified. */\nfireauth.IdToken.prototype.isVerified = function() {\n  return this.verified_;\n};\n\n\n/** @return {boolean} Whether token is expired. */\nfireauth.IdToken.prototype.isExpired = function() {\n  var now = Math.floor(goog.now() / 1000);\n  // It is expired if token expiration time is less than current time.\n  return this.getExp() <= now;\n};\n\n\n/** @return {string} The issuer of the token. */\nfireauth.IdToken.prototype.getIssuer = function() {\n  return this.iss_;\n};\n\n\n/** @return {?string} The phone number of the account. */\nfireauth.IdToken.prototype.getPhoneNumber = function() {\n  return this.phoneNumber_;\n};\n\n\n/**\n * @return {string} The JWT string.\n * @override\n */\nfireauth.IdToken.prototype.toString = function() {\n  return this.jwt_;\n};\n\n\n/**\n * Parses the JWT token and extracts the information part without verifying the\n * token signature.\n * @param {string} tokenString The JWT token.\n * @return {?fireauth.IdToken} The decoded token.\n */\nfireauth.IdToken.parse = function(tokenString) {\n  try {\n    return new fireauth.IdToken(tokenString);\n  } catch (e) {\n    return null;\n  }\n};\n\n/**\n * Converts the information part of JWT token to plain object format.\n * @param {?string} tokenString The JWT token.\n * @return {?Object}\n */\nfireauth.IdToken.parseIdTokenClaims = function(tokenString) {\n  if (!tokenString) {\n    return null;\n  }\n  // Token format is <algorithm>.<info>.<sig>\n  var fields = tokenString.split('.');\n  if (fields.length != 3) {\n    return null;\n  }\n  var jsonInfo = fields[1];\n  // Google base64 library does not handle padding.\n  var padLen = (4 - jsonInfo.length % 4) % 4;\n  for (var i = 0; i < padLen; i++) {\n    jsonInfo += '.';\n  }\n  try {\n    var token = JSON.parse(goog.crypt.base64.decodeString(jsonInfo, true));\n    return /** @type {?Object} */ (token);\n  } catch (e) {}\n  return null;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the IdP provider IDs and related settings.\n */\n\ngoog.provide('fireauth.idp');\ngoog.provide('fireauth.idp.IdpSettings');\ngoog.provide('fireauth.idp.ProviderId');\ngoog.provide('fireauth.idp.Settings');\ngoog.provide('fireauth.idp.SignInMethod');\n\ngoog.require('fireauth.constants');\n\n\n/**\n * Enums for supported provider IDs. These provider IDs correspond to the\n * sign_in_provider in the Firebase ID token and do not correspond to the\n * supported client exposed firebase.auth.AuthProviders.\n * @enum {string}\n */\nfireauth.idp.ProviderId = {\n  ANONYMOUS: 'anonymous',\n  CUSTOM: 'custom',\n  FACEBOOK: 'facebook.com',\n  FIREBASE: 'firebase',\n  GITHUB: 'github.com',\n  GOOGLE: 'google.com',\n  PASSWORD: 'password',\n  PHONE: 'phone',\n  TWITTER: 'twitter.com'\n};\n\n\n/**\n * Enums for supported sign in methods.\n * @enum {string}\n */\nfireauth.idp.SignInMethod = {\n  EMAIL_LINK: 'emailLink',\n  EMAIL_PASSWORD: 'password',\n  FACEBOOK: 'facebook.com',\n  GITHUB: 'github.com',\n  GOOGLE: 'google.com',\n  PHONE: 'phone',\n  TWITTER: 'twitter.com'\n};\n\n\n/**\n * The settings of an identity provider. The fields are:\n * <ul>\n * <li>languageParam: defines the custom OAuth language parameter.\n * <li>popupWidth: defines the popup recommended width.\n * <li>popupHeight: defines the popup recommended height.\n * <li>providerId: defines the provider ID.\n * <li>reservedOAuthParameters: defines the list of reserved OAuth parameters.\n * </ul>\n * @typedef {{\n *   languageParam: (?string|undefined),\n *   popupWidth: (?number|undefined),\n *   popupHeight: (?number|undefined),\n *   providerId: !fireauth.idp.ProviderId,\n *   reservedOAuthParameters: !Array<string>\n * }}\n */\nfireauth.idp.IdpSettings;\n\n\n/**\n * The list of reserved OAuth 1.0 parameters.\n * @const {!Array<string>}\n */\nfireauth.idp.RESERVED_OAUTH1_PARAMS =\n    ['oauth_consumer_key', 'oauth_nonce', 'oauth_signature',\n     'oauth_signature_method', 'oauth_timestamp', 'oauth_token',\n     'oauth_version'];\n\n\n/**\n * The list of reserved OAuth 2.0 parameters.\n * @const {!Array<string>}\n */\nfireauth.idp.RESERVED_OAUTH2_PARAMS =\n    ['client_id', 'response_type', 'scope', 'redirect_uri', 'state'];\n\n\n/**\n * The recommendations for the different IdP display settings.\n * @enum {!fireauth.idp.IdpSettings}\n */\nfireauth.idp.Settings = {\n  FACEBOOK: {\n    languageParam: 'locale',\n    popupWidth: 700,\n    popupHeight: 600,\n    providerId: fireauth.idp.ProviderId.FACEBOOK,\n    reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n  },\n  GITHUB: {\n    languageParam: null,\n    popupWidth: 500,\n    popupHeight: 750,\n    providerId: fireauth.idp.ProviderId.GITHUB,\n    reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n  },\n  GOOGLE: {\n    languageParam: 'hl',\n    popupWidth: 515,\n    popupHeight: 680,\n    providerId: fireauth.idp.ProviderId.GOOGLE,\n    reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n  },\n  TWITTER: {\n    languageParam: 'lang',\n    popupWidth: 485,\n    popupHeight: 705,\n    providerId: fireauth.idp.ProviderId.TWITTER,\n    reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH1_PARAMS,\n  },\n  APPLE: {\n    languageParam: 'locale',\n    popupWidth: 640,\n    popupHeight: 600,\n    providerId: 'apple.com',\n    reservedOAuthParameters: [],\n  },\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The requested provider ID.\n * @return {?fireauth.idp.Settings} The settings for the requested provider ID.\n */\nfireauth.idp.getIdpSettings = function(providerId) {\n  for (var key in fireauth.idp.Settings) {\n    if (fireauth.idp.Settings[key].providerId == providerId) {\n      return fireauth.idp.Settings[key];\n    }\n  }\n  return null;\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The requested provider ID.\n * @return {!Array<string>} The list of reserved OAuth parameters.\n */\nfireauth.idp.getReservedOAuthParams = function(providerId) {\n  var settings = fireauth.idp.getIdpSettings(providerId);\n  return (settings && settings.reservedOAuthParameters) || [];\n};\n\n\n/**\n * @param {?string|undefined} identifier The provider identifier.\n * @return {boolean} Whether the identifier provided is a SAML provider ID.\n */\nfireauth.idp.isSaml = function(identifier) {\n   return typeof identifier === 'string' &&\n     identifier.indexOf(fireauth.constants.SAML_PREFIX) == 0;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines all the fireauth additional user info interfaces,\n * implementations and subclasses.\n */\n\ngoog.provide('fireauth.AdditionalUserInfo');\ngoog.provide('fireauth.FacebookAdditionalUserInfo');\ngoog.provide('fireauth.FederatedAdditionalUserInfo');\ngoog.provide('fireauth.GenericAdditionalUserInfo');\ngoog.provide('fireauth.GithubAdditionalUserInfo');\ngoog.provide('fireauth.GoogleAdditionalUserInfo');\ngoog.provide('fireauth.TwitterAdditionalUserInfo');\n\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\n\n\n/**\n * The interface that represents additional user info.\n * @interface\n */\nfireauth.AdditionalUserInfo = function() {};\n\n\n/**\n * Constructs the corresponding additional user info for the backend\n * verifyAssertion response.\n * @param {?Object|undefined} resp The backend verifyAssertion,\n *     verifyPhoneNumber or verifyPassword/setAccountInfo response.\n * @return {?fireauth.AdditionalUserInfo} The fireauth.AdditionalUserInfo\n *     instance.\n */\nfireauth.AdditionalUserInfo.fromPlainObject = function(resp) {\n  var factory = {};\n  factory[fireauth.idp.ProviderId.FACEBOOK] =\n      fireauth.FacebookAdditionalUserInfo;\n  factory[fireauth.idp.ProviderId.GOOGLE] =\n      fireauth.GoogleAdditionalUserInfo;\n  factory[fireauth.idp.ProviderId.GITHUB] =\n      fireauth.GithubAdditionalUserInfo;\n  factory[fireauth.idp.ProviderId.TWITTER] =\n      fireauth.TwitterAdditionalUserInfo;\n  // Provider ID and UID are required.\n  var providerId =\n      resp &&\n      resp[fireauth.AdditionalUserInfo.VerifyAssertionField.PROVIDER_ID];\n  try {\n    // Provider ID already present.\n    if (providerId) {\n      if (factory[providerId]) {\n        // 1st class supported federated providers.\n        return new factory[providerId](resp);\n      } else {\n        // Generic federated providers.\n        return new fireauth.FederatedAdditionalUserInfo(\n            /** @type {!Object} */ (resp));\n      }\n    } else if (typeof resp[fireauth.AdditionalUserInfo.VerifyAssertionField\n                           .ID_TOKEN] !== 'undefined') {\n      // For all other ID token responses with no providerId, get the required\n      // providerId from the ID token itself.\n      return new fireauth.GenericAdditionalUserInfo(\n          /** @type {!Object} */ (resp));\n    }\n  } catch (e) {\n    // Do nothing, null will be returned.\n  }\n  return null;\n};\n\n\n\n/**\n * verifyAssertion response additional user info fields.\n * @enum {string}\n */\nfireauth.AdditionalUserInfo.VerifyAssertionField = {\n  ID_TOKEN: 'idToken',\n  IS_NEW_USER: 'isNewUser',\n  KIND: 'kind',\n  PROVIDER_ID: 'providerId',\n  RAW_USER_INFO: 'rawUserInfo',\n  SCREEN_NAME: 'screenName'\n};\n\n\n/**\n * Constructs a generic additional user info object from the backend\n * verifyPhoneNumber and verifyPassword provider response.\n * @param {!Object} info The verifyPhoneNumber/verifyPassword/setAccountInfo\n *     response data object.\n * @constructor\n * @implements {fireauth.AdditionalUserInfo}\n */\nfireauth.GenericAdditionalUserInfo = function(info) {\n  // Federated provider profile data.\n  var providerId =\n      info[fireauth.AdditionalUserInfo.VerifyAssertionField.PROVIDER_ID];\n  // Try to get providerId from the ID token if available.\n  if (!providerId &&\n      info[fireauth.AdditionalUserInfo.VerifyAssertionField.ID_TOKEN]) {\n    // verifyPassword/setAccountInfo and verifyPhoneNumber return an ID token\n    // but no providerId. Get providerId from the token itself.\n    // isNewUser will be returned for verifyPhoneNumber.\n    var idToken = fireauth.IdToken.parse(\n        info[fireauth.AdditionalUserInfo.VerifyAssertionField.ID_TOKEN]);\n    if (idToken && idToken.getProviderId()) {\n      providerId = idToken.getProviderId();\n    }\n  }\n  if (!providerId) {\n    // This is internal only.\n    throw new Error('Invalid additional user info!');\n  }\n  // For custom token and anonymous token, set provider ID to null.\n  if (providerId == fireauth.idp.ProviderId.ANONYMOUS ||\n      providerId == fireauth.idp.ProviderId.CUSTOM) {\n      providerId = null;\n  }\n  // Check whether user is new. Temporary Solution since backend does not return\n  // isNewUser field for SignupNewUserResponse.\n  var isNewUser = false;\n  if (typeof info[fireauth.AdditionalUserInfo.VerifyAssertionField.IS_NEW_USER]\n      !== 'undefined') {\n    isNewUser =\n        !!info[fireauth.AdditionalUserInfo.VerifyAssertionField.IS_NEW_USER];\n  } else if (info[fireauth.AdditionalUserInfo.VerifyAssertionField.KIND]\n             === 'identitytoolkit#SignupNewUserResponse') {\n    //For SignupNewUserResponse, always set isNewUser to true.\n    isNewUser = true;\n  }\n  // Set required providerId.\n  fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n  // Set read-only isNewUser property.\n  fireauth.object.setReadonlyProperty(this, 'isNewUser', isNewUser);\n};\n\n\n/**\n * Constructs a federated additional user info object from the backend\n * verifyAssertion federated provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.GenericAdditionalUserInfo}\n */\nfireauth.FederatedAdditionalUserInfo = function(info) {\n  fireauth.FederatedAdditionalUserInfo.base(this, 'constructor', info);\n  // Federated provider profile data.\n  // This structure will also be used for generic IdPs.\n  var profile = fireauth.util.parseJSON(\n      info[fireauth.AdditionalUserInfo.VerifyAssertionField.RAW_USER_INFO] ||\n      '{}');\n  // Set read-only profile property.\n  fireauth.object.setReadonlyProperty(\n      this,\n      'profile',\n      fireauth.object.unsafeCreateReadOnlyCopy(profile || {}));\n};\ngoog.inherits(\n    fireauth.FederatedAdditionalUserInfo, fireauth.GenericAdditionalUserInfo);\n\n\n/**\n * Constructs a Facebook additional user info object from the backend\n * verifyAssertion Facebook provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.FacebookAdditionalUserInfo = function(info) {\n  fireauth.FacebookAdditionalUserInfo.base(this, 'constructor', info);\n  // This should not happen as this object is initialized via fromPlainObject.\n  if (this['providerId'] != fireauth.idp.ProviderId.FACEBOOK) {\n    throw new Error('Invalid provider ID!');\n  }\n};\ngoog.inherits(\n    fireauth.FacebookAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a GitHub additional user info object from the backend\n * verifyAssertion GitHub provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.GithubAdditionalUserInfo = function(info) {\n  fireauth.GithubAdditionalUserInfo.base(this, 'constructor', info);\n  // This should not happen as this object is initialized via fromPlainObject.\n  if (this['providerId'] != fireauth.idp.ProviderId.GITHUB) {\n    throw new Error('Invalid provider ID!');\n  }\n  // GitHub username.\n  fireauth.object.setReadonlyProperty(\n      this,\n      'username',\n      (this['profile'] && this['profile']['login']) || null);\n};\ngoog.inherits(\n    fireauth.GithubAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a Google additional user info object from the backend\n * verifyAssertion Google provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.GoogleAdditionalUserInfo = function(info) {\n  fireauth.GoogleAdditionalUserInfo.base(this, 'constructor', info);\n  // This should not happen as this object is initialized via fromPlainObject.\n  if (this['providerId'] != fireauth.idp.ProviderId.GOOGLE) {\n    throw new Error('Invalid provider ID!');\n  }\n};\ngoog.inherits(\n    fireauth.GoogleAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a Twitter additional user info object from the backend\n * verifyAssertion Twitter provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.TwitterAdditionalUserInfo = function(info) {\n  fireauth.TwitterAdditionalUserInfo.base(this, 'constructor', info);\n  // This should not happen as this object is initialized via fromPlainObject.\n  if (this['providerId'] != fireauth.idp.ProviderId.TWITTER) {\n    throw new Error('Invalid provider ID!');\n  }\n  // Twitter user name.\n  fireauth.object.setReadonlyProperty(\n      this,\n      'username',\n      info[fireauth.AdditionalUserInfo.VerifyAssertionField.SCREEN_NAME] ||\n      null);\n};\ngoog.inherits(\n    fireauth.TwitterAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines Auth credentials used for signInWithCredential.\n */\n\ngoog.provide('fireauth.AuthCredential');\ngoog.provide('fireauth.AuthProvider');\ngoog.provide('fireauth.EmailAuthCredential');\ngoog.provide('fireauth.EmailAuthProvider');\ngoog.provide('fireauth.FacebookAuthProvider');\ngoog.provide('fireauth.FederatedProvider');\ngoog.provide('fireauth.GithubAuthProvider');\ngoog.provide('fireauth.GoogleAuthProvider');\ngoog.provide('fireauth.OAuthCredential');\ngoog.provide('fireauth.OAuthProvider');\ngoog.provide('fireauth.OAuthResponse');\ngoog.provide('fireauth.PhoneAuthCredential');\ngoog.provide('fireauth.PhoneAuthProvider');\ngoog.provide('fireauth.SAMLAuthCredential');\ngoog.provide('fireauth.SAMLAuthProvider');\ngoog.provide('fireauth.TwitterAuthProvider');\n\ngoog.requireType('fireauth.RpcHandler');\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeURL');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.DynamicLink');\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.MultiFactorAuthCredential');\ngoog.require('fireauth.MultiFactorEnrollmentRequestIdentifier');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.MultiFactorSignInRequestIdentifier');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n\n/**\n * The interface that represents Auth credential. It provides the underlying\n * implementation for retrieving the ID token depending on the type of\n * credential.\n * @interface\n */\nfireauth.AuthCredential = function() {};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n *     idTokenPromise The RPC handler method that returns a promise which\n *     resolves with an ID token.\n */\nfireauth.AuthCredential.prototype.getIdTokenProvider = function(rpcHandler) {};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n *     are linked.\n */\nfireauth.AuthCredential.prototype.linkToIdToken =\n    function(rpcHandler, idToken) {};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n *     idToken UID match succeeds and returns the server response.\n */\nfireauth.AuthCredential.prototype.matchIdTokenWithUid =\n    function(rpcHandler, uid) {};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential. This\n *     will be exposed as toJSON() externally.\n */\nfireauth.AuthCredential.prototype.toPlainObject = function() {};\n\n\n/**\n * @param {!goog.Promise<!Object>} idTokenResolver A promise that resolves with\n *     the ID token response.\n * @param {string} uid The UID to match in the token response.\n * @return {!goog.Promise<!Object>} A promise that resolves with the same\n *     response if the UID matches.\n */\nfireauth.AuthCredential.verifyTokenResponseUid =\n    function(idTokenResolver, uid) {\n  return idTokenResolver.then(function(response) {\n    // This should not happen as rpcHandler verifyAssertion and verifyPassword\n    // always guarantee an ID token is available.\n    if (response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n      // Parse the token object.\n      var parsedIdToken = fireauth.IdToken.parse(\n          response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n      // Confirm token localId matches the provided UID. If not, throw the user\n      // mismatch error.\n      if (!parsedIdToken || uid != parsedIdToken.getLocalId()) {\n        throw new fireauth.AuthError(fireauth.authenum.Error.USER_MISMATCH);\n      }\n      return response;\n    }\n    throw new fireauth.AuthError(fireauth.authenum.Error.USER_MISMATCH);\n  })\n  .thenCatch(function(error) {\n    // Translate auth/user-not-found error directly to auth/user-mismatch.\n    throw fireauth.AuthError.translateError(\n        error,\n        fireauth.authenum.Error.USER_DELETED,\n        fireauth.authenum.Error.USER_MISMATCH);\n  });\n};\n\n\n\n/**\n * The interface that represents the Auth provider.\n * @interface\n */\nfireauth.AuthProvider = function() {};\n\n\n/**\n * @param {...*} var_args The credential data.\n * @return {!fireauth.AuthCredential} The Auth provider credential.\n */\nfireauth.AuthProvider.credential;\n\n\n/**\n * @typedef {{\n *   accessToken: (?string|undefined),\n *   idToken: (?string|undefined),\n *   nonce: (?string|undefined),\n *   oauthToken: (?string|undefined),\n *   oauthTokenSecret: (?string|undefined),\n *   pendingToken: (?string|undefined)\n * }}\n */\nfireauth.OAuthResponse;\n\n\n/**\n * The SAML Auth credential class. The Constructor is not publicly visible.\n * This is constructed by the SDK on successful or failure after SAML sign-in\n * and returned to developer.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {string} pendingToken The SAML response pending token.\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.SAMLAuthCredential = function(providerId, pendingToken) {\n  if (pendingToken) {\n    /** @private {string} The pending token where SAML response is encrypted. */\n    this.pendingToken_ = pendingToken;\n  } else {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n        'failed to construct a credential');\n  }\n\n  fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n  fireauth.object.setReadonlyProperty(this, 'signInMethod', providerId);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n *     idTokenPromise The RPC handler method that returns a promise which\n *     resolves with an ID token.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.getIdTokenProvider =\n    function(rpcHandler) {\n  return rpcHandler.verifyAssertion(\n      /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (\n      this.makeVerifyAssertionRequest_()));\n};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n *     are linked, returning the backend response.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.linkToIdToken =\n    function(rpcHandler, idToken) {\n  var request = this.makeVerifyAssertionRequest_();\n  request['idToken'] = idToken;\n  return rpcHandler.verifyAssertionForLinking(\n      /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request));\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n *     idToken UID match succeeds and returns the server response.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.matchIdTokenWithUid =\n    function(rpcHandler, uid) {\n  var request = this.makeVerifyAssertionRequest_();\n  // Do not create a new account if the user doesn't exist.\n  return fireauth.AuthCredential.verifyTokenResponseUid(\n      rpcHandler.verifyAssertionForExisting(\n          /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request)),\n      uid);\n};\n\n\n/**\n * @return {!Object} A request to the VerifyAssertion endpoint, populated with\n *     the assertion data from this credential.\n * @private\n */\nfireauth.SAMLAuthCredential.prototype.makeVerifyAssertionRequest_ =\n    function() {\n  return {\n    'pendingToken': this.pendingToken_,\n    // Always use http://localhost.\n    'requestUri': 'http://localhost'\n  };\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.toPlainObject = function() {\n  return {\n    'providerId': this['providerId'],\n    'signInMethod': this['signInMethod'],\n    'pendingToken': this.pendingToken_\n  };\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n *     SAMLAuthCredential.\n * @return {?fireauth.SAMLAuthCredential} The SAML credential if the object\n *     is a JSON representation of a SAMLAuthCredential, null otherwise.\n */\nfireauth.SAMLAuthCredential.fromJSON = function(json) {\n  if (json &&\n      json['providerId'] &&\n      json['signInMethod'] &&\n      json['providerId'].indexOf(fireauth.constants.SAML_PREFIX) == 0 &&\n      json['pendingToken']) {\n    try {\n      return new fireauth.SAMLAuthCredential(\n          json['providerId'], json['pendingToken']);\n    } catch (e) {\n      return null;\n    }\n  }\n  return null;\n};\n\n\n/**\n * The OAuth credential class.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {!fireauth.OAuthResponse} oauthResponse The OAuth\n *     response object containing token information.\n * @param {!fireauth.idp.SignInMethod} signInMethod The sign in method.\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.OAuthCredential = function(providerId, oauthResponse, signInMethod) {\n  /**\n   * @private {?string} The pending token where the IdP response is encrypted.\n   */\n  this.pendingToken_ = null;\n  if (oauthResponse['idToken'] || oauthResponse['accessToken']) {\n    // OAuth 2 and either ID token or access token.\n    if (oauthResponse['idToken']) {\n      fireauth.object.setReadonlyProperty(\n          this, 'idToken', oauthResponse['idToken']);\n    }\n    if (oauthResponse['accessToken']) {\n      fireauth.object.setReadonlyProperty(\n          this, 'accessToken', oauthResponse['accessToken']);\n    }\n    // Add nonce if available and no pendingToken is present.\n    if (oauthResponse['nonce'] && !oauthResponse['pendingToken']) {\n      fireauth.object.setReadonlyProperty(\n          this, 'nonce', oauthResponse['nonce']);\n    }\n    if (oauthResponse['pendingToken']) {\n      this.pendingToken_ = oauthResponse['pendingToken'];\n    }\n  } else if (oauthResponse['oauthToken'] &&\n             oauthResponse['oauthTokenSecret'])  {\n    // OAuth 1 and OAuth token with OAuth token secret.\n    fireauth.object.setReadonlyProperty(\n        this, 'accessToken', oauthResponse['oauthToken']);\n    fireauth.object.setReadonlyProperty(\n        this, 'secret', oauthResponse['oauthTokenSecret']);\n  } else {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n        'failed to construct a credential');\n  }\n\n  fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n  fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n *     idTokenPromise The RPC handler method that returns a promise which\n *     resolves with an ID token.\n * @override\n */\nfireauth.OAuthCredential.prototype.getIdTokenProvider = function(rpcHandler) {\n  return rpcHandler.verifyAssertion(\n      /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (\n      this.makeVerifyAssertionRequest_()));\n};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n *     are linked, returning the backend response.\n * @override\n */\nfireauth.OAuthCredential.prototype.linkToIdToken =\n    function(rpcHandler, idToken) {\n  var request = this.makeVerifyAssertionRequest_();\n  request['idToken'] = idToken;\n  return rpcHandler.verifyAssertionForLinking(\n      /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request));\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n *     idToken UID match succeeds and returns the server response.\n * @override\n */\nfireauth.OAuthCredential.prototype.matchIdTokenWithUid =\n    function(rpcHandler, uid) {\n  var request = this.makeVerifyAssertionRequest_();\n  // Do not create a new account if the user doesn't exist.\n  return fireauth.AuthCredential.verifyTokenResponseUid(\n      rpcHandler.verifyAssertionForExisting(\n          /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request)),\n      uid);\n};\n\n\n/**\n * @return {!Object} A request to the VerifyAssertion endpoint, populated with\n *     the OAuth data from this credential.\n * @private\n */\nfireauth.OAuthCredential.prototype.makeVerifyAssertionRequest_ = function() {\n  var postBody = {};\n  if (this['idToken']) {\n    postBody['id_token'] = this['idToken'];\n  }\n  if (this['accessToken']) {\n    postBody['access_token'] = this['accessToken'];\n  }\n  if (this['secret']) {\n    postBody['oauth_token_secret'] = this['secret'];\n  }\n  postBody['providerId'] = this['providerId'];\n  // Pass nonce in postBody if available.\n  if (this['nonce'] && !this.pendingToken_) {\n    postBody['nonce'] = this['nonce'];\n  }\n  var request = {\n    'postBody': goog.Uri.QueryData.createFromMap(postBody).toString(),\n    // Always use http://localhost.\n    'requestUri': 'http://localhost'\n  };\n  if (this.pendingToken_) {\n    // For pendingToken, just pass it through and drop postBody.\n    delete request['postBody'];\n    request['pendingToken'] = this.pendingToken_;\n  }\n  return request;\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.OAuthCredential.prototype.toPlainObject = function() {\n  var obj = {\n    'providerId': this['providerId'],\n    'signInMethod': this['signInMethod']\n  };\n  if (this['idToken']) {\n    obj['oauthIdToken'] = this['idToken'];\n  }\n  if (this['accessToken']) {\n    obj['oauthAccessToken'] = this['accessToken'];\n  }\n  if (this['secret']) {\n    obj['oauthTokenSecret'] = this['secret'];\n  }\n  if (this['nonce']) {\n    obj['nonce'] = this['nonce'];\n  }\n  if (this.pendingToken_) {\n    obj['pendingToken'] = this.pendingToken_;\n  }\n  return obj;\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of an\n *     OAuthCredential.\n * @return {?fireauth.OAuthCredential} The OAuth/OIDC credential if the object\n *     is a JSON representation of an OAuthCredential, null otherwise.\n */\nfireauth.OAuthCredential.fromJSON = function(json) {\n  if (json &&\n      json['providerId'] &&\n      json['signInMethod']) {\n    // Convert to OAuthResponse format.\n    var oauthResponse = {\n      // OIDC && google.com.\n      'idToken': json['oauthIdToken'],\n      // OAuth 2.0 providers.\n      'accessToken': json['oauthTokenSecret'] ? null : json['oauthAccessToken'],\n      // OAuth 1.0 provider, eg. Twitter.\n      'oauthTokenSecret': json['oauthTokenSecret'],\n      'oauthToken': json['oauthTokenSecret'] && json['oauthAccessToken'],\n      'nonce': json['nonce'],\n      'pendingToken': json['pendingToken']\n    };\n    try {\n      // Constructor will validate the OAuthResponse.\n      return new fireauth.OAuthCredential(\n          json['providerId'], oauthResponse, json['signInMethod']);\n    } catch (e) {\n      return null;\n    }\n  }\n  return null;\n};\n\n\n/**\n * A generic OAuth provider (OAuth1 or OAuth2).\n * @param {string} providerId The IdP provider ID (e.g. google.com,\n *     facebook.com) registered with the backend.\n * @param {?Array<string>=} opt_reservedParams The backlist of parameters that\n *     cannot be set through setCustomParameters.\n * @constructor\n */\nfireauth.FederatedProvider = function(providerId, opt_reservedParams) {\n  /** @private {!Array<string>} */\n  this.reservedParams_ = opt_reservedParams || [];\n\n  // Set read only instance providerId property.\n  // Set read only instance isOAuthProvider property.\n  fireauth.object.setReadonlyProperties(this, {\n    'providerId': providerId,\n    'isOAuthProvider': true\n  });\n\n  /** @private {!Object} The OAuth custom parameters for current provider. */\n  this.customParameters_ = {};\n  /** @protected {?string} The custom OAuth language parameter. */\n  this.languageParameter =\n      (fireauth.idp.getIdpSettings(/** @type {!fireauth.idp.ProviderId} */ (\n          providerId)) || {}).languageParam || null;\n  /** @protected {?string} The default language. */\n  this.defaultLanguageCode = null;\n};\n\n/**\n * @param {!Object} customParameters The custom OAuth parameters to pass\n *     in OAuth request.\n * @return {!fireauth.FederatedProvider} The FederatedProvider instance, for\n *     chaining method calls.\n */\nfireauth.FederatedProvider.prototype.setCustomParameters =\n    function(customParameters) {\n  this.customParameters_ = goog.object.clone(customParameters);\n  return this;\n};\n\n\n/**\n * Set the default language code on the provider instance.\n * @param {?string} languageCode The default language code to set if not already\n *     provided in the custom parameters.\n */\nfireauth.FederatedProvider.prototype.setDefaultLanguage =\n    function(languageCode) {\n  this.defaultLanguageCode = languageCode;\n};\n\n\n/**\n * @return {!Object} The custom OAuth parameters to pass in OAuth request.\n */\nfireauth.FederatedProvider.prototype.getCustomParameters = function() {\n  // The backend already checks for these values and makes sure no reserved\n  // fields like client ID, redirect URI, state are overwritten by these\n  // fields.\n  var params =\n      fireauth.util.copyWithoutNullsOrUndefined(this.customParameters_);\n  // Convert to strings.\n  for (var key in params) {\n    params[key] = params[key].toString();\n  }\n  // Remove blacklisted OAuth custom parameters.\n  var customParams =\n      fireauth.util.removeEntriesWithKeys(params, this.reservedParams_);\n  // If language param supported and not already provided, use default language.\n  if (this.languageParameter &&\n      this.defaultLanguageCode &&\n      !customParams[this.languageParameter]) {\n    customParams[this.languageParameter] = this.defaultLanguageCode;\n  }\n  return customParams;\n};\n\n\n/**\n * Generic SAML auth provider.\n * @param {string} providerId The SAML IdP provider ID (e.g. saml.saml2rp)\n *     registered with the backend.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.SAMLAuthProvider = function(providerId) {\n  // SAML provider IDs must be prefixed with the SAML_PREFIX.\n  if (!fireauth.idp.isSaml(providerId)) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'SAML provider IDs must be prefixed with \"' +\n        fireauth.constants.SAML_PREFIX + '\"');\n  }\n  // isOAuthProvider is true even though this is not an OAuth provider.\n  // This can be confusing as this is a SAML provider. However, this property\n  // is needed to allow signInWithPopup/Redirect. We should rename it to\n  // something more accurate: isFederatedProvider.\n  fireauth.SAMLAuthProvider.base(this, 'constructor', providerId, []);\n};\ngoog.inherits(fireauth.SAMLAuthProvider, fireauth.FederatedProvider);\n\n\n/**\n * Generic OAuth2 Auth provider.\n * @param {string} providerId The IdP provider ID (e.g. google.com,\n *     facebook.com) registered with the backend.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.OAuthProvider = function(providerId) {\n  fireauth.OAuthProvider.base(this, 'constructor', providerId,\n      fireauth.idp.RESERVED_OAUTH2_PARAMS);\n\n  /** @private {!Array<string>} The list of OAuth2 scopes to request. */\n  this.scopes_ = [];\n};\ngoog.inherits(fireauth.OAuthProvider, fireauth.FederatedProvider);\n\n\n/**\n * @param {string} scope The OAuth scope to request.\n * @return {!fireauth.OAuthProvider} The OAuthProvider instance, for chaining\n *     method calls.\n */\nfireauth.OAuthProvider.prototype.addScope = function(scope) {\n  // If not already added, add scope to list.\n  if (!goog.array.contains(this.scopes_, scope)) {\n    this.scopes_.push(scope);\n  }\n  return this;\n};\n\n\n/** @return {!Array<string>} The Auth provider's list of scopes. */\nfireauth.OAuthProvider.prototype.getScopes = function() {\n  return goog.array.clone(this.scopes_);\n};\n\n\n/**\n * Initializes an OAuth AuthCredential. At least one of ID token or access token\n * must be defined. When providing an OIDC ID token with a nonce encoded, the\n * raw nonce must also be provided.\n * @param {?Object|string} optionsOrIdToken Either the options object containing\n *     the ID token, access token and raw nonce or the ID token string.\n * @param {?string=} opt_accessToken The optional OAuth access token.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.OAuthProvider.prototype.credential =\n    function(optionsOrIdToken, opt_accessToken) {\n  var oauthResponse;\n  if (goog.isObject(optionsOrIdToken)) {\n    oauthResponse = {\n      'idToken': optionsOrIdToken['idToken'] || null,\n      'accessToken': optionsOrIdToken['accessToken'] || null,\n      'nonce': optionsOrIdToken['rawNonce'] || null\n    };\n  } else {\n    oauthResponse = {\n      'idToken': optionsOrIdToken || null,\n      'accessToken': opt_accessToken || null\n    };\n  }\n  if (!oauthResponse['idToken'] && !oauthResponse['accessToken']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        'credential failed: must provide the ID token and/or the access ' +\n        'token.');\n  }\n  // For OAuthCredential, sign in method is same as providerId.\n  return new fireauth.OAuthCredential(this['providerId'],\n                                      oauthResponse,\n                                      this['providerId']);\n};\n\n\n/**\n * Facebook Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.FacebookAuthProvider = function() {\n  fireauth.FacebookAuthProvider.base(this, 'constructor',\n      fireauth.idp.ProviderId.FACEBOOK);\n};\ngoog.inherits(fireauth.FacebookAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider,\n    'PROVIDER_ID', fireauth.idp.ProviderId.FACEBOOK);\n\nfireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider,\n    'FACEBOOK_SIGN_IN_METHOD', fireauth.idp.SignInMethod.FACEBOOK);\n\n\n/**\n * Initializes a Facebook AuthCredential.\n * @param {string} accessTokenOrObject The Facebook access token, or object\n *     containing the token for FirebaseUI backwards compatibility.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.FacebookAuthProvider.credential = function(accessTokenOrObject) {\n  if (!accessTokenOrObject) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        'credential failed: expected 1 argument (the OAuth access token).');\n  }\n  var accessToken = accessTokenOrObject;\n  if (goog.isObject(accessTokenOrObject)) {\n    accessToken = accessTokenOrObject['accessToken'];\n  }\n  return new fireauth.FacebookAuthProvider().credential({\n    'accessToken': /** @type {string} */ (accessToken)\n  });\n};\n\n\n/**\n * GitHub Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.GithubAuthProvider = function() {\n  fireauth.GithubAuthProvider.base(this, 'constructor',\n      fireauth.idp.ProviderId.GITHUB);\n};\ngoog.inherits(fireauth.GithubAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider,\n    'PROVIDER_ID', fireauth.idp.ProviderId.GITHUB);\n\nfireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider,\n    'GITHUB_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GITHUB);\n\n\n/**\n * Initializes a GitHub AuthCredential.\n * @param {string} accessTokenOrObject The GitHub access token, or object\n *     containing the token for FirebaseUI backwards compatibility.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.GithubAuthProvider.credential = function(accessTokenOrObject) {\n  if (!accessTokenOrObject) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        'credential failed: expected 1 argument (the OAuth access token).');\n  }\n  var accessToken = accessTokenOrObject;\n  if (goog.isObject(accessTokenOrObject)) {\n    accessToken = accessTokenOrObject['accessToken'];\n  }\n  return new fireauth.GithubAuthProvider().credential({\n    'accessToken': /** @type {string} */ (accessToken)\n  });\n};\n\n\n/**\n * Google Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.GoogleAuthProvider = function() {\n  fireauth.GoogleAuthProvider.base(this, 'constructor',\n      fireauth.idp.ProviderId.GOOGLE);\n\n  // Add profile scope to Google Auth provider as default scope.\n  // This is to ensure profile info is populated in current user.\n  this.addScope('profile');\n};\ngoog.inherits(fireauth.GoogleAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider,\n    'PROVIDER_ID', fireauth.idp.ProviderId.GOOGLE);\n\nfireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider,\n    'GOOGLE_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GOOGLE);\n\n\n/**\n * Initializes a Google AuthCredential.\n * @param {?string=} idTokenOrObject The Google ID token. If null or undefined,\n *     we expect the access token to be passed. It can also be an object\n *     containing the tokens for FirebaseUI backwards compatibility.\n * @param {?string=} accessToken The Google access token. If null or\n *     undefined, we expect the ID token to have been passed.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.GoogleAuthProvider.credential =\n    function(idTokenOrObject, accessToken) {\n  var idToken = idTokenOrObject;\n  if (goog.isObject(idTokenOrObject)) {\n    idToken = idTokenOrObject['idToken'];\n    accessToken = idTokenOrObject['accessToken'];\n  }\n  return new fireauth.GoogleAuthProvider().credential({\n    'idToken':  /** @type {string} */ (idToken),\n    'accessToken': /** @type {string} */ (accessToken)\n  });\n};\n\n\n/**\n * Twitter Auth provider.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.TwitterAuthProvider = function() {\n  fireauth.TwitterAuthProvider.base(this, 'constructor',\n      fireauth.idp.ProviderId.TWITTER,\n      fireauth.idp.RESERVED_OAUTH1_PARAMS);\n};\ngoog.inherits(fireauth.TwitterAuthProvider, fireauth.FederatedProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider,\n    'PROVIDER_ID', fireauth.idp.ProviderId.TWITTER);\n\nfireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider,\n    'TWITTER_SIGN_IN_METHOD', fireauth.idp.SignInMethod.TWITTER);\n\n\n/**\n * Initializes a Twitter AuthCredential.\n * @param {string} tokenOrObject The Twitter access token, or object\n *     containing the token for FirebaseUI backwards compatibility.\n * @param {string} secret The Twitter secret.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.TwitterAuthProvider.credential = function(tokenOrObject, secret) {\n  var tokenObject = tokenOrObject;\n  if (!goog.isObject(tokenObject)) {\n    tokenObject = {\n      'oauthToken': tokenOrObject,\n      'oauthTokenSecret': secret\n    };\n  }\n\n  if (!tokenObject['oauthToken'] || !tokenObject['oauthTokenSecret']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        'credential failed: expected 2 arguments (the OAuth access token ' +\n        'and secret).');\n  }\n\n  return new fireauth.OAuthCredential(fireauth.idp.ProviderId.TWITTER,\n      /** @type {!fireauth.OAuthResponse} */ (tokenObject),\n      fireauth.idp.SignInMethod.TWITTER);\n};\n\n\n/**\n * The email and password credential class.\n * @param {string} email The credential email.\n * @param {string} password The credential password.\n * @param {string=} opt_signInMethod The credential sign in method can be either\n *     'password' or 'emailLink'\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.EmailAuthCredential = function(email, password, opt_signInMethod) {\n  this.email_ = email;\n  this.password_ = password;\n  fireauth.object.setReadonlyProperty(this, 'providerId',\n      fireauth.idp.ProviderId.PASSWORD);\n  var signInMethod = opt_signInMethod ===\n      fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] ?\n      fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] :\n      fireauth.EmailAuthProvider['EMAIL_PASSWORD_SIGN_IN_METHOD'];\n  fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n *     idTokenPromise The RPC handler method that returns a promise which\n *     resolves with an ID token.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.getIdTokenProvider =\n    function(rpcHandler) {\n  if (this['signInMethod'] ==\n      fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) {\n    return rpcHandler.emailLinkSignIn(this.email_, this.password_);\n  }\n  return rpcHandler.verifyPassword(this.email_, this.password_);\n};\n\n\n/**\n * Adds an email and password account to an existing account, identified by an\n * ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n *     are linked, returning the backend response.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.linkToIdToken =\n    function(rpcHandler, idToken) {\n  if (this['signInMethod'] ==\n      fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) {\n    return rpcHandler.emailLinkSignInForLinking(\n        idToken, this.email_, this.password_);\n  }\n  return rpcHandler.updateEmailAndPassword(\n      idToken, this.email_, this.password_);\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n *     reauthentication succeeds.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.matchIdTokenWithUid =\n    function(rpcHandler, uid) {\n  // Do not create a new account if the user doesn't exist.\n  return fireauth.AuthCredential.verifyTokenResponseUid(\n      // This shouldn't create a new email/password account.\n      this.getIdTokenProvider(rpcHandler),\n      uid);\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.toPlainObject = function() {\n  return {\n    'email': this.email_,\n    'password': this.password_,\n    'signInMethod': this['signInMethod']\n  };\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n *     EmailAuthCredential.\n * @return {?fireauth.EmailAuthCredential} The email credential if the object\n *     is a JSON representation of an EmailAuthCredential, null otherwise.\n */\nfireauth.EmailAuthCredential.fromJSON = function(json) {\n  if (json && json['email'] && json['password']) {\n    return new fireauth.EmailAuthCredential(\n        json['email'],\n        json['password'],\n        json['signInMethod']);\n  }\n  return null;\n};\n\n\n/**\n * Email password Auth provider implementation.\n * @constructor\n * @implements {fireauth.AuthProvider}\n */\nfireauth.EmailAuthProvider = function() {\n  // Set read-only instance providerId and isOAuthProvider property.\n  fireauth.object.setReadonlyProperties(this, {\n    'providerId': fireauth.idp.ProviderId.PASSWORD,\n    'isOAuthProvider': false\n  });\n};\n\n\n/**\n * Initializes an instance of an email/password Auth credential.\n * @param {string} email The credential email.\n * @param {string} password The credential password.\n * @return {!fireauth.EmailAuthCredential} The Auth credential object.\n */\nfireauth.EmailAuthProvider.credential = function(email, password) {\n  return new fireauth.EmailAuthCredential(email, password);\n};\n\n\n/**\n * @param {string} email The credential email.\n * @param {string} emailLink The credential email link.\n * @return {!fireauth.EmailAuthCredential} The Auth credential object.\n */\nfireauth.EmailAuthProvider.credentialWithLink = function(email, emailLink) {\n  var actionCodeUrl = fireauth.EmailAuthProvider\n      .getActionCodeUrlFromSignInEmailLink(emailLink);\n  if (!actionCodeUrl) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!');\n  }\n  return new fireauth.EmailAuthCredential(email, actionCodeUrl['code'],\n      fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']);\n};\n\n\n/**\n * @param {string} emailLink The sign in email link to be validated.\n * @return {?fireauth.ActionCodeURL} The sign in email link action code URL.\n *     Returns null if the email link is invalid.\n */\nfireauth.EmailAuthProvider.getActionCodeUrlFromSignInEmailLink =\n    function(emailLink) {\n  emailLink = fireauth.DynamicLink.parseDeepLink(emailLink);\n  var actionCodeUrl = fireauth.ActionCodeURL.parseLink(emailLink);\n  if (actionCodeUrl && (actionCodeUrl['operation'] ===\n      fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN)) {\n    return actionCodeUrl;\n  }\n  return null;\n};\n\n\n// Set read only PROVIDER_ID property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n  'PROVIDER_ID': fireauth.idp.ProviderId.PASSWORD\n});\n\n// Set read only EMAIL_LINK_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n  'EMAIL_LINK_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_LINK\n});\n\n// Set read only EMAIL_PASSWORD_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n  'EMAIL_PASSWORD_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_PASSWORD\n});\n\n\n/**\n * A credential for phone number sign-in. Phone credentials can also be used as\n * second factor assertions.\n * A `PhoneAuthCredential` is also a `MultiFactorAuthCredential`. A\n * `PhoneMultiFactorAssertion` requires a `PhoneAuthCredential`.\n * @param {!fireauth.PhoneAuthCredential.Parameters_} params The credential\n *     parameters that prove the user owns the claimed phone number.\n * @constructor\n * @implements {fireauth.MultiFactorAuthCredential}\n */\nfireauth.PhoneAuthCredential = function(params) {\n  // Either verification ID and code, or phone number temporary proof must be\n  // provided.\n  if (!(params.verificationId && params.verificationCode) &&\n      !(params.temporaryProof && params.phoneNumber)) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n\n  /**\n   * The phone Auth parameters that prove ownership of a phone number, either\n   * through completion of a phone verification flow, or by referencing a\n   * previously completed verification flow (\"temporaryProof\").\n   * @private {!fireauth.PhoneAuthCredential.Parameters_}\n   */\n  this.params_ = params;\n\n  fireauth.object.setReadonlyProperty(this, 'providerId',\n      fireauth.idp.ProviderId.PHONE);\n  /**\n   * @public {string} The provider ID required by the\n   *     `fireauth.MultiFactorAuthCredential` interface.\n   */\n  this.providerId = fireauth.idp.ProviderId.PHONE;\n\n  fireauth.object.setReadonlyProperty(\n      this, 'signInMethod', fireauth.idp.SignInMethod.PHONE);\n};\n\n\n/**\n * Parameters that prove ownership of a phone number via a ID \"verificationId\"\n * of a request to send a code to the phone number, with the code\n * \"verificationCode\" that the user received on their phone.\n * @private\n * @typedef {{\n *   verificationId: string,\n *   verificationCode: string\n * }}\n */\nfireauth.PhoneAuthCredential.VerificationParameters_;\n\n\n/**\n * Parameters that prove ownership of a phone number by referencing a previously\n * completed phone Auth flow.\n * @private\n * @typedef {{\n *   temporaryProof: string,\n *   phoneNumber: string\n * }}\n */\nfireauth.PhoneAuthCredential.TemporaryProofParameters_;\n\n\n/**\n * @private\n * @typedef {\n *   !fireauth.PhoneAuthCredential.VerificationParameters_|\n *   !fireauth.PhoneAuthCredential.TemporaryProofParameters_\n * }\n */\nfireauth.PhoneAuthCredential.Parameters_;\n\n\n/**\n * Retrieves an ID token from the backend given the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object>} A Promise that resolves with the\n *     backend response.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.getIdTokenProvider =\n    function(rpcHandler) {\n  return rpcHandler.verifyPhoneNumber(this.makeVerifyPhoneNumberRequest_());\n};\n\n\n/**\n * Adds a phone credential to an existing account identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n *     are linked, returning the backend response.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.linkToIdToken =\n    function(rpcHandler, idToken) {\n  var request = this.makeVerifyPhoneNumberRequest_();\n  request['idToken'] = idToken;\n  return rpcHandler.verifyPhoneNumberForLinking(request);\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n *     reauthentication succeeds.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.matchIdTokenWithUid =\n    function(rpcHandler, uid) {\n  var request = this.makeVerifyPhoneNumberRequest_();\n  return fireauth.AuthCredential.verifyTokenResponseUid(\n      rpcHandler.verifyPhoneNumberForExisting(request),\n      uid);\n};\n\n\n/**\n * Converts a PhoneAuthCredential to a plain object.\n * @return {!Object}\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.toPlainObject = function() {\n  var obj =  {\n    'providerId': fireauth.idp.ProviderId.PHONE\n  };\n  if (this.params_.verificationId) {\n    obj['verificationId'] = this.params_.verificationId;\n  }\n  if (this.params_.verificationCode) {\n    obj['verificationCode'] = this.params_.verificationCode;\n  }\n  if (this.params_.temporaryProof) {\n    obj['temporaryProof'] = this.params_.temporaryProof;\n  }\n  if (this.params_.phoneNumber) {\n    obj['phoneNumber'] = this.params_.phoneNumber;\n  }\n  return obj;\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n *     PhoneAuthCredential.\n * @return {?fireauth.PhoneAuthCredential} The phone credential if the object\n *     is a JSON representation of an PhoneAuthCredential, null otherwise.\n */\nfireauth.PhoneAuthCredential.fromJSON = function(json) {\n  if (json &&\n      json['providerId'] === fireauth.idp.ProviderId.PHONE &&\n      ((json['verificationId'] && json['verificationCode']) ||\n       (json['temporaryProof'] && json['phoneNumber']))) {\n    var params = {};\n    var allowedKeys = [\n      'verificationId', 'verificationCode', 'temporaryProof', 'phoneNumber'\n    ];\n    goog.array.forEach(allowedKeys, function(key) {\n      if (json[key]) {\n        params[key] = json[key];\n      }\n    });\n    return new fireauth.PhoneAuthCredential(\n        /** @type {!fireauth.PhoneAuthCredential.Parameters_} */ (params));\n  }\n  return null;\n};\n\n\n/**\n * @return {!Object} A request to the verifyPhoneNumber endpoint based on the\n *     current state of the object.\n * @private\n */\nfireauth.PhoneAuthCredential.prototype.makeVerifyPhoneNumberRequest_ =\n    function() {\n  if (this.params_.temporaryProof && this.params_.phoneNumber) {\n    return {\n      'temporaryProof': this.params_.temporaryProof,\n      'phoneNumber': this.params_.phoneNumber\n    };\n  }\n\n  return {\n    'sessionInfo': this.params_.verificationId,\n    'code': this.params_.verificationCode\n  };\n};\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current AuthCredential\n * using the enrollment request identifier.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n *     The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the updated ID and refresh tokens.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.finalizeMfaEnrollment =\n    function(rpcHandler, enrollmentRequest) {\n  goog.object.extend(\n      enrollmentRequest,\n      {\n        'phoneVerificationInfo': this.makeVerifyPhoneNumberRequest_()\n      });\n  return /** @type {!goog.Promise<{idToken: string, refreshToken: string}>} */ (\n      rpcHandler.finalizePhoneMfaEnrollment(enrollmentRequest));\n};\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current AuthCredential\n * using the sign-in request identifier.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n *     The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the signed in user's ID and refresh tokens.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.finalizeMfaSignIn =\n    function(rpcHandler, signInRequest) {\n  goog.object.extend(\n      signInRequest,\n      {\n        'phoneVerificationInfo': this.makeVerifyPhoneNumberRequest_()\n      });\n  return /** @type {!goog.Promise<{idToken: string, refreshToken: string}>} */ (\n      rpcHandler.finalizePhoneMfaSignIn(signInRequest));\n};\n\n\n/**\n * Phone Auth provider implementation.\n * @param {?fireauth.Auth=} opt_auth The Firebase Auth instance.\n * @constructor\n * @implements {fireauth.AuthProvider}\n */\nfireauth.PhoneAuthProvider = function(opt_auth) {\n  try {\n    /** @private {!fireauth.Auth} */\n    this.auth_ = opt_auth || firebase['auth']();\n  } catch (e) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        'Either an instance of firebase.auth.Auth must be passed as an ' +\n        'argument to the firebase.auth.PhoneAuthProvider constructor, or the ' +\n        'default firebase App instance must be initialized via ' +\n        'firebase.initializeApp().');\n  }\n  fireauth.object.setReadonlyProperties(this, {\n    'providerId': fireauth.idp.ProviderId.PHONE,\n    'isOAuthProvider': false\n  });\n};\n\n\n/**\n * The phone info options for single-factor sign-in. Only phone number is\n * required.\n * @private\n * @typedef {{\n *   phoneNumber: string\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneSingleFactorInfoOptions_;\n\n/**\n * The phone info options for multi-factor enrollment. Phone number and\n * multi-factor session are required.\n * @private\n * @typedef {{\n *   phoneNumber: string,\n *   session: !fireauth.MultiFactorSession\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneMultiFactorEnrollInfoOptions_;\n\n\n/**\n * The phone info options for multi-factor sign-in. Either multi-factor hint or\n * multi-factor UID and multi-factor session are required.\n * @private\n * @typedef {{\n *   multiFactorHint: !fireauth.MultiFactorInfo,\n *   session: !fireauth.MultiFactorSession\n * }|{\n *   multiFactorUid: string,\n *   session: !fireauth.MultiFactorSession\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneMultiFactorSignInInfoOptions_;\n\n\n/**\n * The options for verifying the ownership of the phone number. It could be\n * used for single-factor sign-in, multi-factor enrollment or multi-factor\n * sign-in.\n * @typedef {\n *   !fireauth.PhoneAuthProvider.PhoneSingleFactorInfoOptions_|\n *   !fireauth.PhoneAuthProvider.PhoneMultiFactorEnrollInfoOptions_|\n *   !fireauth.PhoneAuthProvider.PhoneMultiFactorSignInInfoOptions_\n * }\n */\nfireauth.PhoneAuthProvider.PhoneInfoOptions;\n\n\n/**\n * Initiates a phone number confirmation flow. If session is provided, it is\n * used to verify ownership of the second factor phone number.\n *\n * @param {string|!fireauth.PhoneAuthProvider.PhoneInfoOptions} phoneInfoOptions\n *     The user's phone options for verifying the ownship of the phone number.\n * @param {!firebase.auth.ApplicationVerifier} applicationVerifier The\n *     application verifier for anti-abuse purposes.\n * @return {!goog.Promise<string>} A Promise that resolves with the\n *     verificationId of the phone number confirmation flow.\n */\nfireauth.PhoneAuthProvider.prototype.verifyPhoneNumber =\n    function(phoneInfoOptions, applicationVerifier) {\n  var rpcHandler = this.auth_.getRpcHandler();\n\n  // Convert the promise into a goog.Promise. If the applicationVerifier throws\n  // an error, just propagate it to the client. Reset the reCAPTCHA widget every\n  // time after sending the token to the server.\n  return goog.Promise.resolve(applicationVerifier['verify']())\n      .then(function(assertion) {\n        if (typeof assertion !== 'string') {\n          throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n              'An implementation of firebase.auth.ApplicationVerifier' +\n              '.prototype.verify() must return a firebase.Promise ' +\n              'that resolves with a string.');\n        }\n\n        switch (applicationVerifier['type']) {\n          case 'recaptcha':\n            var session = goog.isObject(phoneInfoOptions) ?\n                phoneInfoOptions['session'] : null;\n            // PhoneInfoOptions can be a phone number string for backward\n            // compatibility.\n            var phoneNumber = goog.isObject(phoneInfoOptions) ?\n                phoneInfoOptions['phoneNumber'] : phoneInfoOptions;\n            var verifyPromise;\n            if (session &&\n                session.type == fireauth.MultiFactorSession.Type.ENROLL) {\n              verifyPromise = session.getRawSession()\n                  .then(function(rawSession) {\n                    return rpcHandler.startPhoneMfaEnrollment({\n                      'idToken': rawSession,\n                      'phoneEnrollmentInfo': {\n                        'phoneNumber': phoneNumber,\n                        'recaptchaToken': assertion\n                      }\n                    });\n                  });\n            } else if (session &&\n                       session.type ==\n                           fireauth.MultiFactorSession.Type.SIGN_IN) {\n              verifyPromise = session.getRawSession()\n                  .then(function(rawSession) {\n                    var mfaEnrollmentId =\n                        (phoneInfoOptions['multiFactorHint'] &&\n                         phoneInfoOptions['multiFactorHint']['uid']) ||\n                        phoneInfoOptions['multiFactorUid'];\n                    return rpcHandler.startPhoneMfaSignIn({\n                      'mfaPendingCredential': rawSession,\n                      'mfaEnrollmentId': mfaEnrollmentId,\n                      'phoneSignInInfo': {\n                        'recaptchaToken': assertion\n                      }\n                    });\n                  });\n            } else {\n              verifyPromise = rpcHandler.sendVerificationCode({\n                'phoneNumber': phoneNumber,\n                'recaptchaToken': assertion\n              });\n            }\n            // Reset the applicationVerifier after code is sent.\n            return verifyPromise.then(function(verificationId) {\n              if (typeof applicationVerifier.reset === 'function') {\n                applicationVerifier.reset();\n              }\n              return verificationId;\n            }, function(error) {\n              if (typeof applicationVerifier.reset === 'function') {\n                applicationVerifier.reset();\n              }\n              throw error;\n            });\n          default:\n            throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n                'Only firebase.auth.ApplicationVerifiers with ' +\n                'type=\"recaptcha\" are currently supported.');\n        }\n      });\n};\n\n\n/**\n * Creates a PhoneAuthCredential.\n * @param {string} verificationId The ID of the phone number flow, to correlate\n *     this request with a previous call to\n *     PhoneAuthProvider.prototype.verifyPhoneNumber.\n * @param {string} verificationCode The verification code that was sent to the\n *     user's phone.\n * @return {!fireauth.PhoneAuthCredential}\n */\nfireauth.PhoneAuthProvider.credential =\n    function(verificationId, verificationCode) {\n  if (!verificationId) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_SESSION_INFO);\n  }\n  if (!verificationCode) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n  }\n  return new fireauth.PhoneAuthCredential({\n    verificationId: verificationId,\n    verificationCode: verificationCode\n  });\n};\n\n\n// Set read only PROVIDER_ID property.\nfireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, {\n  'PROVIDER_ID': fireauth.idp.ProviderId.PHONE\n});\n\n\n// Set read only PHONE_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, {\n  'PHONE_SIGN_IN_METHOD': fireauth.idp.SignInMethod.PHONE\n});\n\n\n/**\n * Constructs an Auth credential from a backend response.\n * Note, unlike fromJSON which constructs the AuthCredential from a toJSON()\n * response, this helper constructs the credential from the server response.\n * @param {?Object} response The backend response to build a credential from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthProvider.getCredentialFromResponse = function(response) {\n  // Handle phone Auth credential responses, as they have a different format\n  // from other backend responses (i.e. no providerId).\n  if (response['temporaryProof'] && response['phoneNumber']) {\n    return new fireauth.PhoneAuthCredential({\n      temporaryProof: response['temporaryProof'],\n      phoneNumber: response['phoneNumber']\n    });\n  }\n\n  // Get all OAuth response parameters from response.\n  var providerId = response && response['providerId'];\n\n  // Email and password is not supported as there is no situation where the\n  // server would return the password to the client.\n  if (!providerId || providerId === fireauth.idp.ProviderId.PASSWORD) {\n    return null;\n  }\n\n  var accessToken = response && response['oauthAccessToken'];\n  var accessTokenSecret = response && response['oauthTokenSecret'];\n  // Note this is not actually returned by the backend. It is introduced in\n  // rpcHandler.\n  var rawNonce = response && response['nonce'];\n  // Google Id Token returned when no additional scopes provided.\n  var idToken = response && response['oauthIdToken'];\n  // Pending token for SAML and OAuth/OIDC providers.\n  var pendingToken = response && response['pendingToken'];\n  try {\n    switch (providerId) {\n      case fireauth.idp.ProviderId.GOOGLE:\n        return fireauth.GoogleAuthProvider.credential(\n            idToken, accessToken);\n\n      case fireauth.idp.ProviderId.FACEBOOK:\n        return fireauth.FacebookAuthProvider.credential(\n            accessToken);\n\n      case fireauth.idp.ProviderId.GITHUB:\n        return fireauth.GithubAuthProvider.credential(\n            accessToken);\n\n      case fireauth.idp.ProviderId.TWITTER:\n        return fireauth.TwitterAuthProvider.credential(\n            accessToken, accessTokenSecret);\n\n      default:\n        if (!accessToken && !accessTokenSecret && !idToken && !pendingToken) {\n          return null;\n        }\n        if (pendingToken) {\n          if (providerId.indexOf(fireauth.constants.SAML_PREFIX) == 0) {\n            return new fireauth.SAMLAuthCredential(providerId, pendingToken);\n          } else {\n            // OIDC and non-default providers excluding Twitter.\n            return new fireauth.OAuthCredential(\n                providerId,\n                {\n                  'pendingToken': pendingToken,\n                  'idToken': response['oauthIdToken'],\n                  'accessToken': response['oauthAccessToken']\n                },\n                providerId);\n          }\n        }\n        return new fireauth.OAuthProvider(providerId).credential({\n          'idToken': idToken,\n          'accessToken': accessToken,\n          'rawNonce': rawNonce\n        });\n    }\n  } catch (e) {\n    return null;\n  }\n};\n\n\n/**\n * Constructs an Auth credential from a JSON representation.\n * Note, unlike getCredentialFromResponse which constructs the AuthCredential\n * from a server response, this helper constructs credential from the toJSON()\n * result.\n * @param {!Object|string} json The JSON representation to construct credential\n *     from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthProvider.getCredentialFromJSON = function(json) {\n  var obj = typeof json === 'string' ? JSON.parse(json) : json;\n  var credential;\n  var fromJSON = [\n    fireauth.OAuthCredential.fromJSON,\n    fireauth.EmailAuthCredential.fromJSON,\n    fireauth.PhoneAuthCredential.fromJSON,\n    fireauth.SAMLAuthCredential.fromJSON\n  ];\n  for (var i = 0; i < fromJSON.length; i++) {\n    credential = fromJSON[i](obj);\n    if (credential) {\n      return credential;\n    }\n  }\n  return null;\n};\n\n\n/**\n * Constructs an Auth credential from a JSON representation.\n * @param {!Object|string} json The JSON representation to construct credential from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthCredential.fromPlainObject =\n    fireauth.AuthProvider.getCredentialFromJSON;\n\n\n/**\n * Checks if OAuth is supported by provider, if not throws an error.\n * @param {!fireauth.AuthProvider} provider The provider to check.\n */\nfireauth.AuthProvider.checkIfOAuthSupported =\n    function(provider) {\n  if (!provider['isOAuthProvider']) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INVALID_OAUTH_PROVIDER);\n  }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the Auth event object.\n */\n\ngoog.provide('fireauth.AuthEvent');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Defines the authentication event.\n * @param {!fireauth.AuthEvent.Type} type The Auth event type.\n * @param {?string=} opt_eventId The event identifier.\n * @param {?string=} opt_urlResponse The URL with IdP response.\n * @param {?string=} opt_sessionId The session ID used to prevent session\n *     fixation attacks.\n * @param {?fireauth.AuthError=} opt_error The optional error encountered.\n * @param {?string=} opt_postBody The optional POST body.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @constructor\n */\nfireauth.AuthEvent = function(\n    type, opt_eventId, opt_urlResponse, opt_sessionId, opt_error,\n    opt_postBody, opt_tenantId) {\n  /** @const @private {!fireauth.AuthEvent.Type} The Auth event type. */\n  this.type_ = type;\n  /** @const @private {?string} The Auth event ID. */\n  this.eventId_ = opt_eventId || null;\n  /** @const @private {?string} The callback URL with the sign in response. */\n  this.urlResponse_ = opt_urlResponse || null;\n  /** @const @private {?string} The sign in operation session ID. */\n  this.sessionId_ = opt_sessionId || null;\n  /** @const @private {?string} The POST body string if available. */\n  this.postBody_ = opt_postBody || null;\n  /** @const @private {?string} The tenant ID if available. */\n  this.tenantId_ = opt_tenantId || null;\n  /**\n   * @const @private {?fireauth.AuthError} The Auth event error if available.\n   */\n  this.error_ = opt_error || null;\n  if (!this.urlResponse_ && !this.error_) {\n    // Either URL or error is required. They can't be both null.\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n  } else if (this.urlResponse_ && this.error_) {\n    // An error must not be provided when a URL is available.\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n  } else if (this.urlResponse_ && !this.sessionId_) {\n    // A session ID must accompany a URL response.\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n  }\n};\n\n\n\n/**\n * Auth event operation types.\n * All Auth event types that are used for popup operations should be suffixed\n * with `Popup`, whereas those used for redirect operations should be suffixed\n * with `Redirect`.\n * TODO: consider changing the type from a string to an object with ID\n * and some metadata for determining mode: redirect, popup or none.\n * @enum {string}\n */\nfireauth.AuthEvent.Type = {\n  LINK_VIA_POPUP: 'linkViaPopup',\n  LINK_VIA_REDIRECT: 'linkViaRedirect',\n  REAUTH_VIA_POPUP: 'reauthViaPopup',\n  REAUTH_VIA_REDIRECT: 'reauthViaRedirect',\n  SIGN_IN_VIA_POPUP: 'signInViaPopup',\n  SIGN_IN_VIA_REDIRECT: 'signInViaRedirect',\n  UNKNOWN: 'unknown',\n  VERIFY_APP: 'verifyApp'\n};\n\n\n/**\n * @param {!fireauth.AuthEvent} event The Auth event.\n * @return {boolean} Whether the event is a redirect type.\n */\nfireauth.AuthEvent.isRedirect = function(event) {\n  return !!event.getType().match(/Redirect$/);\n};\n\n\n/**\n * @param {!fireauth.AuthEvent} event The Auth event.\n * @return {boolean} Whether the event is a popup type.\n */\nfireauth.AuthEvent.isPopup = function(event) {\n  return !!event.getType().match(/Popup$/);\n};\n\n\n/** @return {!fireauth.AuthEvent.Type} The type of Auth event. */\nfireauth.AuthEvent.prototype.getType = function() {\n  return this.type_;\n};\n\n\n/** @return {?string} The Auth event identifier. */\nfireauth.AuthEvent.prototype.getEventId = function() {\n  return this.eventId_;\n};\n\n\n/** @return {string} The event unique identifier. */\nfireauth.AuthEvent.prototype.getUid = function() {\n  var components = [];\n  components.push(this.type_);\n  if (this.eventId_) {\n    components.push(this.eventId_);\n  }\n  if (this.sessionId_) {\n    components.push(this.sessionId_);\n  }\n  if (this.tenantId_) {\n    components.push(this.tenantId_);\n  }\n  return components.join('-');\n};\n\n\n/** @return {?string} The url response of Auth event. */\nfireauth.AuthEvent.prototype.getUrlResponse = function() {\n  return this.urlResponse_;\n};\n\n\n/** @return {?string} The session ID Auth event. */\nfireauth.AuthEvent.prototype.getSessionId = function() {\n  return this.sessionId_;\n};\n\n\n/** @return {?string} The POST body of the Auth event, if available. */\nfireauth.AuthEvent.prototype.getPostBody = function() {\n  return this.postBody_;\n};\n\n\n/** @return {?string} The tenant ID of the Auth event, if available. */\nfireauth.AuthEvent.prototype.getTenantId = function() {\n  return this.tenantId_;\n};\n\n\n/** @return {?fireauth.AuthError} The error of Auth event. */\nfireauth.AuthEvent.prototype.getError = function() {\n  return this.error_;\n};\n\n\n/** @return {boolean} Whether Auth event has an error. */\nfireauth.AuthEvent.prototype.hasError = function() {\n  return !!this.error_;\n};\n\n\n/** @return {!Object} The plain object representation of event. */\nfireauth.AuthEvent.prototype.toPlainObject = function() {\n  return {\n    'type': this.type_,\n    'eventId': this.eventId_,\n    'urlResponse': this.urlResponse_,\n    'sessionId': this.sessionId_,\n    'postBody': this.postBody_,\n    'tenantId': this.tenantId_,\n    'error': this.error_ && this.error_.toPlainObject()\n  };\n};\n\n\n/**\n * @param {?Object} rawResponse The plain object representation of Auth event.\n * @return {?fireauth.AuthEvent} The Auth event representation of plain object.\n */\nfireauth.AuthEvent.fromPlainObject = function(rawResponse) {\n  var response = rawResponse || {};\n  if (response['type']) {\n    return new fireauth.AuthEvent(\n        response['type'],\n        response['eventId'],\n        response['urlResponse'],\n        response['sessionId'],\n        response['error'] &&\n            fireauth.AuthError.fromPlainObject(response['error']),\n        response['postBody'],\n        response['tenantId']\n        );\n  }\n  return null;\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Provides the universal link subscriber utility to allow\n * multiple subscriptions for incoming universal link detection.\n */\ngoog.provide('fireauth.UniversalLinkSubscriber');\n\ngoog.require('fireauth.util');\ngoog.require('goog.array');\n\n/**\n * Defines the universal link subscriber class used to allow multiple universal\n * link subscriptions since the underlying plugin only works with one.\n * This utility is needed since the universal link cordova plugin can only allow\n * one subscriber and multiple app instances can subscribe to this.\n * @constructor @final @struct\n */\nfireauth.UniversalLinkSubscriber = function() {\n  /**\n   * @private {?function(?Object)} The master callback that subscribes directly\n   *     to universalLinks.\n   */\n  this.masterCb_ = null;\n  /**\n   * @private {!Array<function(?Object)>} The list of external subscribers that\n   *     are triggered every time the master callback is triggered.\n   */\n  this.cb_ = [];\n};\n\n\n/**\n * @return {!fireauth.UniversalLinkSubscriber} The default universal link\n *     subscriber instance.\n */\nfireauth.UniversalLinkSubscriber.getInstance = function() {\n  if (!fireauth.UniversalLinkSubscriber.instance_) {\n    fireauth.UniversalLinkSubscriber.instance_ =\n        new fireauth.UniversalLinkSubscriber();\n  }\n  return fireauth.UniversalLinkSubscriber.instance_;\n};\n\n\n/** Clears singleton instance. Useful for testing. */\nfireauth.UniversalLinkSubscriber.clear = function() {\n  fireauth.UniversalLinkSubscriber.instance_ = null;\n};\n\n\n/**\n * @private {?fireauth.UniversalLinkSubscriber} The singleton universal\n *     link subscriber instance.\n */\nfireauth.UniversalLinkSubscriber.instance_ = null;\n\n\n/**\n * Subscribes a callback to the universal link plugin listener.\n * @param {function(?Object)} cb The callback to subscribe to the universal\n *     link plugin.\n */\nfireauth.UniversalLinkSubscriber.prototype.subscribe  = function(cb) {\n  var self = this;\n  this.cb_.push(cb);\n  if (!this.masterCb_) {\n    this.masterCb_ = function(event) {\n      for (var i = 0; i < self.cb_.length; i++) {\n        self.cb_[i](event);\n      }\n    };\n    var subscribe = fireauth.util.getObjectRef(\n        'universalLinks.subscribe', goog.global);\n    // For iOS environments, this plugin is not used, therefore this is a no-op\n    // and no error needs to be thrown.\n    if (typeof subscribe === 'function') {\n      subscribe(null, this.masterCb_);\n    }\n  }\n};\n\n\n/**\n * Unsubscribes a callback from the universal link plugin listener.\n * @param {function(?Object)} cb The callback to unsubscribe from the universal\n *     link plugin.\n */\nfireauth.UniversalLinkSubscriber.prototype.unsubscribe = function(cb) {\n  goog.array.removeAllIf(this.cb_, function(ele) {\n    return ele == cb;\n  });\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the invalid origin error, a subclass of\n * fireauth.AuthError.\n */\n\n\ngoog.provide('fireauth.InvalidOriginError');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('goog.Uri');\ngoog.require('goog.string');\n\n\n\n/**\n * Invalid origin error that can be returned to the developer.\n * @param {string} origin The invalid domain name.\n * @constructor\n * @extends {fireauth.AuthError}\n */\nfireauth.InvalidOriginError = function(origin) {\n  var code = fireauth.authenum.Error.INVALID_ORIGIN;\n  var message = undefined;\n  var uri = goog.Uri.parse(origin);\n  // Get domain.\n  var domain = uri.getDomain();\n  // Get scheme.\n  var scheme = uri.getScheme();\n  // Only http, https and chrome-extension currently supported.\n  if (scheme == 'chrome-extension') {\n    // Chrome extension whitelisting.\n    // Replace chrome-extension://CHROME_EXT_ID in error message template.\n    message = goog.string.subs(\n        fireauth.InvalidOriginError.CHROME_EXTENSION_MESSAGE_TEMPLATE_,\n        domain);\n  } else if (scheme == 'http' || scheme == 'https') {\n    // Replace domain in error message template.\n    message = goog.string.subs(\n        fireauth.InvalidOriginError.HTTP_MESSAGE_TEMPLATE_,\n        domain);\n  } else {\n    // Throw operation not supported when non http, https or Chrome extension\n    // protocol.\n    code = fireauth.authenum.Error.OPERATION_NOT_SUPPORTED;\n  }\n  fireauth.InvalidOriginError.base(this, 'constructor', code, message);\n};\ngoog.inherits(fireauth.InvalidOriginError, fireauth.AuthError);\n\n\n/** @private @const {string} The http invalid origin message template. */\nfireauth.InvalidOriginError.HTTP_MESSAGE_TEMPLATE_ = 'This domain (%s) is no' +\n    't authorized to run this operation. Add it to the OAuth redirect domain' +\n    's list in the Firebase console -> Auth section -> Sign in method tab.';\n\n\n/**\n * @private @const {string} The Chrome extension invalid origin message\n *     template.\n */\nfireauth.InvalidOriginError.CHROME_EXTENSION_MESSAGE_TEMPLATE_ = 'This chrom' +\n    'e extension ID (chrome-extension://%s) is not authorized to run this op' +\n    'eration. Add it to the OAuth redirect domains list in the Firebase cons' +\n    'ole -> Auth section -> Sign in method tab.';\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the Auth errors that include emails and an Auth\n * credential, a subclass of fireauth.AuthError.\n */\n\n\ngoog.provide('fireauth.AuthErrorWithCredential');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.object');\ngoog.require('goog.object');\n\n\n/**\n * Error with email and credential that can be returned to the developer.\n * @param {fireauth.authenum.Error} code The error code.\n * @param {?fireauth.AuthErrorWithCredential.CredentialInfo=} opt_credentialInfo\n *     Additional credential information to associate with the error.\n * @param {string=} opt_message The human-readable message.\n * @constructor\n * @extends {fireauth.AuthError}\n */\nfireauth.AuthErrorWithCredential =\n    function(code, opt_credentialInfo, opt_message) {\n  fireauth.AuthErrorWithCredential.base(\n      this, 'constructor', code, opt_message);\n  var credentialInfo = opt_credentialInfo || {};\n\n  // These properties are public.\n  if (credentialInfo.email) {\n    fireauth.object.setReadonlyProperty(this, 'email', credentialInfo.email);\n  }\n  if (credentialInfo.phoneNumber) {\n    fireauth.object.setReadonlyProperty(this, 'phoneNumber',\n        credentialInfo.phoneNumber);\n  }\n  if (credentialInfo.credential) {\n    fireauth.object.setReadonlyProperty(this, 'credential',\n        credentialInfo.credential);\n  }\n  if (credentialInfo.tenantId) {\n    fireauth.object.setReadonlyProperty(this, 'tenantId',\n        credentialInfo.tenantId);\n  }\n};\ngoog.inherits(fireauth.AuthErrorWithCredential, fireauth.AuthError);\n\n\n/**\n * Additional credential information to associate with an error, so that the\n * user does not have to execute the Auth flow again on linking errors.\n * @typedef {{\n *   email: (?string|undefined),\n *   phoneNumber: (?string|undefined),\n *   credential: (?fireauth.AuthCredential|undefined),\n *   tenantId: (?string|undefined),\n * }}\n */\nfireauth.AuthErrorWithCredential.CredentialInfo;\n\n\n/**\n * @return {!Object} The plain object form of the error.\n * @override\n */\nfireauth.AuthErrorWithCredential.prototype.toPlainObject = function() {\n  var obj = {\n    'code': this['code'],\n    'message': this.message\n  };\n  if (this['email']) {\n    obj['email'] = this['email'];\n  }\n  if (this['phoneNumber']) {\n    obj['phoneNumber'] = this['phoneNumber'];\n  }\n  if (this['tenantId']) {\n    obj['tenantId'] = this['tenantId'];\n  }\n\n  var credential = this['credential'] && this['credential'].toPlainObject();\n  if (credential){\n    goog.object.extend(obj, credential);\n  }\n  return obj;\n};\n\n\n/**\n * @return {!Object} The plain object form of the error. This is used by\n *     JSON.toStringify() to return the stringified representation of the error;\n * @override\n */\nfireauth.AuthErrorWithCredential.prototype.toJSON = function() {\n  // Return the plain object representation in case JSON.stringify is called on\n  // an Auth error instance.\n  return this.toPlainObject();\n};\n\n\n/**\n * @param {?Object|undefined} response The object response to convert to a\n *     fireauth.AuthErrorWithCredential.\n * @return {?fireauth.AuthError} The error representation of the response.\n */\nfireauth.AuthErrorWithCredential.fromPlainObject = function(response) {\n  // Code included.\n  if (response['code']) {\n    var code = response['code'] || '';\n    // Remove prefix from name if available.\n    if (code.indexOf(fireauth.AuthError.ERROR_CODE_PREFIX) == 0) {\n      code = code.substring(fireauth.AuthError.ERROR_CODE_PREFIX.length);\n    }\n\n    // Credentials and tenant ID in response.\n    var credentialInfo = {\n      credential: fireauth.AuthProvider.getCredentialFromResponse(response),\n      tenantId: response['tenantId']\n    };\n    if (response['email']) {\n      credentialInfo.email = response['email'];\n    } else if (response['phoneNumber']) {\n      credentialInfo.phoneNumber = response['phoneNumber'];\n    } else if (!credentialInfo.credential) {\n      // Neither email, phone number or credentials are set; return a generic\n      // error.\n      return new fireauth.AuthError(code, response['message'] || undefined);\n    }\n\n    return new fireauth.AuthErrorWithCredential(code, credentialInfo,\n        response['message']);\n  }\n  // No error or invalid response.\n  return null;\n};\n","// Copyright 2006 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF 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 Low level handling of XMLHttpRequest.\n */\n\ngoog.provide('goog.net.DefaultXmlHttpFactory');\ngoog.provide('goog.net.XmlHttp');\ngoog.provide('goog.net.XmlHttp.OptionType');\ngoog.provide('goog.net.XmlHttp.ReadyState');\ngoog.provide('goog.net.XmlHttpDefines');\n\ngoog.require('goog.asserts');\ngoog.require('goog.net.WrapperXmlHttpFactory');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n/**\n * Static class for creating XMLHttpRequest objects.\n * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object.\n */\ngoog.net.XmlHttp = function() {\n  return goog.net.XmlHttp.factory_.createInstance();\n};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n *     true bypasses the ActiveX probing code.\n * NOTE(ruilopes): Due to the way JSCompiler works, this define *will not* strip\n * out the ActiveX probing code from binaries.  To achieve this, use\n * `goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR` instead.\n * TODO(ruilopes): Collapse both defines.\n */\ngoog.net.XmlHttp.ASSUME_NATIVE_XHR =\n    goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);\n\n\n/** @const */\ngoog.net.XmlHttpDefines = {};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n *     true eliminates the ActiveX probing code.\n */\ngoog.net.XmlHttpDefines.ASSUME_NATIVE_XHR =\n    goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false);\n\n\n/**\n * Gets the options to use with the XMLHttpRequest objects obtained using\n * the static methods.\n * @return {Object} The options.\n */\ngoog.net.XmlHttp.getOptions = function() {\n  return goog.net.XmlHttp.factory_.getOptions();\n};\n\n\n/**\n * Type of options that an XmlHttp object can have.\n * @enum {number}\n */\ngoog.net.XmlHttp.OptionType = {\n  /**\n   * Whether a goog.nullFunction should be used to clear the onreadystatechange\n   * handler instead of null.\n   */\n  USE_NULL_FUNCTION: 0,\n\n  /**\n   * NOTE(user): In IE if send() errors on a *local* request the readystate\n   * is still changed to COMPLETE.  We need to ignore it and allow the\n   * try/catch around send() to pick up the error.\n   */\n  LOCAL_REQUEST_ERROR: 1,\n};\n\n\n/**\n * Status constants for XMLHTTP, matches:\n * https://msdn.microsoft.com/en-us/library/ms534361(v=vs.85).aspx\n * @enum {number}\n */\ngoog.net.XmlHttp.ReadyState = {\n  /**\n   * Constant for when xmlhttprequest.readyState is uninitialized\n   */\n  UNINITIALIZED: 0,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is loading.\n   */\n  LOADING: 1,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is loaded.\n   */\n  LOADED: 2,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is in an interactive state.\n   */\n  INTERACTIVE: 3,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is completed\n   */\n  COMPLETE: 4,\n};\n\n\n/**\n * The global factory instance for creating XMLHttpRequest objects.\n * @type {goog.net.XmlHttpFactory}\n * @private\n */\ngoog.net.XmlHttp.factory_;\n\n\n/**\n * Sets the factories for creating XMLHttpRequest objects and their options.\n * @param {Function} factory The factory for XMLHttpRequest objects.\n * @param {Function} optionsFactory The factory for options.\n * @deprecated Use setGlobalFactory instead.\n */\ngoog.net.XmlHttp.setFactory = function(factory, optionsFactory) {\n  goog.net.XmlHttp.setGlobalFactory(\n      new goog.net.WrapperXmlHttpFactory(\n          goog.asserts.assert(factory), goog.asserts.assert(optionsFactory)));\n};\n\n\n/**\n * Sets the global factory object.\n * @param {!goog.net.XmlHttpFactory} factory New global factory object.\n */\ngoog.net.XmlHttp.setGlobalFactory = function(factory) {\n  goog.net.XmlHttp.factory_ = factory;\n};\n\n\n\n/**\n * Default factory to use when creating xhr objects.  You probably shouldn't be\n * instantiating this directly, but rather using it via goog.net.XmlHttp.\n * @extends {goog.net.XmlHttpFactory}\n * @constructor\n */\ngoog.net.DefaultXmlHttpFactory = function() {\n  goog.net.XmlHttpFactory.call(this);\n};\ngoog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {\n  var progId = this.getProgId_();\n  if (progId) {\n    return new ActiveXObject(progId);\n  } else {\n    return new XMLHttpRequest();\n  }\n};\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {\n  var progId = this.getProgId_();\n  var options = {};\n  if (progId) {\n    options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;\n    options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;\n  }\n  return options;\n};\n\n\n/**\n * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.\n * @type {string|undefined}\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.ieProgId_;\n\n\n/**\n * Initialize the private state used by other functions.\n * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {\n  if (goog.net.XmlHttp.ASSUME_NATIVE_XHR ||\n      goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) {\n    return '';\n  }\n\n  // The following blog post describes what PROG IDs to use to create the\n  // XMLHTTP object in Internet Explorer:\n  // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx\n  // However we do not (yet) fully trust that this will be OK for old versions\n  // of IE on Win9x so we therefore keep the last 2.\n  if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&\n      typeof ActiveXObject != 'undefined') {\n    // Candidate Active X types.\n    var ACTIVE_X_IDENTS = [\n      'MSXML2.XMLHTTP.6.0',\n      'MSXML2.XMLHTTP.3.0',\n      'MSXML2.XMLHTTP',\n      'Microsoft.XMLHTTP',\n    ];\n    for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {\n      var candidate = ACTIVE_X_IDENTS[i];\n\n      try {\n        new ActiveXObject(candidate);\n        // NOTE(user): cannot assign progid and return candidate in one line\n        // because JSCompiler complaings: BUG 658126\n        this.ieProgId_ = candidate;\n        return candidate;\n      } catch (e) {\n        // do nothing; try next choice\n      }\n    }\n\n    // couldn't find any matches\n    throw new Error(\n        'Could not create ActiveXObject. ActiveX might be disabled,' +\n        ' or MSXML might not be installed');\n  }\n\n  return /** @type {string} */ (this.ieProgId_);\n};\n\n\n// Set the global factory to an instance of the default factory.\ngoog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());\n","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF 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 This file contain classes that add support for cross-domain XHR\n * requests (see http://www.w3.org/TR/cors/). Most modern browsers are able to\n * use a regular XMLHttpRequest for that, but IE 8 use XDomainRequest object\n * instead. This file provides an adapter from this object to a goog.net.XhrLike\n * and a factory to allow using this with a goog.net.XhrIo instance.\n *\n * IE 7 and older versions are not supported (given that they do not support\n * CORS requests).\n */\ngoog.provide('goog.net.CorsXmlHttpFactory');\ngoog.provide('goog.net.IeCorsXhrAdapter');\n\ngoog.require('goog.net.HttpStatus');\ngoog.require('goog.net.XhrLike');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * A factory of XML http request objects that supports cross domain requests.\n * This class should be instantiated and passed as the parameter of a\n * goog.net.XhrIo constructor to allow cross-domain requests in every browser.\n *\n * @extends {goog.net.XmlHttpFactory}\n * @constructor\n * @final\n */\ngoog.net.CorsXmlHttpFactory = function() {\n  goog.net.XmlHttpFactory.call(this);\n};\ngoog.inherits(goog.net.CorsXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.CorsXmlHttpFactory.prototype.createInstance = function() {\n  var xhr = new XMLHttpRequest();\n  if (('withCredentials' in xhr)) {\n    return xhr;\n  } else if (typeof XDomainRequest != 'undefined') {\n    return new goog.net.IeCorsXhrAdapter();\n  } else {\n    throw new Error('Unsupported browser');\n  }\n};\n\n\n/** @override */\ngoog.net.CorsXmlHttpFactory.prototype.internalGetOptions = function() {\n  return {};\n};\n\n\n\n/**\n * An adapter around Internet Explorer's XDomainRequest object that makes it\n * look like a standard XMLHttpRequest. This can be used instead of\n * XMLHttpRequest to support CORS.\n *\n * @implements {goog.net.XhrLike}\n * @constructor\n * @struct\n * @final\n */\ngoog.net.IeCorsXhrAdapter = function() {\n  /**\n   * The underlying XDomainRequest used to make the HTTP request.\n   * @type {!XDomainRequest}\n   * @private\n   */\n  this.xdr_ = new XDomainRequest();\n\n  /**\n   * The simulated ready state.\n   * @type {number}\n   */\n  this.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;\n\n  /**\n   * The simulated ready state change callback function.\n   * @type {?function()|undefined}\n   */\n  this.onreadystatechange = null;\n\n  /** @override */\n  this.response = '';\n\n  /**\n   * The simulated response text parameter.\n   * @type {string}\n   */\n  this.responseText = '';\n\n  /**\n   * This implementation only supports text response.\n   * @type {string}\n   * @override\n   */\n  this.responseType = '';\n\n  /**\n   * The simulated status code\n   * @type {number}\n   */\n  this.status = -1;\n\n  /** @override */\n  this.responseXML = null;\n\n  /** @override */\n  this.statusText = '';\n\n  this.xdr_.onload = goog.bind(this.handleLoad_, this);\n  this.xdr_.onerror = goog.bind(this.handleError_, this);\n  this.xdr_.onprogress = goog.bind(this.handleProgress_, this);\n  this.xdr_.ontimeout = goog.bind(this.handleTimeout_, this);\n};\n\n\n/**\n * Opens a connection to the provided URL.\n * @param {string} method The HTTP method to use. Valid methods include GET and\n *     POST.\n * @param {string} url The URL to contact. The authority of this URL must match\n *     the authority of the current page's URL (e.g. http or https).\n * @param {?boolean=} opt_async Whether the request is asynchronous, defaulting\n *     to true. XDomainRequest does not support syncronous requests, so setting\n *     it to false will actually raise an exception.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.open = function(method, url, opt_async) {\n  if (opt_async != null && (!opt_async)) {\n    throw new Error('Only async requests are supported.');\n  }\n  this.xdr_.open(method, url);\n};\n\n\n/**\n * Sends the request to the remote server. Before calling this function, always\n * call {@link open}.\n * @param {(ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string)=}\n *     opt_content The content to send as POSTDATA, if any. Only string data is\n *     supported by this implementation.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.send = function(opt_content) {\n  if (opt_content) {\n    if (typeof opt_content == 'string') {\n      this.xdr_.send(opt_content);\n    } else {\n      throw new Error('Only string data is supported');\n    }\n  } else {\n    this.xdr_.send();\n  }\n};\n\n\n/**\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.abort = function() {\n  this.xdr_.abort();\n};\n\n\n/**\n * Sets a request header to send to the remote server. Because this\n * implementation does not support request headers, this function does nothing.\n * @param {string} key The name of the HTTP header to set. Ignored.\n * @param {string} value The value to set for the HTTP header. Ignored.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.setRequestHeader = function(key, value) {\n  // Unsupported; ignore the header.\n};\n\n\n/**\n * Returns the value of the response header identified by key. This\n * implementation only supports the 'content-type' header.\n * @param {string} key The request header to fetch. If this parameter is set to\n *     'content-type' (case-insensitive), this function returns the value of\n *     the 'content-type' request header. If this parameter is set to any other\n *     value, this function always returns an empty string.\n * @return {string} The value of the response header, or an empty string if key\n *     is not 'content-type' (case-insensitive).\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.getResponseHeader = function(key) {\n  if (key.toLowerCase() == 'content-type') {\n    return this.xdr_.contentType;\n  }\n  return '';\n};\n\n\n/**\n * Handles a request that has fully loaded successfully.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleLoad_ = function() {\n  // IE only calls onload if the status is 200, so the status code must be OK.\n  this.status = goog.net.HttpStatus.OK;\n  this.response = this.responseText = this.xdr_.responseText;\n  this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);\n};\n\n\n/**\n * Handles a request that has failed to load.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleError_ = function() {\n  // IE doesn't tell us what the status code actually is (other than the fact\n  // that it is not 200), so simulate an INTERNAL_SERVER_ERROR.\n  this.status = goog.net.HttpStatus.INTERNAL_SERVER_ERROR;\n  this.response = this.responseText = '';\n  this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);\n};\n\n\n/**\n * Handles a request that timed out.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleTimeout_ = function() {\n  this.handleError_();\n};\n\n\n/**\n * Handles a request that is in the process of loading.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleProgress_ = function() {\n  // IE only calls onprogress if the status is 200, so the status code must be\n  // OK.\n  this.status = goog.net.HttpStatus.OK;\n  this.setReadyState_(goog.net.XmlHttp.ReadyState.LOADING);\n};\n\n\n/**\n * Sets this XHR's ready state and fires the onreadystatechange listener (if one\n * is set).\n * @param {number} readyState The new ready state.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.setReadyState_ = function(readyState) {\n  this.readyState = readyState;\n  if (this.onreadystatechange) {\n    this.onreadystatechange();\n  }\n};\n\n\n/**\n * Returns the response headers from the server. This implemntation only returns\n * the 'content-type' header.\n * @return {string} The headers returned from the server.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.getAllResponseHeaders = function() {\n  return 'content-type: ' + this.xdr_.contentType;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the Logger class. Please minimize dependencies\n * this file has on other closure classes as any dependency it takes won't be\n * able to use the logging infrastructure.\n *\n * @see ../demos/debug.html\n */\n\ngoog.provide('goog.debug.LogManager');\ngoog.provide('goog.debug.Loggable');\ngoog.provide('goog.debug.Logger');\ngoog.provide('goog.debug.Logger.Level');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug');\ngoog.require('goog.debug.LogBuffer');\ngoog.require('goog.debug.LogRecord');\n\n\n/**\n * A message value that can be handled by a Logger.\n *\n * Functions are treated like callbacks, but are only called when the event's\n * log level is enabled. This is useful for logging messages that are expensive\n * to construct.\n *\n * @typedef {string|function(): string}\n */\ngoog.debug.Loggable;\n\n\n\n/**\n * The Logger is an object used for logging debug messages. Loggers are\n * normally named, using a hierarchical dot-separated namespace. Logger names\n * can be arbitrary strings, but they should normally be based on the package\n * name or class name of the logged component, such as goog.net.BrowserChannel.\n *\n * The Logger object is loosely based on the java class\n * java.util.logging.Logger. It supports different levels of filtering for\n * different loggers.\n *\n * The logger object should never be instantiated by application code. It\n * should always use the goog.debug.Logger.getLogger function.\n *\n * @constructor\n * @param {string} name The name of the Logger.\n * @final\n */\ngoog.debug.Logger = function(name) {\n  /**\n   * Name of the Logger. Generally a dot-separated namespace\n   * @private {string}\n   */\n  this.name_ = name;\n\n  /**\n   * Parent Logger.\n   * @private {?goog.debug.Logger}\n   */\n  this.parent_ = null;\n\n  /**\n   * Level that this logger only filters above. Null indicates it should\n   * inherit from the parent.\n   * @private {?goog.debug.Logger.Level}\n   */\n  this.level_ = null;\n\n  /**\n   * Map of children loggers. The keys are the leaf names of the children and\n   * the values are the child loggers.\n   * @private {?Object}\n   */\n  this.children_ = null;\n\n  /**\n   * Handlers that are listening to this logger.\n   * @private {?Array<?Function>}\n   */\n  this.handlers_ = null;\n};\n\n\n/** @const */\ngoog.debug.Logger.ROOT_LOGGER_NAME = '';\n\n\n/**\n * @define {boolean} Toggles whether loggers other than the root logger can have\n *     log handlers attached to them and whether they can have their log level\n *     set. Logging is a bit faster when this is set to false.\n */\ngoog.debug.Logger.ENABLE_HIERARCHY =\n    goog.define('goog.debug.Logger.ENABLE_HIERARCHY', true);\n\n\n/**\n * @define {boolean} Toggles whether active log statements are also recorded\n *     to the profiler.\n */\ngoog.debug.Logger.ENABLE_PROFILER_LOGGING =\n    goog.define('goog.debug.Logger.ENABLE_PROFILER_LOGGING', false);\n\n\nif (!goog.debug.Logger.ENABLE_HIERARCHY) {\n  /**\n   * @type {!Array<Function>}\n   * @private\n   */\n  goog.debug.Logger.rootHandlers_ = [];\n\n\n  /**\n   * @type {goog.debug.Logger.Level}\n   * @private\n   */\n  goog.debug.Logger.rootLevel_;\n}\n\n\n\n/**\n * The Level class defines a set of standard logging levels that\n * can be used to control logging output.  The logging Level objects\n * are ordered and are specified by ordered integers.  Enabling logging\n * at a given level also enables logging at all higher levels.\n * <p>\n * Clients should normally use the predefined Level constants such\n * as Level.SEVERE.\n * <p>\n * The levels in descending order are:\n * <ul>\n * <li>SEVERE (highest value)\n * <li>WARNING\n * <li>INFO\n * <li>CONFIG\n * <li>FINE\n * <li>FINER\n * <li>FINEST  (lowest value)\n * </ul>\n * In addition there is a level OFF that can be used to turn\n * off logging, and a level ALL that can be used to enable\n * logging of all messages.\n *\n * @param {string} name The name of the level.\n * @param {number} value The numeric value of the level.\n * @constructor\n * @final\n */\ngoog.debug.Logger.Level = function(name, value) {\n  /**\n   * The name of the level\n   * @type {string}\n   */\n  this.name = name;\n\n  /**\n   * The numeric value of the level\n   * @type {number}\n   */\n  this.value = value;\n};\n\n\n/**\n * @return {string} String representation of the logger level.\n * @override\n */\ngoog.debug.Logger.Level.prototype.toString = function() {\n  return this.name;\n};\n\n\n/**\n * OFF is a special level that can be used to turn off logging.\n * This level is initialized to <CODE>Infinity</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.OFF = new goog.debug.Logger.Level('OFF', Infinity);\n\n\n/**\n * SHOUT is a message level for extra debugging loudness.\n * This level is initialized to <CODE>1200</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200);\n\n\n/**\n * SEVERE is a message level indicating a serious failure.\n * This level is initialized to <CODE>1000</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000);\n\n\n/**\n * WARNING is a message level indicating a potential problem.\n * This level is initialized to <CODE>900</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900);\n\n\n/**\n * INFO is a message level for informational messages.\n * This level is initialized to <CODE>800</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800);\n\n\n/**\n * CONFIG is a message level for static configuration messages.\n * This level is initialized to <CODE>700</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700);\n\n\n/**\n * FINE is a message level providing tracing information.\n * This level is initialized to <CODE>500</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500);\n\n\n/**\n * FINER indicates a fairly detailed tracing message.\n * This level is initialized to <CODE>400</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400);\n\n/**\n * FINEST indicates a highly detailed tracing message.\n * This level is initialized to <CODE>300</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\n\ngoog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300);\n\n\n/**\n * ALL indicates that all messages should be logged.\n * This level is initialized to <CODE>0</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0);\n\n\n/**\n * The predefined levels.\n * @type {!Array<!goog.debug.Logger.Level>}\n * @final\n */\ngoog.debug.Logger.Level.PREDEFINED_LEVELS = [\n  goog.debug.Logger.Level.OFF, goog.debug.Logger.Level.SHOUT,\n  goog.debug.Logger.Level.SEVERE, goog.debug.Logger.Level.WARNING,\n  goog.debug.Logger.Level.INFO, goog.debug.Logger.Level.CONFIG,\n  goog.debug.Logger.Level.FINE, goog.debug.Logger.Level.FINER,\n  goog.debug.Logger.Level.FINEST, goog.debug.Logger.Level.ALL\n];\n\n\n/**\n * A lookup map used to find the level object based on the name or value of\n * the level object.\n * @type {?Object}\n * @private\n */\ngoog.debug.Logger.Level.predefinedLevelsCache_ = null;\n\n\n/**\n * Creates the predefined levels cache and populates it.\n * @private\n */\ngoog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {\n  goog.debug.Logger.Level.predefinedLevelsCache_ = {};\n  for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];\n       i++) {\n    goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;\n    goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;\n  }\n};\n\n\n/**\n * Gets the predefined level with the given name.\n * @param {string} name The name of the level.\n * @return {goog.debug.Logger.Level} The level, or null if none found.\n */\ngoog.debug.Logger.Level.getPredefinedLevel = function(name) {\n  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {\n    goog.debug.Logger.Level.createPredefinedLevelsCache_();\n  }\n\n  return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;\n};\n\n\n/**\n * Gets the highest predefined level <= #value.\n * @param {number} value Level value.\n * @return {goog.debug.Logger.Level} The level, or null if none found.\n */\ngoog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {\n  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {\n    goog.debug.Logger.Level.createPredefinedLevelsCache_();\n  }\n\n  if (value in /** @type {!Object} */ (\n          goog.debug.Logger.Level.predefinedLevelsCache_)) {\n    return goog.debug.Logger.Level.predefinedLevelsCache_[value];\n  }\n\n  for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {\n    var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];\n    if (level.value <= value) {\n      return level;\n    }\n  }\n  return null;\n};\n\n\n/**\n * Finds or creates a logger for a named subsystem. If a logger has already been\n * created with the given name it is returned. Otherwise a new logger is\n * created. If a new logger is created its log level will be configured based\n * on the LogManager configuration and it will configured to also send logging\n * output to its parent's handlers. It will be registered in the LogManager\n * global namespace.\n *\n * @param {string} name A name for the logger. This should be a dot-separated\n * name and should normally be based on the package name or class name of the\n * subsystem, such as goog.net.BrowserChannel.\n * @return {!goog.debug.Logger} The named logger.\n * @deprecated use {@link goog.log} instead.\n */\ngoog.debug.Logger.getLogger = function(name) {\n  return goog.debug.LogManager.getLogger(name);\n};\n\n\n/**\n * Logs a message to profiling tools, if available.\n * {@see https://developers.google.com/web-toolkit/speedtracer/logging-api}\n * {@see http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx}\n * @param {string} msg The message to log.\n */\ngoog.debug.Logger.logToProfilers = function(msg) {\n  // Some browsers also log timeStamp calls to the console, only log\n  // if actually asked.\n  if (goog.debug.Logger.ENABLE_PROFILER_LOGGING) {\n    var msWriteProfilerMark = goog.global['msWriteProfilerMark'];\n    if (msWriteProfilerMark) {\n      // Logs a message to the Microsoft profiler\n      // On IE, console['timeStamp'] may output to console\n      msWriteProfilerMark(msg);\n      return;\n    }\n\n    // Using goog.global, as loggers might be used in window-less contexts.\n    var console = goog.global['console'];\n    if (console && console['timeStamp']) {\n      // Logs a message to Firebug, Web Inspector, SpeedTracer, etc.\n      console['timeStamp'](msg);\n    }\n  }\n};\n\n\n/**\n * Gets the name of this logger.\n * @return {string} The name of this logger.\n */\ngoog.debug.Logger.prototype.getName = function() {\n  return this.name_;\n};\n\n\n/**\n * Adds a handler to the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {Function} handler Handler function to add.\n */\ngoog.debug.Logger.prototype.addHandler = function(handler) {\n  if (goog.debug.LOGGING_ENABLED) {\n    if (goog.debug.Logger.ENABLE_HIERARCHY) {\n      if (!this.handlers_) {\n        this.handlers_ = [];\n      }\n      this.handlers_.push(handler);\n    } else {\n      goog.asserts.assert(\n          !this.name_, 'Cannot call addHandler on a non-root logger when ' +\n              'goog.debug.Logger.ENABLE_HIERARCHY is false.');\n      goog.debug.Logger.rootHandlers_.push(handler);\n    }\n  }\n};\n\n\n/**\n * Removes a handler from the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {Function} handler Handler function to remove.\n * @return {boolean} Whether the handler was removed.\n */\ngoog.debug.Logger.prototype.removeHandler = function(handler) {\n  if (goog.debug.LOGGING_ENABLED) {\n    var handlers = goog.debug.Logger.ENABLE_HIERARCHY ?\n        this.handlers_ :\n        goog.debug.Logger.rootHandlers_;\n    return !!handlers && goog.array.remove(handlers, handler);\n  } else {\n    return false;\n  }\n};\n\n\n/**\n * Returns the parent of this logger.\n * @return {goog.debug.Logger} The parent logger or null if this is the root.\n */\ngoog.debug.Logger.prototype.getParent = function() {\n  return this.parent_;\n};\n\n\n/**\n * Returns the children of this logger as a map of the child name to the logger.\n * @return {!Object} The map where the keys are the child leaf names and the\n *     values are the Logger objects.\n */\ngoog.debug.Logger.prototype.getChildren = function() {\n  if (!this.children_) {\n    this.children_ = {};\n  }\n  return this.children_;\n};\n\n\n/**\n * Set the log level specifying which message levels will be logged by this\n * logger. Message levels lower than this value will be discarded.\n * The level value Level.OFF can be used to turn off logging. If the new level\n * is null, it means that this node should inherit its level from its nearest\n * ancestor with a specific (non-null) level value.\n *\n * @param {goog.debug.Logger.Level} level The new level.\n */\ngoog.debug.Logger.prototype.setLevel = function(level) {\n  if (goog.debug.LOGGING_ENABLED) {\n    if (goog.debug.Logger.ENABLE_HIERARCHY) {\n      this.level_ = level;\n    } else {\n      goog.asserts.assert(\n          !this.name_, 'Cannot call setLevel() on a non-root logger when ' +\n              'goog.debug.Logger.ENABLE_HIERARCHY is false.');\n      goog.debug.Logger.rootLevel_ = level;\n    }\n  }\n};\n\n\n/**\n * Gets the log level specifying which message levels will be logged by this\n * logger. Message levels lower than this value will be discarded.\n * The level value Level.OFF can be used to turn off logging. If the level\n * is null, it means that this node should inherit its level from its nearest\n * ancestor with a specific (non-null) level value.\n *\n * @return {goog.debug.Logger.Level} The level.\n */\ngoog.debug.Logger.prototype.getLevel = function() {\n  return goog.debug.LOGGING_ENABLED ? this.level_ : goog.debug.Logger.Level.OFF;\n};\n\n\n/**\n * Returns the effective level of the logger based on its ancestors' levels.\n * @return {goog.debug.Logger.Level} The level.\n */\ngoog.debug.Logger.prototype.getEffectiveLevel = function() {\n  if (!goog.debug.LOGGING_ENABLED) {\n    return goog.debug.Logger.Level.OFF;\n  }\n\n  if (!goog.debug.Logger.ENABLE_HIERARCHY) {\n    return goog.debug.Logger.rootLevel_;\n  }\n  if (this.level_) {\n    return this.level_;\n  }\n  if (this.parent_) {\n    return this.parent_.getEffectiveLevel();\n  }\n  goog.asserts.fail('Root logger has no level set.');\n  return null;\n};\n\n\n/**\n * Checks if a message of the given level would actually be logged by this\n * logger. This check is based on the Loggers effective level, which may be\n * inherited from its parent.\n * @param {goog.debug.Logger.Level} level The level to check.\n * @return {boolean} Whether the message would be logged.\n */\ngoog.debug.Logger.prototype.isLoggable = function(level) {\n  return goog.debug.LOGGING_ENABLED &&\n      level.value >= this.getEffectiveLevel().value;\n};\n\n\n/**\n * Logs a message. If the logger is currently enabled for the\n * given message level then the given message is forwarded to all the\n * registered output Handler objects.\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error|Object=} opt_exception An exception associated with the\n *     message.\n */\ngoog.debug.Logger.prototype.log = function(level, msg, opt_exception) {\n  // java caches the effective level, not sure it's necessary here\n  if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) {\n    // Message callbacks can be useful when a log message is expensive to build.\n    if (goog.isFunction(msg)) {\n      msg = msg();\n    }\n\n    this.doLogRecord_(this.getLogRecord(level, msg, opt_exception));\n  }\n};\n\n\n/**\n * Creates a new log record and adds the exception (if present) to it.\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {string} msg The string message.\n * @param {Error|Object=} opt_exception An exception associated with the\n *     message.\n * @return {!goog.debug.LogRecord} A log record.\n * @suppress {es5Strict}\n */\ngoog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception) {\n  if (goog.debug.LogBuffer.isBufferingEnabled()) {\n    var logRecord =\n        goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);\n  } else {\n    logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);\n  }\n  if (opt_exception) {\n    logRecord.setException(opt_exception);\n  }\n  return logRecord;\n};\n\n\n/**\n * Logs a message at the Logger.Level.SHOUT level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.shout = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.SEVERE level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.severe = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.WARNING level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.warning = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.INFO level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.info = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.CONFIG level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.config = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINE level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.fine = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINER level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.finer = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINEST level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.finest = function(msg, opt_exception) {\n  if (goog.debug.LOGGING_ENABLED) {\n    this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);\n  }\n};\n\n\n/**\n * Logs a LogRecord. If the logger is currently enabled for the\n * given message level then the given message is forwarded to all the\n * registered output Handler objects.\n * @param {goog.debug.LogRecord} logRecord A log record to log.\n */\ngoog.debug.Logger.prototype.logRecord = function(logRecord) {\n  if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) {\n    this.doLogRecord_(logRecord);\n  }\n};\n\n\n/**\n * Logs a LogRecord.\n * @param {goog.debug.LogRecord} logRecord A log record to log.\n * @private\n */\ngoog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {\n  if (goog.debug.Logger.ENABLE_PROFILER_LOGGING) {\n    goog.debug.Logger.logToProfilers('log:' + logRecord.getMessage());\n  }\n  if (goog.debug.Logger.ENABLE_HIERARCHY) {\n    var target = this;\n    while (target) {\n      target.callPublish_(logRecord);\n      target = target.getParent();\n    }\n  } else {\n    for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++];) {\n      handler(logRecord);\n    }\n  }\n};\n\n\n/**\n * Calls the handlers for publish.\n * @param {goog.debug.LogRecord} logRecord The log record to publish.\n * @private\n */\ngoog.debug.Logger.prototype.callPublish_ = function(logRecord) {\n  if (this.handlers_) {\n    for (var i = 0, handler; handler = this.handlers_[i]; i++) {\n      handler(logRecord);\n    }\n  }\n};\n\n\n/**\n * Sets the parent of this logger. This is used for setting up the logger tree.\n * @param {goog.debug.Logger} parent The parent logger.\n * @private\n */\ngoog.debug.Logger.prototype.setParent_ = function(parent) {\n  this.parent_ = parent;\n};\n\n\n/**\n * Adds a child to this logger. This is used for setting up the logger tree.\n * @param {string} name The leaf name of the child.\n * @param {goog.debug.Logger} logger The child logger.\n * @private\n */\ngoog.debug.Logger.prototype.addChild_ = function(name, logger) {\n  this.getChildren()[name] = logger;\n};\n\n\n/**\n * There is a single global LogManager object that is used to maintain a set of\n * shared state about Loggers and log services. This is loosely based on the\n * java class java.util.logging.LogManager.\n * @const\n */\ngoog.debug.LogManager = {};\n\n\n/**\n * Map of logger names to logger objects.\n *\n * @type {!Object<string, !goog.debug.Logger>}\n * @private\n */\ngoog.debug.LogManager.loggers_ = {};\n\n\n/**\n * The root logger which is the root of the logger tree.\n * @type {?goog.debug.Logger}\n * @private\n */\ngoog.debug.LogManager.rootLogger_ = null;\n\n\n/**\n * Initializes the LogManager if not already initialized.\n */\ngoog.debug.LogManager.initialize = function() {\n  if (!goog.debug.LogManager.rootLogger_) {\n    goog.debug.LogManager.rootLogger_ =\n        new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME);\n    goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] =\n        goog.debug.LogManager.rootLogger_;\n    goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);\n  }\n};\n\n\n/**\n * Returns all the loggers.\n * @return {!Object<string, !goog.debug.Logger>} Map of logger names to logger\n *     objects.\n */\ngoog.debug.LogManager.getLoggers = function() {\n  return goog.debug.LogManager.loggers_;\n};\n\n\n/**\n * Returns the root of the logger tree namespace, the logger with the empty\n * string as its name.\n *\n * @return {!goog.debug.Logger} The root logger.\n */\ngoog.debug.LogManager.getRoot = function() {\n  goog.debug.LogManager.initialize();\n  return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_);\n};\n\n\n/**\n * Finds a named logger.\n *\n * @param {string} name A name for the logger. This should be a dot-separated\n * name and should normally be based on the package name or class name of the\n * subsystem, such as goog.net.BrowserChannel.\n * @return {!goog.debug.Logger} The named logger.\n */\ngoog.debug.LogManager.getLogger = function(name) {\n  goog.debug.LogManager.initialize();\n  var ret = goog.debug.LogManager.loggers_[name];\n  return ret || goog.debug.LogManager.createLogger_(name);\n};\n\n\n/**\n * Creates a function that can be passed to goog.debug.catchErrors. The function\n * will log all reported errors using the given logger.\n * @param {goog.debug.Logger=} opt_logger The logger to log the errors to.\n *     Defaults to the root logger.\n * @return {function(Object)} The created function.\n */\ngoog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {\n  return function(info) {\n    var logger = opt_logger || goog.debug.LogManager.getRoot();\n    logger.severe(\n        'Error: ' + info.message + ' (' + info.fileName + ' @ Line: ' +\n        info.line + ')');\n  };\n};\n\n\n/**\n * Creates the named logger. Will also create the parents of the named logger\n * if they don't yet exist.\n * @param {string} name The name of the logger.\n * @return {!goog.debug.Logger} The named logger.\n * @private\n */\ngoog.debug.LogManager.createLogger_ = function(name) {\n  // find parent logger\n  var logger = new goog.debug.Logger(name);\n  if (goog.debug.Logger.ENABLE_HIERARCHY) {\n    var lastDotIndex = name.lastIndexOf('.');\n    var parentName = name.substr(0, lastDotIndex);\n    var leafName = name.substr(lastDotIndex + 1);\n    var parentLogger = goog.debug.LogManager.getLogger(parentName);\n\n    // tell the parent about the child and the child about the parent\n    parentLogger.addChild_(leafName, logger);\n    logger.setParent_(parentLogger);\n  }\n\n  goog.debug.LogManager.loggers_[name] = logger;\n  return logger;\n};\n","// Copyright 2015 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\ngoog.provide('goog.net.FetchXmlHttp');\ngoog.provide('goog.net.FetchXmlHttpFactory');\n\ngoog.require('goog.asserts');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.functions');\ngoog.require('goog.log');\ngoog.require('goog.net.XhrLike');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * Factory for creating Xhr objects that uses the native fetch() method.\n * https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\n * Note that this factory is intended for use in Service Worker only.\n * @param {!WorkerGlobalScope} worker The Service Worker global scope.\n * @extends {goog.net.XmlHttpFactory}\n * @struct\n * @constructor\n */\ngoog.net.FetchXmlHttpFactory = function(worker) {\n  goog.net.FetchXmlHttpFactory.base(this, 'constructor');\n\n  /** @private @final {!WorkerGlobalScope} */\n  this.worker_ = worker;\n\n  /** @private {!RequestCredentials|undefined} */\n  this.credentialsMode_ = undefined;\n\n  /** @private {!RequestCache|undefined} */\n  this.cacheMode_ = undefined;\n};\ngoog.inherits(goog.net.FetchXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.FetchXmlHttpFactory.prototype.createInstance = function() {\n  var instance = new goog.net.FetchXmlHttp(this.worker_);\n  if (this.credentialsMode_) {\n    instance.setCredentialsMode(this.credentialsMode_);\n  }\n  if (this.cacheMode_) {\n    instance.setCacheMode(this.cacheMode_);\n  }\n  return instance;\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttpFactory.prototype.internalGetOptions =\n    goog.functions.constant({});\n\n\n/**\n * @param {!RequestCredentials} credentialsMode The credentials mode of the\n *     Service Worker fetch.\n */\ngoog.net.FetchXmlHttpFactory.prototype.setCredentialsMode = function(\n    credentialsMode) {\n  this.credentialsMode_ = credentialsMode;\n};\n\n\n/**\n * @param {!RequestCache} cacheMode The cache mode of the Service Worker fetch.\n */\ngoog.net.FetchXmlHttpFactory.prototype.setCacheMode = function(cacheMode) {\n  this.cacheMode_ = cacheMode;\n};\n\n\n\n/**\n * FetchXmlHttp object constructor.\n * @param {!WorkerGlobalScope} worker\n * @extends {goog.events.EventTarget}\n * @implements {goog.net.XhrLike}\n * @constructor\n * @struct\n */\ngoog.net.FetchXmlHttp = function(worker) {\n  goog.net.FetchXmlHttp.base(this, 'constructor');\n\n  /** @private @final {!WorkerGlobalScope} */\n  this.worker_ = worker;\n\n  /** @private {RequestCredentials|undefined} */\n  this.credentialsMode_ = undefined;\n\n  /** @private {RequestCache|undefined} */\n  this.cacheMode_ = undefined;\n\n  /**\n   * Request state.\n   * @type {goog.net.FetchXmlHttp.RequestState}\n   */\n  this.readyState = goog.net.FetchXmlHttp.RequestState.UNSENT;\n\n  /**\n   * HTTP status.\n   * @type {number}\n   */\n  this.status = 0;\n\n  /**\n   * HTTP status string.\n   * @type {string}\n   */\n  this.statusText = '';\n\n  /**\n   * Content of the response.\n   * @type {string|!ArrayBuffer}\n   */\n  this.response = '';\n\n  /**\n   * Content of the response.\n   * @type {string}\n   */\n  this.responseText = '';\n\n  /**\n   * The type of the response.  If this is set to 'arraybuffer' the request will\n   * be discrete, streaming is only supported for text encoded requests.\n   * @type {string}\n   */\n  this.responseType = '';\n\n  /**\n   * Document response entity body.\n   * NOTE: This is always null and not supported by this class.\n   * @final {null}\n   */\n  this.responseXML = null;\n\n  /**\n   * Method to call when the state changes.\n   * @type {?function()}\n   */\n  this.onreadystatechange = null;\n\n  /** @private {!Headers} */\n  this.requestHeaders_ = new Headers();\n\n  /** @private {?Headers} */\n  this.responseHeaders_ = null;\n\n  /**\n   * Request method (GET or POST).\n   * @private {string}\n   */\n  this.method_ = 'GET';\n\n  /**\n   * Request URL.\n   * @private {string}\n   */\n  this.url_ = '';\n\n  /**\n   * Whether the request is in progress.\n   * @private {boolean}\n   */\n  this.inProgress_ = false;\n\n  /** @private @final {?goog.log.Logger} */\n  this.logger_ = goog.log.getLogger('goog.net.FetchXmlHttp');\n\n  /** @private {?Response} */\n  this.fetchResponse_ = null;\n\n  /** @private {!ReadableStreamDefaultReader|null} */\n  this.currentReader_ = null;\n\n  /** @private {?TextDecoder} */\n  this.textDecoder_ = null;\n};\ngoog.inherits(goog.net.FetchXmlHttp, goog.events.EventTarget);\n\n\n/**\n * State of the requests.\n * @enum {number}\n */\ngoog.net.FetchXmlHttp.RequestState = {\n  UNSENT: 0,\n  OPENED: 1,\n  HEADER_RECEIVED: 2,\n  LOADING: 3,\n  DONE: 4,\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.open = function(method, url, opt_async) {\n  goog.asserts.assert(!!opt_async, 'Only async requests are supported.');\n  if (this.readyState != goog.net.FetchXmlHttp.RequestState.UNSENT) {\n    this.abort();\n    throw new Error('Error reopening a connection');\n  }\n\n  this.method_ = method;\n  this.url_ = url;\n\n  this.readyState = goog.net.FetchXmlHttp.RequestState.OPENED;\n  this.dispatchCallback_();\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.send = function(opt_data) {\n  if (this.readyState != goog.net.FetchXmlHttp.RequestState.OPENED) {\n    this.abort();\n    throw new Error('need to call open() first. ');\n  }\n\n  this.inProgress_ = true;\n  var requestInit = {\n    headers: this.requestHeaders_,\n    method: this.method_,\n    credentials: this.credentialsMode_,\n    cache: this.cacheMode_,\n  };\n  if (opt_data) {\n    requestInit['body'] = opt_data;\n  }\n  this.worker_\n      .fetch(new Request(this.url_, /** @type {!RequestInit} */ (requestInit)))\n      .then(\n          this.handleResponse_.bind(this), this.handleSendFailure_.bind(this));\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.abort = function() {\n  this.response = this.responseText = '';\n  this.requestHeaders_ = new Headers();\n  this.status = 0;\n\n  if (!!this.currentReader_) {\n    this.currentReader_.cancel('Request was aborted.');\n  }\n\n  if (((this.readyState >= goog.net.FetchXmlHttp.RequestState.OPENED) &&\n       this.inProgress_) &&\n      (this.readyState != goog.net.FetchXmlHttp.RequestState.DONE)) {\n    this.inProgress_ = false;\n    this.requestDone_(false);\n  }\n\n  this.readyState = goog.net.FetchXmlHttp.RequestState.UNSENT;\n};\n\n\n/**\n * Handles the fetch response.\n * @param {!Response} response\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponse_ = function(response) {\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n\n  this.fetchResponse_ = response;\n\n  if (!this.responseHeaders_) {\n    this.responseHeaders_ = response.headers;\n    this.readyState = goog.net.FetchXmlHttp.RequestState.HEADER_RECEIVED;\n    this.dispatchCallback_();\n  }\n  // A callback may abort the request.\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n\n  this.readyState = goog.net.FetchXmlHttp.RequestState.LOADING;\n  this.dispatchCallback_();\n  // A callback may abort the request.\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n\n  if (this.responseType === 'arraybuffer') {\n    response.arrayBuffer().then(\n        this.handleResponseArrayBuffer_.bind(this),\n        this.handleSendFailure_.bind(this));\n  } else if (\n      typeof (goog.global.ReadableStream) !== 'undefined' &&\n      'body' in response) {\n    this.response = this.responseText = '';\n    this.currentReader_ =\n        /** @type {!ReadableStreamDefaultReader} */ (response.body.getReader());\n    this.textDecoder_ = new TextDecoder();\n    this.readInputFromFetch_();\n  } else {\n    response.text().then(\n        this.handleResponseText_.bind(this),\n        this.handleSendFailure_.bind(this));\n  }\n};\n\n\n/**\n * Reads the next chunk of data from the fetch response.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.readInputFromFetch_ = function() {\n  this.currentReader_.read()\n      .then(this.handleDataFromStream_.bind(this))\n      .catch(this.handleSendFailure_.bind(this));\n};\n\n\n/**\n * Handles a chunk of data from the fetch response stream reader.\n * @param {!IteratorResult} result\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleDataFromStream_ = function(result) {\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n\n  var dataPacket = result.value ? /** @type {!Uint8Array} */ (result.value) :\n                                  new Uint8Array(0);\n  var newText = this.textDecoder_.decode(dataPacket, {stream: !result.done});\n  if (newText) {\n    this.responseText += newText;\n    this.response = this.responseText;\n  }\n\n  if (result.done) {\n    this.requestDone_(true);\n  } else {\n    this.dispatchCallback_();\n  }\n\n  if (this.readyState == goog.net.FetchXmlHttp.RequestState.LOADING) {\n    this.readInputFromFetch_();\n  }\n};\n\n\n/**\n * Handles the response text.\n * @param {string} responseText\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponseText_ = function(responseText) {\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n  this.response = this.responseText = responseText;\n  this.requestDone_(true);\n};\n\n\n/**\n * Handles the response text.\n * @param {!ArrayBuffer} responseArrayBuffer\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponseArrayBuffer_ = function(\n    responseArrayBuffer) {\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n  this.response = responseArrayBuffer;\n  this.requestDone_(true);\n};\n\n\n/**\n * Handles the send failure.\n * @param {*} error\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleSendFailure_ = function(error) {\n  var e = error instanceof Error ? error : Error(error);\n  goog.log.warning(this.logger_, 'Failed to fetch url ' + this.url_, e);\n  if (!this.inProgress_) {\n    // The request was aborted, ignore.\n    return;\n  }\n  this.requestDone_(true);\n};\n\n\n/**\n * Sets the request state to DONE and performs cleanup.\n * @param {boolean} setStatus whether to set the status and statusText fields,\n * this is not necessary when the request is aborted.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.requestDone_ = function(setStatus) {\n  if (setStatus && this.fetchResponse_) {\n    this.status = this.fetchResponse_.status;\n    this.statusText = this.fetchResponse_.statusText;\n  }\n\n  this.readyState = goog.net.FetchXmlHttp.RequestState.DONE;\n\n  this.fetchResponse_ = null;\n  this.currentReader_ = null;\n  this.textDecoder_ = null;\n\n  this.dispatchCallback_();\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.setRequestHeader = function(header, value) {\n  this.requestHeaders_.append(header, value);\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.getResponseHeader = function(header) {\n  // TODO(user): This method should return null when the headers are not\n  // present or the specified header is missing. The externs need to be fixed.\n  if (!this.responseHeaders_) {\n    goog.log.warning(\n        this.logger_,\n        'Attempting to get response header but no headers have been received ' +\n            'for url: ' + this.url_);\n    return '';\n  }\n  return this.responseHeaders_.get(header.toLowerCase()) || '';\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.getAllResponseHeaders = function() {\n  if (!this.responseHeaders_) {\n    goog.log.warning(\n        this.logger_,\n        'Attempting to get all response headers but no headers have been ' +\n            'received for url: ' + this.url_);\n    return '';\n  }\n  var lines = [];\n  var iter = this.responseHeaders_.entries();\n  var entry = iter.next();\n  while (!entry.done) {\n    var pair = entry.value;\n    lines.push(pair[0] + ': ' + pair[1]);\n    entry = iter.next();\n  }\n  return lines.join('\\r\\n');\n};\n\n\n/**\n * @param {!RequestCredentials} credentialsMode The credentials mode of the\n *     Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.setCredentialsMode = function(credentialsMode) {\n  this.credentialsMode_ = credentialsMode;\n};\n\n\n/**\n * @param {!RequestCache} cacheMode The cache mode of the Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.setCacheMode = function(cacheMode) {\n  this.cacheMode_ = cacheMode;\n};\n\n\n/**\n * Dispatches the callback, if the callback attribute is defined.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.dispatchCallback_ = function() {\n  if (this.onreadystatechange) {\n    this.onreadystatechange.call(this);\n  }\n};\n","// Copyright 2006 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF 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 Wrapper class for handling XmlHttpRequests.\n *\n * One off requests can be sent through goog.net.XhrIo.send() or an\n * instance can be created to send multiple requests.  Each request uses its\n * own XmlHttpRequest object and handles clearing of the event callback to\n * ensure no leaks.\n *\n * XhrIo is event based, it dispatches events on success, failure, finishing,\n * ready-state change, or progress (download and upload).\n *\n * The ready-state or timeout event fires first, followed by\n * a generic completed event. Then the abort, error, or success event\n * is fired as appropriate. Progress events are fired as they are\n * received. Lastly, the ready event will fire to indicate that the\n * object may be used to make another request.\n *\n * The error event may also be called before completed and\n * ready-state-change if the XmlHttpRequest.open() or .send() methods throw.\n *\n * This class does not support multiple requests, queuing, or prioritization.\n *\n * When progress events are supported by the browser, and progress is\n * enabled via .setProgressEventsEnabled(true), the\n * goog.net.EventType.PROGRESS event will be the re-dispatched browser\n * progress event. Additionally, a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event\n * will be fired for download and upload progress respectively.\n */\n\n\ngoog.provide('goog.net.XhrIo');\ngoog.provide('goog.net.XhrIo.ResponseType');\n\ngoog.require('goog.Timer');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.json.hybrid');\ngoog.require('goog.log');\ngoog.require('goog.net.ErrorCode');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.HttpStatus');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.structs.Map');\ngoog.require('goog.uri.utils');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\n\ngoog.scope(function() {\n\n/**\n * Basic class for handling XMLHttpRequests.\n * @param {goog.net.XmlHttpFactory=} opt_xmlHttpFactory Factory to use when\n *     creating XMLHttpRequest objects.\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.net.XhrIo = function(opt_xmlHttpFactory) {\n  XhrIo.base(this, 'constructor');\n\n  /**\n   * Map of default headers to add to every request, use:\n   * XhrIo.headers.set(name, value)\n   * @type {!goog.structs.Map}\n   */\n  this.headers = new goog.structs.Map();\n\n  /**\n   * Optional XmlHttpFactory\n   * @private {goog.net.XmlHttpFactory}\n   */\n  this.xmlHttpFactory_ = opt_xmlHttpFactory || null;\n\n  /**\n   * Whether XMLHttpRequest is active.  A request is active from the time send()\n   * is called until onReadyStateChange() is complete, or error() or abort()\n   * is called.\n   * @private {boolean}\n   */\n  this.active_ = false;\n\n  /**\n   * The XMLHttpRequest object that is being used for the transfer.\n   * @private {?goog.net.XhrLike.OrNative}\n   */\n  this.xhr_ = null;\n\n  /**\n   * The options to use with the current XMLHttpRequest object.\n   * @private {?Object}\n   */\n  this.xhrOptions_ = null;\n\n  /**\n   * Last URL that was requested.\n   * @private {string|goog.Uri}\n   */\n  this.lastUri_ = '';\n\n  /**\n   * Method for the last request.\n   * @private {string}\n   */\n  this.lastMethod_ = '';\n\n  /**\n   * Last error code.\n   * @private {!goog.net.ErrorCode}\n   */\n  this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n\n  /**\n   * Last error message.\n   * @private {Error|string}\n   */\n  this.lastError_ = '';\n\n  /**\n   * Used to ensure that we don't dispatch an multiple ERROR events. This can\n   * happen in IE when it does a synchronous load and one error is handled in\n   * the ready statte change and one is handled due to send() throwing an\n   * exception.\n   * @private {boolean}\n   */\n  this.errorDispatched_ = false;\n\n  /**\n   * Used to make sure we don't fire the complete event from inside a send call.\n   * @private {boolean}\n   */\n  this.inSend_ = false;\n\n  /**\n   * Used in determining if a call to {@link #onReadyStateChange_} is from\n   * within a call to this.xhr_.open.\n   * @private {boolean}\n   */\n  this.inOpen_ = false;\n\n  /**\n   * Used in determining if a call to {@link #onReadyStateChange_} is from\n   * within a call to this.xhr_.abort.\n   * @private {boolean}\n   */\n  this.inAbort_ = false;\n\n  /**\n   * Number of milliseconds after which an incomplete request will be aborted\n   * and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout\n   * is set.\n   * @private {number}\n   */\n  this.timeoutInterval_ = 0;\n\n  /**\n   * Timer to track request timeout.\n   * @private {?number}\n   */\n  this.timeoutId_ = null;\n\n  /**\n   * The requested type for the response. The empty string means use the default\n   * XHR behavior.\n   * @private {goog.net.XhrIo.ResponseType}\n   */\n  this.responseType_ = ResponseType.DEFAULT;\n\n  /**\n   * Whether a \"credentialed\" request is to be sent (one that is aware of\n   * cookies and authentication). This is applicable only for cross-domain\n   * requests and more recent browsers that support this part of the HTTP Access\n   * Control standard.\n   *\n   * @see http://www.w3.org/TR/XMLHttpRequest/#the-withcredentials-attribute\n   *\n   * @private {boolean}\n   */\n  this.withCredentials_ = false;\n\n  /**\n   * Whether progress events are enabled for this request. This is\n   * disabled by default because setting a progress event handler\n   * causes pre-flight OPTIONS requests to be sent for CORS requests,\n   * even in cases where a pre-flight request would not otherwise be\n   * sent.\n   *\n   * @see http://xhr.spec.whatwg.org/#security-considerations\n   *\n   * Note that this can cause problems for Firefox 22 and below, as an\n   * older \"LSProgressEvent\" will be dispatched by the browser. That\n   * progress event is no longer supported, and can lead to failures,\n   * including throwing exceptions.\n   *\n   * @see http://bugzilla.mozilla.org/show_bug.cgi?id=845631\n   * @see b/23469793\n   *\n   * @private {boolean}\n   */\n  this.progressEventsEnabled_ = false;\n\n  /**\n   * True if we can use XMLHttpRequest's timeout directly.\n   * @private {boolean}\n   */\n  this.useXhr2Timeout_ = false;\n};\ngoog.inherits(goog.net.XhrIo, goog.events.EventTarget);\n\nvar XhrIo = goog.net.XhrIo;\n\n/**\n * Response types that may be requested for XMLHttpRequests.\n * @enum {string}\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute\n */\ngoog.net.XhrIo.ResponseType = {\n  DEFAULT: '',\n  TEXT: 'text',\n  DOCUMENT: 'document',\n  // Not supported as of Chrome 10.0.612.1 dev\n  BLOB: 'blob',\n  ARRAY_BUFFER: 'arraybuffer',\n};\n\nvar ResponseType = goog.net.XhrIo.ResponseType;\n\n\n/**\n * A reference to the XhrIo logger\n * @private {?goog.log.Logger}\n * @const\n */\ngoog.net.XhrIo.prototype.logger_ = goog.log.getLogger('goog.net.XhrIo');\n\n\n/**\n * The Content-Type HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TYPE_HEADER = 'Content-Type';\n\n\n/**\n * The Content-Transfer-Encoding HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding';\n\n\n/**\n * The pattern matching the 'http' and 'https' URI schemes\n * @type {!RegExp}\n */\ngoog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i;\n\n\n/**\n * The methods that typically come along with form data.  We set different\n * headers depending on whether the HTTP action is one of these.\n * @type {!Array<string>}\n */\ngoog.net.XhrIo.METHODS_WITH_FORM_DATA = ['POST', 'PUT'];\n\n\n/**\n * The Content-Type HTTP header value for a url-encoded form\n * @type {string}\n */\ngoog.net.XhrIo.FORM_CONTENT_TYPE =\n    'application/x-www-form-urlencoded;charset=utf-8';\n\n\n/**\n * The XMLHttpRequest Level two timeout delay ms property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_TIMEOUT_ = 'timeout';\n\n\n/**\n * The XMLHttpRequest Level two ontimeout handler property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_ON_TIMEOUT_ = 'ontimeout';\n\n\n/**\n * All non-disposed instances of goog.net.XhrIo created\n * by {@link goog.net.XhrIo.send} are in this Array.\n * @see goog.net.XhrIo.cleanup\n * @private {!Array<!goog.net.XhrIo>}\n */\ngoog.net.XhrIo.sendInstances_ = [];\n\n\n/**\n * Static send that creates a short lived instance of XhrIo to send the\n * request.\n * @see goog.net.XhrIo.cleanup\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {?function(this:goog.net.XhrIo, ?)=} opt_callback Callback function\n *     for when request is complete.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n *     opt_content Body data.\n * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the\n *     request.\n * @param {number=} opt_timeoutInterval Number of milliseconds after which an\n *     incomplete request will be aborted; 0 means no timeout is set.\n * @param {boolean=} opt_withCredentials Whether to send credentials with the\n *     request. Default to false. See {@link goog.net.XhrIo#setWithCredentials}.\n * @return {!goog.net.XhrIo} The sent XhrIo.\n */\ngoog.net.XhrIo.send = function(\n    url, opt_callback, opt_method, opt_content, opt_headers,\n    opt_timeoutInterval, opt_withCredentials) {\n  var x = new goog.net.XhrIo();\n  goog.net.XhrIo.sendInstances_.push(x);\n  if (opt_callback) {\n    x.listen(goog.net.EventType.COMPLETE, opt_callback);\n  }\n  x.listenOnce(goog.net.EventType.READY, x.cleanupSend_);\n  if (opt_timeoutInterval) {\n    x.setTimeoutInterval(opt_timeoutInterval);\n  }\n  if (opt_withCredentials) {\n    x.setWithCredentials(opt_withCredentials);\n  }\n  x.send(url, opt_method, opt_content, opt_headers);\n  return x;\n};\n\n\n/**\n * Disposes all non-disposed instances of goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send}.\n * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance\n * it creates when the request completes or fails.  However, if\n * the request never completes, then the goog.net.XhrIo is not disposed.\n * This can occur if the window is unloaded before the request completes.\n * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo\n * it creates and make the client of {@link goog.net.XhrIo.send} be\n * responsible for disposing it in this case.  However, this makes things\n * significantly more complicated for the client, and the whole point\n * of {@link goog.net.XhrIo.send} is that it's simple and easy to use.\n * Clients of {@link goog.net.XhrIo.send} should call\n * {@link goog.net.XhrIo.cleanup} when doing final\n * cleanup on window unload.\n */\ngoog.net.XhrIo.cleanup = function() {\n  var instances = goog.net.XhrIo.sendInstances_;\n  while (instances.length) {\n    instances.pop().dispose();\n  }\n};\n\n\n/**\n * Installs exception protection for all entry point introduced by\n * goog.net.XhrIo instances which are not protected by\n * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},\n * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or\n * {@link goog.events.protectBrowserEventEntryPoint}.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n *     protect the entry point(s).\n */\ngoog.net.XhrIo.protectEntryPoints = function(errorHandler) {\n  goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n      errorHandler.protectEntryPoint(\n          goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n};\n\n\n/**\n * Disposes of the specified goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send} and removes it from\n * {@link goog.net.XhrIo.pendingStaticSendInstances_}.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanupSend_ = function() {\n  this.dispose();\n  goog.array.remove(goog.net.XhrIo.sendInstances_, this);\n};\n\n\n/**\n * Returns the number of milliseconds after which an incomplete request will be\n * aborted, or 0 if no timeout is set.\n * @return {number} Timeout interval in milliseconds.\n */\ngoog.net.XhrIo.prototype.getTimeoutInterval = function() {\n  return this.timeoutInterval_;\n};\n\n\n/**\n * Sets the number of milliseconds after which an incomplete request will be\n * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no\n * timeout is set.\n * @param {number} ms Timeout interval in milliseconds; 0 means none.\n */\ngoog.net.XhrIo.prototype.setTimeoutInterval = function(ms) {\n  this.timeoutInterval_ = Math.max(0, ms);\n};\n\n\n/**\n * Sets the desired type for the response. At time of writing, this is only\n * supported in very recent versions of WebKit (10.0.612.1 dev and later).\n *\n * If this is used, the response may only be accessed via {@link #getResponse}.\n *\n * @param {goog.net.XhrIo.ResponseType} type The desired type for the response.\n */\ngoog.net.XhrIo.prototype.setResponseType = function(type) {\n  this.responseType_ = type;\n};\n\n\n/**\n * Gets the desired type for the response.\n * @return {goog.net.XhrIo.ResponseType} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getResponseType = function() {\n  return this.responseType_;\n};\n\n\n/**\n * Sets whether a \"credentialed\" request that is aware of cookie and\n * authentication information should be made. This option is only supported by\n * browsers that support HTTP Access Control. As of this writing, this option\n * is not supported in IE.\n *\n * @param {boolean} withCredentials Whether this should be a \"credentialed\"\n *     request.\n */\ngoog.net.XhrIo.prototype.setWithCredentials = function(withCredentials) {\n  this.withCredentials_ = withCredentials;\n};\n\n\n/**\n * Gets whether a \"credentialed\" request is to be sent.\n * @return {boolean} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getWithCredentials = function() {\n  return this.withCredentials_;\n};\n\n\n/**\n * Sets whether progress events are enabled for this request. Note\n * that progress events require pre-flight OPTIONS request handling\n * for CORS requests, and may cause trouble with older browsers. See\n * progressEventsEnabled_ for details.\n * @param {boolean} enabled Whether progress events should be enabled.\n */\ngoog.net.XhrIo.prototype.setProgressEventsEnabled = function(enabled) {\n  this.progressEventsEnabled_ = enabled;\n};\n\n\n/**\n * Gets whether progress events are enabled.\n * @return {boolean} Whether progress events are enabled for this request.\n */\ngoog.net.XhrIo.prototype.getProgressEventsEnabled = function() {\n  return this.progressEventsEnabled_;\n};\n\n\n/**\n * Instance send that actually uses XMLHttpRequest to make a server call.\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n *     opt_content Body data.\n * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the\n *     request.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters for opt_headers.\n */\ngoog.net.XhrIo.prototype.send = function(\n    url, opt_method, opt_content, opt_headers) {\n  if (this.xhr_) {\n    throw new Error(\n        '[goog.net.XhrIo] Object is active with another request=' +\n        this.lastUri_ + '; newUri=' + url);\n  }\n\n  var method = opt_method ? opt_method.toUpperCase() : 'GET';\n\n  this.lastUri_ = url;\n  this.lastError_ = '';\n  this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n  this.lastMethod_ = method;\n  this.errorDispatched_ = false;\n  this.active_ = true;\n\n  // Use the factory to create the XHR object and options\n  this.xhr_ = this.createXhr();\n  this.xhrOptions_ = this.xmlHttpFactory_ ? this.xmlHttpFactory_.getOptions() :\n                                            goog.net.XmlHttp.getOptions();\n\n  // Set up the onreadystatechange callback\n  this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this);\n\n  // Set up upload/download progress events, if progress events are supported.\n  if (this.getProgressEventsEnabled() && 'onprogress' in this.xhr_) {\n    this.xhr_.onprogress =\n        goog.bind(function(e) { this.onProgressHandler_(e, true); }, this);\n    if (this.xhr_.upload) {\n      this.xhr_.upload.onprogress = goog.bind(this.onProgressHandler_, this);\n    }\n  }\n\n  /**\n   * Try to open the XMLHttpRequest (always async), if an error occurs here it\n   * is generally permission denied\n   */\n  try {\n    goog.log.fine(this.logger_, this.formatMsg_('Opening Xhr'));\n    this.inOpen_ = true;\n    this.xhr_.open(method, String(url), true);  // Always async!\n    this.inOpen_ = false;\n  } catch (err) {\n    goog.log.fine(\n        this.logger_, this.formatMsg_('Error opening Xhr: ' + err.message));\n    this.error_(goog.net.ErrorCode.EXCEPTION, err);\n    return;\n  }\n\n  // We can't use null since this won't allow requests with form data to have a\n  // content length specified which will cause some proxies to return a 411\n  // error.\n  var content = opt_content || '';\n\n  var headers = this.headers.clone();\n\n  // Add headers specific to this request\n  if (opt_headers) {\n    goog.structs.forEach(\n        opt_headers, function(value, key) { headers.set(key, value); });\n  }\n\n  // Find whether a content type header is set, ignoring case.\n  // HTTP header names are case-insensitive.  See:\n  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2\n  var contentTypeKey =\n      goog.array.find(headers.getKeys(), goog.net.XhrIo.isContentTypeHeader_);\n\n  var contentIsFormData =\n      (goog.global['FormData'] && (content instanceof goog.global['FormData']));\n  if (goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) &&\n      !contentTypeKey && !contentIsFormData) {\n    // For requests typically with form data, default to the url-encoded form\n    // content type unless this is a FormData request.  For FormData,\n    // the browser will automatically add a multipart/form-data content type\n    // with an appropriate multipart boundary.\n    headers.set(\n        goog.net.XhrIo.CONTENT_TYPE_HEADER, goog.net.XhrIo.FORM_CONTENT_TYPE);\n  }\n\n  // Add the headers to the Xhr object\n  headers.forEach(function(value, key) {\n    this.xhr_.setRequestHeader(key, value);\n  }, this);\n\n  if (this.responseType_) {\n    this.xhr_.responseType = this.responseType_;\n  }\n  // Set xhr_.withCredentials only when the value is different, or else in\n  // synchronous XMLHtppRequest.open Firefox will throw an exception.\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=736340\n  if ('withCredentials' in this.xhr_ &&\n      this.xhr_.withCredentials !== this.withCredentials_) {\n    this.xhr_.withCredentials = this.withCredentials_;\n  }\n\n  /**\n   * Try to send the request, or other wise report an error (404 not found).\n   */\n  try {\n    this.cleanUpTimeoutTimer_();  // Paranoid, should never be running.\n    if (this.timeoutInterval_ > 0) {\n      this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_);\n      goog.log.fine(\n          this.logger_, this.formatMsg_(\n                            'Will abort after ' + this.timeoutInterval_ +\n                            'ms if incomplete, xhr2 ' + this.useXhr2Timeout_));\n      if (this.useXhr2Timeout_) {\n        this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_;\n        this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] =\n            goog.bind(this.timeout_, this);\n      } else {\n        this.timeoutId_ =\n            goog.Timer.callOnce(this.timeout_, this.timeoutInterval_, this);\n      }\n    }\n    goog.log.fine(this.logger_, this.formatMsg_('Sending request'));\n    this.inSend_ = true;\n    this.xhr_.send(content);\n    this.inSend_ = false;\n\n  } catch (err) {\n    goog.log.fine(this.logger_, this.formatMsg_('Send error: ' + err.message));\n    this.error_(goog.net.ErrorCode.EXCEPTION, err);\n  }\n};\n\n\n/**\n * Determines if the argument is an XMLHttpRequest that supports the level 2\n * timeout value and event.\n *\n * Currently, FF 21.0 OS X has the fields but won't actually call the timeout\n * handler.  Perhaps the confusion in the bug referenced below hasn't\n * entirely been resolved.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n * @see https://bugzilla.mozilla.org/show_bug.cgi?id=525816\n *\n * @param {!goog.net.XhrLike.OrNative} xhr The request.\n * @return {boolean} True if the request supports level 2 timeout.\n * @private\n */\ngoog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) {\n  return goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9) &&\n      typeof xhr[goog.net.XhrIo.XHR2_TIMEOUT_] === 'number' &&\n      xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_] !== undefined;\n};\n\n\n/**\n * @param {string} header An HTTP header key.\n * @return {boolean} Whether the key is a content type header (ignoring\n *     case.\n * @private\n */\ngoog.net.XhrIo.isContentTypeHeader_ = function(header) {\n  return goog.string.caseInsensitiveEquals(\n      goog.net.XhrIo.CONTENT_TYPE_HEADER, header);\n};\n\n\n/**\n * Creates a new XHR object.\n * @return {!goog.net.XhrLike.OrNative} The newly created XHR object.\n * @protected\n */\ngoog.net.XhrIo.prototype.createXhr = function() {\n  return this.xmlHttpFactory_ ? this.xmlHttpFactory_.createInstance() :\n                                goog.net.XmlHttp();\n};\n\n\n/**\n * The request didn't complete after {@link goog.net.XhrIo#timeoutInterval_}\n * milliseconds; raises a {@link goog.net.EventType.TIMEOUT} event and aborts\n * the request.\n * @private\n */\ngoog.net.XhrIo.prototype.timeout_ = function() {\n  if (typeof goog == 'undefined') {\n    // If goog is undefined then the callback has occurred as the application\n    // is unloading and will error.  Thus we let it silently fail.\n  } else if (this.xhr_) {\n    this.lastError_ =\n        'Timed out after ' + this.timeoutInterval_ + 'ms, aborting';\n    this.lastErrorCode_ = goog.net.ErrorCode.TIMEOUT;\n    goog.log.fine(this.logger_, this.formatMsg_(this.lastError_));\n    this.dispatchEvent(goog.net.EventType.TIMEOUT);\n    this.abort(goog.net.ErrorCode.TIMEOUT);\n  }\n};\n\n\n/**\n * Something errorred, so inactivate, fire error callback and clean up\n * @param {goog.net.ErrorCode} errorCode The error code.\n * @param {Error} err The error object.\n * @private\n */\ngoog.net.XhrIo.prototype.error_ = function(errorCode, err) {\n  this.active_ = false;\n  if (this.xhr_) {\n    this.inAbort_ = true;\n    this.xhr_.abort();  // Ensures XHR isn't hung (FF)\n    this.inAbort_ = false;\n  }\n  this.lastError_ = err;\n  this.lastErrorCode_ = errorCode;\n  this.dispatchErrors_();\n  this.cleanUpXhr_();\n};\n\n\n/**\n * Dispatches COMPLETE and ERROR in case of an error. This ensures that we do\n * not dispatch multiple error events.\n * @private\n */\ngoog.net.XhrIo.prototype.dispatchErrors_ = function() {\n  if (!this.errorDispatched_) {\n    this.errorDispatched_ = true;\n    this.dispatchEvent(goog.net.EventType.COMPLETE);\n    this.dispatchEvent(goog.net.EventType.ERROR);\n  }\n};\n\n\n/**\n * Abort the current XMLHttpRequest\n * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -\n *     defaults to ABORT.\n */\ngoog.net.XhrIo.prototype.abort = function(opt_failureCode) {\n  if (this.xhr_ && this.active_) {\n    goog.log.fine(this.logger_, this.formatMsg_('Aborting'));\n    this.active_ = false;\n    this.inAbort_ = true;\n    this.xhr_.abort();\n    this.inAbort_ = false;\n    this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;\n    this.dispatchEvent(goog.net.EventType.COMPLETE);\n    this.dispatchEvent(goog.net.EventType.ABORT);\n    this.cleanUpXhr_();\n  }\n};\n\n\n/**\n * Nullifies all callbacks to reduce risks of leaks.\n * @override\n * @protected\n */\ngoog.net.XhrIo.prototype.disposeInternal = function() {\n  if (this.xhr_) {\n    // We explicitly do not call xhr_.abort() unless active_ is still true.\n    // This is to avoid unnecessarily aborting a successful request when\n    // dispose() is called in a callback triggered by a complete response, but\n    // in which browser cleanup has not yet finished.\n    // (See http://b/issue?id=1684217.)\n    if (this.active_) {\n      this.active_ = false;\n      this.inAbort_ = true;\n      this.xhr_.abort();\n      this.inAbort_ = false;\n    }\n    this.cleanUpXhr_(true);\n  }\n\n  XhrIo.base(this, 'disposeInternal');\n};\n\n\n/**\n * Internal handler for the XHR object's readystatechange event.  This method\n * checks the status and the readystate and fires the correct callbacks.\n * If the request has ended, the handlers are cleaned up and the XHR object is\n * nullified.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChange_ = function() {\n  if (this.isDisposed()) {\n    // This method is the target of an untracked goog.Timer.callOnce().\n    return;\n  }\n  if (!this.inOpen_ && !this.inSend_ && !this.inAbort_) {\n    // Were not being called from within a call to this.xhr_.send\n    // this.xhr_.abort, or this.xhr_.open, so this is an entry point\n    this.onReadyStateChangeEntryPoint_();\n  } else {\n    this.onReadyStateChangeHelper_();\n  }\n};\n\n\n/**\n * Used to protect the onreadystatechange handler entry point.  Necessary\n * as {#onReadyStateChange_} maybe called from within send or abort, this\n * method is only called when {#onReadyStateChange_} is called as an\n * entry point.\n * {@see #protectEntryPoints}\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() {\n  this.onReadyStateChangeHelper_();\n};\n\n\n/**\n * Helper for {@link #onReadyStateChange_}.  This is used so that\n * entry point calls to {@link #onReadyStateChange_} can be routed through\n * {@link #onReadyStateChangeEntryPoint_}.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() {\n  if (!this.active_) {\n    // can get called inside abort call\n    return;\n  }\n\n  if (typeof goog == 'undefined') {\n    // NOTE(user): If goog is undefined then the callback has occurred as the\n    // application is unloading and will error.  Thus we let it silently fail.\n\n  } else if (\n      this.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] &&\n      this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE &&\n      this.getStatus() == 2) {\n    // NOTE(user): In IE if send() errors on a *local* request the readystate\n    // is still changed to COMPLETE.  We need to ignore it and allow the\n    // try/catch around send() to pick up the error.\n    goog.log.fine(\n        this.logger_,\n        this.formatMsg_('Local request error detected and ignored'));\n\n  } else {\n    // In IE when the response has been cached we sometimes get the callback\n    // from inside the send call and this usually breaks code that assumes that\n    // XhrIo is asynchronous.  If that is the case we delay the callback\n    // using a timer.\n    if (this.inSend_ &&\n        this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE) {\n      goog.Timer.callOnce(this.onReadyStateChange_, 0, this);\n      return;\n    }\n\n    this.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE);\n\n    // readyState indicates the transfer has finished\n    if (this.isComplete()) {\n      goog.log.fine(this.logger_, this.formatMsg_('Request complete'));\n\n      this.active_ = false;\n\n      try {\n        // Call the specific callbacks for success or failure. Only call the\n        // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)\n        if (this.isSuccess()) {\n          this.dispatchEvent(goog.net.EventType.COMPLETE);\n          this.dispatchEvent(goog.net.EventType.SUCCESS);\n        } else {\n          this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;\n          this.lastError_ =\n              this.getStatusText() + ' [' + this.getStatus() + ']';\n          this.dispatchErrors_();\n        }\n      } finally {\n        this.cleanUpXhr_();\n      }\n    }\n  }\n};\n\n\n/**\n * Internal handler for the XHR object's onprogress event. Fires both a generic\n * PROGRESS event and either a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event to\n * allow specific binding for each XHR progress event.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {boolean=} opt_isDownload Whether the current progress event is from a\n *     download. Used to determine whether DOWNLOAD_PROGRESS or UPLOAD_PROGRESS\n *     event should be dispatched.\n * @private\n */\ngoog.net.XhrIo.prototype.onProgressHandler_ = function(e, opt_isDownload) {\n  goog.asserts.assert(\n      e.type === goog.net.EventType.PROGRESS,\n      'goog.net.EventType.PROGRESS is of the same type as raw XHR progress.');\n  this.dispatchEvent(\n      goog.net.XhrIo.buildProgressEvent_(e, goog.net.EventType.PROGRESS));\n  this.dispatchEvent(\n      goog.net.XhrIo.buildProgressEvent_(\n          e, opt_isDownload ? goog.net.EventType.DOWNLOAD_PROGRESS :\n                              goog.net.EventType.UPLOAD_PROGRESS));\n};\n\n\n/**\n * Creates a representation of the native ProgressEvent. IE doesn't support\n * constructing ProgressEvent via \"new\", and the alternatives (e.g.,\n * ProgressEvent.initProgressEvent) are non-standard or deprecated.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {!goog.net.EventType} eventType The type of the event.\n * @return {!ProgressEvent} The progress event.\n * @private\n */\ngoog.net.XhrIo.buildProgressEvent_ = function(e, eventType) {\n  return /** @type {!ProgressEvent} */ ({\n    type: eventType,\n    lengthComputable: e.lengthComputable,\n    loaded: e.loaded,\n    total: e.total,\n  });\n};\n\n\n/**\n * Remove the listener to protect against leaks, and nullify the XMLHttpRequest\n * object.\n * @param {boolean=} opt_fromDispose If this is from the dispose (don't want to\n *     fire any events).\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpXhr_ = function(opt_fromDispose) {\n  if (this.xhr_) {\n    // Cancel any pending timeout event handler.\n    this.cleanUpTimeoutTimer_();\n\n    // Save reference so we can mark it as closed after the READY event.  The\n    // READY event may trigger another request, thus we must nullify this.xhr_\n    var xhr = this.xhr_;\n    var clearedOnReadyStateChange =\n        this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ?\n        goog.nullFunction :\n        null;\n    this.xhr_ = null;\n    this.xhrOptions_ = null;\n\n    if (!opt_fromDispose) {\n      this.dispatchEvent(goog.net.EventType.READY);\n    }\n\n    try {\n      // NOTE(user): Not nullifying in FireFox can still leak if the callbacks\n      // are defined in the same scope as the instance of XhrIo. But, IE doesn't\n      // allow you to set the onreadystatechange to NULL so nullFunction is\n      // used.\n      xhr.onreadystatechange = clearedOnReadyStateChange;\n    } catch (e) {\n      // This seems to occur with a Gears HTTP request. Delayed the setting of\n      // this onreadystatechange until after READY is sent out and catching the\n      // error to see if we can track down the problem.\n      goog.log.error(\n          this.logger_,\n          'Problem encountered resetting onreadystatechange: ' + e.message);\n    }\n  }\n};\n\n\n/**\n * Make sure the timeout timer isn't running.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpTimeoutTimer_ = function() {\n  if (this.xhr_ && this.useXhr2Timeout_) {\n    this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null;\n  }\n  if (this.timeoutId_) {\n    goog.Timer.clear(this.timeoutId_);\n    this.timeoutId_ = null;\n  }\n};\n\n\n/**\n * @return {boolean} Whether there is an active request.\n */\ngoog.net.XhrIo.prototype.isActive = function() {\n  return !!this.xhr_;\n};\n\n\n/**\n * @return {boolean} Whether the request has completed.\n */\ngoog.net.XhrIo.prototype.isComplete = function() {\n  return this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE;\n};\n\n\n/**\n * @return {boolean} Whether the request completed with a success.\n */\ngoog.net.XhrIo.prototype.isSuccess = function() {\n  var status = this.getStatus();\n  // A zero status code is considered successful for local files.\n  return goog.net.HttpStatus.isSuccess(status) ||\n      status === 0 && !this.isLastUriEffectiveSchemeHttp_();\n};\n\n\n/**\n * @return {boolean} whether the effective scheme of the last URI that was\n *     fetched was 'http' or 'https'.\n * @private\n */\ngoog.net.XhrIo.prototype.isLastUriEffectiveSchemeHttp_ = function() {\n  var scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_));\n  return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme);\n};\n\n\n/**\n * Get the readystate from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {goog.net.XmlHttp.ReadyState} goog.net.XmlHttp.ReadyState.*.\n */\ngoog.net.XhrIo.prototype.getReadyState = function() {\n  return this.xhr_ ?\n      /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) :\n                                                 goog.net.XmlHttp.ReadyState\n                                                     .UNINITIALIZED;\n};\n\n\n/**\n * Get the status from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {number} Http status.\n */\ngoog.net.XhrIo.prototype.getStatus = function() {\n  /**\n   * IE doesn't like you checking status until the readystate is greater than 2\n   * (i.e. it is receiving or complete).  The try/catch is used for when the\n   * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n   */\n  try {\n    return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n        this.xhr_.status :\n        -1;\n  } catch (e) {\n    return -1;\n  }\n};\n\n\n/**\n * Get the status text from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {string} Status text.\n */\ngoog.net.XhrIo.prototype.getStatusText = function() {\n  /**\n   * IE doesn't like you checking status until the readystate is greater than 2\n   * (i.e. it is receiving or complete).  The try/catch is used for when the\n   * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n   */\n  try {\n    return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n        this.xhr_.statusText :\n        '';\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get status: ' + e.message);\n    return '';\n  }\n};\n\n\n/**\n * Get the last Uri that was requested\n * @return {string} Last Uri.\n */\ngoog.net.XhrIo.prototype.getLastUri = function() {\n  return String(this.lastUri_);\n};\n\n\n/**\n * Get the response text from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {string} Result from the server, or '' if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseText = function() {\n  try {\n    return this.xhr_ ? this.xhr_.responseText : '';\n  } catch (e) {\n    // http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute\n    // states that responseText should return '' (and responseXML null)\n    // when the state is not LOADING or DONE. Instead, IE can\n    // throw unexpected exceptions, for example when a request is aborted\n    // or no data is available yet.\n    goog.log.fine(this.logger_, 'Can not get responseText: ' + e.message);\n    return '';\n  }\n};\n\n\n/**\n * Get the response body from the Xhr object. This property is only available\n * in IE since version 7 according to MSDN:\n * http://msdn.microsoft.com/en-us/library/ie/ms534368(v=vs.85).aspx\n * Will only return correct result when called from the context of a callback.\n *\n * One option is to construct a VBArray from the returned object and convert\n * it to a JavaScript array using the toArray method:\n * `(new window['VBArray'](xhrIo.getResponseBody())).toArray()`\n * This will result in an array of numbers in the range of [0..255]\n *\n * Another option is to use the VBScript CStr method to convert it into a\n * string as outlined in http://stackoverflow.com/questions/1919972\n *\n * @return {Object} Binary result from the server or null if not available.\n */\ngoog.net.XhrIo.prototype.getResponseBody = function() {\n  try {\n    if (this.xhr_ && 'responseBody' in this.xhr_) {\n      return this.xhr_['responseBody'];\n    }\n  } catch (e) {\n    // IE can throw unexpected exceptions, for example when a request is aborted\n    // or no data is yet available.\n    goog.log.fine(this.logger_, 'Can not get responseBody: ' + e.message);\n  }\n  return null;\n};\n\n\n/**\n * Get the response XML from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {Document} The DOM Document representing the XML file, or null\n * if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseXml = function() {\n  try {\n    return this.xhr_ ? this.xhr_.responseXML : null;\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get responseXML: ' + e.message);\n    return null;\n  }\n};\n\n\n/**\n * Get the response and evaluates it as JSON from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @param {string=} opt_xssiPrefix Optional XSSI prefix string to use for\n *     stripping of the response before parsing. This needs to be set only if\n *     your backend server prepends the same prefix string to the JSON response.\n * @throws Error if the response text is invalid JSON.\n * @return {Object|undefined} JavaScript object.\n */\ngoog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) {\n  if (!this.xhr_) {\n    return undefined;\n  }\n\n  var responseText = this.xhr_.responseText;\n  if (opt_xssiPrefix && responseText.indexOf(opt_xssiPrefix) == 0) {\n    responseText = responseText.substring(opt_xssiPrefix.length);\n  }\n\n  return goog.json.hybrid.parse(responseText);\n};\n\n\n/**\n * Get the response as the type specificed by {@link #setResponseType}. At time\n * of writing, this is only directly supported in very recent versions of WebKit\n * (10.0.612.1 dev and later). If the field is not supported directly, we will\n * try to emulate it.\n *\n * Emulating the response means following the rules laid out at\n * http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute\n *\n * On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only\n * response types of DEFAULT or TEXT may be used, and the response returned will\n * be the text response.\n *\n * On browsers with Mozilla's draft support for array buffers (Firefox 4, 5),\n * only response types of DEFAULT, TEXT, and ARRAY_BUFFER may be used, and the\n * response returned will be either the text response or the Mozilla\n * implementation of the array buffer response.\n *\n * On browsers will full support, any valid response type supported by the\n * browser may be used, and the response provided by the browser will be\n * returned.\n *\n * @return {*} The response.\n */\ngoog.net.XhrIo.prototype.getResponse = function() {\n  try {\n    if (!this.xhr_) {\n      return null;\n    }\n    if ('response' in this.xhr_) {\n      return this.xhr_.response;\n    }\n    switch (this.responseType_) {\n      case ResponseType.DEFAULT:\n      case ResponseType.TEXT:\n        return this.xhr_.responseText;\n      // DOCUMENT and BLOB don't need to be handled here because they are\n      // introduced in the same spec that adds the .response field, and would\n      // have been caught above.\n      // ARRAY_BUFFER needs an implementation for Firefox 4, where it was\n      // implemented using a draft spec rather than the final spec.\n      case ResponseType.ARRAY_BUFFER:\n        if ('mozResponseArrayBuffer' in this.xhr_) {\n          return this.xhr_.mozResponseArrayBuffer;\n        }\n    }\n    // Fell through to a response type that is not supported on this browser.\n    goog.log.error(\n        this.logger_, 'Response type ' + this.responseType_ + ' is not ' +\n            'supported on this browser');\n    return null;\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get response: ' + e.message);\n    return null;\n  }\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object\n * Will only return correct result when called from the context of a callback\n * and the request has completed\n * @param {string} key The name of the response-header to retrieve.\n * @return {string|undefined} The value of the response-header named key.\n */\ngoog.net.XhrIo.prototype.getResponseHeader = function(key) {\n  if (!this.xhr_ || !this.isComplete()) {\n    return undefined;\n  }\n\n  var value = this.xhr_.getResponseHeader(key);\n  return value === null ? undefined : value;\n};\n\n\n/**\n * Gets the text of all the headers in the response.\n * Will only return correct result when called from the context of a callback\n * and the request has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllResponseHeaders = function() {\n  // getAllResponseHeaders can return null if no response has been received,\n  // ensure we always return an empty string.\n  return this.xhr_ && this.isComplete() ?\n      (this.xhr_.getAllResponseHeaders() || '') :\n      '';\n};\n\n\n/**\n * Returns all response headers as a key-value map.\n * Multiple values for the same header key can be combined into one,\n * separated by a comma and a space.\n * Note that the native getResponseHeader method for retrieving a single header\n * does a case insensitive match on the header name. This method does not\n * include any case normalization logic, it will just return a key-value\n * representation of the headers.\n * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method\n * @return {!Object<string, string>} An object with the header keys as keys\n *     and header values as values.\n */\ngoog.net.XhrIo.prototype.getResponseHeaders = function() {\n  // TODO(user): Make this function parse headers as per the spec\n  // (https://tools.ietf.org/html/rfc2616#section-4.2).\n\n  var headersObject = {};\n  var headersArray = this.getAllResponseHeaders().split('\\r\\n');\n  for (var i = 0; i < headersArray.length; i++) {\n    if (goog.string.isEmptyOrWhitespace(headersArray[i])) {\n      continue;\n    }\n    var keyValue =\n        goog.string.splitLimit(headersArray[i], ':', /* maxSplitCount= */ 1);\n    var key = keyValue[0];\n    var value = keyValue[1];\n\n    if (typeof value !== 'string') {\n      // There must be a value but it can be the empty string.\n      continue;\n    }\n\n    // Whitespace at the start and end of the value is meaningless.\n    value = value.trim();\n    // The key should not contain whitespace but we currently ignore that.\n\n    var values = headersObject[key] || [];\n    headersObject[key] = values;\n    values.push(value);\n  }\n\n  return goog.object.map(headersObject, function(values) {\n    return values.join(', ');\n  });\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object.\n * As opposed to {@link #getResponseHeader}, this method does not require that\n * the request has completed.\n * @param {string} key The name of the response-header to retrieve.\n * @return {?string} The value of the response-header, or null if it is\n *     unavailable.\n */\ngoog.net.XhrIo.prototype.getStreamingResponseHeader = function(key) {\n  return this.xhr_ ? this.xhr_.getResponseHeader(key) : null;\n};\n\n\n/**\n * Gets the text of all the headers in the response. As opposed to\n * {@link #getAllResponseHeaders}, this method does not require that the request\n * has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllStreamingResponseHeaders = function() {\n  return this.xhr_ ? this.xhr_.getAllResponseHeaders() : '';\n};\n\n\n/**\n * Get the last error message\n * @return {!goog.net.ErrorCode} Last error code.\n */\ngoog.net.XhrIo.prototype.getLastErrorCode = function() {\n  return this.lastErrorCode_;\n};\n\n\n/**\n * Get the last error message\n * @return {string} Last error message.\n */\ngoog.net.XhrIo.prototype.getLastError = function() {\n  return typeof this.lastError_ === 'string' ? this.lastError_ :\n                                               String(this.lastError_);\n};\n\n\n/**\n * Adds the last method, status and URI to the message.  This is used to add\n * this information to the logging calls.\n * @param {string} msg The message text that we want to add the extra text to.\n * @return {string} The message with the extra text appended.\n * @private\n */\ngoog.net.XhrIo.prototype.formatMsg_ = function(msg) {\n  return msg + ' [' + this.lastMethod_ + ' ' + this.lastUri_ + ' ' +\n      this.getStatus() + ']';\n};\n\n\n// Register the xhr handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) {\n      goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n          transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n    });\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple utilities for dealing with URI strings.\n *\n * This is intended to be a lightweight alternative to constructing goog.Uri\n * objects.  Whereas goog.Uri adds several kilobytes to the binary regardless\n * of how much of its functionality you use, this is designed to be a set of\n * mostly-independent utilities so that the compiler includes only what is\n * necessary for the task.  Estimated savings of porting is 5k pre-gzip and\n * 1.5k post-gzip.  To ensure the savings remain, future developers should\n * avoid adding new functionality to existing functions, but instead create\n * new ones and factor out shared code.\n *\n * Many of these utilities have limited functionality, tailored to common\n * cases.  The query parameter utilities assume that the parameter keys are\n * already encoded, since most keys are compile-time alphanumeric strings.  The\n * query parameter mutation utilities also do not tolerate fragment identifiers.\n *\n * By design, these functions can be slower than goog.Uri equivalents.\n * Repeated calls to some of functions may be quadratic in behavior for IE,\n * although the effect is somewhat limited given the 2kb limit.\n *\n * One advantage of the limited functionality here is that this approach is\n * less sensitive to differences in URI encodings than goog.Uri, since these\n * functions operate on strings directly, rather than decoding them and\n * then re-encoding.\n *\n * Uses features of RFC 3986 for parsing/formatting URIs:\n *   http://www.ietf.org/rfc/rfc3986.txt\n */\n\ngoog.provide('goog.uri.utils');\ngoog.provide('goog.uri.utils.ComponentIndex');\ngoog.provide('goog.uri.utils.QueryArray');\ngoog.provide('goog.uri.utils.QueryValue');\ngoog.provide('goog.uri.utils.StandardQueryParam');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.string');\n\n\n/**\n * Character codes inlined to avoid object allocations due to charCode.\n * @enum {number}\n * @private\n */\ngoog.uri.utils.CharCode_ = {\n  AMPERSAND: 38,\n  EQUAL: 61,\n  HASH: 35,\n  QUESTION: 63\n};\n\n\n/**\n * Builds a URI string from already-encoded parts.\n *\n * No encoding is performed.  Any component may be omitted as either null or\n * undefined.\n *\n * @param {?string=} opt_scheme The scheme such as 'http'.\n * @param {?string=} opt_userInfo The user name before the '@'.\n * @param {?string=} opt_domain The domain such as 'www.google.com', already\n *     URI-encoded.\n * @param {(string|number|null)=} opt_port The port number.\n * @param {?string=} opt_path The path, already URI-encoded.  If it is not\n *     empty, it must begin with a slash.\n * @param {?string=} opt_queryData The URI-encoded query data.\n * @param {?string=} opt_fragment The URI-encoded fragment identifier.\n * @return {string} The fully combined URI.\n */\ngoog.uri.utils.buildFromEncodedParts = function(\n    opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData,\n    opt_fragment) {\n  var out = '';\n\n  if (opt_scheme) {\n    out += opt_scheme + ':';\n  }\n\n  if (opt_domain) {\n    out += '//';\n\n    if (opt_userInfo) {\n      out += opt_userInfo + '@';\n    }\n\n    out += opt_domain;\n\n    if (opt_port) {\n      out += ':' + opt_port;\n    }\n  }\n\n  if (opt_path) {\n    out += opt_path;\n  }\n\n  if (opt_queryData) {\n    out += '?' + opt_queryData;\n  }\n\n  if (opt_fragment) {\n    out += '#' + opt_fragment;\n  }\n\n  return out;\n};\n\n\n/**\n * A regular expression for breaking a URI into its component parts.\n *\n * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B\n * As the \"first-match-wins\" algorithm is identical to the \"greedy\"\n * disambiguation method used by POSIX regular expressions, it is natural and\n * commonplace to use a regular expression for parsing the potential five\n * components of a URI reference.\n *\n * The following line is the regular expression for breaking-down a\n * well-formed URI reference into its components.\n *\n * <pre>\n * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?\n *  12            3  4          5       6  7        8 9\n * </pre>\n *\n * The numbers in the second line above are only to assist readability; they\n * indicate the reference points for each subexpression (i.e., each paired\n * parenthesis). We refer to the value matched for subexpression <n> as $<n>.\n * For example, matching the above expression to\n * <pre>\n *     http://www.ics.uci.edu/pub/ietf/uri/#Related\n * </pre>\n * results in the following subexpression matches:\n * <pre>\n *    $1 = http:\n *    $2 = http\n *    $3 = //www.ics.uci.edu\n *    $4 = www.ics.uci.edu\n *    $5 = /pub/ietf/uri/\n *    $6 = <undefined>\n *    $7 = <undefined>\n *    $8 = #Related\n *    $9 = Related\n * </pre>\n * where <undefined> indicates that the component is not present, as is the\n * case for the query component in the above example. Therefore, we can\n * determine the value of the five components as\n * <pre>\n *    scheme    = $2\n *    authority = $4\n *    path      = $5\n *    query     = $7\n *    fragment  = $9\n * </pre>\n *\n * The regular expression has been modified slightly to expose the\n * userInfo, domain, and port separately from the authority.\n * The modified version yields\n * <pre>\n *    $1 = http              scheme\n *    $2 = <undefined>       userInfo -\\\n *    $3 = www.ics.uci.edu   domain     | authority\n *    $4 = <undefined>       port     -/\n *    $5 = /pub/ietf/uri/    path\n *    $6 = <undefined>       query without ?\n *    $7 = Related           fragment without #\n * </pre>\n * @type {!RegExp}\n * @private\n */\ngoog.uri.utils.splitRe_ = new RegExp(\n    '^' +\n    '(?:' +\n    '([^:/?#.]+)' +  // scheme - ignore special characters\n                     // used by other URL parts such as :,\n                     // ?, /, #, and .\n    ':)?' +\n    '(?://' +\n    '(?:([^/?#]*)@)?' +  // userInfo\n    '([^/#?]*?)' +       // domain\n    '(?::([0-9]+))?' +   // port\n    '(?=[/\\\\\\\\#?]|$)' +  // authority-terminating character\n    ')?' +\n    '([^?#]+)?' +          // path\n    '(?:\\\\?([^#]*))?' +    // query\n    '(?:#([\\\\s\\\\S]*))?' +  // fragment\n    '$');\n\n\n/**\n * The index of each URI component in the return value of goog.uri.utils.split.\n * @enum {number}\n */\ngoog.uri.utils.ComponentIndex = {\n  SCHEME: 1,\n  USER_INFO: 2,\n  DOMAIN: 3,\n  PORT: 4,\n  PATH: 5,\n  QUERY_DATA: 6,\n  FRAGMENT: 7\n};\n\n\n/**\n * Splits a URI into its component parts.\n *\n * Each component can be accessed via the component indices; for example:\n * <pre>\n * goog.uri.utils.split(someStr)[goog.uri.utils.ComponentIndex.QUERY_DATA];\n * </pre>\n *\n * @param {string} uri The URI string to examine.\n * @return {!Array<string|undefined>} Each component still URI-encoded.\n *     Each component that is present will contain the encoded value, whereas\n *     components that are not present will be undefined or empty, depending\n *     on the browser's regular expression implementation.  Never null, since\n *     arbitrary strings may still look like path names.\n */\ngoog.uri.utils.split = function(uri) {\n  // See @return comment -- never null.\n  return /** @type {!Array<string|undefined>} */ (\n      uri.match(goog.uri.utils.splitRe_));\n};\n\n\n/**\n * @param {?string} uri A possibly null string.\n * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986\n *     reserved characters will not be removed.\n * @return {?string} The string URI-decoded, or null if uri is null.\n * @private\n */\ngoog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) {\n  if (!uri) {\n    return uri;\n  }\n\n  return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri);\n};\n\n\n/**\n * Gets a URI component by index.\n *\n * It is preferred to use the getPathEncoded() variety of functions ahead,\n * since they are more readable.\n *\n * @param {goog.uri.utils.ComponentIndex} componentIndex The component index.\n * @param {string} uri The URI to examine.\n * @return {?string} The still-encoded component, or null if the component\n *     is not present.\n * @private\n */\ngoog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {\n  // Convert undefined, null, and empty string into null.\n  return goog.uri.utils.split(uri)[componentIndex] || null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The protocol or scheme, or null if none.  Does not\n *     include trailing colons or slashes.\n */\ngoog.uri.utils.getScheme = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.SCHEME, uri);\n};\n\n\n/**\n * Gets the effective scheme for the URL.  If the URL is relative then the\n * scheme is derived from the page's location.\n * @param {string} uri The URI to examine.\n * @return {string} The protocol or scheme, always lower case.\n */\ngoog.uri.utils.getEffectiveScheme = function(uri) {\n  var scheme = goog.uri.utils.getScheme(uri);\n  if (!scheme && goog.global.self && goog.global.self.location) {\n    var protocol = goog.global.self.location.protocol;\n    scheme = protocol.substr(0, protocol.length - 1);\n  }\n  // NOTE: When called from a web worker in Firefox 3.5, location may be null.\n  // All other browsers with web workers support self.location from the worker.\n  return scheme ? scheme.toLowerCase() : '';\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The user name still encoded, or null if none.\n */\ngoog.uri.utils.getUserInfoEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.USER_INFO, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded user info, or null if none.\n */\ngoog.uri.utils.getUserInfo = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getUserInfoEncoded(uri));\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The domain name still encoded, or null if none.\n */\ngoog.uri.utils.getDomainEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.DOMAIN, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded domain, or null if none.\n */\ngoog.uri.utils.getDomain = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?number} The port number, or null if none.\n */\ngoog.uri.utils.getPort = function(uri) {\n  // Coerce to a number.  If the result of getComponentByIndex_ is null or\n  // non-numeric, the number coersion yields NaN.  This will then return\n  // null for all non-numeric cases (though also zero, which isn't a relevant\n  // port number).\n  return Number(\n             goog.uri.utils.getComponentByIndex_(\n                 goog.uri.utils.ComponentIndex.PORT, uri)) ||\n      null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The path still encoded, or null if none. Includes the\n *     leading slash, if any.\n */\ngoog.uri.utils.getPathEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.PATH, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded path, or null if none.  Includes the leading\n *     slash, if any.\n */\ngoog.uri.utils.getPath = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The query data still encoded, or null if none.  Does not\n *     include the question mark itself.\n */\ngoog.uri.utils.getQueryData = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.QUERY_DATA, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The fragment identifier, or null if none.  Does not\n *     include the hash mark itself.\n */\ngoog.uri.utils.getFragmentEncoded = function(uri) {\n  // The hash mark may not appear in any other part of the URL.\n  var hashIndex = uri.indexOf('#');\n  return hashIndex < 0 ? null : uri.substr(hashIndex + 1);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @param {?string} fragment The encoded fragment identifier, or null if none.\n *     Does not include the hash mark itself.\n * @return {string} The URI with the fragment set.\n */\ngoog.uri.utils.setFragmentEncoded = function(uri, fragment) {\n  return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : '');\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded fragment identifier, or null if none.  Does\n *     not include the hash mark.\n */\ngoog.uri.utils.getFragment = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getFragmentEncoded(uri));\n};\n\n\n/**\n * Extracts everything up to the port of the URI.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getHost = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      pieces[goog.uri.utils.ComponentIndex.SCHEME],\n      pieces[goog.uri.utils.ComponentIndex.USER_INFO],\n      pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n      pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Returns the origin for a given URL.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getOrigin = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      pieces[goog.uri.utils.ComponentIndex.SCHEME], null /* opt_userInfo */,\n      pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n      pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Extracts the path of the URL and everything after.\n * @param {string} uri The URI string.\n * @return {string} The URI, starting at the path and including the query\n *     parameters and fragment identifier.\n */\ngoog.uri.utils.getPathAndAfter = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH],\n      pieces[goog.uri.utils.ComponentIndex.QUERY_DATA],\n      pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Gets the URI with the fragment identifier removed.\n * @param {string} uri The URI to examine.\n * @return {string} Everything preceding the hash mark.\n */\ngoog.uri.utils.removeFragment = function(uri) {\n  // The hash mark may not appear in any other part of the URL.\n  var hashIndex = uri.indexOf('#');\n  return hashIndex < 0 ? uri : uri.substr(0, hashIndex);\n};\n\n\n/**\n * Ensures that two URI's have the exact same domain, scheme, and port.\n *\n * Unlike the version in goog.Uri, this checks protocol, and therefore is\n * suitable for checking against the browser's same-origin policy.\n *\n * @param {string} uri1 The first URI.\n * @param {string} uri2 The second URI.\n * @return {boolean} Whether they have the same scheme, domain and port.\n */\ngoog.uri.utils.haveSameDomain = function(uri1, uri2) {\n  var pieces1 = goog.uri.utils.split(uri1);\n  var pieces2 = goog.uri.utils.split(uri2);\n  return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n      pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n      pieces1[goog.uri.utils.ComponentIndex.SCHEME] ==\n      pieces2[goog.uri.utils.ComponentIndex.SCHEME] &&\n      pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n      pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n/**\n * Asserts that there are no fragment or query identifiers, only in uncompiled\n * mode.\n * @param {string} uri The URI to examine.\n * @private\n */\ngoog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {\n  goog.asserts.assert(\n      uri.indexOf('#') < 0 && uri.indexOf('?') < 0,\n      'goog.uri.utils: Fragment or query identifiers are not supported: [%s]',\n      uri);\n};\n\n\n/**\n * Supported query parameter values by the parameter serializing utilities.\n *\n * If a value is null or undefined, the key-value pair is skipped, as an easy\n * way to omit parameters conditionally.  Non-array parameters are converted\n * to a string and URI encoded.  Array values are expanded into multiple\n * &key=value pairs, with each element stringized and URI-encoded.\n *\n * @typedef {*}\n */\ngoog.uri.utils.QueryValue;\n\n\n/**\n * An array representing a set of query parameters with alternating keys\n * and values.\n *\n * Keys are assumed to be URI encoded already and live at even indices.  See\n * goog.uri.utils.QueryValue for details on how parameter values are encoded.\n *\n * Example:\n * <pre>\n * var data = [\n *   // Simple param: ?name=BobBarker\n *   'name', 'BobBarker',\n *   // Conditional param -- may be omitted entirely.\n *   'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,\n *   // Multi-valued param: &house=LosAngeles&house=NewYork&house=null\n *   'house', ['LosAngeles', 'NewYork', null]\n * ];\n * </pre>\n *\n * @typedef {!Array<string|goog.uri.utils.QueryValue>}\n */\ngoog.uri.utils.QueryArray;\n\n\n/**\n * Parses encoded query parameters and calls callback function for every\n * parameter found in the string.\n *\n * Missing value of parameter (e.g. “…&key&…”) is treated as if the value was an\n * empty string.  Keys may be empty strings (e.g. “…&=value&…”) which also means\n * that “…&=&…” and “…&&…” will result in an empty key and value.\n *\n * @param {string} encodedQuery Encoded query string excluding question mark at\n *     the beginning.\n * @param {function(string, string)} callback Function called for every\n *     parameter found in query string.  The first argument (name) will not be\n *     urldecoded (so the function is consistent with buildQueryData), but the\n *     second will.  If the parameter has no value (i.e. “=” was not present)\n *     the second argument (value) will be an empty string.\n */\ngoog.uri.utils.parseQueryData = function(encodedQuery, callback) {\n  if (!encodedQuery) {\n    return;\n  }\n  var pairs = encodedQuery.split('&');\n  for (var i = 0; i < pairs.length; i++) {\n    var indexOfEquals = pairs[i].indexOf('=');\n    var name = null;\n    var value = null;\n    if (indexOfEquals >= 0) {\n      name = pairs[i].substring(0, indexOfEquals);\n      value = pairs[i].substring(indexOfEquals + 1);\n    } else {\n      name = pairs[i];\n    }\n    callback(name, value ? goog.string.urlDecode(value) : '');\n  }\n};\n\n\n/**\n * Split the URI into 3 parts where the [1] is the queryData without a leading\n * '?'. For example, the URI http://foo.com/bar?a=b#abc returns\n * ['http://foo.com/bar','a=b','#abc'].\n * @param {string} uri The URI to parse.\n * @return {!Array<string>} An array representation of uri of length 3 where the\n *     middle value is the queryData without a leading '?'.\n * @private\n */\ngoog.uri.utils.splitQueryData_ = function(uri) {\n  // Find the query data and hash.\n  var hashIndex = uri.indexOf('#');\n  if (hashIndex < 0) {\n    hashIndex = uri.length;\n  }\n  var questionIndex = uri.indexOf('?');\n  var queryData;\n  if (questionIndex < 0 || questionIndex > hashIndex) {\n    questionIndex = hashIndex;\n    queryData = '';\n  } else {\n    queryData = uri.substring(questionIndex + 1, hashIndex);\n  }\n  return [uri.substr(0, questionIndex), queryData, uri.substr(hashIndex)];\n};\n\n\n/**\n * Join an array created by splitQueryData_ back into a URI.\n * @param {!Array<string>} parts A URI in the form generated by splitQueryData_.\n * @return {string} The joined URI.\n * @private\n */\ngoog.uri.utils.joinQueryData_ = function(parts) {\n  return parts[0] + (parts[1] ? '?' + parts[1] : '') + parts[2];\n};\n\n\n/**\n * @param {string} queryData\n * @param {string} newData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryData_ = function(queryData, newData) {\n  if (!newData) {\n    return queryData;\n  }\n  return queryData ? queryData + '&' + newData : newData;\n};\n\n\n/**\n * @param {string} uri\n * @param {string} queryData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryDataToUri_ = function(uri, queryData) {\n  if (!queryData) {\n    return uri;\n  }\n  var parts = goog.uri.utils.splitQueryData_(uri);\n  parts[1] = goog.uri.utils.appendQueryData_(parts[1], queryData);\n  return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Appends key=value pairs to an array, supporting multi-valued objects.\n * @param {*} key The key prefix.\n * @param {goog.uri.utils.QueryValue} value The value to serialize.\n * @param {!Array<string>} pairs The array to which the 'key=value' strings\n *     should be appended.\n * @private\n */\ngoog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {\n  goog.asserts.assertString(key);\n  if (Array.isArray(value)) {\n    // Convince the compiler it's an array.\n    goog.asserts.assertArray(value);\n    for (var j = 0; j < value.length; j++) {\n      // Convert to string explicitly, to short circuit the null and array\n      // logic in this function -- this ensures that null and undefined get\n      // written as literal 'null' and 'undefined', and arrays don't get\n      // expanded out but instead encoded in the default way.\n      goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);\n    }\n  } else if (value != null) {\n    // Skip a top-level null or undefined entirely.\n    pairs.push(\n        key +\n        // Check for empty string. Zero gets encoded into the url as literal\n        // strings.  For empty string, skip the equal sign, to be consistent\n        // with UriBuilder.java.\n        (value === '' ? '' : '=' + goog.string.urlEncode(value)));\n  }\n};\n\n\n/**\n * Builds a query data string from a sequence of alternating keys and values.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!IArrayLike<string|goog.uri.utils.QueryValue>} keysAndValues\n *     Alternating keys and values. See the QueryArray typedef.\n * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {\n  goog.asserts.assert(\n      Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2 == 0,\n      'goog.uri.utils: Key/value lists must be even in length.');\n\n  var params = [];\n  for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {\n    var key = /** @type {string} */ (keysAndValues[i]);\n    goog.uri.utils.appendKeyValuePairs_(key, keysAndValues[i + 1], params);\n  }\n  return params.join('&');\n};\n\n\n/**\n * Builds a query data string from a map.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys\n *     are URI-encoded parameter keys, and the values are arbitrary types\n *     or arrays. Keys with a null value are dropped.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryDataFromMap = function(map) {\n  var params = [];\n  for (var key in map) {\n    goog.uri.utils.appendKeyValuePairs_(key, map[key], params);\n  }\n  return params.join('&');\n};\n\n\n/**\n * Appends URI parameters to an existing URI.\n *\n * The variable arguments may contain alternating keys and values.  Keys are\n * assumed to be already URI encoded.  The values should not be URI-encoded,\n * and will instead be encoded by this function.\n * <pre>\n * appendParams('http://www.foo.com?existing=true',\n *     'key1', 'value1',\n *     'key2', 'value?willBeEncoded',\n *     'key3', ['valueA', 'valueB', 'valueC'],\n *     'key4', null);\n * result: 'http://www.foo.com?existing=true&' +\n *     'key1=value1&' +\n *     'key2=value%3FwillBeEncoded&' +\n *     'key3=valueA&key3=valueB&key3=valueC'\n * </pre>\n *\n * A single call to this function will not exhibit quadratic behavior in IE,\n * whereas multiple repeated calls may, although the effect is limited by\n * fact that URL's generally can't exceed 2kb.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {...(goog.uri.utils.QueryArray|goog.uri.utils.QueryValue)}\n * var_args\n *     An array or argument list conforming to goog.uri.utils.QueryArray.\n * @return {string} The URI with all query parameters added.\n */\ngoog.uri.utils.appendParams = function(uri, var_args) {\n  var queryData = arguments.length == 2 ?\n      goog.uri.utils.buildQueryData(arguments[1], 0) :\n      goog.uri.utils.buildQueryData(arguments, 1);\n  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends query parameters from a map.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {!Object<goog.uri.utils.QueryValue>} map An object where keys are\n *     URI-encoded parameter keys, and the values are arbitrary types or arrays.\n *     Keys with a null value are dropped.\n * @return {string} The new parameters.\n */\ngoog.uri.utils.appendParamsFromMap = function(uri, map) {\n  var queryData = goog.uri.utils.buildQueryDataFromMap(map);\n  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends a single URI parameter.\n *\n * Repeated calls to this can exhibit quadratic behavior in IE6 due to the\n * way string append works, though it should be limited given the 2kb limit.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} key The key, which must already be URI encoded.\n * @param {*=} opt_value The value, which will be stringized and encoded\n *     (assumed not already to be encoded).  If omitted, undefined, or null, the\n *     key will be added as a valueless parameter.\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.appendParam = function(uri, key, opt_value) {\n  var value = (opt_value != null) ? '=' + goog.string.urlEncode(opt_value) : '';\n  return goog.uri.utils.appendQueryDataToUri_(uri, key + value);\n};\n\n\n/**\n * Finds the next instance of a query parameter with the specified name.\n *\n * Does not instantiate any objects.\n *\n * @param {string} uri The URI to search.  May contain a fragment identifier\n *     if opt_hashIndex is specified.\n * @param {number} startIndex The index to begin searching for the key at.  A\n *     match may be found even if this is one character after the ampersand.\n * @param {string} keyEncoded The URI-encoded key.\n * @param {number} hashOrEndIndex Index to stop looking at.  If a hash\n *     mark is present, it should be its index, otherwise it should be the\n *     length of the string.\n * @return {number} The position of the first character in the key's name,\n *     immediately after either a question mark or a dot.\n * @private\n */\ngoog.uri.utils.findParam_ = function(\n    uri, startIndex, keyEncoded, hashOrEndIndex) {\n  var index = startIndex;\n  var keyLength = keyEncoded.length;\n\n  // Search for the key itself and post-filter for surronuding punctuation,\n  // rather than expensively building a regexp.\n  while ((index = uri.indexOf(keyEncoded, index)) >= 0 &&\n         index < hashOrEndIndex) {\n    var precedingChar = uri.charCodeAt(index - 1);\n    // Ensure that the preceding character is '&' or '?'.\n    if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n        precedingChar == goog.uri.utils.CharCode_.QUESTION) {\n      // Ensure the following character is '&', '=', '#', or NaN\n      // (end of string).\n      var followingChar = uri.charCodeAt(index + keyLength);\n      if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL ||\n          followingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n          followingChar == goog.uri.utils.CharCode_.HASH) {\n        return index;\n      }\n    }\n    index += keyLength + 1;\n  }\n\n  return -1;\n};\n\n\n/**\n * Regular expression for finding a hash mark or end of string.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.hashOrEndRe_ = /#|$/;\n\n\n/**\n * Determines if the URI contains a specific key.\n *\n * Performs no object instantiations.\n *\n * @param {string} uri The URI to process.  May contain a fragment\n *     identifier.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {boolean} Whether the key is present.\n */\ngoog.uri.utils.hasParam = function(uri, keyEncoded) {\n  return goog.uri.utils.findParam_(\n             uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;\n};\n\n\n/**\n * Gets the first value of a query parameter.\n * @param {string} uri The URI to process.  May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {?string} The first value of the parameter (URI-decoded), or null\n *     if the parameter is not found.\n */\ngoog.uri.utils.getParamValue = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var foundIndex =\n      goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex);\n\n  if (foundIndex < 0) {\n    return null;\n  } else {\n    var endPosition = uri.indexOf('&', foundIndex);\n    if (endPosition < 0 || endPosition > hashOrEndIndex) {\n      endPosition = hashOrEndIndex;\n    }\n    // Progress forth to the end of the \"key=\" or \"key&\" substring.\n    foundIndex += keyEncoded.length + 1;\n    // Use substr, because it (unlike substring) will return empty string\n    // if foundIndex > endPosition.\n    return goog.string.urlDecode(\n        uri.substr(foundIndex, endPosition - foundIndex));\n  }\n};\n\n\n/**\n * Gets all values of a query parameter.\n * @param {string} uri The URI to process.  May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {!Array<string>} All URI-decoded values with the given key.\n *     If the key is not found, this will have length 0, but never be null.\n */\ngoog.uri.utils.getParamValues = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var position = 0;\n  var foundIndex;\n  var result = [];\n\n  while ((foundIndex = goog.uri.utils.findParam_(\n              uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n    // Find where this parameter ends, either the '&' or the end of the\n    // query parameters.\n    position = uri.indexOf('&', foundIndex);\n    if (position < 0 || position > hashOrEndIndex) {\n      position = hashOrEndIndex;\n    }\n\n    // Progress forth to the end of the \"key=\" or \"key&\" substring.\n    foundIndex += keyEncoded.length + 1;\n    // Use substr, because it (unlike substring) will return empty string\n    // if foundIndex > position.\n    result.push(\n        goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex)));\n  }\n\n  return result;\n};\n\n\n/**\n * Regexp to find trailing question marks and ampersands.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;\n\n\n/**\n * Removes all instances of a query parameter.\n * @param {string} uri The URI to process.  Must not contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.\n * @return {string} The URI with all instances of the parameter removed.\n */\ngoog.uri.utils.removeParam = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var position = 0;\n  var foundIndex;\n  var buffer = [];\n\n  // Look for a query parameter.\n  while ((foundIndex = goog.uri.utils.findParam_(\n              uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n    // Get the portion of the query string up to, but not including, the ?\n    // or & starting the parameter.\n    buffer.push(uri.substring(position, foundIndex));\n    // Progress to immediately after the '&'.  If not found, go to the end.\n    // Avoid including the hash mark.\n    position = Math.min(\n        (uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex, hashOrEndIndex);\n  }\n\n  // Append everything that is remaining.\n  buffer.push(uri.substr(position));\n\n  // Join the buffer, and remove trailing punctuation that remains.\n  return buffer.join('').replace(\n      goog.uri.utils.trailingQueryPunctuationRe_, '$1');\n};\n\n\n/**\n * Replaces all existing definitions of a parameter with a single definition.\n *\n * Repeated calls to this can exhibit quadratic behavior due to the need to\n * find existing instances and reconstruct the string, though it should be\n * limited given the 2kb limit.  Consider using appendParams or setParamsFromMap\n * to update multiple parameters in bulk.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} keyEncoded The key, which must already be URI encoded.\n * @param {*} value The value, which will be stringized and encoded (assumed\n *     not already to be encoded).\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.setParam = function(uri, keyEncoded, value) {\n  return goog.uri.utils.appendParam(\n      goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);\n};\n\n\n/**\n * Effeciently set or remove multiple query parameters in a URI. Order of\n * unchanged parameters will not be modified, all updated parameters will be\n * appended to the end of the query. Params with values of null or undefined are\n * removed.\n *\n * @param {string} uri The URI to process.\n * @param {!Object<string, goog.uri.utils.QueryValue>} params A list of\n *     parameters to update. If null or undefined, the param will be removed.\n * @return {string} An updated URI where the query data has been updated with\n *     the params.\n */\ngoog.uri.utils.setParamsFromMap = function(uri, params) {\n  var parts = goog.uri.utils.splitQueryData_(uri);\n  var queryData = parts[1];\n  var buffer = [];\n  if (queryData) {\n    goog.array.forEach(queryData.split('&'), function(pair) {\n      var indexOfEquals = pair.indexOf('=');\n      var name = indexOfEquals >= 0 ? pair.substr(0, indexOfEquals) : pair;\n      if (!params.hasOwnProperty(name)) {\n        buffer.push(pair);\n      }\n    });\n  }\n  parts[1] = goog.uri.utils.appendQueryData_(\n      buffer.join('&'), goog.uri.utils.buildQueryDataFromMap(params));\n  return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Generates a URI path using a given URI and a path with checks to\n * prevent consecutive \"//\". The baseUri passed in must not contain\n * query or fragment identifiers. The path to append may not contain query or\n * fragment identifiers.\n *\n * @param {string} baseUri URI to use as the base.\n * @param {string} path Path to append.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.appendPath = function(baseUri, path) {\n  goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);\n\n  // Remove any trailing '/'\n  if (goog.string.endsWith(baseUri, '/')) {\n    baseUri = baseUri.substr(0, baseUri.length - 1);\n  }\n  // Remove any leading '/'\n  if (goog.string.startsWith(path, '/')) {\n    path = path.substr(1);\n  }\n  return goog.string.buildString(baseUri, '/', path);\n};\n\n\n/**\n * Replaces the path.\n * @param {string} uri URI to use as the base.\n * @param {string} path New path.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.setPath = function(uri, path) {\n  // Add any missing '/'.\n  if (!goog.string.startsWith(path, '/')) {\n    path = '/' + path;\n  }\n  var parts = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      parts[goog.uri.utils.ComponentIndex.SCHEME],\n      parts[goog.uri.utils.ComponentIndex.USER_INFO],\n      parts[goog.uri.utils.ComponentIndex.DOMAIN],\n      parts[goog.uri.utils.ComponentIndex.PORT], path,\n      parts[goog.uri.utils.ComponentIndex.QUERY_DATA],\n      parts[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Standard supported query parameters.\n * @enum {string}\n */\ngoog.uri.utils.StandardQueryParam = {\n\n  /** Unused parameter for unique-ifying. */\n  RANDOM: 'zx'\n};\n\n\n/**\n * Sets the zx parameter of a URI to a random value.\n * @param {string} uri Any URI.\n * @return {string} That URI with the \"zx\" parameter added or replaced to\n *     contain a random string.\n */\ngoog.uri.utils.makeUnique = function(uri) {\n  return goog.uri.utils.setParam(\n      uri, goog.uri.utils.StandardQueryParam.RANDOM,\n      goog.string.getRandomString());\n};\n","// Copyright 2007 Bob Ippolito. All Rights Reserved.\n// Modifications Copyright 2009 The Closure Library Authors. All Rights\n// Reserved.\n\n/**\n * @license Portions of this code are from MochiKit, received by\n * The Closure Authors under the MIT license. All other code is Copyright\n * 2005-2009 The Closure Authors. All Rights Reserved.\n */\n\n/**\n * @fileoverview Classes for tracking asynchronous operations and handling the\n * results. The Deferred object here is patterned after the Deferred object in\n * the Twisted python networking framework.\n *\n * See: http://twistedmatrix.com/projects/core/documentation/howto/defer.html\n *\n * Based on the Dojo code which in turn is based on the MochiKit code.\n *\n */\n\ngoog.provide('goog.async.Deferred');\ngoog.provide('goog.async.Deferred.AlreadyCalledError');\ngoog.provide('goog.async.Deferred.CanceledError');\n\ngoog.require('goog.Promise');\ngoog.require('goog.Thenable');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug.Error');\n\n\n\n/**\n * A Deferred represents the result of an asynchronous operation. A Deferred\n * instance has no result when it is created, and is \"fired\" (given an initial\n * result) by calling `callback` or `errback`.\n *\n * Once fired, the result is passed through a sequence of callback functions\n * registered with `addCallback` or `addErrback`. The functions may\n * mutate the result before it is passed to the next function in the sequence.\n *\n * Callbacks and errbacks may be added at any time, including after the Deferred\n * has been \"fired\". If there are no pending actions in the execution sequence\n * of a fired Deferred, any new callback functions will be called with the last\n * computed result. Adding a callback function is the only way to access the\n * result of the Deferred.\n *\n * If a Deferred operation is canceled, an optional user-provided cancellation\n * function is invoked which may perform any special cleanup, followed by firing\n * the Deferred's errback sequence with a `CanceledError`. If the\n * Deferred has already fired, cancellation is ignored.\n *\n * Deferreds may be templated to a specific type they produce using generics\n * with syntax such as:\n *\n *    /** @type {goog.async.Deferred<string>} *\\\n *    var d = new goog.async.Deferred();\n *    // Compiler can infer that foo is a string.\n *    d.addCallback(function(foo) {...});\n *    d.callback('string');  // Checked to be passed a string\n *\n * Since deferreds are often used to produce different values across a chain,\n * the type information is not propagated across chains, but rather only\n * associated with specifically cast objects.\n *\n * @param {Function=} opt_onCancelFunction A function that will be called if the\n *     Deferred is canceled. If provided, this function runs before the\n *     Deferred is fired with a `CanceledError`.\n * @param {Object=} opt_defaultScope The default object context to call\n *     callbacks and errbacks in.\n * @constructor\n * @implements {goog.Thenable<VALUE>}\n * @template VALUE\n */\ngoog.async.Deferred = function(opt_onCancelFunction, opt_defaultScope) {\n  /**\n   * Entries in the sequence are arrays containing a callback, an errback, and\n   * an optional scope. The callback or errback in an entry may be null.\n   * @type {!Array<!Array>}\n   * @private\n   */\n  this.sequence_ = [];\n\n  /**\n   * Optional function that will be called if the Deferred is canceled.\n   * @type {Function|undefined}\n   * @private\n   */\n  this.onCancelFunction_ = opt_onCancelFunction;\n\n  /**\n   * The default scope to execute callbacks and errbacks in.\n   * @type {Object}\n   * @private\n   */\n  this.defaultScope_ = opt_defaultScope || null;\n\n  /**\n   * Whether the Deferred has been fired.\n   * @type {boolean}\n   * @private\n   */\n  this.fired_ = false;\n\n  /**\n   * Whether the last result in the execution sequence was an error.\n   * @type {boolean}\n   * @private\n   */\n  this.hadError_ = false;\n\n  /**\n   * The current Deferred result, updated as callbacks and errbacks are\n   * executed.\n   * @type {*}\n   * @private\n   */\n  this.result_ = undefined;\n\n  /**\n   * Whether the Deferred is blocked waiting on another Deferred to fire. If a\n   * callback or errback returns a Deferred as a result, the execution sequence\n   * is blocked until that Deferred result becomes available.\n   * @type {boolean}\n   * @private\n   */\n  this.blocked_ = false;\n\n  /**\n   * Whether this Deferred is blocking execution of another Deferred. If this\n   * instance was returned as a result in another Deferred's execution\n   * sequence,that other Deferred becomes blocked until this instance's\n   * execution sequence completes. No additional callbacks may be added to a\n   * Deferred once it is blocking another instance.\n   * @type {boolean}\n   * @private\n   */\n  this.blocking_ = false;\n\n  /**\n   * Whether the Deferred has been canceled without having a custom cancel\n   * function.\n   * @type {boolean}\n   * @private\n   */\n  this.silentlyCanceled_ = false;\n\n  /**\n   * If an error is thrown during Deferred execution with no errback to catch\n   * it, the error is rethrown after a timeout. Reporting the error after a\n   * timeout allows execution to continue in the calling context (empty when\n   * no error is scheduled).\n   * @type {number}\n   * @private\n   */\n  this.unhandledErrorId_ = 0;\n\n  /**\n   * If this Deferred was created by branch(), this will be the \"parent\"\n   * Deferred.\n   * @type {?goog.async.Deferred}\n   * @private\n   */\n  this.parent_ = null;\n\n  /**\n   * The number of Deferred objects that have been branched off this one. This\n   * will be decremented whenever a branch is fired or canceled.\n   * @type {number}\n   * @private\n   */\n  this.branches_ = 0;\n\n  if (goog.async.Deferred.LONG_STACK_TRACES) {\n    /**\n     * Holds the stack trace at time of deferred creation if the JS engine\n     * provides the Error.captureStackTrace API.\n     * @private {?string}\n     */\n    this.constructorStack_ = null;\n    if (Error.captureStackTrace) {\n      var target = { stack: '' };\n      Error.captureStackTrace(target, goog.async.Deferred);\n      // Check if Error.captureStackTrace worked. It fails in gjstest.\n      if (typeof target.stack == 'string') {\n        // Remove first line and force stringify to prevent memory leak due to\n        // holding on to actual stack frames.\n        this.constructorStack_ = target.stack.replace(/^[^\\n]*\\n/, '');\n      }\n    }\n  }\n};\n\n\n/**\n * @define {boolean} Whether unhandled errors should always get rethrown to the\n * global scope. Defaults to false.\n */\ngoog.async.Deferred.STRICT_ERRORS =\n    goog.define('goog.async.Deferred.STRICT_ERRORS', false);\n\n\n/**\n * @define {boolean} Whether to attempt to make stack traces long.  Defaults to\n * false.\n */\ngoog.async.Deferred.LONG_STACK_TRACES =\n    goog.define('goog.async.Deferred.LONG_STACK_TRACES', false);\n\n\n/**\n * Cancels a Deferred that has not yet been fired, or is blocked on another\n * deferred operation. If this Deferred is waiting for a blocking Deferred to\n * fire, the blocking Deferred will also be canceled.\n *\n * If this Deferred was created by calling branch() on a parent Deferred with\n * opt_propagateCancel set to true, the parent may also be canceled. If\n * opt_deepCancel is set, cancel() will be called on the parent (as well as any\n * other ancestors if the parent is also a branch). If one or more branches were\n * created with opt_propagateCancel set to true, the parent will be canceled if\n * cancel() is called on all of those branches.\n *\n * @param {boolean=} opt_deepCancel If true, cancels this Deferred's parent even\n *     if cancel() hasn't been called on some of the parent's branches. Has no\n *     effect on a branch without opt_propagateCancel set to true.\n */\ngoog.async.Deferred.prototype.cancel = function(opt_deepCancel) {\n  if (!this.hasFired()) {\n    if (this.parent_) {\n      // Get rid of the parent reference before potentially running the parent's\n      // canceler function to ensure that this cancellation isn't\n      // double-counted.\n      var parent = this.parent_;\n      delete this.parent_;\n      if (opt_deepCancel) {\n        parent.cancel(opt_deepCancel);\n      } else {\n        parent.branchCancel_();\n      }\n    }\n\n    if (this.onCancelFunction_) {\n      // Call in user-specified scope.\n      this.onCancelFunction_.call(this.defaultScope_, this);\n    } else {\n      this.silentlyCanceled_ = true;\n    }\n    if (!this.hasFired()) {\n      this.errback(new goog.async.Deferred.CanceledError(this));\n    }\n  } else if (this.result_ instanceof goog.async.Deferred) {\n    this.result_.cancel();\n  }\n};\n\n\n/**\n * Handle a single branch being canceled. Once all branches are canceled, this\n * Deferred will be canceled as well.\n *\n * @private\n */\ngoog.async.Deferred.prototype.branchCancel_ = function() {\n  this.branches_--;\n  if (this.branches_ <= 0) {\n    this.cancel();\n  }\n};\n\n\n/**\n * Called after a blocking Deferred fires. Unblocks this Deferred and resumes\n * its execution sequence.\n *\n * @param {boolean} isSuccess Whether the result is a success or an error.\n * @param {*} res The result of the blocking Deferred.\n * @private\n */\ngoog.async.Deferred.prototype.continue_ = function(isSuccess, res) {\n  this.blocked_ = false;\n  this.updateResult_(isSuccess, res);\n};\n\n\n/**\n * Updates the current result based on the success or failure of the last action\n * in the execution sequence.\n *\n * @param {boolean} isSuccess Whether the new result is a success or an error.\n * @param {*} res The result.\n * @private\n */\ngoog.async.Deferred.prototype.updateResult_ = function(isSuccess, res) {\n  this.fired_ = true;\n  this.result_ = res;\n  this.hadError_ = !isSuccess;\n  this.fire_();\n};\n\n\n/**\n * Verifies that the Deferred has not yet been fired.\n *\n * @private\n * @throws {Error} If this has already been fired.\n */\ngoog.async.Deferred.prototype.check_ = function() {\n  if (this.hasFired()) {\n    if (!this.silentlyCanceled_) {\n      throw new goog.async.Deferred.AlreadyCalledError(this);\n    }\n    this.silentlyCanceled_ = false;\n  }\n};\n\n\n/**\n * Fire the execution sequence for this Deferred by passing the starting result\n * to the first registered callback.\n * @param {VALUE=} opt_result The starting result.\n */\ngoog.async.Deferred.prototype.callback = function(opt_result) {\n  this.check_();\n  this.assertNotDeferred_(opt_result);\n  this.updateResult_(true /* isSuccess */, opt_result);\n};\n\n\n/**\n * Fire the execution sequence for this Deferred by passing the starting error\n * result to the first registered errback.\n * @param {*=} opt_result The starting error.\n */\ngoog.async.Deferred.prototype.errback = function(opt_result) {\n  this.check_();\n  this.assertNotDeferred_(opt_result);\n  this.makeStackTraceLong_(opt_result);\n  this.updateResult_(false /* isSuccess */, opt_result);\n};\n\n\n/**\n * Attempt to make the error's stack trace be long in that it contains the\n * stack trace from the point where the deferred was created on top of the\n * current stack trace to give additional context.\n * @param {*} error\n * @private\n * @suppress {missingProperties} error.stack\n */\ngoog.async.Deferred.prototype.makeStackTraceLong_ = function(error) {\n  if (!goog.async.Deferred.LONG_STACK_TRACES) {\n    return;\n  }\n  if (this.constructorStack_ && goog.isObject(error) && error.stack &&\n      // Stack looks like it was system generated. See\n      // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\n      (/^[^\\n]+(\\n   [^\\n]+)+/).test(error.stack)) {\n    error.stack = error.stack + '\\nDEFERRED OPERATION:\\n' +\n        this.constructorStack_;\n  }\n};\n\n\n/**\n * Asserts that an object is not a Deferred.\n * @param {*} obj The object to test.\n * @throws {Error} Throws an exception if the object is a Deferred.\n * @private\n */\ngoog.async.Deferred.prototype.assertNotDeferred_ = function(obj) {\n  goog.asserts.assert(\n      !(obj instanceof goog.async.Deferred),\n      'An execution sequence may not be initiated with a blocking Deferred.');\n};\n\n\n/**\n * Register a callback function to be called with a successful result. If no\n * value is returned by the callback function, the result value is unchanged. If\n * a new value is returned, it becomes the Deferred result and will be passed to\n * the next callback in the execution sequence.\n *\n * If the function throws an error, the error becomes the new result and will be\n * passed to the next errback in the execution chain.\n *\n * If the function returns a Deferred, the execution sequence will be blocked\n * until that Deferred fires. Its result will be passed to the next callback (or\n * errback if it is an error result) in this Deferred's execution sequence.\n *\n * @param {function(this:T,VALUE):?} cb The function to be called with a\n *     successful result.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addCallback = function(cb, opt_scope) {\n  return this.addCallbacks(cb, null, opt_scope);\n};\n\n\n/**\n * Register a callback function to be called with an error result. If no value\n * is returned by the function, the error result is unchanged. If a new error\n * value is returned or thrown, that error becomes the Deferred result and will\n * be passed to the next errback in the execution sequence.\n *\n * If the errback function handles the error by returning a non-error value,\n * that result will be passed to the next normal callback in the sequence.\n *\n * If the function returns a Deferred, the execution sequence will be blocked\n * until that Deferred fires. Its result will be passed to the next callback (or\n * errback if it is an error result) in this Deferred's execution sequence.\n *\n * @param {function(this:T,?):?} eb The function to be called on an\n *     unsuccessful result.\n * @param {T=} opt_scope An optional scope to call the errback in.\n * @return {!goog.async.Deferred<VALUE>} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addErrback = function(eb, opt_scope) {\n  return this.addCallbacks(null, eb, opt_scope);\n};\n\n\n/**\n * Registers one function as both a callback and errback.\n *\n * @param {function(this:T,?):?} f The function to be called on any result.\n * @param {T=} opt_scope An optional scope to call the function in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addBoth = function(f, opt_scope) {\n  return this.addCallbacks(f, f, opt_scope);\n};\n\n\n/**\n * Like addBoth, but propagates uncaught exceptions in the errback.\n *\n * @param {function(this:T,?):?} f The function to be called on any result.\n * @param {T=} opt_scope An optional scope to call the function in.\n * @return {!goog.async.Deferred<VALUE>} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addFinally = function(f, opt_scope) {\n  return this.addCallbacks(f, function(err) {\n    var result = f.call(/** @type {?} */ (this), err);\n    if (result === undefined) {\n      throw err;\n    }\n    return result;\n  }, opt_scope);\n};\n\n\n/**\n * Registers a callback function and an errback function at the same position\n * in the execution sequence. Only one of these functions will execute,\n * depending on the error state during the execution sequence.\n *\n * NOTE: This is not equivalent to {@code def.addCallback().addErrback()}! If\n * the callback is invoked, the errback will be skipped, and vice versa.\n *\n * @param {?(function(this:T,VALUE):?)} cb The function to be called on a\n *     successful result.\n * @param {?(function(this:T,?):?)} eb The function to be called on an\n *     unsuccessful result.\n * @param {T=} opt_scope An optional scope to call the functions in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addCallbacks = function(cb, eb, opt_scope) {\n  goog.asserts.assert(!this.blocking_, 'Blocking Deferreds can not be re-used');\n  this.sequence_.push([cb, eb, opt_scope]);\n  if (this.hasFired()) {\n    this.fire_();\n  }\n  return this;\n};\n\n\n/**\n * Implements {@see goog.Thenable} for seamless integration with\n * {@see goog.Promise}.\n * Deferred results are mutable and may represent multiple values over\n * their lifetime. Calling `then` on a Deferred returns a Promise\n * with the result of the Deferred at that point in its callback chain.\n * Note that if the Deferred result is never mutated, and only\n * `then` calls are made, the Deferred will behave like a Promise.\n *\n * @override\n */\ngoog.async.Deferred.prototype.then = function(opt_onFulfilled, opt_onRejected,\n    opt_context) {\n  var resolve, reject;\n  var promise = new goog.Promise(function(res, rej) {\n    // Copying resolvers to outer scope, so that they are available when the\n    // deferred callback fires (which may be synchronous).\n    resolve = res;\n    reject = rej;\n  });\n  this.addCallbacks(resolve, function(reason) {\n    if (reason instanceof goog.async.Deferred.CanceledError) {\n      promise.cancel();\n    } else {\n      reject(reason);\n    }\n  });\n  return promise.then(opt_onFulfilled, opt_onRejected, opt_context);\n};\ngoog.Thenable.addImplementation(goog.async.Deferred);\n\n\n/**\n * Links another Deferred to the end of this Deferred's execution sequence. The\n * result of this execution sequence will be passed as the starting result for\n * the chained Deferred, invoking either its first callback or errback.\n *\n * @param {!goog.async.Deferred} otherDeferred The Deferred to chain.\n * @return {!goog.async.Deferred} This Deferred.\n */\ngoog.async.Deferred.prototype.chainDeferred = function(otherDeferred) {\n  this.addCallbacks(\n      otherDeferred.callback, otherDeferred.errback, otherDeferred);\n  return this;\n};\n\n\n/**\n * Makes this Deferred wait for another Deferred's execution sequence to\n * complete before continuing.\n *\n * This is equivalent to adding a callback that returns `otherDeferred`,\n * but doesn't prevent additional callbacks from being added to\n * `otherDeferred`.\n *\n * @param {!goog.async.Deferred|!goog.Thenable} otherDeferred The Deferred\n *     to wait for.\n * @return {!goog.async.Deferred} This Deferred.\n */\ngoog.async.Deferred.prototype.awaitDeferred = function(otherDeferred) {\n  if (!(otherDeferred instanceof goog.async.Deferred)) {\n    // The Thenable case.\n    return this.addCallback(function() {\n      return otherDeferred;\n    });\n  }\n  return this.addCallback(goog.bind(otherDeferred.branch, otherDeferred));\n};\n\n\n/**\n * Creates a branch off this Deferred's execution sequence, and returns it as a\n * new Deferred. The branched Deferred's starting result will be shared with the\n * parent at the point of the branch, even if further callbacks are added to the\n * parent.\n *\n * All branches at the same stage in the execution sequence will receive the\n * same starting value.\n *\n * @param {boolean=} opt_propagateCancel If cancel() is called on every child\n *     branch created with opt_propagateCancel, the parent will be canceled as\n *     well.\n * @return {!goog.async.Deferred<VALUE>} A Deferred that will be started with\n *     the computed result from this stage in the execution sequence.\n */\ngoog.async.Deferred.prototype.branch = function(opt_propagateCancel) {\n  var d = new goog.async.Deferred();\n  this.chainDeferred(d);\n  if (opt_propagateCancel) {\n    d.parent_ = this;\n    this.branches_++;\n  }\n  return d;\n};\n\n\n/**\n * @return {boolean} Whether the execution sequence has been started on this\n *     Deferred by invoking `callback` or `errback`.\n */\ngoog.async.Deferred.prototype.hasFired = function() {\n  return this.fired_;\n};\n\n\n/**\n * @param {*} res The latest result in the execution sequence.\n * @return {boolean} Whether the current result is an error that should cause\n *     the next errback to fire. May be overridden by subclasses to handle\n *     special error types.\n * @protected\n */\ngoog.async.Deferred.prototype.isError = function(res) {\n  return res instanceof Error;\n};\n\n\n/**\n * @return {boolean} Whether an errback exists in the remaining sequence.\n * @private\n */\ngoog.async.Deferred.prototype.hasErrback_ = function() {\n  return goog.array.some(this.sequence_, function(sequenceRow) {\n    // The errback is the second element in the array.\n    return goog.isFunction(sequenceRow[1]);\n  });\n};\n\n\n/**\n * Exhausts the execution sequence while a result is available. The result may\n * be modified by callbacks or errbacks, and execution will block if the\n * returned result is an incomplete Deferred.\n *\n * @private\n */\ngoog.async.Deferred.prototype.fire_ = function() {\n  if (this.unhandledErrorId_ && this.hasFired() && this.hasErrback_()) {\n    // It is possible to add errbacks after the Deferred has fired. If a new\n    // errback is added immediately after the Deferred encountered an unhandled\n    // error, but before that error is rethrown, the error is unscheduled.\n    goog.async.Deferred.unscheduleError_(this.unhandledErrorId_);\n    this.unhandledErrorId_ = 0;\n  }\n\n  if (this.parent_) {\n    this.parent_.branches_--;\n    delete this.parent_;\n  }\n\n  var res = this.result_;\n  var unhandledException = false;\n  var isNewlyBlocked = false;\n\n  while (this.sequence_.length && !this.blocked_) {\n    var sequenceEntry = this.sequence_.shift();\n\n    var callback = sequenceEntry[0];\n    var errback = sequenceEntry[1];\n    var scope = sequenceEntry[2];\n\n    var f = this.hadError_ ? errback : callback;\n    if (f) {\n\n      try {\n        var ret = f.call(scope || this.defaultScope_, res);\n\n        // If no result, then use previous result.\n        if (ret !== undefined) {\n          // Bubble up the error as long as the return value hasn't changed.\n          this.hadError_ = this.hadError_ && (ret == res || this.isError(ret));\n          this.result_ = res = ret;\n        }\n\n        if (goog.Thenable.isImplementedBy(res) ||\n            (typeof goog.global['Promise'] === 'function' &&\n            res instanceof goog.global['Promise'])) {\n          isNewlyBlocked = true;\n          this.blocked_ = true;\n        }\n\n      } catch (ex) {\n        res = ex;\n        this.hadError_ = true;\n        this.makeStackTraceLong_(res);\n\n        if (!this.hasErrback_()) {\n          // If an error is thrown with no additional errbacks in the queue,\n          // prepare to rethrow the error.\n          unhandledException = true;\n        }\n      }\n    }\n  }\n\n  this.result_ = res;\n\n  if (isNewlyBlocked) {\n    var onCallback = goog.bind(this.continue_, this, true /* isSuccess */);\n    var onErrback = goog.bind(this.continue_, this, false /* isSuccess */);\n\n    if (res instanceof goog.async.Deferred) {\n      res.addCallbacks(onCallback, onErrback);\n      res.blocking_ = true;\n    } else {\n      /** @type {!IThenable} */ (res).then(onCallback, onErrback);\n    }\n  } else if (goog.async.Deferred.STRICT_ERRORS && this.isError(res) &&\n      !(res instanceof goog.async.Deferred.CanceledError)) {\n    this.hadError_ = true;\n    unhandledException = true;\n  }\n\n  if (unhandledException) {\n    // Rethrow the unhandled error after a timeout. Execution will continue, but\n    // the error will be seen by global handlers and the user. The throw will\n    // be canceled if another errback is appended before the timeout executes.\n    // The error's original stack trace is preserved where available.\n    this.unhandledErrorId_ = goog.async.Deferred.scheduleError_(res);\n  }\n};\n\n\n/**\n * Creates a Deferred that has an initial result.\n *\n * @param {*=} opt_result The result.\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.succeed = function(opt_result) {\n  var d = new goog.async.Deferred();\n  d.callback(opt_result);\n  return d;\n};\n\n\n/**\n * Creates a Deferred that fires when the given promise resolves.\n * Use only during migration to Promises.\n *\n * Note: If the promise resolves to a thenable value (which is not allowed by\n * conforming promise implementations), then the deferred may behave\n * unexpectedly as it tries to wait on it. This should not be a risk when using\n * goog.Promise, goog.async.Deferred, or native Promise objects.\n *\n * @param {!IThenable<T>} promise\n * @return {!goog.async.Deferred<T>} The new Deferred.\n * @template T\n */\ngoog.async.Deferred.fromPromise = function(promise) {\n  var d = new goog.async.Deferred();\n  promise.then(\n      function(value) {\n        d.callback(value);\n      },\n      function(error) {\n        d.errback(error);\n      });\n  return d;\n};\n\n\n/**\n * Creates a Deferred that has an initial error result.\n *\n * @param {*} res The error result.\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.fail = function(res) {\n  var d = new goog.async.Deferred();\n  d.errback(res);\n  return d;\n};\n\n\n/**\n * Creates a Deferred that has already been canceled.\n *\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.canceled = function() {\n  var d = new goog.async.Deferred();\n  d.cancel();\n  return d;\n};\n\n\n/**\n * Normalizes values that may or may not be Deferreds.\n *\n * If the input value is a Deferred, the Deferred is branched (so the original\n * execution sequence is not modified) and the input callback added to the new\n * branch. The branch is returned to the caller.\n *\n * If the input value is not a Deferred, the callback will be executed\n * immediately and an already firing Deferred will be returned to the caller.\n *\n * In the following (contrived) example, if <code>isImmediate</code> is true\n * then 3 is alerted immediately, otherwise 6 is alerted after a 2-second delay.\n *\n * <pre>\n * var value;\n * if (isImmediate) {\n *   value = 3;\n * } else {\n *   value = new goog.async.Deferred();\n *   setTimeout(function() { value.callback(6); }, 2000);\n * }\n *\n * var d = goog.async.Deferred.when(value, alert);\n * </pre>\n *\n * @param {*} value Deferred or normal value to pass to the callback.\n * @param {function(this:T, ?):?} callback The callback to execute.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @return {!goog.async.Deferred} A new Deferred that will call the input\n *     callback with the input value.\n * @template T\n */\ngoog.async.Deferred.when = function(value, callback, opt_scope) {\n  if (value instanceof goog.async.Deferred) {\n    return value.branch(true).addCallback(callback, opt_scope);\n  } else {\n    return goog.async.Deferred.succeed(value).addCallback(callback, opt_scope);\n  }\n};\n\n\n\n/**\n * An error sub class that is used when a Deferred has already been called.\n * @param {!goog.async.Deferred} deferred The Deferred.\n *\n * @constructor\n * @extends {goog.debug.Error}\n */\ngoog.async.Deferred.AlreadyCalledError = function(deferred) {\n  goog.debug.Error.call(this);\n\n  /**\n   * The Deferred that raised this error.\n   * @type {goog.async.Deferred}\n   */\n  this.deferred = deferred;\n};\ngoog.inherits(goog.async.Deferred.AlreadyCalledError, goog.debug.Error);\n\n\n/** @override */\ngoog.async.Deferred.AlreadyCalledError.prototype.message =\n    'Deferred has already fired';\n\n\n/** @override */\ngoog.async.Deferred.AlreadyCalledError.prototype.name = 'AlreadyCalledError';\n\n\n\n/**\n * An error sub class that is used when a Deferred is canceled.\n *\n * @param {!goog.async.Deferred} deferred The Deferred object.\n * @constructor\n * @extends {goog.debug.Error}\n */\ngoog.async.Deferred.CanceledError = function(deferred) {\n  goog.debug.Error.call(this);\n\n  /**\n   * The Deferred that raised this error.\n   * @type {goog.async.Deferred}\n   */\n  this.deferred = deferred;\n};\ngoog.inherits(goog.async.Deferred.CanceledError, goog.debug.Error);\n\n\n/** @override */\ngoog.async.Deferred.CanceledError.prototype.message = 'Deferred was canceled';\n\n\n/** @override */\ngoog.async.Deferred.CanceledError.prototype.name = 'CanceledError';\n\n\n\n/**\n * Wrapper around errors that are scheduled to be thrown by failing deferreds\n * after a timeout.\n *\n * @param {*} error Error from a failing deferred.\n * @constructor\n * @final\n * @private\n * @struct\n */\ngoog.async.Deferred.Error_ = function(error) {\n  /** @const @private {number} */\n  this.id_ = goog.global.setTimeout(goog.bind(this.throwError, this), 0);\n\n  /** @const @private {*} */\n  this.error_ = error;\n};\n\n\n/**\n * Actually throws the error and removes it from the list of pending\n * deferred errors.\n */\ngoog.async.Deferred.Error_.prototype.throwError = function() {\n  goog.asserts.assert(goog.async.Deferred.errorMap_[this.id_],\n      'Cannot throw an error that is not scheduled.');\n  delete goog.async.Deferred.errorMap_[this.id_];\n  throw this.error_;\n};\n\n\n/**\n * Resets the error throw timer.\n */\ngoog.async.Deferred.Error_.prototype.resetTimer = function() {\n  goog.global.clearTimeout(this.id_);\n};\n\n\n/**\n * Map of unhandled errors scheduled to be rethrown in a future timestep.\n * @private {!Object<(number|string), goog.async.Deferred.Error_>}\n */\ngoog.async.Deferred.errorMap_ = {};\n\n\n/**\n * Schedules an error to be thrown after a delay.\n * @param {*} error Error from a failing deferred.\n * @return {number} Id of the error.\n * @private\n */\ngoog.async.Deferred.scheduleError_ = function(error) {\n  var deferredError = new goog.async.Deferred.Error_(error);\n  goog.async.Deferred.errorMap_[deferredError.id_] = deferredError;\n  return deferredError.id_;\n};\n\n\n/**\n * Unschedules an error from being thrown.\n * @param {number} id Id of the deferred error to unschedule.\n * @private\n */\ngoog.async.Deferred.unscheduleError_ = function(id) {\n  var error = goog.async.Deferred.errorMap_[id];\n  if (error) {\n    error.resetTimer();\n    delete goog.async.Deferred.errorMap_[id];\n  }\n};\n\n\n/**\n * Asserts that there are no pending deferred errors. If there are any\n * scheduled errors, one will be thrown immediately to make this function fail.\n */\ngoog.async.Deferred.assertNoErrors = function() {\n  var map = goog.async.Deferred.errorMap_;\n  for (var key in map) {\n    var error = map[key];\n    error.resetTimer();\n    error.throwError();\n  }\n};\n","// Copyright 2011 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF 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 A utility to load JavaScript files via DOM script tags.\n * Refactored from goog.net.Jsonp. Works cross-domain.\n */\n\ngoog.provide('goog.net.jsloader');\ngoog.provide('goog.net.jsloader.Error');\ngoog.provide('goog.net.jsloader.ErrorCode');\ngoog.provide('goog.net.jsloader.Options');\n\ngoog.require('goog.array');\ngoog.require('goog.async.Deferred');\ngoog.require('goog.debug.Error');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.object');\n\n\n/**\n * The name of the property of goog.global under which the JavaScript\n * verification object is stored by the loaded script.\n * @private {string}\n */\ngoog.net.jsloader.GLOBAL_VERIFY_OBJS_ = 'closure_verification';\n\n\n/**\n * The default length of time, in milliseconds, we are prepared to wait for a\n * load request to complete.\n * @type {number}\n */\ngoog.net.jsloader.DEFAULT_TIMEOUT = 5000;\n\n\n/**\n * Optional parameters for goog.net.jsloader.send.\n * timeout: The length of time, in milliseconds, we are prepared to wait\n *     for a load request to complete, or 0 or negative for no timeout. Default\n *     is 5 seconds.\n * document: The HTML document under which to load the JavaScript. Default is\n *     the current document.\n * cleanupWhenDone: If true clean up the script tag after script completes to\n *     load. This is important if you just want to read data from the JavaScript\n *     and then throw it away. Default is false.\n * attributes: Additional attributes to set on the script tag.\n *\n * @typedef {{\n *   timeout: (number|undefined),\n *   document: (HTMLDocument|undefined),\n *   cleanupWhenDone: (boolean|undefined),\n *   attributes: (!Object<string, string>|undefined)\n * }}\n */\ngoog.net.jsloader.Options;\n\n\n/**\n * Scripts (URIs) waiting to be loaded.\n * @private {!Array<!goog.html.TrustedResourceUrl>}\n */\ngoog.net.jsloader.scriptsToLoad_ = [];\n\n\n/**\n * The deferred result of loading the URIs in scriptsToLoad_.\n * We need to return this to a caller that wants to load URIs while\n * a deferred is already working on them.\n * @private {!goog.async.Deferred<null>}\n */\ngoog.net.jsloader.scriptLoadingDeferred_;\n\n\n\n/**\n * Loads and evaluates the JavaScript files at the specified URIs, guaranteeing\n * the order of script loads.\n *\n * Because we have to load the scripts in serial (load script 1, exec script 1,\n * load script 2, exec script 2, and so on), this will be slower than doing\n * the network fetches in parallel.\n *\n * If you need to load a large number of scripts but dependency order doesn't\n * matter, you should just call goog.net.jsloader.safeLoad N times.\n *\n * If you need to load a large number of scripts on the same domain,\n * you may want to use goog.module.ModuleLoader.\n *\n * @param {Array<!goog.html.TrustedResourceUrl>} trustedUris The URIs to load.\n * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See\n *     goog.net.jsloader.options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n *     callbacks\n */\ngoog.net.jsloader.safeLoadMany = function(trustedUris, opt_options) {\n  // Loading the scripts in serial introduces asynchronosity into the flow.\n  // Therefore, there are race conditions where client A can kick off the load\n  // sequence for client B, even though client A's scripts haven't all been\n  // loaded yet.\n  //\n  // To work around this issue, all module loads share a queue.\n  if (!trustedUris.length) {\n    return goog.async.Deferred.succeed(null);\n  }\n\n  var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;\n  goog.array.extend(goog.net.jsloader.scriptsToLoad_, trustedUris);\n  if (isAnotherModuleLoading) {\n    // jsloader is still loading some other scripts.\n    // In order to prevent the race condition noted above, we just add\n    // these URIs to the end of the scripts' queue and return the deferred\n    // result of the ongoing script load, so the caller knows when they\n    // finish loading.\n    return goog.net.jsloader.scriptLoadingDeferred_;\n  }\n\n  trustedUris = goog.net.jsloader.scriptsToLoad_;\n  var popAndLoadNextScript = function() {\n    var trustedUri = trustedUris.shift();\n    var deferred = goog.net.jsloader.safeLoad(trustedUri, opt_options);\n    if (trustedUris.length) {\n      deferred.addBoth(popAndLoadNextScript);\n    }\n    return deferred;\n  };\n  goog.net.jsloader.scriptLoadingDeferred_ = popAndLoadNextScript();\n  return goog.net.jsloader.scriptLoadingDeferred_;\n};\n\n\n/**\n * Loads and evaluates a JavaScript file.\n * When the script loads, a user callback is called.\n * It is the client's responsibility to verify that the script ran successfully.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedUri The URI of the JavaScript.\n * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See\n *     goog.net.jsloader.Options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n *     callbacks and/or cancel the transmission.\n *     The error callback will be called with a single goog.net.jsloader.Error\n *     parameter.\n */\ngoog.net.jsloader.safeLoad = function(trustedUri, opt_options) {\n  var options = opt_options || {};\n  var doc = options.document || document;\n  var uri = goog.html.TrustedResourceUrl.unwrap(trustedUri);\n\n  var script = goog.dom.createElement(goog.dom.TagName.SCRIPT);\n  var request = {script_: script, timeout_: undefined};\n  var deferred = new goog.async.Deferred(goog.net.jsloader.cancel_, request);\n\n  // Set a timeout.\n  var timeout = null;\n  var timeoutDuration = (options.timeout != null) ?\n      options.timeout :\n      goog.net.jsloader.DEFAULT_TIMEOUT;\n  if (timeoutDuration > 0) {\n    timeout = window.setTimeout(function() {\n      goog.net.jsloader.cleanup_(script, true);\n      deferred.errback(\n          new goog.net.jsloader.Error(\n              goog.net.jsloader.ErrorCode.TIMEOUT,\n              'Timeout reached for loading script ' + uri));\n    }, timeoutDuration);\n    request.timeout_ = timeout;\n  }\n\n  // Hang the user callback to be called when the script completes to load.\n  // NOTE(user): This callback will be called in IE even upon error. In any\n  // case it is the client's responsibility to verify that the script ran\n  // successfully.\n  script.onload = script.onreadystatechange = function() {\n    if (!script.readyState || script.readyState == 'loaded' ||\n        script.readyState == 'complete') {\n      var removeScriptNode = options.cleanupWhenDone || false;\n      goog.net.jsloader.cleanup_(script, removeScriptNode, timeout);\n      deferred.callback(null);\n    }\n  };\n\n  // Add an error callback.\n  // NOTE(user): Not supported in IE.\n  script.onerror = function() {\n    goog.net.jsloader.cleanup_(script, true, timeout);\n    deferred.errback(\n        new goog.net.jsloader.Error(\n            goog.net.jsloader.ErrorCode.LOAD_ERROR,\n            'Error while loading script ' + uri));\n  };\n\n  var properties = options.attributes || {};\n  goog.object.extend(\n      properties, {'type': 'text/javascript', 'charset': 'UTF-8'});\n  goog.dom.setProperties(script, properties);\n  // NOTE(user): Safari never loads the script if we don't set the src\n  // attribute before appending.\n  goog.dom.safe.setScriptSrc(script, trustedUri);\n  var scriptParent = goog.net.jsloader.getScriptParentElement_(doc);\n  scriptParent.appendChild(script);\n\n  return deferred;\n};\n\n\n/**\n * Loads a JavaScript file and verifies it was evaluated successfully, using a\n * verification object.\n * The verification object is set by the loaded JavaScript at the end of the\n * script.\n * We verify this object was set and return its value in the success callback.\n * If the object is not defined we trigger an error callback.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedUri The URI of the JavaScript.\n * @param {string} verificationObjName The name of the verification object that\n *     the loaded script should set.\n * @param {goog.net.jsloader.Options} options Optional parameters. See\n *     goog.net.jsloader.Options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n *     callbacks and/or cancel the transmission.\n *     The success callback will be called with a single parameter containing\n *     the value of the verification object.\n *     The error callback will be called with a single goog.net.jsloader.Error\n *     parameter.\n */\ngoog.net.jsloader.safeLoadAndVerify = function(\n    trustedUri, verificationObjName, options) {\n  // Define the global objects variable.\n  if (!goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]) {\n    goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_] = {};\n  }\n  var verifyObjs = goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_];\n  var uri = goog.html.TrustedResourceUrl.unwrap(trustedUri);\n\n  // Verify that the expected object does not exist yet.\n  if (verifyObjs[verificationObjName] !== undefined) {\n    // TODO(user): Error or reset variable?\n    return goog.async.Deferred.fail(\n        new goog.net.jsloader.Error(\n            goog.net.jsloader.ErrorCode.VERIFY_OBJECT_ALREADY_EXISTS,\n            'Verification object ' + verificationObjName +\n                ' already defined.'));\n  }\n\n  // Send request to load the JavaScript.\n  var sendDeferred = goog.net.jsloader.safeLoad(trustedUri, options);\n\n  // Create a deferred object wrapping the send result.\n  var deferred =\n      new goog.async.Deferred(goog.bind(sendDeferred.cancel, sendDeferred));\n\n  // Call user back with object that was set by the script.\n  sendDeferred.addCallback(function() {\n    var result = verifyObjs[verificationObjName];\n    if (result !== undefined) {\n      deferred.callback(result);\n      delete verifyObjs[verificationObjName];\n    } else {\n      // Error: script was not loaded properly.\n      deferred.errback(\n          new goog.net.jsloader.Error(\n              goog.net.jsloader.ErrorCode.VERIFY_ERROR, 'Script ' + uri +\n                  ' loaded, but verification object ' + verificationObjName +\n                  ' was not defined.'));\n    }\n  });\n\n  // Pass error to new deferred object.\n  sendDeferred.addErrback(function(error) {\n    if (verifyObjs[verificationObjName] !== undefined) {\n      delete verifyObjs[verificationObjName];\n    }\n    deferred.errback(error);\n  });\n\n  return deferred;\n};\n\n\n/**\n * Gets the DOM element under which we should add new script elements.\n * How? Take the first head element, and if not found take doc.documentElement,\n * which always exists.\n *\n * @param {!HTMLDocument} doc The relevant document.\n * @return {!Element} The script parent element.\n * @private\n */\ngoog.net.jsloader.getScriptParentElement_ = function(doc) {\n  var headElements = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD, doc);\n  if (!headElements || goog.array.isEmpty(headElements)) {\n    return doc.documentElement;\n  } else {\n    return headElements[0];\n  }\n};\n\n\n/**\n * Cancels a given request.\n * @this {{script_: Element, timeout_: number}} The request context.\n * @private\n */\ngoog.net.jsloader.cancel_ = function() {\n  var request = this;\n  if (request && request.script_) {\n    var scriptNode = request.script_;\n    if (scriptNode && scriptNode.tagName == goog.dom.TagName.SCRIPT) {\n      goog.net.jsloader.cleanup_(scriptNode, true, request.timeout_);\n    }\n  }\n};\n\n\n/**\n * Removes the script node and the timeout.\n * @param {Node} scriptNode The node to be cleaned up.\n * @param {boolean} removeScriptNode If true completely remove the script node.\n * @param {?number=} opt_timeout The timeout handler to cleanup.\n * @private\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\ngoog.net.jsloader.cleanup_ = function(\n    scriptNode, removeScriptNode, opt_timeout) {\n  if (opt_timeout != null) {\n    goog.global.clearTimeout(opt_timeout);\n  }\n\n  scriptNode.onload = goog.nullFunction;\n  scriptNode.onerror = goog.nullFunction;\n  scriptNode.onreadystatechange = goog.nullFunction;\n\n  // Do this after a delay (removing the script node of a running script can\n  // confuse older IEs).\n  if (removeScriptNode) {\n    window.setTimeout(function() { goog.dom.removeNode(scriptNode); }, 0);\n  }\n};\n\n\n/**\n * Possible error codes for jsloader.\n * @enum {number}\n */\ngoog.net.jsloader.ErrorCode = {\n  LOAD_ERROR: 0,\n  TIMEOUT: 1,\n  VERIFY_ERROR: 2,\n  VERIFY_OBJECT_ALREADY_EXISTS: 3,\n};\n\n\n\n/**\n * A jsloader error.\n *\n * @param {goog.net.jsloader.ErrorCode} code The error code.\n * @param {string=} opt_message Additional message.\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.net.jsloader.Error = function(code, opt_message) {\n  var msg = 'Jsloader error (code #' + code + ')';\n  if (opt_message) {\n    msg += ': ' + opt_message;\n  }\n  goog.net.jsloader.Error.base(this, 'constructor', msg);\n\n  /**\n   * The code for this error.\n   *\n   * @type {goog.net.jsloader.ErrorCode}\n   */\n  this.code = code;\n};\ngoog.inherits(goog.net.jsloader.Error, goog.debug.Error);\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Utility for handling RPC requests to server.\n */\ngoog.provide('fireauth.RpcHandler');\ngoog.provide('fireauth.RpcHandler.ApiMethodHandler');\ngoog.provide('fireauth.RpcHandler.VerifyAssertionData');\ngoog.provide('fireauth.XmlHttpFactory');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthErrorWithCredential');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.idp.ProviderId');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Uri');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.json');\ngoog.require('goog.net.CorsXmlHttpFactory');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.FetchXmlHttpFactory');\ngoog.require('goog.net.XhrIo');\ngoog.require('goog.net.XmlHttpFactory');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.object');\ngoog.require('goog.string.Const');\n\n\n\n/**\n * Firebase Auth XmlHttpRequest factory. This is useful for environments like\n * Node.js where XMLHttpRequest does not exist. XmlHttpFactory would be\n * initialized using the polyfill XMLHttpRequest module.\n * @param {function(new:XMLHttpRequest)} xmlHttpRequest The xmlHttpRequest\n *     constructor.\n * @constructor\n * @extends {goog.net.XmlHttpFactory}\n * @final\n */\nfireauth.XmlHttpFactory = function(xmlHttpRequest) {\n  /**\n   * @private {function(new:XMLHttpRequest)} The underlying XHR reference.\n   */\n  this.xmlHttpRequest_ = xmlHttpRequest;\n  fireauth.XmlHttpFactory.base(this, 'constructor');\n};\ngoog.inherits(fireauth.XmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/**\n * @return {!goog.net.XhrLike|!XMLHttpRequest} A new XhrLike instance.\n * @override\n */\nfireauth.XmlHttpFactory.prototype.createInstance = function() {\n  return new this.xmlHttpRequest_();\n};\n\n\n/**\n * @return {!Object} Options describing how XHR objects obtained from this\n *     factory should be used.\n * @override\n */\nfireauth.XmlHttpFactory.prototype.internalGetOptions = function() {\n  return {};\n};\n\n\n\n/**\n * Creates an RPC request handler for the project specified by the API key.\n *\n * @param {string} apiKey The API key.\n * @param {?Object=} opt_config The RPC request processor configuration.\n * @param {?string=} opt_firebaseClientVersion The optional Firebase client\n *     version to log with requests to Firebase Auth server.\n * @constructor\n */\nfireauth.RpcHandler = function(apiKey, opt_config, opt_firebaseClientVersion) {\n  /** @private {string} The project API key. */\n  this.apiKey_ = apiKey;\n  var config = opt_config || {};\n  this.secureTokenEndpoint_ = config['secureTokenEndpoint'] ||\n      fireauth.RpcHandler.SECURE_TOKEN_ENDPOINT_;\n  /**\n   * @private @const {!fireauth.util.Delay} The delay for secure token endpoint\n   *     network timeout.\n   */\n  this.secureTokenTimeout_ = config['secureTokenTimeout'] ||\n      fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_TIMEOUT_;\n  /** @private @const {!Object} The secure token server headers. */\n  this.secureTokenHeaders_ = goog.object.clone(\n      config['secureTokenHeaders'] ||\n      fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_HEADERS_);\n  /** @private @const {string} The Firebase Auth endpoint. */\n  this.firebaseEndpoint_ = config['firebaseEndpoint'] ||\n      fireauth.RpcHandler.FIREBASE_ENDPOINT_;\n  /** @private @const {string} The identity platform endpoint. */\n  this.identityPlatformEndpoint_ = config['identityPlatformEndpoint'] ||\n      fireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_;\n  /**\n   * @private @const {!fireauth.util.Delay} The delay for Firebase Auth endpoint\n   *     network timeout.\n   */\n  this.firebaseTimeout_ = config['firebaseTimeout'] ||\n      fireauth.RpcHandler.DEFAULT_FIREBASE_TIMEOUT_;\n  this.firebaseHeaders_ = goog.object.clone(\n      config['firebaseHeaders'] ||\n      fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_);\n  // If Firebase client version needs to be logged too.\n  if (opt_firebaseClientVersion) {\n    // Log client version for Firebase Auth server.\n    this.firebaseHeaders_['X-Client-Version'] = opt_firebaseClientVersion;\n    // Log client version for securetoken server.\n    this.secureTokenHeaders_['X-Client-Version'] = opt_firebaseClientVersion;\n  }\n\n  // Get XMLHttpRequest reference.\n  var XMLHttpRequest = fireauth.RpcHandler.getXMLHttpRequest();\n  if (!XMLHttpRequest && !fireauth.util.isWorker()) {\n    // In a Node.js environment, xmlhttprequest module needs to be required.\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n        'The XMLHttpRequest compatibility library was not found.');\n  }\n  /** @private {!goog.net.XmlHttpFactory|undefined} The XHR factory. */\n  this.rpcHandlerXhrFactory_ = undefined;\n  // Initialize XHR factory. CORS does not apply in native environments or\n  // workers so don't use CorsXmlHttpFactory in those cases.\n  if (fireauth.util.isWorker()) {\n    // For worker environment use FetchXmlHttpFactory.\n    this.rpcHandlerXhrFactory_ = new goog.net.FetchXmlHttpFactory(\n        /** @type {!WorkerGlobalScope} */ (self));\n  } else if (fireauth.util.isNativeEnvironment()) {\n    // For Node.js, this is the polyfill library. For other environments,\n    // this is the native global XMLHttpRequest.\n    this.rpcHandlerXhrFactory_ = new fireauth.XmlHttpFactory(\n        /** @type {function(new:XMLHttpRequest)} */ (XMLHttpRequest));\n  } else {\n    // CORS Browser environment.\n    this.rpcHandlerXhrFactory_ = new goog.net.CorsXmlHttpFactory();\n  }\n  /** @private {?string} The tenant ID. */\n  this.tenantId_ = null;\n};\n\n\n/**\n * @return {?function(new:XMLHttpRequest)|undefined} The current environment\n *     XMLHttpRequest. This is undefined for worker environment.\n */\nfireauth.RpcHandler.getXMLHttpRequest = function() {\n  // In Node.js XMLHttpRequest is polyfilled.\n  var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n  var XMLHttpRequest = goog.global['XMLHttpRequest'] ||\n      (isNode &&\n       firebase.INTERNAL['node'] &&\n       firebase.INTERNAL['node']['XMLHttpRequest']);\n  return XMLHttpRequest;\n};\n\n\n/**\n * Enums for HTTP request methods.\n * @enum {string}\n */\nfireauth.RpcHandler.HttpMethod = {\n  POST: 'POST',\n  GET: 'GET'\n};\n\n\n/**\n * Firebase Auth server error codes.\n * @enum {string}\n */\nfireauth.RpcHandler.ServerError = {\n  ADMIN_ONLY_OPERATION: 'ADMIN_ONLY_OPERATION',\n  CAPTCHA_CHECK_FAILED: 'CAPTCHA_CHECK_FAILED',\n  CORS_UNSUPPORTED: 'CORS_UNSUPPORTED',\n  CREDENTIAL_MISMATCH: 'CREDENTIAL_MISMATCH',\n  CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'CREDENTIAL_TOO_OLD_LOGIN_AGAIN',\n  DYNAMIC_LINK_NOT_ACTIVATED: 'DYNAMIC_LINK_NOT_ACTIVATED',\n  EMAIL_CHANGE_NEEDS_VERIFICATION: 'EMAIL_CHANGE_NEEDS_VERIFICATION',\n  EMAIL_EXISTS: 'EMAIL_EXISTS',\n  EMAIL_NOT_FOUND: 'EMAIL_NOT_FOUND',\n  EXPIRED_OOB_CODE: 'EXPIRED_OOB_CODE',\n  FEDERATED_USER_ID_ALREADY_LINKED: 'FEDERATED_USER_ID_ALREADY_LINKED',\n  INVALID_APP_CREDENTIAL: 'INVALID_APP_CREDENTIAL',\n  INVALID_APP_ID: 'INVALID_APP_ID',\n  INVALID_CERT_HASH: 'INVALID_CERT_HASH',\n  INVALID_CODE: 'INVALID_CODE',\n  INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',\n  INVALID_CUSTOM_TOKEN: 'INVALID_CUSTOM_TOKEN',\n  INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',\n  INVALID_EMAIL: 'INVALID_EMAIL',\n  INVALID_ID_TOKEN: 'INVALID_ID_TOKEN',\n  INVALID_IDP_RESPONSE: 'INVALID_IDP_RESPONSE',\n  INVALID_IDENTIFIER: 'INVALID_IDENTIFIER',\n  INVALID_MESSAGE_PAYLOAD: 'INVALID_MESSAGE_PAYLOAD',\n  INVALID_MFA_PENDING_CREDENTIAL: 'INVALID_MFA_PENDING_CREDENTIAL',\n  INVALID_OAUTH_CLIENT_ID: 'INVALID_OAUTH_CLIENT_ID',\n  INVALID_OOB_CODE: 'INVALID_OOB_CODE',\n  INVALID_PASSWORD: 'INVALID_PASSWORD',\n  INVALID_PENDING_TOKEN: 'INVALID_PENDING_TOKEN',\n  INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',\n  INVALID_PROVIDER_ID: 'INVALID_PROVIDER_ID',\n  INVALID_RECIPIENT_EMAIL: 'INVALID_RECIPIENT_EMAIL',\n  INVALID_SENDER: 'INVALID_SENDER',\n  INVALID_SESSION_INFO: 'INVALID_SESSION_INFO',\n  INVALID_TEMPORARY_PROOF: 'INVALID_TEMPORARY_PROOF',\n  INVALID_TENANT_ID: 'INVALID_TENANT_ID',\n  MFA_ENROLLMENT_NOT_FOUND: 'MFA_ENROLLMENT_NOT_FOUND',\n  MISSING_ANDROID_PACKAGE_NAME: 'MISSING_ANDROID_PACKAGE_NAME',\n  MISSING_APP_CREDENTIAL: 'MISSING_APP_CREDENTIAL',\n  MISSING_CODE: 'MISSING_CODE',\n  MISSING_CONTINUE_URI: 'MISSING_CONTINUE_URI',\n  MISSING_CUSTOM_TOKEN: 'MISSING_CUSTOM_TOKEN',\n  MISSING_IOS_BUNDLE_ID: 'MISSING_IOS_BUNDLE_ID',\n  MISSING_MFA_ENROLLMENT_ID: 'MISSING_MFA_ENROLLMENT_ID',\n  MISSING_MFA_PENDING_CREDENTIAL: 'MISSING_MFA_PENDING_CREDENTIAL',\n  MISSING_OOB_CODE: 'MISSING_OOB_CODE',\n  MISSING_OR_INVALID_NONCE: 'MISSING_OR_INVALID_NONCE',\n  MISSING_PASSWORD: 'MISSING_PASSWORD',\n  MISSING_PHONE_NUMBER: 'MISSING_PHONE_NUMBER',\n  MISSING_SESSION_INFO: 'MISSING_SESSION_INFO',\n  OPERATION_NOT_ALLOWED: 'OPERATION_NOT_ALLOWED',\n  PASSWORD_LOGIN_DISABLED: 'PASSWORD_LOGIN_DISABLED',\n  QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',\n  RESET_PASSWORD_EXCEED_LIMIT: 'RESET_PASSWORD_EXCEED_LIMIT',\n  REJECTED_CREDENTIAL: 'REJECTED_CREDENTIAL',\n  SECOND_FACTOR_EXISTS: 'SECOND_FACTOR_EXISTS',\n  SECOND_FACTOR_LIMIT_EXCEEDED: 'SECOND_FACTOR_LIMIT_EXCEEDED',\n  SESSION_EXPIRED: 'SESSION_EXPIRED',\n  TENANT_ID_MISMATCH: 'TENANT_ID_MISMATCH',\n  TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n  TOO_MANY_ATTEMPTS_TRY_LATER: 'TOO_MANY_ATTEMPTS_TRY_LATER',\n  UNSUPPORTED_FIRST_FACTOR: 'UNSUPPORTED_FIRST_FACTOR',\n  UNSUPPORTED_TENANT_OPERATION: 'UNSUPPORTED_TENANT_OPERATION',\n  UNVERIFIED_EMAIL: 'UNVERIFIED_EMAIL',\n  UNAUTHORIZED_DOMAIN: 'UNAUTHORIZED_DOMAIN',\n  USER_CANCELLED: 'USER_CANCELLED',\n  USER_DISABLED: 'USER_DISABLED',\n  USER_NOT_FOUND: 'USER_NOT_FOUND',\n  WEAK_PASSWORD: 'WEAK_PASSWORD'\n};\n\n\n/**\n * A map of server error codes to client errors.\n * @typedef {!Object<\n *     !fireauth.RpcHandler.ServerError, !fireauth.authenum.Error>}\n */\nfireauth.RpcHandler.ServerErrorMap;\n\n\n/**\n * Firebase Auth response field names.\n * @enum {string}\n */\nfireauth.RpcHandler.AuthServerField = {\n  ALL_PROVIDERS: 'allProviders',\n  AUTH_URI: 'authUri',\n  AUTHORIZED_DOMAINS: 'authorizedDomains',\n  DYNAMIC_LINKS_DOMAIN: 'dynamicLinksDomain',\n  EMAIL: 'email',\n  ERROR_MESSAGE: 'errorMessage',\n  EXPIRES_IN: 'expiresIn',\n  ID_TOKEN: 'idToken',\n  MFA_PENDING_CREDENTIAL: 'mfaPendingCredential',\n  NEED_CONFIRMATION: 'needConfirmation',\n  OAUTH_ID_TOKEN: 'oauthIdToken',\n  PENDING_TOKEN: 'pendingToken',\n  PHONE_RESPONSE_INFO: 'phoneResponseInfo',\n  PHONE_SESSION_INFO: 'phoneSessionInfo',\n  POST_BODY: 'postBody',\n  PROVIDER_ID: 'providerId',\n  RECAPTCHA_SITE_KEY: 'recaptchaSiteKey',\n  REQUEST_URI: 'requestUri',\n  REFRESH_TOKEN: 'refreshToken',\n  SESSION_ID: 'sessionId',\n  SESSION_INFO: 'sessionInfo',\n  SIGNIN_METHODS: 'signinMethods',\n  TEMPORARY_PROOF: 'temporaryProof'\n};\n\n\n/**\n * Firebase Auth response injected fields.\n * @enum {string}\n */\nfireauth.RpcHandler.InjectedResponseField = {\n  NONCE: 'nonce'\n};\n\n\n/**\n * Firebase Auth getOobConfirmationCode requestType possible values.\n * @enum {string}\n */\nfireauth.RpcHandler.GetOobCodeRequestType = {\n  EMAIL_SIGNIN: 'EMAIL_SIGNIN',\n  NEW_EMAIL_ACCEPT: 'NEW_EMAIL_ACCEPT',\n  PASSWORD_RESET: 'PASSWORD_RESET',\n  VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',\n  VERIFY_EMAIL: 'VERIFY_EMAIL'\n};\n\n\n/**\n * Firebase Auth response field names.\n * @enum {string}\n */\nfireauth.RpcHandler.StsServerField = {\n  ACCESS_TOKEN: 'access_token',\n  EXPIRES_IN: 'expires_in',\n  REFRESH_TOKEN: 'refresh_token'\n};\n\n\n/**\n * @return {string} The API key.\n */\nfireauth.RpcHandler.prototype.getApiKey = function() {\n  return this.apiKey_;\n};\n\n\n/**\n * The Firebase custom locale header.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.FIREBASE_LOCALE_KEY_ = 'X-Firebase-Locale';\n\n\n/**\n * The secure token endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.SECURE_TOKEN_ENDPOINT_ =\n    'https://securetoken.googleapis.com/v1/token';\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests sending to\n *     STS token endpoint.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_SECURE_TOKEN_TIMEOUT_ =\n    new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * The STS token RPC content headers.\n * @const {!Object}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_SECURE_TOKEN_HEADERS_ = {\n  'Content-Type': 'application/x-www-form-urlencoded'\n};\n\n\n/**\n * The Firebase endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.FIREBASE_ENDPOINT_ =\n    'https://www.googleapis.com/identitytoolkit/v3/relyingparty/';\n\n\n/**\n * The Identity Platform endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_ =\n    'https://identitytoolkit.googleapis.com/v2/';\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests sending to\n *     Firebase endpoint.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_FIREBASE_TIMEOUT_ =\n    new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * The Firebase RPC content headers.\n * @const {!Object}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_ = {\n  'Content-Type': 'application/json'\n};\n\n\n/**\n * Updates the custom locale header.\n * @param {?string} languageCode The new languageCode.\n */\nfireauth.RpcHandler.prototype.updateCustomLocaleHeader =\n    function(languageCode) {\n  if (languageCode) {\n    // If a language code is provided, add it to the header.\n    this.firebaseHeaders_[fireauth.RpcHandler.FIREBASE_LOCALE_KEY_] =\n        languageCode;\n  } else {\n    // Otherwise remove the custom locale header.\n    delete this.firebaseHeaders_[fireauth.RpcHandler.FIREBASE_LOCALE_KEY_];\n  }\n};\n\n\n/**\n * Updates the X-Client-Version in the header.\n * @param {?string} clientVersion The new client version.\n */\nfireauth.RpcHandler.prototype.updateClientVersion = function(clientVersion) {\n  if (clientVersion) {\n    // Update client version for Firebase Auth server.\n    this.firebaseHeaders_['X-Client-Version'] = clientVersion;\n    // Update client version for securetoken server.\n    this.secureTokenHeaders_['X-Client-Version'] = clientVersion;\n  } else {\n    // Remove client version from header.\n    delete this.firebaseHeaders_['X-Client-Version'];\n    delete this.secureTokenHeaders_['X-Client-Version'];\n  }\n};\n\n\n/**\n * Updates the tenant ID in the request.\n * @param {?string} tenantId The new tenant ID.\n */\nfireauth.RpcHandler.prototype.updateTenantId = function(tenantId) {\n  this.tenantId_ = tenantId;\n};\n\n\n/**\n * Returns the tenant ID.\n * @return {?string} The tenant ID.\n */\nfireauth.RpcHandler.prototype.getTenantId = function() {\n  return this.tenantId_;\n};\n\n\n/**\n * Sends XhrIo request using goog.net.XhrIo.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n *     opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhr_ = function(\n    url,\n    opt_callback,\n    opt_httpMethod,\n    opt_data,\n    opt_headers,\n    opt_timeout) {\n  var sendXhr;\n  if (fireauth.util.supportsCors() || fireauth.util.isWorker()) {\n    // If supports CORS use goog.net.XhrIo.\n    sendXhr = goog.bind(this.sendXhrUsingXhrIo_, this);\n  } else {\n    // Load gapi.client.request and gapi.auth dependency dynamically.\n    if (!fireauth.RpcHandler.loadGApi_) {\n      fireauth.RpcHandler.loadGApi_ =\n          new goog.Promise(function(resolve, reject) {\n            // On load, resolve.\n            fireauth.RpcHandler.loadGApiJs_(resolve, reject);\n          });\n    }\n    // If does not support CORS, use gapi.client.request.\n    sendXhr = goog.bind(this.sendXhrUsingGApiClient_, this);\n  }\n  sendXhr(\n      url, opt_callback, opt_httpMethod, opt_data, opt_headers, opt_timeout);\n};\n\n\n/**\n * Sends XhrIo request using goog.net.XhrIo.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n *     opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhrUsingXhrIo_ = function(\n    url,\n    opt_callback,\n    opt_httpMethod,\n    opt_data,\n    opt_headers,\n    opt_timeout) {\n  if (fireauth.util.isWorker() && !fireauth.util.isFetchSupported()) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n        'fetch, Headers and Request native APIs or equivalent Polyfills ' +\n        'must be available to support HTTP requests from a Worker ' +\n        'environment.');\n  }\n  var xhrIo = new goog.net.XhrIo(this.rpcHandlerXhrFactory_);\n\n  // xhrIo.setTimeoutInterval not working in IE10 and IE11, handle manually.\n  var requestTimeout;\n  if (opt_timeout) {\n    xhrIo.setTimeoutInterval(opt_timeout);\n    requestTimeout = setTimeout(function() {\n      xhrIo.dispatchEvent(goog.net.EventType.TIMEOUT);\n    }, opt_timeout);\n  }\n  // Run callback function on completion.\n  xhrIo.listen(\n      goog.net.EventType.COMPLETE,\n      /** @this {goog.net.XhrIo} */\n      function() {\n        // Clear timeout timer.\n        if (requestTimeout) {\n          clearTimeout(requestTimeout);\n        }\n        // Response assumed to be in json format. If not, catch, log error and\n        // pass null to callback.\n        var response = null;\n        try {\n          // Do not use this.responseJson() as it uses goog.json.parse\n          // underneath. Internal goog.json.parse parsing uses eval and since\n          // recommended Content Security Policy does not allow unsafe-eval,\n          // this is failing and throwing an error in chrome extensions and\n          // warnings else where. Use native parsing instead via JSON.parse.\n          response = JSON.parse(this.getResponseText()) || null;\n        } catch (e) {\n          response = null;\n        }\n        if (opt_callback) {\n          opt_callback(/** @type {?Object} */ (response));\n        }\n      });\n  // Dispose xhrIo on ready.\n  xhrIo.listenOnce(\n      goog.net.EventType.READY,\n      /** @this {goog.net.XhrIo} */\n      function() {\n        // Clear timeout timer.\n        if (requestTimeout) {\n          clearTimeout(requestTimeout);\n        }\n        // Dispose xhrIo.\n        this.dispose();\n      });\n  // Listen to timeout error.\n  // This should work when request is aborted too.\n  xhrIo.listenOnce(\n      goog.net.EventType.TIMEOUT,\n      /** @this {goog.net.XhrIo} */\n      function() {\n        // Clear timeout timer.\n        if (requestTimeout) {\n          clearTimeout(requestTimeout);\n        }\n        // Dispose xhrIo.\n        this.dispose();\n        // The request timed out.\n        if (opt_callback) {\n          opt_callback(null);\n        }\n      });\n  xhrIo.send(url, opt_httpMethod, opt_data, opt_headers);\n};\n\n\n/**\n * @const {!goog.string.Const} The GApi client library URL.\n * @private\n */\nfireauth.RpcHandler.GAPI_SRC_ = goog.string.Const.from(\n    'https://apis.google.com/js/client.js?onload=%{onload}');\n\n\n/**\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.GAPI_CALLBACK_NAME_ =\n    '__fcb' + Math.floor(Math.random() * 1000000).toString();\n\n\n/**\n * Loads the GApi client library if it is not loaded.\n * @param {function()} callback The callback to invoke once it's loaded.\n * @param {function(?Object)} errback The error callback.\n * @private\n */\nfireauth.RpcHandler.loadGApiJs_ = function(callback, errback) {\n  // If gapi.client.request not available, load it dynamically.\n  if (!((window['gapi'] || {})['client'] || {})['request']) {\n    goog.global[fireauth.RpcHandler.GAPI_CALLBACK_NAME_] = function() {\n      // Callback will be called by GApi, test properly loaded here instead of\n      // after jsloader resolves.\n      if (!((window['gapi'] || {})['client'] || {})['request']) {\n        errback(new Error(fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED));\n      } else {\n        callback();\n      }\n    };\n    var url = goog.html.TrustedResourceUrl.format(\n        fireauth.RpcHandler.GAPI_SRC_,\n        {'onload': fireauth.RpcHandler.GAPI_CALLBACK_NAME_});\n    // TODO: replace goog.net.jsloader with our own script includer.\n    var result = goog.net.jsloader.safeLoad(url);\n    result.addErrback(function() {\n      // In case file fails to load.\n      errback(new Error(fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED));\n    });\n  } else {\n    callback();\n  }\n};\n\n\n/**\n * Sends XhrIo request using gapi.client.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n *     opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhrUsingGApiClient_ = function(\n    url,\n    opt_callback,\n    opt_httpMethod,\n    opt_data,\n    opt_headers,\n    opt_timeout) {\n  var self = this;\n  // Wait for GApi dependency to load.\n  fireauth.RpcHandler.loadGApi_.then(function() {\n    window['gapi']['client']['setApiKey'](self.getApiKey());\n    // GApi maintains the Auth result and automatically append the Auth token to\n    // all outgoing requests. Firebase Auth requests will be rejected if there\n    // are others scopes (e.g. google plus) for the Auth token. Need to empty\n    // the token before call gitkit api. Restored in callback.\n    var oauth2Token = window['gapi']['auth']['getToken']();\n    window['gapi']['auth']['setToken'](null);\n    window['gapi']['client']['request']({\n      'path': url,\n      'method': opt_httpMethod,\n      'body': opt_data,\n      'headers': opt_headers,\n      // This needs to be set to none, otherwise the access token will be passed\n      // in the header field causing apiary to complain.\n      'authType': 'none',\n      'callback': function(response) {\n        window['gapi']['auth']['setToken'](oauth2Token);\n        if (opt_callback) {\n          opt_callback(response);\n        }\n      }\n    });\n  }).thenCatch(function(error) {\n    // Catches failure to support CORS and propagates it.\n    if (opt_callback) {\n      // Simulate backend server error to be caught by upper layer.\n      opt_callback({\n        'error': {\n          'message': (error && error['message']) ||\n              fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED\n        }\n      });\n    }\n  });\n};\n\n\n/**\n * Validates the request for the STS access token.\n *\n * @param {?Object} data The STS token request body.\n * @return {boolean} Whether the request is valid.\n * @private\n */\nfireauth.RpcHandler.prototype.validateStsTokenRequest_ = function(data) {\n  if (data['grant_type'] == 'refresh_token' && data['refresh_token']) {\n    // Exchange refresh token.\n    return true;\n  } else if (data['grant_type'] == 'authorization_code' && data['code']) {\n    // Exchange ID token.\n    return true;\n  } else {\n    // Invalid.\n    return false;\n  }\n};\n\n\n/**\n * Handles the request for the STS access token.\n *\n * @param {!Object} data The STS token request body.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestStsToken = function(data) {\n  var self = this;\n  return new goog.Promise(function(resolve, reject) {\n    if (self.validateStsTokenRequest_(data)) {\n      self.sendXhr_(\n          self.secureTokenEndpoint_ + '?key=' +\n          encodeURIComponent(self.getApiKey()),\n          function(response) {\n            if (!response) {\n              // An unparseable response from the XHR most likely indicates some\n              // problem with the network.\n              reject(new fireauth.AuthError(\n                  fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n            } else if (fireauth.RpcHandler.hasError_(response)) {\n              reject(fireauth.RpcHandler.getDeveloperError_(response));\n            } else if (\n                !response[fireauth.RpcHandler.StsServerField.ACCESS_TOKEN] ||\n                !response[fireauth.RpcHandler.StsServerField.REFRESH_TOKEN]) {\n              reject(new fireauth.AuthError(\n                  fireauth.authenum.Error.INTERNAL_ERROR));\n            } else {\n              resolve(response);\n            }\n          },\n          fireauth.RpcHandler.HttpMethod.POST,\n          goog.Uri.QueryData.createFromMap(data).toString(),\n          self.secureTokenHeaders_,\n          self.secureTokenTimeout_.get());\n    } else {\n      reject(new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR));\n    }\n  });\n};\n\n\n/**\n * @param {!Object} data The object to serialize.\n * @return {string} The serialized object with null, undefined and empty string\n *     values removed.\n * @private\n */\nfireauth.RpcHandler.serialize_ = function(data) {\n  // goog.json.serialize converts undefined values to null.\n  // This helper removes all empty strings, nulls and undefined from serialized\n  // object.\n  // Serialize trimmed data.\n  return goog.json.serialize(fireauth.util.copyWithoutNullsOrUndefined(data));\n};\n\n\n/**\n * Creates and executes a request for the given API method using the legacy\n * Firebase Auth endpoint.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n *     request, the contents of this object will be form encoded and appended\n *     to the query string of the URL. No post body is sent in that case. If an\n *     object value is specified, it will be converted to a string:\n *     encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n *     of server error codes to client errors to override default error\n *     handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n *     request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestFirebaseEndpoint = function(\n    method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n  return this.requestAuthEndpoint_(\n      this.firebaseEndpoint_, method, httpMethod, data, opt_customErrorMap,\n      opt_cachebuster);\n};\n\n\n/**\n * Creates and executes a request for the given API method using the identity\n * platform endpoint.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n *     request, the contents of this object will be form encoded and appended\n *     to the query string of the URL. No post body is sent in that case. If an\n *     object value is specified, it will be converted to a string:\n *     encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n *     of server error codes to client errors to override default error\n *     handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n *     request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestIdentityPlatformEndpoint = function(\n    method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n  return this.requestAuthEndpoint_(\n      this.identityPlatformEndpoint_, method, httpMethod, data,\n      opt_customErrorMap, opt_cachebuster);\n};\n\n\n/**\n * Creates and executes a request for the given API method and Auth endpoint.\n * @param {string} endpoint The Auth endpoint to use.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n *     request, the contents of this object will be form encoded and appended\n *     to the query string of the URL. No post body is sent in that case. If an\n *     object value is specified, it will be converted to a string:\n *     encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n *     of server error codes to client errors to override default error\n *     handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n *     request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n * @private\n */\nfireauth.RpcHandler.prototype.requestAuthEndpoint_ = function(\n    endpoint, method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n  var self = this;\n  // Construct endpoint URL.\n  var uri = goog.Uri.parse(endpoint + method);\n  uri.setParameterValue('key', this.getApiKey());\n  // Check whether to append cachebuster to request.\n  if (opt_cachebuster) {\n    uri.setParameterValue('cb', goog.now().toString());\n  }\n  // Firebase allows GET endpoints.\n  var isGet = httpMethod == fireauth.RpcHandler.HttpMethod.GET;\n  if (isGet) {\n    // For GET HTTP method, append data to query string.\n    for (var key in data) {\n      if (data.hasOwnProperty(key)) {\n        uri.setParameterValue(key, data[key]);\n      }\n    }\n  }\n  return new goog.Promise(function(resolve, reject) {\n    self.sendXhr_(\n        uri.toString(),\n        function(response) {\n          if (!response) {\n            // An unparseable response from the XHR most likely indicates some\n            // problem with the network.\n            reject(new fireauth.AuthError(\n                fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n          } else if (fireauth.RpcHandler.hasError_(response)) {\n            reject(fireauth.RpcHandler.getDeveloperError_(response,\n                opt_customErrorMap || {}));\n          } else {\n            resolve(response);\n          }\n        },\n        httpMethod,\n        // No post body data in GET requests.\n        isGet ? undefined : fireauth.RpcHandler.serialize_(data),\n        self.firebaseHeaders_,\n        self.firebaseTimeout_.get());\n  });\n};\n\n\n/**\n * Verifies that the request has a valid email set.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateRequestHasEmail_ = function(request) {\n  if (!fireauth.util.isValidEmailAddress(request['email'])) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_EMAIL);\n  }\n};\n\n\n/**\n * Verifies that the response has a valid email set.\n * @param {!Object} response\n * @private\n */\nfireauth.RpcHandler.validateResponseHasEmail_ = function(response) {\n  if (!fireauth.util.isValidEmailAddress(response['email'])) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Verifies that the an email is valid, if it is there.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateEmailIfPresent_ = function(request) {\n  if ('email' in request) {\n    fireauth.RpcHandler.validateRequestHasEmail_(request);\n  }\n};\n\n\n/**\n * @param {string} providerId The provider ID.\n * @param {?Array<string>=} opt_additionalScopes The list of scope strings.\n * @return {?string} The IDP and its comma separated scope strings serialized.\n * @private\n */\nfireauth.RpcHandler.getAdditionalScopes_ =\n    function(providerId, opt_additionalScopes) {\n  var scopes = {};\n  if (opt_additionalScopes && opt_additionalScopes.length) {\n    scopes[providerId] = opt_additionalScopes.join(',');\n    // Return stringified scopes.\n    return goog.json.serialize(scopes);\n  }\n  return null;\n};\n\n\n/**\n * Validates a response from getAuthUri.\n * @param {?Object} response The getAuthUri response data.\n * @private\n */\nfireauth.RpcHandler.validateGetAuthResponse_ = function(response) {\n  if (!response[fireauth.RpcHandler.AuthServerField.AUTH_URI]) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n        'Unable to determine the authorization endpoint for the specified '+\n        'provider. This may be an issue in the provider configuration.');\n  } else if ( !response[fireauth.RpcHandler.AuthServerField.SESSION_ID]) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests createAuthUri endpoint to retrieve the authUri and session ID for\n * the start of an OAuth handshake.\n * @param {string} providerId The provider ID.\n * @param {string} continueUri The IdP callback URL.\n * @param {?Object=} opt_customParameters The optional OAuth custom parameters\n *     plain object.\n * @param {?Array<string>=} opt_additionalScopes The list of scope strings.\n * @param {?string=} opt_email The optional email.\n * @param {?string=} opt_sessionId The optional session ID.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getAuthUri = function(\n    providerId,\n    continueUri,\n    opt_customParameters,\n    opt_additionalScopes,\n    opt_email,\n    opt_sessionId) {\n  // SAML provider request is constructed differently than OAuth requests.\n  var isSaml = fireauth.idp.isSaml(providerId);\n  var request = {\n    'identifier': opt_email,\n    'providerId': providerId,\n    'continueUri': continueUri,\n    'customParameter': opt_customParameters || {},\n    'oauthScope': fireauth.RpcHandler.getAdditionalScopes_(\n        providerId, opt_additionalScopes),\n    'sessionId': opt_sessionId\n  };\n  // Custom parameters and OAuth scopes should be ignored.\n  if (isSaml) {\n    delete request['customParameter'];\n    delete request['oauthScope'];\n  }\n  // When sessionId is provided, mobile flow (Cordova) is being used, force\n  // code flow and not implicit flow. All other providers use code flow by\n  // default.\n  if (opt_sessionId && providerId == fireauth.idp.ProviderId.GOOGLE) {\n    request['authFlowType'] = 'CODE_FLOW';\n  }\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_AUTH_URI,\n      request);\n};\n\n\n/**\n * Gets the list of IDPs that can be used to log in for the given identifier.\n * @param {string} identifier The identifier, such as an email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.fetchProvidersForIdentifier =\n    function(identifier) {\n  // createAuthUri returns an error if continue URI is not http or https.\n  // For environments like Cordova, Chrome extensions, native frameworks, file\n  // systems, etc, use http://localhost as continue URL.\n  var continueUri = fireauth.util.isHttpOrHttps() ?\n      fireauth.util.getCurrentUrl() : 'http://localhost';\n  var request = {\n    'identifier': identifier,\n    'continueUri': continueUri\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI, request)\n      .then(function(response) {\n        return response[fireauth.RpcHandler.AuthServerField.ALL_PROVIDERS] ||\n            [];\n      });\n};\n\n\n/**\n * Returns the list of sign in methods for the given identifier.\n * @param {string} identifier The identifier, such as an email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.fetchSignInMethodsForIdentifier = function(\n    identifier) {\n  // createAuthUri returns an error if continue URI is not http or https.\n  // For environments like Cordova, Chrome extensions, native frameworks, file\n  // systems, etc, use http://localhost as continue URL.\n  var continueUri = fireauth.util.isHttpOrHttps() ?\n      fireauth.util.getCurrentUrl() :\n      'http://localhost';\n  var request = {\n    'identifier': identifier,\n    'continueUri': continueUri\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI, request)\n      .then(function(response) {\n        return response[fireauth.RpcHandler.AuthServerField.SIGNIN_METHODS] ||\n            [];\n      });\n};\n\n\n/**\n * Gets the list of authorized domains for the specified project.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.getAuthorizedDomains = function() {\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, {})\n      .then(function(response) {\n        return response[\n           fireauth.RpcHandler.AuthServerField.AUTHORIZED_DOMAINS] || [];\n      });\n};\n\n\n/**\n * Gets the reCAPTCHA parameters needed to render the project's provisioned\n * reCAPTCHA.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getRecaptchaParam = function() {\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_RECAPTCHA_PARAM, {});\n};\n\n\n/**\n * Gets the list of authorized domains for the specified project.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.getDynamicLinkDomain = function() {\n  var request = {\n    'returnDynamicLink': true\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.RETURN_DYNAMIC_LINK, request);\n};\n\n\n/**\n * Checks if the provided iOS bundle ID belongs to the project as specified by\n * the API key.\n * @param {string} iosBundleId  The iOS bundle ID to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isIosBundleIdValid = function(iosBundleId) {\n  var request = {\n    'iosBundleId': iosBundleId\n  };\n  // This will either resolve if the identifier is valid or throw INVALID_APP_ID\n  // if not.\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n      .then(function(result) {\n        // Do not return anything.\n      });\n};\n\n\n/**\n * Checks if the provided Android package name belongs to the project as\n * specified by the API key.\n * @param {string} androidPackageName  The iOS bundle ID to check.\n * @param {?string=} opt_sha1Cert The optional SHA-1 Android cert to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isAndroidPackageNameValid =\n    function(androidPackageName, opt_sha1Cert) {\n  var request = {\n    'androidPackageName': androidPackageName\n  };\n  // This is relevant for the native Android SDK flow.\n  // This will redirect to an FDL domain owned by GMScore instead of\n  // the developer's FDL domain as is done for Cordova apps.\n  if (!!opt_sha1Cert) {\n    request['sha1Cert'] = opt_sha1Cert;\n  }\n  // When no sha1Cert is passed, this will either resolve if the identifier is\n  // valid or throw INVALID_APP_ID if not.\n  // When sha1Cert is also passed, this will either resolve or fail with an\n  // INVALID_CERT_HASH error.\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n      .then(function(result) {\n        // Do not return anything.\n      });\n};\n\n\n/**\n * Checks if the provided OAuth client ID belongs to the project as specified by\n * the API key.\n * @param {string} clientId The OAuth client ID to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isOAuthClientIdValid = function(clientId) {\n  var request = {\n    'clientId': clientId\n  };\n  // This will either resolve if the client ID is valid or throw\n  // INVALID_OAUTH_CLIENT_ID if not.\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n      .then(function(result) {\n        // Do not return anything.\n      });\n};\n\n\n/**\n * Requests getAccountInfo endpoint using an ID token.\n * @param {string} idToken The ID token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getAccountInfoByIdToken = function(idToken) {\n  var request = {'idToken': idToken};\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_ACCOUNT_INFO,\n      request);\n};\n\n\n/**\n * Validates a request to sign in with email and password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateVerifyCustomTokenRequest_ = function(request) {\n  if (!request['token']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_CUSTOM_TOKEN);\n  }\n};\n\n\n/**\n * Verifies a custom token and returns a Promise that resolves with the ID\n * token.\n * @param {string} token The custom token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyCustomToken = function(token) {\n  var request = {'token': token};\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.VERIFY_CUSTOM_TOKEN,\n      request);\n};\n\n\n/**\n * Validates a request to sign in with email and password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateVerifyPasswordRequest_ = function(request) {\n  fireauth.RpcHandler.validateRequestHasEmail_(request);\n  if (!request['password']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_PASSWORD);\n  }\n};\n\n\n/**\n * Verifies a password and returns a Promise that resolves with the ID\n * token.\n * @param {string} email The email address.\n * @param {string} password The entered password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPassword = function(email, password) {\n  var request = {\n    'email': email,\n    'password': password\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.VERIFY_PASSWORD,\n      request);\n};\n\n\n/**\n * Verifies an email link OTP for sign-in and returns a Promise that resolves\n * with the ID token.\n * @param {string} email The email address.\n * @param {string} oobCode The email action OTP.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.emailLinkSignIn = function(email, oobCode) {\n  var request = {\n    'email': email,\n    'oobCode': oobCode\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN, request);\n};\n\n\n/**\n * Verifies an email link OTP for linking and returns a Promise that resolves\n * with the ID token.\n * @param {string} idToken The ID token.\n * @param {string} email The email address.\n * @param {string} oobCode The email action OTP.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.emailLinkSignInForLinking =\n    function(idToken, email, oobCode) {\n  var request = {\n    'idToken': idToken,\n    'email': email,\n    'oobCode': oobCode\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN_FOR_LINKING,\n      request);\n};\n\n\n/**\n * Validates a response that should contain an ID token.\n * If no ID token is available, it checks if a multi-factor pending credential\n * is available instead. In that case, it throws the MFA_REQUIRED error code.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateIdTokenResponse_ = function(response) {\n  if (!response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n    // User could be a second factor user.\n    // When second factor is required, a pending credential is returned.\n    if (response[fireauth.RpcHandler.AuthServerField.MFA_PENDING_CREDENTIAL]) {\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.MFA_REQUIRED,\n          null,\n          goog.object.clone(response));\n    }\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Validates a getRecaptchaParam response.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateGetRecaptchaParamResponse_ = function(response) {\n  // Both are required. This could change though.\n  if (!response[fireauth.RpcHandler.AuthServerField.RECAPTCHA_SITE_KEY]) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Validates a request that sends the verification ID and code for a sign in/up\n * phone Auth flow.\n * @param {!Object} request The server request object.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberRequest_ = function(request) {\n  // There are 2 cases here:\n  // case 1: sessionInfo and code\n  // case 2: phoneNumber and temporaryProof\n  if (request['phoneNumber'] || request['temporaryProof']) {\n    // Case 2. Both phoneNumber and temporaryProof should be set.\n    if (!request['phoneNumber'] || !request['temporaryProof']) {\n      throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n    }\n  } else {\n    // Otherwise it's case 1, so we expect sessionInfo and code.\n    if (!request['sessionInfo']) {\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.MISSING_SESSION_INFO);\n    }\n    if (!request['code']) {\n      throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n    }\n  }\n};\n\n\n/**\n * Validates a request that sends the verification ID and code for a link/update\n * phone Auth flow.\n * @param {!Object} request The server request object.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberLinkRequest_ = function(request) {\n  // idToken should be required here.\n  if (!request['idToken']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  // The other request parameters match the sign in flow.\n  fireauth.RpcHandler.validateVerifyPhoneNumberRequest_(request);\n};\n\n\n/**\n * Validates a request to create an email and password account.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateCreateAccountRequest_ = function(request) {\n  fireauth.RpcHandler.validateRequestHasEmail_(request);\n  if (!request['password']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.WEAK_PASSWORD);\n  }\n};\n\n\n/**\n * Validates a request to createAuthUri.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateGetAuthUriRequest_ = function(request) {\n  if (!request['continueUri']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CONTINUE_URI);\n  }\n  // Either a SAML or non SAML providerId must be provided.\n  if (!request['providerId']) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INTERNAL_ERROR,\n        'A provider ID must be provided in the request.');\n  }\n};\n\n\n/**\n * Creates an email/password account. Returns a Promise that resolves with the\n * ID token.\n * @param {string} email The email address of the account.\n * @param {string} password The password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.createAccount = function(email, password) {\n  var request = {\n    'email': email,\n    'password': password\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_ACCOUNT,\n      request);\n};\n\n\n/**\n * Signs in a user as anonymous. Returns a Promise that resolves with the\n * ID token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.signInAnonymously = function() {\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SIGN_IN_ANONYMOUSLY, {});\n};\n\n\n/**\n * Deletes the user's account corresponding to the idToken given.\n * @param {string} idToken The idToken of the user.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.RpcHandler.prototype.deleteAccount = function(idToken) {\n  var request = {\n    'idToken': idToken\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.DELETE_ACCOUNT,\n      request);\n};\n\n\n/**\n * Requests setAccountInfo endpoint for updateEmail operation.\n * @param {string} idToken The ID token.\n * @param {string} newEmail The new email.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateEmail = function(idToken, newEmail) {\n  var request = {\n    'idToken': idToken,\n    'email': newEmail\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO,\n      request);\n};\n\n\n/**\n * Validates a setAccountInfo request that updates the password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateSetAccountInfoSensitive_ = function(request) {\n  fireauth.RpcHandler.validateEmailIfPresent_(request);\n  if (!request['password']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.WEAK_PASSWORD);\n  }\n};\n\n\n/**\n * Requests setAccountInfo endpoint for updatePassword operation.\n * @param {string} idToken The ID token.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updatePassword = function(idToken, newPassword) {\n  var request = {\n    'idToken': idToken,\n    'password': newPassword\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO_SENSITIVE, request);\n};\n\n\n/**\n * Requests setAccountInfo endpoint to set the email and password. This can be\n * used to link an existing account to a new email and password account.\n * @param {string} idToken The ID token.\n * @param {string} newEmail The new email.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateEmailAndPassword = function(idToken,\n    newEmail, newPassword) {\n  var request = {\n    'idToken': idToken,\n    'email': newEmail,\n    'password': newPassword\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO_SENSITIVE, request);\n};\n\n\n/**\n * Maps the name of a field in the account info object to the backend enum\n * value, for deletion of profile fields.\n * @private {!Object<string, string>}\n */\nfireauth.RpcHandler.PROFILE_FIELD_TO_ENUM_NAME_ = {\n  'displayName': 'DISPLAY_NAME',\n  'photoUrl': 'PHOTO_URL'\n};\n\n\n/**\n * Updates the profile of the user. When resolved, promise returns a response\n * similar to that of getAccountInfo.\n * @param {string} idToken The ID token of the user whose profile is changing.\n * @param {!Object} profileData The new profile data.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateProfile = function(idToken, profileData) {\n  var data = {\n    'idToken': idToken\n  };\n  var fieldsToDelete = [];\n\n  // Copy over the relevant fields from profileData, or explicitly flag a field\n  // for deletion if null is passed as the value. Note that this currently only\n  // checks profileData to the first level.\n  goog.object.forEach(fireauth.RpcHandler.PROFILE_FIELD_TO_ENUM_NAME_,\n      function(enumName, fieldName) {\n        var fieldValue = profileData[fieldName];\n        if (fieldValue === null) {\n          // If null is explicitly provided, delete the field.\n          fieldsToDelete.push(enumName);\n        } else if (fieldName in profileData) {\n          // If the field is explicitly set, send it to the backend.\n          data[fieldName] = fieldValue;\n        }\n      });\n  if (fieldsToDelete.length) {\n    data['deleteAttribute'] = fieldsToDelete;\n  }\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO, data);\n};\n\n\n/**\n * Validates a request for an email action code for password reset.\n * @param {!Object} request The getOobCode request data for password reset.\n * @private\n */\nfireauth.RpcHandler.validateOobCodeRequest_ = function(request) {\n  if (request['requestType'] !=\n          fireauth.RpcHandler.GetOobCodeRequestType.PASSWORD_RESET) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  fireauth.RpcHandler.validateRequestHasEmail_(request);\n};\n\n\n/**\n * Validates a request for an email action for passwordless email sign-in.\n * @param {!Object} request The getOobCode request data for email sign-in.\n * @private\n */\nfireauth.RpcHandler.validateEmailSignInCodeRequest_ = function(request) {\n  if (request['requestType'] !=\n      fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  fireauth.RpcHandler.validateRequestHasEmail_(request);\n};\n\n\n/**\n * Validates a request for an email action for email verification.\n * @param {!Object} request The getOobCode request data for email verification.\n * @private\n */\nfireauth.RpcHandler.validateEmailVerificationCodeRequest_ = function(request) {\n  if (request['requestType'] !=\n          fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_EMAIL) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Validates a request for an email action for email verification before update.\n * @param {!Object} request The getOobCode request data for email verification\n *     before update.\n * @private\n */\nfireauth.RpcHandler.validateEmailVerificationCodeBeforeUpdateRequest_ =\n    function(request) {\n  if (request['requestType'] !=\n          fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_AND_CHANGE_EMAIL) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests getOobCode endpoint for password reset, returns promise that\n * resolves with user's email.\n * @param {string} email The email account with the password to be reset.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendPasswordResetEmail =\n    function(email, additionalRequestData) {\n  var request = {\n    'requestType': fireauth.RpcHandler.GetOobCodeRequestType.PASSWORD_RESET,\n    'email': email\n  };\n  // Extend the original request with the additional data.\n  goog.object.extend(request, additionalRequestData);\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_OOB_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for passwordless email sign-in, returns promise\n * that resolves with user's email.\n * @param {string} email The email account to sign in with.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendSignInLinkToEmail = function(\n    email, additionalRequestData) {\n  var request = {\n    'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN,\n    'email': email\n  };\n  // Extend the original request with the additional data.\n  goog.object.extend(request, additionalRequestData);\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_EMAIL_SIGNIN_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for email verification, returns promise that\n * resolves with user's email.\n * @param {string} idToken The idToken of the user confirming his email.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendEmailVerification =\n    function(idToken, additionalRequestData) {\n  var request = {\n    'requestType': fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_EMAIL,\n    'idToken': idToken\n  };\n  // Extend the original request with the additional data.\n  goog.object.extend(request, additionalRequestData);\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for email verification before updating the\n * email.\n * @param {string} idToken The idToken of the user updating his email.\n * @param {string} newEmail The new email.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.verifyBeforeUpdateEmail =\n    function(idToken, newEmail, additionalRequestData) {\n  var request = {\n    'requestType':\n        fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_AND_CHANGE_EMAIL,\n    'idToken': idToken,\n    'newEmail': newEmail\n  };\n  // Extend the original request with the additional data.\n  goog.object.extend(request, additionalRequestData);\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE,\n      request);\n};\n\n\n/**\n * Requests sendVerificationCode endpoint for verifying the user's ownership of\n * a phone number. It resolves with a sessionInfo (verificationId).\n * @param {!Object} request The verification request which contains a phone\n *     number and an assertion.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendVerificationCode = function(request) {\n  // In the future, we could support other types of assertions so for now,\n  // we are keeping the request an object.\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.SEND_VERIFICATION_CODE, request);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for sign in/sign up phone number\n * authentication flow and resolves with the STS token response.\n * @param {!Object} request The phone number ID and code to exchange for a\n *     Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumber = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER, request);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for link/update phone number\n * authentication flow and resolves with the STS token response.\n * @param {!Object} request The phone number ID and code to exchange for a\n *     Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumberForLinking = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_LINKING, request);\n};\n\n\n/**\n * Validates a response to a phone number linking request.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberForLinkingResponse_ =\n    function(response) {\n  if (response[fireauth.RpcHandler.AuthServerField.TEMPORARY_PROOF]) {\n    response['code'] = fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n    throw fireauth.AuthErrorWithCredential.fromPlainObject(response);\n  }\n\n  // If there's no temporary proof, then we expect the request to have\n  // succeeded and returned an ID token.\n  fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for reauthenticating with a phone number\n * and resolves with the STS token response.\n * @param {!Object} request The phone number ID, code, and current ID token to\n *     exchange for a refreshed Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumberForExisting = function(request) {\n  request['operation'] = 'REAUTH';\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_EXISTING,\n      request);\n};\n\n\n/**\n * Validates a request for starting phone MFA enrollment.\n * @param {!Object} request The startPhoneMfaEnrollment request data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaEnrollmentRequest_ =\n    function(request) {\n  if (!request['phoneEnrollmentInfo']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  if (!request['phoneEnrollmentInfo']['phoneNumber']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_PHONE_NUMBER);\n  }\n  if (!request['phoneEnrollmentInfo']['recaptchaToken']) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.MISSING_APP_CREDENTIAL);\n  }\n};\n\n\n/**\n * Validates a response to a start phone MFA enrollment request.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaEnrollmentResponse_ =\n    function(response) {\n  if (!response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO] ||\n      !response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO]\n          [fireauth.RpcHandler.AuthServerField.SESSION_INFO]) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests startMfaEnrollment endpoint for verifying the user's ownership of\n * a phone number before enrolling to MFA. It resolves with a sessionInfo\n * (verificationId) string.\n * @param {!Object} request The enroll MFA request for phone.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.startPhoneMfaEnrollment = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_ENROLLMENT, request)\n      .then(function(response) {\n        // Extract the sessionInfo(verificationId) from response.\n        return response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO]\n            [fireauth.RpcHandler.AuthServerField.SESSION_INFO];\n      });\n};\n\n\n/**\n * Validates a request for finalizing phone MFA enrollment or sign-in.\n * @param {!Object} request The finalizePhoneMfaEnrollment or\n *     finalizePhoneMfaSignIn request data.\n * @private\n */\nfireauth.RpcHandler.validateFinalizePhoneMfaRequest_ = function(request) {\n  if (!request['phoneVerificationInfo']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  if (!request['phoneVerificationInfo']['sessionInfo']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_SESSION_INFO);\n  }\n  if (!request['phoneVerificationInfo']['code']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n  }\n};\n\n\n/**\n * Requests finalizeMfaEnrollment endpoint to finish the enrollment flow for\n * phone MFA. It resolves with the MFA token response.\n * @param {!Object} request The enroll MFA request for phone.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.finalizePhoneMfaEnrollment = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_ENROLLMENT, request);\n};\n\n\n/**\n * Validates a request for starting phone MFA sign-in.\n * @param {!Object} request The startPhoneMfaSignIn request data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaSignInRequest_ = function(request) {\n  if (!request['phoneSignInInfo'] ||\n      !request['phoneSignInInfo']['recaptchaToken']) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.MISSING_APP_CREDENTIAL);\n  }\n};\n\n\n/**\n * Validates a response to a start phone MFA sign-in request.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaSignInResponse_ = function(response) {\n  if (!response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO] ||\n      !response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO]\n          [fireauth.RpcHandler.AuthServerField.SESSION_INFO]) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests startMfaSignIn endpoint for verifying the user's ownership of\n * a phone number before signing in to MFA. It resolves with a sessionInfo\n * (verificationId) string.\n * @param {!Object} request The sign in MFA request for phone.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.startPhoneMfaSignIn = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_SIGN_IN, request)\n      .then(function(response) {\n        // Extract the sessionInfo(verificationId) from response.\n        return response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO]\n            [fireauth.RpcHandler.AuthServerField.SESSION_INFO];\n      });\n};\n\n\n/**\n * Requests finalizeMfaSignIn endpoint to finish the sign-in flow for\n * phone MFA. It resolves with the MFA token response.\n * @param {!Object} request The sign in MFA request for phone.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.finalizePhoneMfaSignIn = function(request) {\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_SIGN_IN, request);\n};\n\n\n/**\n * Validates the response for unenrolling a second factor. If the user is still\n * considered signed in, the endpoint returns new tokens. However, if the\n * user session is revoked no tokens will be returned.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateWithdrawMfaResponse_ = function(response) {\n  var hasIdToken = !!response[fireauth.RpcHandler.AuthServerField.ID_TOKEN];\n  var hasRefreshToken =\n      !!response[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN];\n\n  if (hasIdToken ^ hasRefreshToken) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests the withdraw endpoint to unenroll a second factor. Returns new\n * tokens if the user is still considered signed in or no tokens if the user\n * session is revoked and the user is being signed out.\n * @param {string} idToken The ID token.\n * @param {string} mfaEnrollmentId The MFA enrollment ID.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.withdrawMfa = function(idToken, mfaEnrollmentId) {\n  var request = {\n    'idToken': idToken,\n    'mfaEnrollmentId': mfaEnrollmentId\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.WITHDRAW_MFA, request);\n};\n\n\n/**\n * The custom error map for reauth with verifyPhoneNumber.\n * @private {!fireauth.RpcHandler.ServerErrorMap}\n */\nfireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_ = {};\n\n// For most RPCs, the backend error USER_NOT_FOUND means that the sent STS\n// token is invalid. However, for this specific case, USER_NOT_FOUND actually\n// means that the sent credential is invalid.\nfireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_[\n  fireauth.RpcHandler.ServerError.USER_NOT_FOUND] =\n    fireauth.authenum.Error.USER_DELETED;\n\n\n/**\n * Validates a request to deleteLinkedAccounts.\n * @param {?Object} request\n * @private\n */\nfireauth.RpcHandler.validateDeleteLinkedAccountsRequest_ = function(request) {\n  if (!goog.isArray(request['deleteProvider'])) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Updates the providers for the account associated with the idToken.\n * @param {string} idToken The ID token.\n * @param {!Array<string>} providersToDelete The array of providers to delete.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.deleteLinkedAccounts =\n    function(idToken, providersToDelete) {\n  var request = {\n    'idToken': idToken,\n    'deleteProvider': providersToDelete\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.DELETE_LINKED_ACCOUNTS,\n      request);\n};\n\n\n/**\n * Validates a verifyAssertion request.\n * @param {?Object} request The verifyAssertion request data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionRequest_ = function(request) {\n  // Either (requestUri and sessionId), (requestUri and postBody) or\n  // (requestUri and pendingToken) are required.\n  if (!request[fireauth.RpcHandler.AuthServerField.REQUEST_URI] ||\n      (!request[fireauth.RpcHandler.AuthServerField.SESSION_ID] &&\n       !request[fireauth.RpcHandler.AuthServerField.POST_BODY] &&\n       !request[fireauth.RpcHandler.AuthServerField.PENDING_TOKEN])) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Processes the verifyAssertion response and injects the same raw nonce\n * if available in request.\n * @param {!Object} request The verifyAssertion request data.\n * @param {!Object} response The original verifyAssertion response data.\n * @return {!Object} The modified verifyAssertion response.\n * @private\n */\nfireauth.RpcHandler.processVerifyAssertionResponse_ =\n    function(request, response) {\n  // This makes it possible for OIDC providers to:\n  // 1. Initialize an OIDC Auth credential on successful response.\n  // 2. Initialize an OIDC Auth credential within the recovery error.\n\n  // When request has sessionId and response has OIDC ID token and no pending\n  // token, a credential with raw nonce and OIDC ID token needs to be returned.\n  if (response[fireauth.RpcHandler.AuthServerField.OAUTH_ID_TOKEN] &&\n      response[fireauth.RpcHandler.AuthServerField.PROVIDER_ID] &&\n      response[fireauth.RpcHandler.AuthServerField.PROVIDER_ID]\n          .indexOf(fireauth.constants.OIDC_PREFIX) == 0 &&\n      // Use pendingToken instead of idToken and rawNonce when available.\n      !response[fireauth.RpcHandler.AuthServerField.PENDING_TOKEN]) {\n    if (request[fireauth.RpcHandler.AuthServerField.SESSION_ID]) {\n      // For full OAuth flow, the nonce is in the session ID.\n      response[fireauth.RpcHandler.InjectedResponseField.NONCE] =\n          request[fireauth.RpcHandler.AuthServerField.SESSION_ID];\n    } else if (request[fireauth.RpcHandler.AuthServerField.POST_BODY]) {\n      // For credential flow, the nonce is in the postBody nonce field.\n      var queryData = new goog.Uri.QueryData(\n          request[fireauth.RpcHandler.AuthServerField.POST_BODY]);\n      if (queryData.containsKey(\n              fireauth.RpcHandler.InjectedResponseField.NONCE)) {\n        response[fireauth.RpcHandler.InjectedResponseField.NONCE] =\n            queryData.get(fireauth.RpcHandler.InjectedResponseField.NONCE);\n      }\n    }\n  }\n  return response;\n};\n\n\n/**\n * Validates a response from verifyAssertionForExisting.\n * @param {?Object} response The verifyAssertionForExisting response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionForExistingResponse_ =\n    function(response) {\n  // When returnIdpCredential is set to true and the account is new, no error\n  // is thrown but an errorMessage is added to the response. No idToken is\n  // passed.\n  if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] &&\n      response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n          fireauth.RpcHandler.ServerError.USER_NOT_FOUND) {\n    // This corresponds to user-not-found.\n    throw new fireauth.AuthError(fireauth.authenum.Error.USER_DELETED);\n  } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]) {\n    // Construct developer facing error message from server code in errorMessage\n    // field.\n    throw fireauth.RpcHandler.getDeveloperErrorFromCode_(\n        response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]);\n  }\n  // Need confirmation should not be returned when do not create new user flag\n  // is set.\n  // Validate if ID token or multi-factor pending credential is available.\n  fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Validates a response from verifyAssertion.\n * @param {?Object} response The verifyAssertion response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionResponse_ = function(response) {\n  var error = null;\n  if (response[fireauth.RpcHandler.AuthServerField.NEED_CONFIRMATION]) {\n    // Account linking required, previously logged in to another account\n    // with same email. User must authenticate they are owners of the\n    // first account.\n    // If enough info for Auth linking error, throw an instance of Auth linking\n    // error. This will be used by developer after reauthenticating with email\n    // provided by error to link using the credentials in Auth linking error.\n    // If missing information, return regular Auth error.\n    response['code'] = fireauth.authenum.Error.NEED_CONFIRMATION;\n    error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n  } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n             fireauth.RpcHandler.ServerError.FEDERATED_USER_ID_ALREADY_LINKED) {\n    // When FEDERATED_USER_ID_ALREADY_LINKED returned in error message, auth\n    // credential and email will also be returned, throw relevant error in that\n    // case.\n    // In this case the developer needs to signInWithCredential to the returned\n    // credentials.\n    response['code'] = fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n    error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n  } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n             fireauth.RpcHandler.ServerError.EMAIL_EXISTS) {\n    // When EMAIL_EXISTS returned in error message, Auth credential and email\n    // will also be returned, throw relevant error in that case.\n    // In this case, the developers needs to sign in the user to the original\n    // owner of the account and then link to the returned credential here.\n    response['code'] = fireauth.authenum.Error.EMAIL_EXISTS;\n    error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n  } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]) {\n    // Construct developer facing error message from server code in errorMessage\n    // field.\n    error = fireauth.RpcHandler.getDeveloperErrorFromCode_(\n        response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]);\n  }\n  // If error found, throw it.\n  if (error) {\n    throw error;\n  }\n  // Validate if ID token or multi-factor pending credential is available.\n  fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Validates a verifyAssertion with linking request.\n * @param {?Object} request The verifyAssertion request data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionLinkRequest_ = function(request) {\n  // idToken with either (requestUri and sessionId) or (requestUri and postBody)\n  // are required.\n  fireauth.RpcHandler.validateVerifyAssertionRequest_(request);\n  if (!request['idToken']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * @typedef {{\n *   autoCreate: (boolean|undefined),\n *   requestUri: string,\n *   postBody: (?string|undefined),\n *   pendingIdToken: (?string|undefined),\n *   sessionId: (?string|undefined),\n *   idToken: (?string|undefined),\n *   returnIdpCredential: (boolean|undefined),\n *   tenantId: (?string|undefined)\n * }}\n */\nfireauth.RpcHandler.VerifyAssertionData;\n\n\n/**\n * Requests verifyAssertion endpoint. When resolved, promise returns the whole\n * response.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertion = function(request) {\n  // Force Auth credential to be returned on the following errors:\n  // FEDERATED_USER_ID_ALREADY_LINKED\n  // EMAIL_EXISTS\n  request['returnIdpCredential'] = true;\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION,\n      request);\n};\n\n\n/**\n * Requests verifyAssertion endpoint for federated account linking. When\n * resolved, promise returns the whole response.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertionForLinking = function(request) {\n  // Force Auth credential to be returned on the following errors:\n  // FEDERATED_USER_ID_ALREADY_LINKED\n  // EMAIL_EXISTS\n  request['returnIdpCredential'] = true;\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_LINKING,\n      request);\n};\n\n\n/**\n * Requests verifyAssertion endpoint for an existing federated account. When\n * resolved, promise returns the whole response. If not existing, a\n * user-not-found error is thrown.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertionForExisting = function(request) {\n  // Since we are setting returnIdpCredential to true, a response will be\n  // returned even though the account doesn't exist but an error message is\n  // appended with value set to USER_NOT_FOUND. If this flag is not passed, only\n  // the USER_NOT_FOUND error is thrown without any response.\n  request['returnIdpCredential'] = true;\n  // Do not create a new account if the user doesn't exist.\n  request['autoCreate'] = false;\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_EXISTING,\n      request);\n};\n\n\n/**\n * Validates a request that should contain an action code.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateApplyActionCodeRequest_ = function(request) {\n  if (!request['oobCode']) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_OOB_CODE);\n  }\n};\n\n\n/**\n * Validates that a checkActionCode response contains the email and requestType\n * fields.\n * @param {!Object} response The raw response returned by the server.\n * @private\n */\nfireauth.RpcHandler.validateCheckActionCodeResponse_ = function(response) {\n  // If the code is invalid, usually a clear error would be returned.\n  // In this case, something unexpected happened.\n  // Email could be empty only if the request type is EMAIL_SIGNIN.\n  var operation = response['requestType'];\n  if (!operation ||\n      (!response['email'] && operation != 'EMAIL_SIGNIN' &&\n       operation != 'VERIFY_AND_CHANGE_EMAIL')) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n};\n\n\n/**\n * Requests resetPassword endpoint for password reset, returns promise that\n * resolves with user's email.\n * @param {string} code The email action code to confirm for password reset.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.confirmPasswordReset =\n    function(code, newPassword) {\n  var request = {\n    'oobCode': code,\n    'newPassword': newPassword\n  };\n  return this.invokeRpc(fireauth.RpcHandler.ApiMethod.RESET_PASSWORD, request);\n};\n\n\n/**\n * Checks the validity of an email action code and returns the response\n * received.\n * @param {string} code The email action code to check.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.checkActionCode = function(code) {\n  var request = {\n    'oobCode': code\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.CHECK_ACTION_CODE, request);\n};\n\n\n/**\n * Applies an out-of-band email action code, such as an email verification code.\n * @param {string} code The email action code.\n * @return {!goog.Promise<string>} A promise that resolves with the user's\n *     email.\n */\nfireauth.RpcHandler.prototype.applyActionCode = function(code) {\n  var request = {\n    'oobCode': code\n  };\n  return this.invokeRpc(\n      fireauth.RpcHandler.ApiMethod.APPLY_OOB_CODE, request);\n};\n\n\n/**\n * The specification of an RPC call. The fields are:\n * <ul>\n * <li>cachebuster: defines whether to send a unique string with request to\n *     force the backend to return an uncached response to request.\n * <li>customErrorMap: A map of backend error codes to client-side errors.\n *     Any entries set here override the default handling of the backend error\n *     code.\n * <li>endpoint: defines the backend endpoint to call.\n * <li>httpMethod: defines the HTTP method to use, defaulting to POST if not\n *     specified.\n * <li>requestRequiredFields: an array of the fields that are required in the\n *     request. The RPC call will fail with an INTERNAL_ERROR error if a\n *     required field is not present or if it is null, undefined, or the empty\n *     string.\n * <li>requestValidator: a function that takes in the request object and throws\n *     an error if the request is invalid.\n * <li>responsePreprocessor: a function to modify the response before running\n *     validation. The function takes in the request and response object.\n * <li>responseValidator: a function that takes in the response object and\n *     throws an error if the response is invalid.\n * <li>responseField: the field of the response object that will be returned\n *     from the RPC call. If no field is specified, the entire response object\n *     will be returned.\n * <li>returnSecureToken: Set to true to explicitly request STS tokens instead\n *     of legacy Google Identity Toolkit tokens from the backend.\n * <li>requireTenantId: Set to true to send tenant ID to backend in the request.\n * <li>useIdentityPlatformEndpoint: Whether to use new identity platform\n *     endpoints. The default is false.\n * </ul>\n * @typedef {{\n *   cachebuster: (boolean|undefined),\n *   customErrorMap: (!fireauth.RpcHandler.ServerErrorMap|undefined),\n *   endpoint: string,\n *   httpMethod: (!fireauth.RpcHandler.HttpMethod|undefined),\n *   requestRequiredFields: (!Array<string>|undefined),\n *   requestValidator: (function(!Object):void|undefined),\n *   responsePreprocessor: ((function(!Object, !Object):!Object)|undefined),\n *   responseValidator: (function(!Object):void|undefined),\n *   responseField: (string|undefined),\n *   returnSecureToken: (boolean|undefined),\n *   requireTenantId: (boolean|undefined),\n *   useIdentityPlatformEndpoint: (boolean|undefined)\n * }}\n */\nfireauth.RpcHandler.ApiMethodHandler;\n\n\n/**\n * The specifications for the backend API methods.\n * @enum {!fireauth.RpcHandler.ApiMethodHandler}\n */\nfireauth.RpcHandler.ApiMethod = {\n  APPLY_OOB_CODE: {\n    endpoint: 'setAccountInfo',\n    requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  CHECK_ACTION_CODE: {\n    endpoint: 'resetPassword',\n    requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n    responseValidator: fireauth.RpcHandler.validateCheckActionCodeResponse_,\n    requireTenantId: true\n  },\n  CREATE_ACCOUNT: {\n    endpoint: 'signupNewUser',\n    requestValidator: fireauth.RpcHandler.validateCreateAccountRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true,\n    requireTenantId: true\n  },\n  CREATE_AUTH_URI: {\n    endpoint: 'createAuthUri',\n    requireTenantId: true\n  },\n  DELETE_ACCOUNT: {\n    endpoint: 'deleteAccount',\n    requestRequiredFields: ['idToken']\n  },\n  DELETE_LINKED_ACCOUNTS: {\n    endpoint: 'setAccountInfo',\n    requestRequiredFields: ['idToken', 'deleteProvider'],\n    requestValidator: fireauth.RpcHandler.validateDeleteLinkedAccountsRequest_\n  },\n  EMAIL_LINK_SIGNIN: {\n    endpoint: 'emailLinkSignin',\n    requestRequiredFields: ['email', 'oobCode'],\n    requestValidator: fireauth.RpcHandler.validateRequestHasEmail_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true,\n    requireTenantId: true\n  },\n  EMAIL_LINK_SIGNIN_FOR_LINKING: {\n    endpoint: 'emailLinkSignin',\n    requestRequiredFields: ['idToken', 'email', 'oobCode'],\n    requestValidator: fireauth.RpcHandler.validateRequestHasEmail_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true\n  },\n  FINALIZE_PHONE_MFA_ENROLLMENT: {\n    endpoint: 'accounts/mfaEnrollment:finalize',\n    requestRequiredFields: ['idToken', 'phoneVerificationInfo'],\n    requestValidator:\n        fireauth.RpcHandler.validateFinalizePhoneMfaRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    requireTenantId: true,\n    useIdentityPlatformEndpoint: true\n  },\n  FINALIZE_PHONE_MFA_SIGN_IN: {\n    endpoint: 'accounts/mfaSignIn:finalize',\n    requestRequiredFields: ['mfaPendingCredential', 'phoneVerificationInfo'],\n    requestValidator:\n        fireauth.RpcHandler.validateFinalizePhoneMfaRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    requireTenantId: true,\n    useIdentityPlatformEndpoint: true\n  },\n  GET_ACCOUNT_INFO: {\n    endpoint: 'getAccountInfo'\n  },\n  GET_AUTH_URI: {\n    endpoint: 'createAuthUri',\n    requestValidator: fireauth.RpcHandler.validateGetAuthUriRequest_,\n    responseValidator: fireauth.RpcHandler.validateGetAuthResponse_,\n    requireTenantId: true\n  },\n  GET_EMAIL_SIGNIN_CODE: {\n    endpoint: 'getOobConfirmationCode',\n    requestRequiredFields: ['requestType'],\n    requestValidator: fireauth.RpcHandler.validateEmailSignInCodeRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  GET_EMAIL_VERIFICATION_CODE: {\n    endpoint: 'getOobConfirmationCode',\n    requestRequiredFields: ['idToken', 'requestType'],\n    requestValidator: fireauth.RpcHandler.validateEmailVerificationCodeRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE: {\n    endpoint: 'getOobConfirmationCode',\n    requestRequiredFields: ['idToken', 'newEmail', 'requestType'],\n    requestValidator:\n        fireauth.RpcHandler.validateEmailVerificationCodeBeforeUpdateRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  GET_OOB_CODE: {\n    endpoint: 'getOobConfirmationCode',\n    requestRequiredFields: ['requestType'],\n    requestValidator: fireauth.RpcHandler.validateOobCodeRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  GET_PROJECT_CONFIG: {\n    // Microsoft edge caching bug. There are two getProjectConfig API calls,\n    // first from top level window and then from iframe. The second call has a\n    // response of 304 which means it's a cached response. We suspect the call\n    // from iframe is reusing the response from the first call and checks the\n    // allowed origin in the cached response, which only contains the domain for\n    // the top level window.\n    cachebuster: true,\n    endpoint: 'getProjectConfig',\n    httpMethod: fireauth.RpcHandler.HttpMethod.GET\n  },\n  GET_RECAPTCHA_PARAM: {\n    cachebuster: true,\n    endpoint: 'getRecaptchaParam',\n    httpMethod: fireauth.RpcHandler.HttpMethod.GET,\n    responseValidator: fireauth.RpcHandler.validateGetRecaptchaParamResponse_\n  },\n  RESET_PASSWORD: {\n    endpoint: 'resetPassword',\n    requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n    responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n    requireTenantId: true\n  },\n  RETURN_DYNAMIC_LINK: {\n    cachebuster: true,\n    endpoint: 'getProjectConfig',\n    httpMethod: fireauth.RpcHandler.HttpMethod.GET,\n    responseField: fireauth.RpcHandler.AuthServerField.DYNAMIC_LINKS_DOMAIN\n  },\n  SEND_VERIFICATION_CODE: {\n    endpoint: 'sendVerificationCode',\n    // Currently only reCAPTCHA tokens supported.\n    requestRequiredFields: ['phoneNumber', 'recaptchaToken'],\n    responseField: fireauth.RpcHandler.AuthServerField.SESSION_INFO,\n    requireTenantId: true\n  },\n  SET_ACCOUNT_INFO: {\n    endpoint: 'setAccountInfo',\n    requestRequiredFields: ['idToken'],\n    requestValidator: fireauth.RpcHandler.validateEmailIfPresent_,\n    returnSecureToken: true // Maybe updating email will invalidate token in the\n                            // future, this will prevent breaking the client.\n  },\n  SET_ACCOUNT_INFO_SENSITIVE: {\n    endpoint: 'setAccountInfo',\n    requestRequiredFields: ['idToken'],\n    requestValidator: fireauth.RpcHandler.validateSetAccountInfoSensitive_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true // Updating password will send back new sts tokens.\n  },\n  SIGN_IN_ANONYMOUSLY: {\n    endpoint: 'signupNewUser',\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true,\n    requireTenantId: true\n  },\n  START_PHONE_MFA_ENROLLMENT: {\n    endpoint: 'accounts/mfaEnrollment:start',\n    requestRequiredFields: ['idToken', 'phoneEnrollmentInfo'],\n    requestValidator:\n        fireauth.RpcHandler.validateStartPhoneMfaEnrollmentRequest_,\n    responseValidator:\n        fireauth.RpcHandler.validateStartPhoneMfaEnrollmentResponse_,\n    requireTenantId: true,\n    useIdentityPlatformEndpoint: true\n  },\n  START_PHONE_MFA_SIGN_IN: {\n    endpoint: 'accounts/mfaSignIn:start',\n    requestRequiredFields: ['mfaPendingCredential', 'mfaEnrollmentId',\n                            'phoneSignInInfo'],\n    requestValidator:\n        fireauth.RpcHandler.validateStartPhoneMfaSignInRequest_,\n    responseValidator:\n        fireauth.RpcHandler.validateStartPhoneMfaSignInResponse_,\n    requireTenantId: true,\n    useIdentityPlatformEndpoint: true\n  },\n  VERIFY_ASSERTION: {\n    endpoint: 'verifyAssertion',\n    requestValidator: fireauth.RpcHandler.validateVerifyAssertionRequest_,\n    responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n    responseValidator: fireauth.RpcHandler.validateVerifyAssertionResponse_,\n    returnSecureToken: true,\n    // Tenant ID is required for this endpoint. But for\n    // signInWithRedirect/Popup APIs, to make createAuthUri call and\n    // verifyAssertion call atomic, the tenant ID on RPC handler will be\n    // overridden by the tenant ID passed directly from the\n    // request, which is retrieved from Auth event. For signInWithCredential\n    // API, the tenant ID will still be retrieved from the RPC handler.\n    requireTenantId: true\n  },\n  VERIFY_ASSERTION_FOR_EXISTING: {\n    endpoint: 'verifyAssertion',\n    requestValidator: fireauth.RpcHandler.validateVerifyAssertionRequest_,\n    responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n    responseValidator:\n        fireauth.RpcHandler.validateVerifyAssertionForExistingResponse_,\n    returnSecureToken: true,\n    // Tenant ID is required for this endpoint. But for\n    // reauthenticateWithRedirect/Popup APIs, to make createAuthUri call and\n    // verifyAssertion call atomic, the tenant ID on RPC handler will be\n    // overridden by the tenant ID passed directly from the\n    // request, which is retrieved from Auth event. For\n    // reauthenticateWithCredential API, the tenant ID will still be retrieved\n    // from the RPC handler.\n    requireTenantId: true\n  },\n  VERIFY_ASSERTION_FOR_LINKING: {\n    endpoint: 'verifyAssertion',\n    requestValidator: fireauth.RpcHandler.validateVerifyAssertionLinkRequest_,\n    responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n    responseValidator: fireauth.RpcHandler.validateVerifyAssertionResponse_,\n    returnSecureToken: true\n  },\n  VERIFY_CUSTOM_TOKEN: {\n    endpoint: 'verifyCustomToken',\n    requestValidator: fireauth.RpcHandler.validateVerifyCustomTokenRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true,\n    requireTenantId: true\n  },\n  VERIFY_PASSWORD: {\n    endpoint: 'verifyPassword',\n    requestValidator: fireauth.RpcHandler.validateVerifyPasswordRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    returnSecureToken: true,\n    requireTenantId: true\n  },\n  VERIFY_PHONE_NUMBER: {\n    endpoint: 'verifyPhoneNumber',\n    requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    requireTenantId: true\n  },\n  VERIFY_PHONE_NUMBER_FOR_LINKING: {\n    endpoint: 'verifyPhoneNumber',\n    requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberLinkRequest_,\n    responseValidator:\n        fireauth.RpcHandler.validateVerifyPhoneNumberForLinkingResponse_\n  },\n  VERIFY_PHONE_NUMBER_FOR_EXISTING: {\n    customErrorMap: fireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_,\n    endpoint: 'verifyPhoneNumber',\n    requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberRequest_,\n    responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n    requireTenantId: true\n  },\n  WITHDRAW_MFA: {\n    endpoint: 'accounts/mfaEnrollment:withdraw',\n    requestRequiredFields: ['idToken', 'mfaEnrollmentId'],\n    responseValidator: fireauth.RpcHandler.validateWithdrawMfaResponse_,\n    requireTenantId: true,\n    useIdentityPlatformEndpoint: true\n  }\n};\n\n\n/**\n * @const {string} The parameter to send to the backend to specify that the\n *     client accepts STS tokens directly from Firebear backends.\n * @private\n */\nfireauth.RpcHandler.USE_STS_TOKEN_PARAM_ = 'returnSecureToken';\n\n\n/**\n * @const {string} The parameter to send to the backend to specify the tenant\n *     ID.\n * @private\n */\nfireauth.RpcHandler.TENANT_ID_PARAM_ = 'tenantId';\n\n\n/**\n * Invokes an RPC method according to the specification defined by\n * {@code fireauth.RpcHandler.ApiMethod}.\n * @param {!fireauth.RpcHandler.ApiMethod} method The method to invoke.\n * @param {!Object} request The input data to the method.\n * @return {!goog.Promise} A promise that resolves with the results of the RPC.\n *     The format of the results can be modified in\n *     {@code fireauth.RpcHandler.ApiMethod}.\n */\nfireauth.RpcHandler.prototype.invokeRpc = function(method, request) {\n  if (!fireauth.object.hasNonEmptyFields(\n      request, method.requestRequiredFields)) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.INTERNAL_ERROR));\n  }\n\n  var useIdentityPlatformEndpoint = !!method.useIdentityPlatformEndpoint;\n  var httpMethod = method.httpMethod || fireauth.RpcHandler.HttpMethod.POST;\n  var self = this;\n  var response;\n  return goog.Promise.resolve(request)\n      .then(method.requestValidator)\n      .then(function() {\n        if (method.returnSecureToken) {\n          // Signal that the client accepts STS tokens, for the legacy Google\n          // Identity Toolkit token to STS token migration.\n          request[fireauth.RpcHandler.USE_STS_TOKEN_PARAM_] = true;\n        }\n        // If tenant ID is explicitly passed in the request, it will override\n        // the tenant ID on RPC handler.\n        if (method.requireTenantId && self.tenantId_ &&\n            (typeof request[fireauth.RpcHandler.TENANT_ID_PARAM_] ===\n             'undefined')) {\n          request[fireauth.RpcHandler.TENANT_ID_PARAM_] = self.tenantId_;\n        }\n        return useIdentityPlatformEndpoint ?\n            self.requestIdentityPlatformEndpoint(method.endpoint, httpMethod,\n                request, method.customErrorMap, method.cachebuster || false) :\n            self.requestFirebaseEndpoint(method.endpoint, httpMethod,\n                request, method.customErrorMap, method.cachebuster || false);\n      })\n      .then(function(tempResponse) {\n        response = tempResponse;\n        // If response processor is available, pass request and response through\n        // it. Modifications would be made using response reference.\n        if (method.responsePreprocessor) {\n          return method.responsePreprocessor(request, response);\n        }\n        return response;\n      })\n      .then(method.responseValidator)\n      .then(function() {\n        if (!method.responseField) {\n          return response;\n        }\n        if (!(method.responseField in response)) {\n          throw new fireauth.AuthError(\n              fireauth.authenum.Error.INTERNAL_ERROR);\n        }\n        return response[method.responseField];\n      });\n};\n\n\n/**\n * Checks if the server response contains errors.\n * @param {!Object} resp The API response.\n * @return {boolean} {@code true} if the response contains errors.\n * @private\n */\nfireauth.RpcHandler.hasError_ = function(resp) {\n  return !!resp['error'];\n};\n\n\n/**\n * Returns the developer facing error corresponding to the server code provided.\n * @param {string} serverErrorCode The server error message.\n * @return {!fireauth.AuthError} The corresponding error object.\n * @private\n */\nfireauth.RpcHandler.getDeveloperErrorFromCode_ = function(serverErrorCode) {\n  // Encapsulate the server error code in a typical server error response with\n  // the code populated within. This will convert the response to a developer\n  // facing one.\n  return fireauth.RpcHandler.getDeveloperError_({\n    'error': {\n      'errors': [\n        {\n          'message': serverErrorCode\n        }\n      ],\n      'code': 400,\n      'message': serverErrorCode\n    }\n  });\n};\n\n\n/**\n * Converts a server response with errors to a developer-facing AuthError.\n * @param {!Object} response The server response.\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map of\n *     backend error codes to client-side errors. Any entries set here\n *     override the default handling of the backend error code.\n * @return {!fireauth.AuthError} The corresponding error object.\n * @private\n */\nfireauth.RpcHandler.getDeveloperError_ =\n    function(response, opt_customErrorMap) {\n  var errorMessage;\n  var apiaryError = fireauth.RpcHandler.getApiaryError_(response);\n  if (apiaryError) {\n    return apiaryError;\n  }\n\n  var serverErrorCode = fireauth.RpcHandler.getErrorCode_(response);\n\n  var errorMap = {};\n\n  // Custom token errors.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_CUSTOM_TOKEN] =\n      fireauth.authenum.Error.INVALID_CUSTOM_TOKEN;\n  errorMap[fireauth.RpcHandler.ServerError.CREDENTIAL_MISMATCH] =\n      fireauth.authenum.Error.CREDENTIAL_MISMATCH;\n  // This can only happen if the SDK sends a bad request.\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_CUSTOM_TOKEN] =\n      fireauth.authenum.Error.INTERNAL_ERROR;\n\n  // Create Auth URI errors.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_IDENTIFIER] =\n      fireauth.authenum.Error.INVALID_EMAIL;\n  // This can only happen if the SDK sends a bad request.\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_CONTINUE_URI] =\n      fireauth.authenum.Error.INTERNAL_ERROR;\n\n  // Sign in with email and password errors (some apply to sign up too).\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_EMAIL] =\n      fireauth.authenum.Error.INVALID_EMAIL;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_PASSWORD] =\n      fireauth.authenum.Error.INVALID_PASSWORD;\n  errorMap[fireauth.RpcHandler.ServerError.USER_DISABLED] =\n      fireauth.authenum.Error.USER_DISABLED;\n  // This can only happen if the SDK sends a bad request.\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_PASSWORD] =\n      fireauth.authenum.Error.INTERNAL_ERROR;\n\n  // Sign up with email and password errors.\n  errorMap[fireauth.RpcHandler.ServerError.EMAIL_EXISTS] =\n      fireauth.authenum.Error.EMAIL_EXISTS;\n  errorMap[fireauth.RpcHandler.ServerError.PASSWORD_LOGIN_DISABLED] =\n      fireauth.authenum.Error.OPERATION_NOT_ALLOWED;\n\n  // Verify assertion for sign in with credential errors:\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_IDP_RESPONSE] =\n      fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_PENDING_TOKEN] =\n      fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n  errorMap[fireauth.RpcHandler.ServerError.FEDERATED_USER_ID_ALREADY_LINKED] =\n      fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_OR_INVALID_NONCE] =\n      fireauth.authenum.Error.MISSING_OR_INVALID_NONCE;\n\n  // Email template errors while sending emails:\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_MESSAGE_PAYLOAD] =\n      fireauth.authenum.Error.INVALID_MESSAGE_PAYLOAD;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_RECIPIENT_EMAIL] =\n      fireauth.authenum.Error.INVALID_RECIPIENT_EMAIL;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_SENDER] =\n      fireauth.authenum.Error.INVALID_SENDER;\n\n  // Send Password reset email errors:\n  errorMap[fireauth.RpcHandler.ServerError.EMAIL_NOT_FOUND] =\n      fireauth.authenum.Error.USER_DELETED;\n  errorMap[fireauth.RpcHandler.ServerError.RESET_PASSWORD_EXCEED_LIMIT] =\n      fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER;\n\n  // Reset password errors:\n  errorMap[fireauth.RpcHandler.ServerError.EXPIRED_OOB_CODE] =\n      fireauth.authenum.Error.EXPIRED_OOB_CODE;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_OOB_CODE] =\n      fireauth.authenum.Error.INVALID_OOB_CODE;\n  // This can only happen if the SDK sends a bad request.\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_OOB_CODE] =\n      fireauth.authenum.Error.INTERNAL_ERROR;\n\n  // Get Auth URI errors:\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_PROVIDER_ID] =\n      fireauth.authenum.Error.INVALID_PROVIDER_ID;\n\n  // Operations that require ID token in request:\n  errorMap[fireauth.RpcHandler.ServerError.CREDENTIAL_TOO_OLD_LOGIN_AGAIN] =\n      fireauth.authenum.Error.CREDENTIAL_TOO_OLD_LOGIN_AGAIN;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_ID_TOKEN] =\n      fireauth.authenum.Error.INVALID_AUTH;\n  errorMap[fireauth.RpcHandler.ServerError.TOKEN_EXPIRED] =\n      fireauth.authenum.Error.TOKEN_EXPIRED;\n  errorMap[fireauth.RpcHandler.ServerError.USER_NOT_FOUND] =\n      fireauth.authenum.Error.TOKEN_EXPIRED;\n\n  // CORS issues.\n  errorMap[fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED] =\n      fireauth.authenum.Error.CORS_UNSUPPORTED;\n\n  // Dynamic link not activated.\n  errorMap[fireauth.RpcHandler.ServerError.DYNAMIC_LINK_NOT_ACTIVATED] =\n      fireauth.authenum.Error.DYNAMIC_LINK_NOT_ACTIVATED;\n\n  // iosBundleId or androidPackageName not valid error.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_APP_ID] =\n      fireauth.authenum.Error.INVALID_APP_ID;\n\n  // Other errors.\n  errorMap[fireauth.RpcHandler.ServerError.TOO_MANY_ATTEMPTS_TRY_LATER] =\n      fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER;\n  errorMap[fireauth.RpcHandler.ServerError.WEAK_PASSWORD] =\n      fireauth.authenum.Error.WEAK_PASSWORD;\n  errorMap[fireauth.RpcHandler.ServerError.OPERATION_NOT_ALLOWED] =\n      fireauth.authenum.Error.OPERATION_NOT_ALLOWED;\n  errorMap[fireauth.RpcHandler.ServerError.USER_CANCELLED] =\n      fireauth.authenum.Error.USER_CANCELLED;\n\n  // Phone Auth related errors.\n  errorMap[fireauth.RpcHandler.ServerError.CAPTCHA_CHECK_FAILED] =\n      fireauth.authenum.Error.CAPTCHA_CHECK_FAILED;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_APP_CREDENTIAL] =\n      fireauth.authenum.Error.INVALID_APP_CREDENTIAL;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_CODE] =\n      fireauth.authenum.Error.INVALID_CODE;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_PHONE_NUMBER] =\n      fireauth.authenum.Error.INVALID_PHONE_NUMBER;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_SESSION_INFO] =\n      fireauth.authenum.Error.INVALID_SESSION_INFO;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_TEMPORARY_PROOF] =\n      fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_APP_CREDENTIAL] =\n      fireauth.authenum.Error.MISSING_APP_CREDENTIAL;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_CODE] =\n      fireauth.authenum.Error.MISSING_CODE;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_PHONE_NUMBER] =\n      fireauth.authenum.Error.MISSING_PHONE_NUMBER;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_SESSION_INFO] =\n      fireauth.authenum.Error.MISSING_SESSION_INFO;\n  errorMap[fireauth.RpcHandler.ServerError.QUOTA_EXCEEDED] =\n      fireauth.authenum.Error.QUOTA_EXCEEDED;\n  errorMap[fireauth.RpcHandler.ServerError.SESSION_EXPIRED] =\n      fireauth.authenum.Error.CODE_EXPIRED;\n  errorMap[fireauth.RpcHandler.ServerError.REJECTED_CREDENTIAL] =\n      fireauth.authenum.Error.REJECTED_CREDENTIAL;\n\n  // Other action code errors when additional settings passed.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_CONTINUE_URI] =\n      fireauth.authenum.Error.INVALID_CONTINUE_URI;\n  // MISSING_CONTINUE_URI is getting mapped to INTERNAL_ERROR above.\n  // This is OK as this error will be caught by client side validation.\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_ANDROID_PACKAGE_NAME] =\n      fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_IOS_BUNDLE_ID] =\n      fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;\n  errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =\n      fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =\n      fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;\n\n  // getProjectConfig errors when clientId is passed.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_OAUTH_CLIENT_ID] =\n      fireauth.authenum.Error.INVALID_OAUTH_CLIENT_ID;\n  // getProjectConfig errors when sha1Cert is passed.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_CERT_HASH] =\n      fireauth.authenum.Error.INVALID_CERT_HASH;\n\n  // Multi-tenant related errors.\n  errorMap[fireauth.RpcHandler.ServerError.UNSUPPORTED_TENANT_OPERATION] =\n      fireauth.authenum.Error.UNSUPPORTED_TENANT_OPERATION;\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_TENANT_ID] =\n      fireauth.authenum.Error.INVALID_TENANT_ID;\n  errorMap[fireauth.RpcHandler.ServerError.TENANT_ID_MISMATCH] =\n      fireauth.authenum.Error.TENANT_ID_MISMATCH;\n\n  // User actions (sign-up or deletion) disabled errors.\n  errorMap[fireauth.RpcHandler.ServerError.ADMIN_ONLY_OPERATION] =\n      fireauth.authenum.Error.ADMIN_ONLY_OPERATION;\n\n  // Multi-factor related errors.\n  errorMap[fireauth.RpcHandler.ServerError.INVALID_MFA_PENDING_CREDENTIAL] =\n      fireauth.authenum.Error.INVALID_MFA_PENDING_CREDENTIAL;\n  errorMap[fireauth.RpcHandler.ServerError.MFA_ENROLLMENT_NOT_FOUND] =\n      fireauth.authenum.Error.MFA_ENROLLMENT_NOT_FOUND;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_MFA_PENDING_CREDENTIAL] =\n      fireauth.authenum.Error.MISSING_MFA_PENDING_CREDENTIAL;\n  errorMap[fireauth.RpcHandler.ServerError.MISSING_MFA_ENROLLMENT_ID] =\n      fireauth.authenum.Error.MISSING_MFA_ENROLLMENT_ID;\n  errorMap[fireauth.RpcHandler.ServerError.EMAIL_CHANGE_NEEDS_VERIFICATION] =\n      fireauth.authenum.Error.EMAIL_CHANGE_NEEDS_VERIFICATION;\n  errorMap[fireauth.RpcHandler.ServerError.SECOND_FACTOR_EXISTS] =\n      fireauth.authenum.Error.SECOND_FACTOR_EXISTS;\n  errorMap[fireauth.RpcHandler.ServerError.SECOND_FACTOR_LIMIT_EXCEEDED] =\n      fireauth.authenum.Error.SECOND_FACTOR_LIMIT_EXCEEDED;\n  errorMap[fireauth.RpcHandler.ServerError.UNSUPPORTED_FIRST_FACTOR] =\n      fireauth.authenum.Error.UNSUPPORTED_FIRST_FACTOR;\n  errorMap[fireauth.RpcHandler.ServerError.UNVERIFIED_EMAIL] =\n      fireauth.authenum.Error.UNVERIFIED_EMAIL;\n\n  // Override errors set in the custom map.\n  var customErrorMap = opt_customErrorMap || {};\n  goog.object.extend(errorMap, customErrorMap);\n\n  // Get detailed message if available.\n  errorMessage = fireauth.RpcHandler.getErrorCodeDetails(serverErrorCode);\n\n  // Handle backend errors where the error code can be a prefix of the message\n  // (e.g. \"WEAK_PASSWORD : Password should be at least 6 characters\").\n  // Use the details after the colon as the error message. If none available,\n  // pass undefined, which will default to the client hard coded error messages.\n  for (var prefixCode in errorMap) {\n    if (serverErrorCode.indexOf(prefixCode) === 0) {\n      return new fireauth.AuthError(errorMap[prefixCode], errorMessage);\n    }\n  }\n\n  // No error message found, return the serialized response as the message.\n  // This is likely to be an Apiary error for unexpected cases like keyExpired,\n  // etc.\n  if (!errorMessage && response) {\n     errorMessage = fireauth.util.stringifyJSON(response);\n  }\n  // The backend returned some error we don't recognize; this is an error on\n  // our side.\n  return new fireauth.AuthError(\n      fireauth.authenum.Error.INTERNAL_ERROR, errorMessage);\n};\n\n\n/**\n * @param {string} serverMessage The server error code.\n * @return {string|undefined} The detailed error code message.\n */\nfireauth.RpcHandler.getErrorCodeDetails = function(serverMessage) {\n  // Use the error details part as the autherror message.\n  // For a message INVALID_CUSTOM_TOKEN : [error detail here],\n  // The Auth error message should be [error detail here].\n  // No space should be contained in the error code, otherwise no detailed error\n  // message returned.\n  var matches = serverMessage.match(/^[^\\s]+\\s*:\\s*([\\s\\S]*)$/);\n  if (matches && matches.length > 1) {\n    return matches[1];\n  }\n  return undefined;\n};\n\n\n/**\n * Gets the Apiary error from a backend response, if applicable.\n * @param {!Object} response The API response.\n * @return {?fireauth.AuthError} The error, if applicable.\n * @private\n */\nfireauth.RpcHandler.getApiaryError_ = function(response) {\n  var error = response['error'] && response['error']['errors'] &&\n      response['error']['errors'][0] || {};\n  var reason = error['reason'] || '';\n\n  var errorReasonMap = {\n    'keyInvalid': fireauth.authenum.Error.INVALID_API_KEY,\n    'ipRefererBlocked': fireauth.authenum.Error.APP_NOT_AUTHORIZED\n  };\n\n  if (errorReasonMap[reason]) {\n    return new fireauth.AuthError(errorReasonMap[reason]);\n  }\n\n  return null;\n};\n\n\n/**\n * Gets the server error code from the response.\n * @param {!Object} resp The API response.\n * @return {string} The error code if present.\n * @private\n */\nfireauth.RpcHandler.getErrorCode_ = function(resp) {\n  return (resp['error'] && resp['error']['message']) || '';\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines fireauth.iframeclient.IframeWrapper used to communicate\n * with the hidden iframe to detect Auth events.\n */\n\ngoog.provide('fireauth.iframeclient.IframeWrapper');\n\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.string.Const');\n\n\n/**\n * Defines the hidden iframe wrapper for cross origin communications.\n * @param {string} url The hidden iframe src URL.\n * @constructor\n */\nfireauth.iframeclient.IframeWrapper = function(url) {\n  /** @private {string} The hidden iframe URL. */\n  this.url_ = url;\n\n  /**\n   * @type {?gapi.iframes.Iframe}\n   * @private\n   */\n  this.iframe_ = null;\n\n  /** @private {!goog.Promise} A promise that resolves on iframe open. */\n  this.onIframeOpen_ = this.open_();\n};\n\n\n/**\n * @typedef {{\n *   type: string\n * }}\n */\nfireauth.iframeclient.IframeWrapper.Message;\n\n/**\n * Returns URL, src of the hidden iframe.\n * @return {string}\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.getPath_ = function() {\n  return this.url_;\n};\n\n\n/**\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n */\nfireauth.iframeclient.IframeWrapper.prototype.onReady = function() {\n  return this.onIframeOpen_;\n};\n\n\n/**\n * Returns options used to open the iframe.\n * @return {!gapi.iframes.OptionsBag}\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.getOptions_ = function() {\n  var options = /** @type {!gapi.iframes.OptionsBag} */ ({\n    'where': document.body,\n    'url': this.getPath_(),\n    'messageHandlersFilter': /** @type {!gapi.iframes.IframesFilter} */ (\n        fireauth.util.getObjectRef(\n            'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')),\n    'attributes': {\n      'style': {\n        'position': 'absolute',\n        'top': '-100px',\n        'width': '1px',\n        'height': '1px'\n      }\n    },\n    'dontclear': true\n  });\n  return options;\n};\n\n\n/**\n * Opens an iframe.\n * @return {!goog.Promise} A promise that resolves on successful iframe open.\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.open_ = function() {\n  var self = this;\n  return fireauth.iframeclient.IframeWrapper.loadGApiJs_().then(function() {\n    return new goog.Promise(function(resolve, reject) {\n      /**\n       * @param {?gapi.iframes.Iframe} iframe The new opened iframe.\n       */\n      var onOpen = function(iframe) {\n        self.iframe_ = iframe;\n        self.iframe_.restyle({\n          // Prevent iframe from closing on mouse out.\n          'setHideOnLeave': false\n        });\n        // Confirm iframe is correctly loaded.\n        // To fallback on failure, set a timeout.\n        var networkErrorTimer = setTimeout(function() {\n          reject(new Error('Network Error'));\n        }, fireauth.iframeclient.IframeWrapper.PING_TIMEOUT_.get());\n        // Clear timer and resolve pending iframe ready promise.\n        var clearTimerAndResolve = function() {\n          clearTimeout(networkErrorTimer);\n          resolve();\n        };\n        // This returns an IThenable. However the reject part does not call\n        // when the iframe is not loaded.\n        iframe.ping(clearTimerAndResolve).then(\n            clearTimerAndResolve,\n            function(error) { reject(new Error('Network Error')); });\n      };\n      /** @type {function():!gapi.iframes.Context} */ (\n          fireauth.util.getObjectRef('gapi.iframes.getContext'))().open(\n              self.getOptions_(), onOpen);\n    });\n  });\n};\n\n\n/**\n * @param {!fireauth.iframeclient.IframeWrapper.Message} message to send.\n * @return {!goog.Promise<?Object>} The promise that resolve when message is\n *     sent.\n */\nfireauth.iframeclient.IframeWrapper.prototype.sendMessage = function(message) {\n  var self = this;\n  return this.onIframeOpen_.then(function() {\n    return new goog.Promise(function(resolve, reject) {\n      self.iframe_.send(\n          message['type'],\n          message,\n          resolve,\n          /** @type {!gapi.iframes.IframesFilter} */ (\n              fireauth.util.getObjectRef(\n                  'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')));\n\n    });\n  });\n};\n\n\n/**\n * Registers a listener to a post message.\n * @param {string} eventName The message to register for.\n * @param {gapi.iframes.MessageHandler} handler Message handler.\n */\nfireauth.iframeclient.IframeWrapper.prototype.registerEvent =\n    function(eventName, handler) {\n  var self = this;\n  this.onIframeOpen_.then(function() {\n    self.iframe_.register(\n        eventName,\n        /** @type {function(this:gapi.iframes.Iframe,\n         *                  *, gapi.iframes.Iframe): *}\n         */ (handler),\n        /** @type {!gapi.iframes.IframesFilter} */ (\n            fireauth.util.getObjectRef(\n                'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')));\n  });\n};\n\n\n/**\n * Unregisters a listener to a post message.\n * @param {string} eventName The message to unregister.\n * @param {gapi.iframes.MessageHandler} handler Message handler.\n */\nfireauth.iframeclient.IframeWrapper.prototype.unregisterEvent =\n    function(eventName, handler) {\n  var self = this;\n  this.onIframeOpen_.then(function() {\n    self.iframe_.unregister(\n        eventName,\n        /** @type {(function(this:gapi.iframes.Iframe,\n         *                   *, gapi.iframes.Iframe): *|undefined)}\n         */ (handler));\n  });\n};\n\n\n/** @private @const {!goog.string.Const} The GApi loader URL. */\nfireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_ = goog.string.Const.from(\n    'https://apis.google.com/js/api.js?onload=%{onload}');\n\n\n/**\n * @private @const {!fireauth.util.Delay} The gapi.load network error timeout\n *     delay with units in ms.\n */\nfireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_ =\n    new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * @private @const {!fireauth.util.Delay} The iframe ping error timeout delay\n *     with units in ms.\n */\nfireauth.iframeclient.IframeWrapper.PING_TIMEOUT_ =\n    new fireauth.util.Delay(5000, 15000);\n\n\n/** @private {?goog.Promise} The cached GApi loader promise. */\nfireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n\n\n/** Resets the cached GApi loader. */\nfireauth.iframeclient.IframeWrapper.resetCachedGApiLoader = function() {\n  fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n};\n\n\n\n/**\n * Loads the GApi client library if it is not loaded for gapi.iframes usage.\n * @return {!goog.Promise} A promise that resolves when gapi.iframes is loaded.\n * @private\n */\nfireauth.iframeclient.IframeWrapper.loadGApiJs_ = function() {\n  // If already pending or resolved, return the cached promise.\n  if (fireauth.iframeclient.IframeWrapper.cachedGApiLoader_) {\n    return fireauth.iframeclient.IframeWrapper.cachedGApiLoader_;\n  }\n  // If there is no cached promise, initialize a new one.\n  fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ =\n      new goog.Promise(function(resolve, reject) {\n    // Function to run when gapi.load is ready.\n    var onGapiLoad = function() {\n      // The developer may have tried to previously run gapi.load and failed.\n      // Run this to fix that.\n      fireauth.util.resetUnloadedGapiModules();\n      var loader = /** @type {function(string, !Object)} */ (\n          fireauth.util.getObjectRef('gapi.load'));\n      loader('gapi.iframes', {\n        'callback': resolve,\n        'ontimeout': function() {\n          // The above reset may be sufficient, but having this reset after\n          // failure ensures that if the developer calls gapi.load after the\n          // connection is re-established and before another attempt to embed\n          // the iframe, it would work and would not be broken because of our\n          // failed attempt.\n          // Timeout when gapi.iframes.Iframe not loaded.\n          fireauth.util.resetUnloadedGapiModules();\n          reject(new Error('Network Error'));\n        },\n        'timeout': fireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_.get()\n      });\n    };\n    if (fireauth.util.getObjectRef('gapi.iframes.Iframe')) {\n      // If gapi.iframes.Iframe available, resolve.\n      resolve();\n    } else if (fireauth.util.getObjectRef('gapi.load')) {\n      // Gapi loader ready, load gapi.iframes.\n      onGapiLoad();\n    } else {\n      // Create a new iframe callback when this is called so as not to overwrite\n      // any previous defined callback. This happens if this method is called\n      // multiple times in parallel and could result in the later callback\n      // overwriting the previous one. This would end up with a iframe\n      // timeout.\n      var cbName = '__iframefcb' +\n          Math.floor(Math.random() * 1000000).toString();\n      // GApi loader not available, dynamically load platform.js.\n      goog.global[cbName] = function() {\n        // GApi loader should be ready.\n        if (fireauth.util.getObjectRef('gapi.load')) {\n          onGapiLoad();\n        } else {\n          // Gapi loader failed, throw error.\n          reject(new Error('Network Error'));\n        }\n      };\n      // Build GApi loader.\n      var url = goog.html.TrustedResourceUrl.format(\n          fireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_,\n          {'onload': cbName});\n      // Load GApi loader.\n      var result = goog.Promise.resolve(goog.net.jsloader.safeLoad(url));\n      result.thenCatch(function(error) {\n        // In case library fails to load, typically due to a network error,\n        // reset cached loader to null to force a refresh on a retrial.\n        reject(new Error('Network Error'));\n      });\n    }\n  }).thenCatch(function(error) {\n    // Reset cached promise to allow for retrial.\n    fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n    throw error;\n  });\n  return fireauth.iframeclient.IframeWrapper.cachedGApiLoader_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines fireauth.iframeclient.IfcHandler used to communicate\n * with the serverless widget.\n */\n\ngoog.provide('fireauth.iframeclient.IfcHandler');\ngoog.provide('fireauth.iframeclient.IframeUrlBuilder');\ngoog.provide('fireauth.iframeclient.OAuthUrlBuilder');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.InvalidOriginError');\ngoog.require('fireauth.OAuthSignInHandler');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.iframeclient.IframeWrapper');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * The OAuth handler and iframe prototcol.\n * @const {string}\n * @suppress {const|duplicate}\n */\nfireauth.iframeclient.SCHEME = 'https';\n\n\n\n/**\n * The OAuth handler and iframe port number.\n * @const {?number}\n * @suppress {const|duplicate}\n */\nfireauth.iframeclient.PORT_NUMBER = null;\n\n\n\n/**\n * The iframe URL builder used to build the iframe widget URL.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @constructor\n */\nfireauth.iframeclient.IframeUrlBuilder = function(authDomain, apiKey, appName) {\n  /** @private {string} The application authDomain. */\n  this.authDomain_ = authDomain;\n  /** @private {string} The API key. */\n  this.apiKey_ = apiKey;\n  /** @private {string} The App name. */\n  this.appName_ = appName;\n  /** @private {?string|undefined} The client version. */\n  this.v_ = null;\n  /**\n   * @private {!goog.Uri} The URI object used to build the iframe URL.\n   */\n  this.uri_ = goog.Uri.create(\n      fireauth.iframeclient.SCHEME,\n      null,\n      this.authDomain_,\n      fireauth.iframeclient.PORT_NUMBER,\n      '/__/auth/iframe',\n      null,\n      null);\n  this.uri_.setParameterValue('apiKey', this.apiKey_);\n  this.uri_.setParameterValue('appName', this.appName_);\n  /** @private {?string|undefined} The endpoint ID. */\n  this.endpointId_ = null;\n  /** @private {!Array<string>} The list of framework IDs. */\n  this.frameworks_ = [];\n};\n\n\n/**\n * Sets the client version.\n * @param {?string|undefined} v The client version.\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n *     builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setVersion = function(v) {\n  this.v_ = v;\n  return this;\n};\n\n\n/**\n * Sets the endpoint ID.\n * @param {?string|undefined} eid The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n *     builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setEndpointId = function(eid) {\n  this.endpointId_ = eid;\n  return this;\n};\n\n\n/**\n * Sets the list of frameworks to pass to the iframe.\n * @param {?Array<string>|undefined} frameworks The list of frameworks to log.\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n *     builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setFrameworks =\n    function(frameworks) {\n  this.frameworks_ = goog.array.clone(frameworks || []);\n  return this;\n};\n\n\n/**\n * Modifes the URI with the relevant Auth provider parameters.\n * @return {string} The constructed OAuth URL string.\n * @override\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.toString = function() {\n  // Pass the client version if available.\n  if (this.v_) {\n    this.uri_.setParameterValue('v', this.v_);\n  } else {\n    this.uri_.removeParameter('v');\n  }\n  // Pass the endpoint ID if available.\n  if (this.endpointId_) {\n    this.uri_.setParameterValue('eid', this.endpointId_);\n  } else {\n    this.uri_.removeParameter('eid');\n  }\n  // Pass the list of frameworks if available.\n  if (this.frameworks_.length) {\n    this.uri_.setParameterValue('fw', this.frameworks_.join(','));\n  } else {\n    this.uri_.removeParameter('fw');\n  }\n  return this.uri_.toString();\n};\n\n\n\n/**\n * The OAuth URL builder used to build the OAuth handler widget URL.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @param {string} authType The Auth operation type.\n * @param {!fireauth.AuthProvider} provider The Auth provider that the OAuth\n *     handler request is built to sign in to.\n * @constructor\n */\nfireauth.iframeclient.OAuthUrlBuilder =\n    function(authDomain, apiKey, appName, authType, provider) {\n  /** @private {string} The application authDomain. */\n  this.authDomain_ = authDomain;\n  /** @private {string} The API key. */\n  this.apiKey_ = apiKey;\n  /** @private {string} The App name. */\n  this.appName_ = appName;\n  /** @private {string} The Auth operation type. */\n  this.authType_ = authType;\n  /**\n   * @private {?string|undefined} The redirect URL used in redirect operations.\n   */\n  this.redirectUrl_ = null;\n  /** @private {?string|undefined} The event ID. */\n  this.eventId_ = null;\n  /** @private {?string|undefined} The client version. */\n  this.v_ = null;\n  /**\n   * @private {!fireauth.AuthProvider} The Firebase Auth provider that the OAuth\n   *     handler request is built to sign in to.\n   */\n  this.provider_ = provider;\n  /** @private {?string|undefined} The endpoint ID. */\n  this.endpointId_ = null;\n  /** @private {?string|undefined} The tenant ID. */\n  this.tenantId_ = null;\n};\n\n\n/**\n * Sets the redirect URL.\n * @param {?string|undefined} redirectUrl The redirect URL used in redirect\n *     operations.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setRedirectUrl =\n    function(redirectUrl) {\n  this.redirectUrl_ = redirectUrl;\n  return this;\n};\n\n\n/**\n * Sets the event ID.\n * @param {?string|undefined} eventId The event ID.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setEventId = function(eventId) {\n  this.eventId_ = eventId;\n  return this;\n};\n\n\n/**\n * Sets the tenant ID.\n * @param {?string|undefined} tenantId The event ID.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setTenantId =\n    function(tenantId) {\n  this.tenantId_ = tenantId;\n  return this;\n};\n\n\n/**\n * Sets the client version.\n * @param {?string|undefined} v The client version.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setVersion = function(v) {\n  this.v_ = v;\n  return this;\n};\n\n\n/**\n * Sets the endpoint ID.\n * @param {?string|undefined} eid The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setEndpointId = function(eid) {\n  this.endpointId_ = eid;\n  return this;\n};\n\n\n/**\n * Sets any additional optional parameters. This will overwrite any previously\n * set additional parameters.\n * @param {?Object<string, string>|undefined} additionalParams The optional\n *     additional parameters.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n *     builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setAdditionalParameters =\n    function(additionalParams) {\n  this.additionalParams_ = goog.object.clone(additionalParams || null);\n  return this;\n};\n\n\n/**\n * Modifies the URI with the relevant Auth provider parameters.\n * @return {string} The constructed OAuth URL string.\n * @override\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.toString = function() {\n  var uri = goog.Uri.create(\n      fireauth.iframeclient.SCHEME,\n      null,\n      this.authDomain_,\n      fireauth.iframeclient.PORT_NUMBER,\n      '/__/auth/handler',\n      null,\n      null);\n  uri.setParameterValue('apiKey', this.apiKey_);\n  uri.setParameterValue('appName', this.appName_);\n  uri.setParameterValue('authType', this.authType_);\n\n  // Add custom parameters for OAuth1/OAuth2 providers.\n  if (this.provider_['isOAuthProvider']) {\n    // Set default language if available and no language already set.\n    /** @type {!fireauth.FederatedProvider} */ (this.provider_)\n        .setDefaultLanguage(this.getAuthLanguage_());\n    uri.setParameterValue('providerId', this.provider_['providerId']);\n    var customParameters = /** @type {!fireauth.FederatedProvider} */ (\n        this.provider_).getCustomParameters();\n    if (!goog.object.isEmpty(customParameters)) {\n      uri.setParameterValue(\n          'customParameters',\n          /** @type {string} */ (fireauth.util.stringifyJSON(customParameters))\n          );\n    }\n  }\n\n  // Add scopes for OAuth2 providers.\n  if (typeof this.provider_.getScopes === 'function') {\n    var scopes = this.provider_.getScopes();\n    if (scopes.length) {\n      uri.setParameterValue('scopes', scopes.join(','));\n    }\n  }\n\n  if (this.redirectUrl_) {\n    uri.setParameterValue('redirectUrl', this.redirectUrl_);\n  } else {\n    uri.removeParameter('redirectUrl');\n  }\n  if (this.eventId_) {\n    uri.setParameterValue('eventId', this.eventId_);\n  } else {\n    uri.removeParameter('eventId');\n  }\n  // Pass the client version if available.\n  if (this.v_) {\n    uri.setParameterValue('v', this.v_);\n  } else {\n    uri.removeParameter('v');\n  }\n  if (this.additionalParams_) {\n    for (var key in this.additionalParams_) {\n      if (this.additionalParams_.hasOwnProperty(key) &&\n          // Don't overwrite other existing parameters.\n          !uri.getParameterValue(key)) {\n        uri.setParameterValue(key, this.additionalParams_[key]);\n      }\n    }\n  }\n  // Pass the tenant ID if available.\n  if (this.tenantId_) {\n    uri.setParameterValue('tid', this.tenantId_);\n  } else {\n    uri.removeParameter('tid');\n  }\n  // Pass the endpoint ID if available.\n  if (this.endpointId_) {\n    uri.setParameterValue('eid', this.endpointId_);\n  } else {\n    uri.removeParameter('eid');\n  }\n  // Append any framework IDs to the handler URL to log in handler RPC requests.\n  var frameworks = this.getAuthFrameworks_();\n  if (frameworks.length) {\n    uri.setParameterValue('fw', frameworks.join(','));\n  }\n  return uri.toString();\n};\n\n\n/**\n * Returns the current Auth instance's language code.\n * @return {?string} The corresponding language code.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.getAuthLanguage_ = function() {\n  try {\n    // Get the Auth instance for the current App identified by the App name.\n    // This could fail if, for example, the App instance was deleted.\n    return firebase['app'](this.appName_)['auth']().getLanguageCode();\n  } catch (e) {\n    return null;\n  }\n};\n\n\n/**\n * Returns the list of Firebase frameworks used for logging purposes.\n * @return {!Array<string>} The list of corresponding Firebase frameworks.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.getAuthFrameworks_ =\n    function() {\n  return fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n      this.appName_);\n};\n\n\n/**\n * Returns the list of Firebase frameworks used for logging purposes\n * corresponding to the Firebase App name provided.\n * @param {string} appName The Firebase App name.\n * @return {!Array<string>} The list of corresponding Firebase frameworks.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_ =\n    function(appName) {\n  try {\n    // Get the Auth instance's list of Firebase framework IDs for the current\n    // App identified by the App name.\n    // This could fail if, for example, the App instance was deleted.\n    return firebase['app'](appName)['auth']().getFramework();\n  } catch (e) {\n    return [];\n  }\n};\n\n\n\n/**\n * Initializes the ifcHandler which provides the mechanism to listen to Auth\n * events on the hidden iframe.\n * @param {string} authDomain The firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n *     request.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @constructor\n * @implements {fireauth.OAuthSignInHandler}\n */\nfireauth.iframeclient.IfcHandler = function(authDomain, apiKey, appName,\n    opt_clientVersion, opt_endpointId) {\n  /** @private {string} The Auth domain. */\n  this.authDomain_ = authDomain;\n  /** @private {string} The API key. */\n  this.apiKey_ = apiKey;\n  /** @private {string} The App name. */\n  this.appName_ = appName;\n  /** @private {?string} The client version. */\n  this.clientVersion_ = opt_clientVersion || null;\n  /** @private {?string} The Auth endpoint ID. */\n  this.endpointId_ = opt_endpointId || null;\n  // Delay RPC handler and iframe URL initialization until needed to ensure\n  // logged frameworks are propagated to the iframe.\n  /** @private {?string} The full client version string. */\n  this.fullClientVersion_ = null;\n  /** @private {?string} The iframe URL. */\n  this.iframeUrl_ = null;\n  /** @private {?fireauth.RpcHandler} The RPC handler for provided API key. */\n  this.rpcHandler_ = null;\n  /**\n   * @private {!Array<!function(?fireauth.AuthEvent)>} The Auth event\n   *     listeners.\n   */\n  this.authEventListeners_ = [];\n  // Delay origin validator determination until needed, so the error is not\n  // thrown in the background. This will also prevent the getProjectConfig RPC\n  // until it is required.\n  /** @private {?goog.Promise} The origin validator. */\n  this.originValidator_ = null;\n  /** @private {?goog.Promise} The initialization promise. */\n  this.isInitialized_ = null;\n};\n\n\n/**\n * Validates the provided URL.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler used to validate the\n *     requested origin.\n * @param {string=} opt_origin The optional page origin. If not provided, the\n *     window.location.href value is used.\n * @return {!goog.Promise} The promise that resolves if the provided origin is\n *     valid.\n * @private\n */\nfireauth.iframeclient.IfcHandler.getOriginValidator_ =\n    function(rpcHandler, opt_origin) {\n  var origin = opt_origin || fireauth.util.getCurrentUrl();\n  return rpcHandler.getAuthorizedDomains().then(function(authorizedDomains) {\n    if (!fireauth.util.isAuthorizedDomain(authorizedDomains, origin)) {\n      throw new fireauth.InvalidOriginError(fireauth.util.getCurrentUrl());\n    }\n  });\n};\n\n\n/**\n * Initializes the iframe client wrapper.\n * @return {!goog.Promise} The promise that resolves on initialization.\n */\nfireauth.iframeclient.IfcHandler.prototype.initialize = function() {\n  // Already initialized.\n  if (this.isInitialized_) {\n    return this.isInitialized_;\n  }\n  var self = this;\n  this.isInitialized_ = fireauth.util.onDomReady().then(function() {\n    /**\n     * @private {!fireauth.iframeclient.IframeWrapper} The iframe wrapper\n     *     instance.\n     */\n    self.iframeWrapper_ = new fireauth.iframeclient.IframeWrapper(\n        self.getIframeUrl());\n    // Register all event listeners to Auth event messages sent from Auth\n    // iframe.\n    self.registerEvents_();\n  });\n  return this.isInitialized_;\n};\n\n\n/**\n * Waits for popup window to close. When closed start timeout listener for popup\n * pending promise. If in the process, it was detected that the iframe does not\n * support web storage, the popup is closed and the web storage unsupported\n * error is thrown.\n * @param {!Window} popupWin The popup window.\n * @param {!function(!fireauth.AuthError)} onError The on error callback.\n * @param {number} timeoutDuration The time to wait in ms after the popup is\n *     closed before triggering the popup closed by user error.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.startPopupTimeout =\n    function(popupWin, onError, timeoutDuration) {\n  // Expire pending timeout promise for popup operation.\n  var popupClosedByUserError = new fireauth.AuthError(\n      fireauth.authenum.Error.POPUP_CLOSED_BY_USER);\n  // If web storage is disabled in the iframe, expire popup timeout quickly with\n  // this error.\n  var webStorageNotSupportedError = new fireauth.AuthError(\n      fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n  var self = this;\n  var isResolved = false;\n  // Wait for the iframe to be ready first.\n  return this.initializeAndWait().then(function() {\n    // We do not return isWebStorageSupported() to ensure that this is backward\n    // compatible.\n    // Pushing the following client changes before updating the iframe to\n    // respond to these events would continue to work.\n    // The downside is that the popup could be closed before this resolves.\n    // In that case, they would get an error that the popup was closed and not\n    // the error that web storage is not supported, though that is unlikely\n    // as isWebStorageSupported should execute faster than the popup timeout.\n    // If web storage is not supported in the iframe, fail quickly.\n    self.isWebStorageSupported().then(function(isSupported) {\n      if (!isSupported) {\n        // If not supported, close window.\n        if (popupWin) {\n          fireauth.util.closeWindow(popupWin);\n        }\n        onError(webStorageNotSupportedError);\n        isResolved = true;\n      }\n    });\n  }).thenCatch(function(error) {\n    // Ignore any possible error in iframe embedding.\n    // These types of errors will be handled in processPopup which will close\n    // the popup too if that happens.\n    return;\n  }).then(function() {\n    // Skip if already resolved.\n    if (isResolved) {\n      return;\n    }\n    // After the iframe is ready, wait for popup to close and then start timeout\n    // check.\n    return fireauth.util.onPopupClose(popupWin);\n  }).then(function() {\n    // Skip if already resolved.\n    if (isResolved) {\n      return;\n    }\n    return goog.Timer.promise(timeoutDuration).then(function() {\n      // If this is already resolved or rejected, this will do nothing.\n      onError(popupClosedByUserError);\n    });\n  });\n};\n\n\n/**\n * @return {boolean} Whether the handler should be initialized early.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.shouldBeInitializedEarly =\n    function() {\n  var ua = fireauth.util.getUserAgentString();\n  // Cannot run in the background (can't wait for iframe to be embedded\n  // before triggering popup redirect) and is Safari (can only detect\n  // localStorage in iframe via change event) => embed iframe ASAP.\n  // Do the same for mobile browsers on iOS devices as they use the same\n  // Safari implementation underneath.\n  return !fireauth.util.runsInBackground(ua) &&\n         !fireauth.util.iframeCanSyncWebStorage(ua);\n};\n\n\n/**\n * @return {boolean} Whether the sign-in handler in the current environment\n *     has volatile session storage.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.hasVolatileStorage = function() {\n  // Web environment with web storage enabled has stable sessionStorage.\n  return false;\n};\n\n\n/**\n * Processes the popup request. The popup instance must be provided externally\n * and on error, the requestor must close the window.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function()} onInitialize The function to call on initialization.\n * @param {function(*)} onError The function to call on error.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n *     to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.processPopup = function(\n    popupWin,\n    mode,\n    provider,\n    onInitialize,\n    onError,\n    opt_eventId,\n    opt_alreadyRedirected,\n    opt_tenantId) {\n  // processPopup is failing since it tries to access popup win when tab can\n  // not run in background. For now bypass processPopup which runs\n  // additional origin check not accounted above. Besides, iframe will never\n  // hand result to parent if origin not whitelisted.\n  // Error thrown by browser: Unable to establish a connection with the\n  // popup. It may have been blocked by the browser.\n  // If popup is null, startPopupTimeout will catch it without having the\n  // above error getting triggered due to popup access from opener.\n\n  // Reject immediately if the popup is blocked.\n  if (!popupWin) {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.POPUP_BLOCKED));\n  }\n  // Already redirected and cannot run in the background, resolve quickly while\n  // initializing.\n  if (opt_alreadyRedirected && !fireauth.util.runsInBackground()) {\n    // Initialize first before resolving.\n    this.initializeAndWait().thenCatch(function(error) {\n      fireauth.util.closeWindow(popupWin);\n      onError(error);\n    });\n    onInitialize();\n    // Already redirected.\n    return goog.Promise.resolve();\n  }\n  // If origin validator not determined yet.\n  if (!this.originValidator_) {\n    this.originValidator_ =\n        fireauth.iframeclient.IfcHandler.getOriginValidator_(\n            this.getRpcHandler_());\n  }\n  var self = this;\n  return this.originValidator_.then(function() {\n    // After origin validation, wait for iframe to be ready before redirecting.\n    var onReady = self.initializeAndWait().thenCatch(function(error) {\n      fireauth.util.closeWindow(popupWin);\n      onError(error);\n      throw error;\n    });\n    onInitialize();\n    return onReady;\n  }).then(function() {\n    // Popup and redirect operations work for OAuth providers only.\n    fireauth.AuthProvider.checkIfOAuthSupported(provider);\n    // Already redirected to intended destination, no need to redirect again.\n    if (opt_alreadyRedirected) {\n      return;\n    }\n    var oauthHelperWidgetUrl =\n        fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n            self.authDomain_,\n            self.apiKey_,\n            self.appName_,\n            mode,\n            provider,\n            null,\n            opt_eventId,\n            self.clientVersion_,\n            undefined,\n            self.endpointId_,\n            opt_tenantId);\n    // Redirect popup to OAuth helper widget URL.\n    fireauth.util.goTo(oauthHelperWidgetUrl, /** @type {!Window} */ (popupWin));\n  }).thenCatch(function(e) {\n    // Force another origin validation.\n    if (e.code == 'auth/network-request-failed') {\n      self.originValidator_ = null;\n    }\n    throw e;\n  });\n};\n\n\n/**\n * @return {!fireauth.RpcHandler} The RPC handler instance with the relevant\n *     endpoints, version and frameworks.\n * @private\n */\nfireauth.iframeclient.IfcHandler.prototype.getRpcHandler_ = function() {\n  if (!this.rpcHandler_) {\n    this.fullClientVersion_ = this.clientVersion_ ?\n        fireauth.util.getClientVersion(\n            fireauth.util.ClientImplementation.JSCORE,\n            this.clientVersion_,\n            fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n                this.appName_)) :\n        null;\n    this.rpcHandler_ = new fireauth.RpcHandler(\n        this.apiKey_,\n        // Get the client Auth endpoint used.\n        fireauth.constants.getEndpointConfig(this.endpointId_),\n        this.fullClientVersion_);\n  }\n  return this.rpcHandler_;\n};\n\n\n/**\n * Processes the redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.processRedirect =\n    function(mode, provider, opt_eventId, opt_tenantId) {\n  // If origin validator not determined yet.\n  if (!this.originValidator_) {\n    this.originValidator_ =\n        fireauth.iframeclient.IfcHandler.getOriginValidator_(\n            this.getRpcHandler_());\n  }\n  var self = this;\n  // Make sure origin is validated.\n  return this.originValidator_.then(function() {\n    fireauth.AuthProvider.checkIfOAuthSupported(provider);\n    var oauthHelperWidgetUrl =\n        fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n            self.authDomain_,\n            self.apiKey_,\n            self.appName_,\n            mode,\n            provider,\n            fireauth.util.getCurrentUrl(),\n            opt_eventId,\n            self.clientVersion_,\n            undefined,\n            self.endpointId_,\n            opt_tenantId);\n    // Redirect to OAuth helper widget URL.\n    fireauth.util.goTo(oauthHelperWidgetUrl);\n  }).thenCatch(function(e) {\n    // Force another origin validation on network errors.\n    if (e.code == 'auth/network-request-failed') {\n      self.originValidator_ = null;\n    }\n    throw e;\n  });\n};\n\n\n/** @return {string} The iframe URL. */\nfireauth.iframeclient.IfcHandler.prototype.getIframeUrl = function() {\n  if (!this.iframeUrl_) {\n    this.iframeUrl_ = fireauth.iframeclient.IfcHandler.getAuthIframeUrl(\n        this.authDomain_, this.apiKey_, this.appName_, this.clientVersion_,\n        this.endpointId_,\n        fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n            this.appName_));\n  }\n  return this.iframeUrl_;\n};\n\n\n/**\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.initializeAndWait = function() {\n  // Initialize if not initialized yet.\n  var self = this;\n  return this.initialize().then(function() {\n    return self.iframeWrapper_.onReady();\n  }).thenCatch(function(error) {\n    // Reset origin validator.\n    self.originValidator_ = null;\n    // Reject iframe ready promise with network error.\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.NETWORK_REQUEST_FAILED);\n  });\n};\n\n\n/**\n * @return {boolean} Whether the handler will unload the current page on\n *     redirect operations.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.unloadsOnRedirect = function() {\n  return true;\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n *     request.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @param {?Array<string>=} opt_frameworks The optional list of framework IDs.\n * @return {string} The data iframe src URL.\n */\nfireauth.iframeclient.IfcHandler.getAuthIframeUrl = function(authDomain, apiKey,\n    appName, opt_clientVersion, opt_endpointId, opt_frameworks) {\n  // OAuth helper iframe URL.\n  var builder = new fireauth.iframeclient.IframeUrlBuilder(\n      authDomain, apiKey, appName);\n  return builder\n      .setVersion(opt_clientVersion)\n      .setEndpointId(opt_endpointId)\n      .setFrameworks(opt_frameworks)\n      .toString();\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n *     request.\n * @param {string} authType The type of operation that depends on OAuth sign in.\n * @param {!fireauth.AuthProvider} provider The provider to sign in to.\n * @param {?string=} opt_redirectUrl The optional URL to redirect to on OAuth\n *     sign in completion.\n * @param {?string=} opt_eventId The optional event ID to identify on receipt.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?Object<string, string>=} opt_additionalParams The optional\n *     additional parameters.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {string} The OAuth helper widget URL.\n */\nfireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl = function(\n    authDomain,\n    apiKey,\n    appName,\n    authType,\n    provider,\n    opt_redirectUrl,\n    opt_eventId,\n    opt_clientVersion,\n    opt_additionalParams,\n    opt_endpointId,\n    opt_tenantId) {\n  // OAuth helper widget URL.\n  var builder = new fireauth.iframeclient.OAuthUrlBuilder(\n      authDomain, apiKey, appName, authType, provider);\n  return builder\n      .setRedirectUrl(opt_redirectUrl)\n      .setEventId(opt_eventId)\n      .setVersion(opt_clientVersion)\n      .setAdditionalParameters(opt_additionalParams)\n      .setEndpointId(opt_endpointId)\n      .setTenantId(opt_tenantId)\n      .toString();\n};\n\n\n/**\n * Post message receiver event names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.ReceiverEvent = {\n  AUTH_EVENT: 'authEvent'\n};\n\n\n/**\n * Post message sender event names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.SenderEvent = {\n  WEB_STORAGE_SUPPORT_EVENT: 'webStorageSupport'\n};\n\n\n/**\n * Post message response field names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.Response = {\n  STATUS: 'status',\n  AUTH_EVENT: 'authEvent',\n  WEB_STORAGE_SUPPORT: 'webStorageSupport'\n};\n\n\n/**\n * Post message status values.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.Status = {\n  ACK: 'ACK',\n  ERROR: 'ERROR'\n};\n\n\n/**\n * Registers all event listeners.\n * @private\n */\nfireauth.iframeclient.IfcHandler.prototype.registerEvents_ = function() {\n  // Should be run in initialization.\n  if (!this.iframeWrapper_) {\n    throw new Error('IfcHandler must be initialized!');\n  }\n  var self = this;\n  // Listen to Auth change events emitted from iframe.\n  this.iframeWrapper_.registerEvent(\n      fireauth.iframeclient.IfcHandler.ReceiverEvent.AUTH_EVENT,\n      function(response) {\n        var resolveResponse = {};\n        if (response &&\n            response[fireauth.iframeclient.IfcHandler.Response.AUTH_EVENT]) {\n          var isHandled = false;\n          // Get Auth event (plain object).\n          var authEvent = fireauth.AuthEvent.fromPlainObject(\n              response[fireauth.iframeclient.IfcHandler.Response.AUTH_EVENT]);\n          // Trigger Auth change on all listeners.\n          for (var i = 0; i < self.authEventListeners_.length; i++) {\n            isHandled = self.authEventListeners_[i](authEvent) || isHandled;\n          }\n          // Return ack response to notify sender of success.\n          resolveResponse = {};\n          resolveResponse[fireauth.iframeclient.IfcHandler.Response.STATUS] =\n              isHandled ? fireauth.iframeclient.IfcHandler.Status.ACK :\n                  fireauth.iframeclient.IfcHandler.Status.ERROR;\n          return goog.Promise.resolve(resolveResponse);\n        }\n        // Return error status if the response is invalid.\n        resolveResponse[fireauth.iframeclient.IfcHandler.Response.STATUS] =\n            fireauth.iframeclient.IfcHandler.Status.ERROR;\n        return goog.Promise.resolve(resolveResponse);\n      });\n};\n\n\n/**\n * @return {!goog.Promise<boolean>} Whether web storage is supported in the\n *     iframe.\n */\nfireauth.iframeclient.IfcHandler.prototype.isWebStorageSupported = function() {\n  var webStorageSupportEvent =\n      fireauth.iframeclient.IfcHandler.SenderEvent.WEB_STORAGE_SUPPORT_EVENT;\n  var message = {\n    'type': webStorageSupportEvent\n  };\n  var self = this;\n  // Initialize if not initialized yet.\n  return this.initialize().then(function() {\n    return self.iframeWrapper_.sendMessage(message);\n  }).then(function(response) {\n    // Parse the response and return the passed web storage support status.\n    var key = fireauth.iframeclient.IfcHandler.Response.WEB_STORAGE_SUPPORT;\n    if (response &&\n        response.length &&\n        typeof response[0][key] !== 'undefined') {\n      return response[0][key];\n    }\n    // Internal error.\n    throw new Error;\n  });\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n *     listener to add.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.addAuthEventListener =\n    function(listener) {\n  this.authEventListeners_.push(listener);\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n *     listener to remove.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.removeAuthEventListener =\n    function(listener) {\n  goog.array.removeAllIf(this.authEventListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the MessageChannel based wrapper for receiving\n * messages from other windows or workers.\n */\n\ngoog.provide('fireauth.messagechannel.Receiver');\n\ngoog.require('fireauth.messagechannel.Status');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * Initializes a channel to receive specific messages from a specified event\n * target.\n * Note receivers should not be manually instantiated. Instead `getInstance()`\n * should be used instead to get a receiver instance for a specified event\n * target.\n * @param {!EventTarget} eventTarget The event target to listen to.\n * @constructor\n */\nfireauth.messagechannel.Receiver = function(eventTarget) {\n  /**\n   * @const @private {!EventTarget} The messageChannel event target.\n   */\n  this.eventTarget_ = eventTarget;\n  /**\n   * @const @private {!Object.<string,\n   *                    !Array<function(string, *):!goog.Promise<?>|void>>}\n   *     This is the event type to handlers hash map. It is used to hold the\n   *     corresponding handlers for specified events.\n   */\n  this.eventHandlers_ = {};\n  /**\n   * @const @private {function(!Event)} The internal 'message' event handler\n   *     used to reroute the request to corresponding subscribed handlers.\n   */\n  this.messageEventHandler_ = goog.bind(this.handleEvent_, this);\n};\n\n\n/**\n * @param {!EventTarget} eventTarget The event target to check for.\n * @return {boolean} Whether the receiver is listening to the specified event\n *     target.\n */\nfireauth.messagechannel.Receiver.prototype.isListeningTo =\n    function(eventTarget) {\n  return this.eventTarget_ == eventTarget;\n};\n\n\n/**\n * @const @private {!Array<!fireauth.messagechannel.Receiver>} The list of all\n *     created `fireauth.messagechannel.Receiver` instances.\n */\nfireauth.messagechannel.Receiver.receivers_ = [];\n\n\n/**\n * Return a receiver instance for the specified event target. This is needed\n * since one instance can be available per event target. Otherwise receivers\n * could clobber each other.\n * @param {!EventTarget} eventTarget The event target to listen to.\n * @return {!fireauth.messagechannel.Receiver} The receiver instance for the\n *     specified event target.\n */\nfireauth.messagechannel.Receiver.getInstance = function(eventTarget) {\n  // The results are stored in an array since objects can't be keys for other\n  // objects. In addition, setting a unique property on an event target as a\n  // hash map key may not be allowed due to CORS restrictions.\n  var instance;\n  goog.array.forEach(\n      fireauth.messagechannel.Receiver.receivers_,\n      function(receiver) {\n        if (receiver.isListeningTo(eventTarget)) {\n          instance = receiver;\n        }\n      });\n  if (!instance) {\n    instance = new fireauth.messagechannel.Receiver(eventTarget);\n    fireauth.messagechannel.Receiver.receivers_.push(instance);\n  }\n  return instance;\n};\n\n\n/**\n * Handles a PostMessage event based on the following protocol:\n * <ul>\n * <li>When an event is first detected, check there is a subscribed handler.\n *     If not, do nothing as there could be other listeners.</li>\n * <li>If there is a subscribed event, reply with an ACK event to notify the\n *     sender that the event can be handled.</li>\n * <li>Trigger the subscribed handlers.</li>\n * <li>Reply again with the combined results of all subscribed handlers and\n *     return the response back.</li>\n * </ul>\n *\n * @param {!Event} event The PostMessage event to handle.\n * @private\n */\nfireauth.messagechannel.Receiver.prototype.handleEvent_ = function(event) {\n  // Respond to sender first with ack reply. This will let the client\n  // know that the service worker can handle this event.\n  var eventType = event.data['eventType'];\n  var eventId = event.data['eventId'];\n  var handlers = this.eventHandlers_[eventType];\n  if (handlers && handlers.length > 0) {\n    // Event can be handled.\n    event.ports[0].postMessage({\n      'status': fireauth.messagechannel.Status.ACK,\n      'eventId': eventId,\n      'eventType': eventType,\n      'response': null\n    });\n    var promises = [];\n    goog.array.forEach(handlers, function(handler) {\n      // Wrap in promise in case the handler doesn't return a promise.\n      promises.push(goog.Promise.resolve().then(function() {\n        return handler(event.origin, event.data['data']);\n      }));\n    });\n    // allSettled is more flexible as it executes all the promises passed and\n    // returns whether they succeeded or failed.\n    goog.Promise.allSettled(promises)\n        .then(function(result) {\n          // allResponse has the format:\n          // !Array<!{fulfilled: boolean, value: (*|undefined),\n          //          reason: (*|undefined)}>\n          // Respond to sender with ack reply.\n          // De-obfuscate the allSettled result.\n          var allResponses = [];\n          goog.array.forEach(result, function(item) {\n            allResponses.push({\n              'fulfilled': item.fulfilled,\n              'value': item.value,\n              // Error cannot be clone in postMessage.\n              'reason': item.reason ? item.reason.message : undefined\n            });\n          });\n          // Remove undefined fields.\n          goog.array.forEach(allResponses, function(item) {\n            for (var key in item) {\n              if (typeof item[key] === 'undefined') {\n                delete item[key];\n              }\n            }\n          });\n          event.ports[0].postMessage({\n            'status': fireauth.messagechannel.Status.DONE,\n            'eventId': eventId,\n            'eventType': eventType,\n            'response': allResponses\n          });\n        });\n  }\n  // Let unsupported events time out, as there could be external receivers\n  // that can handle them.\n};\n\n\n/**\n * Subscribes to events of the specified type.\n * @param {string} eventType The event type to listen to.\n * @param {function(string, *):!goog.Promise<?>|void} handler The async callback\n *     function to run when the event is triggered.\n */\nfireauth.messagechannel.Receiver.prototype.subscribe =\n    function(eventType, handler) {\n  if (goog.object.isEmpty(this.eventHandlers_)) {\n    this.eventTarget_.addEventListener('message', this.messageEventHandler_);\n  }\n  if (typeof this.eventHandlers_[eventType] === 'undefined') {\n    this.eventHandlers_[eventType] = [];\n  }\n  this.eventHandlers_[eventType].push(handler);\n};\n\n\n/**\n * Unsubscribes the specified handler from the specified event. If no handler\n * is specified, all handlers are unsubscribed.\n * @param {string} eventType The event type to unsubscribe from.\n * @param {?function(string, *):!goog.Promise<?>|void=} opt_handler The\n *     callback function to unsubscribe from the specified event type. If none\n *     is specified, all handlers are unsubscribed.\n */\nfireauth.messagechannel.Receiver.prototype.unsubscribe =\n    function(eventType, opt_handler) {\n  if (typeof this.eventHandlers_[eventType] !== 'undefined' && opt_handler) {\n    goog.array.removeAllIf(this.eventHandlers_[eventType], function(ele) {\n      return ele == opt_handler;\n    });\n    if (this.eventHandlers_[eventType].length == 0) {\n      delete this.eventHandlers_[eventType];\n    }\n  } else if (!opt_handler) {\n    // Unsubscribe all handlers for speficied event.\n    delete this.eventHandlers_[eventType];\n  }\n  if (goog.object.isEmpty(this.eventHandlers_)) {\n    this.eventTarget_.removeEventListener('message', this.messageEventHandler_);\n  }\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the MessageChannel based wrapper for sending messages\n * to other windows or workers.\n */\n\ngoog.provide('fireauth.messagechannel.Sender');\n\ngoog.require('fireauth.messagechannel.Error');\ngoog.require('fireauth.messagechannel.PostMessager');\ngoog.require('fireauth.messagechannel.Status');\ngoog.require('fireauth.messagechannel.TimeoutDuration');\ngoog.require('fireauth.messagechannel.utils');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\n\n\n/**\n * This is the interface defining a MessageChannel/handler pair.\n *\n * @typedef {{\n *   onMessage: function(!Event),\n *   messageChannel: !MessageChannel\n * }}\n */\nfireauth.messagechannel.MessageHandler;\n\n\n/**\n * Helper static function to create messageChannel errors.\n * @param {!fireauth.messagechannel.Error} errorId The error identifier.\n * @param {?string=} opt_message The optional error message used for generic\n *     error types.\n * @return {!Error} The constructed error to return.\n * @private\n */\nfireauth.messagechannel.createError_ = function(errorId, opt_message) {\n  if (errorId != fireauth.messagechannel.Error.UNKNOWN || !opt_message) {\n    return new Error(errorId);\n  } else {\n    return new Error(opt_message);\n  }\n};\n\n\n/**\n * Initializes a channel to send specific messages to a specified PostMessage.\n * @param {!fireauth.messagechannel.PostMessager} postMessager The post messager\n *     to send messages to.\n * @constructor\n */\nfireauth.messagechannel.Sender = function(postMessager) {\n  /**\n   * @const @private {!fireauth.messagechannel.PostMessager} The messageChannel\n   *     PostMessager.\n   */\n  this.postMessager_ = postMessager;\n  /** @private {boolean} Whether the connection was closed. */\n  this.closed_ = false;\n  /**\n   * @const @private {!Array<!fireauth.messagechannel.MessageHandler>} The list\n   *     of subscribed message handlers and their corresponding MessageChannels.\n   */\n  this.messageHandlers_ = [];\n};\n\n\n/**\n * Sends a message to the receiver. The message is identified by an event\n * type and can carry additional payload data.\n * The sender protocol works as follows:\n * <ul>\n * <li>The request is constructed and postMessaged to the receiver with the port\n *     used to reply back to sender.</li>\n * <li>The operation will block until an ACK response is received. If not, it\n *     will timeout and reject with an error.</li>\n * <li>If an ACK response is received, it will wait longer for the full\n *     processed response.</li>\n * <li>Once the response is received, the operation will resolve with that\n *     result.</li>\n * </ul>\n *\n * @param {string} eventType The event type identifying the message. This is\n *     used to help the receiver handle this message.\n * @param {?Object=} opt_data The optional data to send along the message.\n * @param {?boolean=} opt_useLongTimeout Whether long timeout should be used\n *     for ACK responses.\n * @return {!goog.Promise<!Array<{fulfilled: boolean,\n *                                value: (*|undefined),\n *                                reason: (*|undefined)}>>} A promise that\n *     resolves with the receiver responses.\n */\nfireauth.messagechannel.Sender.prototype.send = function(\n    eventType, opt_data, opt_useLongTimeout) {\n  var self = this;\n  var eventId;\n  var data = opt_data || {};\n  var onMessage;\n  var ackTimer;\n  var completionTimer;\n  var entry = null;\n  if (this.closed_) {\n    return goog.Promise.reject(fireauth.messagechannel.createError_(\n        fireauth.messagechannel.Error.CONNECTION_UNAVAILABLE));\n  }\n  var ackTimeout =\n      !!opt_useLongTimeout ?\n      fireauth.messagechannel.TimeoutDuration.LONG_ACK :\n      fireauth.messagechannel.TimeoutDuration.ACK;\n  var messageChannel =\n      fireauth.messagechannel.utils.initializeMessageChannel();\n  return new goog.Promise(function(resolve, reject) {\n    // Send message along with port for reply\n    if (messageChannel) {\n      eventId = fireauth.messagechannel.utils.generateEventId();\n      // Start the connection if not already started.\n      messageChannel.port1.start();\n      // Handler for receiving message reply from receiver.\n      // Blocks promise resolution until service worker detects the change.\n      ackTimer = setTimeout(function() {\n        // The receiver may not be able to handle the response for various\n        // reasons: library not included, or an incompatible version of\n        // the library is included.\n        // Timeout after some time.\n        reject(fireauth.messagechannel.createError_(\n            fireauth.messagechannel.Error.UNSUPPORTED_EVENT));\n      }, ackTimeout);\n      onMessage = function(event) {\n        // Process only the expected events that match current event ID.\n        if (event.data['eventId'] !== eventId) {\n          return;\n        }\n        // This avoids adding a long wait when the receiver is unable to handle\n        // the event.\n        if (event.data['status'] === fireauth.messagechannel.Status.ACK) {\n          clearTimeout(ackTimer);\n          // Set longer timeout to allow receiver to process.\n          completionTimer = setTimeout(function() {\n            reject(fireauth.messagechannel.createError_(\n                fireauth.messagechannel.Error.TIMEOUT));\n          }, fireauth.messagechannel.TimeoutDuration.COMPLETION);\n          return;\n        } else if (event.data['status'] ===\n                   fireauth.messagechannel.Status.DONE) {\n          clearTimeout(completionTimer);\n          if (typeof event.data['response'] !== 'undefined') {\n            resolve(event.data['response']);\n          } else {\n            reject(fireauth.messagechannel.createError_(\n                fireauth.messagechannel.Error.UNKNOWN));\n          }\n        } else {\n          clearTimeout(ackTimer);\n          clearTimeout(completionTimer);\n          reject(fireauth.messagechannel.createError_(\n              fireauth.messagechannel.Error.INVALID_RESPONSE));\n        }\n      };\n      entry = {\n        'messageChannel': messageChannel,\n        'onMessage': onMessage\n      };\n      self.messageHandlers_.push(entry);\n      messageChannel.port1.addEventListener('message', onMessage);\n      var request = {\n        'eventType': eventType,\n        'eventId': eventId,\n        'data': data\n      };\n      // It is possible the receiver cannot handle this result.\n      // For example, the developer may not be including the library in the\n      // receiver or using an outdated version.\n      self.postMessager_.postMessage(\n          request,\n          [messageChannel.port2]);\n    } else {\n      // No connection available.\n      reject(fireauth.messagechannel.createError_(\n          fireauth.messagechannel.Error.CONNECTION_UNAVAILABLE));\n    }\n  }).then(function(result) {\n    // On completion, remove the message handler. A new one is needed for a\n    // new message.\n    self.removeMessageHandler_(entry);\n    return result;\n  }).thenCatch(function(error) {\n    // On failure, remove the message handler. A new one is needed for a new\n    // message.\n    self.removeMessageHandler_(entry);\n    throw error;\n  });\n};\n\n\n/**\n * Removes the onMessage handler for the specified messageChannel.\n * @param {?fireauth.messagechannel.MessageHandler} messageHandler\n * @private\n */\nfireauth.messagechannel.Sender.prototype.removeMessageHandler_ =\n    function(messageHandler) {\n  if (!messageHandler) {\n    return;\n  }\n  var messageChannel = messageHandler['messageChannel'];\n  var onMessage = messageHandler['onMessage'];\n  if (messageChannel) {\n    messageChannel.port1.removeEventListener('message', onMessage);\n    messageChannel.port1.close();\n  }\n  goog.array.removeAllIf(this.messageHandlers_, function(ele) {\n    return ele == messageHandler;\n  });\n};\n\n\n/** Closes the underlying MessageChannel connection. */\nfireauth.messagechannel.Sender.prototype.close = function() {\n  // Any pending event will timeout.\n  while (this.messageHandlers_.length > 0) {\n    this.removeMessageHandler_(this.messageHandlers_[0]);\n  }\n  this.closed_ = true;\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines a local storage interface with an indexedDB\n * implementation to be used as a fallback with browsers that do not synchronize\n * local storage changes between different windows of the same origin.\n */\n\ngoog.provide('fireauth.storage.IndexedDB');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.messagechannel.Receiver');\ngoog.require('fireauth.messagechannel.Sender');\ngoog.require('fireauth.messagechannel.WorkerClientPostMessager');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.array');\n\n\n\n/**\n * Initialize an indexedDB local storage manager used to mimic local storage\n * using an indexedDB underlying implementation including the ability to listen\n * to storage changes by key similar to localstorage storage event.\n * @param {string} dbName The indexedDB database name where all local storage\n *     data is to be stored.\n * @param {string} objectStoreName The indexedDB object store name where all\n *     local storage data is to be stored.\n * @param {string} dataKeyPath The indexedDB object store index name used to key\n *     all local storage data.\n * @param {string} valueKeyPath The indexedDB object store value field for each\n *     entry.\n * @param {number} version The indexedDB database version number.\n * @param {?IDBFactory=} opt_indexedDB The optional IndexedDB factory object.\n * @implements {fireauth.storage.Storage}\n * @constructor\n */\nfireauth.storage.IndexedDB = function(\n    dbName,\n    objectStoreName,\n    dataKeyPath,\n    valueKeyPath,\n    version,\n    opt_indexedDB) {\n  // indexedDB not available, fail hard.\n  if (!fireauth.storage.IndexedDB.isAvailable()) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n  }\n  /**\n   * @const @private {string} The indexedDB database name where all local\n   *     storage data is to be stored.\n   */\n  this.dbName_ = dbName;\n  /**\n   * @const @private {string} The indexedDB object store name where all local\n   *     storage data is to be stored.\n   */\n  this.objectStoreName_ = objectStoreName;\n  /**\n   * @const @private {string} The indexedDB object store index name used to key\n   *     all local storage data.\n   */\n  this.dataKeyPath_ = dataKeyPath;\n  /**\n   * @const @private {string} The indexedDB object store value field for each\n   *     entry.\n   */\n  this.valueKeyPath_ = valueKeyPath;\n  /** @const @private {number} The indexedDB database version number. */\n  this.version_ = version;\n  /** @private {!Object.<string, *>} The local indexedDB map copy. */\n  this.localMap_ = {};\n  /**\n   * @private {!Array<function(!Array<string>)>} Listeners to storage events.\n   */\n  this.storageListeners_ = [];\n  /** @private {number} The indexedDB pending write operations tracker. */\n  this.pendingOpsTracker_ = 0;\n  /** @private {!IDBFactory} The indexedDB factory object. */\n  this.indexedDB_ = /** @type {!IDBFactory} */ (\n      opt_indexedDB || goog.global.indexedDB);\n  /** @public {string} The storage type identifier. */\n  this.type = fireauth.storage.Storage.Type.INDEXEDDB;\n  /**\n   * @private {?goog.Promise<void>} The pending polling promise for syncing\n   *     unprocessed indexedDB external changes.\n   */\n  this.poll_ = null;\n  /**\n   * @private {?number} The poll timer ID for syncing external indexedDB\n   *     changes.\n   */\n  this.pollTimerId_ = null;\n  /**\n   * @private {?fireauth.messagechannel.Receiver} The messageChannel receiver if\n   *     running from a serviceworker.\n   */\n  this.receiver_ = null;\n  /**\n   * @private {?fireauth.messagechannel.Sender} The messageChannel sender to\n   *     send keyChanged messages to the service worker from the client.\n   */\n  this.sender_ = null;\n  /**\n   * @private {boolean} Whether the service worker has a receiver for the\n   *     keyChanged events.\n   */\n  this.serviceWorkerReceiverAvailable_ = false;\n  /** @private {?ServiceWorker} The current active service worker. */\n  this.activeServiceWorker_ = null;\n  var scope = this;\n  if (fireauth.util.getWorkerGlobalScope()) {\n    this.receiver_ = fireauth.messagechannel.Receiver.getInstance(\n        /** @type {!WorkerGlobalScope} */ (\n            fireauth.util.getWorkerGlobalScope()));\n    // Listen to indexedDB changes.\n    this.receiver_.subscribe('keyChanged', function(origin, request) {\n      // Sync data.\n      return scope.sync_().then(function(keys) {\n        // Trigger listeners if unhandled changes are detected.\n        if (keys.length > 0) {\n          goog.array.forEach(\n              scope.storageListeners_,\n              function(listener) {\n                listener(keys);\n              });\n        }\n        // When this is false, it means the change was already\n        // detected and processed before the notification.\n        return {\n          'keyProcessed': goog.array.contains(keys, request['key'])\n        };\n      });\n    });\n    // Used to inform sender that service worker what events it supports.\n    this.receiver_.subscribe('ping', function(origin, request) {\n      return goog.Promise.resolve(['keyChanged']);\n    });\n  } else {\n    // Get active service worker when its available.\n    fireauth.util.getActiveServiceWorker()\n        .then(function(sw) {\n          scope.activeServiceWorker_ = sw;\n          if (sw) {\n            // Initialize the sender.\n            scope.sender_ = new fireauth.messagechannel.Sender(\n                new fireauth.messagechannel.WorkerClientPostMessager(sw));\n            // Ping the service worker to check what events they can handle.\n            // Use long timeout.\n            scope.sender_.send('ping', null, true)\n                .then(function(results) {\n                  // Check if keyChanged is supported.\n                  if (results[0]['fulfilled'] &&\n                      goog.array.contains(results[0]['value'], 'keyChanged')) {\n                    scope.serviceWorkerReceiverAvailable_ = true;\n                  }\n                })\n                .thenCatch(function(error) {\n                  // Ignore error.\n                });\n          }\n        });\n  }\n};\n\n\n\n/**\n * The indexedDB database name where all local storage data is to be stored.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DB_NAME_ = 'firebaseLocalStorageDb';\n\n\n/**\n * The indexedDB object store name where all local storage data is to be stored.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DATA_OBJECT_STORE_NAME_ = 'firebaseLocalStorage';\n\n\n/**\n * The indexedDB object store index name used to key all local storage data.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DATA_KEY_PATH_ = 'fbase_key';\n\n\n/**\n * The indexedDB object store value field for each entry.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.VALUE_KEY_PATH_ = 'value';\n\n\n/**\n * The indexedDB database version number.\n * @private @const {number}\n */\nfireauth.storage.IndexedDB.VERSION_ = 1;\n\n\n/**\n * The indexedDB polling delay time in milliseconds.\n * @private @const {number}\n */\nfireauth.storage.IndexedDB.POLLING_DELAY_ = 800;\n\n\n/**\n * The indexedDB polling stop error.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.STOP_ERROR_ = 'STOP_EVENT';\n\n\n\n/**\n * @return {!fireauth.storage.IndexedDB} The Firebase Auth indexedDB\n *     local storage manager.\n */\nfireauth.storage.IndexedDB.getFireauthManager = function() {\n  if (!fireauth.storage.IndexedDB.managerInstance_) {\n    fireauth.storage.IndexedDB.managerInstance_ =\n        new fireauth.storage.IndexedDB(\n            fireauth.storage.IndexedDB.DB_NAME_,\n            fireauth.storage.IndexedDB.DATA_OBJECT_STORE_NAME_,\n            fireauth.storage.IndexedDB.DATA_KEY_PATH_,\n            fireauth.storage.IndexedDB.VALUE_KEY_PATH_,\n            fireauth.storage.IndexedDB.VERSION_);\n  }\n  return fireauth.storage.IndexedDB.managerInstance_;\n};\n\n\n/**\n * Delete the indexedDB database.\n * @return {!goog.Promise<!IDBDatabase>} A promise that resolves on successful\n *     database deletion.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.deleteDb_ = function() {\n  var self = this;\n  return new goog.Promise(function(resolve, reject) {\n    var request = self.indexedDB_.deleteDatabase(self.dbName_);\n    request.onsuccess = function(event) {\n      resolve();\n    };\n    request.onerror = function(event) {\n      reject(new Error(event.target.error));\n    };\n  });\n};\n\n\n/**\n * Initializes The indexedDB database, creates it if not already created and\n * opens it.\n * @return {!goog.Promise<!IDBDatabase>} A promise for the database object.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.initializeDb_ = function() {\n  var self = this;\n  return new goog.Promise(function(resolve, reject) {\n    var request = self.indexedDB_.open(self.dbName_, self.version_);\n    request.onerror = function(event) {\n      // Suppress this from surfacing to browser console.\n      try {\n        event.preventDefault();\n      } catch (e) {}\n      reject(new Error(event.target.error));\n    };\n    request.onupgradeneeded = function(event) {\n      var db = event.target.result;\n      try {\n        db.createObjectStore(\n            self.objectStoreName_,\n            {\n              'keyPath': self.dataKeyPath_\n            });\n      } catch (e) {\n        reject(e);\n      }\n    };\n    request.onsuccess = function(event) {\n      var db = event.target.result;\n      // Strange bug that occurs in Firefox when multiple tabs are opened at the\n      // same time. The only way to recover seems to be deleting the database\n      // and re-initializing it.\n      // https://github.com/firebase/firebase-js-sdk/issues/634\n      if (!db.objectStoreNames.contains(self.objectStoreName_)) {\n        self.deleteDb_()\n            .then(function() {\n              return self.initializeDb_();\n            })\n            .then(function(newDb) {\n              resolve(newDb);\n            })\n            .thenCatch(function(e) {\n              reject(e);\n            });\n      } else {\n        resolve(db);\n      }\n    };\n  });\n};\n\n\n/**\n * Checks if indexedDB is initialized, if so, the callback is run, otherwise,\n * it waits for the db to initialize and then runs the callback function.\n * @return {!goog.Promise<!IDBDatabase>} A promise for the initialized indexedDB\n *     database.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.initializeDbAndRun_ =\n    function() {\n  if (!this.initPromise_) {\n    this.initPromise_ = this.initializeDb_();\n  }\n  return this.initPromise_;\n};\n\n\n/**\n * @return {boolean} Whether indexedDB is available or not.\n */\nfireauth.storage.IndexedDB.isAvailable = function() {\n  try {\n    return !!goog.global['indexedDB'];\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * Creates a reference for the local storage indexedDB object store and returns\n * it.\n * @param {!IDBTransaction} tx The IDB transaction instance.\n * @return {!IDBObjectStore} The indexedDB object store.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.getDataObjectStore_ =\n    function(tx) {\n  return tx.objectStore(this.objectStoreName_);\n};\n\n\n/**\n * Creates an IDB transaction and returns it.\n * @param {!IDBDatabase} db The indexedDB instance.\n * @param {boolean} isReadWrite Whether the current indexedDB operation is a\n *     read/write operation or not.\n * @return {!IDBTransaction} The requested IDB transaction instance.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.getTransaction_ =\n    function(db, isReadWrite) {\n  var tx = db.transaction(\n      [this.objectStoreName_],\n      isReadWrite ? 'readwrite' : 'readonly');\n  return tx;\n};\n\n\n/**\n * @param {!IDBRequest} request The IDB request instance.\n * @return {!goog.Promise} The promise to resolve on transaction completion.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.onIDBRequest_ =\n    function(request) {\n  return new goog.Promise(function(resolve, reject) {\n    request.onsuccess = function(event) {\n      if (event && event.target) {\n        resolve(event.target.result);\n      } else {\n        resolve();\n      }\n    };\n    request.onerror = function(event) {\n      reject(event.target.error);\n    };\n  });\n};\n\n\n/**\n * Sets the item's identified by the key provided to the value passed. If the\n * item does not exist, it is created. An optional callback is run on success.\n * @param {string} key The storage key for the item to set. If the item exists,\n *     it is updated, otherwise created.\n * @param {*} value The value to store for the item to set.\n * @return {!goog.Promise<void>} A promise that resolves on operation success.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.set = function(key, value) {\n  var isLocked = false;\n  var dbTemp;\n  var self = this;\n  return this.initializeDbAndRun_()\n      .then(function(db) {\n        dbTemp = db;\n        var objectStore = self.getDataObjectStore_(\n            self.getTransaction_(dbTemp, true));\n        return self.onIDBRequest_(objectStore.get(key));\n      })\n      .then(function(data) {\n        var objectStore = self.getDataObjectStore_(\n            self.getTransaction_(dbTemp, true));\n        if (data) {\n          // Update the value(s) in the object that you want to change\n          data.value = value;\n          // Put this updated object back into the database.\n          return self.onIDBRequest_(objectStore.put(data));\n        }\n        self.pendingOpsTracker_++;\n        isLocked = true;\n        var obj = {};\n        obj[self.dataKeyPath_] = key;\n        obj[self.valueKeyPath_] = value;\n        return self.onIDBRequest_(objectStore.add(obj));\n      })\n      .then(function() {\n        // Save in local copy to avoid triggering false external event.\n        self.localMap_[key] = value;\n        // Announce change in key to service worker.\n        return self.notifySW_(key);\n      })\n      .thenAlways(function() {\n        if (isLocked) {\n          self.pendingOpsTracker_--;\n        }\n      });\n};\n\n\n/**\n * Notify the service worker of the indexeDB write operation.\n * Waits until the operation is processed.\n * @param {string} key The key which is changing.\n * @return {!goog.Promise<void>} A promise that resolves on delivery.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.notifySW_ = function(key) {\n  // If sender is available.\n  // Run some sanity check to confirm no sw change occurred.\n  // For now, we support one service worker per page.\n  if (this.sender_ &&\n      this.activeServiceWorker_ &&\n      fireauth.util.getServiceWorkerController() ===\n      this.activeServiceWorker_) {\n    return this.sender_.send(\n        'keyChanged',\n        {'key': key},\n        // Use long timeout if receiver is known to be available.\n        this.serviceWorkerReceiverAvailable_)\n        .then(function(responses) {\n          // Return nothing.\n        })\n        .thenCatch(function(error) {\n          // This is a best effort approach. Ignore errors.\n        });\n  }\n  return goog.Promise.resolve();\n};\n\n\n/**\n * Retrieves a stored item identified by the key provided asynchronously.\n * The value is passed to the callback function provided.\n * @param {string} key The storage key for the item to fetch.\n * @return {!goog.Promise} A promise that resolves with the item's value, or\n *     null if the item is not found.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.get = function(key) {\n  var self = this;\n  return this.initializeDbAndRun_()\n      .then(function(db) {\n        return self.onIDBRequest_(\n            self.getDataObjectStore_(self.getTransaction_(db, false)).get(key));\n      })\n      .then(function(response) {\n        return response && response.value;\n      });\n};\n\n\n/**\n * Deletes the item identified by the key provided and on success, runs the\n * optional callback.\n * @param {string} key The storage key for the item to remove.\n * @return {!goog.Promise<void>} A promise that resolves on operation success.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.remove = function(key) {\n  var isLocked = false;\n  var self = this;\n  return this.initializeDbAndRun_()\n      .then(function(db) {\n        isLocked = true;\n        self.pendingOpsTracker_++;\n        return self.onIDBRequest_(\n            self.getDataObjectStore_(\n                self.getTransaction_(db, true))['delete'](key));\n      }).then(function() {\n        // Delete from local copy to avoid triggering false external event.\n        delete self.localMap_[key];\n        // Announce change in key to service worker.\n        return self.notifySW_(key);\n      }).thenAlways(function() {\n        if (isLocked) {\n          self.pendingOpsTracker_--;\n        }\n      });\n};\n\n\n/**\n * @return {!goog.Promise<!Array<string>>} A promise that resolved with all the\n *     storage keys that have changed.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.sync_ = function() {\n  var self = this;\n  return this.initializeDbAndRun_()\n      .then(function(db) {\n        var objectStore =\n            self.getDataObjectStore_(self.getTransaction_(db, false));\n        if (objectStore['getAll']) {\n          // Get all keys and value pairs using getAll if supported.\n          return self.onIDBRequest_(objectStore['getAll']());\n        } else {\n          // If getAll isn't supported, fallback to cursor.\n          return new goog.Promise(function(resolve, reject) {\n            var res = [];\n            var request = objectStore.openCursor();\n            request.onsuccess = function(event) {\n              var cursor = event.target.result;\n              if (cursor) {\n                res.push(cursor.value);\n                cursor['continue']();\n              } else {\n                resolve(res);\n              }\n            };\n            request.onerror = function(event) {\n              reject(event.target.error);\n            };\n          });\n        }\n      }).then(function(res) {\n        var centralCopy = {};\n        // List of keys differing from central copy.\n        var diffKeys = [];\n        // Build central copy (external copy).\n        if (self.pendingOpsTracker_ == 0) {\n          for (var i = 0; i < res.length; i++) {\n            centralCopy[res[i][self.dataKeyPath_]] =\n                res[i][self.valueKeyPath_];\n          }\n          // Get diff of central copy and local copy.\n          diffKeys = fireauth.util.getKeyDiff(self.localMap_, centralCopy);\n          // Update local copy.\n          self.localMap_ = centralCopy;\n        }\n        // Return modified keys.\n        return diffKeys;\n      });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!Array<string>)} listener The storage event listener.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.addStorageListener =\n    function(listener) {\n  // First listener, start listeners.\n  if (this.storageListeners_.length == 0) {\n    this.startListeners_();\n  }\n  this.storageListeners_.push(listener);\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!Array<string>)} listener The storage event listener.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.removeStorageListener =\n    function(listener) {\n  goog.array.removeAllIf(\n      this.storageListeners_,\n      function(ele) {\n        return ele == listener;\n      });\n  // No more listeners, stop.\n  if (this.storageListeners_.length == 0) {\n    this.stopListeners_();\n  }\n};\n\n\n/**\n * Removes all listeners to storage event change.\n */\nfireauth.storage.IndexedDB.prototype.removeAllStorageListeners =\n    function() {\n  this.storageListeners_ = [];\n  // No more listeners, stop.\n  this.stopListeners_();\n};\n\n\n/**\n * Starts the listener to storage events.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.startListeners_ = function() {\n  var self = this;\n  // Stop any previous listeners.\n  this.stopListeners_();\n  var repeat = function() {\n    self.pollTimerId_ = setTimeout(\n        function() {\n          self.poll_ = self.sync_()\n              .then(function(keys) {\n                // If keys modified, call listeners.\n                if (keys.length > 0) {\n                  goog.array.forEach(\n                      self.storageListeners_,\n                      function(listener) {\n                        listener(keys);\n                      });\n                }\n              })\n              .then(function() {\n                repeat();\n              })\n              .thenCatch(function(error) {\n                if (error.message != fireauth.storage.IndexedDB.STOP_ERROR_) {\n                  repeat();\n                }\n              });\n        },\n        fireauth.storage.IndexedDB.POLLING_DELAY_);\n  };\n  repeat();\n};\n\n\n/**\n * Stops the listener to storage events.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.stopListeners_ = function() {\n  if (this.poll_) {\n    // Cancel polling function.\n    this.poll_.cancel(fireauth.storage.IndexedDB.STOP_ERROR_);\n  }\n  // Clear any pending polling timer.\n  if (this.pollTimerId_) {\n    clearTimeout(this.pollTimerId_);\n    this.pollTimerId_ = null;\n  }\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngoog.provide('fireauth.storage.HybridIndexedDB');\n\ngoog.require('fireauth.storage.IndexedDB');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\n\n/**\n * HybridStorage provides an interface to indexedDB, the persistent Web\n * Storage API for browsers that support it. This will fallback to the provided\n * fallback storage when indexedDB is not supported which is determined\n * asynchronously.\n * @param {!fireauth.storage.Storage} fallbackStorage The storage to fallback to\n *     when indexedDB is not available.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.HybridIndexedDB = function(fallbackStorage) {\n  var self = this;\n  var storage = null;\n  /**\n   * @const @private {!Array<function((!goog.events.BrowserEvent|\n   *                                   !Array<string>))>} The storage listeners.\n   */\n  this.storageListeners_ = [];\n  // This type may change if the fallback is used.\n  /** @public {string} The storage type identifier. */\n  this.type = fireauth.storage.Storage.Type.INDEXEDDB;\n  /**\n   * @const @private {!fireauth.storage.Storage} The fallback storage when\n   *     indexedDB is unavailable.\n   */\n  this.fallbackStorage_ = fallbackStorage;\n  /**\n   * @const @private {!goog.Promise<!fireauth.storage.Storage>} A promise that\n   *     resolves with the underlying indexedDB storage or a fallback when not\n   *     supported.\n   */\n  this.underlyingStoragePromise_ = goog.Promise.resolve().then(function() {\n    // Initial check shows indexedDB is available. This is not enough.\n    // Try to write/read from indexedDB. If it fails, switch to fallback.\n    if (fireauth.storage.IndexedDB.isAvailable()) {\n      // Test write/read using a random key. This is important for the following\n      // reasons:\n      // 1. Double inclusion of the firebase-auth.js library.\n      // 2. Multiple windows opened at the same time.\n      // The above may cause collision if multiple instances try to\n      // write/read/delete from the same entry.\n      var randomId = fireauth.util.generateEventId();\n      var randomKey = fireauth.storage.HybridIndexedDB.KEY_ + randomId;\n      storage = fireauth.storage.IndexedDB.getFireauthManager();\n      return storage.set(randomKey, randomId)\n          .then(function() {\n            return storage.get(randomKey);\n          })\n          .then(function(value) {\n            if (value !== randomId) {\n              throw new Error('indexedDB not supported!');\n            }\n            return storage.remove(randomKey);\n          })\n          .then(function() {\n            return storage;\n          })\n          .thenCatch(function(error) {\n            return self.fallbackStorage_;\n          });\n    } else {\n      // indexedDB not available, use fallback.\n      return self.fallbackStorage_;\n    }\n  }).then(function(storage) {\n    // Update type.\n    self.type = storage.type;\n    // Listen to all storage changes.\n    storage.addStorageListener(function(key) {\n      // Trigger all attached storage listeners.\n      goog.array.forEach(self.storageListeners_, function(listener) {\n        listener(key);\n      });\n    });\n    return storage;\n  });\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.HybridIndexedDB.KEY_ = '__sak';\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.get = function(key) {\n  return this.underlyingStoragePromise_.then(function(storage) {\n    return storage.get(key);\n  });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.set = function(key, value) {\n  return this.underlyingStoragePromise_.then(function(storage) {\n    return storage.set(key, value);\n  });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.remove = function(key) {\n  return this.underlyingStoragePromise_.then(function(storage) {\n    return storage.remove(key);\n  });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function((!goog.events.BrowserEvent|!Array<string>))} listener The\n *     storage event listener.\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.addStorageListener =\n    function(listener) {\n  this.storageListeners_.push(listener);\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n *     listener.\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.removeStorageListener =\n    function(listener) {\n  goog.array.removeAllIf(this.storageListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngoog.provide('fireauth.storage.LocalStorage');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.events');\n\n\n\n/**\n * LocalStorage provides an interface to localStorage, the persistent Web\n * Storage API.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.LocalStorage = function() {\n  // Check is localStorage available in the current environment.\n  if (!fireauth.storage.LocalStorage.isAvailable()) {\n    // In a Node.js environment, dom-storage module needs to be required.\n    if (fireauth.util.getEnvironment() == fireauth.util.Env.NODE) {\n      throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n          'The LocalStorage compatibility library was not found.');\n    }\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n  }\n\n  /**\n   * The underlying storage instance for persistent data.\n   * @private {!Storage}\n   */\n  this.storage_ = /** @type {!Storage} */ (\n      fireauth.storage.LocalStorage.getGlobalStorage() ||\n      firebase.INTERNAL['node']['localStorage']);\n  /** @public {string} The storage type identifier. */\n  this.type = fireauth.storage.Storage.Type.LOCAL_STORAGE;\n};\n\n\n/** @return {?Storage|undefined} The global localStorage instance. */\nfireauth.storage.LocalStorage.getGlobalStorage = function() {\n  try {\n    var storage = goog.global['localStorage'];\n    // Try editing web storage. If an error is thrown, it may be disabled.\n    var key = fireauth.util.generateEventId();\n    if (storage) {\n      storage['setItem'](key, '1');\n      storage['removeItem'](key);\n    }\n    return storage;\n  } catch (e) {\n    // In some cases, browsers with web storage disabled throw an error simply\n    // on access.\n    return null;\n  }\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_ = '__sak';\n\n\n/** @return {boolean} Whether localStorage is available. */\nfireauth.storage.LocalStorage.isAvailable = function() {\n  // In Node.js localStorage is polyfilled.\n  var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n  // Either window should provide this storage mechanism or in case of Node.js,\n  // firebase.INTERNAL should provide it.\n  var storage = fireauth.storage.LocalStorage.getGlobalStorage() ||\n      (isNode &&\n       firebase.INTERNAL['node'] &&\n       firebase.INTERNAL['node']['localStorage']);\n  if (!storage) {\n    return false;\n  }\n  try {\n    // setItem will throw an exception if we cannot access web storage (e.g.,\n    // Safari in private mode).\n    storage.setItem(fireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_, '1');\n    storage.removeItem(fireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_);\n    return true;\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.get = function(key) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        var json = self.storage_.getItem(key);\n        return fireauth.util.parseJSON(json);\n      });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.set = function(key, value) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        var obj = fireauth.util.stringifyJSON(value);\n        if (obj === null) {\n          self.remove(key);\n        } else {\n          self.storage_.setItem(key, obj);\n        }\n      });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.remove = function(key) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        self.storage_.removeItem(key);\n      });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n *     listener.\n * @override\n */\nfireauth.storage.LocalStorage.prototype.addStorageListener = function(\n    listener) {\n  if (goog.global['window']) {\n    goog.events.listen(goog.global['window'], 'storage', listener);\n  }\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n *     listener.\n * @override\n */\nfireauth.storage.LocalStorage.prototype.removeStorageListener = function(\n    listener) {\n  if (goog.global['window']) {\n    goog.events.unlisten(goog.global['window'], 'storage', listener);\n  }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngoog.provide('fireauth.storage.SessionStorage');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\n\n\n\n/**\n * SessionStorage provides an interface to sessionStorage, the temporary web\n * storage API.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.SessionStorage = function() {\n  // Check is sessionStorage available in the current environment.\n  if (!fireauth.storage.SessionStorage.isAvailable()) {\n    // In a Node.js environment, dom-storage module needs to be required.\n    if (fireauth.util.getEnvironment() == fireauth.util.Env.NODE) {\n      throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n          'The SessionStorage compatibility library was not found.');\n    }\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n  }\n\n  /**\n   * The underlying storage instance for temporary data.\n   * @private {!Storage}\n   */\n  this.storage_ = /** @type {!Storage} */ (\n      fireauth.storage.SessionStorage.getGlobalStorage() ||\n      firebase.INTERNAL['node']['sessionStorage']);\n  /** @public {string} The storage type identifier. */\n  this.type = fireauth.storage.Storage.Type.SESSION_STORAGE;\n};\n\n\n/** @return {?Storage|undefined} The global sessionStorage instance. */\nfireauth.storage.SessionStorage.getGlobalStorage = function() {\n  try {\n    var storage = goog.global['sessionStorage'];\n    // Try editing web storage. If an error is thrown, it may be disabled.\n    var key = fireauth.util.generateEventId();\n    if (storage) {\n      storage['setItem'](key, '1');\n      storage['removeItem'](key);\n    }\n    return storage;\n  } catch (e) {\n    // In some cases, browsers with web storage disabled throw an error simply\n    // on access.\n    return null;\n  }\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_ = '__sak';\n\n\n/** @return {boolean} Whether sessionStorage is available. */\nfireauth.storage.SessionStorage.isAvailable = function() {\n  // In Node.js sessionStorage is polyfilled.\n  var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n  // Either window should provide this storage mechanism or in case of Node.js,\n  // firebase.INTERNAL should provide it.\n  var storage = fireauth.storage.SessionStorage.getGlobalStorage() ||\n      (isNode &&\n       firebase.INTERNAL['node'] &&\n       firebase.INTERNAL['node']['sessionStorage']);\n  if (!storage) {\n    return false;\n  }\n  try {\n    // setItem will throw an exception if we cannot access web storage (e.g.,\n    // Safari in private mode).\n    storage.setItem(\n        fireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_, '1');\n    storage.removeItem(fireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_);\n    return true;\n  } catch (e) {\n    return false;\n  }\n};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.get = function(key) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        var json = self.storage_.getItem(key);\n        return fireauth.util.parseJSON(json);\n      });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.set = function(key, value) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        var obj = fireauth.util.stringifyJSON(value);\n        if (obj === null) {\n          self.remove(key);\n        } else {\n          self.storage_.setItem(key, obj);\n        }\n      });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.remove = function(key) {\n  var self = this;\n  return goog.Promise.resolve()\n      .then(function() {\n        self.storage_.removeItem(key);\n      });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n *     listener.\n * @override\n */\nfireauth.storage.SessionStorage.prototype.addStorageListener = function(\n    listener) {};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n *     listener.\n * @override\n */\nfireauth.storage.SessionStorage.prototype.removeStorageListener = function(\n    listener) {};\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 Defines utilities for session management.\n */\n\ngoog.provide('fireauth.authStorage');\ngoog.provide('fireauth.authStorage.Key');\ngoog.provide('fireauth.authStorage.Manager');\ngoog.provide('fireauth.authStorage.Persistence');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Factory');\ngoog.require('fireauth.storage.IndexedDB');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.object');\n\n\n\n/**\n * The namespace for Firebase Auth storage.\n * @private @const {string}\n */\nfireauth.authStorage.NAMESPACE_ = 'firebase';\n\n\n/**\n * The separator for Firebase Auth storage with App ID key.\n * @private @const {string}\n */\nfireauth.authStorage.SEPARATOR_ = ':';\n\n\n/**\n * @const {number} The IE 10 localStorage cross tab synchronization delay in\n *     milliseconds.\n */\nfireauth.authStorage.IE10_LOCAL_STORAGE_SYNC_DELAY = 10;\n\n\n/**\n * Enums for Auth state persistence.\n * @enum {string}\n */\nfireauth.authStorage.Persistence = {\n  // State will persist even when the browser window is closed or the activity\n  // is destroyed in react-native.\n  LOCAL: 'local',\n  // State is only stored in memory and will be cleared when the window or\n  // activity is refreshed.\n  NONE: 'none',\n  // State will only persist in current session/tab, relevant to web only, and\n  // will be cleared when the tab is closed.\n  SESSION: 'session'\n};\n\n\n/**\n * Validates that an argument is a valid persistence value. If an invalid type\n * is specified, an error is thrown synchronously.\n * @param {*} arg The argument to validate.\n */\nfireauth.authStorage.validatePersistenceArgument =\n    function(arg) {\n  // Invalid type error.\n  var invalidTypeError = new fireauth.AuthError(\n      fireauth.authenum.Error.INVALID_PERSISTENCE);\n  // Unsupported type error.\n  var unsupportedTypeError = new fireauth.AuthError(\n      fireauth.authenum.Error.UNSUPPORTED_PERSISTENCE);\n  // Check if the persistence type is a valid one.\n  // Throw invalid type error if not valid.\n  if (!goog.object.containsValue(fireauth.authStorage.Persistence, arg) ||\n      // goog.object.containsValue(fireauth.authStorage.Persistence, ['none'])\n      // returns true.\n      typeof arg !== 'string') {\n    throw invalidTypeError;\n  }\n  // Validate if the specified type is supported in the current environment.\n  switch (fireauth.util.getEnvironment()) {\n    case fireauth.util.Env.REACT_NATIVE:\n      // This is only supported in a browser.\n      if (arg === fireauth.authStorage.Persistence.SESSION) {\n        throw unsupportedTypeError;\n      }\n      break;\n    case fireauth.util.Env.NODE:\n      // Only none is supported in Node.js.\n      if (arg !== fireauth.authStorage.Persistence.NONE) {\n        throw unsupportedTypeError;\n      }\n      break;\n    case fireauth.util.Env.WORKER:\n      // In a worker environment, either LOCAL or NONE are supported.\n      // If indexedDB not supported and LOCAL provided, throw an error.\n      if (arg === fireauth.authStorage.Persistence.SESSION ||\n          (!fireauth.storage.IndexedDB.isAvailable() &&\n           arg !== fireauth.authStorage.Persistence.NONE)) {\n        throw unsupportedTypeError;\n      }\n      break;\n    case fireauth.util.Env.BROWSER:\n    default:\n      // This is restricted by what the browser supports.\n      if (!fireauth.util.isWebStorageSupported() &&\n          arg !== fireauth.authStorage.Persistence.NONE) {\n        throw unsupportedTypeError;\n      }\n      break;\n  }\n};\n\n\n/**\n * Storage key metadata.\n * @typedef {{name: string, persistent: !fireauth.authStorage.Persistence}}\n */\nfireauth.authStorage.Key;\n\n\n/**\n * Storage manager.\n * @param {string} namespace The optional namespace.\n * @param {string} separator The optional separator.\n * @param {boolean} safariLocalStorageNotSynced Whether browser has Safari\n *     iframe restriction with storage event triggering but storage not updated.\n * @param {boolean} runsInBackground Whether browser can detect storage event\n *     when it had already been pushed to the background. This may happen in\n *     some mobile browsers. A localStorage change in the foreground window\n *     will not be detected in the background window via the storage event.\n *     This was detected in iOS 7.x mobile browsers.\n * @param {boolean} webStorageSupported Whether browser web storage is\n *     supported.\n * @constructor @struct @final\n */\nfireauth.authStorage.Manager = function(\n    namespace,\n    separator,\n    safariLocalStorageNotSynced,\n    runsInBackground,\n    webStorageSupported) {\n  /** @const @private {string} Storage namespace. */\n  this.namespace_ = namespace;\n  /** @const @private {string} Storage namespace key separator. */\n  this.separator_ = separator;\n  /**\n   * @const @private {boolean} Whether browser has Safari iframe restriction\n   *     with storage event triggering but storage not updated.\n   */\n  this.safariLocalStorageNotSynced_ = safariLocalStorageNotSynced;\n  /**\n   *  @private {boolean} Whether browser can detect storage event when it\n   *     had already been pushed to the background. This may happen in some\n   *     mobile browsers.\n   */\n  this.runsInBackground_ = runsInBackground;\n  /**  @const @private {boolean} Whether browser web storage is supported. */\n  this.webStorageSupported_ = webStorageSupported;\n\n  /**\n   * @const @private {!Object.<string, !Array<function()>>} The storage event\n   *     key to listeners map.\n   */\n  this.listeners_ = {};\n\n  var storageFactory = fireauth.storage.Factory.getInstance();\n  try {\n    /**\n     * @private {!fireauth.storage.Storage} Persistence storage.\n     */\n    this.persistentStorage_ = storageFactory.makePersistentStorage();\n  } catch (e) {\n    // Default to in memory storage if the preferred persistent storage is not\n    // supported.\n    this.persistentStorage_ = storageFactory.makeInMemoryStorage();\n    // Do not use indexedDB fallback.\n    this.localStorageNotSynchronized_ = false;\n    // Do not set polling functions on window.localStorage.\n    this.runsInBackground_ = true;\n  }\n  try {\n    /**\n     * @private {!fireauth.storage.Storage} Temporary session storage.\n     */\n    this.temporaryStorage_ = storageFactory.makeTemporaryStorage();\n  } catch (e) {\n    // Default to in memory storage if the preferred temporary storage is not\n    // supported. This should be a different in memory instance as the\n    // persistent storage, since the same key could be available for both types\n    // of storage.\n    this.temporaryStorage_ = storageFactory.makeInMemoryStorage();\n  }\n  /**\n   * @private {!fireauth.storage.Storage} In memory storage.\n   */\n  this.inMemoryStorage_ = storageFactory.makeInMemoryStorage();\n\n  /**\n   * @const @private {function(!goog.events.BrowserEvent)|\n   *                  function(!Array<string>)} Storage change handler.\n   */\n  this.storageChangeEventHandler_ = goog.bind(this.storageChangeEvent_, this);\n  /** @private {!Object.<string, *>} Local map for localStorage. */\n  this.localMap_ = {};\n};\n\n\n/**\n * @return {!fireauth.authStorage.Manager} The default Auth storage manager\n *     instance.\n */\nfireauth.authStorage.Manager.getInstance = function() {\n  // Creates the default instance for Auth storage maanger.\n  if (!fireauth.authStorage.Manager.instance_) {\n    /**\n     * @private {?fireauth.authStorage.Manager} The default storage manager\n     *     instance.\n     */\n    fireauth.authStorage.Manager.instance_ = new fireauth.authStorage.Manager(\n        fireauth.authStorage.NAMESPACE_,\n        fireauth.authStorage.SEPARATOR_,\n        fireauth.util.isSafariLocalStorageNotSynced(),\n        fireauth.util.runsInBackground(),\n        fireauth.util.isWebStorageSupported());\n  }\n  return fireauth.authStorage.Manager.instance_;\n};\n\n\n/** Clears storage manager instances. This is used for testing. */\nfireauth.authStorage.Manager.clear = function() {\n  fireauth.authStorage.Manager.instance_ = null;\n};\n\n\n/**\n * Returns the storage corresponding to the specified persistence.\n * @param {!fireauth.authStorage.Persistence} persistent The type of storage\n *     persistence.\n * @return {!fireauth.storage.Storage} The corresponding storage instance.\n * @private\n */\nfireauth.authStorage.Manager.prototype.getStorage_ = function(persistent) {\n  switch (persistent) {\n    case fireauth.authStorage.Persistence.SESSION:\n      return this.temporaryStorage_;\n    case fireauth.authStorage.Persistence.NONE:\n      return this.inMemoryStorage_;\n    case fireauth.authStorage.Persistence.LOCAL:\n    default:\n      return this.persistentStorage_;\n  }\n};\n\n\n/**\n * Constructs the corresponding storage key name.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {?string=} opt_id This ID associates storage values with specific\n *     apps.\n * @return {string} The corresponding key name with namespace prefixed.\n * @private\n */\nfireauth.authStorage.Manager.prototype.getKeyName_ = function(dataKey, opt_id) {\n  return this.namespace_ + this.separator_ + dataKey.name +\n      (opt_id ? this.separator_ + opt_id : '');\n};\n\n\n/**\n * Migrates window.localStorage to the provided persistent storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the persistent\n *     value is supposed to be stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n *     associates storage values with specific apps.\n * @return {!goog.Promise<void>} A promise that resolves when the data stored\n *     in window.localStorage is migrated to the provided persistent storage\n *     identified by the provided data key.\n */\nfireauth.authStorage.Manager.prototype.migrateFromLocalStorage =\n    function(dataKey, opt_id) {\n  var self = this;\n  var key = this.getKeyName_(dataKey, opt_id);\n  var storage = this.getStorage_(dataKey.persistent);\n  // Get data stored in the default persistent storage identified by dataKey.\n  return this.get(dataKey, opt_id).then(function(response) {\n    // Get the stored value in window.localStorage if available.\n    var oldStorageValue = null;\n    try {\n      oldStorageValue = fireauth.util.parseJSON(\n          goog.global['localStorage']['getItem'](key));\n    } catch (e) {\n      // Set value as null. This will resolve the promise immediately.\n    }\n    // If data is stored in window.localStorage but no data is available in\n    // default persistent storage, migrate data from window.localStorage to\n    // default persistent storage.\n    if (oldStorageValue && !response) {\n      // This condition may fail in situations where a user opens a tab with\n      // an old version while using a tab with a new version, or when a\n      // developer switches back and forth between and old and new version of\n      // the library.\n      goog.global['localStorage']['removeItem'](key);\n      // Migrate the value to new default persistent storage.\n      return self.set(dataKey, oldStorageValue, opt_id);\n    } else if (oldStorageValue &&\n               response &&\n               storage.type != fireauth.storage.Storage.Type.LOCAL_STORAGE) {\n      // Data stored in both localStorage and new persistent storage (eg.\n      // indexedDB) for some reason.\n      // This could happen if the developer is migrating back and forth.\n      // The new default persistent storage (eg. indexedDB) takes precedence.\n      goog.global['localStorage']['removeItem'](key);\n    }\n  });\n};\n\n\n/**\n * Gets the stored value from the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n *     associates storage values with specific apps.\n * @return {!goog.Promise} A Promise that resolves with the stored value.\n */\nfireauth.authStorage.Manager.prototype.get = function(dataKey, opt_id) {\n  var keyName = this.getKeyName_(dataKey, opt_id);\n  return this.getStorage_(dataKey.persistent).get(keyName);\n};\n\n\n/**\n * Removes the stored value from the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n *     associates storage values with specific apps.\n * @return {!goog.Promise<void>} A Promise that resolves when the operation is\n *     completed.\n */\nfireauth.authStorage.Manager.prototype.remove = function(dataKey, opt_id) {\n  var keyName = this.getKeyName_(dataKey, opt_id);\n  // Keep local map up to date for requested key if persistent storage is used.\n  if (dataKey.persistent == fireauth.authStorage.Persistence.LOCAL) {\n    this.localMap_[keyName] = null;\n  }\n  return this.getStorage_(dataKey.persistent).remove(keyName);\n};\n\n\n/**\n * Stores the value in the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {*} value The value to be stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n *     associates storage values with specific apps.\n * @return {!goog.Promise<void>} A Promise that resolves when the operation is\n *     completed.\n */\nfireauth.authStorage.Manager.prototype.set = function(dataKey, value, opt_id) {\n  var keyName = this.getKeyName_(dataKey, opt_id);\n  var self = this;\n  var storage = this.getStorage_(dataKey.persistent);\n  return storage.set(keyName, value)\n      .then(function() {\n        return storage.get(keyName);\n      })\n      .then(function(serializedValue) {\n        // Keep local map up to date for requested key if persistent storage is\n        // used.\n        if (dataKey.persistent == fireauth.authStorage.Persistence.LOCAL) {\n          self.localMap_[keyName] = serializedValue;\n        }\n      });\n};\n\n\n/**\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {?string} id When operating in multiple app mode, this ID associates\n *     storage values with specific apps.\n * @param {function()} listener The callback listener to run on storage event\n *     related to key.\n */\nfireauth.authStorage.Manager.prototype.addListener =\n    function(dataKey, id, listener) {\n  var key = this.getKeyName_(dataKey, id);\n  // Initialize local map for current key if web storage is supported.\n  if (this.webStorageSupported_) {\n    this.localMap_[key] = goog.global['localStorage']['getItem'](key);\n  }\n  if (goog.object.isEmpty(this.listeners_)) {\n    // Start listeners.\n    this.startListeners_();\n  }\n  if (!this.listeners_[key]) {\n    this.listeners_[key] = [];\n  }\n  this.listeners_[key].push(listener);\n};\n\n\n/**\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n *     stored.\n * @param {?string} id When operating in multiple app mode, this ID associates\n *     storage values with specific apps.\n * @param {function()} listener The listener to remove.\n */\nfireauth.authStorage.Manager.prototype.removeListener =\n    function(dataKey, id, listener) {\n  var key = this.getKeyName_(dataKey, id);\n  if (this.listeners_[key]) {\n    goog.array.removeAllIf(\n        this.listeners_[key],\n        function(ele) {\n          return ele == listener;\n        });\n    if (this.listeners_[key].length == 0) {\n      delete this.listeners_[key];\n    }\n  }\n  if (goog.object.isEmpty(this.listeners_)) {\n    // Stop listeners.\n    this.stopListeners_();\n  }\n};\n\n\n/**\n * The delay to wait between continuous checks of localStorage on browsers where\n * tabs do not run in the background. After each interval wait, we check for\n * external changes in localStorage that were not detected in the current tab.\n * @const {number}\n * @private\n */\nfireauth.authStorage.Manager.LOCAL_STORAGE_POLLING_TIMER_ = 1000;\n\n\n/**\n * Starts all storage event listeners.\n * @private\n */\nfireauth.authStorage.Manager.prototype.startListeners_ = function() {\n  this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n      .addStorageListener(this.storageChangeEventHandler_);\n  // TODO: refactor this implementation to be handled by the underlying\n  // storage mechanism.\n  if (!this.runsInBackground_ &&\n      // Add an exception for browsers that persist storage with indexedDB, we\n      // should stick with indexedDB listener implementation in that case.\n      !fireauth.util.persistsStorageWithIndexedDB() &&\n      // Confirm browser web storage is supported as polling relies on it.\n      this.webStorageSupported_) {\n    this.startManualListeners_();\n  }\n};\n\n/**\n * Starts manual polling function to detect storage event changes.\n * @private\n */\nfireauth.authStorage.Manager.prototype.startManualListeners_ = function() {\n  var self = this;\n  this.stopManualListeners_();\n  /** @private {?number} The interval timer for manual storage checking. */\n  this.manualListenerTimer_ = setInterval(function() {\n    // Check all keys with listeners on them.\n    for (var key in self.listeners_) {\n      // Get value from localStorage.\n      var currentValue = goog.global['localStorage']['getItem'](key);\n      var oldValue = self.localMap_[key];\n      // If local map value does not match, trigger listener with storage event.\n      if (currentValue != oldValue) {\n        self.localMap_[key] = currentValue;\n        var event = new goog.events.BrowserEvent(/** @type {!Event} */ ({\n          type: 'storage',\n          key: key,\n          target: window,\n          oldValue: oldValue,\n          newValue: currentValue,\n          // Differentiate this simulated event from the real storage event.\n          poll: true\n        }));\n        self.storageChangeEvent_(event);\n      }\n    }\n  }, fireauth.authStorage.Manager.LOCAL_STORAGE_POLLING_TIMER_);\n};\n\n\n/**\n * Stops manual polling function to detect storage event changes.\n * @private\n */\nfireauth.authStorage.Manager.prototype.stopManualListeners_ = function() {\n  if (this.manualListenerTimer_) {\n    clearInterval(this.manualListenerTimer_);\n    this.manualListenerTimer_ = null;\n  }\n};\n\n\n/**\n * Stops all storage event listeners.\n * @private\n */\nfireauth.authStorage.Manager.prototype.stopListeners_ = function() {\n  this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n      .removeStorageListener(this.storageChangeEventHandler_);\n  this.stopManualListeners_();\n};\n\n\n/**\n * @param {!goog.events.BrowserEvent|!Array<string>} data The storage event\n *     triggered or the array of keys modified.\n * @private\n */\nfireauth.authStorage.Manager.prototype.storageChangeEvent_ = function(data) {\n  if (data && data.getBrowserEvent) {\n    var event = /** @type {!goog.events.BrowserEvent} */ (data);\n    var key = event.getBrowserEvent().key;\n    // Key would be null in some situations, like when localStorage is cleared\n    // from the browser developer tools.\n    if (key == null) {\n      // For all keys of interest.\n      for (var keyName in this.listeners_) {\n        // Check if something changed in this key's real value.\n        var storedValue = this.localMap_[keyName];\n        // localStorage returns null when a field is not found.\n        if (typeof storedValue === 'undefined') {\n          storedValue = null;\n        }\n        var realValue = goog.global['localStorage']['getItem'](keyName);\n        if (realValue !== storedValue) {\n          // Update local map with real value.\n          this.localMap_[keyName] = realValue;\n          // Trigger that key's listener.\n          this.callListeners_(keyName);\n        }\n      }\n      return;\n    }\n    // Check if the key is Firebase Auth related, otherwise ignore.\n    if (key.indexOf(this.namespace_ + this.separator_) != 0 ||\n        // Ignore keys that have no listeners.\n        !this.listeners_[key]) {\n      return;\n    }\n    // Check the mechanism how this event was detected.\n    // The first event will dictate the mechanism to be used.\n    // Do not use hasOwnProperty('poll') as poll gets obfuscated.\n    if (typeof event.getBrowserEvent().poll !== 'undefined') {\n      // Environment detects storage changes via polling.\n      // Remove storage event listener to prevent possible event duplication.\n      this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n          .removeStorageListener(this.storageChangeEventHandler_);\n    } else {\n      // Environment detects storage changes via storage event listener.\n      // Remove polling listener to prevent possible event duplication.\n      this.stopManualListeners_();\n    }\n    // Safari embedded iframe. Storage event will trigger with the delta changes\n    // but no changes will be applied to the iframe localStorage.\n    if (this.safariLocalStorageNotSynced_) {\n      // Get current iframe page value, old value and new value.\n      var currentValue = goog.global['localStorage']['getItem'](key);\n      var newValue = event.getBrowserEvent().newValue;\n      // Value not synchronized, synchronize manually.\n      if (newValue !== currentValue) {\n        if (newValue !== null) {\n          // Value changed from current value.\n          goog.global['localStorage']['setItem'](key, newValue);\n        } else {\n          // Current value deleted.\n          goog.global['localStorage']['removeItem'](key);\n        }\n      } else {\n        // Already detected and processed, do not trigger listeners again.\n        if (this.localMap_[key] === newValue &&\n            // Real storage event.\n            typeof event.getBrowserEvent().poll === 'undefined') {\n          return;\n        }\n      }\n    }\n    var self = this;\n    var triggerListeners = function() {\n      // Keep local map up to date in case storage event is triggered before\n      // poll.\n      if (typeof event.getBrowserEvent().poll === 'undefined' &&\n          self.localMap_[key] === goog.global['localStorage']['getItem'](key)) {\n        // Real storage event which has already been detected, do nothing.\n        // This seems to trigger in some IE browsers for some reason.\n        return;\n      }\n      self.localMap_[key] = goog.global['localStorage']['getItem'](key);\n      self.callListeners_(key);\n    };\n    if (fireauth.util.isIe10() &&\n        goog.global['localStorage']['getItem'](key) !==\n        event.getBrowserEvent().newValue &&\n        event.getBrowserEvent().newValue !== event.getBrowserEvent().oldValue) {\n      // IE 10 has this weird bug where a storage event would trigger with the\n      // correct key, oldValue and newValue but localStorage.getItem(key) does\n      // not yield the updated value until a few milliseconds. This ensures this\n      // recovers from that situation.\n      setTimeout(\n          triggerListeners, fireauth.authStorage.IE10_LOCAL_STORAGE_SYNC_DELAY);\n    } else {\n      triggerListeners();\n    }\n  } else {\n    var keys = /** @type {!Array<string>} */ (data);\n    goog.array.forEach(keys, goog.bind(this.callListeners_, this));\n  }\n};\n\n\n/**\n * Calls all listeners for specified storage event key.\n * @param {string} key The storage event key whose listeners are to be run.\n * @private\n */\nfireauth.authStorage.Manager.prototype.callListeners_ = function(key) {\n  if (this.listeners_[key]) {\n    goog.array.forEach(\n        this.listeners_[key],\n        function(listener) {\n          listener();\n        });\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Base class for SHA-2 cryptographic hash.\n *\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 * Some code similar to SHA1 are borrowed from sha1.js written by mschilder@.\n */\n\ngoog.provide('goog.crypt.Sha2');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.crypt.Hash');\n\n\n\n/**\n * SHA-2 cryptographic hash constructor.\n * This constructor should not be used directly to create the object. Rather,\n * one should use the constructor of the sub-classes.\n * @param {number} numHashBlocks The size of output in 16-byte blocks.\n * @param {!Array<number>} initHashBlocks The hash-specific initialization\n * @constructor\n * @extends {goog.crypt.Hash}\n * @struct\n */\ngoog.crypt.Sha2 = function(numHashBlocks, initHashBlocks) {\n  goog.crypt.Sha2.base(this, 'constructor');\n\n  this.blockSize = goog.crypt.Sha2.BLOCKSIZE_;\n\n  /**\n   * A chunk holding the currently processed message bytes. Once the chunk has\n   * 64 bytes, we feed it into computeChunk_ function and reset this.chunk_.\n   * @private {!Array<number>|!Uint8Array}\n   */\n  this.chunk_ = goog.global['Uint8Array'] ? new Uint8Array(this.blockSize) :\n                                            new Array(this.blockSize);\n\n  /**\n   * Current number of bytes in this.chunk_.\n   * @private {number}\n   */\n  this.inChunk_ = 0;\n\n  /**\n   * Total number of bytes in currently processed message.\n   * @private {number}\n   */\n  this.total_ = 0;\n\n\n  /**\n   * Holds the previous values of accumulated hash a-h in the computeChunk_\n   * function.\n   * @private {!Array<number>|!Int32Array}\n   */\n  this.hash_ = [];\n\n  /**\n   * The number of output hash blocks (each block is 4 bytes long).\n   * @private {number}\n   */\n  this.numHashBlocks_ = numHashBlocks;\n\n  /**\n   * @private {!Array<number>} initHashBlocks\n   */\n  this.initHashBlocks_ = initHashBlocks;\n\n  /**\n   * Temporary array used in chunk computation.  Allocate here as a\n   * member rather than as a local within computeChunk_() as a\n   * performance optimization to reduce the number of allocations and\n   * reduce garbage collection.\n   * @private {!Int32Array|!Array<number>}\n   */\n  this.w_ = goog.global['Int32Array'] ? new Int32Array(64) : new Array(64);\n\n  if (goog.crypt.Sha2.Kx_ === undefined) {\n    // This is the first time this constructor has been called.\n    if (goog.global['Int32Array']) {\n      // Typed arrays exist\n      goog.crypt.Sha2.Kx_ = new Int32Array(goog.crypt.Sha2.K_);\n    } else {\n      // Typed arrays do not exist\n      goog.crypt.Sha2.Kx_ = goog.crypt.Sha2.K_;\n    }\n  }\n\n  this.reset();\n};\ngoog.inherits(goog.crypt.Sha2, goog.crypt.Hash);\n\n\n/**\n * The block size\n * @private {number}\n */\ngoog.crypt.Sha2.BLOCKSIZE_ = 512 / 8;\n\n\n/**\n * Contains data needed to pad messages less than BLOCK_SIZE_ bytes.\n * @private {!Array<number>}\n */\ngoog.crypt.Sha2.PADDING_ = goog.array.concat(\n    128, goog.array.repeat(0, goog.crypt.Sha2.BLOCKSIZE_ - 1));\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.reset = function() {\n  this.inChunk_ = 0;\n  this.total_ = 0;\n  this.hash_ = goog.global['Int32Array'] ?\n      new Int32Array(this.initHashBlocks_) :\n      goog.array.clone(this.initHashBlocks_);\n};\n\n\n/**\n * Helper function to compute the hashes for a given 512-bit message chunk.\n * @private\n */\ngoog.crypt.Sha2.prototype.computeChunk_ = function() {\n  var chunk = this.chunk_;\n  goog.asserts.assert(chunk.length == this.blockSize);\n  var rounds = 64;\n\n  // Divide the chunk into 16 32-bit-words.\n  var w = this.w_;\n  var index = 0;\n  var offset = 0;\n  while (offset < chunk.length) {\n    w[index++] = (chunk[offset] << 24) | (chunk[offset + 1] << 16) |\n        (chunk[offset + 2] << 8) | (chunk[offset + 3]);\n    offset = index * 4;\n  }\n\n  // Extend the w[] array to be the number of rounds.\n  for (var i = 16; i < rounds; i++) {\n    var w_15 = w[i - 15] | 0;\n    var s0 = ((w_15 >>> 7) | (w_15 << 25)) ^ ((w_15 >>> 18) | (w_15 << 14)) ^\n        (w_15 >>> 3);\n    var w_2 = w[i - 2] | 0;\n    var s1 = ((w_2 >>> 17) | (w_2 << 15)) ^ ((w_2 >>> 19) | (w_2 << 13)) ^\n        (w_2 >>> 10);\n\n    // As a performance optimization, construct the sum a pair at a time\n    // with casting to integer (bitwise OR) to eliminate unnecessary\n    // double<->integer conversions.\n    var partialSum1 = ((w[i - 16] | 0) + s0) | 0;\n    var partialSum2 = ((w[i - 7] | 0) + s1) | 0;\n    w[i] = (partialSum1 + partialSum2) | 0;\n  }\n\n  var a = this.hash_[0] | 0;\n  var b = this.hash_[1] | 0;\n  var c = this.hash_[2] | 0;\n  var d = this.hash_[3] | 0;\n  var e = this.hash_[4] | 0;\n  var f = this.hash_[5] | 0;\n  var g = this.hash_[6] | 0;\n  var h = this.hash_[7] | 0;\n  for (var i = 0; i < rounds; i++) {\n    var S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^\n        ((a >>> 22) | (a << 10));\n    var maj = ((a & b) ^ (a & c) ^ (b & c));\n    var t2 = (S0 + maj) | 0;\n    var S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^\n        ((e >>> 25) | (e << 7));\n    var ch = ((e & f) ^ ((~e) & g));\n\n    // As a performance optimization, construct the sum a pair at a time\n    // with casting to integer (bitwise OR) to eliminate unnecessary\n    // double<->integer conversions.\n    var partialSum1 = (h + S1) | 0;\n    var partialSum2 = (ch + (goog.crypt.Sha2.Kx_[i] | 0)) | 0;\n    var partialSum3 = (partialSum2 + (w[i] | 0)) | 0;\n    var t1 = (partialSum1 + partialSum3) | 0;\n\n    h = g;\n    g = f;\n    f = e;\n    e = (d + t1) | 0;\n    d = c;\n    c = b;\n    b = a;\n    a = (t1 + t2) | 0;\n  }\n\n  this.hash_[0] = (this.hash_[0] + a) | 0;\n  this.hash_[1] = (this.hash_[1] + b) | 0;\n  this.hash_[2] = (this.hash_[2] + c) | 0;\n  this.hash_[3] = (this.hash_[3] + d) | 0;\n  this.hash_[4] = (this.hash_[4] + e) | 0;\n  this.hash_[5] = (this.hash_[5] + f) | 0;\n  this.hash_[6] = (this.hash_[6] + g) | 0;\n  this.hash_[7] = (this.hash_[7] + h) | 0;\n};\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.update = function(message, opt_length) {\n  if (opt_length === undefined) {\n    opt_length = message.length;\n  }\n  // Process the message from left to right up to |opt_length| bytes.\n  // When we get a 512-bit chunk, compute the hash of it and reset\n  // this.chunk_. The message might not be multiple of 512 bits so we\n  // might end up with a chunk that is less than 512 bits. We store\n  // such partial chunk in this.chunk_ and it will be filled up later\n  // in digest().\n  var n = 0;\n  var inChunk = this.inChunk_;\n\n  // The input message could be either byte array of string.\n  if (typeof message === 'string') {\n    while (n < opt_length) {\n      this.chunk_[inChunk++] = message.charCodeAt(n++);\n      if (inChunk == this.blockSize) {\n        this.computeChunk_();\n        inChunk = 0;\n      }\n    }\n  } else if (goog.isArrayLike(message)) {\n    while (n < opt_length) {\n      var b = message[n++];\n      if (!('number' == typeof b && 0 <= b && 255 >= b && b == (b | 0))) {\n        throw new Error('message must be a byte array');\n      }\n      this.chunk_[inChunk++] = b;\n      if (inChunk == this.blockSize) {\n        this.computeChunk_();\n        inChunk = 0;\n      }\n    }\n  } else {\n    throw new Error('message must be string or array');\n  }\n\n  // Record the current bytes in chunk to support partial update.\n  this.inChunk_ = inChunk;\n\n  // Record total message bytes we have processed so far.\n  this.total_ += opt_length;\n};\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.digest = function() {\n  var digest = [];\n  var totalBits = this.total_ * 8;\n\n  // Append pad 0x80 0x00*.\n  if (this.inChunk_ < 56) {\n    this.update(goog.crypt.Sha2.PADDING_, 56 - this.inChunk_);\n  } else {\n    this.update(\n        goog.crypt.Sha2.PADDING_, this.blockSize - (this.inChunk_ - 56));\n  }\n\n  // Append # bits in the 64-bit big-endian format.\n  for (var i = 63; i >= 56; i--) {\n    this.chunk_[i] = totalBits & 255;\n    totalBits /= 256;  // Don't use bit-shifting here!\n  }\n  this.computeChunk_();\n\n  // Finally, output the result digest.\n  var n = 0;\n  for (var i = 0; i < this.numHashBlocks_; i++) {\n    for (var j = 24; j >= 0; j -= 8) {\n      digest[n++] = ((this.hash_[i] >> j) & 255);\n    }\n  }\n  return digest;\n};\n\n\n/**\n * Constants used in SHA-2.\n * @const\n * @private {!Array<number>}\n */\ngoog.crypt.Sha2.K_ = [\n  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n  0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n  0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n  0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n  0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\n\n/**\n * Sha2.K as an Int32Array if this JS supports typed arrays; otherwise,\n * the same array as Sha2.K.\n *\n * The compiler cannot remove an Int32Array, even if it is not needed\n * (There are certain cases where creating an Int32Array is not\n * side-effect free).  Instead, the first time we construct a Sha2\n * instance, we convert or assign Sha2.K as appropriate.\n * @private {undefined|!Array<number>|!Int32Array}\n */\ngoog.crypt.Sha2.Kx_;\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines Cordova utility and helper functions.\n * The following plugins must be installed:\n * cordova plugin add cordova-plugin-buildinfo\n * cordova plugin add cordova-universal-links-plugin-fix\n * cordova plugin add cordova-plugin-browsertab\n * cordova plugin add cordova-plugin-inappbrowser\n * iOS custom scheme support:\n * cordova plugin add cordova-plugin-customurlscheme --variable \\\n * URL_SCHEME=com.firebase.example\n * Console logging in iOS:\n * cordova plugin add cordova-plugin-console\n */\n\ngoog.provide('fireauth.CordovaHandler');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.DynamicLink');\ngoog.require('fireauth.OAuthSignInHandler');\ngoog.require('fireauth.UniversalLinkSubscriber');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.storage.AuthEventManager');\ngoog.require('fireauth.storage.OAuthHandlerManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.crypt');\ngoog.require('goog.crypt.Sha256');\n\n\n/**\n * Cordova environment utility and helper functions.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {number=} opt_initialTimeout Initial Auth event timeout.\n * @param {number=} opt_redirectTimeout Redirect result timeout.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @constructor\n * @implements {fireauth.OAuthSignInHandler}\n */\nfireauth.CordovaHandler = function(authDomain, apiKey, appName,\n    opt_clientVersion, opt_initialTimeout, opt_redirectTimeout,\n    opt_endpointId) {\n  /** @private {string} The application authDomain. */\n  this.authDomain_ = authDomain;\n  /** @private {string} The application API key. */\n  this.apiKey_ = apiKey;\n  /** @private {string} The application name. */\n  this.appName_ = appName;\n  /** @private {?string} The client version */\n  this.clientVersion_ = opt_clientVersion || null;\n  /** @private {?string} The Auth endpoint ID. */\n  this.endpointId_ = opt_endpointId || null;\n  /** @private {string} The storage key. */\n  this.storageKey_ = fireauth.util.createStorageKey(apiKey, appName);\n  /**\n   * @private {!fireauth.storage.OAuthHandlerManager} The OAuth handler\n   *     storage manager reference, used to save a partial Auth event when\n   *     redirect operation is triggered.\n   */\n  this.savePartialEventManager_ = new fireauth.storage.OAuthHandlerManager();\n  /**\n   * @private {!fireauth.storage.AuthEventManager} The Auth event storage\n   *     manager reference. This is used to get back the saved partial Auth\n   *     event and then delete on successful handling.\n   */\n  this.getAndDeletePartialEventManager_ =\n      new fireauth.storage.AuthEventManager(this.storageKey_);\n  /**\n   * @private {?goog.Promise<!fireauth.AuthEvent>} A promise that resolves with\n   *     the OAuth redirect URL response.\n   */\n  this.initialAuthEvent_ = null;\n  /**\n   * @private {!Array<!function(?fireauth.AuthEvent)>} The Auth event\n   *     listeners.\n   */\n  this.authEventListeners_ = [];\n  /** @private {number} The initial Auth event timeout. */\n  this.initialTimeout_ = opt_initialTimeout ||\n      fireauth.CordovaHandler.INITIAL_TIMEOUT_MS_;\n  /** @private {number} The return to app after redirect timeout. */\n  this.redirectTimeout_ = opt_redirectTimeout ||\n      fireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_;\n  /**\n   * @private {?goog.Promise} The last pending redirect promise. This is null if\n   *     already completed.\n   */\n  this.pendingRedirect_ = null;\n  /**\n   * @private {?Object} The inAppBrowser reference window if available. This is\n   *     relevant to iOS 7 and 8 embedded webviews.\n   */\n  this.inAppBrowserRef_ = null;\n};\n\n\n/**\n * The total number of chars used to generate the session ID string.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.SESSION_ID_TOTAL_CHARS_ = 20;\n\n\n/**\n * The default initial Auth event timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.INITIAL_TIMEOUT_MS_ = 500;\n\n\n/**\n * The default timeout in milliseconds for a pending redirect operation after\n * returning to the app.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_ = 2000;\n\n\n/**\n * Constructs a Cordova configuration error message.\n * @param {?string=} opt_message The optional error message to be used. This\n *     will override the existing default one.\n * @return {!fireauth.AuthError} The Cordova invalid configuration error with\n *     the custom message provided. If no message is provided, the default\n *     message is used.\n * @private\n */\nfireauth.CordovaHandler.getError_ = function(opt_message) {\n  return new fireauth.AuthError(\n      fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION,\n      opt_message);\n};\n\n\n/**\n * Initializes the Cordova environment and waits for it to be ready.\n * @return {!goog.Promise} A promise that resolves if the current environment is\n *     a Cordova environment.\n * @override\n */\nfireauth.CordovaHandler.prototype.initializeAndWait = function() {\n  if (this.isReady_) {\n    return this.isReady_;\n  }\n  this.isReady_ = fireauth.util.checkIfCordova().then(function() {\n    // Check all dependencies installed.\n    // Note that cordova-universal-links-plugin has been abandoned.\n    // A fork with latest fixes is available at:\n    // https://www.npmjs.com/package/cordova-universal-links-plugin-fix\n    var subscribe = fireauth.util.getObjectRef(\n        'universalLinks.subscribe', goog.global);\n    if (typeof subscribe !== 'function') {\n      throw fireauth.CordovaHandler.getError_(\n          'cordova-universal-links-plugin-fix is not installed');\n    }\n    // https://www.npmjs.com/package/cordova-plugin-buildinfo\n    var appIdentifier =\n        fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n    if (typeof appIdentifier === 'undefined') {\n      throw fireauth.CordovaHandler.getError_(\n          'cordova-plugin-buildinfo is not installed');\n    }\n    // https://github.com/google/cordova-plugin-browsertab\n    var openUrl = fireauth.util.getObjectRef(\n        'cordova.plugins.browsertab.openUrl', goog.global);\n    if (typeof openUrl !== 'function') {\n      throw fireauth.CordovaHandler.getError_(\n          'cordova-plugin-browsertab is not installed');\n    }\n    // https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/\n    var openInAppBrowser = fireauth.util.getObjectRef(\n        'cordova.InAppBrowser.open', goog.global);\n    if (typeof openInAppBrowser !== 'function') {\n      throw fireauth.CordovaHandler.getError_(\n          'cordova-plugin-inappbrowser is not installed');\n    }\n  }, function(error) {\n    // If not supported.\n    throw new fireauth.AuthError(fireauth.authenum.Error.CORDOVA_NOT_READY);\n  });\n  return this.isReady_;\n};\n\n\n/**\n * Generates a session ID. Used to prevent session fixation attacks.\n * @param {number} numOfChars The number of characters to generate.\n * @return {string} The generated session ID.\n * @private\n */\nfireauth.CordovaHandler.prototype.generateSessionId_ = function(numOfChars) {\n  var chars = [];\n  var allowedChars =\n      '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  while (numOfChars > 0) {\n    var index = Math.floor(Math.random() * allowedChars.length);\n    chars.push(allowedChars.charAt(index));\n    numOfChars--;\n  }\n  return chars.join('');\n};\n\n\n/**\n * Computes the sha256 hash of a session ID.\n * @param {string} str The string to hash.\n * @return {string} The hashed string.\n * @private\n */\nfireauth.CordovaHandler.prototype.computeSecureHash_ = function(str) {\n  // sha256 the sessionId. This will be passed to the OAuth backend.\n  // When exchanging the Auth code with a firebase ID token, the raw session ID\n  // needs to be provided.\n  var sha256 = new goog.crypt.Sha256();\n  sha256.update(str);\n  return goog.crypt.byteArrayToHex(sha256.digest());\n};\n\n\n/**\n * Waits for popup window to close and time out if the result is unhandled.\n * This is not supported in Cordova.\n * @param {!Window} popupWin The popup window.\n * @param {!function(!fireauth.AuthError)} onError The on error callback.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.CordovaHandler.prototype.startPopupTimeout =\n    function(popupWin, onError, timeoutDuration) {\n  // Not supported operation, check processPopup for details.\n  onError(new fireauth.AuthError(\n      fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  return goog.Promise.resolve();\n};\n\n\n/**\n * Processes the popup request. This is not supported in Cordova.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function()} onInitialize The function to call on initialization.\n * @param {function(*)} onError The function to call on error.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n *     to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n * @override\n */\nfireauth.CordovaHandler.prototype.processPopup = function(\n    popupWin,\n    mode,\n    provider,\n    onInitialize,\n    onError,\n    opt_eventId,\n    opt_alreadyRedirected,\n    opt_tenantId) {\n  // Popups not supported in Cordova as the activity could be destroyed in\n  // some cases. Redirect works better as getRedirectResult can be used as a\n  // fallback to get the result when the activity is detroyed.\n  return goog.Promise.reject(new fireauth.AuthError(\n      fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n};\n\n\n/**\n * @return {boolean} Whether the handler will unload the current page on\n *     redirect operations.\n * @override\n */\nfireauth.CordovaHandler.prototype.unloadsOnRedirect = function() {\n  // Does not necessarily unload the page on redirect.\n  return false;\n};\n\n\n/**\n * @return {boolean} Whether the handler should be initialized early.\n * @override\n */\nfireauth.CordovaHandler.prototype.shouldBeInitializedEarly = function() {\n  // Initialize early to detect incoming link. This is not an expensive\n  // operation, unlike embedding an iframe.\n  return true;\n};\n\n\n/**\n * @return {boolean} Whether the sign-in handler in the current environment\n *     has volatile session storage.\n * @override\n */\nfireauth.CordovaHandler.prototype.hasVolatileStorage = function() {\n  // An activity can be destroyed and thereby sessionStorage wiped out.\n  return true;\n};\n\n\n/**\n * Processes the OAuth redirect request. Will resolve when the OAuth response\n * is detected in the incoming link and the corresponding Auth event is\n * triggered.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.CordovaHandler.prototype.processRedirect = function(\n    mode,\n    provider,\n    opt_eventId,\n    opt_tenantId) {\n  // If there is already a pending redirect, throw an error.\n  if (this.pendingRedirect_) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.REDIRECT_OPERATION_PENDING));\n  }\n  var self = this;\n  var doc = goog.global.document;\n  // On close timer promise.\n  var onClose = null;\n  // Auth event detection callback;\n  var authEventCallback = null;\n  // On resume (return from the redirect operation).\n  var onResume = null;\n  // On visibility change used to detect return to app in certain versions,\n  // currently iOS.\n  var onVisibilityChange = null;\n  // When the processRedirect promise completes, clean up any remaining\n  // temporary listeners and timers.\n  var cleanup = function() {\n    // Remove current resume listener.\n    if (onResume) {\n      doc.removeEventListener('resume', onResume, false);\n    }\n    // Remove visibility change listener.\n    if (onVisibilityChange) {\n      doc.removeEventListener('visibilitychange', onVisibilityChange, false);\n    }\n    // Cancel onClose promise if not already cancelled.\n    if (onClose) {\n      onClose.cancel();\n    }\n    // Remove Auth event callback.\n    if (authEventCallback) {\n      self.removeAuthEventListener(authEventCallback);\n    }\n    // Clear any pending redirect now that it is completed.\n    self.pendingRedirect_ = null;\n  };\n  // Save the pending redirect promise and clear it on completion.\n  this.pendingRedirect_ = goog.Promise.resolve().then(function() {\n    // Validate provider.\n    // Fail fast in this case.\n    fireauth.AuthProvider.checkIfOAuthSupported(provider);\n    return self.getInitialAuthEvent_();\n  }).then(function() {\n    return self.processRedirectInternal_(\n        mode, provider, opt_eventId, opt_tenantId);\n  }).then(function() {\n    // Wait for result (universal link) before resolving this operation.\n    // This ensures that if the activity is not destroyed, we can still\n    // return the result of this operation.\n    return new goog.Promise(function(resolve, reject) {\n      /**\n       * @param {?fireauth.AuthEvent} event The Auth event detected.\n       * @return {boolean}\n       */\n      authEventCallback = function(event) {\n        // Auth event detected, resolve promise.\n        // Close SFSVC if still open.\n        var closeBrowsertab = fireauth.util.getObjectRef(\n            'cordova.plugins.browsertab.close', goog.global);\n        resolve();\n        // Close the SFSVC if it is still open (iOS 9+).\n        if (typeof closeBrowsertab === 'function') {\n          closeBrowsertab();\n        }\n        // Close inappbrowser emebedded webview in iOS7 and 8 case if still\n        // open.\n        if (self.inAppBrowserRef_ &&\n            typeof self.inAppBrowserRef_['close'] === 'function') {\n          self.inAppBrowserRef_['close']();\n          // Reset reference.\n          self.inAppBrowserRef_ = null;\n        }\n        return false;\n      };\n      // Wait and listen for the operation to complete (Auth event would\n      // trigger).\n      self.addAuthEventListener(authEventCallback);\n      // On resume (return from the redirect operation).\n      onResume = function() {\n        // Already resumed. Do not run again.\n        if (onClose) {\n          return;\n        }\n        // Wait for some time before throwing the error that the flow was\n        // cancelled by the user.\n        onClose = goog.Timer.promise(self.redirectTimeout_).then(function() {\n          // Throw the redirect cancelled by user error.\n          reject(new fireauth.AuthError(\n              fireauth.authenum.Error.REDIRECT_CANCELLED_BY_USER));\n        });\n      };\n      onVisibilityChange = function() {\n        // If app is visible, run onResume. Otherwise, ignore.\n        if (fireauth.util.isAppVisible()) {\n          onResume();\n        }\n      };\n      // Listen to resume event (will trigger when the user returns to the app).\n      doc.addEventListener('resume', onResume, false);\n      // Listen to visibility change. This is used for iOS Cordova Safari 7+.\n      // Does not work in Android stock browser versions older than 4.4.\n      // We rely on resume event in Android as it works reliably in all\n      // versions.\n      if (!fireauth.util.isAndroid()) {\n        doc.addEventListener('visibilitychange', onVisibilityChange, false);\n      }\n    }).thenCatch(function(error) {\n      // Remove any pending partial event.\n      return self.getPartialStoredEvent_().then(function() {\n        throw error;\n      });\n    });\n  }).thenAlways(cleanup);\n  // Return the pending redirect promise.\n  return this.pendingRedirect_;\n};\n\n/**\n * Processes the OAuth redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @private\n */\nfireauth.CordovaHandler.prototype.processRedirectInternal_ = function(\n    mode,\n    provider,\n    opt_eventId,\n    opt_tenantId) {\n  var self = this;\n  // https://github.com/google/cordova-plugin-browsertab\n  // Opens chrome custom tab in Android if chrome is installed,\n  // SFSafariViewController in iOS if supported.\n  // If the above are not supported, opens the system browser.\n  // Opening a system browser could result in an app being rejected in the App\n  // Store. The only solution here is to use an insecure embedded UIWebView.\n  // This applies to older iOS versions 8 and under.\n  // Generate a random session ID.\n  var sessionId = this.generateSessionId_(\n      fireauth.CordovaHandler.SESSION_ID_TOTAL_CHARS_);\n  // Create the partial Auth event.\n  var event = new fireauth.AuthEvent(\n      mode,\n      opt_eventId,\n      null,\n      sessionId,\n      new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT),\n      null,\n      opt_tenantId);\n  // Use buildinfo package to get app metadata.\n  // https://www.npmjs.com/package/cordova-plugin-buildinfo\n  // Get app identifier.\n  var appIdentifier =\n      fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n  // initializeAndWait will ensure this does not happen.\n  if (typeof appIdentifier !== 'string') {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n  }\n  // Get app display name.\n  var appDisplayName =\n      fireauth.util.getObjectRef('BuildInfo.displayName', goog.global);\n  // Construct additional params to pass to OAuth handler.\n  var additionalParams  = {};\n  // Append app identifier.\n  if (fireauth.util.isIOS()) {\n    // iOS app.\n    additionalParams['ibi'] = appIdentifier;\n  } else if (fireauth.util.isAndroid()) {\n    // Android app.\n    additionalParams['apn'] = appIdentifier;\n  } else {\n    // This should not happen as Cordova handler should not even be used in this\n    // case.\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  // Pass app display name.\n  if (appDisplayName) {\n    additionalParams['appDisplayName'] = appDisplayName;\n  }\n  // Hash the session ID and pass it to additional params.\n  var hashedSessionId = this.computeSecureHash_(sessionId);\n  // Append session ID.\n  additionalParams['sessionId'] = hashedSessionId;\n  // Construct OAuth handler URL.\n  var oauthHelperWidgetUrl =\n      fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n          this.authDomain_,\n          this.apiKey_,\n          this.appName_,\n          mode,\n          provider,\n          null,\n          opt_eventId,\n          this.clientVersion_,\n          additionalParams,\n          this.endpointId_,\n          opt_tenantId);\n  // Make sure handler initialized and ready.\n  // This should also ensure all plugins are installed.\n  return this.initializeAndWait().then(function() {\n    // Save partial Auth event.\n    return self.savePartialEventManager_.setAuthEvent(self.storageKey_, event);\n  }).then(function() {\n    // initializeAndWait will ensure this plugin is installed.\n    var isAvailable = /** @type {!function(!function(*))} */ (\n        fireauth.util.getObjectRef(\n            'cordova.plugins.browsertab.isAvailable', goog.global));\n    if (typeof isAvailable !== 'function') {\n      throw new fireauth.AuthError(\n          fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n    }\n    var openUrl = null;\n    // Check if browsertab is supported.\n    isAvailable(function(result) {\n      if (result) {\n        // browsertab supported.\n        openUrl = /** @type {!function(string, ...*)} */ (\n            fireauth.util.getObjectRef(\n                'cordova.plugins.browsertab.openUrl', goog.global));\n        if (typeof openUrl !== 'function') {\n          throw new fireauth.AuthError(\n              fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n        }\n        // Open OAuth handler.\n        openUrl(oauthHelperWidgetUrl);\n      } else {\n        // browsertab not supported, switch to inappbrowser.\n        openUrl = /** @type {!function(string, string, string=)} */ (\n            fireauth.util.getObjectRef(\n                'cordova.InAppBrowser.open', goog.global));\n        if (typeof openUrl !== 'function') {\n          throw new fireauth.AuthError(\n              fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n        }\n        // Open in embedded webview for iOS 7 and 8 as Apple rejects apps that\n        // switch context.\n        // _blank opens an embedded webview.\n        // _system opens the system browser.\n        // _system (opens a system browser) is used as a fallback when\n        // browsertab plugin is unable to open a chromecustomtab or SFSVC.\n        // This has to exclude all iOS older versions where switching to a\n        // browser is frowned upon by Apple and embedding a UIWebView is the\n        // only option but is insecure and deprecated by Google for OAuth\n        // sign-in. This will be applicable in old versions of Android.\n        self.inAppBrowserRef_ = openUrl(\n            oauthHelperWidgetUrl,\n            fireauth.util.isIOS7Or8() ? '_blank' : '_system',\n            'location=yes');\n      }\n    });\n  });\n};\n\n\n/**\n * Dispatches the detected Auth event to all subscribed listeners.\n * @param {!fireauth.AuthEvent} event A detected Auth event.\n * @private\n */\nfireauth.CordovaHandler.prototype.dispatchEvent_ = function(event) {\n  for (var i = 0; i < this.authEventListeners_.length; i++) {\n    try {\n      this.authEventListeners_[i](event);\n    } catch (e) {\n      // If any handler fails, ignore and run next handler.\n    }\n  }\n};\n\n\n/**\n * Resolves the first redirect Auth event and caches it.\n * @return {!goog.Promise<!fireauth.AuthEvent>} A promise that resolves with the\n *     initial Auth event response from a redirect operation. Initializes the\n *     internal Auth event listener which will dispatch Auth events to all\n *     subscribed listeners.\n * @private\n */\nfireauth.CordovaHandler.prototype.getInitialAuthEvent_ = function() {\n  var self = this;\n  if (!this.initialAuthEvent_) {\n    // Cache this result so on next call, it is not triggered again.\n    this.initialAuthEvent_ = this.initializeAndWait().then(function() {\n      return new goog.Promise(function(resolve, reject) {\n        /**\n         * @param {?fireauth.AuthEvent} event The Auth event detected.\n         * @return {boolean}\n         */\n        var authEventCallback = function(event) {\n          resolve(event);\n          // Remove on completion.\n          self.removeAuthEventListener(authEventCallback);\n          return false;\n        };\n        // Listen to Auth events. If resolved, resolve promise.\n        self.addAuthEventListener(authEventCallback);\n        // This should succeed as initializeAndWait should guarantee plugins are\n        // ready.\n        self.setAuthEventListener_();\n      });\n    });\n  }\n  return this.initialAuthEvent_;\n};\n\n\n/**\n * Gets and deletes the current stored partial event from storage.\n * @return {!goog.Promise<?fireauth.AuthEvent>} A promise that resolves with the\n *     stored Auth event.\n * @private\n */\nfireauth.CordovaHandler.prototype.getPartialStoredEvent_ = function() {\n  var event = null;\n  var self = this;\n  // Get any saved partial Auth event.\n  return this.getAndDeletePartialEventManager_.getAuthEvent()\n    .then(function(authEvent) {\n      // Save partial event locally.\n      event = authEvent;\n      // Delete partial event.\n      return self.getAndDeletePartialEventManager_.removeAuthEvent();\n    }).then(function() {\n      // Return the locally saved partial event.\n      return event;\n    });\n};\n\n\n/**\n * Extracts the Auth event pertaining to the incoming URL.\n * @param {!fireauth.AuthEvent} partialEvent The partial Auth event.\n * @param {string} url The incoming universal link.\n * @return {?fireauth.AuthEvent} The resolved Auth event corresponding to the\n *     callback URL. This is null if no event is found.\n * @private\n */\nfireauth.CordovaHandler.prototype.extractAuthEventFromUrl_ =\n    function(partialEvent, url) {\n  // Default no redirect event result.\n  var authEvent = null;\n  // Parse the deep link within the dynamic link URL.\n  var callbackUrl = fireauth.DynamicLink.parseDeepLink(url);\n  // Confirm it is actually a callback URL.\n  // Currently the universal link will be of this format:\n  // https://<AUTH_DOMAIN>/__/auth/callback<OAUTH_RESPONSE>\n  // This is a fake URL but is not intended to take the user anywhere\n  // and just redirect to the app.\n  if (callbackUrl.indexOf('/__/auth/callback') != -1) {\n    // Check if there is an error in the URL.\n    // This mechanism is also used to pass errors back to the app:\n    // https://<AUTH_DOMAIN>/__/auth/callback?firebaseError=<STRINGIFIED_ERROR>\n    var uri = goog.Uri.parse(callbackUrl);\n    // Get the error object corresponding to the stringified error if found.\n    var errorObject = fireauth.util.parseJSON(\n        uri.getParameterValue('firebaseError') || null);\n    var error = typeof errorObject === 'object' ?\n        fireauth.AuthError.fromPlainObject(\n            /** @type {?Object} */ (errorObject)) :\n        null;\n    if (error) {\n      // Construct the full failed Auth event.\n      authEvent = new fireauth.AuthEvent(\n          partialEvent.getType(),\n          partialEvent.getEventId(),\n          null,\n          null,\n          error,\n          null,\n          partialEvent.getTenantId());\n    } else {\n      // Construct the full successful Auth event.\n      authEvent = new fireauth.AuthEvent(\n          partialEvent.getType(),\n          partialEvent.getEventId(),\n          callbackUrl,\n          partialEvent.getSessionId(),\n          null,\n          null,\n          partialEvent.getTenantId());\n    }\n  }\n  return authEvent;\n};\n\n\n/**\n * Sets the internal Auth event listener. This listens to incoming universal\n * links and on detection, repackages them into an Auth event and then\n * dispatches the events in all event listeners.\n * @private\n */\nfireauth.CordovaHandler.prototype.setAuthEventListener_ = function() {\n  // https://github.com/nordnet/cordova-universal-links-plugin-fix\n  var self = this;\n  // Default no redirect event result.\n  var noEvent = new fireauth.AuthEvent(\n      fireauth.AuthEvent.Type.UNKNOWN,\n      null,\n      null,\n      null,\n      new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT));\n  var initialResolve = false;\n  // On initialization, if no incoming universal link detected, trigger\n  // no Auth event (no redirect operation previously called) after waiting\n  // for a short period of time.\n  var noEventTimer = goog.Timer.promise(this.initialTimeout_).then(function() {\n    // Delete any pending unhandled event.\n    return self.getPartialStoredEvent_().then(function(event) {\n      // On timeout trigger noEvent if not already resolved in link\n      // subscriber.\n      if (!initialResolve) {\n        self.dispatchEvent_(noEvent);\n      }\n    });\n  });\n  // No event name needed, subscribe to all incoming universal links.\n  var universalLinkCb = function(eventData) {\n    initialResolve = true;\n    // Cancel no event timer.\n    if (noEventTimer) {\n      noEventTimer.cancel();\n    }\n    // Incoming link detected.\n    // Check for any stored partial event.\n    self.getPartialStoredEvent_().then(function(event) {\n      // Initialize to an unknown event.\n      var authEvent = noEvent;\n      // Confirm OAuth response included.\n      if (event && eventData && eventData['url']) {\n        // Construct complete event. Default to unknown event if none found.\n        authEvent = self.extractAuthEventFromUrl_(event, eventData['url']) ||\n            noEvent;\n      }\n      // Dispatch Auth event.\n      self.dispatchEvent_(authEvent);\n    });\n  };\n  // iOS 7 or 8 custom URL schemes.\n  // This is also the current default behavior for iOS 9+.\n  // For this to work, cordova-plugin-customurlscheme needs to be installed.\n  // https://github.com/EddyVerbruggen/Custom-URL-scheme\n  // Do not overwrite the existing developer's URL handler.\n  var existingHandlerOpenURL = goog.global['handleOpenURL'];\n  goog.global['handleOpenURL'] = function(url) {\n    var appIdentifier =\n        fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n    // Apply case insensitive match. While bundle IDs are case sensitive,\n    // when creating a new app, Apple verifies the Bundle ID using\n    // case-insensitive search. So it is not possible that an app in the app\n    // store try to impersonate another one by lower/upper casing characters.\n    if (url.toLowerCase().indexOf(appIdentifier.toLowerCase() + '://') == 0) {\n      universalLinkCb({\n        'url': url\n      });\n    }\n    // Call the developer's handler if it is present.\n    if (typeof existingHandlerOpenURL === 'function') {\n      try {\n        existingHandlerOpenURL(url);\n      } catch(e) {\n        // This doesn't swallow the error but also does not interrupt the flow.\n        console.error(e);\n      }\n    }\n  };\n  fireauth.UniversalLinkSubscriber.getInstance().subscribe(universalLinkCb);\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n *     listener to add.\n * @override\n */\nfireauth.CordovaHandler.prototype.addAuthEventListener = function(listener) {\n  // TODO: consider creating an abstract base class that OAuth handlers\n  // extend with add, remove Auth event listeners and dispatcher methods.\n  this.authEventListeners_.push(listener);\n  // Set internal listener to Auth events. This will be ignored on subsequent\n  // calls.\n  this.getInitialAuthEvent_().thenCatch(function(error) {\n    // Suppress this error as it should be caught through other actionable\n    // public methods.\n    // This would typically happen on invalid Cordova setup, when the OAuth\n    // plugins are not installed. This should still trigger the Auth event\n    // as developers are not forced to use OAuth sign-in in their Cordova app.\n    // This is needed for onAuthStateChanged listener to trigger initially.\n    if (error.code === 'auth/invalid-cordova-configuration') {\n      var noEvent = new fireauth.AuthEvent(\n          fireauth.AuthEvent.Type.UNKNOWN,\n          null,\n          null,\n          null,\n          new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT));\n      listener(noEvent);\n    }\n  });\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n *     listener to remove.\n * @override\n */\nfireauth.CordovaHandler.prototype.removeAuthEventListener = function(listener) {\n  goog.array.removeAllIf(this.authEventListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the Auth event manager instance.\n */\n\ngoog.provide('fireauth.AuthEventHandler');\ngoog.provide('fireauth.AuthEventManager');\ngoog.provide('fireauth.AuthEventManager.Result');\ngoog.provide('fireauth.PopupAuthEventProcessor');\ngoog.provide('fireauth.RedirectAuthEventProcessor');\n\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.CordovaHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.storage.PendingRedirectManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.array');\n\n\n/**\n * Initializes the Auth event manager which provides the mechanism to connect\n * external Auth events to their corresponding listeners.\n * @param {string} authDomain The Firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n *     request.\n * @constructor\n */\nfireauth.AuthEventManager = function(authDomain, apiKey, appName) {\n  /**\n   * @private {!Object<string, boolean>} The map of processed auth event IDs.\n   */\n  this.processedEvents_ = {};\n  /** @private {number} The last saved processed event time in milliseconds. */\n  this.lastProcessedEventTime_ = 0;\n  /** @private {string} The Auth domain. */\n  this.authDomain_ = authDomain;\n  /** @private {string} The browser API key. */\n  this.apiKey_ = apiKey;\n  /** @private {string} The App name. */\n  this.appName_ = appName;\n  /**\n   * @private {!Array<!fireauth.AuthEventHandler>} List of subscribed handlers.\n   */\n  this.subscribedHandlers_ = [];\n  /**\n   * @private {boolean} Whether the Auth event manager instance is initialized.\n   */\n  this.initialized_ = false;\n  /** @private {function(?fireauth.AuthEvent)} The Auth event handler. */\n  this.authEventHandler_ = goog.bind(this.handleAuthEvent_, this);\n  /** @private {!fireauth.RedirectAuthEventProcessor} The redirect event\n   *      processor. */\n  this.redirectAuthEventProcessor_ =\n      new fireauth.RedirectAuthEventProcessor(this);\n  /** @private {!fireauth.PopupAuthEventProcessor} The popup event processor. */\n  this.popupAuthEventProcessor_ = new fireauth.PopupAuthEventProcessor(this);\n  /**\n   * @private {!fireauth.storage.PendingRedirectManager} The pending redirect\n   *     storage manager instance.\n   */\n  this.pendingRedirectStorageManager_ =\n      new fireauth.storage.PendingRedirectManager(\n          fireauth.AuthEventManager.getKey_(this.apiKey_, this.appName_));\n\n  /**\n   * @private {!Object.<!fireauth.AuthEvent.Type, !fireauth.AuthEventProcessor>}\n   *     Map containing Firebase event processor instances keyed by event type.\n   */\n  this.typeToManager_ = {};\n  this.typeToManager_[fireauth.AuthEvent.Type.UNKNOWN] =\n      this.redirectAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT] =\n      this.redirectAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.LINK_VIA_REDIRECT] =\n      this.redirectAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT] =\n      this.redirectAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP] =\n      this.popupAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.LINK_VIA_POPUP] =\n      this.popupAuthEventProcessor_;\n  this.typeToManager_[fireauth.AuthEvent.Type.REAUTH_VIA_POPUP] =\n      this.popupAuthEventProcessor_;\n  /**\n   * @private {!fireauth.OAuthSignInHandler} The OAuth sign in handler depending\n   *     on the current environment.\n   */\n  this.oauthSignInHandler_ =\n      fireauth.AuthEventManager.instantiateOAuthSignInHandler(\n          this.authDomain_, this.apiKey_, this.appName_,\n          firebase.SDK_VERSION || null,\n          fireauth.constants.clientEndpoint);\n};\n\n\n/**\n * @const {number} The number of milliseconds since the last processed\n *     event before the event duplication cache is cleared. This is currently\n *     10 minutes.\n */\nfireauth.AuthEventManager.EVENT_DUPLICATION_CACHE_DURATION = 10 * 60 * 1000;\n\n\n/**\n * @return {!fireauth.RedirectAuthEventProcessor} The redirect event processor.\n */\nfireauth.AuthEventManager.prototype.getRedirectAuthEventProcessor = function() {\n  return this.redirectAuthEventProcessor_;\n};\n\n\n/** @return {!fireauth.PopupAuthEventProcessor} The popup event processor. */\nfireauth.AuthEventManager.prototype.getPopupAuthEventProcessor = function() {\n  return this.popupAuthEventProcessor_;\n};\n\n\n/**\n * Instantiates an OAuth sign-in handler depending on the current environment\n * and returns it.\n * @param {string} authDomain The Firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n *     request.\n * @param {?string} version The SDK client version.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.OAuthSignInHandler} The OAuth sign in handler depending\n *     on the current environment.\n */\nfireauth.AuthEventManager.instantiateOAuthSignInHandler =\n    function(authDomain, apiKey, appName, version, opt_endpointId) {\n  // This assumes that android/iOS file environment must be a Cordova\n  // environment which is not true. This is the best way currently available\n  // to instantiate this synchronously without waiting for checkIfCordova to\n  // resolve. If it is determined that the Cordova was falsely detected, it will\n  // be caught via actionable public popup and redirect methods.\n  return fireauth.util.isAndroidOrIosCordovaScheme() ?\n      new fireauth.CordovaHandler(\n          authDomain, apiKey, appName, version, undefined, undefined,\n          opt_endpointId) :\n      new fireauth.iframeclient.IfcHandler(\n          authDomain, apiKey, appName, version, opt_endpointId);\n};\n\n\n/** Reset iframe. This will require reinitializing it.*/\nfireauth.AuthEventManager.prototype.reset = function() {\n  // Reset initialized status. This will force a popup request to re-initialize\n  // the iframe.\n  this.initialized_ = false;\n  // Remove any previous existing Auth event listener.\n  this.oauthSignInHandler_.removeAuthEventListener(this.authEventHandler_);\n  // Construct a new instance of OAuth sign in handler.\n\n  this.oauthSignInHandler_ =\n      fireauth.AuthEventManager.instantiateOAuthSignInHandler(\n          this.authDomain_, this.apiKey_, this.appName_,\n          firebase.SDK_VERSION || null);\n  this.processedEvents_ = {};\n};\n\n\n/**\n * Clears the cached redirect result as long as there is no pending redirect\n * result being processed. Unrecoverable errors will not be cleared.\n */\nfireauth.AuthEventManager.prototype.clearRedirectResult = function() {\n  this.redirectAuthEventProcessor_.clearRedirectResult();\n};\n\n\n/**\n * @typedef {{\n *   user: (?fireauth.AuthUser|undefined),\n *   credential: (?fireauth.AuthCredential|undefined),\n *   operationType: (?string|undefined),\n *   additionalUserInfo: (?fireauth.AdditionalUserInfo|undefined)\n * }}\n */\nfireauth.AuthEventManager.Result;\n\n\n/**\n * Whether to enable Auth event manager subscription.\n * @const {boolean}\n */\nfireauth.AuthEventManager.ENABLED = true;\n\n\n/**\n * Initializes the ifchandler and add Auth event listener on it.\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n */\nfireauth.AuthEventManager.prototype.initialize = function() {\n  var self = this;\n  // Initialize once.\n  if (!this.initialized_) {\n    this.initialized_ = true;\n    // Listen to Auth events on iframe.\n    this.oauthSignInHandler_.addAuthEventListener(this.authEventHandler_);\n  }\n  var previousOauthSignInHandler = this.oauthSignInHandler_;\n  // This should initialize ifchandler underneath.\n  // Return on OAuth handler ready promise.\n  // Check for error in ifcHandler used to embed the iframe.\n  return this.oauthSignInHandler_.initializeAndWait()\n      .thenCatch(function(error) {\n        // Force ifchandler to reinitialize on retrial.\n        if (self.oauthSignInHandler_ == previousOauthSignInHandler) {\n          // If a new OAuth sign in handler was already created, do not reset.\n          self.reset();\n        }\n        throw error;\n      });\n};\n\n\n/**\n * Called after it is determined that there is no pending redirect result.\n * Will populate the redirect result if it is guaranteed to be null and will\n * force an early initialization of the OAuth sign in handler if the\n * environment requires it.\n * @private\n */\nfireauth.AuthEventManager.prototype.initializeWithNoPendingRedirectResult_ =\n    function() {\n  var self = this;\n  // Check if the OAuth sign in handler should be initialized early in all\n  // cases.\n  if (this.oauthSignInHandler_.shouldBeInitializedEarly()) {\n    this.initialize().thenCatch(function(error) {\n      // Current environment was falsely detected as Cordova, trigger a fake\n      // Auth event to notify getRedirectResult that operation is not supported.\n      var notSupportedEvent = new fireauth.AuthEvent(\n          fireauth.AuthEvent.Type.UNKNOWN,\n          null,\n          null,\n          null,\n          new fireauth.AuthError(\n              fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n      if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n          /** @type {?fireauth.AuthError} */ (error))) {\n        self.handleAuthEvent_(notSupportedEvent);\n      }\n    });\n  }\n  // For environments where storage is volatile, we can't determine that\n  // there is no pending redirect response. This is true in Cordova\n  // where an activity would be destroyed in some cases and the\n  // sessionStorage is lost.\n  if (!this.oauthSignInHandler_.hasVolatileStorage()) {\n    // Since there is no redirect result, it is safe to default to empty\n    // redirect result instead of blocking on this.\n    // The downside here is that on iOS devices, calling signInWithPopup\n    // after getRedirectResult resolves and the iframe does not finish\n    // loading, the popup event propagating to the iframe would not be\n    // detected. This is because in iOS devices, storage events only trigger\n    // in iframes but are not actually saved in web storage. The iframe must\n    // be embedded and ready before the storage event propagates. Otherwise\n    // it won't be detected.\n    this.redirectAuthEventProcessor_.defaultToEmptyResponse();\n  }\n};\n\n\n/**\n * Subscribes an Auth event handler to list of handlers.\n * @param {!fireauth.AuthEventHandler} handler The instance to subscribe.\n */\nfireauth.AuthEventManager.prototype.subscribe = function(handler) {\n  if (!goog.array.contains(this.subscribedHandlers_, handler)) {\n    this.subscribedHandlers_.push(handler);\n  }\n  if (this.initialized_) {\n    return;\n  }\n  var self = this;\n  // Check pending redirect status.\n  this.pendingRedirectStorageManager_.getPendingStatus()\n      .then(function(status) {\n    // Pending redirect detected.\n    if (status) {\n      // Remove pending status and initialize.\n      self.pendingRedirectStorageManager_.removePendingStatus()\n          .then(function() {\n            self.initialize().thenCatch(function(error) {\n              // Current environment was falsely detected as Cordova, trigger a\n              // fake Auth event to notify getRedirectResult that operation is\n              // not supported.\n              var notSupportedEvent = new fireauth.AuthEvent(\n                 fireauth.AuthEvent.Type.UNKNOWN,\n                 null,\n                 null,\n                 null,\n                 new fireauth.AuthError(\n                     fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n              if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n                  /** @type {?fireauth.AuthError} */ (error))) {\n                self.handleAuthEvent_(notSupportedEvent);\n              }\n            });\n          });\n    } else {\n      // No previous redirect, default to empty response.\n      self.initializeWithNoPendingRedirectResult_();\n    }\n  }).thenCatch(function(error) {\n    // Error checking pending status, default to empty response.\n    self.initializeWithNoPendingRedirectResult_();\n  });\n};\n\n\n/**\n * @param {!fireauth.AuthEventHandler} handler The possible subscriber.\n * @return {boolean} Whether the handle is subscribed.\n */\nfireauth.AuthEventManager.prototype.isSubscribed = function(handler) {\n  return goog.array.contains(this.subscribedHandlers_, handler);\n};\n\n\n/**\n * Unsubscribes an Auth event handler to list of handlers.\n * @param {!fireauth.AuthEventHandler} handler The instance to unsubscribe.\n */\nfireauth.AuthEventManager.prototype.unsubscribe = function(handler) {\n  goog.array.removeAllIf(this.subscribedHandlers_, function(ele) {\n    return ele == handler;\n  });\n};\n\n\n/**\n * @param {?fireauth.AuthEvent} authEvent External Auth event to check.\n * @return {boolean} Whether the event was previously processed.\n * @private\n */\nfireauth.AuthEventManager.prototype.hasProcessedAuthEvent_ =\n    function(authEvent) {\n  // Prevent duplicate event tracker from growing too large.\n  if (goog.now() - this.lastProcessedEventTime_ >=\n      fireauth.AuthEventManager.EVENT_DUPLICATION_CACHE_DURATION) {\n    this.processedEvents_ = {};\n    this.lastProcessedEventTime_ = 0;\n  }\n  if (authEvent && authEvent.getUid() &&\n      this.processedEvents_.hasOwnProperty(authEvent.getUid())) {\n    // If event is already processed, ignore it.\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Saves the provided event uid to prevent processing duplication.\n * @param {?fireauth.AuthEvent} authEvent External Auth event to track in\n *     processed list of events.\n * @private\n */\nfireauth.AuthEventManager.prototype.saveProcessedAuthEvent_ =\n    function(authEvent) {\n  if (authEvent &&\n      (authEvent.getSessionId() || authEvent.getEventId())) {\n    // Save processed event ID. We keep the cache for 10 minutes to prevent it\n    // from growing too large.\n    this.processedEvents_[\n        /** @type {string} */ (authEvent.getUid())] = true;\n    // Save last processing time.\n    this.lastProcessedEventTime_ = goog.now();\n  }\n};\n\n\n/**\n * Handles external Auth event detected by the OAuth sign-in handler.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @return {boolean} Whether the event found an appropriate owner that can\n *     handle it. This signals to the OAuth helper iframe that the event is safe\n *     to delete.\n * @private\n */\nfireauth.AuthEventManager.prototype.handleAuthEvent_ = function(authEvent) {\n  // This should not happen as fireauth.iframe.AuthRelay will not send null\n  // events.\n  if (!authEvent) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n  }\n  if (this.hasProcessedAuthEvent_(authEvent)) {\n    // If event is already processed, ignore it.\n    return false;\n  }\n  // Initialize event processed status to false. When set to false, the event is\n  // not clear to delete in the OAuth helper iframe as the owner of this event\n  // could be a user in another tab.\n  var processed = false;\n  // Lookup a potential handler for this event.\n  for (var i = 0; i < this.subscribedHandlers_.length; i++) {\n    var potentialHandler = this.subscribedHandlers_[i];\n    if (potentialHandler.canHandleAuthEvent(\n        authEvent.getType(), authEvent.getEventId())) {\n      var eventManager = this.typeToManager_[authEvent.getType()];\n      if (eventManager) {\n        eventManager.processAuthEvent(authEvent, potentialHandler);\n        // Prevent events with event IDs or session IDs from duplicate\n        // processing.\n        this.saveProcessedAuthEvent_(authEvent);\n      }\n      // Event has been processed, free to clear in OAuth helper.\n      processed = true;\n      break;\n    }\n  }\n  // If no redirect response ready yet, default to an empty response.\n  this.redirectAuthEventProcessor_.defaultToEmptyResponse();\n  // Notify iframe of processed status.\n  return processed;\n};\n\n\n/**\n * The popup promise timeout delay with units in ms between the time the iframe\n * is ready (successfully embedded on the page) and the time the popup Auth\n * event is detected in the parent container.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.AuthEventManager.POPUP_TIMEOUT_MS_ =\n    new fireauth.util.Delay(2000, 10000);\n\n\n/**\n * The redirect promise timeout delay with units in ms. Unlike the popup\n * timeout, this covers the entire duration from start to getRedirectResult\n * resolution.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_ =\n    new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthEventManager.prototype.getRedirectResult = function() {\n  return this.redirectAuthEventProcessor_.getRedirectResult();\n};\n\n\n/**\n * Processes the popup request. The popup instance must be provided externally\n * and on error, the requestor must close the window.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n *     to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n */\nfireauth.AuthEventManager.prototype.processPopup =\n    function(popupWin, mode, provider, opt_eventId, opt_alreadyRedirected,\n             opt_tenantId) {\n  var self = this;\n  return this.oauthSignInHandler_.processPopup(\n      popupWin,\n      mode,\n      provider,\n      // On initialization, add Auth event listener if not already added.\n      function() {\n        if (!self.initialized_) {\n          self.initialized_ = true;\n          // Listen to Auth events on iframe.\n          self.oauthSignInHandler_.addAuthEventListener(self.authEventHandler_);\n        }\n      },\n      // On error, reset to force re-initialization on retrial.\n      function(error) {\n        self.reset();\n      },\n      opt_eventId,\n      opt_alreadyRedirected,\n      opt_tenantId);\n};\n\n\n/**\n * @param {?fireauth.AuthError} error The error to check for Cordova false\n *     positive.\n * @return {boolean} Whether the current environment was falsely identified as\n *     Cordova.\n * @private\n */\nfireauth.AuthEventManager.isCordovaFalsePositive_ = function(error) {\n  if (error && error['code'] == 'auth/cordova-not-ready') {\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Processes the redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n */\nfireauth.AuthEventManager.prototype.processRedirect =\n    function(mode, provider, opt_eventId, opt_tenantId) {\n  var self = this;\n  var error;\n  // Save pending status first.\n  return this.pendingRedirectStorageManager_.setPendingStatus()\n    .then(function() {\n      // Try to redirect.\n      return self.oauthSignInHandler_.processRedirect(\n          mode, provider, opt_eventId, opt_tenantId)\n        .thenCatch(function(e) {\n          if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n              /** @type {?fireauth.AuthError} */ (e))) {\n            throw new fireauth.AuthError(\n                fireauth.authenum.Error.OPERATION_NOT_SUPPORTED);\n          }\n          // On failure, remove pending status and rethrow the error.\n          error = e;\n          return self.pendingRedirectStorageManager_.removePendingStatus()\n            .then(function() {\n              throw error;\n            });\n        })\n        .then(function() {\n          // Resolve, if the OAuth handler unloads the page on redirect.\n          if (!self.oauthSignInHandler_.unloadsOnRedirect()) {\n            // Relevant to Cordova case, will not matter in web case where\n            // browser redirects.\n            // In Cordova, the activity could still be running in the background\n            // so we need to wait for getRedirectResult to resolve before\n            // resolving this current promise.\n            // Otherwise, if the activity is destroyed, getRedirectResult would\n            // be used.\n            // At this point, authEvent should have been triggered.\n            // When this promise resolves, the developer should be able to\n            // call getRedirectResult to get the result of this operation.\n            // Remove pending status as result should be resolved.\n            return self.pendingRedirectStorageManager_.removePendingStatus()\n                .then(function() {\n                  // Ensure redirect result ready before resolving.\n                  return self.getRedirectResult();\n                }).then(function(result) {\n                  // Do nothing. Developer expected to call getRedirectResult to\n                  // get result.\n                }).thenCatch(function(error) {\n                  // Do nothing. Developer expected to call getRedirectResult to\n                  // get result.\n                });\n          } else {\n            // For environments that will unload the page on redirect, keep\n            // the promise pending on success. This makes it easier to reuse\n            // the same code for Cordova environment and browser environment.\n            // The developer can always add getRedirectResult on promise\n            // resolution and expect that when it runs, the redirect operation\n            // was completed.\n            return new goog.Promise(function(resolve, reject) {\n              // Keep this pending.\n            });\n          }\n        });\n    });\n};\n\n\n/**\n * Waits for popup window to close. When closed start timeout listener for popup\n * pending promise. If in the process, it was detected that the iframe does not\n * support web storage, the popup is closed and the web storage unsupported\n * error is thrown.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!Window} popupWin The popup window.\n * @param {?string=} opt_eventId The event ID.\n * @return {!goog.Promise}\n */\nfireauth.AuthEventManager.prototype.startPopupTimeout =\n    function(owner, mode, popupWin, opt_eventId) {\n  return this.oauthSignInHandler_.startPopupTimeout(\n      popupWin,\n      // On popup error such as popup closed by user or web storage not\n      // supported.\n      function(error) {\n        // Notify owner of the error.\n        owner.resolvePendingPopupEvent(mode, null, error, opt_eventId);\n      },\n      fireauth.AuthEventManager.POPUP_TIMEOUT_MS_.get());\n};\n\n\n\n/**\n * @private {!Object.<string, !fireauth.AuthEventManager>} Map containing\n *     Firebase event manager instances keyed by Auth event manager ID.\n */\nfireauth.AuthEventManager.manager_ = {};\n\n\n/**\n * The separator for manager keys to concatenate app name and apiKey.\n * @const {string}\n * @private\n */\nfireauth.AuthEventManager.KEY_SEPARATOR_ = ':';\n\n\n/**\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The Auth instance that initiated the Auth event.\n * @return {string} The key identifying the Auth event manager instance.\n * @private\n */\nfireauth.AuthEventManager.getKey_ = function(apiKey, appName) {\n  return apiKey + fireauth.AuthEventManager.KEY_SEPARATOR_ + appName;\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n *     OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The Auth instance that initiated the Auth event\n *     manager.\n * @return {!fireauth.AuthEventManager} the requested manager instance.\n */\nfireauth.AuthEventManager.getManager = function(authDomain, apiKey, appName) {\n  // Construct storage key.\n  var key = fireauth.AuthEventManager.getKey_(apiKey, appName);\n  if (!fireauth.AuthEventManager.manager_[key]) {\n    fireauth.AuthEventManager.manager_[key] =\n        new fireauth.AuthEventManager(authDomain, apiKey, appName);\n  }\n  return fireauth.AuthEventManager.manager_[key];\n};\n\n\n\n/**\n * The interface that represents a specific type of Auth event processor.\n * @interface\n */\nfireauth.AuthEventProcessor = function() {};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.AuthEventProcessor.prototype.processAuthEvent =\n    function(authEvent, owner) {};\n\n\n\n/**\n * Redirect Auth event manager.\n * @param {!fireauth.AuthEventManager} manager The parent Auth event manager.\n * @constructor\n * @implements {fireauth.AuthEventProcessor}\n */\nfireauth.RedirectAuthEventProcessor = function(manager) {\n  this.manager_ = manager;\n  // Only one redirect result can be tracked on first load.\n  /**\n   * @private {?function():!goog.Promise<!fireauth.AuthEventManager.Result>}\n   *     Redirect result resolver. This will be used to resolve the\n   *     getRedirectResult promise. When the redirect result is obtained, this\n   *     field will be set.\n   */\n  this.redirectedUserPromise_ = null;\n  /**\n   * @private {!Array<function(!fireauth.AuthEventManager.Result)>} Pending\n   *     promise redirect resolver. When the redirect result is obtained and the\n   *     user is detected, this will be called.\n   */\n  this.redirectResolve_ = [];\n  /**\n   * @private {!Array<function(*)>} Pending Promise redirect rejecter. When the\n   *     redirect result is obtained and an error is detected, this will be\n   *     called.\n   */\n  this.redirectReject_ = [];\n  /** @private {?goog.Promise} Pending timeout promise for redirect. */\n  this.redirectTimeoutPromise_ = null;\n  /**\n   * @private {boolean} Whether redirect result is resolved. This is true\n   *     when a valid Auth event has been triggered.\n   */\n  this.redirectResultResolved_ = false;\n  /**\n   * @private {boolean} Whether an unrecoverable error was detected. This\n   *     includes web storage unsupported or operation not allowed errors.\n   */\n  this.unrecoverableErrorDetected_ = false;\n};\n\n\n/** Reset any previous redirect result. */\nfireauth.RedirectAuthEventProcessor.prototype.reset = function() {\n  // Reset to allow override getRedirectResult. This is relevant for Cordova\n  // environment where redirect events do not necessarily unload the current\n  // page.\n  this.redirectedUserPromise_ = null;\n  if (this.redirectTimeoutPromise_) {\n    this.redirectTimeoutPromise_.cancel();\n    this.redirectTimeoutPromise_ = null;\n  }\n};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @override\n */\nfireauth.RedirectAuthEventProcessor.prototype.processAuthEvent =\n    function(authEvent, owner) {\n  // This should not happen as fireauth.iframe.AuthRelay will not send null\n  // events.\n  if (!authEvent) {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n  }\n  // Reset any pending redirect result. This event will overwrite it.\n  this.reset();\n  this.redirectResultResolved_ = true;\n  var mode = authEvent.getType();\n  var eventId = authEvent.getEventId();\n  // Check if web storage is not supported in the iframe.\n  var isWebStorageNotSupported =\n      authEvent.getError() &&\n      authEvent.getError()['code'] == 'auth/web-storage-unsupported';\n  /// Check if operation is supported in this environment.\n  var isOperationNotSupported =\n      authEvent.getError() &&\n      authEvent.getError()['code'] == 'auth/operation-not-supported-in-this-' +\n          'environment';\n  this.unrecoverableErrorDetected_ =\n      !!(isWebStorageNotSupported || isOperationNotSupported);\n  // UNKNOWN mode is always triggered on load by iframe when no popup/redirect\n  // data is available. If web storage unsupported error is thrown, process as\n  // error and not as unknown event. If the operation is not supported in this\n  // environment, also treat as an error and not as an unknown event.\n  if (mode == fireauth.AuthEvent.Type.UNKNOWN &&\n      !isWebStorageNotSupported &&\n      !isOperationNotSupported) {\n    return this.processUnknownEvent_();\n  } else if (authEvent.hasError()) {\n    return this.processErrorEvent_(authEvent, owner);\n  } else if (owner.getAuthEventHandlerFinisher(mode, eventId)) {\n    return this.processSuccessEvent_(authEvent, owner);\n  } else {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n  }\n};\n\n\n/**\n * Sets an empty redirect result response when no redirect result is available.\n */\nfireauth.RedirectAuthEventProcessor.prototype.defaultToEmptyResponse =\n    function() {\n  // If the first event does not resolve redirectResult and no subscriber can\n  // handle it, set redirect result to null.\n  // An example of this scenario would be a link via redirect that was triggered\n  // by a user that was not logged in. canHandleAuthEvent will be false for all\n  // subscribers. So make sure getRedirectResult when called will resolve to a\n  // null user.\n  if (!this.redirectResultResolved_) {\n    this.redirectResultResolved_ = true;\n    // No Auth event available, getRedirectResult should resolve with null.\n    this.setRedirectResult_(false, null, null);\n  }\n};\n\n\n/**\n * Clears the cached redirect result as long as there is no pending redirect\n * result being processed. Unrecoverable errors will not be cleared.\n */\nfireauth.RedirectAuthEventProcessor.prototype.clearRedirectResult = function() {\n  // Clear the result if it is already resolved and no unrecoverable errors are\n  // detected.\n  if (this.redirectResultResolved_ && !this.unrecoverableErrorDetected_) {\n    this.setRedirectResult_(false, null, null);\n  }\n};\n\n\n/**\n * Processes the unknown event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processUnknownEvent_ =\n    function() {\n  // No Auth event available, getRedirectResult should resolve with null.\n  this.setRedirectResult_(false, null, null);\n  return goog.Promise.resolve();\n};\n\n\n/**\n * Processes an error event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processErrorEvent_ =\n    function(authEvent, owner) {\n  // Set redirect result to resolve with null if event is not a redirect or\n  // reject with error if event is an error.\n  this.setRedirectResult_(true, null, authEvent.getError());\n  return goog.Promise.resolve();\n};\n\n\n/**\n * Processes a successful event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processSuccessEvent_ =\n    function(authEvent, owner) {\n  var self = this;\n  var eventId = authEvent.getEventId();\n  var mode = authEvent.getType();\n  var handler = owner.getAuthEventHandlerFinisher(mode, eventId);\n  var requestUri = /** @type {string} */ (authEvent.getUrlResponse());\n  var sessionId = /** @type {string} */ (authEvent.getSessionId());\n  var postBody = /** @type {?string} */ (authEvent.getPostBody());\n  var tenantId = /** @type {?string} */ (authEvent.getTenantId());\n  var isRedirect = fireauth.AuthEvent.isRedirect(authEvent);\n  // Complete sign in or link account operation and then pass result to\n  // relevant pending popup promise.\n  return handler(requestUri, sessionId, tenantId, postBody)\n      .then(function(popupRedirectResponse) {\n    // Flow completed.\n    // For a redirect operation resolve with the popupRedirectResponse,\n    // otherwise resolve with null.\n    self.setRedirectResult_(isRedirect, popupRedirectResponse, null);\n  }).thenCatch(function(error) {\n    // Flow not completed due to error.\n    // For a redirect operation reject with the error, otherwise resolve\n    // with null.\n    self.setRedirectResult_(\n        isRedirect, null, /** @type {!fireauth.AuthError} */ (error));\n    // Always resolve.\n    return;\n  });\n};\n\n\n/**\n * Sets redirect error result.\n * @param {!fireauth.AuthError} error The redirect operation error.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectReject_ =\n    function(error) {\n  // If a redirect error detected, reject getRedirectResult with that error.\n  this.redirectedUserPromise_ = function() {\n    return goog.Promise.reject(error);\n  };\n  // Reject all pending getRedirectResult promises.\n  if (this.redirectReject_.length) {\n    for (var i = 0; i < this.redirectReject_.length; i++) {\n      this.redirectReject_[i](error);\n    }\n  }\n};\n\n\n/**\n * Sets redirect success result.\n * @param {!fireauth.AuthEventManager.Result} popupRedirectResult The\n *     resolved user for a successful or null user redirect.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectResolve_ =\n    function(popupRedirectResult) {\n  // If a redirect user detected, resolve getRedirectResult with the\n  // popupRedirectResult.\n  // Result should not be null in this case.\n  this.redirectedUserPromise_ = function() {\n    return goog.Promise.resolve(\n        /** @type {!fireauth.AuthEventManager.Result} */ (popupRedirectResult));\n  };\n  // Resolve all pending getRedirectResult promises.\n  if (this.redirectResolve_.length) {\n    for (var i = 0; i < this.redirectResolve_.length; i++) {\n      this.redirectResolve_[i](\n          /** @type {!fireauth.AuthEventManager.Result} */ (\n              popupRedirectResult));\n    }\n  }\n};\n\n\n/**\n * @param {boolean} isRedirect Whether Auth event is a redirect event.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The\n *     resolved user for a successful redirect. This user is null if no redirect\n *     operation run.\n * @param {?fireauth.AuthError} error The redirect operation error.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectResult_ =\n    function(isRedirect, popupRedirectResult, error) {\n  if (isRedirect) {\n    // This is a redirect operation, either resolves with user or error.\n    if (error) {\n      // If a redirect error detected, reject getRedirectResult with that error.\n      this.setRedirectReject_(error);\n    } else {\n      // If a redirect user detected, resolve getRedirectResult with the\n      // popupRedirectResult.\n      // Result should not be null in this case.\n      this.setRedirectResolve_(\n          /** @type {!fireauth.AuthEventManager.Result} */ (\n              popupRedirectResult));\n    }\n  } else {\n    // Not a redirect, set redirectUser_ to return null.\n    this.setRedirectResolve_({\n      'user': null\n    });\n  }\n  // Reset all pending promises.\n  this.redirectResolve_ = [];\n  this.redirectReject_ = [];\n};\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.RedirectAuthEventProcessor.prototype.getRedirectResult = function() {\n  var self = this;\n  // Initial result could be overridden in the case of Cordova.\n  // Auth domain must be included for this to resolve.\n  // If still pending just return the pending promise.\n  var p = new goog.Promise(function(resolve, reject) {\n    // The following logic works if this method was called before Auth event\n    // is triggered.\n    if (!self.redirectedUserPromise_) {\n      // Save resolves and rejects of pending promise for redirect operation.\n      self.redirectResolve_.push(resolve);\n      self.redirectReject_.push(reject);\n      // Start timeout listener to getRedirectResult pending promise.\n      // Call this only when redirectedUserPromise_ is not determined.\n      self.startRedirectTimeout_();\n    } else {\n      // Called after Auth event is triggered.\n      self.redirectedUserPromise_().then(resolve, reject);\n    }\n  });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (p);\n};\n\n\n/**\n * Starts timeout listener for getRedirectResult pending promise. This method\n * should not be called again after getRedirectResult's redirectedUserPromise_\n * is determined.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.startRedirectTimeout_ =\n    function() {\n  // Expire pending timeout promise for popup operation.\n  var self = this;\n  var error = new fireauth.AuthError(\n      fireauth.authenum.Error.TIMEOUT);\n  if (this.redirectTimeoutPromise_) {\n    this.redirectTimeoutPromise_.cancel();\n  }\n  // For redirect mode.\n  this.redirectTimeoutPromise_ =\n      goog.Timer.promise(fireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_.get())\n      .then(function() {\n        // If not resolved yet, reject with timeout error.\n        if (!self.redirectedUserPromise_) {\n          // Consider redirect result resolved.\n          self.redirectResultResolved_ = true;\n          self.setRedirectResult_(true, null, error);\n        }\n      });\n\n};\n\n\n\n/**\n * Popup Auth event manager.\n * @param {!fireauth.AuthEventManager} manager The parent Auth event manager.\n * @constructor\n * @implements {fireauth.AuthEventProcessor}\n */\nfireauth.PopupAuthEventProcessor = function(manager) {\n  this.manager_ = manager;\n};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @override\n */\nfireauth.PopupAuthEventProcessor.prototype.processAuthEvent =\n    function(authEvent, owner) {\n  // This should not happen as fireauth.iframe.AuthRelay will not send null\n  // events.\n  if (!authEvent) {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n  }\n  var mode = authEvent.getType();\n  var eventId = authEvent.getEventId();\n  if (authEvent.hasError()) {\n    return this.processErrorEvent_(authEvent, owner);\n  } else if (owner.getAuthEventHandlerFinisher(mode, eventId)) {\n    return this.processSuccessEvent_(authEvent, owner);\n  } else {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n  }\n};\n\n\n/**\n * Processes an error event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.PopupAuthEventProcessor.prototype.processErrorEvent_ =\n    function(authEvent, owner) {\n  var eventId = authEvent.getEventId();\n  var mode = authEvent.getType();\n  // For pending popup promises trigger rejects with the error.\n  owner.resolvePendingPopupEvent(mode, null, authEvent.getError(), eventId);\n  return goog.Promise.resolve();\n};\n\n\n/**\n * Processes a successful event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n *     iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.PopupAuthEventProcessor.prototype.processSuccessEvent_ =\n    function(authEvent, owner) {\n  var eventId = authEvent.getEventId();\n  var mode = authEvent.getType();\n  var handler = owner.getAuthEventHandlerFinisher(mode, eventId);\n  // Successful operation, complete the exchange for an ID token.\n  var requestUri = /** @type {string} */ (authEvent.getUrlResponse());\n  var sessionId = /** @type {string} */ (authEvent.getSessionId());\n  var postBody = /** @type {?string} */ (authEvent.getPostBody());\n  var tenantId = /** @type {?string} */ (authEvent.getTenantId());\n  // Complete sign in or link account operation and then pass result to\n  // relevant pending popup promise.\n  return handler(requestUri, sessionId, tenantId, postBody)\n      .then(function(popupRedirectResponse) {\n    // Flow completed.\n    // Resolve pending popup promise if it exists.\n    owner.resolvePendingPopupEvent(mode, popupRedirectResponse, null, eventId);\n  }).thenCatch(function(error) {\n    // Flow not completed due to error.\n    // Resolve pending promise if it exists.\n    owner.resolvePendingPopupEvent(\n        mode, null, /** @type {!fireauth.AuthError} */ (error), eventId);\n    // Always resolve.\n    return;\n  });\n};\n\n\n\n/**\n * The interface that represents an Auth event handler. It provides the\n * ability for the Auth event manager to determine the owner of an Auth event,\n * the ability to resolve a pending popup event and the appropriate handler for\n * an event.\n * @interface\n */\nfireauth.AuthEventHandler = function() {};\n\n\n/**\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the Auth event handler can handler the provided\n *     event.\n */\nfireauth.AuthEventHandler.prototype.canHandleAuthEvent =\n    function(mode, opt_eventId) {};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n *     to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n */\nfireauth.AuthEventHandler.prototype.resolvePendingPopupEvent =\n    function(mode, popupRedirectResult, error, opt_eventId) {};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n *     ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthEventHandler.prototype.getAuthEventHandlerFinisher =\n    function(mode, opt_eventId) {};\n","/**\n * @license\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the multi-factor resolver class used to facilitate\n *     recovery when a multi-factor user tries to sign-in with a first factor.\n */\n\ngoog.provide('fireauth.MultiFactorResolver');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * Initializes a `MultiFactorResolver` instance. This is used when a\n * multi-factor user signs in with the first factor but is required to provide\n * a second factor assertion before completing sign-in.\n *\n * @param {!fireauth.Auth} auth The Auth instance.\n * @param {!fireauth.MultiFactorResolver.ErrorResponse} errorResponse The server\n *     error response containing the pending multi-factor credential.\n * @param {function({idToken: string, refreshToken: string}):\n *         !goog.Promise<!fireauth.AuthEventManager.Result>} onIdTokenResolver\n *     A function that takes the assertion token response and any previous\n *     information returned with the error and completes sign in with a\n *     `UserCredential`.\n * @constructor\n */\nfireauth.MultiFactorResolver = function(\n    auth, errorResponse, onIdTokenResolver) {\n  var pendingCredential = errorResponse && errorResponse[\n      fireauth.MultiFactorResolver.SignInResponseField.MFA_PENDING_CREDENTIAL];\n  if (!pendingCredential) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'Internal assert: Invalid MultiFactorResolver');\n  }\n  /** @const @private {!fireauth.Auth} The Auth instance. */\n  this.auth_ = auth;\n  /**\n   * @const @private {!fireauth.MultiFactorResolver.ErrorResponse} The server\n   *     error response with the pending credential.\n   */\n  this.errorResponse_ = goog.object.clone(errorResponse);\n  /**\n   * @const @private {function({idToken: string, refreshToken: string}):\n   *                  !goog.Promise<!fireauth.AuthEventManager.Result>} The ID\n   *     token resolver.\n   */\n  this.onIdTokenResolver_ = onIdTokenResolver;\n  /**\n   * @const @private {!fireauth.MultiFactorSession} The corresponding\n   *     multi-factor session.\n   */\n  this.session_ = new fireauth.MultiFactorSession(\n      null,\n      pendingCredential);\n  /**\n   * @const @private {!Array<!fireauth.MultiFactorInfo>} The list of\n   *     multi-factor hints corresponding to the current user session.\n   */\n  this.hints_ = [];\n  var enrollmentList = errorResponse[\n      fireauth.MultiFactorResolver.SignInResponseField.MFA_INFO] || [];\n  var self = this;\n  goog.array.forEach(enrollmentList, function(mfaEnrollment) {\n    var info = fireauth.MultiFactorInfo.fromServerResponse(mfaEnrollment);\n    if (info) {\n      self.hints_.push(info);\n    }\n  });\n  fireauth.object.setReadonlyProperty(this, 'auth', this.auth_);\n  fireauth.object.setReadonlyProperty(this, 'session', this.session_);\n  fireauth.object.setReadonlyProperty(\n      this, 'hints', this.hints_);\n};\n\n\n/**\n * The server side error response on multi-factor sign-in.\n * @typedef {{\n *   mfaInfo: (?Array<!Object>|undefined),\n *   mfaPendingCredential: (?string|undefined)\n * }}\n */\nfireauth.MultiFactorResolver.ErrorResponse;\n\n/**\n * Sign in response fields for multi-factor sign-in.\n * @enum {string}\n */\nfireauth.MultiFactorResolver.SignInResponseField = {\n  MFA_INFO: 'mfaInfo',\n  MFA_PENDING_CREDENTIAL: 'mfaPendingCredential'\n};\n\n\n/**\n * Completes the second factor sign-in with the multi-factor assertion provided\n * and returns a promise that resolves with the `UserCredential` object.\n *\n * @param {!fireauth.MultiFactorAssertion} assertion The multi-factor assertion\n *     to resolve sign-in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A promise that\n *     resolves with the `UserCredential` after ID token processing.\n */\nfireauth.MultiFactorResolver.prototype.resolveSignIn = function(assertion) {\n  var self = this;\n  return assertion.process(this.auth_.getRpcHandler(), this.session_)\n      .then(function(result) {\n        var newSignInResponse = goog.object.clone(self.errorResponse_);\n        // These fields are no longer needed.\n        delete newSignInResponse[\n            fireauth.MultiFactorResolver.SignInResponseField.MFA_INFO];\n        delete newSignInResponse[fireauth.MultiFactorResolver\n            .SignInResponseField.MFA_PENDING_CREDENTIAL];\n        goog.object.extend(newSignInResponse, result);\n        // Return ID token/refresh token result and the original error response.\n        // This is needed as the original server response may contain additional\n        // data such as OAuth credentials, raw user info, etc that needs to be\n        // returned to the developer on successful sign-in.\n        return self.onIdTokenResolver_(\n            /** @type {{idToken: string, refreshToken: string}} */ (\n                newSignInResponse));\n      });\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the `firebase.auth.MultiFactorAssertion` abstract class\n * and all its subclasses, such as PhoneMultiFactorAssertion.\n */\n\ngoog.provide('fireauth.AuthCredentialMultiFactorAssertion');\ngoog.provide('fireauth.MultiFactorAssertion');\ngoog.provide('fireauth.PhoneMultiFactorAssertion');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.MultiFactorAuthCredential');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\n\n\n/**\n * Abstract class representing a `firebase.auth.MultiFactorAssertion` interface.\n * This is used to facilitate enrollment of a second factor on an existing user\n * or sign-in of a user who already verified the first factor.\n * @abstract\n * @constructor\n */\nfireauth.MultiFactorAssertion = function() {};\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current\n * MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n *     The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the updated ID and refresh tokens.\n * @protected\n */\nfireauth.MultiFactorAssertion.prototype.finalizeEnrollmentWithVerificationInfo =\n    goog.abstractMethod;\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n *     The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the signed in user's ID and refresh tokens.\n * @protected\n */\nfireauth.MultiFactorAssertion.prototype.finalizeSignInWithVerificationInfo =\n    goog.abstractMethod;\n\n\n/**\n * Processes the `MultiFactorAssertion` instance using the `MultiFactorSession`\n * provided and optional display name for enrollment flows.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session\n *     instance.\n * @param {?string=} displayName The optional display name for a multi-factor\n *     enrollment.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the signed in or enrolled user's ID and refresh\n *     tokens.\n */\nfireauth.MultiFactorAssertion.prototype.process =\n    function(rpcHandler, session, displayName) {\n  // Session obtained from user in enroll.\n  // It is obtained from error in resolver.\n  if (session.type == fireauth.MultiFactorSession.Type.ENROLL) {\n    return this.finalizeMfaEnrollment_(rpcHandler, session, displayName);\n  } else {\n    return this.finalizeMfaSignIn_(rpcHandler, session);\n  }\n};\n\n\n/**\n * Finalizes the multi-factor enrollment.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session for\n *     the current signed in user.\n * @param {?string=} displayName The optional display name for a multi-factor\n *     enrollment.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the enrolled user's ID and refresh tokens.\n * @private\n */\nfireauth.MultiFactorAssertion.prototype.finalizeMfaEnrollment_ =\n    function(rpcHandler, session, displayName) {\n  var self = this;\n  return session.getRawSession().then(function(rawSession) {\n    var request = {\n      'idToken': rawSession\n    };\n    if (typeof displayName !== 'undefined') {\n      request['displayName'] = displayName;\n    }\n    return self.finalizeEnrollmentWithVerificationInfo(rpcHandler, request);\n  });\n};\n\n\n/**\n * Finalizes the multi-factor sign-in.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session for\n *     the multi-factor enrolled user trying to sign-in.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the signed in user's ID and refresh tokens.\n * @private\n */\nfireauth.MultiFactorAssertion.prototype.finalizeMfaSignIn_ =\n    function(rpcHandler, session) {\n  var self = this;\n  return session.getRawSession().then(function(rawSession) {\n    var request = {\n      'mfaPendingCredential': rawSession,\n    };\n    return self.finalizeSignInWithVerificationInfo(rpcHandler, request);\n  });\n};\n\n\n/**\n * Defines a class for handling MultiFactorAssertions based on\n * `MultiFactorAuthCredentials`.\n * @param {!fireauth.MultiFactorAuthCredential} multiFactorAuthCredential The\n *     multi-factor AuthCredential.\n * @constructor\n * @extends {fireauth.MultiFactorAssertion}\n */\nfireauth.AuthCredentialMultiFactorAssertion =\n    function(multiFactorAuthCredential) {\n  // This assumes the factor ID matches the credential providerId.\n  // If this is ever not true, the subclass can overwrite that.\n  fireauth.object.setReadonlyProperty(\n      this, 'factorId', multiFactorAuthCredential.providerId);\n  /**\n   * @protected {!fireauth.MultiFactorAuthCredential} The underlying\n   *     multi-factor AuthCredential.\n   */\n  this.multiFactorAuthCredential = multiFactorAuthCredential;\n};\ngoog.inherits(\n    fireauth.AuthCredentialMultiFactorAssertion, fireauth.MultiFactorAssertion);\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current\n * MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n *     The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the updated ID and refresh tokens.\n * @protected\n * @override\n */\nfireauth.AuthCredentialMultiFactorAssertion.prototype\n    .finalizeEnrollmentWithVerificationInfo = function(rpcHandler,\n                                                       enrollmentRequest) {\n  return this.multiFactorAuthCredential.finalizeMfaEnrollment(\n      rpcHandler, enrollmentRequest);\n};\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n *     The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n *     that resolves with the signed in user's ID and refresh tokens.\n * @protected\n * @override\n */\nfireauth.AuthCredentialMultiFactorAssertion.prototype\n    .finalizeSignInWithVerificationInfo = function(rpcHandler,\n                                                   signInRequest) {\n  return this.multiFactorAuthCredential.finalizeMfaSignIn(\n      rpcHandler, signInRequest);\n};\n\n\n/**\n * Defines a class for handling MultiFactorAssertions based on\n * PhoneAuthCredentials. This class extends `AuthCredentialMultiFactorAssertion`\n * but for `PhoneAuthCredentials` only.\n * @param {!fireauth.PhoneAuthCredential} phoneAuthCredential\n * @constructor\n * @extends {fireauth.AuthCredentialMultiFactorAssertion}\n */\nfireauth.PhoneMultiFactorAssertion = function(phoneAuthCredential) {\n  fireauth.PhoneMultiFactorAssertion.base(\n      this, 'constructor', phoneAuthCredential);\n  // This class supports phone credentials only.\n  if (this.multiFactorAuthCredential.providerId !=\n      fireauth.PhoneAuthProvider['PROVIDER_ID']) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'firebase.auth.PhoneMultiFactorAssertion requires a valid ' +\n        'firebase.auth.PhoneAuthCredential');\n  }\n};\ngoog.inherits(\n    fireauth.PhoneMultiFactorAssertion,\n    fireauth.AuthCredentialMultiFactorAssertion);\n","/**\n * @license\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the `MultiFactorUser` class used to retrieve the\n * enrolled second factors on a user and to facilitate enrollment and\n * unenrollment of second factors.\n */\n\ngoog.provide('fireauth.MultiFactorUser');\n\ngoog.require('fireauth.MultiFactorAssertion');\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.object');\ngoog.require('goog.array');\ngoog.require('goog.events');\n\n\n/**\n * Initializes the multi-factor instance corresponding to a signed in user.\n * This provides the ability to retrieve the enrolled second factors for that\n * user, as well as the ability to enroll new second factors or unenroll\n * existing ones.\n * @param {!fireauth.AuthUser} user The user the multi-factor instance\n *     represents.\n * @param {?fireauth.AuthUser.AccountInfo=} accountInfo The optional user\n *     account info.\n * @constructor\n */\nfireauth.MultiFactorUser = function(user, accountInfo) {\n  /**\n   * @private {!fireauth.AuthUser} The user this multi-factor instance\n   *     represents.\n   */\n  this.user_ = user;\n  /** @private {!Array<!fireauth.MultiFactorInfo>} The enrolled factors. */\n  this.enrolledFactors_ = [];\n  /**\n   * @const @private {function({userServerResponse: !Object})} The handler for\n   *     user reload events.\n   */\n  this.userReloadedListener_ = goog.bind(this.handleUserReload_, this);\n  goog.events.listen(\n      this.user_,\n      fireauth.UserEventType.USER_RELOADED,\n      this.userReloadedListener_);\n  var enrolledFactors = [];\n  // AccountInfo is typically loaded from storage where it is stored in plain\n  // object format. Otherwise, the enrolled factors will be loaded from\n  // getAccountInfo response triggered by user reload event.\n  if (accountInfo &&\n      accountInfo['multiFactor'] &&\n      accountInfo['multiFactor']['enrolledFactors']) {\n    var enrolledFactorsPlainObject =\n        accountInfo['multiFactor']['enrolledFactors'];\n    goog.array.forEach(enrolledFactorsPlainObject, function(mfaEnrollment) {\n      var info = fireauth.MultiFactorInfo.fromPlainObject(mfaEnrollment);\n      if (info) {\n        enrolledFactors.push(info);\n      }\n    });\n  }\n  this.updateEnrolledFactors_(enrolledFactors);\n};\n\n\n/**\n * @const @private {string} The key for the list of second factor enrollments in\n *     the GetAccountInfo server response.\n */\nfireauth.MultiFactorUser.GET_ACCOUNT_INFO_MFA_INFO_ = 'mfaInfo';\n\n\n/** @return {!fireauth.AuthUser} The corresponding user. */\nfireauth.MultiFactorUser.prototype.getUser = function() {\n  return this.user_;\n};\n\n\n/**\n * Extracts the enrolled factors from getAccountInfo response and returns an\n * array of corresponding multi-factor info data.\n * @param {!Object} resp The GetAccountInfo response object.\n * @return {!Array<!fireauth.MultiFactorInfo>} The enrolled factors.\n * @private\n */\nfireauth.MultiFactorUser.extractEnrolledFactors_ = function(resp) {\n  // Parse MFA enrollments.\n  var mfaInfo = resp[fireauth.MultiFactorUser.GET_ACCOUNT_INFO_MFA_INFO_] || [];\n  var enrolledFactors = [];\n  goog.array.forEach(mfaInfo, function(mfaEnrollment) {\n    var info = fireauth.MultiFactorInfo.fromServerResponse(mfaEnrollment);\n    if (info) {\n      enrolledFactors.push(info);\n    }\n  });\n  return enrolledFactors;\n};\n\n\n/**\n * Handles user reload event. This will parse the enrollments from the\n * response and update them on the current multi-factor instance.\n * @param {{userServerResponse: !Object}} event The user reload event.\n * @private\n */\nfireauth.MultiFactorUser.prototype.handleUserReload_ = function(event) {\n  this.updateEnrolledFactors_(fireauth.MultiFactorUser.extractEnrolledFactors_(\n      event.userServerResponse));\n};\n\n\n/**\n * Updates the enrolledFactors property.\n * @param {!Array<!fireauth.MultiFactorInfo>} enrolledFactors The new list of\n *     `MultiFactorInfo` objects on the user.\n * @private\n */\nfireauth.MultiFactorUser.prototype.updateEnrolledFactors_ =\n    function(enrolledFactors) {\n  this.enrolledFactors_ = enrolledFactors;\n  fireauth.object.setReadonlyProperty(\n      this, 'enrolledFactors', enrolledFactors);\n};\n\n\n/**\n * Copies the list of enrolled factors on the user. This facilitates copying a\n * user to another user. The underlying user reference is not updated.\n * @param {!fireauth.MultiFactorUser} multiFactorUser The instance to copy.\n */\nfireauth.MultiFactorUser.prototype.copy = function(multiFactorUser) {\n  this.updateEnrolledFactors_(multiFactorUser.enrolledFactors_);\n};\n\n\n/**\n * Provides a multi-factor session used to start a multi-factor enrollment flow.\n * @return {!goog.Promise<!fireauth.MultiFactorSession>} A promise that resolves\n *     with a multi-factor session.\n */\nfireauth.MultiFactorUser.prototype.getSession = function() {\n  return this.user_.getIdToken()\n      .then(function(idToken) {\n        return new fireauth.MultiFactorSession(idToken, null);\n      });\n};\n\n\n/**\n * Enrolls a second factor as identified by the multi-factor assertion for\n * the current user.\n * @param {!fireauth.MultiFactorAssertion} assertion The multi-factor assertion.\n * @param {?string=} displayName The optional display name used to identify\n *     the 2nd factor to the end user.\n * @return {!goog.Promise<void>} A promise that resolves when the second factor\n *     is enrolled.\n */\nfireauth.MultiFactorUser.prototype.enroll = function(assertion, displayName) {\n  var self = this;\n  var rpcHandler = this.user_.getRpcHandler();\n  return this.getSession().then(function(session) {\n    return assertion.process(rpcHandler, session, displayName);\n  }).then(function(tokenResponse) {\n    // New tokens will be issued after enrollment of the new second factors.\n    // They need to be updated on the user.\n    self.user_.updateTokensIfPresent(tokenResponse);\n    // The user needs to be reloaded to get the new multi-factor information\n    // from server. USER_RELOADED event will be triggered and `enrolledFactors`\n    // will be updated.\n    return self.user_.reload();\n  });\n};\n\n\n/**\n * Removes a second factor from the current user. The factor to be removed can\n * either be identified with the corresponding MultiFactorInfo object or with\n * the second factor's uid string.\n *\n * As part of the unenrollment process, the backend may decide to log the user\n * out. If so, this will still succeed and invalidate the user's state.\n * @param {!fireauth.MultiFactorInfo|string} target The second factor to remove.\n * @return {!goog.Promise<void>}\n */\nfireauth.MultiFactorUser.prototype.unenroll = function(target) {\n  var self = this;\n  var uid = typeof target === 'string' ? target : target['uid'];\n  var rpcHandler = this.user_.getRpcHandler();\n  return this.user_.getIdToken().then(function(idToken) {\n    return rpcHandler.withdrawMfa(idToken, uid);\n  }).then(function(tokenResponse) {\n    // Remove the second factor from the user's list.\n    var enrolledFactors = goog.array.filter(self.enrolledFactors_,\n      function(info) {\n        return info['uid'] != uid;\n      });\n    self.updateEnrolledFactors_(enrolledFactors);\n    // Depending on whether the backend decided to revoke the user's session,\n    // the tokenResponse may be empty. If the tokens were not updated (and they\n    // are now invalid), reloading the user will discover this and invalidate\n    // the user's state accordingly.\n    self.user_.updateTokensIfPresent(tokenResponse);\n    return self.user_.reload().thenCatch(function(error) {\n      if (error['code'] != 'auth/user-token-expired') {\n        throw error;\n      }\n    });\n  });\n};\n\n\n/**\n * @return {!Object} The plain object representation of the `MultiFactorUser`.\n */\nfireauth.MultiFactorUser.prototype.toPlainObject = function() {\n  return {\n    'multiFactor': {\n      'enrolledFactors': goog.array.map(this.enrolledFactors_, function(info) {\n        return info.toPlainObject();\n      })\n    }\n  };\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Utility for proactive refresh with exponential backoff\n * algorithm typically used to define a retry policy for certain async\n * operations.\n */\n\ngoog.provide('fireauth.ProactiveRefresh');\n\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\n\n\n/**\n * The helper utility used to proactively refresh a certain operation based on\n * certain constraints with an exponential backoff retrial policy when\n * specific recoverable errors occur. Typically this is used to retry an\n * operation on network errors.\n * @param {!function():!goog.Promise} operation The promise returning operation\n *     to run.\n * @param {!function(*):boolean} retryPolicy A function that takes in an error\n *     and returns whether a retry policy should be implemented based on the\n *     error. If not, the operation will not run again.\n * @param {!function():number} getWaitDuration A function that returns the wait\n *     period before running again.\n * @param {number} lowerBound The lower bound duration to wait when an error\n *     occurs. This is the first interval to wait before rerunning after an\n *     error is detected.\n * @param {number} upperBound The upper bound duration to wait when an error\n *     keeps occurring. This upper bound should not be exceeded.\n * @param {boolean=} opt_runInBackground Whether to run in the background, when\n *     the tab is not visible. If the refresh should only run when the app is\n *     visible, the operation will block until the app is visible and then run.\n * @constructor @struct @final\n */\nfireauth.ProactiveRefresh = function(\n    operation,\n    retryPolicy,\n    getWaitDuration,\n    lowerBound,\n    upperBound,\n    opt_runInBackground) {\n  /**\n   * @const @private {!function():!goog.Promise} The promise returning operation\n   *     to run.\n   */\n  this.operation_ = operation;\n  /**\n   * @const @private {!function(*):boolean} The function that takes in an error\n   *     and returns whether a retry policy should be implemented based on the\n   *     error caught.\n   */\n  this.retryPolicy_ = retryPolicy;\n  /**\n   * @const @private {!function():number} The function that returns the wait\n   *     period after a successful operation before running again.\n   */\n  this.getWaitDuration_ = getWaitDuration;\n  /**\n   * @const @private {number} The lower bound duration to wait when an error\n   *     first occurs.\n   */\n  this.lowerBound_ = lowerBound;\n  /**\n   * @const @private {number} The upper bound duration to wait when an error\n   *     keeps occurring. This upper bound should not be exceeded.\n   */\n  this.upperBound_ = upperBound;\n  /**\n   * @const @private {boolean} Whether to run in the background, when the tab is\n   *     not visible.\n   */\n  this.runInBackground_ = !!opt_runInBackground;\n  /**\n   * @private {?goog.Promise} The pending promise for the next operation to run.\n   */\n  this.pending_ = null;\n  /**\n   * @private {number} The first wait interval when a new error occurs.\n   */\n  this.nextErrorWaitInterval_ = this.lowerBound_;\n  // Throw an error if the lower bound is greater than upper bound.\n  if (this.upperBound_ < this.lowerBound_) {\n    throw new Error('Proactive refresh lower bound greater than upper bound!');\n  }\n};\n\n\n/** Starts the proactive refresh based on the current configuration. */\nfireauth.ProactiveRefresh.prototype.start = function() {\n  // Set the next error wait interval to the lower bound. On each consecutive\n  // error, this will double in value until it reaches the upper bound.\n  this.nextErrorWaitInterval_ = this.lowerBound_;\n  // Start proactive refresh with clean slate (successful status).\n  this.process_(true);\n};\n\n\n/**\n * Returns the wait duration before the next run depending on the last run\n * status. If the last operation has succeeded, returns the getWaitDuration()\n * response. Otherwise, doubles the last error wait interval starting from\n * lowerBound and up to upperBound.\n * @param {boolean} hasSucceeded Whether last run succeeded.\n * @return {number} The wait time for the next run.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.getNextRun_ = function(hasSucceeded) {\n  if (hasSucceeded) {\n    // If last operation succeeded, reset next error wait interval and return\n    // the default wait duration.\n    this.nextErrorWaitInterval_ = this.lowerBound_;\n    // Return typical wait duration interval after a successful operation.\n    return this.getWaitDuration_();\n  } else {\n    // Get next error wait interval.\n    var currentErrorWaitInterval = this.nextErrorWaitInterval_;\n    // Double interval for next consecutive error.\n    this.nextErrorWaitInterval_ *= 2;\n    // Make sure next wait interval does not exceed the maximum upper bound.\n    if (this.nextErrorWaitInterval_  > this.upperBound_) {\n      this.nextErrorWaitInterval_  = this.upperBound_;\n    }\n    return currentErrorWaitInterval;\n  }\n};\n\n\n/**\n * Processes one refresh call and sets the timer for the next call based on\n * the last recorded result.\n * @param {boolean} hasSucceeded Whether last run succeeded.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.process_ = function(hasSucceeded) {\n  var self = this;\n  // Stop any other pending operation.\n  this.stop();\n  // Wait for next scheduled run based on whether an error occurred during last\n  // run.\n  this.pending_ = goog.Timer.promise(this.getNextRun_(hasSucceeded))\n      .then(function() {\n        // Block for conditions (if app is required to be visible) to be ready.\n        return self.waitUntilReady_();\n       })\n       .then(function() {\n         // Run the operation.\n         return self.operation_();\n       })\n      .then(function() {\n         // If successful, try again on next cycle with no previous error\n         // passed.\n         self.process_(true);\n       })\n      .thenCatch(function(error) {\n         // If an error occurs, only rerun when the error meets the retry\n         // policy.\n         if (self.retryPolicy_(error)) {\n           // Should retry with error to trigger exponentional backoff.\n           self.process_(false);\n         }\n         // Any other error is considered unrecoverable. Do not try again.\n       });\n};\n\n\n/**\n * Returns a promise which resolves when the current tab is visible.\n * This resolves quickly if refresh is supposed to run in the background too.\n * @return {!goog.Promise} The promise that resolves when the tab is visible or\n *     that requirement is not needed.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.waitUntilReady_ = function() {\n  // Wait until app is in foreground if required.\n  if (this.runInBackground_) {\n    // If runs in background, resolve quickly.\n    return goog.Promise.resolve();\n  } else {\n    // Wait for the app to be visible before resolving the promise.\n    return fireauth.util.onAppVisible();\n  }\n};\n\n\n/** Stops the proactive refresh from running again. */\nfireauth.ProactiveRefresh.prototype.stop = function() {\n  // If there is a pending promise.\n  if (this.pending_) {\n    // Cancel the pending promise and nullify it.\n    this.pending_.cancel();\n    this.pending_ = null;\n  }\n};\n\n\n/** @return {boolean} Whether the proactive refresh is running or not. */\nfireauth.ProactiveRefresh.prototype.isRunning = function() {\n  return !!this.pending_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Utility class to retrieve and cache STS token.\n */\ngoog.provide('fireauth.StsTokenManager');\ngoog.provide('fireauth.StsTokenManager.Response');\ngoog.provide('fireauth.StsTokenManager.ResponseData');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('goog.Promise');\ngoog.require('goog.asserts');\n\n\n\n/**\n * Creates STS token manager.\n *\n * @param {!fireauth.RpcHandler} rpcHandler Handler for RPC requests.\n * @constructor\n */\nfireauth.StsTokenManager = function(rpcHandler) {\n  /**\n   * @const @private {!fireauth.RpcHandler} The RPC handler used to request STS\n   *     tokens.\n   */\n  this.rpcHandler_ = rpcHandler;\n  /** @private {?string} The STS refresh token. */\n  this.refreshToken_ = null;\n  /** @private {?fireauth.IdToken} The STS ID token. */\n  this.accessToken_ = null;\n};\n\n\n/**\n * @return {!Object} The plain object representation of the STS token manager.\n */\nfireauth.StsTokenManager.prototype.toPlainObject = function() {\n  return {\n    'apiKey': this.rpcHandler_.getApiKey(),\n    'refreshToken': this.refreshToken_,\n    'accessToken': this.accessToken_ && this.accessToken_.toString(),\n    // To support downgrade flows, return expiration time.\n    'expirationTime': this.getExpirationTime()\n  };\n};\n\n\n/**\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler for the token\n *     manager.\n * @param {?Object} obj The plain object whose STS token manager instance is to\n *     be returned.\n * @return {?fireauth.StsTokenManager} The STS token manager instance from the\n *     plain object provided using the RPC handler provided.\n */\nfireauth.StsTokenManager.fromPlainObject = function(rpcHandler, obj) {\n  var stsTokenManager = null;\n  if (obj && obj['apiKey']) {\n    // These should be always equals and must be enforced in internal use.\n    goog.asserts.assert(obj['apiKey'] == rpcHandler.getApiKey());\n    stsTokenManager = new fireauth.StsTokenManager(rpcHandler);\n    stsTokenManager.setRefreshToken(obj['refreshToken']);\n    stsTokenManager.setAccessToken(obj['accessToken']);\n  }\n  return stsTokenManager;\n};\n\n\n/**\n * @typedef {{\n *   accessToken: (?string),\n *   refreshToken: (?string)\n * }}\n */\nfireauth.StsTokenManager.Response;\n\n\n/**\n * @typedef {{\n *   access_token: (?string|undefined),\n *   refresh_token: (?string|undefined)\n * }}\n */\nfireauth.StsTokenManager.ResponseData;\n\n\n/**\n * @param {?string} refreshToken The STS refresh token.\n */\nfireauth.StsTokenManager.prototype.setRefreshToken = function(refreshToken) {\n  this.refreshToken_ = refreshToken;\n};\n\n\n/**\n * @param {?string} accessToken The STS access token.\n */\nfireauth.StsTokenManager.prototype.setAccessToken = function(accessToken) {\n  this.accessToken_ = fireauth.IdToken.parse(accessToken || '');\n};\n\n\n/**\n * @return {?string} The refresh token.\n */\nfireauth.StsTokenManager.prototype.getRefreshToken = function() {\n  return this.refreshToken_;\n};\n\n\n/**\n * @return {number} The STS access token expiration time in milliseconds.\n */\nfireauth.StsTokenManager.prototype.getExpirationTime = function() {\n  return (this.accessToken_ && this.accessToken_.getExp() * 1000) || 0;\n};\n\n\n/**\n * The number of milliseconds before the official expiration time of a token\n * to refresh that token, to provide a buffer for RPCs to complete.\n * @const {number}\n */\nfireauth.StsTokenManager.TOKEN_REFRESH_BUFFER = 30 * 1000;\n\n\n/**\n * @return {boolean} Whether the STS access token is expired or not.\n * @private\n */\nfireauth.StsTokenManager.prototype.isExpired_ = function() {\n  return goog.now() >\n      this.getExpirationTime() - fireauth.StsTokenManager.TOKEN_REFRESH_BUFFER;\n};\n\n\n/**\n * Parses a response from the server that contains STS tokens (e.g. from\n * VerifyAssertion or VerifyPassword) and save the access token, refresh token,\n * and expiration time.\n * @param {!Object} response The backend response.\n * @return {string} The STS access token.\n */\nfireauth.StsTokenManager.prototype.parseServerResponse = function(response) {\n  var idToken = response[fireauth.RpcHandler.AuthServerField.ID_TOKEN];\n  var refreshToken =\n      response[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN];\n  this.setAccessToken(idToken);\n  this.setRefreshToken(refreshToken);\n  return idToken;\n};\n\n\n/**\n * Converts STS token manager instance to server response object.\n * @return {!Object}\n */\nfireauth.StsTokenManager.prototype.toServerResponse = function() {\n  var stsTokenManagerResponse = {};\n  stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN] =\n      this.accessToken_ && this.accessToken_.toString();\n  // Refresh token could be expired.\n  stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN] =\n      this.getRefreshToken();\n  return stsTokenManagerResponse;\n};\n\n\n/**\n * Copies IdToken, refreshToken and expirationTime from tokenManagerToCopy.\n * @param {!fireauth.StsTokenManager} tokenManagerToCopy\n */\nfireauth.StsTokenManager.prototype.copy = function(tokenManagerToCopy) {\n  this.accessToken_ = tokenManagerToCopy.accessToken_;\n  this.refreshToken_ = tokenManagerToCopy.refreshToken_;\n};\n\n\n/**\n * Exchanges the current refresh token with an access and refresh token.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n * @private\n */\nfireauth.StsTokenManager.prototype.exchangeRefreshToken_ = function() {\n  var data = {\n    'grant_type': 'refresh_token',\n    'refresh_token': this.refreshToken_\n  };\n  return this.requestToken_(data);\n};\n\n\n/**\n * Sends a request to STS token endpoint for an access/refresh token.\n * @param {!Object} data The request data to send to STS token endpoint.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n * @private\n */\nfireauth.StsTokenManager.prototype.requestToken_ = function(data) {\n  var self = this;\n  // Send RPC request to STS token endpoint.\n  return this.rpcHandler_.requestStsToken(data).then(function(resp) {\n    var response = /** @type {!fireauth.StsTokenManager.ResponseData} */ (resp);\n    self.accessToken_ = fireauth.IdToken.parse(\n        response[fireauth.RpcHandler.StsServerField.ACCESS_TOKEN]);\n    self.refreshToken_ =\n        response[fireauth.RpcHandler.StsServerField.REFRESH_TOKEN];\n    return /** @type {!fireauth.StsTokenManager.Response} */ ({\n      'accessToken': self.accessToken_.toString(),\n      'refreshToken': self.refreshToken_\n    });\n  }).thenCatch(function(error) {\n    // Refresh token expired or user deleted. In this case, reset refresh token\n    // to prevent sending the request again to the STS server unless\n    // the token is manually updated, perhaps via successful reauthentication.\n    if (error['code'] == 'auth/user-token-expired') {\n      self.refreshToken_ = null;\n    }\n    throw error;\n  });\n};\n\n\n/** @return {boolean} Whether the refresh token is expired. */\nfireauth.StsTokenManager.prototype.isRefreshTokenExpired = function() {\n  return !!(this.accessToken_ && !this.refreshToken_);\n};\n\n\n/**\n * Returns an STS token. If the cached one is unexpired it is directly returned.\n * Otherwise the existing ID token or refresh token is exchanged for a new one.\n * If there is no user signed in, returns null.\n *\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n */\nfireauth.StsTokenManager.prototype.getToken = function(opt_forceRefresh) {\n  var self = this;\n  var forceRefresh = !!opt_forceRefresh;\n  // Refresh token is expired.\n  if (this.isRefreshTokenExpired()) {\n    return goog.Promise.reject(\n        new fireauth.AuthError(fireauth.authenum.Error.TOKEN_EXPIRED));\n  }\n  if (!forceRefresh && this.accessToken_ && !this.isExpired_()) {\n    // Cached STS access token not expired, return it.\n    return /** @type {!goog.Promise} */ (goog.Promise.resolve({\n      'accessToken': self.accessToken_.toString(),\n      'refreshToken': self.refreshToken_\n    }));\n  } else if (this.refreshToken_) {\n    // Expired but refresh token available, exchange refresh token for STS\n    // token.\n    return this.exchangeRefreshToken_();\n  } else {\n    // No token, return null token.\n    return goog.Promise.resolve(\n        /** @type {?fireauth.StsTokenManager.Response} */ (null));\n  }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the user info pertaining to an identity provider and\n * the Firebase user object.\n */\n\ngoog.provide('fireauth.AuthUser');\ngoog.provide('fireauth.AuthUser.AccountInfo');\ngoog.provide('fireauth.AuthUserInfo');\ngoog.provide('fireauth.TokenRefreshTime');\ngoog.provide('fireauth.UserMetadata');\n\ngoog.require('fireauth.ActionCodeSettings');\ngoog.require('fireauth.AdditionalUserInfo');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthEventHandler');\ngoog.require('fireauth.AuthEventManager');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.IdTokenResult');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.MultiFactorUser');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.ProactiveRefresh');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.StsTokenManager');\ngoog.require('fireauth.UserEvent');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.constants.AuthEventType');\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.object');\n\n\n\n/**\n * Initializes an instance of a user metadata object.\n * @param {?string=} opt_createdAt The optional creation date UTC timestamp.\n * @param {?string=} opt_lastLoginAt The optional last login date UTC timestamp.\n * @constructor\n */\nfireauth.UserMetadata = function(opt_createdAt, opt_lastLoginAt) {\n  /** @private {?string} The created at UTC timestamp. */\n  this.createdAt_ = opt_createdAt || null;\n  /** @private {?string} The last login at UTC timestamp. */\n  this.lastLoginAt_ = opt_lastLoginAt || null;\n  fireauth.object.setReadonlyProperties(this, {\n    'lastSignInTime': fireauth.util.utcTimestampToDateString(\n        opt_lastLoginAt || null),\n    'creationTime': fireauth.util.utcTimestampToDateString(\n        opt_createdAt || null),\n  });\n};\n\n\n/**\n * @return {!fireauth.UserMetadata} A clone of the current user metadata object.\n */\nfireauth.UserMetadata.prototype.clone = function() {\n  return new fireauth.UserMetadata(this.createdAt_, this.lastLoginAt_);\n};\n\n\n/**\n * @return {!Object} The object representation of the user metadata instance.\n */\nfireauth.UserMetadata.prototype.toPlainObject = function() {\n  return {\n    'lastLoginAt': this.lastLoginAt_,\n    'createdAt': this.createdAt_\n  };\n};\n\n\n/**\n * Initializes an instance of the user info for an identity provider.\n * @param {string} uid The user ID.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {?string=} opt_email The optional user email.\n * @param {?string=} opt_displayName The optional display name.\n * @param {?string=} opt_photoURL The optional photo URL.\n * @param {?string=} opt_phoneNumber The optional phone number.\n * @constructor\n */\nfireauth.AuthUserInfo = function(\n    uid,\n    providerId,\n    opt_email,\n    opt_displayName,\n    opt_photoURL,\n    opt_phoneNumber) {\n  fireauth.object.setReadonlyProperties(this, {\n    'uid': uid,\n    'displayName': opt_displayName || null,\n    'photoURL': opt_photoURL || null,\n    'email': opt_email || null,\n    'phoneNumber': opt_phoneNumber || null,\n    'providerId': providerId\n  });\n};\n\n\n/**\n * Defines the proactive token refresh time constraints in milliseconds.\n * @enum {number}\n */\nfireauth.TokenRefreshTime = {\n  /**\n   * The offset time before token natural expiration to run the refresh.\n   * This is currently 5 minutes.\n   */\n  OFFSET_DURATION: 5 * 60 * 1000,\n  /**\n   * This is the first retrial wait after an error. This is currently\n   * 30 seconds.\n   */\n  RETRIAL_MIN_WAIT: 30 * 1000,\n  /**\n   * This is the maximum retrial wait, currently 16 minutes.\n   */\n  RETRIAL_MAX_WAIT: 16 * 60 * 1000\n};\n\n\n\n/**\n * The Firebase user.\n * @param {!Object} appOptions The application options.\n * @param {!Object} stsTokenResponse The server STS token response.\n * @param {?Object=} opt_accountInfo The optional user account info.\n * @constructor\n * @extends {goog.events.EventTarget}\n * @implements {fireauth.AuthEventHandler}\n */\nfireauth.AuthUser =\n    function(appOptions, stsTokenResponse, opt_accountInfo) {\n  /** @private {!Array<!goog.Promise<*, *>|!goog.Promise<void>>} List of pending\n   *      promises. */\n  this.pendingPromises_ = [];\n  // User is only created via Auth so API key should always be available.\n  /** @private {string} The API key. */\n  this.apiKey_ = /** @type {string} */ (appOptions['apiKey']);\n  // This is needed to associate a user to the corresponding Auth instance.\n  /** @private {string} The App name. */\n  this.appName_ = /** @type {string} */ (appOptions['appName']);\n  /** @private {?string} The Auth domain. */\n  this.authDomain_ = appOptions['authDomain'] || null;\n  var clientFullVersion = firebase.SDK_VERSION ?\n      fireauth.util.getClientVersion(\n          fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION) :\n      null;\n  /** @private {!fireauth.RpcHandler} The RPC handler instance. */\n  this.rpcHandler_ = new fireauth.RpcHandler(\n      this.apiKey_,\n      // Get the client Auth endpoint used.\n      fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n      clientFullVersion);\n  // TODO: Consider having AuthUser take a fireauth.StsTokenManager\n  // instance instead of a token response but make sure lastAccessToken_ also\n  // initialized at the right time. In this case initializeFromIdTokenResponse\n  // will take in a token response object and convert it to an instance of\n  // fireauth.StsTokenManager to properly initialize user.\n  /** @private {!fireauth.StsTokenManager} The STS token manager instance. */\n  this.stsTokenManager_ = new fireauth.StsTokenManager(this.rpcHandler_);\n\n  this.setLastAccessToken_(\n      stsTokenResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n  // STS token manager will always be populated using server response.\n  this.stsTokenManager_.parseServerResponse(stsTokenResponse);\n  fireauth.object.setReadonlyProperty(\n      this, 'refreshToken', this.stsTokenManager_.getRefreshToken());\n  this.setAccountInfo(/** @type {!fireauth.AuthUser.AccountInfo} */ (\n      opt_accountInfo || {}));\n  // Add call to superclass constructor.\n  fireauth.AuthUser.base(this, 'constructor');\n  /** @private {boolean} Whether popup and redirect is enabled on the user. */\n  this.popupRedirectEnabled_ = false;\n  if (this.authDomain_ &&\n      fireauth.AuthEventManager.ENABLED &&\n      // Make sure popup and redirects are supported in the current environment.\n      fireauth.util.isPopupRedirectSupported()) {\n    // Get the Auth event manager associated with this user.\n    this.authEventManager_ = fireauth.AuthEventManager.getManager(\n        this.authDomain_, this.apiKey_, this.appName_);\n  }\n  /** @private {!Array<!function(!fireauth.AuthUser):!goog.Promise>} The list of\n   *      state change listeners. This is needed to make sure state changes are\n   *      resolved before resolving user API promises. For example redirect\n   *      operations should make sure the associated event ID is saved before\n   *      redirecting.\n   */\n  this.stateChangeListeners_ = [];\n  /**\n   * @private {?fireauth.AuthError} The user invalidation error if it exists.\n   */\n  this.userInvalidatedError_ = null;\n  /**\n   * @private {!fireauth.ProactiveRefresh} The reference to the proactive token\n   *     refresher utility for the current user.\n   */\n  this.proactiveRefresh_ = this.initializeProactiveRefreshUtility_();\n  /**\n   * @private {!function(!Object)} The handler for user token changes used to\n   *     realign the proactive token refresh with external token refresh calls.\n   */\n  this.userTokenChangeListener_ = goog.bind(this.handleUserTokenChange_, this);\n  var self = this;\n  /** @private {?string} The current user's language code. */\n  this.languageCode_ = null;\n  /**\n   * @private {function(!goog.events.Event)} The on language code changed event\n   *     handler.\n   */\n  this.onLanguageCodeChanged_ = function(event) {\n    // Update the user language code.\n    self.setLanguageCode(event.languageCode);\n  };\n  /**\n   * @private {?goog.events.EventTarget} The language code change event\n   *     dispatcher.\n   */\n  this.languageCodeChangeEventDispatcher_ = null;\n\n  /** @private {!Array<string>} The current Firebase frameworks. */\n  this.frameworks_ = [];\n  /**\n   * @private {function(!goog.events.Event)} The on framework list changed event\n   *     handler.\n   */\n  this.onFrameworkChanged_ = function(event) {\n    // Update the Firebase frameworks.\n    self.setFramework(event.frameworks);\n  };\n  /**\n   * @private {?goog.events.EventTarget} The framework change event dispatcher.\n   */\n  this.frameworkChangeEventDispatcher_ = null;\n  /**\n   * @const @private {!fireauth.MultiFactorUser} The multifactor user instance.\n   */\n  this.multiFactorUser_ = new fireauth.MultiFactorUser(\n      this, /** @type {?fireauth.AuthUser.AccountInfo|undefined} */ (\n          opt_accountInfo));\n  fireauth.object.setReadonlyProperty(\n      this, 'multiFactor', this.multiFactorUser_);\n};\ngoog.inherits(fireauth.AuthUser, goog.events.EventTarget);\n\n\n/**\n * Updates the user language code.\n * @param {?string} languageCode The current language code to use in user\n *     requests.\n */\nfireauth.AuthUser.prototype.setLanguageCode = function(languageCode) {\n  // Save current language.\n  this.languageCode_ = languageCode;\n  // Update the custom locale header.\n  this.rpcHandler_.updateCustomLocaleHeader(languageCode);\n};\n\n\n/** @return {?string} The current user's language code. */\nfireauth.AuthUser.prototype.getLanguageCode = function() {\n  return this.languageCode_;\n};\n\n\n/**\n * Listens to language code changes triggered by the provided dispatcher.\n * @param {?goog.events.EventTarget} dispatcher The language code changed event\n *     dispatcher.\n */\nfireauth.AuthUser.prototype.setLanguageCodeChangeDispatcher =\n    function(dispatcher) {\n  // Remove any previous listener.\n  if (this.languageCodeChangeEventDispatcher_) {\n    goog.events.unlisten(\n        this.languageCodeChangeEventDispatcher_,\n        fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED,\n        this.onLanguageCodeChanged_);\n  }\n  // Update current dispatcher.\n  this.languageCodeChangeEventDispatcher_ = dispatcher;\n  // Using an event listener makes it easy for non-currentUsers to detect\n  // language changes on the parent Auth instance. A developer could still call\n  // APIs that require localization on signed out user references.\n  if (dispatcher) {\n    goog.events.listen(\n        dispatcher,\n        fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED,\n        this.onLanguageCodeChanged_);\n  }\n};\n\n\n/**\n * Updates the Firebase frameworks on the current user.\n * @param {!Array<string>} framework The list of Firebase frameworks.\n */\nfireauth.AuthUser.prototype.setFramework = function(framework) {\n  // Save current frameworks.\n  this.frameworks_ = framework;\n  // Update the client version in RPC handler with the new frameworks.\n  this.rpcHandler_.updateClientVersion(firebase.SDK_VERSION ?\n        fireauth.util.getClientVersion(\n            fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n            this.frameworks_) :\n        null);\n};\n\n\n/** @return {!Array<string>} The current Firebase frameworks. */\nfireauth.AuthUser.prototype.getFramework = function() {\n  return goog.array.clone(this.frameworks_);\n};\n\n\n/**\n * Listens to framework changes triggered by the provided dispatcher.\n * @param {?goog.events.EventTarget} dispatcher The framework changed event\n *     dispatcher.\n */\nfireauth.AuthUser.prototype.setFrameworkChangeDispatcher =\n    function(dispatcher) {\n  // Remove any previous listener.\n  if (this.frameworkChangeEventDispatcher_) {\n    goog.events.unlisten(\n        this.frameworkChangeEventDispatcher_,\n        fireauth.constants.AuthEventType.FRAMEWORK_CHANGED,\n        this.onFrameworkChanged_);\n  }\n  // Update current dispatcher.\n  this.frameworkChangeEventDispatcher_ = dispatcher;\n  // Using an event listener makes it easy for non-currentUsers to detect\n  // framework changes on the parent Auth instance.\n  if (dispatcher) {\n    goog.events.listen(\n        dispatcher,\n        fireauth.constants.AuthEventType.FRAMEWORK_CHANGED,\n        this.onFrameworkChanged_);\n  }\n};\n\n\n/**\n * Handles user token changes. Currently used to realign the proactive token\n * refresh internal timing with successful external token refreshes.\n * @param {!Object} event The token change event.\n * @private\n */\nfireauth.AuthUser.prototype.handleUserTokenChange_ = function(event) {\n  // If an external service refreshes the token, reset the proactive token\n  // refresh utility in case it is still running so the next run time is\n  // up to date.\n  // This will currently also trigger when the proactive refresh succeeds.\n  // This is not ideal but should not have any downsides. It just adds a\n  // redundant reset which can be optimized not to run in the future.\n  if (this.proactiveRefresh_.isRunning()) {\n    this.proactiveRefresh_.stop();\n    this.proactiveRefresh_.start();\n  }\n};\n\n\n/**\n * @return {!fireauth.Auth} The corresponding Auth instance that created the\n *     current user.\n * @private\n */\nfireauth.AuthUser.prototype.getAuth_ = function() {\n  try {\n    // Get the Auth instance for the current app identified by the App name.\n    // This could fail if, for example, the App instance was deleted.\n    return firebase['app'](this.appName_)['auth']();\n  } catch (e) {\n    // Throw appropriate error.\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INTERNAL_ERROR,\n        'No firebase.auth.Auth instance is available for the Firebase App ' +\n        '\\'' + this.appName_ + '\\'!');\n  }\n};\n\n\n/**\n * @return {string} The user's API key.\n */\nfireauth.AuthUser.prototype.getApiKey = function() {\n  return this.apiKey_;\n};\n\n\n/**\n * Returns the RPC handler of the user.\n * @return {!fireauth.RpcHandler} The RPC handler.\n */\nfireauth.AuthUser.prototype.getRpcHandler = function() {\n  return this.rpcHandler_;\n};\n\n\n/**\n * Used to initialize the current user's proactive token refresher utility.\n * @return {!fireauth.ProactiveRefresh} The user's proactive token refresh\n *     utility.\n * @private\n */\nfireauth.AuthUser.prototype.initializeProactiveRefreshUtility_ = function() {\n  var self = this;\n  return new fireauth.ProactiveRefresh(\n      // Force ID token refresh right before expiration.\n      function() {\n        // Keep in mind when this fails for any reason other than a network\n        // error, it will effectively stop the proactive refresh.\n        return self.getIdToken(true);\n      },\n      // Retry only on network errors.\n      function(error) {\n        if (error && error.code == 'auth/network-request-failed') {\n          return true;\n        }\n        return false;\n      },\n      // Return next time to run with offset applied.\n      function() {\n        // Get time until expiration minus the refresh offset.\n        var waitInterval =\n            self.stsTokenManager_.getExpirationTime() - goog.now() -\n            fireauth.TokenRefreshTime.OFFSET_DURATION;\n        // Set to zero if wait interval is negative.\n        return waitInterval > 0 ? waitInterval : 0;\n      },\n      // Retrial minimum wait.\n      fireauth.TokenRefreshTime.RETRIAL_MIN_WAIT,\n      // Retrial maximum wait.\n      fireauth.TokenRefreshTime.RETRIAL_MAX_WAIT,\n      // Do not run in background as it is common to have multiple tabs open\n      // in a browser and this could increase QPS on server.\n      false);\n};\n\n\n/** Starts token proactive refresh. */\nfireauth.AuthUser.prototype.startProactiveRefresh = function() {\n  // Only allow if not destroyed and not already started.\n  if (!this.destroyed_ && !this.proactiveRefresh_.isRunning()) {\n    this.proactiveRefresh_.start();\n    // Unlisten any previous token change listener.\n    goog.events.unlisten(\n        this,\n        fireauth.UserEventType.TOKEN_CHANGED,\n        this.userTokenChangeListener_);\n    // Listen to token changes to reset the token refresher.\n    goog.events.listen(\n        this,\n        fireauth.UserEventType.TOKEN_CHANGED,\n        this.userTokenChangeListener_);\n  }\n};\n\n\n/** Stops token proactive refresh. */\nfireauth.AuthUser.prototype.stopProactiveRefresh = function() {\n  // Remove internal token change listener.\n  goog.events.unlisten(\n      this,\n      fireauth.UserEventType.TOKEN_CHANGED,\n      this.userTokenChangeListener_);\n  // Stop proactive token refresh.\n  this.proactiveRefresh_.stop();\n};\n\n\n/**\n * Sets latest access token for the AuthUser object.\n * @param {string} lastAccessToken\n * @private\n */\nfireauth.AuthUser.prototype.setLastAccessToken_ = function(lastAccessToken) {\n  /** @private {?string} Latest access token. */\n  this.lastAccessToken_ = lastAccessToken;\n  fireauth.object.setReadonlyProperty(this, '_lat', lastAccessToken);\n};\n\n\n/**\n * @param {function(!fireauth.AuthUser):!goog.Promise} listener The listener\n *     to state changes to add.\n */\nfireauth.AuthUser.prototype.addStateChangeListener = function(listener) {\n  this.stateChangeListeners_.push(listener);\n};\n\n\n/**\n * @param {function(!fireauth.AuthUser):!goog.Promise} listener The listener\n *     to state changes to remove.\n */\nfireauth.AuthUser.prototype.removeStateChangeListener = function(listener) {\n  goog.array.removeAllIf(this.stateChangeListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n\n\n/**\n * Executes all state change listener promises and when all fulfilled, resolves\n * with the current user.\n * @return {!goog.Promise} A promise that resolves when all state listeners\n *     fulfilled.\n * @private\n */\nfireauth.AuthUser.prototype.notifyStateChangeListeners_ = function() {\n  var promises = [];\n  var self = this;\n  for (var i = 0; i < this.stateChangeListeners_.length; i++) {\n    // Run listener with Auth user instance and add to list of promises.\n    promises.push(this.stateChangeListeners_[i](this));\n  }\n  return goog.Promise.allSettled(promises).then(function(results) {\n    // State change errors should be recoverable even if errors occur.\n    return self;\n  });\n};\n\n\n/**\n * Sets the user current pending popup event ID.\n * @param {string} eventId The pending popup event ID.\n */\nfireauth.AuthUser.prototype.setPopupEventId = function(eventId) {\n  // Saving a popup event in a separate property other than redirectEventId\n  // would prevent a pending redirect event from being overwritten by a newly\n  // called popup operation.\n  this.popupEventId_ = eventId;\n};\n\n\n/**\n * @return {?string} The pending popup event ID.\n */\nfireauth.AuthUser.prototype.getPopupEventId = function() {\n  return this.popupEventId_ || null;\n};\n\n\n/**\n * Sets the user current pending redirect event ID.\n * @param {string} eventId The pending redirect event ID.\n */\nfireauth.AuthUser.prototype.setRedirectEventId = function(eventId) {\n  this.redirectEventId_ = eventId;\n};\n\n\n/**\n * @return {?string} The pending redirect event ID.\n */\nfireauth.AuthUser.prototype.getRedirectEventId = function() {\n  return this.redirectEventId_ || null;\n};\n\n\n/**\n * Subscribes to Auth event manager to handle popup and redirect events.\n * This is an explicit operation as users could exist in temporary states. For\n * example a user change could be detected in another tab. When syncing to those\n * changes, a temporary user is retrieved from storage and then copied to\n * existing user. The temporary user should not subscribe to Auth event changes.\n */\nfireauth.AuthUser.prototype.enablePopupRedirect = function() {\n  // Subscribe to Auth event manager if available.\n  if (this.authEventManager_ && !this.popupRedirectEnabled_) {\n    this.popupRedirectEnabled_ = true;\n    this.authEventManager_.subscribe(this);\n  }\n};\n\n\n/**\n * getAccountInfo users field.\n * @const {string}\n */\nfireauth.AuthUser.GET_ACCOUNT_INFO_USERS = 'users';\n\n\n/**\n * getAccountInfo response user fields.\n * @enum {string}\n */\nfireauth.AuthUser.GetAccountInfoField = {\n  CREATED_AT: 'createdAt',\n  DISPLAY_NAME: 'displayName',\n  EMAIL: 'email',\n  EMAIL_VERIFIED: 'emailVerified',\n  LAST_LOGIN_AT: 'lastLoginAt',\n  LOCAL_ID: 'localId',\n  PASSWORD_HASH: 'passwordHash',\n  PASSWORD_UPDATED_AT: 'passwordUpdatedAt',\n  PHONE_NUMBER: 'phoneNumber',\n  PHOTO_URL: 'photoUrl',\n  PROVIDER_USER_INFO: 'providerUserInfo',\n  TENANT_ID: 'tenantId'\n};\n\n\n/**\n * setAccountInfo response user fields.\n * @enum {string}\n */\nfireauth.AuthUser.SetAccountInfoField = {\n  DISPLAY_NAME: 'displayName',\n  EMAIL: 'email',\n  PHOTO_URL: 'photoUrl',\n  PROVIDER_ID: 'providerId',\n  PROVIDER_USER_INFO: 'providerUserInfo'\n};\n\n\n/**\n * getAccountInfo response provider user info fields.\n * @enum {string}\n */\nfireauth.AuthUser.GetAccountInfoProviderField = {\n  DISPLAY_NAME: 'displayName',\n  EMAIL: 'email',\n  PHOTO_URL: 'photoUrl',\n  PHONE_NUMBER: 'phoneNumber',\n  PROVIDER_ID: 'providerId',\n  RAW_ID: 'rawId'\n};\n\n\n/**\n * verifyAssertion response fields.\n * @enum {string}\n */\nfireauth.AuthUser.VerifyAssertionField = {\n  ID_TOKEN: 'idToken',\n  PROVIDER_ID: 'providerId'\n};\n\n\n/** @return {!fireauth.StsTokenManager} The STS token manager instance */\nfireauth.AuthUser.prototype.getStsTokenManager = function() {\n  return this.stsTokenManager_;\n};\n\n\n/**\n * Sets the user account info.\n * @param {!fireauth.AuthUser.AccountInfo} accountInfo The account information\n *     from the default provider.\n */\nfireauth.AuthUser.prototype.setAccountInfo = function(accountInfo) {\n  fireauth.object.setReadonlyProperties(this, {\n    'uid': accountInfo['uid'],\n    'displayName': accountInfo['displayName'] || null,\n    'photoURL': accountInfo['photoURL'] || null,\n    'email': accountInfo['email'] || null,\n    'emailVerified': accountInfo['emailVerified'] || false,\n    'phoneNumber': accountInfo['phoneNumber'] || null,\n    'isAnonymous': accountInfo['isAnonymous'] || false,\n    'tenantId': accountInfo['tenantId'] || null,\n    'metadata': new fireauth.UserMetadata(\n        accountInfo['createdAt'], accountInfo['lastLoginAt']),\n    'providerData': []\n  });\n  // Sets the tenant ID on RPC handler. For requests with ID tokens, the source\n  // of truth is the tenant ID in the ID token. If the request body has a\n  // tenant ID (optional here), the backend will confirm it matches the\n  // tenant ID in the ID token, otherwise throw an error. If no tenant ID is\n  // passed in the request, it will be determined from the ID token.\n  this.rpcHandler_.updateTenantId(this['tenantId']);\n};\n\n\n/**\n * Type specifying the parameters that can be passed to the\n * {@code fireauth.AuthUser} constructor.\n * @typedef {{\n *   uid: (?string|undefined),\n *   displayName: (?string|undefined),\n *   photoURL: (?string|undefined),\n *   email: (?string|undefined),\n *   emailVerified: ?boolean,\n *   phoneNumber: (?string|undefined),\n *   isAnonymous: ?boolean,\n *   createdAt: (?string|undefined),\n *   lastLoginAt: (?string|undefined),\n *   tenantId: (?string|undefined),\n *   multiFactor: ({\n *     enrolledFactors: (?Array<!fireauth.MultiFactorInfo>|undefined)\n *   }|undefined)\n * }}\n */\nfireauth.AuthUser.AccountInfo;\n\n\n/**\n * The provider for all fireauth.AuthUser objects is 'firebase'.\n */\nfireauth.object.setReadonlyProperty(fireauth.AuthUser.prototype, 'providerId',\n    fireauth.idp.ProviderId.FIREBASE);\n\n\n/**\n * Returns nothing. This can be used to consume the output of a Promise.\n * @private\n */\nfireauth.AuthUser.returnNothing_ = function() {\n  // Return nothing. Intentionally left empty.\n};\n\n\n/**\n * Ensures the user is still logged in before moving to the next promise\n * resolution.\n * @return {!goog.Promise<undefined,undefined>}\n * @private\n */\nfireauth.AuthUser.prototype.checkDestroyed_ = function() {\n  var self = this;\n  return goog.Promise.resolve().then(function() {\n    if (self.destroyed_) {\n      throw new fireauth.AuthError(fireauth.authenum.Error.MODULE_DESTROYED);\n    }\n  });\n};\n\n\n/**\n * @return {!Array<!fireauth.idp.ProviderId>} The list of provider IDs.\n */\nfireauth.AuthUser.prototype.getProviderIds = function() {\n  return goog.array.map(this['providerData'], function(userInfo) {\n    return userInfo['providerId'];\n  });\n};\n\n\n/**\n * Adds the provided user info to list of providers' data.\n * @param {?fireauth.AuthUserInfo} providerData Provider data to store for user.\n */\nfireauth.AuthUser.prototype.addProviderData = function(providerData) {\n  if (!providerData) {\n    return;\n  }\n  this.removeProviderData(providerData['providerId']);\n  this['providerData'].push(providerData);\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The provider ID whose\n *     data should be removed.\n */\nfireauth.AuthUser.prototype.removeProviderData = function(providerId) {\n  goog.array.removeAllIf(this['providerData'], function(userInfo) {\n    return userInfo['providerId'] == providerId;\n  });\n};\n\n\n/**\n * @param {string} propName The property name to modify.\n * @param {?string|boolean} value The new value to set.\n */\nfireauth.AuthUser.prototype.updateProperty = function(propName, value) {\n  // User ID is required.\n  if (propName == 'uid' && !value) {\n    return;\n  }\n  if (this.hasOwnProperty(propName)) {\n    fireauth.object.setReadonlyProperty(this, propName, value);\n  }\n};\n\n\n/**\n * @param {!fireauth.AuthUser} otherUser The other user to compare to.\n * @return {boolean} True if both User objects have the same user ID.\n */\nfireauth.AuthUser.prototype.hasSameUserIdAs = function(otherUser) {\n  var thisId = this['uid'];\n  var thatId = otherUser['uid'];\n  if (thisId === undefined || thisId === null || thisId === '' ||\n      thatId === undefined || thatId === null || thatId === '') {\n    return false;\n  }\n  return thisId == thatId;\n};\n\n\n/**\n * Copies all properties and STS token manager instance from userToCopy to\n * current user without triggering any Auth state change or token change\n * listener.\n * @param {!fireauth.AuthUser} userToCopy The updated user to overwrite current\n *     user.\n */\nfireauth.AuthUser.prototype.copy = function(userToCopy) {\n  var self = this;\n  // Copy to self.\n  if (self == userToCopy) {\n    return;\n  }\n  fireauth.object.setReadonlyProperties(this, {\n    'uid': userToCopy['uid'],\n    'displayName': userToCopy['displayName'],\n    'photoURL': userToCopy['photoURL'],\n    'email': userToCopy['email'],\n    'emailVerified': userToCopy['emailVerified'],\n    'phoneNumber': userToCopy['phoneNumber'],\n    'isAnonymous': userToCopy['isAnonymous'],\n    'tenantId': userToCopy['tenantId'],\n    'providerData': []\n  });\n  // This should always be available but just in case there is a conflict with\n  // a user from an older version.\n  if (userToCopy['metadata']) {\n    fireauth.object.setReadonlyProperty(\n        this,\n        'metadata',\n        /** @type{!fireauth.UserMetadata} */ (userToCopy['metadata']).clone());\n  } else {\n    // User to copy has no metadata. Align with that.\n    fireauth.object.setReadonlyProperty(\n        this, 'metadata', new fireauth.UserMetadata());\n  }\n  goog.array.forEach(userToCopy['providerData'], function(userInfo) {\n    self.addProviderData(userInfo);\n  });\n  this.stsTokenManager_.copy(userToCopy.getStsTokenManager());\n  fireauth.object.setReadonlyProperty(\n      this, 'refreshToken', this.stsTokenManager_.getRefreshToken());\n  // Copy multi-factor info to current user.\n  // This should be backward compatible.\n  // If the userToCopy is loaded from an older version, multiFactorUser\n  // enrolled factors will be initialized empty and copied empty to current\n  // multiFactorUser.\n  this.multiFactorUser_.copy(userToCopy.multiFactorUser_);\n};\n\n\n/**\n * Set the Auth user redirect storage manager.\n * @param {?fireauth.storage.RedirectUserManager} redirectStorageManager The\n *     utility used to store or delete the user on redirect.\n */\nfireauth.AuthUser.prototype.setRedirectStorageManager =\n    function(redirectStorageManager) {\n  /**\n   * @private {?fireauth.storage.RedirectUserManager} The redirect user storage\n   *     manager.\n   */\n  this.redirectStorageManager_ = redirectStorageManager;\n};\n\n\n/**\n * Refreshes the current user, if signed in.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.reload = function() {\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(this.checkDestroyed_().then(function() {\n    return self.reloadWithoutSaving_()\n        .then(function() {\n          return self.notifyStateChangeListeners_();\n        })\n        .then(fireauth.AuthUser.returnNothing_);\n  }));\n};\n\n\n/**\n * Refreshes the current user, if signed in.\n * @return {!goog.Promise<string>} Promise that resolves with the idToken.\n * @private\n */\nfireauth.AuthUser.prototype.reloadWithoutSaving_ = function() {\n  var self = this;\n  // ID token is required to refresh the user's data.\n  // If this is called after invalidation, getToken will throw the cached error.\n  return this.getIdToken().then(function(idToken) {\n    var isAnonymous = self['isAnonymous'];\n    return self.setUserAccountInfoFromToken_(idToken)\n        .then(function(user) {\n          if (!isAnonymous) {\n            // Preserves the not anonymous status of the stored user,\n            // even if no more credentials (federated or email/password)\n            // linked to the user.\n            self.updateProperty('isAnonymous', false);\n          }\n          return idToken;\n        });\n  });\n};\n\n\n/**\n * This operation resolves with the Firebase ID token result which contains\n * the entire payload claims.\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<!fireauth.IdTokenResult>} A Promise that resolves with\n *     the ID token result.\n */\nfireauth.AuthUser.prototype.getIdTokenResult = function(opt_forceRefresh) {\n  return this.getIdToken(opt_forceRefresh).then(function(idToken) {\n    return new fireauth.IdTokenResult(idToken);\n  });\n};\n\n\n/**\n * This operation resolves with the Firebase ID token.\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<string>} A Promise that resolves with the ID token.\n */\nfireauth.AuthUser.prototype.getIdToken = function(opt_forceRefresh) {\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(this.checkDestroyed_().then(function() {\n    return self.stsTokenManager_.getToken(opt_forceRefresh);\n  }).then(function(response) {\n    if (!response) {\n      // If the user exists, the token manager should be initialized.\n      throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n    }\n    // Only if the access token is refreshed, notify Auth listeners.\n    if (response['accessToken'] != self.lastAccessToken_) {\n      self.setLastAccessToken_(response['accessToken']);\n      // Auth state change, notify listeners.\n      self.notifyAuthListeners_();\n    }\n    self.updateProperty('refreshToken', response['refreshToken']);\n    return response['accessToken'];\n  }));\n};\n\n\n/**\n * Checks if the error corresponds to a user invalidation action.\n * @param {*} error The error returned by a user operation.\n * @return {boolean} Whether the user is invalidated based on the error\n *     provided.\n * @private\n */\nfireauth.AuthUser.isUserInvalidated_ = function(error) {\n  return !!(error &&\n      (error.code == 'auth/user-disabled' ||\n       error.code == 'auth/user-token-expired'));\n};\n\n\n/**\n * Updates the current tokens using a server response, if new tokens are\n * present and are different from the current ones, and notify the Auth\n * listeners.\n * @param {!Object} response The response from the server.\n */\nfireauth.AuthUser.prototype.updateTokensIfPresent = function(response) {\n  if (response[fireauth.RpcHandler.AuthServerField.ID_TOKEN] &&\n      this.lastAccessToken_ != response[\n          fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n    this.stsTokenManager_.parseServerResponse(response);\n    this.notifyAuthListeners_();\n    this.setLastAccessToken_(response[\n        fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n    // Update refresh token property.\n    this.updateProperty(\n        'refreshToken', this.stsTokenManager_.getRefreshToken());\n  }\n};\n\n\n/**\n * Called internally on Auth (access token) changes to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyAuthListeners_ = function() {\n  this.dispatchEvent(\n      new fireauth.UserEvent(fireauth.UserEventType.TOKEN_CHANGED));\n};\n\n\n/**\n * Called internally on user deletion to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyUserDeletedListeners_ = function() {\n  this.dispatchEvent(\n      new fireauth.UserEvent(fireauth.UserEventType.USER_DELETED));\n};\n\n\n/**\n * Called internally on user session invalidation to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyUserInvalidatedListeners_ = function() {\n  this.dispatchEvent(\n      new fireauth.UserEvent(fireauth.UserEventType.USER_INVALIDATED));\n};\n\n\n/**\n * Queries the backend using the provided ID token for all linked accounts to\n * build the Firebase user object.\n * @param {string} idToken The ID token string.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.AuthUser.prototype.setUserAccountInfoFromToken_ = function(idToken) {\n  return this.rpcHandler_.getAccountInfoByIdToken(idToken)\n      .then(goog.bind(this.parseAccountInfo_, this));\n};\n\n\n/**\n * Parses the response from the getAccountInfo endpoint.\n * @param {!Object} resp The backend response.\n * @private\n */\nfireauth.AuthUser.prototype.parseAccountInfo_ = function(resp) {\n  var users = resp[fireauth.AuthUser.GET_ACCOUNT_INFO_USERS];\n  if (!users || !users.length) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  var user = users[0];\n  var accountInfo = /** @type {!fireauth.AuthUser.AccountInfo} */ ({\n    'uid': /** @type {string} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.LOCAL_ID]),\n    'displayName': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.DISPLAY_NAME]),\n    'photoURL': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.PHOTO_URL]),\n    'email': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.EMAIL]),\n    'emailVerified':\n        !!user[fireauth.AuthUser.GetAccountInfoField.EMAIL_VERIFIED],\n    'phoneNumber': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.PHONE_NUMBER]),\n    'lastLoginAt': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.LAST_LOGIN_AT]),\n    'createdAt': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.CREATED_AT]),\n    'tenantId': /** @type {?string|undefined} */ (\n        user[fireauth.AuthUser.GetAccountInfoField.TENANT_ID])\n  });\n  this.setAccountInfo(accountInfo);\n  var linkedAccounts = this.extractLinkedAccounts_(user);\n  for (var i = 0; i < linkedAccounts.length; i++) {\n    this.addProviderData(linkedAccounts[i]);\n  }\n  // Sets the isAnonymous flag based on email, passwordHash and providerData.\n  var isAnonymous = !(this['email'] &&\n      user[fireauth.AuthUser.GetAccountInfoField.PASSWORD_HASH]) &&\n      !(this['providerData'] && this['providerData'].length);\n  this.updateProperty('isAnonymous', isAnonymous);\n  // Notify external listeners of the reload.\n  this.dispatchEvent(new fireauth.UserEvent(\n      fireauth.UserEventType.USER_RELOADED,\n      {userServerResponse: user}));\n};\n\n\n/**\n * Extracts the linked accounts from getAccountInfo response and returns an\n * array of corresponding provider data.\n * @param {!Object} resp The response object.\n * @return {!Array<!fireauth.AuthUserInfo>} The linked accounts.\n * @private\n */\nfireauth.AuthUser.prototype.extractLinkedAccounts_ = function(resp) {\n  var providerInfo =\n      resp[fireauth.AuthUser.GetAccountInfoField.PROVIDER_USER_INFO];\n  if (!providerInfo || !providerInfo.length) {\n    return [];\n  }\n\n  return goog.array.map(providerInfo, function(info) {\n    return new fireauth.AuthUserInfo(\n        info[fireauth.AuthUser.GetAccountInfoProviderField.RAW_ID],\n        info[fireauth.AuthUser.GetAccountInfoProviderField.PROVIDER_ID],\n        info[fireauth.AuthUser.GetAccountInfoProviderField.EMAIL],\n        info[fireauth.AuthUser.GetAccountInfoProviderField.DISPLAY_NAME],\n        info[fireauth.AuthUser.GetAccountInfoProviderField.PHOTO_URL],\n        info[fireauth.AuthUser.GetAccountInfoProviderField.PHONE_NUMBER]);\n  });\n};\n\n\n/**\n * Reauthenticates a user using a fresh credential, to be used before operations\n * such as updatePassword that require tokens from recent login attempts. It\n * also returns any additional user info data or credentials returned form the\n * backend. It has been deprecated in favor of reauthenticateWithCredential.\n * @param {!fireauth.AuthCredential} credential\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateAndRetrieveDataWithCredential =\n    function(credential) {\n  fireauth.deprecation.log(\n      fireauth.deprecation.Deprecations.REAUTH_WITH_CREDENTIAL);\n  return this.reauthenticateWithCredential(credential);\n};\n\n\n/**\n * Reauthenticates a user using a fresh credential, to be used before operations\n * such as updatePassword that require tokens from recent login attempts. It\n * also returns any additional user info data or credentials returned form the\n * backend.\n * @param {!fireauth.AuthCredential} credential\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithCredential =\n    function(credential) {\n  var self = this;\n  var userCredential = null;\n  // Register this pending promise but bypass user invalidation check.\n  return this.registerPendingPromise_(\n      // Match ID token from credential with the current user UID.\n      credential.matchIdTokenWithUid(this.rpcHandler_, this['uid'])\n      .then(function(response) {\n        // If the credential is valid and matches the current user ID, then\n        // update the tokens accordingly.\n        self.updateTokensIfPresent(response);\n        // Get user credential.\n        userCredential = self.getUserCredential_(\n            response, fireauth.constants.OperationType.REAUTHENTICATE);\n        // This could potentially validate an invalidated user. This happens in\n        // the case a password reset was applied. The refresh token is expired.\n        // Reauthentication should revalidate the user.\n        // User would remain non current if already signed out, but should be\n        // enabled again.\n        self.userInvalidatedError_ = null;\n        return self.reload();\n      }).then(function() {\n        // Return user credential after reauthenticated user is reloaded.\n        return userCredential;\n      }),\n      // Skip invalidation check as reauthentication could revalidate a user.\n      true);\n};\n\n\n/**\n * Reloads the user and then checks if a provider is already linked. If so,\n * this returns a Promise that rejects. Note that state change listeners are not\n * notified on success, so that operations using this can make changes and then\n * do one final listener notification.\n * @param {string} providerId\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.checkIfAlreadyLinked_ =\n    function(providerId) {\n  var self = this;\n  // Reload first in case the user was updated elsewhere.\n  return this.reloadWithoutSaving_()\n      .then(function() {\n        if (goog.array.contains(self.getProviderIds(), providerId)) {\n          return self.notifyStateChangeListeners_()\n              .then(function() {\n                  throw new fireauth.AuthError(\n                      fireauth.authenum.Error.PROVIDER_ALREADY_LINKED);\n              });\n        }\n      });\n};\n\n\n/**\n * Links a provider to the current user and returns any additional user info\n * data or credentials returned form the backend. It has been deprecated in\n * favor of linkWithCredential.\n * @param {!fireauth.AuthCredential} credential The credential from the Auth\n *     provider.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkAndRetrieveDataWithCredential =\n    function(credential) {\n  fireauth.deprecation.log(\n      fireauth.deprecation.Deprecations.LINK_WITH_CREDENTIAL);\n  return this.linkWithCredential(credential);\n};\n\n\n/**\n * Links a provider to the current user and returns any additional user info\n * data or credentials returned form the backend.\n * @param {!fireauth.AuthCredential} credential The credential from the Auth\n *     provider.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkWithCredential = function(credential) {\n  var self = this;\n  var userCredential = null;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      this.checkIfAlreadyLinked_(credential['providerId'])\n      .then(function() {\n        return self.getIdToken();\n      })\n      .then(function(idToken) {\n        return credential.linkToIdToken(self.rpcHandler_, idToken);\n      })\n      .then(function(response) {\n        // Get user credential.\n        userCredential = self.getUserCredential_(\n            response, fireauth.constants.OperationType.LINK);\n        // Finalize linking.\n        return self.finalizeLinking_(response);\n      })\n      .then(function(user) {\n        // Return user credential after finalizing linking.\n        return userCredential;\n      })\n  );\n};\n\n\n/**\n * Links a phone number using the App verifier instance and returns a\n * promise that resolves with the confirmation result which on confirmation\n * will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n *     verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.AuthUser.prototype.linkWithPhoneNumber =\n    function(phoneNumber, appVerifier) {\n  var self = this;\n  return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n      this.registerPendingPromise_(\n          // Check if linked already. If so, throw an error.\n          // This is redundant but is needed to prevent the need to send the\n          // SMS (worth the cost).\n          this.checkIfAlreadyLinked_(fireauth.idp.ProviderId.PHONE)\n              .then(function() {\n                return fireauth.ConfirmationResult.initialize(\n                    self.getAuth_(),\n                    phoneNumber,\n                    appVerifier,\n                    // This will check again if the credential is linked.\n                    goog.bind(self.linkWithCredential, self));\n              })));\n};\n\n\n/**\n * Reauthenticates a user with a phone number using the App verifier instance\n * and returns a promise that resolves with the confirmation result which on\n * confirmation will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n *     verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithPhoneNumber =\n    function(phoneNumber, appVerifier) {\n  var self = this;\n  return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n      this.registerPendingPromise_(\n          // Wrap this operation in a Promise since self.getAuth_() may throw an\n          // error synchronously.\n          goog.Promise.resolve().then(function() {\n            return fireauth.ConfirmationResult.initialize(\n                // Get corresponding Auth instance.\n                self.getAuth_(),\n                phoneNumber,\n                appVerifier,\n                goog.bind(self.reauthenticateWithCredential,\n                    self));\n          }),\n          // Skip invalidation check as reauthentication could revalidate a\n          // user.\n          true));\n};\n\n\n/**\n * Converts an ID token response (eg. verifyAssertion) to a UserCredential\n * object.\n * @param {!Object} idTokenResponse The ID token response.\n * @param {!fireauth.constants.OperationType} operationType The operation type\n *     to set in the user credential.\n * @return {!fireauth.AuthEventManager.Result} The UserCredential object\n *     constructed from the response.\n * @private\n */\nfireauth.AuthUser.prototype.getUserCredential_ =\n    function(idTokenResponse, operationType) {\n  // Get credential if available in the response.\n  var credential = fireauth.AuthProvider.getCredentialFromResponse(\n      idTokenResponse);\n  // Get additional user info data if available in the response.\n  var additionalUserInfo = fireauth.AdditionalUserInfo.fromPlainObject(\n      idTokenResponse);\n  // Return the readonly copy of the user credential object.\n  return fireauth.object.makeReadonlyCopy({\n    // Return the current user reference.\n    'user': this,\n    // Return any credential passed from the backend.\n    'credential': credential,\n    // Return any additional IdP data passed from the backend.\n    'additionalUserInfo': additionalUserInfo,\n    // Return the operation type in the user credential object.\n    'operationType': operationType\n  });\n};\n\n\n/**\n * Finalizes a linking flow, updating idToken and user's data using the\n * RPC linking response.\n * @param {!Object} response The RPC linking response.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n * @private\n */\nfireauth.AuthUser.prototype.finalizeLinking_ = function(response) {\n  // The response may contain a new access token,\n  // so we should update them just like a new sign in.\n  this.updateTokensIfPresent(response);\n  // This will take care of saving the updated state.\n  var self = this;\n  return this.reload().then(function() {\n    return self;\n  });\n};\n\n\n/**\n * Updates the user's email.\n * @param {string} newEmail The new email.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updateEmail = function(newEmail) {\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(this.getIdToken()\n      .then(function(idToken) {\n        return self.rpcHandler_.updateEmail(idToken, newEmail);\n      })\n      .then(function(response) {\n        // Calls to SetAccountInfo may invalidate old tokens.\n        self.updateTokensIfPresent(response);\n        // Reloads the user to update emailVerified.\n        return self.reload();\n      }));\n};\n\n\n/**\n * Updates the user's phone number.\n * @param {!fireauth.PhoneAuthCredential} phoneCredential\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updatePhoneNumber = function(phoneCredential) {\n  var self = this;\n  return this.registerPendingPromise_(this.getIdToken()\n      .then(function(idToken) {\n        // The backend always overwrites the existing phone number during a\n        // link operation.\n        return phoneCredential.linkToIdToken(self.rpcHandler_, idToken);\n      })\n      .then(function(response) {\n        self.updateTokensIfPresent(response);\n        return self.reload();\n      }));\n};\n\n\n/**\n * Updates the user's password.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updatePassword = function(newPassword) {\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      this.getIdToken()\n      .then(function(idToken) {\n        return self.rpcHandler_.updatePassword(idToken, newPassword);\n      })\n      .then(function(response) {\n        self.updateTokensIfPresent(response);\n        // Reloads the user in case email has also been updated and the user\n        // was anonymous.\n        return self.reload();\n      }));\n};\n\n\n/**\n * Updates the user's profile data.\n * @param {!Object} profile The profile data to update.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.AuthUser.prototype.updateProfile = function(profile) {\n  if (profile['displayName'] === undefined &&\n      profile['photoURL'] === undefined) {\n    // No change, directly return.\n    return this.checkDestroyed_();\n  }\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      this.getIdToken().then(function(idToken) {\n        // Translate the request into one that the backend accepts.\n        var profileRequest = {\n          'displayName': profile['displayName'],\n          'photoUrl': profile['photoURL']\n        };\n        return self.rpcHandler_.updateProfile(idToken, profileRequest);\n      })\n      .then(function(response) {\n        // Calls to SetAccountInfo may invalidate old tokens.\n        self.updateTokensIfPresent(response);\n        // Update properties.\n        self.updateProperty('displayName',\n            response[fireauth.AuthUser.SetAccountInfoField.DISPLAY_NAME] ||\n            null);\n        self.updateProperty('photoURL',\n            response[fireauth.AuthUser.SetAccountInfoField.PHOTO_URL] || null);\n        goog.array.forEach(self['providerData'], function(userInfo) {\n          // Check if password provider is linked.\n          if (userInfo['providerId'] === fireauth.idp.ProviderId.PASSWORD) {\n            // If so, update both fields in that provider.\n            fireauth.object.setReadonlyProperty(\n                userInfo, 'displayName', self['displayName']);\n            fireauth.object.setReadonlyProperty(\n                userInfo, 'photoURL', self['photoURL']);\n          }\n        });\n        // Notify changes and resolve.\n        return self.notifyStateChangeListeners_();\n      })\n      .then(fireauth.AuthUser.returnNothing_));\n};\n\n\n/**\n * Unlinks a provider from an account.\n * @param {!fireauth.idp.ProviderId} providerId The ID of the provider to\n *     unlink.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n */\nfireauth.AuthUser.prototype.unlink = function(providerId) {\n  var self = this;\n  // Make sure we have updated user providers to avoid removing a linked\n  // provider that hasn't been updated in current copy of user.\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      this.reloadWithoutSaving_()\n      .then(function(idToken) {\n        // Provider already unlinked.\n        if (!goog.array.contains(self.getProviderIds(), providerId)) {\n          return self.notifyStateChangeListeners_()\n              .then(function() {\n                throw new fireauth.AuthError(\n                    fireauth.authenum.Error.NO_SUCH_PROVIDER);\n              });\n        }\n        // We delete the providerId given.\n        return self.rpcHandler_\n            .deleteLinkedAccounts(idToken, [providerId])\n            .then(function(resp) {\n              // Construct the set of provider IDs returned by server.\n              var remainingProviderIds = {};\n              var userInfo = resp[fireauth.AuthUser.SetAccountInfoField.\n                  PROVIDER_USER_INFO] || [];\n              goog.array.forEach(userInfo, function(obj) {\n                remainingProviderIds[\n                    obj[fireauth.AuthUser.SetAccountInfoField.PROVIDER_ID]] =\n                    true;\n              });\n\n              // Remove all provider data objects where the provider ID no\n              // longer exists in this user.\n              goog.array.forEach(self.getProviderIds(), function(pId) {\n                if (!remainingProviderIds[pId]) {\n                  // This provider no longer linked, remove it from user.\n                  self.removeProviderData(pId);\n                }\n              });\n\n              // Remove the phone number if the phone provider was unlinked.\n              if (!remainingProviderIds[fireauth.PhoneAuthProvider[\n                      'PROVIDER_ID']]) {\n                fireauth.object.setReadonlyProperty(self, 'phoneNumber', null);\n              }\n\n              return self.notifyStateChangeListeners_();\n            });\n      }));\n};\n\n\n/**\n * Deletes the user, triggering an Auth token change if successful.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.delete = function() {\n  // Notice the way of declaring the method, it's to avoid a weird bug on IE8.\n  var self = this;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      this.getIdToken()\n      .then(function(idToken) {\n        return self.rpcHandler_.deleteAccount(idToken);\n      })\n      .then(function() {\n        self.notifyUserDeletedListeners_();\n      }))\n      .then(function() {\n        // Destroying after the registered promise is handled ensures it won't\n        // be canceled.\n        self.destroy();\n      });\n};\n\n\n/**\n * Tells the Auth event manager if this user is the owner of a detected Auth\n * event. A user can handle linkWithPopup and linkWithRedirect operations.\n * In addition, the event ID should match the user's event IDs.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n *     redirect).\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the Auth event handler can handler the provided\n *     event.\n * @override\n */\nfireauth.AuthUser.prototype.canHandleAuthEvent = function(mode, opt_eventId) {\n  if (mode == fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n      this.getPopupEventId() == opt_eventId &&\n      this.pendingPopupResolvePromise_) {\n    // The link via popup event's ID matches the user's popup event ID which\n    // makes this user the owner of this event.\n    return true;\n  } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_POPUP &&\n      this.getPopupEventId() == opt_eventId &&\n      this.pendingPopupResolvePromise_) {\n    // The reauth via popup event's ID matches the user's popup event ID which\n    // makes this user the owner of this event.\n    return true;\n  } else if (mode == fireauth.AuthEvent.Type.LINK_VIA_REDIRECT &&\n             this.getRedirectEventId() == opt_eventId) {\n    // The link via redirect event's ID matches the user's redirect event ID\n    // which makes this user the owner of this event.\n    return true;\n  } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT &&\n             this.getRedirectEventId() == opt_eventId) {\n    // The reauth via redirect event's ID matches the user's redirect event ID\n    // which makes this user the owner of this event.\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n *     redirect).\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n *     to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n * @override\n */\nfireauth.AuthUser.prototype.resolvePendingPopupEvent =\n    function(mode, popupRedirectResult, error, opt_eventId) {\n  // Only handles popup events with event IDs that match a pending popup ID.\n  if ((mode != fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n       mode != fireauth.AuthEvent.Type.REAUTH_VIA_POPUP) ||\n      opt_eventId != this.getPopupEventId()) {\n    return;\n  }\n  if (error && this.pendingPopupRejectPromise_) {\n    // Reject with error for supplied mode.\n    this.pendingPopupRejectPromise_(error);\n  } else if (popupRedirectResult &&\n             !error &&\n             this.pendingPopupResolvePromise_) {\n    // Resolve with result for supplied mode.\n    this.pendingPopupResolvePromise_(popupRedirectResult);\n  }\n  // Now that event is resolved, delete timeout promise.\n  if (this.popupTimeoutPromise_) {\n    this.popupTimeoutPromise_.cancel();\n    this.popupTimeoutPromise_ = null;\n  }\n  // Delete pending promises.\n  delete this.pendingPopupResolvePromise_;\n  delete this.pendingPopupRejectPromise_;\n};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher. Can handle link or reauth events that match existing event IDs.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n *     redirect).\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n *     ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @override\n */\nfireauth.AuthUser.prototype.getAuthEventHandlerFinisher =\n    function(mode, opt_eventId) {\n  if (mode == fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n      opt_eventId == this.getPopupEventId()) {\n    // Link with popup ID matches popup event ID.\n    return goog.bind(this.finishPopupAndRedirectLink, this);\n  } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_POPUP &&\n      opt_eventId == this.getPopupEventId()) {\n    // Reauth with popup ID matches popup event ID.\n    return goog.bind(this.finishPopupAndRedirectReauth, this);\n  } else if (mode == fireauth.AuthEvent.Type.LINK_VIA_REDIRECT &&\n             this.getRedirectEventId() == opt_eventId) {\n    // Link with redirect ID matches redirect event ID.\n    return goog.bind(this.finishPopupAndRedirectLink, this);\n  } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT &&\n             this.getRedirectEventId() == opt_eventId) {\n    // Reauth with redirect ID matches redirect event ID.\n    return goog.bind(this.finishPopupAndRedirectReauth, this);\n  }\n  return null;\n};\n\n\n/**\n * @return {string} The generated event ID used to identify a popup or redirect\n *     event.\n * @private\n */\nfireauth.AuthUser.prototype.generateEventId_ = function() {\n  return fireauth.util.generateEventId(this['uid'] + ':::');\n};\n\n\n/**\n * Links to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkWithPopup = function(provider) {\n  var self = this;\n  // Additional check to return to fail when the provider is already linked.\n  var additionalCheck = function() {\n    return self.checkIfAlreadyLinked_(provider['providerId'])\n        .then(function() {\n          // Notify state listeners after the check as it will update the user\n          // state.\n          return self.notifyStateChangeListeners_();\n        });\n  };\n  return this.runOperationWithPopup_(\n      fireauth.AuthEvent.Type.LINK_VIA_POPUP, provider, additionalCheck, false);\n};\n\n\n/**\n * Reauthenticate to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithPopup = function(provider) {\n  // No additional check needed before running this operation.\n  var additionalCheck = function() {\n    return goog.Promise.resolve();\n  };\n  return this.runOperationWithPopup_(\n      fireauth.AuthEvent.Type.REAUTH_VIA_POPUP,\n      provider,\n      additionalCheck,\n      // Do not update token and skip session invalidation check.\n      true);\n};\n\n\n/**\n * Runs a specific OAuth operation using the Auth provider via popup.\n * @param {!fireauth.AuthEvent.Type} mode The mode of operation (link or\n *     reauth).\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function():!goog.Promise} additionalCheck The additional check to\n *     run before proceeding with the popup processing.\n * @param {boolean} isReauthOperation whether this is a reauth operation or not.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.AuthUser.prototype.runOperationWithPopup_ =\n    function(mode, provider, additionalCheck, isReauthOperation) {\n  // Check if popup and redirect are supported in this environment.\n  if (!fireauth.util.isPopupRedirectSupported()) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  // Quickly throw user invalidation error if already invalidated.\n  if (this.userInvalidatedError_ &&\n      // Skip invalidation check as reauthentication could revalidate a user.\n      !isReauthOperation) {\n    return goog.Promise.reject(this.userInvalidatedError_);\n  }\n  var self = this;\n  // Popup the window immediately to make sure the browser associates the\n  // popup with the click that triggered it.\n\n  // Get provider settings.\n  var settings = fireauth.idp.getIdpSettings(provider['providerId']);\n  // There could multiple users at the same time and multiple users could have\n  // the same UID. So try to ensure event ID uniqueness.\n  var eventId = this.generateEventId_();\n  // If incapable of redirecting popup from opener, popup destination URL\n  // directly. This could also happen in a sandboxed iframe.\n  var oauthHelperWidgetUrl = null;\n  if ((!fireauth.util.runsInBackground() || fireauth.util.isIframe()) &&\n      this.authDomain_ &&\n      provider['isOAuthProvider']) {\n    oauthHelperWidgetUrl =\n        fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n            this.authDomain_,\n            this.apiKey_,\n            this.appName_,\n            mode,\n            provider,\n            null,\n            eventId,\n            firebase.SDK_VERSION || null,\n            null,\n            null,\n            this['tenantId']);\n  }\n  // The popup must have a name, otherwise when successive popups are triggered\n  // they will all render in the same instance and none will succeed since the\n  // popup cancel of first window will close the shared popup window instance.\n  var popupWin =\n      fireauth.util.popup(\n          oauthHelperWidgetUrl,\n          fireauth.util.generateRandomString(),\n          settings && settings.popupWidth,\n          settings && settings.popupHeight);\n  var p = additionalCheck().then(function() {\n    // Auth event manager must be available for account linking or\n    // reauthentication to be possible.\n    self.getAuthEventManager();\n    if (!isReauthOperation) {\n      // Some operations like reauthenticate do not require this.\n      return self.getIdToken().then(function(idToken) {});\n    }\n  }).then(function() {\n    // Process popup request.\n    return self.authEventManager_.processPopup(\n        popupWin, mode, provider, eventId, !!oauthHelperWidgetUrl,\n        self['tenantId']);\n  }).then(function() {\n    return new goog.Promise(function(resolve, reject) {\n      // Expire other pending promises if still available.\n      self.resolvePendingPopupEvent(\n          mode,\n          null,\n          new fireauth.AuthError(fireauth.authenum.Error.EXPIRED_POPUP_REQUEST),\n          // Existing popup event ID.\n          self.getPopupEventId());\n      // Save current pending promises.\n      self.pendingPopupResolvePromise_ = resolve;\n      self.pendingPopupRejectPromise_ = reject;\n      // Overwrite popup event ID with new one.\n      self.setPopupEventId(eventId);\n      // Keep track of timeout promise to cancel it on promise resolution before\n      // it times out.\n      self.popupTimeoutPromise_ =\n          self.authEventManager_.startPopupTimeout(\n              self, mode, /** @type {!Window} */ (popupWin), eventId);\n    });\n  }).then(function(result) {\n    // On resolution, close popup if still opened and pass result through.\n    if (popupWin) {\n      fireauth.util.closeWindow(popupWin);\n    }\n    if (result) {\n      return fireauth.object.makeReadonlyCopy(result);\n    }\n    return null;\n  }).thenCatch(function(error) {\n    if (popupWin) {\n      fireauth.util.closeWindow(popupWin);\n    }\n    throw error;\n  });\n  // Register this pending promise. This will also check for user invalidation.\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(\n          p,\n          // Skip invalidation check as reauthentication could revalidate a\n          // user.\n          isReauthOperation));\n};\n\n\n/**\n * Links to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.linkWithRedirect = function(provider) {\n  var mode = fireauth.AuthEvent.Type.LINK_VIA_REDIRECT;\n  var self = this;\n  // Additional check to return to fail when the provider is already linked.\n  var additionalCheck = function() {\n    return self.checkIfAlreadyLinked_(provider['providerId']);\n  };\n  return this.runOperationWithRedirect_(mode, provider, additionalCheck, false);\n};\n\n\n/**\n * Reauthenticates to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithRedirect = function(provider) {\n  // No additional check needed.\n  var additionalCheck = function() {\n    return goog.Promise.resolve();\n  };\n  return this.runOperationWithRedirect_(\n      fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT,\n      provider,\n      additionalCheck,\n      // Do not update token and skip session invalidation check.\n      true);\n};\n\n\n\n/**\n * Runs a specific OAuth operation using the Auth provider via redirect.\n * @param {!fireauth.AuthEvent.Type} mode The mode of operation (link or\n *     reauth).\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function():!goog.Promise} additionalCheck The additional check to\n *     run before proceeding with the redirect processing.\n * @param {boolean} isReauthOperation whether this is a reauth operation or not.\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.runOperationWithRedirect_ =\n    function(mode, provider, additionalCheck, isReauthOperation) {\n  // Check if popup and redirect are supported in this environment.\n  if (!fireauth.util.isPopupRedirectSupported()) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  // Quickly throw user invalidation error if already invalidated.\n  if (this.userInvalidatedError_ &&\n      // Skip invalidation check as reauthentication could revalidate a user.\n      !isReauthOperation) {\n    return goog.Promise.reject(this.userInvalidatedError_);\n  }\n  var self = this;\n  var errorThrown = null;\n  // There could multiple users at the same time and multiple users could have\n  // the same UID. So try to ensure event ID uniqueness.\n  var eventId = this.generateEventId_();\n  var p = additionalCheck().then(function() {\n    // Auth event manager must be available for account linking or\n    // reauthentication to be possible.\n    self.getAuthEventManager();\n    if (!isReauthOperation) {\n      // Some operations like reauthenticate do not require this.\n      return self.getIdToken().then(function(idToken) {});\n    }\n  }).then(function() {\n    // Process redirect operation.\n    self.setRedirectEventId(eventId);\n    // Before redirecting save the event ID.\n    // It is important that the user redirect event ID is updated in storage\n    // before redirecting.\n    return self.notifyStateChangeListeners_();\n  }).then(function(user) {\n    if (self.redirectStorageManager_) {\n      // Save the user before redirecting in case it is not current so that it\n      // can be retrieved after reloading for linking or reauthentication to\n      // succeed.\n      return self.redirectStorageManager_.setRedirectUser(self);\n    }\n    return user;\n  }).then(function(user) {\n    // Complete the redirect operation.\n    return self.authEventManager_.processRedirect(\n        mode, provider, eventId, self['tenantId']);\n  }).thenCatch(function(error) {\n    // Catch error if any is generated.\n    errorThrown = error;\n    if (self.redirectStorageManager_) {\n      // If an error is detected, delete the redirected user from storage.\n      return self.redirectStorageManager_.removeRedirectUser();\n    }\n    // No storage manager, just throw error.\n    throw errorThrown;\n  }).then(function() {\n    // Rethrow the error.\n    if (errorThrown) {\n      throw errorThrown;\n    }\n  });\n  // Register this pending promise. This will also check for user invalidation.\n  return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(\n      p,\n      // Skip invalidation check as reauthentication could revalidate a user.\n      isReauthOperation));\n};\n\n\n/**\n * @return {!fireauth.AuthEventManager} The user's Auth event manager.\n */\nfireauth.AuthUser.prototype.getAuthEventManager = function() {\n  // Either return the manager instance if available, otherwise throw an error.\n  if (this.authEventManager_ && this.popupRedirectEnabled_) {\n    return this.authEventManager_;\n  } else if (this.authEventManager_ && !this.popupRedirectEnabled_) {\n    // This should not happen as Auth will enable a user after it is created.\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n  }\n  throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_AUTH_DOMAIN);\n};\n\n\n/**\n * Finishes the popup and redirect account linking operations.\n * @param {string} requestUri The callback URL with the OAuth response.\n * @param {string} sessionId The session ID used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.finishPopupAndRedirectLink =\n    function(requestUri, sessionId, tenantId, opt_postBody) {\n  var self = this;\n  // Now that popup has responded, delete popup timeout promise.\n  if (this.popupTimeoutPromise_) {\n    this.popupTimeoutPromise_.cancel();\n    this.popupTimeoutPromise_ = null;\n  }\n  var userCredential = null;\n  // This routine could be run before init state, make sure it waits for that to\n  // complete otherwise this would fail as user not loaded from storage yet.\n  var p = this.getIdToken()\n      .then(function(idToken) {\n        var request = {\n          'requestUri': requestUri,\n          'postBody': opt_postBody,\n          'sessionId': sessionId,\n          // To link a tenant user, the tenant ID will be passed to the\n          // backend as part of the ID token.\n          'idToken': idToken\n        };\n        // This operation should fail if new ID token differs from old one.\n        // So this can be treate as a profile update operation.\n        return self.rpcHandler_.verifyAssertionForLinking(request);\n      })\n      .then(function(response) {\n        // Get user credential.\n        userCredential = self.getUserCredential_(\n            response, fireauth.constants.OperationType.LINK);\n        // Finalizes the linking process.\n        return self.finalizeLinking_(response);\n      })\n      .then(function(user) {\n        // Return the user credential response.\n        return userCredential;\n      });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * Finishes the popup and redirect account reauthentication operations.\n * @param {string} requestUri The callback URL with the OAuth response.\n * @param {string} sessionId The session ID used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.finishPopupAndRedirectReauth =\n    function(requestUri, sessionId, tenantId, opt_postBody) {\n  var self = this;\n  // Now that popup has responded, delete popup timeout promise.\n  if (this.popupTimeoutPromise_) {\n    this.popupTimeoutPromise_.cancel();\n    this.popupTimeoutPromise_ = null;\n  }\n  var userCredential = null;\n  // This routine could be run before init state, make sure it waits for that to\n  // complete otherwise this would fail as user not loaded from storage yet.\n  var p = goog.Promise.resolve()\n      .then(function() {\n        var request = {\n          'requestUri': requestUri,\n          'sessionId': sessionId,\n          'postBody': opt_postBody,\n          // To reauthenticate a tenant user, the tenant ID will be passed to\n          // the backend explicitly.\n          // Even if tenant ID is null, still pass it to RPC handler explicitly\n          // so that it won't be overridden by RPC handler's tenant ID.\n          'tenantId': tenantId\n        };\n        // Finish sign in by calling verifyAssertionForExisting and then\n        // matching the returned ID token's UID with the current user's.\n        return fireauth.AuthCredential.verifyTokenResponseUid(\n            self.rpcHandler_.verifyAssertionForExisting(request),\n            self['uid']);\n      }).then(function(response) {\n        // Get credential from response if available.\n        // Get user credential.\n        userCredential = self.getUserCredential_(\n            response, fireauth.constants.OperationType.REAUTHENTICATE);\n        // If the credential is valid and matches the current user ID, then\n        // update the tokens accordingly.\n        self.updateTokensIfPresent(response);\n        // This could potentially validate an invalidated user. This happens in\n        // the case a password reset was applied. The refresh token is expired.\n        // Reauthentication should revalidate the user.\n        // User would remain non current if already signed out, but should be\n        // enabled again.\n        self.userInvalidatedError_ = null;\n        return self.reload();\n      })\n      .then(function() {\n        // Return the user credential response.\n        return userCredential;\n      });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(\n          p,\n          // Skip invalidation check as reauthentication could revalidate a\n          // user.\n          true));\n};\n\n\n/**\n * Sends the verification email to the email in the user's account.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n *     object.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.sendEmailVerification =\n    function(opt_actionCodeSettings) {\n  var self = this;\n  var idToken = null;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      // Wrap in promise as ActionCodeSettings constructor could throw a\n      // synchronous error if invalid arguments are specified.\n      this.getIdToken().then(function(latestIdToken) {\n        idToken = latestIdToken;\n        if (typeof opt_actionCodeSettings !== 'undefined' &&\n            // Ignore empty objects.\n            !goog.object.isEmpty(opt_actionCodeSettings)) {\n          return new fireauth.ActionCodeSettings(\n              /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n        }\n        return {};\n      })\n      .then(function(additionalRequestData) {\n        return self.rpcHandler_.sendEmailVerification(\n            /** @type {string} */ (idToken), additionalRequestData);\n      })\n      .then(function(email) {\n        if (self['email'] != email) {\n          // Our local copy does not have an email. If the email changed,\n          // reload the user.\n          return self.reload();\n        }\n      })\n      .then(function() {\n        // Return nothing.\n      }));\n};\n\n\n/**\n * Sends the verification email before updating the email on the user.\n * @param {string} newEmail The new email.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n *     object.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.verifyBeforeUpdateEmail =\n    function(newEmail, opt_actionCodeSettings) {\n  var self = this;\n  var idToken = null;\n  // Register this pending promise. This will also check for user invalidation.\n  return this.registerPendingPromise_(\n      // Wrap in promise as ActionCodeSettings constructor could throw a\n      // synchronous error if invalid arguments are specified.\n      this.getIdToken().then(function(latestIdToken) {\n        idToken = latestIdToken;\n        if (typeof opt_actionCodeSettings !== 'undefined' &&\n            // Ignore empty objects.\n            !goog.object.isEmpty(opt_actionCodeSettings)) {\n          return new fireauth.ActionCodeSettings(\n              /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n        }\n        return {};\n      })\n      .then(function(additionalRequestData) {\n        return self.rpcHandler_.verifyBeforeUpdateEmail(\n            /** @type {string} */ (idToken), newEmail, additionalRequestData);\n      })\n      .then(function(email) {\n        if (self['email'] != email) {\n          // If the local copy of the email on user is outdated, reload the\n          // user.\n          return self.reload();\n        }\n      })\n      .then(function() {\n        // Return nothing.\n      }));\n};\n\n\n/**\n * Destroys the user object and makes further operations invalid. Sensitive\n * fields (refreshToken) are also cleared.\n */\nfireauth.AuthUser.prototype.destroy = function() {\n  // Cancel all pending promises.\n  for (var i = 0; i < this.pendingPromises_.length; i++) {\n    this.pendingPromises_[i].cancel(fireauth.authenum.Error.MODULE_DESTROYED);\n  }\n  // Stop listening to language code changes.\n  this.setLanguageCodeChangeDispatcher(null);\n  // Stop listening to framework changes.\n  this.setFrameworkChangeDispatcher(null);\n  // Empty pending promises array.\n  this.pendingPromises_ = [];\n  this.destroyed_ = true;\n  // Stop proactive refresh if running.\n  this.stopProactiveRefresh();\n  fireauth.object.setReadonlyProperty(this, 'refreshToken', null);\n  // Make sure the destroyed user is unsubscribed from Auth event handling.\n  if (this.authEventManager_) {\n    this.authEventManager_.unsubscribe(this);\n  }\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back. If in the process, a user invalidation error is detected, caches the\n * error so next time a call is made on the user, the operation will fail with\n * the cached error.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @param {boolean=} opt_skipInvalidationCheck Whether to skip invalidation\n *     check.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.registerPendingPromise_ =\n    function(p, opt_skipInvalidationCheck) {\n  var self = this;\n  // Check if user invalidation occurs.\n  var processedP = this.checkIfInvalidated_(p, opt_skipInvalidationCheck);\n  // Save created promise in pending list.\n  this.pendingPromises_.push(processedP);\n  processedP.thenAlways(function() {\n    // When fulfilled, remove from pending list.\n    goog.array.remove(self.pendingPromises_, processedP);\n  });\n  // Return the promise.\n  return processedP\n      .thenCatch(function(error) {\n        var multiFactorError = null;\n        if (error && error['code'] === 'auth/multi-factor-auth-required') {\n          multiFactorError = fireauth.MultiFactorError.fromPlainObject(\n              error.toPlainObject(),\n              self.getAuth_(),\n              goog.bind(self.handleMultiFactorIdTokenResolver_, self));\n        }\n        throw multiFactorError || error;\n      });\n};\n\n\n/**\n * Completes multi-factor sign-in. This is only relevant for re-authentication\n * flows.\n * @param {{idToken: string, refreshToken: string}} response The successful\n *     sign-in response containing the new ID tokens.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A Promise that\n *     resolves with the updated `UserCredential`.\n * @private\n */\nfireauth.AuthUser.prototype.handleMultiFactorIdTokenResolver_ =\n    function(response) {\n  var userCredential = null;\n  var self = this;\n  // Validate token response matches current user ID.\n  var p = fireauth.AuthCredential.verifyTokenResponseUid(\n      goog.Promise.resolve(response),\n      self['uid'])\n      .then(function(response) {\n        // Get credential from response if available.\n        userCredential = self.getUserCredential_(\n            response, fireauth.constants.OperationType.REAUTHENTICATE);\n        // If the credential is valid and matches the current user ID, then\n        // update the tokens accordingly.\n        self.updateTokensIfPresent(response);\n        // This could potentially validate an invalidated user.\n        self.userInvalidatedError_ = null;\n        // Reload the user with the latest profile.\n        return self.reload();\n      })\n      .then(function() {\n        // Return the user credential response.\n        return userCredential;\n      });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(\n          p,\n          // Skip invalidation check as reauthentication could revalidate a\n          // user.\n          true));\n};\n\n\n/**\n * Check if user invalidation occurs. If so, it caches the error so it can be\n * thrown immediately the next time an operation is run on the user.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @param {boolean=} opt_skipInvalidationCheck Whether to skip invalidation\n *     check.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.checkIfInvalidated_ =\n    function(p, opt_skipInvalidationCheck) {\n  var self = this;\n  // Already invalidated, reject with token expired error.\n  // Unless invalidation check is to be skipped.\n  if (this.userInvalidatedError_ && !opt_skipInvalidationCheck) {\n    // Cancel pending promise.\n    p.cancel();\n    // Reject with cached error.\n    return goog.Promise.reject(this.userInvalidatedError_);\n  }\n  return p.thenCatch(function(error) {\n    // Session invalidated.\n    if (fireauth.AuthUser.isUserInvalidated_(error)) {\n      // Notify listeners of invalidated session.\n      if (!self.userInvalidatedError_) {\n        self.notifyUserInvalidatedListeners_();\n      }\n      // Cache the invalidation error.\n      self.userInvalidatedError_ = /** @type {!fireauth.AuthError} */ (error);\n    }\n    // Rethrow the error.\n    throw error;\n  });\n};\n\n\n/**\n * @return {!Object} The object representation of the user instance.\n * @override\n */\nfireauth.AuthUser.prototype.toJSON = function() {\n  // Return the plain object representation in case JSON.stringify is called on\n  // a user instance.\n  return this.toPlainObject();\n};\n\n\n/**\n * @return {!Object} The object representation of the user instance.\n */\nfireauth.AuthUser.prototype.toPlainObject = function() {\n  var obj = {\n    'uid': this['uid'],\n    'displayName': this['displayName'],\n    'photoURL': this['photoURL'],\n    'email': this['email'],\n    'emailVerified': this['emailVerified'],\n    'phoneNumber': this['phoneNumber'],\n    'isAnonymous': this['isAnonymous'],\n    'tenantId': this['tenantId'],\n    'providerData': [],\n    'apiKey': this.apiKey_,\n    'appName': this.appName_,\n    'authDomain': this.authDomain_,\n    'stsTokenManager': this.stsTokenManager_.toPlainObject(),\n    // Redirect event ID must be maintained in case there is a pending redirect\n    // event.\n    'redirectEventId': this.getRedirectEventId()\n  };\n  // Extend user plain object with metadata object.\n  if (this['metadata']) {\n    goog.object.extend(obj, this['metadata'].toPlainObject());\n  }\n  goog.array.forEach(this['providerData'], function(userInfo) {\n    obj['providerData'].push(fireauth.object.makeWritableCopy(userInfo));\n  });\n  // Extend plain object with multi-factor user data.\n  goog.object.extend(obj, this.multiFactorUser_.toPlainObject());\n  return obj;\n};\n\n\n/**\n * Converts a plain user object to {@code fireauth.AuthUser}.\n * @param {!Object} user The object representation of the user instance.\n * @return {?fireauth.AuthUser} The Firebase user object corresponding to\n *     object.\n */\nfireauth.AuthUser.fromPlainObject = function(user) {\n  if (!user['apiKey']) {\n    return null;\n  }\n  var options = {\n    'apiKey': user['apiKey'],\n    'authDomain': user['authDomain'],\n    'appName': user['appName']\n  };\n  // Convert to server response format. Constructor does not take\n  // stsTokenManager toPlainObject as that format is different than the return\n  // server response which is always used to initialize a user instance.\n  var stsTokenManagerResponse = {};\n  if (user['stsTokenManager'] &&\n      user['stsTokenManager']['accessToken']) {\n    stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN] =\n        user['stsTokenManager']['accessToken'];\n    // Refresh token could be expired.\n    stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN] =\n        user['stsTokenManager']['refreshToken'] || null;\n  } else {\n    // Token response is a required field.\n    return null;\n  }\n  var firebaseUser = new fireauth.AuthUser(options,\n      stsTokenManagerResponse,\n      /** @type {!fireauth.AuthUser.AccountInfo} */ (user));\n  if (user['providerData']) {\n    goog.array.forEach(user['providerData'], function(userInfo) {\n      if (userInfo) {\n        firebaseUser.addProviderData(/** @type {!fireauth.AuthUserInfo} */ (\n            fireauth.object.makeReadonlyCopy(userInfo)));\n      }\n    });\n  }\n  // Redirect event ID must be restored to complete any pending link with\n  // redirect operation owned by this user.\n  if (user['redirectEventId']) {\n    firebaseUser.setRedirectEventId(user['redirectEventId']);\n  }\n  return firebaseUser;\n};\n\n\n\n/**\n * Factory method for initializing a Firebase user object and populating its\n * user info. This is the recommended way for initializing a user externally.\n * On sign in/up operation, the server returns a token response. The response is\n * all that is needed to initialize this user.\n * @param {!Object} appOptions The application options.\n * @param {!Object} stsTokenResponse The server STS token response.\n * @param {?fireauth.storage.RedirectUserManager=}\n *     opt_redirectStorageManager The utility used to store and delete a user on\n *     link with redirect.\n * @param {?Array<string>=} opt_frameworks The list of frameworks to log on the\n *     user on initialization.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n */\nfireauth.AuthUser.initializeFromIdTokenResponse = function(appOptions,\n    stsTokenResponse, opt_redirectStorageManager, opt_frameworks) {\n  // Initialize the Firebase Auth user.\n  var user = new fireauth.AuthUser(\n      appOptions, stsTokenResponse);\n  // If redirect storage manager provided, set it.\n  if (opt_redirectStorageManager) {\n    user.setRedirectStorageManager(opt_redirectStorageManager);\n  }\n  // If frameworks provided, set it.\n  if (opt_frameworks) {\n    user.setFramework(opt_frameworks);\n  }\n  // Updates the user info and data and resolves with a user instance.\n  return user.reload().then(function() {\n    return user;\n  });\n};\n\n\n/**\n * Returns an AuthUser copy of the provided user using the provided parameters\n * without making any network request.\n * @param {!fireauth.AuthUser} user The user to be copied.\n * @param {?Object=} opt_appOptions The application options.\n * @param {?fireauth.storage.RedirectUserManager=}\n *     opt_redirectStorageManager The utility used to store and delete a user on\n *     link with redirect.\n * @param {?Array<string>=} opt_frameworks The list of frameworks to log on the\n *     user on initialization.\n * @return {!fireauth.AuthUser}\n */\nfireauth.AuthUser.copyUser = function(user, opt_appOptions,\n    opt_redirectStorageManager, opt_frameworks) {\n  var appOptions = opt_appOptions || {\n    'apiKey': user.apiKey_,\n    'authDomain': user.authDomain_,\n    'appName': user.appName_\n  };\n  var newUser = new fireauth.AuthUser(\n      appOptions, user.getStsTokenManager().toServerResponse());\n  // If redirect storage manager provided, set it.\n  if (opt_redirectStorageManager) {\n    newUser.setRedirectStorageManager(opt_redirectStorageManager);\n  }\n  // If frameworks provided, set it.\n  if (opt_frameworks) {\n    newUser.setFramework(opt_frameworks);\n  }\n  // Copy remaining properties.\n  newUser.copy(user);\n  return newUser;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the fireauth.storage.UserManager class which provides\n * utilities to retrieve, store and delete the currently logged in user and to\n * listen to external authentication changes for the same app.\n * With the ability to modify Auth state persistence. The behavior is as\n * follows:\n * Common cases:\n * <ul>\n * <li>Initially, local and session storage will be checked and the state will\n *     be loaded from there without changing it unless the developer calls\n *     setPersistence explicitly. The requirement is that at any time, Auth\n *     state can be saved using one type only of persistence and never more than\n *     one.</li>\n * <li>If the developer tries to sign in with no persistence specified, the\n *     default setting will be used (local in a browser).</li>\n * <li>If the user is not signed in and persistence is set, any future sign-in\n *     attempt will use that type of persistence.</li>\n * <li>If the user is signed in and the developer then switches persistence,\n *     that existing signed in user will change persistence to the new one. All\n *     future sign-in attempts will use that same persistence.</li>\n * <li>When signInWithRedirect is called, the current persistence type is passed\n *     along with that request and on redirect back to app will pass that type\n *     to determine how that state is saved (overriding the default). If the\n *     persistence is explicitly specified on that page, it will change that\n *     redirected Auth state persistence. This is the only time the persistence\n *     is passed from one page to another.\n *     So internally, on redirect, the redirect state is retrieved and then we\n *     check: If the persistence was explicitly provided, we override the\n *     previous type and save the Auth state using that. If no persistence was\n *     explicitly provided, we use the previous persistence type that was passed\n *     in the redirect response.</li>\n * </ul>\n * Behavior across tabs:\n * <ul>\n * <li>User can sign in using session storage on multiple tabs. Each tab cannot\n *     see the state of the other tab.</li>\n * <li>Any attempt to sign in using local storage will be detected and\n *     synchronized on all tabs. If the user was previously signed in on a\n *     specific tab using session storage, that state will be cleared.</li>\n * <li>If the user was previously signed in using local storage and then signs\n *     in using session storage, the user will be signed in on the current tab\n *     only and signed out on all other tabs.</li>\n * <li>Similar logic is applied to the ‘none’ state. In one tab, switching to\n *     ‘none’ state will delete any previously saved state in ‘local’\n *     persistence in other tabs.</li>\n * </ul>\n */\n\ngoog.provide('fireauth.storage.UserManager');\n\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.authStorage');\ngoog.require('goog.Promise');\n\n\n/**\n * Defines the Auth user storage manager. It provides methods to\n * store, load and delete an authenticated current user. It also provides\n * methods to listen to external user changes (updates, sign in, sign out, etc.)\n * @param {string} appId The Auth state's application ID.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n *     manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.UserManager = function(appId, opt_manager) {\n  /** @const @private{string} appId The Auth state's application ID. */\n  this.appId_ = appId;\n  /**\n   * @const @private{!fireauth.authStorage.Manager} The underlying storage\n   *     manager.\n   */\n  this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n  /**\n   * @private {?fireauth.authStorage.Key} The current Auth user storage\n   *     identifier.\n   */\n  this.currentAuthUserKey_ = null;\n  /**\n   * @private {!goog.Promise} Storage operation serializer promise. This will\n   *     initialize the current persistence used and clean up any duplicate\n   *     states or temporary values (persistence for pending redirect).\n   *     Afterwards this is used to queue storage requests to make sure\n   *     storage operations are always synchronized and read/write events are\n   *     processed on the same storage.\n   */\n  this.onReady_ = this.initialize_();\n  // This internal listener will always run before the external ones.\n  // This is needed to queue processing of this first before any getCurrentUser\n  // is called from external listeners.\n  this.manager_.addListener(\n      fireauth.storage.UserManager.getAuthUserKey_(\n          fireauth.authStorage.Persistence.LOCAL),\n      this.appId_,\n      goog.bind(this.switchToLocalOnExternalEvent_, this));\n};\n\n\n/**\n * Switches to local storage on external storage event. This will happen when\n * state is specified as local in an external tab while it is none or session\n * in the current one. If a user signs in in an external tab, the current window\n * should detect this, clear existing storage and switch to local storage.\n * @private\n */\nfireauth.storage.UserManager.prototype.switchToLocalOnExternalEvent_ =\n    function() {\n  var self = this;\n  var localKey = fireauth.storage.UserManager.getAuthUserKey_(\n      fireauth.authStorage.Persistence.LOCAL);\n  // Wait for any pending operation to finish first.\n  // Block next read/write operation until persistence is transitioned to\n  // local.\n  this.waitForReady_(function() {\n    return goog.Promise.resolve().then(function() {\n      // If current persistence is not already local.\n      if (self.currentAuthUserKey_ &&\n          self.currentAuthUserKey_.persistent !=\n          fireauth.authStorage.Persistence.LOCAL) {\n        // Check if new current user is available in local storage.\n        return self.manager_.get(localKey, self.appId_);\n      }\n      return null;\n    }).then(function(response) {\n      // Sign in on an external tab.\n      if (response) {\n        // Remove any existing non-local user.\n        return self.removeAllExcept_(\n            fireauth.authStorage.Persistence.LOCAL).then(function() {\n              // Set persistence to local.\n              self.currentAuthUserKey_ = localKey;\n            });\n      }\n    });\n  });\n};\n\n\n/**\n * Removes all states stored in all supported persistence types excluding the\n * specified one.\n * @param {?fireauth.authStorage.Persistence} persistence The type of storage\n *     persistence to switch to.\n * @return {!goog.Promise} The promise that resolves when all stored values are\n *     removed for types of storage excluding specified persistence. This helps\n *     ensure there is always one type of persistence at any time.\n * @private\n */\nfireauth.storage.UserManager.prototype.removeAllExcept_ =\n    function(persistence) {\n  var promises = [];\n  // Queue all promises to remove current user in any other persistence type.\n  for (var key in fireauth.authStorage.Persistence) {\n    // Skip specified persistence.\n    if (fireauth.authStorage.Persistence[key] !== persistence) {\n      var storageKey = fireauth.storage.UserManager.getAuthUserKey_(\n          fireauth.authStorage.Persistence[key]);\n      promises.push(this.manager_.remove(\n          /** @type {!fireauth.authStorage.Key} */ (storageKey),\n          this.appId_));\n    }\n  }\n  // Clear persistence key (only useful for initial load upon returning from a\n  // a redirect sign-in operation).\n  promises.push(this.manager_.remove(\n      fireauth.storage.UserManager.PERSISTENCE_KEY_,\n      this.appId_));\n  return goog.Promise.all(promises);\n};\n\n\n/**\n * Initializes the current persistence state. This will check the 3 supported\n * types. The first one that is found will be the current persistence. All\n * others will be cleared. If none is found we check PERSISTENCE_KEY_ which\n * when specified means that the operation is returning from a\n * signInWithRedirect call. This persistence will be applied.\n * Otherwise the default local persistence is used.\n * @return {!goog.Promise} A promise that resolves when the current persistence\n *     is resolved.\n * @private\n */\nfireauth.storage.UserManager.prototype.initialize_ = function() {\n  var self = this;\n  // Local key.\n  var localKey = fireauth.storage.UserManager.getAuthUserKey_(\n      fireauth.authStorage.Persistence.LOCAL);\n  // Session key.\n  var sessionKey = fireauth.storage.UserManager.getAuthUserKey_(\n      fireauth.authStorage.Persistence.SESSION);\n  // In memory key. This is unlikely to contain anything on load.\n  var inMemoryKey = fireauth.storage.UserManager.getAuthUserKey_(\n      fireauth.authStorage.Persistence.NONE);\n  // Migrate any old currentUser from localStorage to indexedDB.\n  // This keeps any user signed in without the need for reauthentication and\n  // minimizes risks of dangling Auth states.\n  return this.manager_.migrateFromLocalStorage(\n      localKey, this.appId_).then(function() {\n    // Check if state is stored in session storage.\n    return self.manager_.get(sessionKey, self.appId_);\n  }).then(function(response) {\n    if (response) {\n      // Session storage is being used.\n      return sessionKey;\n    } else {\n      // Session storage is empty. Check in memory storage.\n      return self.manager_.get(inMemoryKey, self.appId_)\n          .then(function(response) {\n            if (response) {\n              // In memory storage being used.\n              return inMemoryKey;\n            } else {\n              // Check local storage.\n              return self.manager_.get(localKey, self.appId_)\n                  .then(function(response) {\n                    if (response) {\n                      // Local storage being used.\n                      return localKey;\n                    } else {\n                      // Nothing found in any supported storage.\n                      // Check current user persistence in storage.\n                      return self.manager_.get(\n                          fireauth.storage.UserManager.PERSISTENCE_KEY_,\n                          self.appId_).then(function(persistence) {\n                            if (persistence) {\n                              // Sign in with redirect operation, apply this\n                              // persistence to any current user.\n                              return fireauth.storage.UserManager\n                                  .getAuthUserKey_(persistence);\n                            } else {\n                              // No persistence found, use the default.\n                              return localKey;\n                            }\n                          });\n                    }\n                  });\n            }\n          });\n    }\n  }).then(function(currentKey) {\n    // Set current key according to the persistence detected.\n    self.currentAuthUserKey_ = currentKey;\n    // Make sure only one state available. Clean up everything else.\n    return self.removeAllExcept_(currentKey.persistent);\n  }).thenCatch(function(error) {\n    // If an error occurs in the process and no current key detected, set to\n    // persistence value to default.\n    if (!self.currentAuthUserKey_) {\n      self.currentAuthUserKey_ = localKey;\n    }\n  });\n};\n\n\n/**\n * @const @private {string} The Auth current user storage identifier name.\n */\nfireauth.storage.UserManager.AUTH_USER_KEY_NAME_ = 'authUser';\n\n\n/**\n * @const @private{!fireauth.authStorage.Key} The Auth user storage persistence\n *     identifier. This is needed to remember the previous persistence state for\n *     sign-in with redirect.\n */\nfireauth.storage.UserManager.PERSISTENCE_KEY_ = {\n  name: 'persistence',\n  persistent: fireauth.authStorage.Persistence.SESSION\n};\n\n\n/**\n * Returns the Auth user key corresponding to the persistence type provided.\n * @param {!fireauth.authStorage.Persistence} persistence The key for the\n *     specified type of persistence.\n * @return {!fireauth.authStorage.Key} The corresponding Auth user storage\n *     identifier.\n * @private\n */\nfireauth.storage.UserManager.getAuthUserKey_ = function(persistence) {\n  return {\n    name: fireauth.storage.UserManager.AUTH_USER_KEY_NAME_,\n    persistent: persistence\n  };\n};\n\n\n/**\n * Sets the persistence to the specified type.\n * If an existing user already is in storage, it copies that value to the new\n * storage and clears all the others.\n * @param {!fireauth.authStorage.Persistence} persistence The type of storage\n *     persistence to switch to.\n * @return {!goog.Promise} A promise that resolves when persistence change is\n *     applied.\n */\nfireauth.storage.UserManager.prototype.setPersistence = function(persistence) {\n  var currentUser = null;\n  var self = this;\n  // Validate the persistence type provided. This will throw a synchronous error\n  // if invalid.\n  fireauth.authStorage.validatePersistenceArgument(persistence);\n  // Wait for turn in queue.\n  return this.waitForReady_(function() {\n    // If persistence hasn't changed, do nothing.\n    if (persistence != self.currentAuthUserKey_.persistent) {\n      // Persistence changed. Copy from current storage to new one.\n      return self.manager_.get(\n        /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n        self.appId_).then(function(result) {\n        // Save current user.\n        currentUser = result;\n        // Clear from current storage.\n        return self.removeAllExcept_(persistence);\n      }).then(function() {\n        // Update persistence key to the new one.\n        self.currentAuthUserKey_ =\n            fireauth.storage.UserManager.getAuthUserKey_(persistence);\n        // Copy current storage type to the new one.\n        if (currentUser) {\n          return self.manager_.set(\n              /** @type {!fireauth.authStorage.Key} */ (\n                  self.currentAuthUserKey_),\n              currentUser,\n              self.appId_);\n        }\n      });\n    }\n    // No change in persistence type.\n    return goog.Promise.resolve();\n  });\n};\n\n\n/**\n * Saves the current persistence type so it can be retrieved after a page\n * redirect. This is relevant for signInWithRedirect.\n * @return {!goog.Promise} Promise that resolve when current persistence is\n *     saved.\n */\nfireauth.storage.UserManager.prototype.savePersistenceForRedirect = function() {\n  var self = this;\n  return this.waitForReady_(function() {\n    // Save persistence to survive redirect.\n    return self.manager_.set(\n        fireauth.storage.UserManager.PERSISTENCE_KEY_,\n        self.currentAuthUserKey_.persistent,\n        self.appId_);\n  });\n};\n\n\n/**\n * Stores the current Auth user for the provided application ID.\n * @param {!fireauth.AuthUser} currentUser The app current Auth user to save.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.UserManager.prototype.setCurrentUser = function(currentUser) {\n  var self = this;\n  // Wait for any pending persistence change to be resolved.\n  return this.waitForReady_(function() {\n    return self.manager_.set(\n        /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n        currentUser.toPlainObject(),\n        self.appId_);\n  });\n};\n\n\n/**\n * Removes the stored current user for provided app ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.UserManager.prototype.removeCurrentUser = function() {\n  var self = this;\n  // Wait for any pending persistence change to be resolved.\n  return this.waitForReady_(function() {\n    return self.manager_.remove(\n        /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n        self.appId_);\n  });\n};\n\n\n/**\n * @param {?string=} opt_authDomain The optional Auth domain to override if\n *     provided.\n * @return {!goog.Promise<?fireauth.AuthUser>} A promise that resolves with\n *     the stored current user for the provided app ID.\n */\nfireauth.storage.UserManager.prototype.getCurrentUser =\n    function(opt_authDomain) {\n  var self = this;\n  // Wait for any pending persistence change to be resolved.\n  return this.waitForReady_(function() {\n    return self.manager_.get(\n        /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n        self.appId_).then(function(response) {\n          // If potential user saved, override Auth domain if authDomain is\n          // provided.\n          // This is useful in cases where on one page the developer initializes\n          // the Auth instance without authDomain and signs in user using\n          // headless methods. On another page, Auth is initialized with\n          // authDomain for the purpose of linking with a popup. The loaded user\n          // (stored without the authDomain) must have this field updated with\n          // the current authDomain.\n          if (response && opt_authDomain) {\n            response['authDomain'] = opt_authDomain;\n          }\n          return fireauth.AuthUser.fromPlainObject(response || {});\n        });\n  });\n};\n\n\n/**\n * Serializes storage access operations especially since persistence\n * could be updated from one type to the other while read/write operations\n * occur.\n * @param {function():!goog.Promise<T>} cb The promise return callback to chain\n *     when pending operations are resolved.\n * @return {!goog.Promise<T>} The resulting promise that resolves when provided\n *     promise finally resolves.\n * @template T\n * @private\n */\nfireauth.storage.UserManager.prototype.waitForReady_ = function(cb) {\n  // Wait for any pending persistence change to be resolved before running\n  // storage related operation. Chain to onReady so next call will wait for\n  // this operation to resolve.\n  // While an error is unlikely, run callback even if it happens, otherwise\n  // no storage related event will be allowed to complete after an error.\n  this.onReady_ = this.onReady_.then(cb, cb);\n  return this.onReady_;\n};\n\n\n/**\n * Adds a listener to Auth current user change event for app ID provided.\n * @param {!function()} listener The listener to run on current user change\n *     event.\n */\nfireauth.storage.UserManager.prototype.addCurrentUserChangeListener =\n    function(listener) {\n  // When this is triggered, getCurrentUser is called, that will have to wait\n  // for switchToLocalOnExternalEvent_ to resolve which is ahead of it in the\n  // queue.\n  this.manager_.addListener(\n      fireauth.storage.UserManager.getAuthUserKey_(\n          fireauth.authStorage.Persistence.LOCAL),\n      this.appId_,\n      listener);\n};\n\n\n/**\n * Removes a listener to Auth current user change event for app ID provided.\n * @param {!function()} listener The listener to remove from current user change\n *     event changes.\n */\nfireauth.storage.UserManager.prototype.removeCurrentUserChangeListener =\n    function(listener) {\n  this.manager_.removeListener(\n      fireauth.storage.UserManager.getAuthUserKey_(\n          fireauth.authStorage.Persistence.LOCAL),\n      this.appId_,\n      listener);\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 The headless Auth class used for authenticating Firebase users.\n */\n\ngoog.provide('fireauth.Auth');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeSettings');\ngoog.require('fireauth.AdditionalUserInfo');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthEventHandler');\ngoog.require('fireauth.AuthEventManager');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.AuthSettings');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.EmailAuthProvider');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.object');\ngoog.require('fireauth.storage.RedirectUserManager');\ngoog.require('fireauth.storage.UserManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.object');\n\n\n\n/**\n * Creates the Firebase Auth corresponding for the App provided.\n *\n * @param {!firebase.app.App} app The corresponding Firebase App.\n * @constructor\n * @implements {fireauth.AuthEventHandler}\n * @implements {firebase.Service}\n * @extends {goog.events.EventTarget}\n */\nfireauth.Auth = function(app) {\n  /** @private {boolean} Whether this instance is deleted. */\n  this.deleted_ = false;\n  /** The Auth instance's settings object. */\n  fireauth.object.setReadonlyProperty(\n      this, 'settings', new fireauth.AuthSettings());\n  /** Auth's corresponding App. */\n  fireauth.object.setReadonlyProperty(this, 'app', app);\n  // Initialize RPC handler.\n  // API key is required for web client RPC calls.\n  if (this.app_().options && this.app_().options['apiKey']) {\n    var clientFullVersion = firebase.SDK_VERSION ?\n        fireauth.util.getClientVersion(\n            fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION) :\n        null;\n    this.rpcHandler_ = new fireauth.RpcHandler(\n        this.app_().options && this.app_().options['apiKey'],\n        // Get the client Auth endpoint used.\n        fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n        clientFullVersion);\n  } else {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_API_KEY);\n  }\n  /** @private {!Array<!goog.Promise<*, *>|!goog.Promise<void>>} List of\n   *      pending promises. */\n  this.pendingPromises_ = [];\n  /** @private {!Array<!function(?string)>} Auth token listeners. */\n  this.authListeners_ = [];\n  /** @private {!Array<!function(?string)>} User change listeners. */\n  this.userChangeListeners_ = [];\n  /**\n   * @private {!firebase.Subscribe} The subscribe function to the Auth ID token\n   *     change observer. This will trigger on ID token changes, including\n   *     token refresh on the same user.\n   */\n  this.onIdTokenChanged_ = firebase.INTERNAL.createSubscribe(\n      goog.bind(this.initIdTokenChangeObserver_, this));\n  /**\n   * @private {?string|undefined} The UID of the user that last triggered the\n   *     user state change listener.\n   */\n  this.userStateChangeUid_ = undefined;\n  /**\n   * @private {!firebase.Subscribe} The subscribe function to the user state\n   *     change observer.\n   */\n  this.onUserStateChanged_ = firebase.INTERNAL.createSubscribe(\n      goog.bind(this.initUserStateObserver_, this));\n  // Set currentUser to null.\n  this.setCurrentUser_(null);\n  /**\n   * @private {!fireauth.storage.UserManager} The Auth user storage\n   *     manager instance.\n   */\n  this.userStorageManager_ =\n      new fireauth.storage.UserManager(this.getStorageKey());\n  /**\n   * @private {!fireauth.storage.RedirectUserManager} The redirect user\n   *     storagemanager instance.\n   */\n  this.redirectUserStorageManager_ =\n      new fireauth.storage.RedirectUserManager(this.getStorageKey());\n  /**\n   * @private {!goog.Promise<undefined>} Promise that resolves when initial\n   *     state is loaded from storage.\n   */\n  this.authStateLoaded_ = this.registerPendingPromise_(this.initAuthState_());\n  /**\n   * @private {!goog.Promise<undefined>} Promise that resolves when state and\n   *     redirect result is ready, after which sign in and sign out operations\n   *     are safe to execute.\n   */\n  this.redirectStateIsReady_ = this.registerPendingPromise_(\n      this.initAuthRedirectState_());\n  /** @private {boolean} Whether initial state has already been resolved. */\n  this.isStateResolved_ = false;\n  /**\n   * @private {!function()} The syncAuthChanges function with context set to\n   *     auth instance.\n   */\n  this.getSyncAuthUserChanges_ = goog.bind(this.syncAuthUserChanges_, this);\n  /** @private {!function(!fireauth.AuthUser):!goog.Promise} The handler for\n   *      user state changes. */\n  this.userStateChangeListener_ =\n      goog.bind(this.handleUserStateChange_, this);\n  /** @private {!function(!Object)} The handler for user token changes. */\n  this.userTokenChangeListener_ =\n      goog.bind(this.handleUserTokenChange_, this);\n  /** @private {!function(!Object)} The handler for user deletion. */\n  this.userDeleteListener_ = goog.bind(this.handleUserDelete_, this);\n  /** @private {!function(!Object)} The handler for user invalidation. */\n  this.userInvalidatedListener_ = goog.bind(this.handleUserInvalidated_, this);\n  /**\n   * @private {?fireauth.AuthEventManager} The Auth event manager instance.\n   */\n  this.authEventManager_ = null;\n  // TODO: find better way to enable or disable auth event manager.\n  if (fireauth.AuthEventManager.ENABLED) {\n    // Initialize Auth event manager to handle popup and redirect operations.\n    this.initAuthEventManager_();\n  }\n\n  // Export INTERNAL namespace.\n  this.INTERNAL = {};\n  this.INTERNAL['delete'] = goog.bind(this.delete, this);\n  this.INTERNAL['logFramework'] = goog.bind(this.logFramework, this);\n  /**\n   * @private {number} The number of Firebase services subscribed to Auth\n   *     changes.\n   */\n  this.firebaseServices_ = 0;\n  // Add call to superclass constructor.\n  fireauth.Auth.base(this, 'constructor');\n  // Initialize readable/writable Auth properties.\n  this.initializeReadableWritableProps_();\n  /**\n   * @private {!Array<string>} List of Firebase frameworks/libraries used. This\n   *     is currently only used to log FirebaseUI.\n   */\n  this.frameworks_ = [];\n};\ngoog.inherits(fireauth.Auth, goog.events.EventTarget);\n\n\n/**\n * Language code change custom event.\n * @param {?string} languageCode The new language code.\n * @constructor\n * @extends {goog.events.Event}\n */\nfireauth.Auth.LanguageCodeChangeEvent = function(languageCode) {\n  goog.events.Event.call(\n      this, fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED);\n  this.languageCode = languageCode;\n};\ngoog.inherits(fireauth.Auth.LanguageCodeChangeEvent, goog.events.Event);\n\n\n/**\n * Framework change custom event.\n * @param {!Array<string>} frameworks The new frameworks array.\n * @constructor\n * @extends {goog.events.Event}\n */\nfireauth.Auth.FrameworkChangeEvent = function(frameworks) {\n  goog.events.Event.call(\n      this, fireauth.constants.AuthEventType.FRAMEWORK_CHANGED);\n  this.frameworks = frameworks;\n};\ngoog.inherits(fireauth.Auth.FrameworkChangeEvent, goog.events.Event);\n\n\n/**\n * Changes the Auth state persistence to the specified one.\n * @param {!fireauth.authStorage.Persistence} persistence The Auth state\n *     persistence mechanism.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.setPersistence = function(persistence) {\n  // TODO: fix auth.delete() behavior and how this affects persistence\n  // change after deletion.\n  // Throw an error if already destroyed.\n  // Set current persistence.\n  var p = this.userStorageManager_.setPersistence(persistence);\n  return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * Get rid of Closure warning - the property is adding in the constructor.\n * @type {!firebase.app.App}\n */\nfireauth.Auth.prototype.app;\n\n\n/**\n * Sets the language code.\n * @param {?string} languageCode\n */\nfireauth.Auth.prototype.setLanguageCode = function(languageCode) {\n  // Don't do anything if no change detected.\n  if (this.languageCode_ !== languageCode && !this.deleted_) {\n    this.languageCode_ = languageCode;\n    // Update custom Firebase locale field.\n    this.rpcHandler_.updateCustomLocaleHeader(this.languageCode_);\n    // Notify external language code change listeners.\n    this.notifyLanguageCodeListeners_();\n  }\n};\n\n\n/**\n * Returns the current auth instance's language code if available.\n * @return {?string}\n */\nfireauth.Auth.prototype.getLanguageCode = function() {\n  return this.languageCode_;\n};\n\n\n/**\n * Sets the current language to the default device/browser preference.\n */\nfireauth.Auth.prototype.useDeviceLanguage = function() {\n  this.setLanguageCode(fireauth.util.getUserLanguage());\n};\n\n\n/**\n * @param {string} frameworkId The framework identifier.\n */\nfireauth.Auth.prototype.logFramework = function(frameworkId) {\n  // Theoretically multiple frameworks could be used\n  // (angularfire and FirebaseUI). Once a framework is used, it is not going\n  // to be unused, so no point adding a method to remove the framework ID.\n  this.frameworks_.push(frameworkId);\n  // Update the client version in RPC handler with the new frameworks.\n  this.rpcHandler_.updateClientVersion(firebase.SDK_VERSION ?\n        fireauth.util.getClientVersion(\n            fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n            this.frameworks_) :\n        null);\n  this.dispatchEvent(new fireauth.Auth.FrameworkChangeEvent(\n      this.frameworks_));\n};\n\n\n/** @return {!Array<string>} The current Firebase frameworks. */\nfireauth.Auth.prototype.getFramework = function() {\n  return goog.array.clone(this.frameworks_);\n};\n\n\n/**\n * Updates the framework list on the provided user and configures the user to\n * listen to the Auth instance for any framework ID changes.\n * @param {!fireauth.AuthUser} user The user to whose framework list needs to be\n *     updated.\n * @private\n */\nfireauth.Auth.prototype.setUserFramework_ = function(user) {\n  // Sets the framework ID on the user.\n  user.setFramework(this.frameworks_);\n  // Sets current Auth instance as framework list change dispatcher on the user.\n  user.setFrameworkChangeDispatcher(this);\n};\n\n\n/**\n * Sets the tenant ID.\n * @param {?string} tenantId The tenant ID of the tenant project if available.\n */\nfireauth.Auth.prototype.setTenantId = function(tenantId) {\n  // Don't do anything if no change detected.\n  if (this.tenantId_ !== tenantId && !this.deleted_) {\n    this.tenantId_ = tenantId;\n    this.rpcHandler_.updateTenantId(this.tenantId_);\n  }\n};\n\n\n/**\n * Returns the current Auth instance's tenant ID.\n * @return {?string}\n */\nfireauth.Auth.prototype.getTenantId = function() {\n  return this.tenantId_;\n};\n\n\n/**\n * Initializes readable/writable properties on Auth.\n * @suppress {invalidCasts}\n * @private\n */\nfireauth.Auth.prototype.initializeReadableWritableProps_ = function() {\n  Object.defineProperty(/** @type {!Object} */ (this), 'lc', {\n    /**\n     * @this {!Object}\n     * @return {?string} The current language code.\n     */\n    get: function() {\n      return this.getLanguageCode();\n    },\n    /**\n     * @this {!Object}\n     * @param {string} value The new language code.\n     */\n    set: function(value) {\n      this.setLanguageCode(value);\n    },\n    enumerable: false\n  });\n  // Initialize to null.\n  /** @private {?string} The current Auth instance's language code. */\n  this.languageCode_ = null;\n\n  // Initialize tenant ID.\n  Object.defineProperty(/** @type {!Object} */ (this), 'ti', {\n    /**\n     * @this {!Object}\n     * @return {?string} The current tenant ID.\n     */\n    get: function() {\n      return this.getTenantId();\n    },\n    /**\n     * @this {!Object}\n     * @param {?string} value The new tenant ID.\n     */\n    set: function(value) {\n      this.setTenantId(value);\n    },\n    enumerable: false\n  });\n  // Initialize to null.\n  /** @private {?string} The current Auth instance's tenant ID. */\n  this.tenantId_ = null;\n};\n\n\n/**\n * Notifies all external listeners of the language code change.\n * @private\n */\nfireauth.Auth.prototype.notifyLanguageCodeListeners_ = function() {\n  // Notify external listeners on the language code change.\n  this.dispatchEvent(new fireauth.Auth.LanguageCodeChangeEvent(\n      this.getLanguageCode()));\n};\n\n\n\n\n\n/**\n * @return {!Object} The object representation of the Auth instance.\n * @override\n */\nfireauth.Auth.prototype.toJSON = function() {\n  // Return the plain object representation in case JSON.stringify is called on\n  // an Auth instance.\n  return {\n    'apiKey': this.app_().options['apiKey'],\n    'authDomain': this.app_().options['authDomain'],\n    'appName': this.app_().name,\n    'currentUser': this.currentUser_() && this.currentUser_().toPlainObject()\n  };\n};\n\n\n/**\n * Returns the Auth event manager promise.\n * @return {!goog.Promise<!fireauth.AuthEventManager>}\n * @private\n */\nfireauth.Auth.prototype.getAuthEventManager_ = function() {\n  // Either return cached Auth event manager promise provider if available or a\n  // promise that rejects with missing Auth domain error.\n  return this.eventManagerProviderPromise_ ||\n      goog.Promise.reject(\n          new fireauth.AuthError(fireauth.authenum.Error.MISSING_AUTH_DOMAIN));\n};\n\n\n/**\n * Initializes the Auth event manager when state is ready.\n * @private\n */\nfireauth.Auth.prototype.initAuthEventManager_ = function() {\n  // Initialize Auth event manager on initState.\n  var self = this;\n  var authDomain = this.app_().options['authDomain'];\n  var apiKey = this.app_().options['apiKey'];\n  // Make sure environment also supports popup and redirect.\n  if (authDomain && fireauth.util.isPopupRedirectSupported()) {\n    // Auth domain is required for Auth event manager to resolve.\n    // Auth state has to be loaded first. One reason is to process link events.\n    this.eventManagerProviderPromise_ = this.authStateLoaded_.then(function() {\n      if (self.deleted_) {\n        return;\n      }\n      // By this time currentUser should be ready if available and will be able\n      // to resolve linkWithRedirect if detected.\n      self.authEventManager_ = fireauth.AuthEventManager.getManager(\n          authDomain, apiKey, self.app_().name);\n      // Subscribe Auth instance.\n      self.authEventManager_.subscribe(self);\n      // Subscribe current user by enabling popup and redirect on that user.\n      if (self.currentUser_()) {\n        self.currentUser_().enablePopupRedirect();\n      }\n      // If a redirect user is present, subscribe to popup and redirect events.\n      // In case current user was not available and the developer called link\n      // with redirect on a signed out user, this will work and the linked\n      // logged out user will be returned in getRedirectResult.\n      // current user and redirect user are the same (was already logged in),\n      // currentUser will have priority as it is subscribed before redirect\n      // user. This change will also allow further popup and redirect events on\n      // the redirect user going forward.\n      if (self.redirectUser_) {\n        self.redirectUser_.enablePopupRedirect();\n        // Set the user language for the redirect user.\n        self.setUserLanguage_(\n            /** @type {!fireauth.AuthUser} */ (self.redirectUser_));\n        // Set the user Firebase frameworks for the redirect user.\n        self.setUserFramework_(\n            /** @type {!fireauth.AuthUser} */ (self.redirectUser_));\n        // Reference to redirect user no longer needed.\n        self.redirectUser_ = null;\n      }\n      return self.authEventManager_;\n    });\n  }\n};\n\n\n/**\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the auth event handler can handler the provided\n *     event.\n * @override\n */\nfireauth.Auth.prototype.canHandleAuthEvent = function(mode, opt_eventId) {\n  // Only sign in events are handled.\n  switch (mode) {\n    // Accept all general sign in with redirect and unknowns.\n    // Migrating redirect events to use session storage will prevent this event\n    // from leaking to other tabs.\n    case fireauth.AuthEvent.Type.UNKNOWN:\n    case fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT:\n      return true;\n    case fireauth.AuthEvent.Type. SIGN_IN_VIA_POPUP:\n      // Pending sign in with popup event must match the stored popup event ID.\n      return this.popupEventId_ == opt_eventId &&\n          !!this.pendingPopupResolvePromise_;\n    default:\n      return false;\n  }\n};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n *     to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n * @override\n */\nfireauth.Auth.prototype.resolvePendingPopupEvent =\n    function(mode, popupRedirectResult, error, opt_eventId) {\n  // Only handles popup events of type sign in and which match popup event ID.\n  if (mode != fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP ||\n      this.popupEventId_ != opt_eventId) {\n    return;\n  }\n  if (error && this.pendingPopupRejectPromise_) {\n    // Reject with error for supplied mode.\n    this.pendingPopupRejectPromise_(error);\n  } else if (popupRedirectResult &&\n             !error &&\n             this.pendingPopupResolvePromise_) {\n    // Resolve with result for supplied mode.\n    this.pendingPopupResolvePromise_(popupRedirectResult);\n  }\n  // Now that event is resolved, delete popup timeout promise.\n  if (this.popupTimeoutPromise_) {\n    this.popupTimeoutPromise_.cancel();\n    this.popupTimeoutPromise_ = null;\n  }\n  // Delete pending promises.\n  delete this.pendingPopupResolvePromise_;\n  delete this.pendingPopupRejectPromise_;\n};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n *     ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @override\n */\nfireauth.Auth.prototype.getAuthEventHandlerFinisher =\n    function(mode, opt_eventId) {\n  // Sign in events will be completed by finishPopupAndRedirectSignIn.\n  if (mode == fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT) {\n    return goog.bind(this.finishPopupAndRedirectSignIn, this);\n  } else if (mode == fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP &&\n             this.popupEventId_ == opt_eventId &&\n             this.pendingPopupResolvePromise_) {\n    return goog.bind(this.finishPopupAndRedirectSignIn, this);\n  }\n  return null;\n};\n\n\n/**\n * Finishes the popup and redirect sign in operations.\n * @param {string} requestUri The callback url with the oauth response.\n * @param {string} sessionId The session id used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.finishPopupAndRedirectSignIn =\n    function(requestUri, sessionId, tenantId, opt_postBody) {\n  var self = this;\n  // Verify assertion request.\n  var request = {\n    'requestUri': requestUri,\n    'postBody': opt_postBody,\n    'sessionId': sessionId,\n    // Even if tenant ID is null, still pass it to RPC handler explicitly so\n    // that it won't be overridden by RPC handler's tenant ID.\n    'tenantId': tenantId\n  };\n  // Now that popup has responded, delete popup timeout promise.\n  if (this.popupTimeoutPromise_) {\n    this.popupTimeoutPromise_.cancel();\n    this.popupTimeoutPromise_ = null;\n  }\n  // When state is ready, run verify assertion request.\n  // This will only run either after initial and redirect state is ready for\n  // popups or after initial state is ready for redirect resolution.\n  return self.authStateLoaded_.then(function() {\n    return self.signInWithIdTokenProvider_(\n        self.rpcHandler_.verifyAssertion(request));\n  });\n};\n\n\n/**\n * @return {string} The generated event ID used to identify a popup event.\n * @private\n */\nfireauth.Auth.prototype.generateEventId_ = function() {\n  return fireauth.util.generateEventId();\n};\n\n\n/**\n * Signs in to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithPopup = function(provider) {\n  // Check if popup and redirect are supported in this environment.\n  if (!fireauth.util.isPopupRedirectSupported()) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  var mode = fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP;\n  var self = this;\n  // Popup the window immediately to make sure the browser associates the\n  // popup with the click that triggered it.\n\n  // Get provider settings.\n  var settings = fireauth.idp.getIdpSettings(provider['providerId']);\n  // There could multiple sign in with popup events in different windows.\n  // We need to match the correct popup to the correct pending promise.\n  var eventId = this.generateEventId_();\n  // If incapable of redirecting popup from opener, popup destination URL\n  // directly. This could also happen in a sandboxed iframe.\n  var oauthHelperWidgetUrl = null;\n  if ((!fireauth.util.runsInBackground() || fireauth.util.isIframe()) &&\n      this.app_().options['authDomain'] &&\n      provider['isOAuthProvider']) {\n    oauthHelperWidgetUrl =\n        fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n            this.app_().options['authDomain'],\n            this.app_().options['apiKey'],\n            this.app_().name,\n            mode,\n            provider,\n            null,\n            eventId,\n            firebase.SDK_VERSION || null,\n            null,\n            null,\n            this.getTenantId());\n  }\n  // The popup must have a name, otherwise when successive popups are triggered\n  // they will all render in the same instance and none will succeed since the\n  // popup cancel of first window will close the shared popup window instance.\n  var popupWin =\n      fireauth.util.popup(\n          oauthHelperWidgetUrl,\n          fireauth.util.generateRandomString(),\n          settings && settings.popupWidth,\n          settings && settings.popupHeight);\n  // Auth event manager must be available for popup sign in to be possible.\n  var p = this.getAuthEventManager_().then(function(manager) {\n    // Process popup request tagging it with newly created event ID.\n    return manager.processPopup(\n        popupWin, mode, provider, eventId, !!oauthHelperWidgetUrl,\n        self.getTenantId());\n  }).then(function() {\n    return new goog.Promise(function(resolve, reject) {\n      // Expire other pending promises if still available..\n      self.resolvePendingPopupEvent(\n          mode,\n          null,\n          new fireauth.AuthError(fireauth.authenum.Error.EXPIRED_POPUP_REQUEST),\n          // Existing pending popup event ID.\n          self.popupEventId_);\n      // Save current pending promises.\n      self.pendingPopupResolvePromise_ = resolve;\n      self.pendingPopupRejectPromise_ = reject;\n      // Overwrite popup event ID with new one corresponding to popup.\n      self.popupEventId_ = eventId;\n      // Keep track of timeout promise to cancel it on promise resolution before\n      // it times out.\n      self.popupTimeoutPromise_ =\n          self.authEventManager_.startPopupTimeout(\n              self, mode, /** @type {!Window} */ (popupWin), eventId);\n    });\n  }).then(function(result) {\n    // On resolution, close popup if still opened and pass result through.\n    if (popupWin) {\n      fireauth.util.closeWindow(popupWin);\n    }\n    if (result) {\n      return fireauth.object.makeReadonlyCopy(result);\n    }\n    return null;\n  }).thenCatch(function(error) {\n    if (popupWin) {\n      fireauth.util.closeWindow(popupWin);\n    }\n    throw error;\n  });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * Signs in to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signInWithRedirect = function(provider) {\n  // Check if popup and redirect are supported in this environment.\n  if (!fireauth.util.isPopupRedirectSupported()) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  var self = this;\n  var mode = fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT;\n  // Auth event manager must be available for sign in via redirect to be\n  // possible.\n  var p = this.getAuthEventManager_().then(function(manager) {\n    // Remember current persistence to apply it on the next page.\n    // This is the only time the state is passed to the next page (when user is\n    // not already logged in).\n    // This is not needed for link and reauthenticate as the user is already\n    // stored with specified persistence.\n    return self.userStorageManager_.savePersistenceForRedirect();\n  }).then(function() {\n    // Process redirect operation.\n    return self.authEventManager_.processRedirect(\n        mode, provider, undefined, self.getTenantId());\n  });\n  return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.Auth.prototype.getRedirectResultWithoutClearing_ = function() {\n  // Check if popup and redirect are supported in this environment.\n  if (!fireauth.util.isPopupRedirectSupported()) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n  }\n  var self = this;\n  // Auth event manager must be available for get redirect result to be\n  // possible.\n  var p = this.getAuthEventManager_().then(function(manager) {\n    // Return redirect result when resolved.\n    return self.authEventManager_.getRedirectResult();\n  }).then(function(result) {\n    if (result) {\n      return fireauth.object.makeReadonlyCopy(result);\n    }\n    return null;\n  });\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * In addition to returning the redirect result as in\n * `getRedirectResultWithoutClearing_`, this will also clear the cached\n * redirect result for security reasons.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.getRedirectResult = function() {\n  return this.getRedirectResultWithoutClearing_()\n        .then((result) => {\n          if (this.authEventManager_) {\n            this.authEventManager_.clearRedirectResult();\n          }\n          return result;\n        })\n        .thenCatch((error) => {\n          if (this.authEventManager_) {\n            this.authEventManager_.clearRedirectResult();\n          }\n          throw error;\n        });\n};\n\n\n/**\n * Asynchronously sets the provided user as currentUser on the current Auth\n * instance.\n * @param {?fireauth.AuthUser} user The user to be copied to Auth instance.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.updateCurrentUser = function(user) {\n  if (!user) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.NULL_USER));\n  }\n  if (this.tenantId_ != user['tenantId']) {\n    return goog.Promise.reject(new fireauth.AuthError(\n        fireauth.authenum.Error.TENANT_ID_MISMATCH));\n  }\n  var self = this;\n  var options = {};\n  options['apiKey'] = this.app_().options['apiKey'];\n  options['authDomain'] = this.app_().options['authDomain'];\n  options['appName'] = this.app_().name;\n  var newUser = fireauth.AuthUser.copyUser(user, options,\n      self.redirectUserStorageManager_, self.getFramework());\n  return this.registerPendingPromise_(\n      this.redirectStateIsReady_.then(function() {\n        if (self.app_().options['apiKey'] != user.getApiKey()) {\n          // Throws auth/invalid-user-token if user doesn't belong to app.\n          // Throws auth/user-token-expired if token expires.\n          return newUser.reload();\n        }\n      }).then(function() {\n        if (self.currentUser_() && user['uid'] == self.currentUser_()['uid']) {\n          // Same user signed in. Update user data and notify Auth listeners.\n          // No need to resubscribe to user events.\n          // TODO: Check if the user to copy is older than current user and skip\n          // the copy logic in that case.\n          self.currentUser_().copy(user);\n          return self.handleUserStateChange_(user);\n        }\n        self.setCurrentUser_(newUser);\n        // Enable popup and redirect events.\n        newUser.enablePopupRedirect();\n        // Save user changes.\n        return self.handleUserStateChange_(newUser);\n      }).then(function(user) {\n        self.notifyAuthListeners_();\n      }));\n};\n\n\n/**\n * Completes the headless sign in with the server response containing the STS\n * access and refresh tokens, and sets the Auth user as current user while\n * setting all listeners to it and saving it to storage.\n * @param {!Object<string, string>} idTokenResponse The ID token response from\n *     the server.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signInWithIdTokenResponse =\n    function(idTokenResponse) {\n  var self = this;\n  var options = {};\n  options['apiKey'] = self.app_().options['apiKey'];\n  options['authDomain'] = self.app_().options['authDomain'];\n  options['appName'] = self.app_().name;\n  // Wait for state to be ready.\n  // This is used internally and is also used for redirect sign in so there is\n  // no need for waiting for redirect result to resolve since redirect result\n  // depends on it.\n  return this.authStateLoaded_.then(function() {\n    // Initialize an Auth user using the provided ID token response.\n    return fireauth.AuthUser.initializeFromIdTokenResponse(\n        options,\n        idTokenResponse,\n        /** @type {!fireauth.storage.RedirectUserManager} */ (\n            self.redirectUserStorageManager_),\n        // Pass frameworks so they are logged in getAccountInfo while populating\n        // the user info.\n        self.getFramework());\n  }).then(function(user) {\n    // Check if the same user is already signed in.\n    if (self.currentUser_() &&\n        user['uid'] == self.currentUser_()['uid']) {\n      // Same user signed in. Update user data and notify Auth listeners.\n      // No need to resubscribe to user events.\n      self.currentUser_().copy(user);\n      return self.handleUserStateChange_(user);\n    }\n    // New user.\n    // Set current user and attach all listeners to it.\n    self.setCurrentUser_(user);\n    // Enable popup and redirect events.\n    user.enablePopupRedirect();\n    // Save user changes.\n    return self.handleUserStateChange_(user);\n  }).then(function() {\n    // Notify external Auth listeners only when state is ready.\n    self.notifyAuthListeners_();\n  });\n};\n\n\n/**\n * Updates the current auth user and attaches event listeners to changes on it.\n * Also removes all event listeners from previously signed in user.\n * @param {?fireauth.AuthUser} user The current user instance.\n * @private\n */\nfireauth.Auth.prototype.setCurrentUser_ = function(user) {\n  // Must be called first before updating currentUser reference.\n  this.attachEventListeners_(user);\n  // Update currentUser property.\n  fireauth.object.setReadonlyProperty(this, 'currentUser', user);\n  if (user) {\n    // If a user is available, set the language code on it and set current Auth\n    // instance as language code change dispatcher.\n    this.setUserLanguage_(user);\n    // Set the current frameworks used on the user and set current Auth instance\n    // as the framework change dispatcher.\n    this.setUserFramework_(user);\n  }\n};\n\n\n/**\n * Signs out the current user while deleting the Auth user from storage and\n * removing all listeners from it.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signOut = function() {\n  var self = this;\n  // Wait for final state to be ready first, otherwise a signed out user could\n  // come back to life.\n  var p = this.redirectStateIsReady_.then(function() {\n    // Clear any cached redirect result on sign out, even if user is already\n    // signed out. For example, sign in could fail due to account conflict\n    // error, the error in redirect result should still be cleared. There is\n    // also the use case where you keep a reference to a signed out user and\n    // call signedOutUser.linkWithRedirect(provider). Even though the user is\n    // signed out, getRedirectResult() will resolve with the modified signed\n    // out user. This could also throw an error\n    // (provider already linked, etc).\n    if (self.authEventManager_) {\n      self.authEventManager_.clearRedirectResult();\n    }\n    // Ignore if already signed out.\n    if (!self.currentUser_()) {\n      return goog.Promise.resolve();\n    }\n    // Detach all event listeners.\n    // Set current user to null.\n    self.setCurrentUser_(null);\n    // Remove current user from storage\n    return /** @type {!fireauth.storage.UserManager} */ (\n        self.userStorageManager_).removeCurrentUser()\n        .then(function() {\n          // Notify external Auth listeners of this Auth change event.\n          self.notifyAuthListeners_();\n        });\n  });\n  return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * @return {!goog.Promise} A promise that resolved when any stored redirect user\n *     is loaded and removed from session storage and then stored locally.\n * @private\n */\nfireauth.Auth.prototype.initRedirectUser_ = function() {\n  var self = this;\n  var authDomain = this.app_().options['authDomain'];\n  // Get any saved redirect user and delete from session storage.\n  // Override user's authDomain with app's authDomain if there is a mismatch.\n  var p = /** @type {!fireauth.storage.RedirectUserManager} */ (\n      this.redirectUserStorageManager_).getRedirectUser(authDomain)\n          .then(function(user) {\n            // Save redirect user.\n            self.redirectUser_ = user;\n            if (user) {\n              // Set redirect storage manager on user.\n              user.setRedirectStorageManager(\n                  /** @type {!fireauth.storage.RedirectUserManager} */ (\n                      self.redirectUserStorageManager_));\n            }\n            // Delete redirect user.\n            return /** @type {!fireauth.storage.RedirectUserManager} */ (\n                self.redirectUserStorageManager_).removeRedirectUser();\n          });\n  return /** @type {!goog.Promise<undefined>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * Loads the initial Auth state for current application from web storage and\n * initializes Auth user accordingly to reflect that state. This routine does\n * not wait for any pending redirect result to be resolved.\n * @return {!goog.Promise<undefined>} Promise that resolves when state is ready,\n *     loaded from storage.\n * @private\n */\nfireauth.Auth.prototype.initAuthState_ = function() {\n  // Load current user from storage.\n  var self = this;\n  var authDomain = this.app_().options['authDomain'];\n  // Get any saved redirected user first.\n  var p = this.initRedirectUser_().then(function() {\n    // Override user's authDomain with app's authDomain if there is a mismatch.\n    return /** @type {!fireauth.storage.UserManager} */ (\n        self.userStorageManager_).getCurrentUser(authDomain);\n  }).then(function(user) {\n    // Logged in user.\n    if (user) {\n      // Set redirect storage manager on user.\n      user.setRedirectStorageManager(\n          /** @type {!fireauth.storage.RedirectUserManager} */ (\n              self.redirectUserStorageManager_));\n      // If the current user is undergoing a redirect operation, do not reload\n      // as that could could potentially delete the user if the token is\n      // expired. Instead any token problems will be detected via the\n      // verifyAssertion flow or the remaining flow. This is critical for\n      // reauthenticateWithRedirect as this flow is potentially used to recover\n      // from a token expiration error.\n      if (self.redirectUser_ &&\n          self.redirectUser_.getRedirectEventId() ==\n          user.getRedirectEventId()) {\n        return user;\n      }\n      // Confirm user valid first before setting listeners.\n      return user.reload().then(function() {\n        // Force user saving after reload as state change listeners not\n        // subscribed yet below via setCurrentUser_. Changes may have happened\n        // externally such as email actions or changes on another device.\n        return self.userStorageManager_.setCurrentUser(user).then(function() {\n          return user;\n        });\n      }).thenCatch(function(error) {\n        if (error['code'] == 'auth/network-request-failed') {\n          // Do not delete the user from storage if connection is lost or app is\n          // offline.\n          return user;\n        }\n        // Invalid user, could be deleted, remove from storage and resolve with\n        // null.\n        return /** @type {!fireauth.storage.UserManager} */(\n            self.userStorageManager_).removeCurrentUser();\n      });\n    }\n    // No logged in user, resolve with null;\n    return null;\n  }).then(function(user) {\n    // Even though state not ready yet pending any redirect result.\n    // Current user needs to be available for link with redirect to complete.\n    // This will also set listener on the user changes in case state changes\n    // occur they would get updated in storage too.\n    self.setCurrentUser_(user || null);\n  });\n  // In case the app is deleted before it is initialized with state from\n  // storage.\n  return /** @type {!goog.Promise<undefined>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * After initial Auth state is loaded, waits for any pending redirect result,\n * resolves it and then adds the external Auth state change listeners and\n * triggers first state of all observers.\n * @return {!goog.Promise<undefined>} Promise that resolves when state is ready\n *     taking into account any pending redirect result.\n * @private\n */\nfireauth.Auth.prototype.initAuthRedirectState_ = function() {\n  var self = this;\n  // Wait first for state to be loaded from storage.\n  return this.authStateLoaded_.then(function() {\n    // Resolve any pending redirect result.\n    return self.getRedirectResultWithoutClearing_();\n  }).thenCatch(function(error) {\n    // Ignore any error in the process. Redirect could be not supported.\n    return;\n  }).then(function() {\n    // Make sure instance was not deleted before proceeding.\n    if (self.deleted_) {\n      return;\n    }\n    // Between init Auth state and get redirect result resolution there\n    // could have been a sign in attempt in another window.\n    // Force sync and then add listener to run sync on change below.\n    return self.getSyncAuthUserChanges_();\n  }).thenCatch(function(error) {\n    // Ignore any error in the process.\n    return;\n  }).then(function() {\n    // Now that final state is ready, make sure instance was not deleted before\n    // proceeding.\n    if (self.deleted_) {\n      return;\n    }\n    // Initial state has been resolved.\n    self.isStateResolved_ = true;\n    // Add user state change listener so changes are synchronized with\n    // other windows and tabs.\n    /** @type {!fireauth.storage.UserManager} */ (self.userStorageManager_\n        ).addCurrentUserChangeListener(self.getSyncAuthUserChanges_);\n  });\n};\n\n\n/**\n * Synchronizes current Auth to stored auth state, used when external state\n * changes occur.\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.Auth.prototype.syncAuthUserChanges_ = function() {\n  // Get Auth user state from storage and compare to current state.\n  // Safe to run when no external change is detected.\n  var self = this;\n  var authDomain = this.app_().options['authDomain'];\n  // Override user's authDomain with app's authDomain if there is a mismatch.\n  return /** @type {!fireauth.storage.UserManager} */ (\n      this.userStorageManager_).getCurrentUser(authDomain)\n      .then(function(user) {\n        // In case this was deleted.\n        if (self.deleted_) {\n          return;\n        }\n        // Since the authDomain could be modified here, saving to storage here\n        // could trigger an infinite loop of changes between this tab and\n        // another tab using different Auth domain but since sync Auth user\n        // changes does not save changes to storage, except for getToken below\n        // if the token needs refreshing but will stop triggering the first time\n        // the token is refreshed on one of the first tab that refreshes it.\n        // The latter should not happen anyway since getToken should be valid\n        // at all times since anything that triggers the storage change should\n        // have communicated with the backend and that requires a valid token.\n        // In addition, authDomain difference is an edge case to begin with.\n\n        // If the same user is to be synchronized.\n        if (self.currentUser_() &&\n            user &&\n            self.currentUser_().hasSameUserIdAs(user)) {\n          // Data update, simply copy data changes.\n          self.currentUser_().copy(user);\n          // If tokens changed from previous user tokens, this will trigger\n          // notifyAuthListeners_.\n          return self.currentUser_().getIdToken();\n        } else if (!self.currentUser_() && !user) {\n          // No change, do nothing (was signed out and remained signed out).\n          return;\n        } else {\n          // Update current Auth state. Either a new login or logout.\n          self.setCurrentUser_(user);\n          // If a new user is signed in, enabled popup and redirect on that\n          // user.\n          if (user) {\n            user.enablePopupRedirect();\n            // Set redirect storage manager on user.\n            user.setRedirectStorageManager(\n                /** @type {!fireauth.storage.RedirectUserManager} */ (\n                    self.redirectUserStorageManager_));\n          }\n          if (self.authEventManager_) {\n            self.authEventManager_.subscribe(self);\n          }\n          // Notify external Auth changes of Auth change event.\n          self.notifyAuthListeners_();\n        }\n      });\n};\n\n\n/**\n * Updates the language code on the provided user and configures the user to\n * listen to the Auth instance for any language code changes.\n * @param {!fireauth.AuthUser} user The user to whose language needs to be set.\n * @private\n */\nfireauth.Auth.prototype.setUserLanguage_ = function(user) {\n  // Sets the current language code on the user.\n  user.setLanguageCode(this.getLanguageCode());\n  // Sets current Auth instance as language code change dispatcher on the user.\n  user.setLanguageCodeChangeDispatcher(this);\n};\n\n\n/**\n * Handles user state changes.\n * @param {!fireauth.AuthUser} user The user which triggered the state changes.\n * @return {!goog.Promise} The promise that resolves when state changes are\n *     handled.\n * @private\n */\nfireauth.Auth.prototype.handleUserStateChange_ = function(user) {\n  // Save Auth user state changes.\n  return /** @type {!fireauth.storage.UserManager} */ (\n      this.userStorageManager_).setCurrentUser(user);\n};\n\n\n/**\n * Handles user token changes.\n * @param {!Object} event The token change event.\n * @private\n */\nfireauth.Auth.prototype.handleUserTokenChange_ = function(event) {\n  // This is only called when user is ready and Auth state has been resolved.\n  // Notify external Auth change listeners.\n  this.notifyAuthListeners_();\n  // Save user token changes.\n  this.handleUserStateChange_(/** @type {!fireauth.AuthUser} */ (\n      this.currentUser_()));\n};\n\n\n/**\n * Handles user deletion events.\n * @param {!Object} event The user delete event.\n * @private\n */\nfireauth.Auth.prototype.handleUserDelete_ = function(event) {\n  // A deleted user will be treated like a sign out event.\n  this.signOut();\n};\n\n\n/**\n * Handles user invalidation events.\n * @param {!Object} event The user invalidation event.\n * @private\n */\nfireauth.Auth.prototype.handleUserInvalidated_ = function(event) {\n  // An invalidated user will be treated like a sign out event.\n  this.signOut();\n};\n\n\n/**\n * Detaches all previous listeners on current user and reattach new listeners to\n * provided user if not null.\n * @param {?fireauth.AuthUser} user The user to attach event listeners to.\n * @private\n */\nfireauth.Auth.prototype.attachEventListeners_ = function(user) {\n  // Remove existing event listeners from previous current user if available.\n  if (this.currentUser_()) {\n    this.currentUser_().removeStateChangeListener(\n        this.userStateChangeListener_);\n    goog.events.unlisten(\n        this.currentUser_(),\n        fireauth.UserEventType.TOKEN_CHANGED,\n        this.userTokenChangeListener_);\n    goog.events.unlisten(\n        this.currentUser_(),\n        fireauth.UserEventType.USER_DELETED,\n        this.userDeleteListener_);\n    goog.events.unlisten(\n        this.currentUser_(),\n        fireauth.UserEventType.USER_INVALIDATED,\n        this.userInvalidatedListener_);\n    // Stop proactive token refresh on the current user.\n    this.currentUser_().stopProactiveRefresh();\n  }\n  // If a new user is provided, attach event listeners to state, token, user\n  // invalidation and delete events.\n  if (user) {\n    user.addStateChangeListener(this.userStateChangeListener_);\n    goog.events.listen(\n        user,\n        fireauth.UserEventType.TOKEN_CHANGED,\n        this.userTokenChangeListener_);\n    goog.events.listen(\n        user,\n        fireauth.UserEventType.USER_DELETED,\n        this.userDeleteListener_);\n     goog.events.listen(\n        user,\n        fireauth.UserEventType.USER_INVALIDATED,\n        this.userInvalidatedListener_);\n    // Start proactive token refresh on new user if there is at least one\n    // Firebase service subscribed to Auth changes.\n    if (this.firebaseServices_ > 0) {\n      user.startProactiveRefresh();\n    }\n  }\n};\n\n\n/**\n * Signs in with ID token promise provider.\n * @param {!goog.Promise<!Object>} idTokenPromise\n *     The rpc handler method that returns a promise which resolves with an ID\n *     token.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.Auth.prototype.signInWithIdTokenProvider_ = function(idTokenPromise) {\n  var self = this;\n  var credential = null;\n  var additionalUserInfo = null;\n  return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n      this.registerPendingPromise_(\n          idTokenPromise\n          .then(function(idTokenResponse) {\n            // Get credential if available in the response.\n            credential = fireauth.AuthProvider.getCredentialFromResponse(\n                idTokenResponse);\n            // Get additional IdP data if available in the response.\n            additionalUserInfo = fireauth.AdditionalUserInfo.fromPlainObject(\n                idTokenResponse);\n            // When custom token is exchanged for idToken, continue sign in with\n            // ID token and return firebase Auth user.\n            return self.signInWithIdTokenResponse(idTokenResponse);\n          }, function(error) {\n            // Catch the MFA_REQUIRED error rejected in ID token promise and\n            // repackage it into a multi-factor error with additional IdP data\n            // if available.\n            var multiFactorError = null;\n            if (error && error['code'] === 'auth/multi-factor-auth-required') {\n              multiFactorError = fireauth.MultiFactorError.fromPlainObject(\n                  error.toPlainObject(),\n                  self,\n                  goog.bind(self.handleMultiFactorIdTokenResolver_, self));\n            }\n            throw multiFactorError || error;\n          })\n          .then(function() {\n            // Resolve promise with a readonly user credential object.\n            return fireauth.object.makeReadonlyCopy({\n              // Return the current user reference.\n              'user': self.currentUser_(),\n              // Return any credential passed from the backend.\n              'credential': credential,\n              // Return any additional IdP data passed from the backend.\n              'additionalUserInfo': additionalUserInfo,\n              // Sign in operation type.\n              'operationType': fireauth.constants.OperationType.SIGN_IN\n            });\n          })));\n};\n\n\n/**\n * Completes multi-factor sign-in with ID token response and additional IdP data\n * if available.\n * @param {{idToken: string, refreshToken: string}} response The successful\n *     sign-in response containing the new ID tokens.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A Promise that\n *     resolves with the updated `UserCredential`.\n * @private\n */\nfireauth.Auth.prototype.handleMultiFactorIdTokenResolver_ =\n    function(response) {\n  var self = this;\n  // Wait for state to be ready and then finish sign-in.\n  return this.redirectStateIsReady_.then(function() {\n    return self.signInWithIdTokenProvider_(goog.Promise.resolve(response));\n  });\n};\n\n\n/**\n * Initializes the Auth state change observer returned by the\n * firebase.INTERNAL.createSubscribe helper.\n * @param {!firebase.Observer} observer The Auth state change observer.\n * @private\n */\nfireauth.Auth.prototype.initIdTokenChangeObserver_ = function(observer) {\n  var self = this;\n  // Adds a listener that will transmit the event everytime it's called.\n  this.addAuthTokenListener(function(accessToken) {\n    observer.next(self.currentUser_());\n  });\n};\n\n\n/**\n * Initializes the user state change observer returned by the\n * firebase.INTERNAL.createSubscribe helper.\n * @param {!firebase.Observer} observer The user state change observer.\n * @private\n */\nfireauth.Auth.prototype.initUserStateObserver_ = function(observer) {\n  var self = this;\n  // Adds a listener that will transmit the event everytime it's called.\n  this.addUserChangeListener_(function(accessToken) {\n    observer.next(self.currentUser_());\n  });\n};\n\n\n/**\n * Adds an observer for Auth state changes, we need to wrap the call as\n * the args checking code needs a method defined on the prototype this way,\n * not within the constructor, and we also have to implement the behavior\n * that will trigger an observer right away if state is ready.\n * @param {!firebase.Observer|function(?fireauth.AuthUser)}\n *     nextOrObserver An observer object or a function triggered on change.\n * @param {function(!fireauth.AuthError)=} opt_error Optional A function\n *     triggered on Auth error.\n * @param {function()=} opt_completed Optional A function triggered when the\n *     observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\nfireauth.Auth.prototype.onIdTokenChanged = function(\n    nextOrObserver, opt_error, opt_completed) {\n  var self = this;\n  // State already determined. Trigger immediately, otherwise initState will\n  // take care of notifying all pending listeners on initialization.\n  // In this case we do not trigger synchronously and trigger via a resolved\n  // promise as required by specs.\n  if (this.isStateResolved_) {\n    // The observer cannot be called synchronously. We're using the\n    // native Promise implementation as otherwise it creates weird behavior\n    // where the order of promises resolution would not be as expected.\n    // It is due to the fact fireauth and firebase.app use their own\n    // and different promises library and this leads to calls resolutions order\n    // being different from the promises registration order.\n    Promise.resolve().then(function() {\n      if (typeof nextOrObserver === 'function') {\n        nextOrObserver(self.currentUser_());\n      } else if (typeof nextOrObserver['next'] === 'function') {\n        nextOrObserver['next'](self.currentUser_());\n      }\n    });\n  }\n  return this.onIdTokenChanged_(\n      /** @type {!firebase.Observer|function(*)|undefined} */ (nextOrObserver),\n      /** @type {function(!Error)|undefined} */ (opt_error),\n      opt_completed);\n};\n\n\n/**\n * Adds an observer for user state changes, we need to wrap the call as\n * the args checking code needs a method defined on the prototype this way,\n * not within the constructor, and we also have to implement the behavior\n * that will trigger an observer right away if state is ready.\n * @param {!firebase.Observer|function(?fireauth.AuthUser)}\n *     nextOrObserver An observer object or a function triggered on change.\n * @param {function(!fireauth.AuthError)=} opt_error Optional A function\n *     triggered on Auth error.\n * @param {function()=} opt_completed Optional A function triggered when the\n *     observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\nfireauth.Auth.prototype.onAuthStateChanged = function(\n    nextOrObserver, opt_error, opt_completed) {\n  var self = this;\n  // State already determined. Trigger immediately, otherwise initState will\n  // take care of notifying all pending listeners on initialization.\n  // In this case we do not trigger synchronously and trigger via a resolved\n  // promise as required by specs.\n  if (this.isStateResolved_) {\n    // The observer cannot be called synchronously. We're using the\n    // native Promise implementation as otherwise it creates weird behavior\n    // where the order of promises resolution would not be as expected.\n    // It is due to the fact fireauth and firebase.app use their own\n    // and different promises library and this leads to calls resolutions order\n    // being different from the promises registration order.\n    Promise.resolve().then(function() {\n      // This ensures that the first time notifyAuthListeners_ is triggered,\n      // it has the correct UID before triggering the user state change\n      // listeners.\n      self.userStateChangeUid_ = self.getUid();\n      if (typeof nextOrObserver === 'function') {\n        nextOrObserver(self.currentUser_());\n      } else if (typeof nextOrObserver['next'] === 'function') {\n        nextOrObserver['next'](self.currentUser_());\n      }\n    });\n  }\n  return this.onUserStateChanged_(\n      /** @type {!firebase.Observer|function(*)|undefined} */ (nextOrObserver),\n      /** @type {function(!Error)|undefined} */ (opt_error),\n      opt_completed);\n};\n\n\n/**\n * Returns an STS token. If the cached one is unexpired it is directly returned.\n * Otherwise the existing ID token or refresh token is exchanged for a new one.\n * If there is no user signed in, returns null.\n *\n * This method is called getIdTokenInternal as the symbol getIdToken is not\n * obfuscated, which could lead to developers incorrectly calling\n * firebase.auth().getIdToken().\n *\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<?Object>}\n */\nfireauth.Auth.prototype.getIdTokenInternal = function(opt_forceRefresh) {\n  var self = this;\n  // Wait for state to be ready.\n  var p = this.redirectStateIsReady_.then(function() {\n    // Call user's underlying getIdToken method.\n    if (self.currentUser_()) {\n      return self.currentUser_().getIdToken(opt_forceRefresh)\n          .then(function(stsAccessToken) {\n            // This is used internally by other services which expect the access\n            // token to be returned in an object.\n            return {\n              'accessToken': stsAccessToken\n            };\n          });\n    }\n    // No logged in user, return null token.\n    return null;\n  });\n  return /** @type {!goog.Promise<?Object>} */ (\n      this.registerPendingPromise_(p));\n};\n\n\n/**\n * Signs in a user asynchronously using a custom token and returns any\n * additional user info data or credentials returned form the backend.\n * @param {string} token The custom token to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithCustomToken = function(token) {\n  var self = this;\n  // Wait for the redirect state to be determined before proceeding. If critical\n  // errors like web storage unsupported are detected, fail before RPC, instead\n  // of after.\n  return this.redirectStateIsReady_.then(function() {\n    return self.signInWithIdTokenProvider_(\n        self.getRpcHandler().verifyCustomToken(token));\n  }).then(function(result) {\n    var user = result['user'];\n    // Manually sets the isAnonymous flag to false as the GetAccountInfo\n    // response will look like an anonymous user (no credentials visible).\n    user.updateProperty('isAnonymous', false);\n    // Save isAnonymous flag changes to current user in storage.\n    self.handleUserStateChange_(user);\n    return result;\n  });\n};\n\n\n/**\n * Sign in using an email and password and returns any additional user info\n * data or credentials returned form the backend.\n * @param {string} email The email to sign in with.\n * @param {string} password The password to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithEmailAndPassword =\n    function(email, password) {\n  var self = this;\n  // Wait for the redirect state to be determined before proceeding. If critical\n  // errors like web storage unsupported are detected, fail before RPC, instead\n  // of after.\n  return this.redirectStateIsReady_.then(function() {\n    return self.signInWithIdTokenProvider_(\n        self.getRpcHandler().verifyPassword(email, password));\n  });\n};\n\n\n/**\n * Creates a new email and password account and returns any additional user\n * info data or credentials returned form the backend.\n * @param {string} email The email to sign up with.\n * @param {string} password The password to sign up with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.createUserWithEmailAndPassword =\n    function(email, password) {\n  var self = this;\n  // Wait for the redirect state to be determined before proceeding. If critical\n  // errors like web storage unsupported are detected, fail before RPC, instead\n  // of after.\n  return this.redirectStateIsReady_.then(function() {\n    return self.signInWithIdTokenProvider_(\n        self.getRpcHandler().createAccount(email, password));\n  });\n};\n\n\n/**\n * Logs into Firebase with the given 3rd party credentials and returns any\n * additional user info data or credentials returned form the backend.\n * @param {!fireauth.AuthCredential} credential The Auth credential.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithCredential = function(credential) {\n  // Credential could be extended in the future, so leave it to credential to\n  // decide how to retrieve ID token.\n  var self = this;\n  // Wait for the redirect state to be determined before proceeding. If critical\n  // errors like web storage unsupported are detected, fail before RPC, instead\n  // of after.\n  return this.redirectStateIsReady_.then(function() {\n    // Return the full response object and not just the user.\n    return self.signInWithIdTokenProvider_(\n        credential.getIdTokenProvider(self.getRpcHandler()));\n  });\n};\n\n\n/**\n * Logs into Firebase with the given 3rd party credentials and returns any\n * additional user info data or credentials returned form the backend. It has\n * been deprecated in favor of signInWithCredential.\n * @param {!fireauth.AuthCredential} credential The Auth credential.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInAndRetrieveDataWithCredential =\n    function(credential) {\n  fireauth.deprecation.log(\n      fireauth.deprecation.Deprecations.SIGN_IN_WITH_CREDENTIAL);\n  return this.signInWithCredential(credential);\n};\n\n\n/**\n * Signs in a user anonymously and returns any additional user info data or\n * credentials returned form the backend.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInAnonymously = function() {\n  var self = this;\n  // Wait for the redirect state to be determined before proceeding. If critical\n  // errors like web storage unsupported are detected, fail before RPC, instead\n  // of after.\n  return this.redirectStateIsReady_.then(function() {\n    var user = self.currentUser_();\n    // If an anonymous user is already signed in, no need to sign him again.\n    if (user && user['isAnonymous']) {\n      var additionalUserInfo = fireauth.object.makeReadonlyCopy({\n        'providerId': null,\n        'isNewUser': false\n      });\n      return fireauth.object.makeReadonlyCopy({\n        // Return the signed in user reference.\n        'user': user,\n        // Do not return credential for anonymous user.\n        'credential': null,\n        // Return any additional IdP data.\n        'additionalUserInfo': additionalUserInfo,\n        // Sign in operation type.\n        'operationType': fireauth.constants.OperationType.SIGN_IN\n      });\n    } else {\n      // No anonymous user currently signed in.\n      return self.signInWithIdTokenProvider_(\n          self.getRpcHandler().signInAnonymously())\n          .then(function(result) {\n            var user = result['user'];\n            // Manually sets the isAnonymous flag to true as\n            // initializeFromIdTokenResponse uses the default value of false and\n            // even though getAccountInfo sets that to true, it will be reverted\n            // to false in reloadWithoutSaving.\n            // TODO: consider optimizing this and cleaning these manual\n            // overwrites.\n            user.updateProperty('isAnonymous', true);\n            // Save isAnonymous flag changes to current user in storage.\n            self.handleUserStateChange_(user);\n            return result;\n          });\n    }\n  });\n};\n\n\n/**\n * @return {string} The key used for storing Auth state.\n */\nfireauth.Auth.prototype.getStorageKey = function() {\n  return fireauth.util.createStorageKey(\n      this.app_().options['apiKey'],\n      this.app_().name);\n};\n\n\n/**\n * @return {!firebase.app.App} The Firebase App this auth object is connected\n *     to.\n * @private\n */\nfireauth.Auth.prototype.app_ = function() {\n  return this['app'];\n};\n\n\n/**\n * @return {!fireauth.RpcHandler} The RPC handler.\n */\nfireauth.Auth.prototype.getRpcHandler = function() {\n  return this.rpcHandler_;\n};\n\n\n/**\n * @return {?fireauth.AuthUser} The currently logged in user.\n * @private\n */\nfireauth.Auth.prototype.currentUser_ = function() {\n  return this['currentUser'];\n};\n\n\n/** @return {?string} The current user UID if available, null if not. */\nfireauth.Auth.prototype.getUid = function() {\n  return (this.currentUser_() && this.currentUser_()['uid']) || null;\n};\n\n\n/**\n * @return {?string} The last cached access token.\n * @private\n */\nfireauth.Auth.prototype.getLastAccessToken_ = function() {\n  return (this.currentUser_() && this.currentUser_()['_lat']) || null;\n};\n\n\n\n/**\n * Called internally on Auth state change to notify listeners.\n * @private\n */\nfireauth.Auth.prototype.notifyAuthListeners_ = function() {\n  // Only run when state is resolved. After state is resolved, the Auth listener\n  // will always trigger.\n  if (this.isStateResolved_) {\n    for (var i = 0; i < this.authListeners_.length; i++) {\n      if (this.authListeners_[i]) {\n        this.authListeners_[i](this.getLastAccessToken_());\n      }\n    }\n    // Trigger user change only if UID changed.\n    if (this.userStateChangeUid_ !== this.getUid() &&\n        this.userChangeListeners_.length) {\n      // Update user state change UID.\n      this.userStateChangeUid_ = this.getUid();\n      // Trigger all subscribed user state change listeners.\n      for (var i = 0; i < this.userChangeListeners_.length; i++) {\n        if (this.userChangeListeners_[i]) {\n          this.userChangeListeners_[i](this.getLastAccessToken_());\n        }\n      }\n    }\n  }\n};\n\n\n/**\n * Attaches a listener function to Auth state change.\n * This is used only by internal Firebase services.\n * @param {!function(?string)} listener The auth state change listener.\n */\nfireauth.Auth.prototype.addAuthTokenListenerInternal = function(listener) {\n  this.addAuthTokenListener(listener);\n  // This is not exact science but should be good enough to detect Firebase\n  // services subscribing to Auth token changes.\n  // This is needed to start proactive token refresh on a user.\n  this.firebaseServices_++;\n  if (this.firebaseServices_ > 0 && this.currentUser_()) {\n    // Start proactive token refresh on the current user.\n    this.currentUser_().startProactiveRefresh();\n  }\n};\n\n\n/**\n * Detaches the provided listener from Auth state change event.\n * This is used only by internal Firebase services.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.removeAuthTokenListenerInternal = function(listener) {\n  // This is unlikely to be called by Firebase services. Services are unlikely\n  // to remove Auth token listeners.\n  // Make sure listener is still subscribed before decrementing.\n  var self = this;\n  goog.array.forEach(this.authListeners_, function(ele) {\n    // This covers the case where the same listener is subscribed more than\n    // once.\n    if (ele == listener) {\n      self.firebaseServices_--;\n    }\n  });\n  if (this.firebaseServices_ < 0) {\n    this.firebaseServices_ = 0;\n  }\n  if (this.firebaseServices_ == 0 && this.currentUser_()) {\n    // Stop proactive token refresh on the current user.\n    this.currentUser_().stopProactiveRefresh();\n  }\n  this.removeAuthTokenListener(listener);\n};\n\n\n/**\n * Attaches a listener function to Auth state change.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.addAuthTokenListener = function(listener) {\n  var self = this;\n  // Save listener.\n  this.authListeners_.push(listener);\n  // Make sure redirect state is ready and then trigger listener.\n  this.registerPendingPromise_(this.redirectStateIsReady_.then(function() {\n    // Do nothing if deleted.\n    if (self.deleted_) {\n      return;\n    }\n    // Make sure listener is still subscribed.\n    if (goog.array.contains(self.authListeners_, listener)) {\n      // Trigger the first call for this now that redirect state is resolved.\n      listener(self.getLastAccessToken_());\n    }\n  }));\n};\n\n\n/**\n * Detaches the provided listener from Auth state change event.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.removeAuthTokenListener = function(listener) {\n  // Remove from Auth listeners.\n  goog.array.removeAllIf(this.authListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n\n\n/**\n * Attaches a listener function to user state change.\n * @param {!function(?string)} listener The user state change listener.\n * @private\n */\nfireauth.Auth.prototype.addUserChangeListener_ = function(listener) {\n  var self = this;\n  // Save listener.\n  this.userChangeListeners_.push(listener);\n  // Make sure redirect state is ready and then trigger listener.\n  this.registerPendingPromise_(this.redirectStateIsReady_.then(function() {\n    // Do nothing if deleted.\n    if (self.deleted_) {\n      return;\n    }\n    // Make sure listener is still subscribed.\n    if (goog.array.contains(self.userChangeListeners_, listener)) {\n      // Confirm UID change before triggering.\n      if (self.userStateChangeUid_ !== self.getUid()) {\n        self.userStateChangeUid_ = self.getUid();\n        // Trigger the first call for this now that redirect state is resolved.\n        listener(self.getLastAccessToken_());\n      }\n    }\n  }));\n};\n\n\n/**\n * Deletes the Auth instance, handling cancellation of all pending async Auth\n * operations.\n * @return {!Promise<void>}\n */\nfireauth.Auth.prototype.delete = function() {\n  this.deleted_ = true;\n  // Cancel all pending promises.\n  for (var i = 0; i < this.pendingPromises_.length; i++) {\n    this.pendingPromises_[i].cancel(fireauth.authenum.Error.MODULE_DESTROYED);\n  }\n\n  // Empty pending promises array.\n  this.pendingPromises_ = [];\n  // Remove current user change listener.\n  if (this.userStorageManager_) {\n    this.userStorageManager_.removeCurrentUserChangeListener(\n        this.getSyncAuthUserChanges_);\n  }\n  // Unsubscribe from Auth event handling.\n  if (this.authEventManager_) {\n    this.authEventManager_.unsubscribe(this);\n    this.authEventManager_.clearRedirectResult();\n  }\n  return Promise.resolve();\n};\n\n\n/** @return {boolean} Whether Auth instance has pending promises. */\nfireauth.Auth.prototype.hasPendingPromises = function() {\n  return this.pendingPromises_.length != 0;\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.Auth.prototype.registerPendingPromise_ = function(p) {\n  var self = this;\n  // Save created promise in pending list.\n  this.pendingPromises_.push(p);\n  p.thenAlways(function() {\n    // When fulfilled, remove from pending list.\n    goog.array.remove(self.pendingPromises_, p);\n  });\n  // Return the promise.\n  return p;\n};\n\n\n/**\n * Gets the list of possible sign in methods for the given email address.\n * @param {string} email The email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.Auth.prototype.fetchSignInMethodsForEmail = function(email) {\n  return /** @type {!goog.Promise<!Array<string>>} */ (\n      this.registerPendingPromise_(\n          this.getRpcHandler().fetchSignInMethodsForIdentifier(email)));\n};\n\n\n/**\n * @param {string} emailLink The email link.\n * @return {boolean} Whether the link is a sign in with email link.\n */\nfireauth.Auth.prototype.isSignInWithEmailLink = function(emailLink) {\n  return  !!fireauth.EmailAuthProvider\n      .getActionCodeUrlFromSignInEmailLink(emailLink);\n};\n\n\n/**\n * Sends the sign-in with email link for the email account provided.\n * @param {string} email The email account to sign in with.\n * @param {!Object} actionCodeSettings The action code settings object.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.sendSignInLinkToEmail = function(\n    email, actionCodeSettings) {\n  var self = this;\n  return this.registerPendingPromise_(\n      // Wrap in promise as ActionCodeSettings constructor could throw a\n      // synchronous error if invalid arguments are specified.\n      goog.Promise.resolve()\n          .then(function() {\n            var actionCodeSettingsBuilder =\n                new fireauth.ActionCodeSettings(actionCodeSettings);\n            if (!actionCodeSettingsBuilder.canHandleCodeInApp()) {\n              throw new fireauth.AuthError(\n                  fireauth.authenum.Error.ARGUMENT_ERROR,\n                  fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP +\n                  ' must be true when sending sign in link to email');\n            }\n            return actionCodeSettingsBuilder.buildRequest();\n          }).then(function(additionalRequestData) {\n            return self.getRpcHandler().sendSignInLinkToEmail(\n                email, additionalRequestData);\n          }).then(function(email) {\n            // Do not return the email.\n          }));\n};\n\n\n/**\n * Verifies an email action code for password reset and returns a promise\n * that resolves with the associated email if verified.\n * @param {string} code The email action code to verify for password reset.\n * @return {!goog.Promise<string>}\n */\nfireauth.Auth.prototype.verifyPasswordResetCode = function(code) {\n  return this.checkActionCode(code).then(function(info) {\n    return info['data']['email'];\n  });\n};\n\n\n/**\n * Requests resetPassword endpoint for password reset, verifies the action code\n * and updates the new password, returns an empty promise.\n * @param {string} code The email action code to confirm for password reset.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<undefined, !fireauth.AuthError>}\n */\nfireauth.Auth.prototype.confirmPasswordReset = function(code, newPassword) {\n  return this.registerPendingPromise_(\n      this.getRpcHandler().confirmPasswordReset(code, newPassword)\n      .then(function(email) {\n        // Do not return the email.\n      }));\n};\n\n\n/**\n * Verifies an email action code and returns an empty promise if verified.\n * @param {string} code The email action code to verify for password reset.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.Auth.prototype.checkActionCode = function(code) {\n  return this.registerPendingPromise_(\n      this.getRpcHandler().checkActionCode(code)\n      .then(function(response) {\n        return new fireauth.ActionCodeInfo(response);\n      }));\n};\n\n\n/**\n * Applies an out-of-band email action code, such as an email verification code.\n * @param {string} code The email action code.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.applyActionCode = function(code) {\n  return this.registerPendingPromise_(\n      this.getRpcHandler().applyActionCode(code)\n      .then(function(email) {\n        // Returns nothing.\n      }));\n};\n\n\n/**\n * Sends the password reset email for the email account provided.\n * @param {string} email The email account with the password to be reset.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n *     object.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.sendPasswordResetEmail =\n    function(email, opt_actionCodeSettings) {\n  var self = this;\n  return this.registerPendingPromise_(\n      // Wrap in promise as ActionCodeSettings constructor could throw a\n      // synchronous error if invalid arguments are specified.\n      goog.Promise.resolve().then(function() {\n        if (typeof opt_actionCodeSettings !== 'undefined' &&\n            // Ignore empty objects.\n            !goog.object.isEmpty(opt_actionCodeSettings)) {\n          return new fireauth.ActionCodeSettings(\n              /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n        }\n        return {};\n      })\n      .then(function(additionalRequestData) {\n        return self.getRpcHandler().sendPasswordResetEmail(\n            email, additionalRequestData);\n      }).then(function(email) {\n        // Do not return the email.\n      }));\n};\n\n\n/**\n * Signs in with a phone number using the app verifier instance and returns a\n * promise that resolves with the confirmation result which on confirmation\n * will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n *     verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.Auth.prototype.signInWithPhoneNumber =\n    function(phoneNumber, appVerifier) {\n  return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n      this.registerPendingPromise_(fireauth.ConfirmationResult.initialize(\n          this,\n          phoneNumber,\n          appVerifier,\n          // This will wait for redirectStateIsReady to resolve first.\n          goog.bind(this.signInWithCredential, this))));\n};\n\n\n/**\n * Signs in a Firebase User with the provided email and the passwordless\n * sign-in email link.\n * @param {string} email The email account to sign in with.\n * @param {?string=} opt_link The optional link which contains the OTP needed\n *     to complete the sign in with email link. If not specified, the current\n *     URL is used instead.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithEmailLink = function(email, opt_link) {\n  return this.registerPendingPromise_(goog.Promise.resolve().then(() => {\n      const link = opt_link || fireauth.util.getCurrentUrl();\n      const credential = fireauth.EmailAuthProvider.credentialWithLink(\n          email, link);\n      // Check if the tenant ID in the email link matches the tenant ID on Auth\n      // instance.\n      const actionCodeUrl =\n          fireauth.EmailAuthProvider.getActionCodeUrlFromSignInEmailLink(link);\n      if (!actionCodeUrl) {\n        throw new fireauth.AuthError(\n            fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!');\n      }\n      if (actionCodeUrl['tenantId'] !== this.getTenantId()) {\n        throw new fireauth.AuthError(\n            fireauth.authenum.Error.TENANT_ID_MISMATCH);\n      }\n      return this.signInWithCredential(credential);\n  }));\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the mock grecaptcha utilities used for development\n * testing.\n */\ngoog.provide('fireauth.GRecaptchaMockFactory');\ngoog.provide('fireauth.RecaptchaMock');\n\ngoog.require('fireauth.grecaptcha');\ngoog.require('fireauth.util');\ngoog.require('goog.dom');\ngoog.require('goog.events');\ngoog.require('goog.events.EventType');\n\n\n/**\n * The mock grecaptcha factory.\n * @constructor\n * @implements {fireauth.grecaptcha}\n */\nfireauth.GRecaptchaMockFactory = function() {\n  /**\n   * @const @private {!Object<string, !fireauth.RecaptchaMock>} The hash map\n   *     that stores the widget ID to mock reCAPTCHA instances.\n   */\n  this.map_ = {};\n  /**\n   * @private {number} The current widget ID counter, incremented each time\n   *     a new mock reCAPTCHA is created.\n   */\n  this.counter_ = fireauth.GRecaptchaMockFactory.START_INSTANCE_ID;\n};\n\n\n/**\n * @const {number} The start ID of the first created mock reCAPTCHA.\n */\nfireauth.GRecaptchaMockFactory.START_INSTANCE_ID = 1000000000000;\n\n\n/** @const {number} The reCAPTCHA expiration time in milliseconds. */\nfireauth.GRecaptchaMockFactory.EXPIRATION_TIME_MS = 60000;\n\n\n/** @const {number} The reCAPTCHA auto solving time in milliseconds. */\nfireauth.GRecaptchaMockFactory.SOLVE_TIME_MS = 500;\n\n\n/**\n * @private {?fireauth.GRecaptchaMockFactory} The singleton instance\n *     for grecaptcha mock object.\n */\nfireauth.GRecaptchaMockFactory.instance_ = null;\n\n\n/**\n * @return {!fireauth.GRecaptchaMockFactory} The singleton grecaptcha mock\n *     instance.\n */\nfireauth.GRecaptchaMockFactory.getInstance = function() {\n  // Check if there is an existing instance. Otherwise, create one and cache it.\n  if (!fireauth.GRecaptchaMockFactory.instance_) {\n    fireauth.GRecaptchaMockFactory.instance_ =\n        new fireauth.GRecaptchaMockFactory();\n  }\n  return fireauth.GRecaptchaMockFactory.instance_;\n};\n\n\n/**\n * Creates a new instance of the mock reCAPTCHA widget.\n *\n * @param {(!Element|string)} elementOrId Element or element ID for the\n *     placeholder to render the reCAPTCHA client.\n * @param {!Object} params Parameters for the reCAPTCHA client.\n * @return {number} The client ID.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.render =\n    function(elementOrId, params) {\n  this.map_[this.counter_.toString()] =\n      new fireauth.RecaptchaMock(elementOrId, params);\n  return this.counter_++;\n};\n\n\n/**\n * Resets a reCAPTCHA with the given ID. If an ID is not provided, resets the\n * first instance.\n *\n * @param {number=} opt_id The id of the reCAPTCHA client. Defaults to the first\n *     widget created if unspecified.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.reset = function(opt_id) {\n  var mock = this.getMock_(opt_id);\n  var id = this.getId_(opt_id);\n  if (mock && id) {\n    mock.delete();\n    delete this.map_[/** @type {string} */ (id)];\n  }\n};\n\n\n/**\n * Gets the response for the client with the given ID. If an ID is not\n * provided, gets the response for the default client.\n *\n * @param {number=} opt_id The ID of the reCAPTCHA widget. Defaults to the first\n *     widget created if unspecified.\n * @return {?string}\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.getResponse = function(opt_id) {\n  var mock = this.getMock_(opt_id);\n  return mock ? mock.getResponse() : null;\n};\n\n\n/**\n * Programmatically triggers the invisible reCAPTCHA.\n *\n * @param {number=} opt_id The ID of the recaptcha client. Defaults to the first\n *     widget created if unspecified.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.execute = function(opt_id) {\n  var mock = this.getMock_(opt_id);\n  if (mock) {\n    mock.execute();\n  }\n};\n\n\n/**\n * @param {number=} opt_id The optional ID to lookup.\n * @return {?fireauth.RecaptchaMock} The corresponding reCAPTCHA mock if found.\n * @private\n */\nfireauth.GRecaptchaMockFactory.prototype.getMock_ = function(opt_id) {\n  var id = this.getId_(opt_id);\n  return id ? this.map_[id] || null : null;\n};\n\n\n/**\n * @param {number=} opt_id The optional ID to lookup.\n * @return {?string} The corresponding reCAPTCHA mock ID if found.\n * @private\n */\nfireauth.GRecaptchaMockFactory.prototype.getId_ = function(opt_id) {\n  var id = typeof opt_id === 'undefined' ?\n      fireauth.GRecaptchaMockFactory.START_INSTANCE_ID : opt_id;\n  return id ? id.toString() : null;\n};\n\n\n/**\n * Mock single reCAPTCHA instance.\n * @param {(!Element|string)} elementOrId Element or element ID for the\n *     placeholder to render the reCAPTCHA client.\n * @param {!Object} params Parameters for the reCAPTCHA client.\n * @constructor\n */\nfireauth.RecaptchaMock = function(elementOrId, params) {\n  /** @private {boolean} Whether the instance was deleted. */\n  this.deleted_ = false;\n  /** @const @private {!Object} The reCAPTCHA parameters. */\n  this.params_ = params;\n  /** @private {?string} The simulated response token if available. */\n  this.responseToken_ = null;\n  /**\n   * @private {?number} The timer ID for response callback/expiration callback\n   *     to trigger.\n   */\n  this.timerId_ = null;\n  /** @const @private {boolean} Whether the reCAPTCHA is visible or not. */\n  this.isVisible_ = this.params_['size'] !== 'invisible';\n  /**\n   * @const @private {?Element} The container or button trigger of the\n   *     reCAPTCHA.\n   */\n  this.element_ = goog.dom.getElement(elementOrId);\n  var self = this;\n  /** @private {function(?)} The on click handler for invisible reCAPTCHAs. */\n  this.onClickHandler_ = function(event) {\n    self.execute();\n  };\n  if (this.isVisible_) {\n    // For a visible reCAPTCHA, simulate reCAPTCHA continuously solved\n    // and then expired.\n    this.execute();\n  } else {\n    // Trigger on button click on when execute is directly called.\n    goog.events.listen(\n        this.element_,\n        goog.events.EventType.CLICK,\n        this.onClickHandler_);\n  }\n};\n\n\n/** @return {?string} The current reCAPTCHA response. */\nfireauth.RecaptchaMock.prototype.getResponse = function() {\n  this.checkIfDeleted_();\n  return this.responseToken_;\n};\n\n\n/** Starts the reCAPTCHA mock solving/expiration cycle. */\nfireauth.RecaptchaMock.prototype.execute = function() {\n  this.checkIfDeleted_();\n  var self = this;\n  if (this.timerId_) {\n    return;\n  }\n  // Wait for expected delay before auto-solving.\n  this.timerId_ = setTimeout(function() {\n    // Generate random string as reCAPTCHA response token.\n    self.responseToken_ = fireauth.util.generateRandomAlphaNumericString(50);\n    // Trigger developer's callbacks.\n    var callback = self.params_['callback'];\n    var expirationCallback = self.params_['expired-callback'];\n    if (callback) {\n      try {\n        callback(self.responseToken_);\n      } catch (e) {}\n    }\n    // Wait for token to expire before triggering expiration callback and\n    // resetting token response.\n    self.timerId_ = setTimeout(function() {\n      self.timerId_ = null;\n      self.responseToken_ = null;\n      if (expirationCallback) {\n        try {\n          expirationCallback();\n        } catch (e) {}\n      }\n      if (self.isVisible_) {\n        self.execute();\n      }\n    }, fireauth.GRecaptchaMockFactory.EXPIRATION_TIME_MS);\n  }, fireauth.GRecaptchaMockFactory.SOLVE_TIME_MS);\n};\n\n\n/** Deletes the current mock instance. */\nfireauth.RecaptchaMock.prototype.delete = function() {\n  this.checkIfDeleted_();\n  this.deleted_ = true;\n  clearTimeout(this.timerId_);\n  this.timerId_ = null;\n  goog.events.unlisten(\n      this.element_,\n      goog.events.EventType.CLICK,\n      this.onClickHandler_);\n};\n\n\n/**\n * Checks whether the instance was deleted.\n * @private\n */\nfireauth.RecaptchaMock.prototype.checkIfDeleted_ = function() {\n  // This error should never be thrown externally.\n  // GRecaptchaMockFactory will ensure that a deleted instance is removed.\n  if (this.deleted_) {\n    throw new Error('reCAPTCHA mock was already deleted!');\n  }\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the RecaptchaLoader implementation used to load all\n * the grecaptcha dependencies.\n */\n\ngoog.provide('fireauth.RecaptchaRealLoader');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.RecaptchaLoader');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.string.Const');\n\n\n/**\n * Utility to help load reCAPTCHA dependencies for specified languages.\n * @constructor\n * @implements {fireauth.RecaptchaLoader}\n */\nfireauth.RecaptchaRealLoader = function() {\n  /**\n   * @private {number} The reCAPTCHA instance counter. This is used to track the\n   *     number of reCAPTCHAs rendered on the page. This is needed to allow\n   *     localization of the reCAPTCHA. Localization is applied by loading the\n   *     grecaptcha SDK with the hl field provided. However, this will break\n   *     existing reCAPTCHAs. So we should only support i18n when there are no\n   *     other widgets rendered on this screen. If the developer is already\n   *     using reCAPTCHA in another context, we will disable localization so we\n   *     don't accidentally break existing reCAPTCHA widgets.\n   */\n  this.counter_ = goog.global['grecaptcha'] ? Infinity : 0;\n  /** @private {?string} The current reCAPTCHA language code. */\n  this.hl_ = null;\n  /** @const @private {string} The reCAPTCHA callback name. */\n  this.cbName_ = '__rcb' + Math.floor(Math.random() * 1000000).toString();\n};\n\n\n/** @private @const {!goog.string.Const} The reCAPTCHA javascript source URL. */\nfireauth.RecaptchaRealLoader.RECAPTCHA_SRC_ = goog.string.Const.from(\n    'https://www.google.com/recaptcha/api.js?onload=%{onload}&render=explicit' +\n    '&hl=%{hl}');\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests loading\n * the external reCAPTCHA dependencies.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_ =\n    new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * Loads the grecaptcha client library if it is not loaded and returns a promise\n * that resolves on success. If the right conditions are available, will reload\n * the dependencies for a specified language code.\n * @param {?string} hl The reCAPTCHA language code.\n * @return {!goog.Promise<!fireauth.grecaptcha>} A promise that resolves when\n *     grecaptcha is loaded.\n * @override\n */\nfireauth.RecaptchaRealLoader.prototype.loadRecaptchaDeps =\n    function(hl) {\n  var self = this;\n  return new goog.Promise(function(resolve, reject) {\n    var timer = setTimeout(\n        function() {\n          reject(new fireauth.AuthError(\n              fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n        },\n        fireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_\n            .get()\n    );\n    // Load grecaptcha SDK if not already loaded or language changed since last\n    // load and no other rendered reCAPTCHA is visible,\n    if (!goog.global['grecaptcha'] || (hl !== self.hl_ && !self.counter_)) {\n      // reCAPTCHA saves the onload function and applies it on subsequent\n      // reloads. This means that the callback name has to remain the same.\n      goog.global[self.cbName_] = function() {\n        if (!goog.global['grecaptcha']) {\n          clearTimeout(timer);\n          // This should not happen.\n          reject(new fireauth.AuthError(\n              fireauth.authenum.Error.INTERNAL_ERROR));\n        } else {\n          // Update the current language code.\n          self.hl_ = hl;\n          var render = goog.global['grecaptcha']['render'];\n          // Wrap grecaptcha.render to keep track of rendered grecaptcha. This\n          // helps detect if the developer rendered a non\n          // firebase.auth.RecaptchaVerifier reCAPTCHA.\n          goog.global['grecaptcha']['render'] =\n              function(container, parameters) {\n            var widgetId = render(container, parameters);\n            // Increment only after render succeeds, in case an error is thrown\n            // during rendering.\n            self.counter_++;\n            return widgetId;\n          };\n          clearTimeout(timer);\n          resolve(goog.global['grecaptcha']);\n        }\n        delete goog.global[self.cbName_];\n      };\n      // Construct reCAPTCHA URL and on load, run the temporary function.\n      var url = goog.html.TrustedResourceUrl.format(\n          fireauth.RecaptchaRealLoader.RECAPTCHA_SRC_,\n          {'onload': self.cbName_, 'hl': hl || ''});\n      // TODO: eventually, replace all dependencies on goog.net.jsloader.\n      goog.Promise.resolve(goog.net.jsloader.safeLoad(url))\n          .thenCatch(function(error) {\n            clearTimeout(timer);\n            // In case library fails to load, typically due to a network error,\n            // reset cached loader to null to force a refresh on a retrial.\n            reject(new fireauth.AuthError(\n                fireauth.authenum.Error.INTERNAL_ERROR,\n                'Unable to load external reCAPTCHA dependencies!'));\n          });\n    } else {\n      clearTimeout(timer);\n      resolve(goog.global['grecaptcha']);\n    }\n  });\n};\n\n\n/**\n * Decrements the reCAPTCHA instance counter.\n * @override\n */\nfireauth.RecaptchaRealLoader.prototype.clearSingleRecaptcha =\n    function() {\n  this.counter_--;\n};\n\n\n/**\n * @private {?fireauth.RecaptchaRealLoader} The singleton instance\n *     for reCAPTCHA dependency loader.\n */\nfireauth.RecaptchaRealLoader.instance_ = null;\n\n\n/**\n * @return {!fireauth.RecaptchaRealLoader} The singleton reCAPTCHA\n *     dependency loader instance.\n */\nfireauth.RecaptchaRealLoader.getInstance = function() {\n  // Check if there is an existing instance. Otherwise create one and cache it.\n  if (!fireauth.RecaptchaRealLoader.instance_) {\n    fireauth.RecaptchaRealLoader.instance_ =\n        new fireauth.RecaptchaRealLoader();\n  }\n  return fireauth.RecaptchaRealLoader.instance_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Defines the reCAPTCHA app verifier and its base class. The\n * former is currently used for web phone authentication whereas the latter is\n * used for the mobile app verification web fallback.\n */\ngoog.provide('fireauth.BaseRecaptchaVerifier');\ngoog.provide('fireauth.RecaptchaVerifier');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.RecaptchaMockLoader');\ngoog.require('fireauth.RecaptchaRealLoader');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.dom');\n\n\n/**\n * Creates the firebase base reCAPTCHA app verifier independent of Firebase\n * App or Auth instances.\n *\n * @param {string} apiKey The API key used to initialize the RPC handler for\n *     querying the Auth backend.\n * @param {!Element|string} container The reCAPTCHA container parameter. This\n *     has different meaning depending on whether the reCAPTCHA is hidden or\n *     visible.\n * @param {?Object=} opt_parameters The optional reCAPTCHA parameters.\n * @param {?(function():?string)=} opt_getLanguageCode The language code getter\n *     function.\n * @param {?string=} opt_clientVersion The optional client version to append to\n *     RPC header.\n * @param {?Object=} opt_rpcHandlerConfig The optional RPC handler\n *     configuration, typically passed when different Auth endpoints are to be\n *     used.\n * @param {boolean=} opt_isTestingMode Whether the reCAPTCHA is to be rendered\n *     in testing mode.\n * @constructor\n */\nfireauth.BaseRecaptchaVerifier = function(apiKey, container, opt_parameters,\n    opt_getLanguageCode, opt_clientVersion, opt_rpcHandlerConfig,\n    opt_isTestingMode) {\n  // Set the type readonly property needed for full implementation of the\n  // firebase.auth.ApplicationVerifier interface.\n  fireauth.object.setReadonlyProperty(this, 'type', 'recaptcha');\n  /**\n   * @private {?goog.Promise<void>} The cached reCAPTCHA ready response. This is\n   *     null until the first time it is triggered or when an error occurs in\n   *     getting ready.\n   */\n  this.cachedReadyPromise_ = null;\n  /** @private {?number} The reCAPTCHA widget ID. Null when not rendered. */\n  this.widgetId_ = null;\n  /** @private {boolean} Whether the instance is already destroyed. */\n  this.destroyed_ = false;\n  /** @private {!Element|string} The reCAPTCHA container. */\n  this.container_ = container;\n  /**\n   * @private {?fireauth.grecaptcha} The reCAPTCHA client library namespace.\n   */\n  this.grecaptcha_ = null;\n  /**\n   * @const @private {!fireauth.RecaptchaLoader} The grecaptcha loader.\n   */\n  this.recaptchaLoader_ = !!opt_isTestingMode ?\n      fireauth.RecaptchaMockLoader.getInstance() :\n      fireauth.RecaptchaRealLoader.getInstance();\n  // If no parameters passed, use default settings.\n  // Currently, visible recaptcha is the default setting as invisible reCAPTCHA\n  // is not yet supported by the backend.\n  /** @private {!Object} The reCAPTCHA parameters. */\n  this.parameters_ = opt_parameters || {\n    'theme': 'light',\n    'type': 'image'\n  };\n  /** @private {!Array<!goog.Promise<*>|!goog.Promise<void>>} List of\n   *      pending promises. */\n  this.pendingPromises_ = [];\n  if (this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SITEKEY]) {\n    // sitekey should not be provided.\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'sitekey should not be provided for reCAPTCHA as one is ' +\n        'automatically provisioned for the current project.');\n  }\n  /** @private {boolean} Whether the reCAPTCHA is invisible or not. */\n  this.isInvisible_ =\n      this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SIZE] ===\n      'invisible';\n  // Check if DOM is supported.\n  if (!fireauth.util.isDOMSupported()) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n        'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' +\n        'environment with DOM support.');\n  }\n  // reCAPTCHA container must be valid and if visible, not empty.\n  // An invisible reCAPTCHA will not render in its container. That container\n  // will execute the reCAPTCHA when it is clicked.\n  if (!goog.dom.getElement(container) ||\n      (!this.isInvisible_ && goog.dom.getElement(container).hasChildNodes())) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'reCAPTCHA container is either not found or already contains inner ' +\n        'elements!');\n  }\n  /**\n   * @private {!fireauth.RpcHandler} The RPC handler for querying the auth\n   *     backend.\n   */\n  this.rpcHandler_ = new fireauth.RpcHandler(\n      apiKey,\n      opt_rpcHandlerConfig || null,\n      opt_clientVersion || null);\n  /**\n   * @private {function():?string} Current language code getter.\n   */\n  this.getLanguageCode_ = opt_getLanguageCode || function() {return null;};\n  var self = this;\n  /**\n   * @private {!Array<function(?string)>} The token change listeners.\n   */\n  this.tokenListeners_ = [];\n  // Wrap token callback.\n  var existingCallback =\n      this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.CALLBACK];\n  this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.CALLBACK] =\n      function(response) {\n    // Dispatch internal event for the token response.\n    self.dispatchEvent_(response);\n    if (typeof existingCallback === 'function') {\n      existingCallback(response);\n    } else if (typeof existingCallback === 'string') {\n      // Check if the provided callback is a global function name.\n      var cb = fireauth.util.getObjectRef(existingCallback, goog.global);\n      if (typeof cb === 'function') {\n        // If so, trigger it.\n        cb(response);\n      }\n    }\n  };\n  // Wrap expired token callback.\n  var existingExpiredCallback = this.parameters_[\n    fireauth.BaseRecaptchaVerifier.ParamName.EXPIRED_CALLBACK];\n  this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.EXPIRED_CALLBACK] =\n      function() {\n    // Dispatch internal event for the token expiration.\n    self.dispatchEvent_(null);\n    if (typeof existingExpiredCallback === 'function') {\n      existingExpiredCallback();\n    } else if (typeof existingExpiredCallback === 'string') {\n      // Check if the provided expired callback is a global function name.\n      var cb = fireauth.util.getObjectRef(existingExpiredCallback, goog.global);\n      if (typeof cb === 'function') {\n        // If so, trigger it.\n        cb();\n      }\n    }\n  };\n};\n\n\n/**\n * grecaptcha parameter names.\n * @enum {string}\n */\nfireauth.BaseRecaptchaVerifier.ParamName = {\n  CALLBACK: 'callback',\n  EXPIRED_CALLBACK: 'expired-callback',\n  SITEKEY: 'sitekey',\n  SIZE: 'size'\n};\n\n\n/**\n * Dispatches the token change event to all subscribed listeners.\n * @param {?string} token The current detected token, null for none.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.dispatchEvent_ = function(token) {\n  for (var i = 0; i < this.tokenListeners_.length; i++) {\n    try {\n      this.tokenListeners_[i](token);\n    } catch (e) {\n      // If any handler fails, ignore and run next handler.\n    }\n  }\n};\n\n\n/**\n * Add a reCAPTCHA token change listener.\n * @param {function(?string)} listener The token listener to add.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.addTokenChangeListener_ =\n    function(listener) {\n  this.tokenListeners_.push(listener);\n};\n\n\n/**\n * Remove a reCAPTCHA token change listener.\n * @param {function(?string)} listener The token listener to remove.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.removeTokenChangeListener_ =\n    function(listener) {\n  goog.array.removeAllIf(this.tokenListeners_, function(ele) {\n    return ele == listener;\n  });\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.registerPendingPromise_ = function(p) {\n  var self = this;\n  // Save created promise in pending list.\n  this.pendingPromises_.push(p);\n  p.thenAlways(function() {\n    // When fulfilled, remove from pending list.\n    goog.array.remove(self.pendingPromises_, p);\n  });\n  // Return the promise.\n  return p;\n};\n\n\n/** @return {boolean} Whether verifier instance has pending promises. */\nfireauth.BaseRecaptchaVerifier.prototype.hasPendingPromises = function() {\n  return this.pendingPromises_.length != 0;\n};\n\n\n/**\n * Gets the current RecaptchaVerifier in a ready state for rendering by first\n * checking that the environment supports a reCAPTCHA, loading reCAPTCHA\n * dependencies if not already available and then getting the Firebase project's\n * provisioned reCAPTCHA configuration.\n * @return {!goog.Promise<void>} The promise that resolves when recaptcha\n *     is ready for rendering.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.isReady_ = function() {\n  var self = this;\n  // If previously called, return the cached response.\n  if (this.cachedReadyPromise_) {\n    return this.cachedReadyPromise_;\n  }\n  this.cachedReadyPromise_ = this.registerPendingPromise_(goog.Promise.resolve()\n      .then(function() {\n        // Verify environment first.\n        // Fail quickly from a worker environment or non-HTTP/HTTPS environment.\n        if (fireauth.util.isHttpOrHttps() && !fireauth.util.isWorker()) {\n          // Wait for DOM to be ready as this feature depends on that.\n          return fireauth.util.onDomReady();\n        } else {\n          throw new fireauth.AuthError(\n              fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n              'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' +\n              'environment.');\n        }\n      })\n      .then(function() {\n        // Load external reCAPTCHA dependencies if not already there, taking\n        // into account the current language code.\n        return self.recaptchaLoader_.loadRecaptchaDeps(self.getLanguageCode_());\n      })\n      .then(function(grecaptcha) {\n        self.grecaptcha_ = grecaptcha;\n        // Load Firebase project's reCAPTCHA configuration.\n        return self.rpcHandler_.getRecaptchaParam();\n      })\n      .then(function(result) {\n        // Update the reCAPTCHA parameters.\n        self.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SITEKEY] =\n            result[fireauth.RpcHandler.AuthServerField.RECAPTCHA_SITE_KEY];\n      }).thenCatch(function(error) {\n        // Anytime an error occurs, reset the cached ready promise to rerun on\n        // retrial.\n        self.cachedReadyPromise_ = null;\n        // Rethrow the error.\n        throw error;\n      }));\n  // Return the cached/pending ready promise.\n  return this.cachedReadyPromise_;\n};\n\n/**\n * Renders the reCAPTCHA and returns the allocated widget ID.\n * @return {!goog.Promise<number>} The promise that resolves with the reCAPTCHA\n *     widget ID when it is rendered.\n */\nfireauth.BaseRecaptchaVerifier.prototype.render = function() {\n  this.checkIfDestroyed_();\n  var self = this;\n  // Get reCAPTCHA ready.\n  return this.registerPendingPromise_(this.isReady_().then(function() {\n    if (self.widgetId_ === null) {\n      // For a visible reCAPTCHA, embed in a wrapper DIV container to allow\n      // re-rendering in the same developer provided container.\n      var container = self.container_;\n      if (!self.isInvisible_) {\n        // Get outer container (the developer provided container).\n        var outerContainer = goog.dom.getElement(container);\n        // Create wrapper temp DIV container.\n        container = goog.dom.createDom(goog.dom.TagName.DIV);\n        // Add temp DIV to outer container.\n        outerContainer.appendChild(container);\n      }\n      // If not initialized, initialize reCAPTCHA and return its widget ID.\n      self.widgetId_ = self.grecaptcha_.render(container, self.parameters_);\n    }\n    return self.widgetId_;\n  }));\n};\n\n\n/**\n * Gets the reCAPTCHA ready and waits for the reCAPTCHA token to be available\n * before resolving the promise returned.\n * @return {!goog.Promise<string>} The promise that resolves with the reCAPTCHA\n *     token when reCAPTCHA challenge is solved.\n */\nfireauth.BaseRecaptchaVerifier.prototype.verify = function() {\n  // Fail if reCAPTCHA is already destroyed.\n  this.checkIfDestroyed_();\n  var self = this;\n  // Render reCAPTCHA.\n  return this.registerPendingPromise_(this.render().then(function(widgetId) {\n    return new goog.Promise(function(resolve, reject) {\n      // Get current reCAPTCHA token.\n      var recaptchaToken = self.grecaptcha_.getResponse(widgetId);\n      if (recaptchaToken) {\n        // Unexpired token already available. Resolve pending promise with that\n        // token.\n        resolve(recaptchaToken);\n      } else {\n        // No token available. Listen to token change.\n        var cb = function(token) {\n          if (!token) {\n            // Ignore token expirations.\n            return;\n          }\n          // Remove temporary token change listener.\n          self.removeTokenChangeListener_(cb);\n          // Resolve with new token.\n          resolve(token);\n        };\n        // Add temporary token change listener.\n        self.addTokenChangeListener_(cb);\n        if (self.isInvisible_) {\n          // Execute invisible reCAPTCHA to force a challenge.\n          // This should do nothing if already triggered either by developer or\n          // by a button click.\n          self.grecaptcha_.execute(/** @type {number} */ (self.widgetId_));\n        }\n      }\n    });\n  }));\n};\n\n\n/**\n * Resets the reCAPTCHA widget.\n */\nfireauth.BaseRecaptchaVerifier.prototype.reset = function() {\n  this.checkIfDestroyed_();\n  if (this.widgetId_ !== null) {\n    this.grecaptcha_.reset(this.widgetId_);\n  }\n};\n\n\n/**\n * Throws an error if the reCAPTCHA verifier is already cleared.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.checkIfDestroyed_ = function() {\n  if (this.destroyed_) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.INTERNAL_ERROR,\n        'RecaptchaVerifier instance has been destroyed.');\n  }\n};\n\n\n/**\n * Removes the reCAPTCHA from the DOM.\n */\nfireauth.BaseRecaptchaVerifier.prototype.clear = function() {\n  this.checkIfDestroyed_();\n  this.destroyed_ = true;\n  // Decrement reCAPTCHA instance counter.\n  this.recaptchaLoader_.clearSingleRecaptcha();\n  // Cancel all pending promises.\n  for (var i = 0; i < this.pendingPromises_.length; i++) {\n    this.pendingPromises_[i].cancel(\n        'RecaptchaVerifier instance has been destroyed.');\n  }\n  if (!this.isInvisible_) {\n    goog.dom.removeChildren(goog.dom.getElement(this.container_));\n  }\n};\n\n\n/**\n * Creates the Firebase reCAPTCHA app verifier, publicly available, for the\n * Firebase app provided, used for web phone authentication.\n * This is a subclass of fireauth.BaseRecaptchaVerifier.\n *\n * @param {!Element|string} container The reCAPTCHA container parameter. This\n *     has different meaning depending on whether the reCAPTCHA is hidden or\n *     visible.\n * @param {?Object=} opt_parameters The optional reCAPTCHA parameters.\n * @param {?firebase.app.App=} opt_app The corresponding Firebase app.\n * @constructor\n * @extends {fireauth.BaseRecaptchaVerifier}\n */\nfireauth.RecaptchaVerifier = function(container, opt_parameters, opt_app) {\n  var isTestingMode = false;\n  var apiKey;\n  try {\n    /** @private {!firebase.app.App} The corresponding Firebase app instance. */\n    this.app_ = opt_app || firebase.app();\n  } catch (error) {\n    throw new fireauth.AuthError(\n        fireauth.authenum.Error.ARGUMENT_ERROR,\n        'No firebase.app.App instance is currently initialized.');\n  }\n  // API key is required for web client RPC calls.\n  if (this.app_.options && this.app_.options['apiKey']) {\n    apiKey = this.app_.options['apiKey'];\n  } else {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_API_KEY);\n  }\n  var self = this;\n  // Construct the language code getter based on the underlying Auth instance.\n  var getLanguageCode = function() {\n    var languageCode;\n    // Get the latest language setting.\n    // reCAPTCHA does not support updating the language of an already\n    // rendered reCAPTCHA. Reloading the SDK with the new hl will break\n    // the existing rendered localized reCAPTCHA. We will need to\n    // document that a new fireauth.BaseRecaptchaVerifier instance needs\n    // to be instantiated after the language is updated. Otherwise, the\n    // old language code will remain active on the existing instance.\n    try {\n      languageCode = self.app_['auth']().getLanguageCode();\n    } catch (e) {\n      languageCode = null;\n    }\n    return languageCode;\n  };\n  // Get the framework version from Auth instance.\n  var frameworkVersion = null;\n  try {\n    frameworkVersion = this.app_['auth']().getFramework();\n  } catch (e) {\n    // Do nothing.\n  }\n  try {\n    isTestingMode =\n        this.app_['auth']()['settings']['appVerificationDisabledForTesting'];\n  } catch (e) {\n    // Do nothing.\n  }\n  // Get the client version based on the Firebase JS version.\n  var clientFullVersion = firebase.SDK_VERSION ?\n      fireauth.util.getClientVersion(\n          fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n          frameworkVersion) :\n      null;\n  // Call the superclass constructor with the computed API key, reCAPTCHA\n  // container, optional parameters, language code getter, Firebase JS client\n  // version and the current client configuration endpoints.\n  fireauth.RecaptchaVerifier.base(this, 'constructor', apiKey,\n      container, opt_parameters, getLanguageCode, clientFullVersion,\n      fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n      isTestingMode);\n};\ngoog.inherits(fireauth.RecaptchaVerifier, fireauth.BaseRecaptchaVerifier);\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Provides function argument validation for third-party calls\n * that cannot be validated with Closure compiler.\n */\n\ngoog.provide('fireauth.args');\ngoog.provide('fireauth.args.Argument');\n\ngoog.require('fireauth.Auth');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Represents an argument to a function. Fields:\n * <ul>\n * <li> name: A label for the argument. For example, the names of the arguments\n *      to a signIn() function might be \"email\" and \"password\".\n * <li> typeLabel: A label for the expected type of the argument, starting with\n *      an article, for example, \"an object\" or \"a valid credential\".\n * <li> optional: Whether or not this argument is optional. Optional arguments\n *      cannot come after non-optional arguments in the input to validate().\n * <li> validator: A function that takes the passed value of this argument\n *      and returns whether the value is valid or not.\n * </ul>\n * @typedef {{\n *   name: string,\n *   typeLabel: string,\n *   optional: boolean,\n *   validator: function (*) : boolean,\n * }}\n */\nfireauth.args.Argument;\n\n\n/**\n * Validates the arguments to a method call and throws an error if invalid. This\n * can be used to validate external calls where the Closure compiler cannot\n * detect errors.\n *\n * Example usage:\n * function greet(recipient, opt_useFormalLanguage) {\n *   fireauth.args.validate('greet', [\n *     fireauth.args.string('recipient'),\n *     fireauth.args.bool('opt_useFormalLanguage', true)\n *   ], arguments);\n *   if (opt_useFormalLanguage) {\n *     console.log('Good day, ' + recipient + '.');\n *   } else {\n *     console.log('Wassup, ' + recipient + '?');\n *   }\n * }\n * greet('Mr. Manager', true); // Prints 'Good day, Mr. Manager.'\n * greet('Billy Bob'); // Prints 'Wassup, Billy Bob?'\n * greet(133); // Throws 'greet failed: First argument \"recipient\" must be a\n *             // valid string.'\n * greet(); // Throws 'greet failed: Expected 1-2 arguments but got 0.'\n * greet('Mr. Manager', true, 'ohno'); // Throws 'greet failed: Expected 1-2\n *                                     // arguments but got 3.'\n *\n * This can also be used to validate setters by passing an additional true\n * argument to fireauth.args.validate. This modifies the error message to be\n * relevant for that setter.\n *\n * @param {string} apiName The name of the method being called, to display in\n *     the error message for debugging purposes.\n * @param {!Array<!fireauth.args.Argument>} expected The expected arguments.\n * @param {!IArrayLike} actual The arguments object of the function whose\n *     parameters we want to validate.\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n *     a single argument.\n */\nfireauth.args.validate = function(apiName, expected, actual, opt_isSetter) {\n  // Convert the arguments object into a real array.\n  var actualAsArray = Array.prototype.slice.call(actual);\n  var errorMessage = fireauth.args.validateAndGetMessage_(\n      expected, actualAsArray, opt_isSetter);\n  if (errorMessage) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n        apiName + ' failed: ' + errorMessage);\n  }\n};\n\n\n/**\n * @param {!Array<!fireauth.args.Argument>} expected\n * @param {!Array<*>} actual\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n *     a single argument.\n * @return {?string} The error message if there is an error, or otherwise\n *     null.\n * @private\n */\nfireauth.args.validateAndGetMessage_ =\n    function(expected, actual, opt_isSetter) {\n  var minNumArgs = fireauth.args.calcNumRequiredArgs_(expected);\n  var maxNumArgs = expected.length;\n  if (actual.length < minNumArgs || maxNumArgs < actual.length) {\n    return fireauth.args.makeLengthError_(minNumArgs, maxNumArgs,\n        actual.length);\n  }\n\n  for (var i = 0; i < actual.length; i++) {\n    // Argument is optional and undefined is explicitly passed.\n    var optionalUndefined = expected[i].optional && actual[i] === undefined;\n    // Check if invalid argument and the argument is not optional with undefined\n    // passed.\n    if (!expected[i].validator(actual[i]) && !optionalUndefined) {\n      return fireauth.args.makeErrorAtPosition_(i, expected[i], opt_isSetter);\n    }\n  }\n\n  return null;\n};\n\n\n/**\n * @param {!Array<!fireauth.args.Argument>} expected\n * @return {number} The number of required arguments.\n * @private\n */\nfireauth.args.calcNumRequiredArgs_ = function(expected) {\n  var numRequiredArgs = 0;\n  var isOptionalSection = false;\n  for (var i = 0; i < expected.length; i++) {\n    if (expected[i].optional) {\n      isOptionalSection = true;\n    } else {\n      if (isOptionalSection) {\n        throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n            'Argument validator encountered a required argument after an ' +\n            'optional argument.');\n      }\n      numRequiredArgs++;\n    }\n  }\n  return numRequiredArgs;\n};\n\n\n/**\n * @param {number} min The minimum number of arguments to the function,\n *     inclusive.\n * @param {number} max The maximum number of arguments to the function,\n *     inclusive.\n * @param {number} actual The actual number of arguments received.\n * @return {string} The error message.\n * @private\n */\nfireauth.args.makeLengthError_ = function(min, max, actual) {\n  var numExpectedString;\n  if (min == max) {\n    if (min == 1) {\n      numExpectedString = '1 argument';\n    } else {\n      numExpectedString = min + ' arguments';\n    }\n  } else {\n    numExpectedString = min + '-' + max + ' arguments';\n  }\n  return 'Expected ' + numExpectedString + ' but got ' + actual + '.';\n};\n\n\n/**\n * @param {number} position The position at which there was an error.\n * @param {!fireauth.args.Argument} expectedType The expected type of the\n *     argument, which was violated.\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n *     a single argument.\n * @return {string} The error message.\n * @private\n */\nfireauth.args.makeErrorAtPosition_ =\n    function(position, expectedType, opt_isSetter) {\n  var ordinal = fireauth.args.makeOrdinal_(position);\n  var argName = expectedType.name ?\n      fireauth.args.quoteString_(expectedType.name) + ' ' : '';\n  // Add support to setters for readable/writable properties which take a\n  // required single argument.\n  var errorPrefix = !!opt_isSetter ? '' : ordinal + ' argument ';\n  return errorPrefix + argName + 'must be ' +\n      expectedType.typeLabel + '.';\n};\n\n\n/** @private {!Array<string>} The first few ordinal numbers. */\nfireauth.args.ORDINAL_NUMBERS_ = ['First', 'Second', 'Third', 'Fourth',\n  'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth'];\n\n\n/**\n * @param {number} cardinal An integer.\n * @return {string} The integer converted to an ordinal number, starting at\n *     \"First\". That is, makeOrdinal_(0) returns \"First\" and makeOrdinal_(1)\n *     returns \"Second\", etc.\n * @private\n */\nfireauth.args.makeOrdinal_ = function(cardinal) {\n  // We only support the first few ordinal numbers. We could provide a more\n  // robust solution, but it is unlikely that a function would need more than\n  // nine arguments.\n  if (cardinal < 0 || cardinal >= fireauth.args.ORDINAL_NUMBERS_.length) {\n    throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n        'Argument validator received an unsupported number of arguments.');\n  }\n  return fireauth.args.ORDINAL_NUMBERS_[cardinal];\n};\n\n\n/**\n * Specifies a string argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.string = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'a valid string',\n    optional: !!opt_optional,\n    validator: x => typeof x === 'string'\n  };\n};\n\n\n/**\n * Specifies a boolean argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.bool = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'a boolean',\n    optional: !!opt_optional,\n    validator: x => typeof x === 'boolean'\n  };\n};\n\n\n/**\n * Specifies a number argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.number = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'a valid number',\n    optional: !!opt_optional,\n    validator: x => typeof x === 'number'\n  };\n};\n\n\n/**\n * Specifies an object argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.object = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'a valid object',\n    optional: !!opt_optional,\n    validator: goog.isObject\n  };\n};\n\n\n/**\n * Specifies a function argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.func = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'a function',\n    optional: !!opt_optional,\n    validator: x => typeof x === 'function'\n  };\n};\n\n\n/**\n * Specifies a null argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.null = function(opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: 'null',\n    optional: !!opt_optional,\n    validator: x => x === null\n  };\n};\n\n\n/**\n * Specifies an HTML element argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.element = function(opt_name, opt_optional) {\n   return /** @type {!fireauth.args.Argument} */ ({\n    name: opt_name || '',\n    typeLabel: 'an HTML element',\n    optional: !!opt_optional,\n    validator: /** @type {function(!Element) : boolean} */ (\n        function(element) {\n          return !!(element && element instanceof Element);\n        })\n  });\n};\n\n\n/**\n * Specifies an instance of Firebase Auth.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseAuth = function(opt_optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: 'auth',\n    typeLabel: 'an instance of Firebase Auth',\n    optional: !!opt_optional,\n    validator: /** @type {function(!fireauth.Auth) : boolean} */ (\n        function(auth) {\n          return !!(auth && auth instanceof fireauth.Auth);\n        })\n  });\n};\n\n\n/**\n * Specifies an instance of Firebase User.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseUser = function(opt_optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: 'user',\n    typeLabel: 'an instance of Firebase User',\n    optional: !!opt_optional,\n    validator: /** @type {function(!fireauth.AuthUser) : boolean} */ (\n        function(user) {\n          return !!(user && user instanceof fireauth.AuthUser);\n        })\n  });\n};\n\n\n/**\n * Specifies an instance of Firebase App.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseApp = function(opt_optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: 'app',\n    typeLabel: 'an instance of Firebase App',\n    optional: !!opt_optional,\n    validator: /** @type {function(!firebase.app.App) : boolean} */ (\n        function(app) {\n          return !!(app && app instanceof firebase.app.App);\n        })\n  });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.AuthCredential interface.\n * @param {?fireauth.idp.ProviderId=} opt_requiredProviderId The required type\n *     of provider.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.authCredential =\n    function(opt_requiredProviderId, opt_name, opt_optional) {\n  var name = opt_name ||\n      (opt_requiredProviderId ?\n       opt_requiredProviderId + 'Credential' :\n       'credential');\n  var typeLabel = opt_requiredProviderId ?\n      'a valid ' + opt_requiredProviderId + ' credential' :\n      'a valid credential';\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: name,\n    typeLabel: typeLabel,\n    optional: !!opt_optional,\n    validator: /** @type {function(!fireauth.AuthCredential) : boolean} */ (\n        function(credential) {\n          if (!credential) {\n            return false;\n          }\n          // If opt_requiredProviderId is set, make sure it matches the\n          // credential's providerId.\n          var matchesRequiredProvider = !opt_requiredProviderId ||\n              (credential['providerId'] === opt_requiredProviderId);\n          return !!(credential.getIdTokenProvider && matchesRequiredProvider);\n        })\n  });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.MultiFactorAssertion\n * interface.\n * @param {?string=} requiredFactorId The required type of second factor.\n * @param {?string=} optionalName The name of the argument.\n * @param {?boolean=} optionalArg Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.multiFactorAssertion =\n    function(requiredFactorId, optionalName, optionalArg) {\n  var name = optionalName ||\n      (requiredFactorId ?\n       requiredFactorId + 'MultiFactorAssertion' : 'multiFactorAssertion');\n  var typeLabel = requiredFactorId ?\n      'a valid ' + requiredFactorId + ' multiFactorAssertion' :\n      'a valid multiFactorAssertion';\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: name,\n    typeLabel: typeLabel,\n    optional: !!optionalArg,\n    validator:\n        /** @type {function(!fireauth.MultiFactorAssertion) : boolean} */ (\n            function(assertion) {\n              if (!assertion) {\n                return false;\n              }\n              // If requiredFactorId is set, make sure it matches the\n              // assertion's factorId.\n              var matchesRequiredFactor = !requiredFactorId ||\n                  (assertion['factorId'] === requiredFactorId);\n              return !!(assertion.process && matchesRequiredFactor);\n            })\n  });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.AuthProvider interface.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.authProvider = function(opt_name, opt_optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: opt_name || 'authProvider',\n    typeLabel: 'a valid Auth provider',\n    optional: !!opt_optional,\n    validator: /** @type {function(!fireauth.AuthProvider) : boolean} */ (\n        function(provider) {\n          return !!(provider &&\n                    provider['providerId'] &&\n                    provider.hasOwnProperty &&\n                    provider.hasOwnProperty('isOAuthProvider'));\n        })\n  });\n};\n\n\n/**\n * Specifies a phone info options argument.\n * @param {?string=} name The name of the argument.\n * @param {?boolean=} optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.phoneInfoOptions = function(name, optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: name || 'phoneInfoOptions',\n    typeLabel: 'valid phone info options',\n    optional: !!optional,\n    validator: /** @type {function(!Object) : boolean} */ (\n        function(phoneInfoOptions) {\n          if (!phoneInfoOptions) {\n            return false;\n          }\n          // For multi-factor enrollment, phone number and MFA session should\n          // be provided.\n          if (phoneInfoOptions['session'] &&\n              phoneInfoOptions['phoneNumber']) {\n            return fireauth.args.validateMultiFactorSession_(\n                       phoneInfoOptions['session'],\n                       fireauth.MultiFactorSession.Type.ENROLL) &&\n                   typeof phoneInfoOptions['phoneNumber'] === 'string';\n          // For multi-factor sign-in, phone multi-factor hint and MFA session\n          // are provided.\n          } else if (phoneInfoOptions['session'] &&\n                     phoneInfoOptions['multiFactorHint']) {\n            return fireauth.args.validateMultiFactorSession_(\n                       phoneInfoOptions['session'],\n                       fireauth.MultiFactorSession.Type.SIGN_IN) &&\n                   fireauth.args.validateMultiFactorInfo_(\n                       phoneInfoOptions['multiFactorHint']);\n          // For multi-factor sign-in, phone multi-factor UID and MFA session\n          // are provided.\n          } else if (phoneInfoOptions['session'] &&\n                     phoneInfoOptions['multiFactorUid']) {\n            return fireauth.args.validateMultiFactorSession_(\n                       phoneInfoOptions['session'],\n                       fireauth.MultiFactorSession.Type.SIGN_IN) &&\n                   typeof phoneInfoOptions['multiFactorUid'] === 'string';\n          // For single-factor sign-in, only phone number needs to be provided.\n          } else if (phoneInfoOptions['phoneNumber']) {\n            return typeof phoneInfoOptions['phoneNumber'] === 'string';\n          }\n          return false;\n        })\n  });\n};\n\n\n/**\n * @param {*} session The multi-factor session object.\n * @param {!fireauth.MultiFactorSession.Type} type The session type.\n * @return {boolean} Whether the seesion is a valid multi-factor session.\n * @private\n */\nfireauth.args.validateMultiFactorSession_ = function(session, type) {\n  return goog.isObject(session) && typeof session.type === 'string' &&\n      session.type === type &&\n      typeof session.getRawSession === 'function';\n};\n\n\n/**\n * @param {*} info The multi-factor info object.\n * @return {boolean} Whether the info is a valid multi-factor info.\n * @private\n */\nfireauth.args.validateMultiFactorInfo_ = function(info) {\n  return goog.isObject(info) && typeof info['uid'] === 'string';\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.MultiFactorInfo\n * interface.\n * @param {?string=} name The name of the argument.\n * @param {?boolean=} optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.multiFactorInfo = function(name, optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: name || 'multiFactorInfo',\n    typeLabel: 'a valid multiFactorInfo',\n    optional: !!optional,\n    validator: fireauth.args.validateMultiFactorInfo_\n  });\n};\n\n\n/**\n * Specifies an argument that implements the firebase.auth.ApplicationVerifier\n * interface.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.applicationVerifier = function(opt_optional) {\n  return /** @type {!fireauth.args.Argument} */ ({\n    name: 'applicationVerifier',\n    typeLabel: 'an implementation of firebase.auth.ApplicationVerifier',\n    optional: !!opt_optional,\n    validator:\n        /** @type {function(!firebase.auth.ApplicationVerifier) : boolean} */ (\n        function(applicationVerifier) {\n          return !!(applicationVerifier &&\n                    typeof applicationVerifier.type === 'string' &&\n                    typeof applicationVerifier.verify === 'function');\n        })\n  });\n};\n\n\n/**\n * Specifies an argument that can be either of two argument types.\n * @param {!fireauth.args.Argument} optionA\n * @param {!fireauth.args.Argument} optionB\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n *     Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.or = function(optionA, optionB, opt_name, opt_optional) {\n  return {\n    name: opt_name || '',\n    typeLabel: optionA.typeLabel + ' or ' + optionB.typeLabel,\n    optional: !!opt_optional,\n    validator: function(value) {\n      return optionA.validator(value) || optionB.validator(value);\n    }\n  };\n};\n\n\n/**\n * @param {string} str\n * @return {string} The string surrounded with quotes.\n * @private\n */\nfireauth.args.quoteString_ = function(str) {\n  return '\"' + str + '\"';\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 Provides utilities for exporting public APIs, with error\n *     checking.\n */\n\ngoog.provide('fireauth.exportlib');\ngoog.provide('fireauth.exportlib.ExportedMethod');\n\ngoog.require('fireauth.args');\n\n\n/**\n * Type constant for Firebase Auth.\n * @const {string}\n */\nfireauth.exportlib.AUTH_TYPE = 'auth';\n\n\n/**\n * Represents an exported method, with the exported name of the method and the\n * expected arguments to that method.\n * @typedef {{\n *   name: string,\n *   args: (Array<!fireauth.args.Argument>|null|undefined)\n * }}\n */\nfireauth.exportlib.ExportedMethod;\n\n\n/**\n * Represents an exported property, with the exported name of the property and\n * the expected argument to the setter of this property.\n * @typedef {{\n *   name: string,\n *   arg: !fireauth.args.Argument\n * }}\n */\nfireauth.exportlib.ExportedProperty;\n\n\n/**\n * Exports prototype methods of an object.\n * @param {!Object} protObj The prototype of an object.\n * @param {!Object<string, fireauth.exportlib.ExportedMethod>} fnMap The map of\n *     prototype functions to their export name and expected arguments.\n */\nfireauth.exportlib.exportPrototypeMethods = function(protObj, fnMap) {\n  // This method exports methods by aliasing the unobfuscated function name\n  // (specified as a string in the \"name\" field of ExportedMethod) to the\n  // obfuscated function name (specified as a key of the fnMap object).\n  //\n  // To give a concrete example, let's say that we have this method:\n  // fireauth.Auth.prototype.fetchProvidersForEmail = function() { ... };\n  //\n  // In the exports file, we export as follows:\n  // fireauth.exportlib.exportPrototypeMethods(fireauth.Auth.prototype, {\n  //   fetchProvidersForEmail: {name: 'fetchProvidersForEmail', args: ...}\n  // });\n  //\n  // When the compiler obfuscates the code, the code above will become something\n  // like this:\n  // fireauth.Auth.prototype.qZ = function() { ... };\n  // fireauth.exportlib.exportPrototypeMethods(fireauth.Auth.prototype, {\n  //   qZ: {name: 'fetchProvidersForEmail', args: ...}\n  // });\n  //\n  // (Of course, fireauth.Auth and fireauth.exportlib.exportPrototypeMethods\n  // would also be obfuscated). Note that the key in fnMap is obfuscated but the\n  // \"name\" field in the ExportedMethod is not. Now, exportPrototypeMethods can\n  // export fetchProvidersForEmail by reading the key (\"qZ\") and the \"name\"\n  // field (\"fetchProvidersForEmail\") and essentially executing this:\n  // fireauth.Auth.prototype['fetchProvidersForEmail'] =\n  //     fireauth.Auth.prototype['qZ'];\n  for (var obfuscatedFnName in fnMap) {\n    var unobfuscatedFnName = fnMap[obfuscatedFnName].name;\n    protObj[unobfuscatedFnName] =\n        fireauth.exportlib.wrapMethodWithArgumentVerifier_(\n        unobfuscatedFnName, protObj[obfuscatedFnName],\n        fnMap[obfuscatedFnName].args);\n  }\n};\n\n\n/**\n * Exports properties of an object. See the docs for exportPrototypeMethods for\n * more information about how this works.\n * @param {!Object} protObj The prototype of an object.\n * @param {!Object<string, !fireauth.exportlib.ExportedProperty>} propMap The\n *     map of properties to their export names.\n */\nfireauth.exportlib.exportPrototypeProperties = function(protObj, propMap) {\n  for (var obfuscatedPropName in propMap) {\n    var unobfuscatedPropName = propMap[obfuscatedPropName].name;\n    // Don't alias a property to itself.\n    // Downside is that argument validation will not be possible. For now, to\n    // get around it, ensure unobfuscated property names are different\n    // than the corresponding obfuscated property names.\n    if (unobfuscatedPropName === obfuscatedPropName) {\n      continue;\n    }\n    /**\n     * @this {!Object}\n     * @param {string} obfuscatedPropName The obfuscated property name.\n     * @return {*} The value of the property.\n     */\n    var getter = function(obfuscatedPropName) {\n      return this[obfuscatedPropName];\n    };\n    /**\n     * @this {!Object}\n     * @param {string} unobfuscatedPropName The unobfuscated property name.\n     * @param {string} obfuscatedPropName The obfuscated property name.\n     * @param {!fireauth.args.Argument} expectedArg The expected argument to the\n     *     setter of this property.\n     * @param {*} value The new value of the property.\n     */\n    var setter = function(unobfuscatedPropName, obfuscatedPropName,\n                          expectedArg, value) {\n      // Validate the argument before setting it.\n      fireauth.args.validate(\n          unobfuscatedPropName, [expectedArg], [value], true);\n      this[obfuscatedPropName] = value;\n    };\n    // Get the expected argument.\n    var expectedArg = propMap[obfuscatedPropName].arg;\n    Object.defineProperty(protObj, unobfuscatedPropName, {\n      /**\n       * @this {!Object}\n       * @return {*} The value of the property.\n       */\n      get: goog.partial(getter, obfuscatedPropName),\n      /**\n       * @this {!Object}\n       * @param {*} value The new value of the property.\n       */\n      set: goog.partial(setter, unobfuscatedPropName, obfuscatedPropName,\n                        expectedArg),\n      enumerable: true\n    });\n  }\n};\n\n\n/**\n * Export a static method as a public API.\n * @param {!Object} parentObj The parent object to patch.\n * @param {string} name The public name of the method.\n * @param {!Function} func The method.\n * @param {?Array<!fireauth.args.Argument>=} opt_expectedArgs The expected\n *     arguments to the method.\n */\nfireauth.exportlib.exportFunction = function(parentObj, name, func,\n    opt_expectedArgs) {\n  parentObj[name] = fireauth.exportlib.wrapMethodWithArgumentVerifier_(\n      name, func, opt_expectedArgs);\n};\n\n\n/**\n * Wraps a method with a function that first verifies the arguments to the\n * method and then calls the original method.\n * @param {string} methodName The name of the method, which will be displayed\n *     on the error message if the arguments are not valid.\n * @param {!Function} method The method to be wrapped.\n * @param {?Array<!fireauth.args.Argument>=} opt_expectedArgs The expected\n *     arguments.\n * @return {!Function} The wrapped method.\n * @private\n */\nfireauth.exportlib.wrapMethodWithArgumentVerifier_ = function(methodName,\n    method, opt_expectedArgs) {\n  if (!opt_expectedArgs) {\n    return method;\n  }\n  var shortName = fireauth.exportlib.extractMethodNameFromFullPath_(methodName);\n  var wrapper = function() {\n    var argumentsAsArray = Array.prototype.slice.call(arguments);\n    fireauth.args.validate(shortName,\n        /** @type {!Array<!fireauth.args.Argument>} */ (opt_expectedArgs),\n        argumentsAsArray);\n    return method.apply(this, argumentsAsArray);\n  };\n  // Reattach all static stuff to wrapper.\n  for (var key in method) {\n    wrapper[key] = method[key];\n  }\n  // Reattach all prototype stuff to wrapper.\n  for (var key in method.prototype) {\n    wrapper.prototype[key] = method.prototype[key];\n  }\n  // Return wrapper with all of method's static and prototype methods and\n  // properties.\n  return wrapper;\n};\n\n\n/**\n * From a full path to a method (e.g. \"fireauth.GoogleAuthProvider.credential\"),\n * get just the method name (\"credential\").\n * @param {string} path The full path.\n * @return {string} The method name.\n * @private\n */\nfireauth.exportlib.extractMethodNameFromFullPath_ = function(path) {\n  var parts = path.split('.');\n  return parts[parts.length - 1];\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngoog.provide('fireauth.exports');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeURL');\ngoog.require('fireauth.Auth');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthErrorWithCredential');\ngoog.require('fireauth.AuthSettings');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.EmailAuthCredential');\ngoog.require('fireauth.EmailAuthProvider');\ngoog.require('fireauth.FacebookAuthProvider');\ngoog.require('fireauth.GRecaptchaMockFactory');\ngoog.require('fireauth.GithubAuthProvider');\ngoog.require('fireauth.GoogleAuthProvider');\ngoog.require('fireauth.InvalidOriginError');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.MultiFactorResolver');\ngoog.require('fireauth.MultiFactorUser');\ngoog.require('fireauth.OAuthCredential');\ngoog.require('fireauth.OAuthProvider');\ngoog.require('fireauth.PhoneAuthCredential');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.PhoneMultiFactorGenerator');\ngoog.require('fireauth.RecaptchaVerifier');\ngoog.require('fireauth.SAMLAuthCredential');\ngoog.require('fireauth.SAMLAuthProvider');\ngoog.require('fireauth.TwitterAuthProvider');\ngoog.require('fireauth.args');\ngoog.require('fireauth.authStorage.Persistence');\ngoog.require('fireauth.exportlib');\ngoog.require('fireauth.grecaptcha');\ngoog.require('fireauth.idp.ProviderId');\ngoog.require('goog.Promise');\n\n/** @define {string} */\nconst AUTH_NPM_PACKAGE_VERSION = '';\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.Auth.prototype, {\n      applyActionCode: {\n        name: 'applyActionCode',\n        args: [fireauth.args.string('code')]\n      },\n      checkActionCode: {\n        name: 'checkActionCode',\n        args: [fireauth.args.string('code')]\n      },\n      confirmPasswordReset: {\n        name: 'confirmPasswordReset',\n        args: [\n          fireauth.args.string('code'),\n          fireauth.args.string('newPassword')\n        ]\n      },\n      createUserWithEmailAndPassword: {\n        name: 'createUserWithEmailAndPassword',\n        args: [fireauth.args.string('email'), fireauth.args.string('password')]\n      },\n      fetchSignInMethodsForEmail: {\n        name: 'fetchSignInMethodsForEmail',\n        args: [fireauth.args.string('email')]\n      },\n      getRedirectResult: {\n        name: 'getRedirectResult',\n        args: []\n      },\n      isSignInWithEmailLink: {\n        name: 'isSignInWithEmailLink',\n        args: [fireauth.args.string('emailLink')]\n      },\n      onAuthStateChanged: {\n        name: 'onAuthStateChanged',\n        args: [\n          fireauth.args.or(\n              fireauth.args.object(),\n              fireauth.args.func(),\n              'nextOrObserver'),\n          fireauth.args.func('opt_error', true),\n          fireauth.args.func('opt_completed', true)\n        ]\n      },\n      onIdTokenChanged: {\n        name: 'onIdTokenChanged',\n        args: [\n          fireauth.args.or(\n              fireauth.args.object(),\n              fireauth.args.func(),\n              'nextOrObserver'),\n          fireauth.args.func('opt_error', true),\n          fireauth.args.func('opt_completed', true)\n        ]\n      },\n      sendPasswordResetEmail: {\n        name: 'sendPasswordResetEmail',\n        args: [\n          fireauth.args.string('email'),\n          fireauth.args.or(\n              fireauth.args.object('opt_actionCodeSettings', true),\n              fireauth.args.null(null, true),\n              'opt_actionCodeSettings',\n              true)\n        ]\n      },\n      sendSignInLinkToEmail: {\n        name: 'sendSignInLinkToEmail',\n        args: [\n          fireauth.args.string('email'),\n          fireauth.args.object('actionCodeSettings')\n        ]\n      },\n      setPersistence: {\n        name: 'setPersistence',\n        args:  [fireauth.args.string('persistence')]\n      },\n      signInAndRetrieveDataWithCredential: {\n        name: 'signInAndRetrieveDataWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      signInAnonymously: {\n        name: 'signInAnonymously',\n        args: []\n      },\n      signInWithCredential: {\n        name: 'signInWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      signInWithCustomToken: {\n        name: 'signInWithCustomToken',\n        args: [fireauth.args.string('token')]\n      },\n      signInWithEmailAndPassword: {\n        name: 'signInWithEmailAndPassword',\n        args: [fireauth.args.string('email'), fireauth.args.string('password')]\n      },\n      signInWithEmailLink: {\n        name: 'signInWithEmailLink',\n        args: [\n          fireauth.args.string('email'), fireauth.args.string('emailLink', true)\n        ]\n      },\n      signInWithPhoneNumber: {\n        name: 'signInWithPhoneNumber',\n        args: [\n          fireauth.args.string('phoneNumber'),\n          fireauth.args.applicationVerifier()\n        ]\n      },\n      signInWithPopup: {\n        name: 'signInWithPopup',\n        args: [fireauth.args.authProvider()]\n      },\n      signInWithRedirect: {\n        name: 'signInWithRedirect',\n        args: [fireauth.args.authProvider()]\n      },\n      updateCurrentUser: {\n        name: 'updateCurrentUser',\n        args: [\n          fireauth.args.or(\n            fireauth.args.firebaseUser(),\n            fireauth.args.null(),\n            'user')\n        ]\n      },\n      signOut: {\n        name: 'signOut',\n        args: []\n      },\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      },\n      useDeviceLanguage: {\n        name: 'useDeviceLanguage',\n        args: []\n      },\n      verifyPasswordResetCode: {\n        name: 'verifyPasswordResetCode',\n        args: [fireauth.args.string('code')]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeProperties(\n    fireauth.Auth.prototype, {\n      'lc': {\n        name: 'languageCode',\n        arg: fireauth.args.or(\n            fireauth.args.string(),\n            fireauth.args.null(),\n            'languageCode')\n      },\n      'ti': {\n        name: 'tenantId',\n        arg: fireauth.args.or(\n            fireauth.args.string(),\n            fireauth.args.null(),\n            'tenantId')\n      }\n    });\n\n// Exports firebase.auth.Auth.Persistence.\nfireauth.Auth['Persistence'] = fireauth.authStorage.Persistence;\nfireauth.Auth['Persistence']['LOCAL'] = fireauth.authStorage.Persistence.LOCAL;\nfireauth.Auth['Persistence']['SESSION'] =\n    fireauth.authStorage.Persistence.SESSION;\nfireauth.Auth['Persistence']['NONE'] = fireauth.authStorage.Persistence.NONE;\n\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.AuthUser.prototype, {\n      'delete': {\n        name: 'delete',\n        args: []\n      },\n      getIdTokenResult: {\n        name: 'getIdTokenResult',\n        args: [fireauth.args.bool('opt_forceRefresh', true)]\n      },\n      getIdToken: {\n        name: 'getIdToken',\n        args: [fireauth.args.bool('opt_forceRefresh', true)]\n      },\n      linkAndRetrieveDataWithCredential: {\n        name: 'linkAndRetrieveDataWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      linkWithCredential: {\n        name: 'linkWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      linkWithPhoneNumber: {\n        name: 'linkWithPhoneNumber',\n        args: [\n          fireauth.args.string('phoneNumber'),\n          fireauth.args.applicationVerifier()\n        ]\n      },\n      linkWithPopup: {\n        name: 'linkWithPopup',\n        args: [fireauth.args.authProvider()]\n      },\n      linkWithRedirect: {\n        name: 'linkWithRedirect',\n        args: [fireauth.args.authProvider()]\n      },\n      reauthenticateAndRetrieveDataWithCredential: {\n        name: 'reauthenticateAndRetrieveDataWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      reauthenticateWithCredential: {\n        name: 'reauthenticateWithCredential',\n        args: [fireauth.args.authCredential()]\n      },\n      reauthenticateWithPhoneNumber: {\n        name: 'reauthenticateWithPhoneNumber',\n        args: [\n          fireauth.args.string('phoneNumber'),\n          fireauth.args.applicationVerifier()\n        ]\n      },\n      reauthenticateWithPopup: {\n        name: 'reauthenticateWithPopup',\n        args: [fireauth.args.authProvider()]\n      },\n      reauthenticateWithRedirect: {\n        name: 'reauthenticateWithRedirect',\n        args: [fireauth.args.authProvider()]\n      },\n      reload: {\n        name: 'reload',\n        args: []\n      },\n      sendEmailVerification: {\n        name: 'sendEmailVerification',\n        args: [\n          fireauth.args.or(\n              fireauth.args.object('opt_actionCodeSettings', true),\n              fireauth.args.null(null, true),\n              'opt_actionCodeSettings',\n              true)\n        ]\n      },\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      },\n      unlink: {\n        name: 'unlink',\n        args: [fireauth.args.string('provider')]\n      },\n      updateEmail: {\n        name: 'updateEmail',\n        args: [fireauth.args.string('email')]\n      },\n      updatePassword: {\n        name: 'updatePassword',\n        args: [fireauth.args.string('password')]\n      },\n      updatePhoneNumber: {\n        name: 'updatePhoneNumber',\n        args: [fireauth.args.authCredential(fireauth.idp.ProviderId.PHONE)]\n      },\n      updateProfile: {\n        name: 'updateProfile',\n        args: [fireauth.args.object('profile')]\n      },\n      verifyBeforeUpdateEmail: {\n        name: 'verifyBeforeUpdateEmail',\n        args: [\n          fireauth.args.string('email'),\n          fireauth.args.or(\n              fireauth.args.object('opt_actionCodeSettings', true),\n              fireauth.args.null(null, true),\n              'opt_actionCodeSettings',\n              true)\n        ]\n      }\n    });\n\n// Ensure internal grecaptcha mock API do not get obfuscated.\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.GRecaptchaMockFactory.prototype, {\n      execute: {\n        name: 'execute'\n      },\n      render: {\n        name: 'render'\n      },\n      reset: {\n        name: 'reset'\n      },\n      getResponse: {\n        name: 'getResponse'\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.grecaptcha.prototype, {\n      execute: {\n        name: 'execute'\n      },\n      render: {\n        name: 'render'\n      },\n      reset: {\n        name: 'reset'\n      },\n      getResponse: {\n        name: 'getResponse'\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    goog.Promise.prototype, {\n      thenAlways: {\n        name: 'finally'\n      },\n      thenCatch: {\n        name: 'catch'\n      },\n      then: {\n        name: 'then'\n      }\n    });\n\nfireauth.exportlib.exportPrototypeProperties(\n    fireauth.AuthSettings.prototype, {\n      'appVerificationDisabled': {\n        name: 'appVerificationDisabledForTesting',\n        arg: fireauth.args.bool('appVerificationDisabledForTesting')\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n   fireauth.ConfirmationResult.prototype, {\n      confirm: {\n        name: 'confirm',\n        args: [\n          fireauth.args.string('verificationCode')\n        ]\n      }\n    });\n\nfireauth.exportlib.exportFunction(\n    fireauth.AuthCredential, 'fromJSON',\n    fireauth.AuthCredential.fromPlainObject, [\n      fireauth.args.or(fireauth.args.string(), fireauth.args.object(), 'json')\n    ]);\n\nfireauth.exportlib.exportFunction(\n    fireauth.EmailAuthProvider, 'credential',\n    fireauth.EmailAuthProvider.credential, [\n      fireauth.args.string('email'),\n      fireauth.args.string('password')\n    ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.EmailAuthCredential.prototype, {\n     toPlainObject: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.FacebookAuthProvider.prototype, {\n      addScope: {\n        name: 'addScope',\n        args: [fireauth.args.string('scope')]\n      },\n      setCustomParameters: {\n        name: 'setCustomParameters',\n        args: [fireauth.args.object('customOAuthParameters')]\n      }\n    });\nfireauth.exportlib.exportFunction(\n    fireauth.FacebookAuthProvider, 'credential',\n    fireauth.FacebookAuthProvider.credential, [\n      fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n          'token')\n    ]);\nfireauth.exportlib.exportFunction(\n    fireauth.EmailAuthProvider, 'credentialWithLink',\n    fireauth.EmailAuthProvider.credentialWithLink, [\n      fireauth.args.string('email'),\n      fireauth.args.string('emailLink')\n    ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.GithubAuthProvider.prototype, {\n      addScope: {\n        name: 'addScope',\n        args: [fireauth.args.string('scope')]\n      },\n      setCustomParameters: {\n        name: 'setCustomParameters',\n        args: [fireauth.args.object('customOAuthParameters')]\n      }\n    });\nfireauth.exportlib.exportFunction(\n    fireauth.GithubAuthProvider, 'credential',\n    fireauth.GithubAuthProvider.credential, [\n      fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n          'token')\n    ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.GoogleAuthProvider.prototype, {\n      addScope: {\n        name: 'addScope',\n        args: [fireauth.args.string('scope')]\n      },\n      setCustomParameters: {\n        name: 'setCustomParameters',\n        args: [fireauth.args.object('customOAuthParameters')]\n      }\n    });\nfireauth.exportlib.exportFunction(\n    fireauth.GoogleAuthProvider, 'credential',\n    fireauth.GoogleAuthProvider.credential, [\n      fireauth.args.or(fireauth.args.string(),\n          fireauth.args.or(fireauth.args.object(), fireauth.args.null()),\n          'idToken'),\n      fireauth.args.or(fireauth.args.string(), fireauth.args.null(),\n          'accessToken', true)\n    ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.TwitterAuthProvider.prototype, {\n      setCustomParameters: {\n        name: 'setCustomParameters',\n        args: [fireauth.args.object('customOAuthParameters')]\n      }\n    });\nfireauth.exportlib.exportFunction(\n    fireauth.TwitterAuthProvider, 'credential',\n    fireauth.TwitterAuthProvider.credential, [\n      fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n          'token'),\n      fireauth.args.string('secret', true)\n    ]);\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.OAuthProvider.prototype, {\n      addScope: {\n        name: 'addScope',\n        args: [fireauth.args.string('scope')]\n      },\n      credential: {\n        name: 'credential',\n        args: [\n          fireauth.args.or(\n              fireauth.args.string(),\n              fireauth.args.or(fireauth.args.object(), fireauth.args.null()),\n              'optionsOrIdToken'),\n          fireauth.args.or(fireauth.args.string(), fireauth.args.null(),\n              'accessToken', true)\n        ]\n      },\n      setCustomParameters: {\n        name: 'setCustomParameters',\n        args: [fireauth.args.object('customOAuthParameters')]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.OAuthCredential.prototype, {\n     toPlainObject: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.SAMLAuthCredential.prototype, {\n     toPlainObject: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\n\nfireauth.exportlib.exportFunction(\n    fireauth.PhoneAuthProvider, 'credential',\n    fireauth.PhoneAuthProvider.credential, [\n      fireauth.args.string('verificationId'),\n      fireauth.args.string('verificationCode')\n    ]);\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.PhoneAuthProvider.prototype, {\n      verifyPhoneNumber: {\n        name: 'verifyPhoneNumber',\n        args: [\n          fireauth.args.or(\n              fireauth.args.string(),\n              fireauth.args.phoneInfoOptions(),\n              'phoneInfoOptions'),\n          fireauth.args.applicationVerifier()\n        ]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.PhoneAuthCredential.prototype, {\n     toPlainObject: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.AuthError.prototype, {\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.AuthErrorWithCredential.prototype, {\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.InvalidOriginError.prototype, {\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.MultiFactorError.prototype, {\n      toJSON: {\n        name: 'toJSON',\n        // This shouldn't take an argument but a blank string is being passed\n        // on JSON.stringify and causing this to fail with an argument error.\n        // So allow an optional string.\n        args: [fireauth.args.string(null, true)]\n      }\n    });\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.MultiFactorResolver.prototype, {\n      resolveSignIn: {\n        name: 'resolveSignIn',\n        args: [fireauth.args.multiFactorAssertion()]\n      }\n    });\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.MultiFactorUser.prototype, {\n      getSession: {\n        name: 'getSession',\n        args: []\n      },\n      enroll: {\n        name: 'enroll',\n        args: [\n          fireauth.args.multiFactorAssertion(),\n          fireauth.args.string('displayName', true)\n        ]\n      },\n      unenroll: {\n        name: 'unenroll',\n        args: [\n          fireauth.args.or(\n              fireauth.args.multiFactorInfo(),\n              fireauth.args.string(),\n              'multiFactorInfoIdentifier')\n        ]\n      }\n    });\n\nfireauth.exportlib.exportPrototypeMethods(\n    fireauth.RecaptchaVerifier.prototype, {\n      clear: {\n        name: 'clear',\n        args: []\n      },\n      render: {\n        name: 'render',\n        args: []\n      },\n      verify: {\n        name: 'verify',\n        args: []\n      }\n    });\n\nfireauth.exportlib.exportFunction(\n    fireauth.ActionCodeURL, 'parseLink',\n    fireauth.ActionCodeURL.parseLink, [fireauth.args.string('link')]);\n\nfireauth.exportlib.exportFunction(\n    fireauth.PhoneMultiFactorGenerator, 'assertion',\n    fireauth.PhoneMultiFactorGenerator.assertion,\n    [fireauth.args.authCredential(fireauth.idp.ProviderId.PHONE)]);\n\n\n(function() {\n  if (typeof firebase === 'undefined' || !firebase.INTERNAL ||\n      !firebase.INTERNAL.registerComponent) {\n    throw new Error('Cannot find the firebase namespace; be sure to include ' +\n        'firebase-app.js before this library.');\n  } else {\n    var namespace = {\n      // Exports firebase.auth.ActionCodeInfo.Operation.\n      'ActionCodeInfo': {\n        'Operation': {\n          'EMAIL_SIGNIN': fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN,\n          'PASSWORD_RESET': fireauth.ActionCodeInfo.Operation.PASSWORD_RESET,\n          'RECOVER_EMAIL': fireauth.ActionCodeInfo.Operation.RECOVER_EMAIL,\n          'REVERT_SECOND_FACTOR_ADDITION':\n              fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION,\n          'VERIFY_AND_CHANGE_EMAIL':\n              fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL,\n          'VERIFY_EMAIL': fireauth.ActionCodeInfo.Operation.VERIFY_EMAIL\n        }\n      },\n      'Auth': fireauth.Auth,\n      'AuthCredential': fireauth.AuthCredential,\n      'Error': fireauth.AuthError\n    };\n    fireauth.exportlib.exportFunction(namespace,\n        'EmailAuthProvider', fireauth.EmailAuthProvider, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'FacebookAuthProvider', fireauth.FacebookAuthProvider, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'GithubAuthProvider', fireauth.GithubAuthProvider, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'GoogleAuthProvider', fireauth.GoogleAuthProvider, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'TwitterAuthProvider', fireauth.TwitterAuthProvider, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'OAuthProvider', fireauth.OAuthProvider, [\n          fireauth.args.string('providerId')\n        ]);\n    fireauth.exportlib.exportFunction(namespace,\n        'SAMLAuthProvider', fireauth.SAMLAuthProvider, [\n          fireauth.args.string('providerId')\n        ]);\n    fireauth.exportlib.exportFunction(namespace,\n        'PhoneAuthProvider', fireauth.PhoneAuthProvider, [\n          fireauth.args.firebaseAuth(true)\n        ]);\n    fireauth.exportlib.exportFunction(namespace,\n        'RecaptchaVerifier', fireauth.RecaptchaVerifier, [\n          fireauth.args.or(\n              fireauth.args.string(),\n              fireauth.args.element(),\n              'recaptchaContainer'),\n          fireauth.args.object('recaptchaParameters', true),\n          fireauth.args.firebaseApp(true)\n        ]);\n    fireauth.exportlib.exportFunction(namespace,\n        'ActionCodeURL', fireauth.ActionCodeURL, []);\n    fireauth.exportlib.exportFunction(namespace,\n        'PhoneMultiFactorGenerator', fireauth.PhoneMultiFactorGenerator, []);\n\n    // Create auth components to register with firebase.\n    // Provides Auth public APIs.\n    const authComponent = { \n      'name': fireauth.exportlib.AUTH_TYPE,\n      'instanceFactory': function(container) {\n        var app = container['getProvider']('app')['getImmediate']();\n        return new fireauth.Auth(app);\n      },\n      'multipleInstances': false,\n      'serviceProps': namespace,\n      'instantiationMode': 'LAZY',\n      'type':  'PUBLIC'\n    };\n  \n    // Provides Auth internal APIs.\n    const authInteropComponent = { \n      'name': 'auth-internal',\n      'instanceFactory': function(container) {\n        var auth = container['getProvider'](fireauth.exportlib.AUTH_TYPE)['getImmediate']();\n        return {\n          'getUid': goog.bind(auth.getUid, auth),\n          'getToken': goog.bind(auth.getIdTokenInternal, auth),\n          'addAuthTokenListener':\n            goog.bind(auth.addAuthTokenListenerInternal, auth),\n          'removeAuthTokenListener':\n            goog.bind(auth.removeAuthTokenListenerInternal, auth)\n        };\n      },\n      'multipleInstances': false,\n      'instantiationMode': 'LAZY',\n      'type':  'PRIVATE'\n    };\n  \n    firebase.INTERNAL.registerComponent(authComponent);\n    firebase.INTERNAL.registerComponent(authInteropComponent);\n    firebase.registerVersion('@firebase/auth', AUTH_NPM_PACKAGE_VERSION);\n\n    // Expose User as firebase.User.\n    firebase.INTERNAL.extendNamespace({\n      'User': fireauth.AuthUser\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} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component<T extends Name = Name> {\n  multipleInstances = false;\n  /**\n   * Properties to be added to the service namespace\n   */\n  serviceProps: Dictionary = {};\n\n  instantiationMode = InstantiationMode.LAZY;\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<T>,\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","/**\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 { InstantiationMode, Name, NameServiceMapping } 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<T extends Name> {\n  private component: Component<T> | null = null;\n  private readonly instances: Map<string, NameServiceMapping[T]> = new Map();\n  private readonly instancesDeferred: Map<\n    string,\n    Deferred<NameServiceMapping[T]>\n  > = 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 = DEFAULT_ENTRY_NAME): Promise<NameServiceMapping[T]> {\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<NameServiceMapping[T]>();\n      this.instancesDeferred.set(normalizedIdentifier, deferred);\n      // If the service instance is available, resolve the promise with it immediately\n      try {\n        const instance = this.getOrInitializeService(normalizedIdentifier);\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    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    const { identifier, optional } = {\n      identifier: DEFAULT_ENTRY_NAME,\n      optional: false,\n      ...options\n    };\n    // if multipleInstances is not supported, use the default name\n    const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n    try {\n      const instance = this.getOrInitializeService(normalizedIdentifier);\n\n      if (!instance) {\n        if (optional) {\n          return null;\n        }\n        throw Error(`Service ${this.name} is not available`);\n      }\n      return instance;\n    } catch (e) {\n      if (optional) {\n        return null;\n      } else {\n        throw e;\n      }\n    }\n  }\n\n  getComponent(): Component<T> | null {\n    return this.component;\n  }\n\n  setComponent(component: Component<T>): 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    // if the service is eager, initialize the default instance\n    if (isComponentEager(component)) {\n      try {\n        this.getOrInitializeService(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 = this.normalizeInstanceIdentifier(\n        instanceIdentifier\n      );\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(normalizedIdentifier)!;\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.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<void> {\n    const services = Array.from(this.instances.values());\n\n    await Promise.all(\n      services\n        .filter(service => 'INTERNAL' in service)\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        .map(service => (service as any).INTERNAL!.delete())\n    );\n  }\n\n  isComponentSet(): boolean {\n    return this.component != null;\n  }\n\n  private getOrInitializeService(\n    identifier: string\n  ): NameServiceMapping[T] | null {\n    let instance = this.instances.get(identifier);\n    if (!instance && this.component) {\n      instance = this.component.instanceFactory(\n        this.container,\n        normalizeIdentifierForFactory(identifier)\n      ) as NameServiceMapping[T];\n      this.instances.set(identifier, instance);\n    }\n\n    return instance || null;\n  }\n\n  private normalizeInstanceIdentifier(identifier: string): 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\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<Name>): 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<string, Provider<Name>>();\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<T extends Name>(component: Component<T>): 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<T extends Name>(component: Component<T>): 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<T extends Name>(name: T): Provider<T> {\n    if (this.providers.has(name)) {\n      return this.providers.get(name) as Provider<T>;\n    }\n\n    // create a Provider for a service that hasn't registered with Firebase\n    const provider = new Provider<T>(name, this);\n    this.providers.set(name, provider);\n\n    return provider as Provider<T>;\n  }\n\n  getProviders(): Array<Provider<Name>> {\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\nimport { jsonEval, stringify } from '@firebase/util';\n\n/**\n * Wraps a DOM Storage object and:\n * - automatically encode objects as JSON strings before storing them to allow us to store arbitrary types.\n * - prefixes names with \"firebase:\" to avoid collisions with app data.\n *\n * We automatically (see storage.js) create two such wrappers, one for sessionStorage,\n * and one for localStorage.\n *\n * @constructor\n */\nexport class DOMStorageWrapper {\n  // Use a prefix to avoid collisions with other stuff saved by the app.\n  private prefix_ = 'firebase:';\n\n  /**\n   * @param {Storage} domStorage_ The underlying storage object (e.g. localStorage or sessionStorage)\n   */\n  constructor(private domStorage_: Storage) {}\n\n  /**\n   * @param {string} key The key to save the value under\n   * @param {?Object} value The value being stored, or null to remove the key.\n   */\n  set(key: string, value: unknown | null) {\n    if (value == null) {\n      this.domStorage_.removeItem(this.prefixedName_(key));\n    } else {\n      this.domStorage_.setItem(this.prefixedName_(key), stringify(value));\n    }\n  }\n\n  /**\n   * @param {string} key\n   * @return {*} The value that was stored under this key, or null\n   */\n  get(key: string): unknown {\n    const storedVal = this.domStorage_.getItem(this.prefixedName_(key));\n    if (storedVal == null) {\n      return null;\n    } else {\n      return jsonEval(storedVal);\n    }\n  }\n\n  /**\n   * @param {string} key\n   */\n  remove(key: string) {\n    this.domStorage_.removeItem(this.prefixedName_(key));\n  }\n\n  isInMemoryStorage: boolean;\n\n  /**\n   * @param {string} name\n   * @return {string}\n   */\n  prefixedName_(name: string): string {\n    return this.prefix_ + name;\n  }\n\n  toString(): string {\n    return this.domStorage_.toString();\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 { contains } from '@firebase/util';\n\n/**\n * An in-memory storage implementation that matches the API of DOMStorageWrapper\n * (TODO: create interface for both to implement).\n *\n * @constructor\n */\nexport class MemoryStorage {\n  private cache_: { [k: string]: unknown } = {};\n\n  set(key: string, value: unknown | null) {\n    if (value == null) {\n      delete this.cache_[key];\n    } else {\n      this.cache_[key] = value;\n    }\n  }\n\n  get(key: string): unknown {\n    if (contains(this.cache_, key)) {\n      return this.cache_[key];\n    }\n    return null;\n  }\n\n  remove(key: string) {\n    delete this.cache_[key];\n  }\n\n  isInMemoryStorage = 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\nimport { DOMStorageWrapper } from './DOMStorageWrapper';\nimport { MemoryStorage } from './MemoryStorage';\n\ndeclare const window: Window;\n\n/**\n * Helper to create a DOMStorageWrapper or else fall back to MemoryStorage.\n * TODO: Once MemoryStorage and DOMStorageWrapper have a shared interface this method annotation should change\n * to reflect this type\n *\n * @param {string} domStorageName Name of the underlying storage object\n *   (e.g. 'localStorage' or 'sessionStorage').\n * @return {?} Turning off type information until a common interface is defined.\n */\nconst createStoragefor = function (\n  domStorageName: string\n): DOMStorageWrapper | MemoryStorage {\n  try {\n    // NOTE: just accessing \"localStorage\" or \"window['localStorage']\" may throw a security exception,\n    // so it must be inside the try/catch.\n    if (\n      typeof window !== 'undefined' &&\n      typeof window[domStorageName] !== 'undefined'\n    ) {\n      // Need to test cache. Just because it's here doesn't mean it works\n      const domStorage = window[domStorageName];\n      domStorage.setItem('firebase:sentinel', 'cache');\n      domStorage.removeItem('firebase:sentinel');\n      return new DOMStorageWrapper(domStorage);\n    }\n  } catch (e) {}\n\n  // Failed to create wrapper.  Just return in-memory storage.\n  // TODO: log?\n  return new MemoryStorage();\n};\n\n/** A storage object that lasts across sessions */\nexport const PersistentStorage = createStoragefor('localStorage');\n\n/** A storage object that only lasts one session */\nexport const SessionStorage = createStoragefor('sessionStorage');\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 { Query } from '../../api/Query';\nimport {\n  assert,\n  base64,\n  Sha1,\n  stringToByteArray,\n  stringify,\n  isNodeSdk\n} from '@firebase/util';\nimport { SessionStorage } from '../storage/storage';\nimport { Logger, LogLevel } from '@firebase/logger';\n\ndeclare const window: Window;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const Windows: any;\n\nconst logClient = new Logger('@firebase/database');\n\n/**\n * Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).\n * @type {function(): number} Generated ID.\n */\nexport const LUIDGenerator: () => number = (function () {\n  let id = 1;\n  return function () {\n    return id++;\n  };\n})();\n\n/**\n * Sha1 hash of the input string\n * @param {!string} str The string to hash\n * @return {!string} The resulting hash\n */\nexport const sha1 = function (str: string): string {\n  const utf8Bytes = stringToByteArray(str);\n  const sha1 = new Sha1();\n  sha1.update(utf8Bytes);\n  const sha1Bytes = sha1.digest();\n  return base64.encodeByteArray(sha1Bytes);\n};\n\n/**\n * @param {...*} varArgs\n * @return {string}\n * @private\n */\nconst buildLogMessage_ = function (...varArgs: unknown[]): string {\n  let message = '';\n  for (let i = 0; i < varArgs.length; i++) {\n    const arg = varArgs[i];\n    if (\n      Array.isArray(arg) ||\n      (arg &&\n        typeof arg === 'object' &&\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        typeof (arg as any).length === 'number')\n    ) {\n      message += buildLogMessage_.apply(null, arg);\n    } else if (typeof arg === 'object') {\n      message += stringify(arg);\n    } else {\n      message += arg;\n    }\n    message += ' ';\n  }\n\n  return message;\n};\n\n/**\n * Use this for all debug messages in Firebase.\n * @type {?function(string)}\n */\nexport let logger: ((a: string) => void) | null = null;\n\n/**\n * Flag to check for log availability on first log message\n * @type {boolean}\n * @private\n */\nlet firstLog_ = true;\n\n/**\n * The implementation of Firebase.enableLogging (defined here to break dependencies)\n * @param {boolean|?function(string)} logger_ A flag to turn on logging, or a custom logger\n * @param {boolean=} persistent Whether or not to persist logging settings across refreshes\n */\nexport const enableLogging = function (\n  logger_?: boolean | ((a: string) => void) | null,\n  persistent?: boolean\n) {\n  assert(\n    !persistent || logger_ === true || logger_ === false,\n    \"Can't turn on custom loggers persistently.\"\n  );\n  if (logger_ === true) {\n    logClient.logLevel = LogLevel.VERBOSE;\n    logger = logClient.log.bind(logClient);\n    if (persistent) {\n      SessionStorage.set('logging_enabled', true);\n    }\n  } else if (typeof logger_ === 'function') {\n    logger = logger_;\n  } else {\n    logger = null;\n    SessionStorage.remove('logging_enabled');\n  }\n};\n\n/**\n *\n * @param {...(string|Arguments)} varArgs\n */\nexport const log = function (...varArgs: unknown[]) {\n  if (firstLog_ === true) {\n    firstLog_ = false;\n    if (logger === null && SessionStorage.get('logging_enabled') === true) {\n      enableLogging(true);\n    }\n  }\n\n  if (logger) {\n    const message = buildLogMessage_.apply(null, varArgs);\n    logger(message);\n  }\n};\n\n/**\n * @param {!string} prefix\n * @return {function(...[*])}\n */\nexport const logWrapper = function (\n  prefix: string\n): (...varArgs: unknown[]) => void {\n  return function (...varArgs: unknown[]) {\n    log(prefix, ...varArgs);\n  };\n};\n\n/**\n * @param {...string} varArgs\n */\nexport const error = function (...varArgs: string[]) {\n  const message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_(...varArgs);\n  logClient.error(message);\n};\n\n/**\n * @param {...string} varArgs\n */\nexport const fatal = function (...varArgs: string[]) {\n  const message = `FIREBASE FATAL ERROR: ${buildLogMessage_(...varArgs)}`;\n  logClient.error(message);\n  throw new Error(message);\n};\n\n/**\n * @param {...*} varArgs\n */\nexport const warn = function (...varArgs: unknown[]) {\n  const message = 'FIREBASE WARNING: ' + buildLogMessage_(...varArgs);\n  logClient.warn(message);\n};\n\n/**\n * Logs a warning if the containing page uses https. Called when a call to new Firebase\n * does not use https.\n */\nexport const warnIfPageIsSecure = function () {\n  // Be very careful accessing browser globals. Who knows what may or may not exist.\n  if (\n    typeof window !== 'undefined' &&\n    window.location &&\n    window.location.protocol &&\n    window.location.protocol.indexOf('https:') !== -1\n  ) {\n    warn(\n      'Insecure Firebase access from a secure page. ' +\n        'Please use https in calls to new Firebase().'\n    );\n  }\n};\n\n/**\n * @param {!String} methodName\n */\nexport const warnAboutUnsupportedMethod = function (methodName: string) {\n  warn(\n    methodName +\n      ' is unsupported and will likely change soon.  ' +\n      'Please do not use.'\n  );\n};\n\n/**\n * Returns true if data is NaN, or +/- Infinity.\n * @param {*} data\n * @return {boolean}\n */\nexport const isInvalidJSONNumber = function (data: unknown): boolean {\n  return (\n    typeof data === 'number' &&\n    (data !== data || // NaN\n      data === Number.POSITIVE_INFINITY ||\n      data === Number.NEGATIVE_INFINITY)\n  );\n};\n\n/**\n * @param {function()} fn\n */\nexport const executeWhenDOMReady = function (fn: () => void) {\n  if (isNodeSdk() || document.readyState === 'complete') {\n    fn();\n  } else {\n    // Modeled after jQuery. Try DOMContentLoaded and onreadystatechange (which\n    // fire before onload), but fall back to onload.\n\n    let called = false;\n    const wrappedFn = function () {\n      if (!document.body) {\n        setTimeout(wrappedFn, Math.floor(10));\n        return;\n      }\n\n      if (!called) {\n        called = true;\n        fn();\n      }\n    };\n\n    if (document.addEventListener) {\n      document.addEventListener('DOMContentLoaded', wrappedFn, false);\n      // fallback to onload.\n      window.addEventListener('load', wrappedFn, false);\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    } else if ((document as any).attachEvent) {\n      // IE.\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (document as any).attachEvent('onreadystatechange', () => {\n        if (document.readyState === 'complete') {\n          wrappedFn();\n        }\n      });\n      // fallback to onload.\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (window as any).attachEvent('onload', wrappedFn);\n\n      // jQuery has an extra hack for IE that we could employ (based on\n      // http://javascript.nwbox.com/IEContentLoaded/) But it looks really old.\n      // I'm hoping we don't need it.\n    }\n  }\n};\n\n/**\n * Minimum key name. Invalid for actual data, used as a marker to sort before any valid names\n * @type {!string}\n */\nexport const MIN_NAME = '[MIN_NAME]';\n\n/**\n * Maximum key name. Invalid for actual data, used as a marker to sort above any valid names\n * @type {!string}\n */\nexport const MAX_NAME = '[MAX_NAME]';\n\n/**\n * Compares valid Firebase key names, plus min and max name\n * @param {!string} a\n * @param {!string} b\n * @return {!number}\n */\nexport const nameCompare = function (a: string, b: string): number {\n  if (a === b) {\n    return 0;\n  } else if (a === MIN_NAME || b === MAX_NAME) {\n    return -1;\n  } else if (b === MIN_NAME || a === MAX_NAME) {\n    return 1;\n  } else {\n    const aAsInt = tryParseInt(a),\n      bAsInt = tryParseInt(b);\n\n    if (aAsInt !== null) {\n      if (bAsInt !== null) {\n        return aAsInt - bAsInt === 0 ? a.length - b.length : aAsInt - bAsInt;\n      } else {\n        return -1;\n      }\n    } else if (bAsInt !== null) {\n      return 1;\n    } else {\n      return a < b ? -1 : 1;\n    }\n  }\n};\n\n/**\n * @param {!string} a\n * @param {!string} b\n * @return {!number} comparison result.\n */\nexport const stringCompare = function (a: string, b: string): number {\n  if (a === b) {\n    return 0;\n  } else if (a < b) {\n    return -1;\n  } else {\n    return 1;\n  }\n};\n\n/**\n * @param {string} key\n * @param {Object} obj\n * @return {*}\n */\nexport const requireKey = function (\n  key: string,\n  obj: { [k: string]: unknown }\n): unknown {\n  if (obj && key in obj) {\n    return obj[key];\n  } else {\n    throw new Error(\n      'Missing required key (' + key + ') in object: ' + stringify(obj)\n    );\n  }\n};\n\n/**\n * @param {*} obj\n * @return {string}\n */\nexport const ObjectToUniqueKey = function (obj: unknown): string {\n  if (typeof obj !== 'object' || obj === null) {\n    return stringify(obj);\n  }\n\n  const keys = [];\n  // eslint-disable-next-line guard-for-in\n  for (const k in obj) {\n    keys.push(k);\n  }\n\n  // Export as json, but with the keys sorted.\n  keys.sort();\n  let key = '{';\n  for (let i = 0; i < keys.length; i++) {\n    if (i !== 0) {\n      key += ',';\n    }\n    key += stringify(keys[i]);\n    key += ':';\n    key += ObjectToUniqueKey(obj[keys[i]]);\n  }\n\n  key += '}';\n  return key;\n};\n\n/**\n * Splits a string into a number of smaller segments of maximum size\n * @param {!string} str The string\n * @param {!number} segsize The maximum number of chars in the string.\n * @return {Array.<string>} The string, split into appropriately-sized chunks\n */\nexport const splitStringBySize = function (\n  str: string,\n  segsize: number\n): string[] {\n  const len = str.length;\n\n  if (len <= segsize) {\n    return [str];\n  }\n\n  const dataSegs = [];\n  for (let c = 0; c < len; c += segsize) {\n    if (c + segsize > len) {\n      dataSegs.push(str.substring(c, len));\n    } else {\n      dataSegs.push(str.substring(c, c + segsize));\n    }\n  }\n  return dataSegs;\n};\n\n/**\n * Apply a function to each (key, value) pair in an object or\n * apply a function to each (index, value) pair in an array\n * @param obj The object or array to iterate over\n * @param fn The function to apply\n */\nexport function each(obj: object, fn: (k: string, v: unknown) => void) {\n  for (const key in obj) {\n    if (obj.hasOwnProperty(key)) {\n      fn(key, obj[key]);\n    }\n  }\n}\n\n/**\n * Like goog.bind, but doesn't bother to create a closure if opt_context is null/undefined.\n * @param {function(*)} callback Callback function.\n * @param {?Object=} context Optional context to bind to.\n * @return {function(*)}\n */\nexport const bindCallback = function (\n  callback: (a: unknown) => void,\n  context?: object | null\n): Function {\n  return context ? callback.bind(context) : callback;\n};\n\n/**\n * Borrowed from http://hg.secondlife.com/llsd/src/tip/js/typedarray.js (MIT License)\n * I made one modification at the end and removed the NaN / Infinity\n * handling (since it seemed broken [caused an overflow] and we don't need it).  See MJL comments.\n * @param {!number} v A double\n * @return {string}\n */\nexport const doubleToIEEE754String = function (v: number): string {\n  assert(!isInvalidJSONNumber(v), 'Invalid JSON number'); // MJL\n\n  const ebits = 11,\n    fbits = 52;\n  const bias = (1 << (ebits - 1)) - 1;\n  let s, e, f, ln, i;\n\n  // Compute sign, exponent, fraction\n  // Skip NaN / Infinity handling --MJL.\n  if (v === 0) {\n    e = 0;\n    f = 0;\n    s = 1 / v === -Infinity ? 1 : 0;\n  } else {\n    s = v < 0;\n    v = Math.abs(v);\n\n    if (v >= Math.pow(2, 1 - bias)) {\n      // Normalized\n      ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);\n      e = ln + bias;\n      f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits));\n    } else {\n      // Denormalized\n      e = 0;\n      f = Math.round(v / Math.pow(2, 1 - bias - fbits));\n    }\n  }\n\n  // Pack sign, exponent, fraction\n  const bits = [];\n  for (i = fbits; i; i -= 1) {\n    bits.push(f % 2 ? 1 : 0);\n    f = Math.floor(f / 2);\n  }\n  for (i = ebits; i; i -= 1) {\n    bits.push(e % 2 ? 1 : 0);\n    e = Math.floor(e / 2);\n  }\n  bits.push(s ? 1 : 0);\n  bits.reverse();\n  const str = bits.join('');\n\n  // Return the data as a hex string. --MJL\n  let hexByteString = '';\n  for (i = 0; i < 64; i += 8) {\n    let hexByte = parseInt(str.substr(i, 8), 2).toString(16);\n    if (hexByte.length === 1) {\n      hexByte = '0' + hexByte;\n    }\n    hexByteString = hexByteString + hexByte;\n  }\n  return hexByteString.toLowerCase();\n};\n\n/**\n * Used to detect if we're in a Chrome content script (which executes in an\n * isolated environment where long-polling doesn't work).\n * @return {boolean}\n */\nexport const isChromeExtensionContentScript = function (): boolean {\n  return !!(\n    typeof window === 'object' &&\n    window['chrome'] &&\n    window['chrome']['extension'] &&\n    !/^chrome/.test(window.location.href)\n  );\n};\n\n/**\n * Used to detect if we're in a Windows 8 Store app.\n * @return {boolean}\n */\nexport const isWindowsStoreApp = function (): boolean {\n  // Check for the presence of a couple WinRT globals\n  return typeof Windows === 'object' && typeof Windows.UI === 'object';\n};\n\n/**\n * Converts a server error code to a Javascript Error\n * @param {!string} code\n * @param {!Query} query\n * @return {Error}\n */\nexport const errorForServerCode = function (code: string, query: Query): Error {\n  let reason = 'Unknown Error';\n  if (code === 'too_big') {\n    reason =\n      'The data requested exceeds the maximum size ' +\n      'that can be accessed with a single request.';\n  } else if (code === 'permission_denied') {\n    reason = \"Client doesn't have permission to access the desired data.\";\n  } else if (code === 'unavailable') {\n    reason = 'The service is unavailable';\n  }\n\n  const error = new Error(\n    code + ' at ' + query.path.toString() + ': ' + reason\n  );\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  (error as any).code = code.toUpperCase();\n  return error;\n};\n\n/**\n * Used to test for integer-looking strings\n * @type {RegExp}\n * @private\n */\nexport const INTEGER_REGEXP_ = new RegExp('^-?(0*)\\\\d{1,10}$');\n\n/**\n * If the string contains a 32-bit integer, return it.  Else return null.\n * @param {!string} str\n * @return {?number}\n */\nexport const tryParseInt = function (str: string): number | null {\n  if (INTEGER_REGEXP_.test(str)) {\n    const intVal = Number(str);\n    if (intVal >= -2147483648 && intVal <= 2147483647) {\n      return intVal;\n    }\n  }\n  return null;\n};\n\n/**\n * Helper to run some code but catch any exceptions and re-throw them later.\n * Useful for preventing user callbacks from breaking internal code.\n *\n * Re-throwing the exception from a setTimeout is a little evil, but it's very\n * convenient (we don't have to try to figure out when is a safe point to\n * re-throw it), and the behavior seems reasonable:\n *\n * * If you aren't pausing on exceptions, you get an error in the console with\n *   the correct stack trace.\n * * If you're pausing on all exceptions, the debugger will pause on your\n *   exception and then again when we rethrow it.\n * * If you're only pausing on uncaught exceptions, the debugger will only pause\n *   on us re-throwing it.\n *\n * @param {!function()} fn The code to guard.\n */\nexport const exceptionGuard = function (fn: () => void) {\n  try {\n    fn();\n  } catch (e) {\n    // Re-throw exception when it's safe.\n    setTimeout(() => {\n      // It used to be that \"throw e\" would result in a good console error with\n      // relevant context, but as of Chrome 39, you just get the firebase.js\n      // file/line number where we re-throw it, which is useless. So we log\n      // e.stack explicitly.\n      const stack = e.stack || '';\n      warn('Exception was thrown by user callback.', stack);\n      throw e;\n    }, Math.floor(0));\n  }\n};\n\n/**\n * Helper function to safely call opt_callback with the specified arguments.  It:\n * 1. Turns into a no-op if opt_callback is null or undefined.\n * 2. Wraps the call inside exceptionGuard to prevent exceptions from breaking our state.\n *\n * @param {?Function=} callback Optional onComplete callback.\n * @param {...*} varArgs Arbitrary args to be passed to opt_onComplete\n */\nexport const callUserCallback = function (\n  callback?: Function | null,\n  ...varArgs: unknown[]\n) {\n  if (typeof callback === 'function') {\n    exceptionGuard(() => {\n      callback(...varArgs);\n    });\n  }\n};\n\n/**\n * @return {boolean} true if we think we're currently being crawled.\n */\nexport const beingCrawled = function (): boolean {\n  const userAgent =\n    (typeof window === 'object' &&\n      window['navigator'] &&\n      window['navigator']['userAgent']) ||\n    '';\n\n  // For now we whitelist the most popular crawlers.  We should refine this to be the set of crawlers we\n  // believe to support JavaScript/AJAX rendering.\n  // NOTE: Google Webmaster Tools doesn't really belong, but their \"This is how a visitor to your website\n  // would have seen the page\" is flaky if we don't treat it as a crawler.\n  return (\n    userAgent.search(\n      /googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i\n    ) >= 0\n  );\n};\n\n/**\n * Export a property of an object using a getter function.\n *\n * @param {!Object} object\n * @param {string} name\n * @param {!function(): *} fnGet\n */\nexport const exportPropGetter = function (\n  object: object,\n  name: string,\n  fnGet: () => unknown\n) {\n  Object.defineProperty(object, name, { get: fnGet });\n};\n\n/**\n * Same as setTimeout() except on Node.JS it will /not/ prevent the process from exiting.\n *\n * It is removed with clearTimeout() as normal.\n *\n * @param {Function} fn Function to run.\n * @param {number} time Milliseconds to wait before running.\n * @return {number|Object} The setTimeout() return value.\n */\nexport const setTimeoutNonBlocking = function (\n  fn: Function,\n  time: number\n): number | object {\n  const timeout: number | object = setTimeout(fn, time);\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  if (typeof timeout === 'object' && (timeout as any)['unref']) {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    (timeout as any)['unref']();\n  }\n  return timeout;\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 { nameCompare } from './util';\nimport { stringLength } from '@firebase/util';\n/**\n * An immutable object representing a parsed path.  It's immutable so that you\n * can pass them around to other functions without worrying about them changing\n * it.\n */\n\nexport class Path {\n  private pieces_: string[];\n  private pieceNum_: number;\n\n  /**\n   * Singleton to represent an empty path\n   *\n   * @const\n   */\n  static get Empty() {\n    return new Path('');\n  }\n\n  /**\n   * @param {string|Array.<string>} pathOrString Path string to parse,\n   *      or another path, or the raw tokens array\n   * @param {number=} pieceNum\n   */\n  constructor(pathOrString: string | string[], pieceNum?: number) {\n    if (pieceNum === void 0) {\n      this.pieces_ = (pathOrString as string).split('/');\n\n      // Remove empty pieces.\n      let copyTo = 0;\n      for (let i = 0; i < this.pieces_.length; i++) {\n        if (this.pieces_[i].length > 0) {\n          this.pieces_[copyTo] = this.pieces_[i];\n          copyTo++;\n        }\n      }\n      this.pieces_.length = copyTo;\n\n      this.pieceNum_ = 0;\n    } else {\n      this.pieces_ = pathOrString as string[];\n      this.pieceNum_ = pieceNum;\n    }\n  }\n\n  getFront(): string | null {\n    if (this.pieceNum_ >= this.pieces_.length) {\n      return null;\n    }\n\n    return this.pieces_[this.pieceNum_];\n  }\n\n  /**\n   * @return {number} The number of segments in this path\n   */\n  getLength(): number {\n    return this.pieces_.length - this.pieceNum_;\n  }\n\n  /**\n   * @return {!Path}\n   */\n  popFront(): Path {\n    let pieceNum = this.pieceNum_;\n    if (pieceNum < this.pieces_.length) {\n      pieceNum++;\n    }\n    return new Path(this.pieces_, pieceNum);\n  }\n\n  /**\n   * @return {?string}\n   */\n  getBack(): string | null {\n    if (this.pieceNum_ < this.pieces_.length) {\n      return this.pieces_[this.pieces_.length - 1];\n    }\n\n    return null;\n  }\n\n  toString(): string {\n    let pathString = '';\n    for (let i = this.pieceNum_; i < this.pieces_.length; i++) {\n      if (this.pieces_[i] !== '') {\n        pathString += '/' + this.pieces_[i];\n      }\n    }\n\n    return pathString || '/';\n  }\n\n  toUrlEncodedString(): string {\n    let pathString = '';\n    for (let i = this.pieceNum_; i < this.pieces_.length; i++) {\n      if (this.pieces_[i] !== '') {\n        pathString += '/' + encodeURIComponent(String(this.pieces_[i]));\n      }\n    }\n\n    return pathString || '/';\n  }\n\n  /**\n   * Shallow copy of the parts of the path.\n   *\n   * @param {number=} begin\n   * @return {!Array<string>}\n   */\n  slice(begin: number = 0): string[] {\n    return this.pieces_.slice(this.pieceNum_ + begin);\n  }\n\n  /**\n   * @return {?Path}\n   */\n  parent(): Path | null {\n    if (this.pieceNum_ >= this.pieces_.length) {\n      return null;\n    }\n\n    const pieces = [];\n    for (let i = this.pieceNum_; i < this.pieces_.length - 1; i++) {\n      pieces.push(this.pieces_[i]);\n    }\n\n    return new Path(pieces, 0);\n  }\n\n  /**\n   * @param {string|!Path} childPathObj\n   * @return {!Path}\n   */\n  child(childPathObj: string | Path): Path {\n    const pieces = [];\n    for (let i = this.pieceNum_; i < this.pieces_.length; i++) {\n      pieces.push(this.pieces_[i]);\n    }\n\n    if (childPathObj instanceof Path) {\n      for (\n        let i = childPathObj.pieceNum_;\n        i < childPathObj.pieces_.length;\n        i++\n      ) {\n        pieces.push(childPathObj.pieces_[i]);\n      }\n    } else {\n      const childPieces = childPathObj.split('/');\n      for (let i = 0; i < childPieces.length; i++) {\n        if (childPieces[i].length > 0) {\n          pieces.push(childPieces[i]);\n        }\n      }\n    }\n\n    return new Path(pieces, 0);\n  }\n\n  /**\n   * @return {boolean} True if there are no segments in this path\n   */\n  isEmpty(): boolean {\n    return this.pieceNum_ >= this.pieces_.length;\n  }\n\n  /**\n   * @param {!Path} outerPath\n   * @param {!Path} innerPath\n   * @return {!Path} The path from outerPath to innerPath\n   */\n  static relativePath(outerPath: Path, innerPath: Path): Path {\n    const outer = outerPath.getFront(),\n      inner = innerPath.getFront();\n    if (outer === null) {\n      return innerPath;\n    } else if (outer === inner) {\n      return Path.relativePath(outerPath.popFront(), innerPath.popFront());\n    } else {\n      throw new Error(\n        'INTERNAL ERROR: innerPath (' +\n          innerPath +\n          ') is not within ' +\n          'outerPath (' +\n          outerPath +\n          ')'\n      );\n    }\n  }\n\n  /**\n   * @param {!Path} left\n   * @param {!Path} right\n   * @return {number} -1, 0, 1 if left is less, equal, or greater than the right.\n   */\n  static comparePaths(left: Path, right: Path): number {\n    const leftKeys = left.slice();\n    const rightKeys = right.slice();\n    for (let i = 0; i < leftKeys.length && i < rightKeys.length; i++) {\n      const cmp = nameCompare(leftKeys[i], rightKeys[i]);\n      if (cmp !== 0) {\n        return cmp;\n      }\n    }\n    if (leftKeys.length === rightKeys.length) {\n      return 0;\n    }\n    return leftKeys.length < rightKeys.length ? -1 : 1;\n  }\n\n  /**\n   *\n   * @param {Path} other\n   * @return {boolean} true if paths are the same.\n   */\n  equals(other: Path): boolean {\n    if (this.getLength() !== other.getLength()) {\n      return false;\n    }\n\n    for (\n      let i = this.pieceNum_, j = other.pieceNum_;\n      i <= this.pieces_.length;\n      i++, j++\n    ) {\n      if (this.pieces_[i] !== other.pieces_[j]) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  /**\n   *\n   * @param {!Path} other\n   * @return {boolean} True if this path is a parent (or the same as) other\n   */\n  contains(other: Path): boolean {\n    let i = this.pieceNum_;\n    let j = other.pieceNum_;\n    if (this.getLength() > other.getLength()) {\n      return false;\n    }\n    while (i < this.pieces_.length) {\n      if (this.pieces_[i] !== other.pieces_[j]) {\n        return false;\n      }\n      ++i;\n      ++j;\n    }\n    return true;\n  }\n} // end Path\n\n/**\n * Dynamic (mutable) path used to count path lengths.\n *\n * This class is used to efficiently check paths for valid\n * length (in UTF8 bytes) and depth (used in path validation).\n *\n * Throws Error exception if path is ever invalid.\n *\n * The definition of a path always begins with '/'.\n */\nexport class ValidationPath {\n  /** @type {!Array<string>} */\n  private parts_: string[];\n  /** @type {number} Initialize to number of '/' chars needed in path. */\n  private byteLength_: number;\n\n  /**\n   * @param {!Path} path Initial Path.\n   * @param {string} errorPrefix_ Prefix for any error messages.\n   */\n  constructor(path: Path, private errorPrefix_: string) {\n    /** @type {!Array<string>} */\n    this.parts_ = path.slice();\n    /** @type {number} Initialize to number of '/' chars needed in path. */\n    this.byteLength_ = Math.max(1, this.parts_.length);\n\n    for (let i = 0; i < this.parts_.length; i++) {\n      this.byteLength_ += stringLength(this.parts_[i]);\n    }\n    this.checkValid_();\n  }\n\n  /** @const {number} Maximum key depth. */\n  static get MAX_PATH_DEPTH() {\n    return 32;\n  }\n\n  /** @const {number} Maximum number of (UTF8) bytes in a Firebase path. */\n  static get MAX_PATH_LENGTH_BYTES() {\n    return 768;\n  }\n\n  /** @param {string} child */\n  push(child: string) {\n    // Count the needed '/'\n    if (this.parts_.length > 0) {\n      this.byteLength_ += 1;\n    }\n    this.parts_.push(child);\n    this.byteLength_ += stringLength(child);\n    this.checkValid_();\n  }\n\n  pop() {\n    const last = this.parts_.pop();\n    this.byteLength_ -= stringLength(last);\n    // Un-count the previous '/'\n    if (this.parts_.length > 0) {\n      this.byteLength_ -= 1;\n    }\n  }\n\n  private checkValid_() {\n    if (this.byteLength_ > ValidationPath.MAX_PATH_LENGTH_BYTES) {\n      throw new Error(\n        this.errorPrefix_ +\n          'has a key path longer than ' +\n          ValidationPath.MAX_PATH_LENGTH_BYTES +\n          ' bytes (' +\n          this.byteLength_ +\n          ').'\n      );\n    }\n    if (this.parts_.length > ValidationPath.MAX_PATH_DEPTH) {\n      throw new Error(\n        this.errorPrefix_ +\n          'path specified exceeds the maximum depth that can be written (' +\n          ValidationPath.MAX_PATH_DEPTH +\n          ') or object contains a cycle ' +\n          this.toErrorString()\n      );\n    }\n  }\n\n  /**\n   * String for use in error messages - uses '.' notation for path.\n   *\n   * @return {string}\n   */\n  toErrorString(): string {\n    if (this.parts_.length === 0) {\n      return '';\n    }\n    return \"in property '\" + this.parts_.join('.') + \"'\";\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 const PROTOCOL_VERSION = '5';\n\nexport const VERSION_PARAM = 'v';\n\nexport const TRANSPORT_SESSION_PARAM = 's';\n\nexport const REFERER_PARAM = 'r';\n\nexport const FORGE_REF = 'f';\n\nexport const FORGE_DOMAIN = 'firebaseio.com';\n\nexport const LAST_SESSION_PARAM = 'ls';\n\nexport const APPLICATION_ID_PARAM = 'p';\n\nexport const WEBSOCKET = 'websocket';\n\nexport const LONG_POLLING = 'long_polling';\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 '@firebase/util';\nimport { PersistentStorage } from './storage/storage';\nimport { LONG_POLLING, WEBSOCKET } from '../realtime/Constants';\nimport { each } from './util/util';\n\n/**\n * A class that holds metadata about a Repo object\n *\n * @constructor\n */\nexport class RepoInfo {\n  host: string;\n  domain: string;\n  internalHost: string;\n\n  /**\n   * @param {string} host Hostname portion of the url for the repo\n   * @param {boolean} secure Whether or not this repo is accessed over ssl\n   * @param {string} namespace The namespace represented by the repo\n   * @param {boolean} webSocketOnly Whether to prefer websockets over all other transports (used by Nest).\n   * @param {string=} persistenceKey Override the default session persistence storage key\n   */\n  constructor(\n    host: string,\n    public secure: boolean,\n    public namespace: string,\n    public webSocketOnly: boolean,\n    public persistenceKey: string = '',\n    public includeNamespaceInQueryParams: boolean = false\n  ) {\n    this.host = host.toLowerCase();\n    this.domain = this.host.substr(this.host.indexOf('.') + 1);\n    this.internalHost =\n      (PersistentStorage.get('host:' + host) as string) || this.host;\n  }\n\n  needsQueryParam(): boolean {\n    return (\n      this.host !== this.internalHost ||\n      this.isCustomHost() ||\n      this.includeNamespaceInQueryParams\n    );\n  }\n\n  isCacheableHost(): boolean {\n    return this.internalHost.substr(0, 2) === 's-';\n  }\n\n  isDemoHost() {\n    return this.domain === 'firebaseio-demo.com';\n  }\n\n  isCustomHost() {\n    return (\n      this.domain !== 'firebaseio.com' && this.domain !== 'firebaseio-demo.com'\n    );\n  }\n\n  updateHost(newHost: string) {\n    if (newHost !== this.internalHost) {\n      this.internalHost = newHost;\n      if (this.isCacheableHost()) {\n        PersistentStorage.set('host:' + this.host, this.internalHost);\n      }\n    }\n  }\n\n  /**\n   * Returns the websocket URL for this repo\n   * @param {string} type of connection\n   * @param {Object} params list\n   * @return {string} The URL for this repo\n   */\n  connectionURL(type: string, params: { [k: string]: string }): string {\n    assert(typeof type === 'string', 'typeof type must == string');\n    assert(typeof params === 'object', 'typeof params must == object');\n\n    let connURL: string;\n    if (type === WEBSOCKET) {\n      connURL =\n        (this.secure ? 'wss://' : 'ws://') + this.internalHost + '/.ws?';\n    } else if (type === LONG_POLLING) {\n      connURL =\n        (this.secure ? 'https://' : 'http://') + this.internalHost + '/.lp?';\n    } else {\n      throw new Error('Unknown connection type: ' + type);\n    }\n    if (this.needsQueryParam()) {\n      params['ns'] = this.namespace;\n    }\n\n    const pairs: string[] = [];\n\n    each(params, (key: string, value: string) => {\n      pairs.push(key + '=' + value);\n    });\n\n    return connURL + pairs.join('&');\n  }\n\n  /** @return {string} */\n  toString(): string {\n    let str = this.toURLString();\n    if (this.persistenceKey) {\n      str += '<' + this.persistenceKey + '>';\n    }\n    return str;\n  }\n\n  /** @return {string} */\n  toURLString(): string {\n    return (this.secure ? 'https://' : 'http://') + this.host;\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 { Path } from '../Path';\nimport { RepoInfo } from '../../RepoInfo';\nimport { warnIfPageIsSecure, warn, fatal } from '../util';\n\n/**\n * @param {!string} pathString\n * @return {string}\n */\nfunction decodePath(pathString: string): string {\n  let pathStringDecoded = '';\n  const pieces = pathString.split('/');\n  for (let i = 0; i < pieces.length; i++) {\n    if (pieces[i].length > 0) {\n      let piece = pieces[i];\n      try {\n        piece = decodeURIComponent(piece.replace(/\\+/g, ' '));\n      } catch (e) {}\n      pathStringDecoded += '/' + piece;\n    }\n  }\n  return pathStringDecoded;\n}\n\n/**\n * @param {!string} queryString\n * @return {!{[key:string]:string}} key value hash\n */\nfunction decodeQuery(queryString: string): { [key: string]: string } {\n  const results = {};\n  if (queryString.charAt(0) === '?') {\n    queryString = queryString.substring(1);\n  }\n  for (const segment of queryString.split('&')) {\n    if (segment.length === 0) {\n      continue;\n    }\n    const kv = segment.split('=');\n    if (kv.length === 2) {\n      results[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]);\n    } else {\n      warn(`Invalid query segment '${segment}' in query '${queryString}'`);\n    }\n  }\n  return results;\n}\n\n/**\n *\n * @param {!string} dataURL\n * @return {{repoInfo: !RepoInfo, path: !Path}}\n */\nexport const parseRepoInfo = function (\n  dataURL: string\n): { repoInfo: RepoInfo; path: Path } {\n  const parsedUrl = parseDatabaseURL(dataURL),\n    namespace = parsedUrl.namespace;\n\n  if (parsedUrl.domain === 'firebase.com') {\n    fatal(\n      parsedUrl.host +\n        ' is no longer supported. ' +\n        'Please use <YOUR FIREBASE>.firebaseio.com instead'\n    );\n  }\n\n  // Catch common error of uninitialized namespace value.\n  if (\n    (!namespace || namespace === 'undefined') &&\n    parsedUrl.domain !== 'localhost'\n  ) {\n    fatal(\n      'Cannot parse Firebase url. Please use https://<YOUR FIREBASE>.firebaseio.com'\n    );\n  }\n\n  if (!parsedUrl.secure) {\n    warnIfPageIsSecure();\n  }\n\n  const webSocketOnly = parsedUrl.scheme === 'ws' || parsedUrl.scheme === 'wss';\n\n  return {\n    repoInfo: new RepoInfo(\n      parsedUrl.host,\n      parsedUrl.secure,\n      namespace,\n      webSocketOnly,\n      /*persistenceKey=*/ '',\n      /*includeNamespaceInQueryParams=*/ namespace !== parsedUrl.subdomain\n    ),\n    path: new Path(parsedUrl.pathString)\n  };\n};\n\n/**\n *\n * @param {!string} dataURL\n * @return {{host: string, port: number, domain: string, subdomain: string, secure: boolean, scheme: string, pathString: string, namespace: string}}\n */\nexport const parseDatabaseURL = function (\n  dataURL: string\n): {\n  host: string;\n  port: number;\n  domain: string;\n  subdomain: string;\n  secure: boolean;\n  scheme: string;\n  pathString: string;\n  namespace: string;\n} {\n  // Default to empty strings in the event of a malformed string.\n  let host = '',\n    domain = '',\n    subdomain = '',\n    pathString = '',\n    namespace = '';\n\n  // Always default to SSL, unless otherwise specified.\n  let secure = true,\n    scheme = 'https',\n    port = 443;\n\n  // Don't do any validation here. The caller is responsible for validating the result of parsing.\n  if (typeof dataURL === 'string') {\n    // Parse scheme.\n    let colonInd = dataURL.indexOf('//');\n    if (colonInd >= 0) {\n      scheme = dataURL.substring(0, colonInd - 1);\n      dataURL = dataURL.substring(colonInd + 2);\n    }\n\n    // Parse host, path, and query string.\n    let slashInd = dataURL.indexOf('/');\n    if (slashInd === -1) {\n      slashInd = dataURL.length;\n    }\n    let questionMarkInd = dataURL.indexOf('?');\n    if (questionMarkInd === -1) {\n      questionMarkInd = dataURL.length;\n    }\n    host = dataURL.substring(0, Math.min(slashInd, questionMarkInd));\n    if (slashInd < questionMarkInd) {\n      // For pathString, questionMarkInd will always come after slashInd\n      pathString = decodePath(dataURL.substring(slashInd, questionMarkInd));\n    }\n    const queryParams = decodeQuery(\n      dataURL.substring(Math.min(dataURL.length, questionMarkInd))\n    );\n\n    // If we have a port, use scheme for determining if it's secure.\n    colonInd = host.indexOf(':');\n    if (colonInd >= 0) {\n      secure = scheme === 'https' || scheme === 'wss';\n      port = parseInt(host.substring(colonInd + 1), 10);\n    } else {\n      colonInd = host.length;\n    }\n\n    const hostWithoutPort = host.slice(0, colonInd);\n    if (hostWithoutPort.toLowerCase() === 'localhost') {\n      domain = 'localhost';\n    } else if (hostWithoutPort.split('.').length <= 2) {\n      domain = hostWithoutPort;\n    } else {\n      // Interpret the subdomain of a 3 or more component URL as the namespace name.\n      const dotInd = host.indexOf('.');\n      subdomain = host.substring(0, dotInd).toLowerCase();\n      domain = host.substring(dotInd + 1);\n      // Normalize namespaces to lowercase to share storage / connection.\n      namespace = subdomain;\n    }\n    // Always treat the value of the `ns` as the namespace name if it is present.\n    if ('ns' in queryParams) {\n      namespace = queryParams['ns'];\n    }\n  }\n\n  return {\n    host,\n    port,\n    domain,\n    subdomain,\n    secure,\n    scheme,\n    pathString,\n    namespace\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 { Path, ValidationPath } from './Path';\nimport {\n  contains,\n  safeGet,\n  errorPrefix as errorPrefixFxn,\n  stringLength\n} from '@firebase/util';\nimport { isInvalidJSONNumber, each } from './util';\n\nimport { RepoInfo } from '../RepoInfo';\n\n/**\n * True for invalid Firebase keys\n * @type {RegExp}\n * @private\n */\nexport const INVALID_KEY_REGEX_ = /[\\[\\].#$\\/\\u0000-\\u001F\\u007F]/;\n\n/**\n * True for invalid Firebase paths.\n * Allows '/' in paths.\n * @type {RegExp}\n * @private\n */\nexport const INVALID_PATH_REGEX_ = /[\\[\\].#$\\u0000-\\u001F\\u007F]/;\n\n/**\n * Maximum number of characters to allow in leaf value\n * @type {number}\n * @private\n */\nexport const MAX_LEAF_SIZE_ = 10 * 1024 * 1024;\n\n/**\n * @param {*} key\n * @return {boolean}\n */\nexport const isValidKey = function (key: unknown): boolean {\n  return (\n    typeof key === 'string' && key.length !== 0 && !INVALID_KEY_REGEX_.test(key)\n  );\n};\n\n/**\n * @param {string} pathString\n * @return {boolean}\n */\nexport const isValidPathString = function (pathString: string): boolean {\n  return (\n    typeof pathString === 'string' &&\n    pathString.length !== 0 &&\n    !INVALID_PATH_REGEX_.test(pathString)\n  );\n};\n\n/**\n * @param {string} pathString\n * @return {boolean}\n */\nexport const isValidRootPathString = function (pathString: string): boolean {\n  if (pathString) {\n    // Allow '/.info/' at the beginning.\n    pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n  }\n\n  return isValidPathString(pathString);\n};\n\n/**\n * @param {*} priority\n * @return {boolean}\n */\nexport const isValidPriority = function (priority: unknown): boolean {\n  return (\n    priority === null ||\n    typeof priority === 'string' ||\n    (typeof priority === 'number' && !isInvalidJSONNumber(priority)) ||\n    (priority &&\n      typeof priority === 'object' &&\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      contains(priority as any, '.sv'))\n  );\n};\n\n/**\n * Pre-validate a datum passed as an argument to Firebase function.\n *\n * @param {string} fnName\n * @param {number} argumentNumber\n * @param {*} data\n * @param {!Path} path\n * @param {boolean} optional\n */\nexport const validateFirebaseDataArg = function (\n  fnName: string,\n  argumentNumber: number,\n  data: unknown,\n  path: Path,\n  optional: boolean\n) {\n  if (optional && data === undefined) {\n    return;\n  }\n\n  validateFirebaseData(\n    errorPrefixFxn(fnName, argumentNumber, optional),\n    data,\n    path\n  );\n};\n\n/**\n * Validate a data object client-side before sending to server.\n *\n * @param {string} errorPrefix\n * @param {*} data\n * @param {!Path|!ValidationPath} path_\n */\nexport const validateFirebaseData = function (\n  errorPrefix: string,\n  data: unknown,\n  path_: Path | ValidationPath\n) {\n  const path =\n    path_ instanceof Path ? new ValidationPath(path_, errorPrefix) : path_;\n\n  if (data === undefined) {\n    throw new Error(errorPrefix + 'contains undefined ' + path.toErrorString());\n  }\n  if (typeof data === 'function') {\n    throw new Error(\n      errorPrefix +\n        'contains a function ' +\n        path.toErrorString() +\n        ' with contents = ' +\n        data.toString()\n    );\n  }\n  if (isInvalidJSONNumber(data)) {\n    throw new Error(\n      errorPrefix + 'contains ' + data.toString() + ' ' + path.toErrorString()\n    );\n  }\n\n  // Check max leaf size, but try to avoid the utf8 conversion if we can.\n  if (\n    typeof data === 'string' &&\n    data.length > MAX_LEAF_SIZE_ / 3 &&\n    stringLength(data) > MAX_LEAF_SIZE_\n  ) {\n    throw new Error(\n      errorPrefix +\n        'contains a string greater than ' +\n        MAX_LEAF_SIZE_ +\n        ' utf8 bytes ' +\n        path.toErrorString() +\n        \" ('\" +\n        data.substring(0, 50) +\n        \"...')\"\n    );\n  }\n\n  // TODO = Perf = Consider combining the recursive validation of keys into NodeFromJSON\n  // to save extra walking of large objects.\n  if (data && typeof data === 'object') {\n    let hasDotValue = false;\n    let hasActualChild = false;\n    each(data, (key: string, value: unknown) => {\n      if (key === '.value') {\n        hasDotValue = true;\n      } else if (key !== '.priority' && key !== '.sv') {\n        hasActualChild = true;\n        if (!isValidKey(key)) {\n          throw new Error(\n            errorPrefix +\n              ' contains an invalid key (' +\n              key +\n              ') ' +\n              path.toErrorString() +\n              '.  Keys must be non-empty strings ' +\n              'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"'\n          );\n        }\n      }\n\n      path.push(key);\n      validateFirebaseData(errorPrefix, value, path);\n      path.pop();\n    });\n\n    if (hasDotValue && hasActualChild) {\n      throw new Error(\n        errorPrefix +\n          ' contains \".value\" child ' +\n          path.toErrorString() +\n          ' in addition to actual children.'\n      );\n    }\n  }\n};\n\n/**\n * Pre-validate paths passed in the firebase function.\n *\n * @param {string} errorPrefix\n * @param {Array<!Path>} mergePaths\n */\nexport const validateFirebaseMergePaths = function (\n  errorPrefix: string,\n  mergePaths: Path[]\n) {\n  let i, curPath;\n  for (i = 0; i < mergePaths.length; i++) {\n    curPath = mergePaths[i];\n    const keys = curPath.slice();\n    for (let j = 0; j < keys.length; j++) {\n      if (keys[j] === '.priority' && j === keys.length - 1) {\n        // .priority is OK\n      } else if (!isValidKey(keys[j])) {\n        throw new Error(\n          errorPrefix +\n            'contains an invalid key (' +\n            keys[j] +\n            ') in path ' +\n            curPath.toString() +\n            '. Keys must be non-empty strings ' +\n            'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"'\n        );\n      }\n    }\n  }\n\n  // Check that update keys are not descendants of each other.\n  // We rely on the property that sorting guarantees that ancestors come\n  // right before descendants.\n  mergePaths.sort(Path.comparePaths);\n  let prevPath: Path | null = null;\n  for (i = 0; i < mergePaths.length; i++) {\n    curPath = mergePaths[i];\n    if (prevPath !== null && prevPath.contains(curPath)) {\n      throw new Error(\n        errorPrefix +\n          'contains a path ' +\n          prevPath.toString() +\n          ' that is ancestor of another path ' +\n          curPath.toString()\n      );\n    }\n    prevPath = curPath;\n  }\n};\n\n/**\n * pre-validate an object passed as an argument to firebase function (\n * must be an object - e.g. for firebase.update()).\n *\n * @param {string} fnName\n * @param {number} argumentNumber\n * @param {*} data\n * @param {!Path} path\n * @param {boolean} optional\n */\nexport const validateFirebaseMergeDataArg = function (\n  fnName: string,\n  argumentNumber: number,\n  data: unknown,\n  path: Path,\n  optional: boolean\n) {\n  if (optional && data === undefined) {\n    return;\n  }\n\n  const errorPrefix = errorPrefixFxn(fnName, argumentNumber, optional);\n\n  if (!(data && typeof data === 'object') || Array.isArray(data)) {\n    throw new Error(\n      errorPrefix + ' must be an object containing the children to replace.'\n    );\n  }\n\n  const mergePaths: Path[] = [];\n  each(data, (key: string, value: unknown) => {\n    const curPath = new Path(key);\n    validateFirebaseData(errorPrefix, value, path.child(curPath));\n    if (curPath.getBack() === '.priority') {\n      if (!isValidPriority(value)) {\n        throw new Error(\n          errorPrefix +\n            \"contains an invalid value for '\" +\n            curPath.toString() +\n            \"', which must be a valid \" +\n            'Firebase priority (a string, finite number, server value, or null).'\n        );\n      }\n    }\n    mergePaths.push(curPath);\n  });\n  validateFirebaseMergePaths(errorPrefix, mergePaths);\n};\n\nexport const validatePriority = function (\n  fnName: string,\n  argumentNumber: number,\n  priority: unknown,\n  optional: boolean\n) {\n  if (optional && priority === undefined) {\n    return;\n  }\n  if (isInvalidJSONNumber(priority)) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'is ' +\n        priority.toString() +\n        ', but must be a valid Firebase priority (a string, finite number, ' +\n        'server value, or null).'\n    );\n  }\n  // Special case to allow importing data with a .sv.\n  if (!isValidPriority(priority)) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'must be a valid Firebase priority ' +\n        '(a string, finite number, server value, or null).'\n    );\n  }\n};\n\nexport const validateEventType = function (\n  fnName: string,\n  argumentNumber: number,\n  eventType: string,\n  optional: boolean\n) {\n  if (optional && eventType === undefined) {\n    return;\n  }\n\n  switch (eventType) {\n    case 'value':\n    case 'child_added':\n    case 'child_removed':\n    case 'child_changed':\n    case 'child_moved':\n      break;\n    default:\n      throw new Error(\n        errorPrefixFxn(fnName, argumentNumber, optional) +\n          'must be a valid event type = \"value\", \"child_added\", \"child_removed\", ' +\n          '\"child_changed\", or \"child_moved\".'\n      );\n  }\n};\n\nexport const validateKey = function (\n  fnName: string,\n  argumentNumber: number,\n  key: string,\n  optional: boolean\n) {\n  if (optional && key === undefined) {\n    return;\n  }\n  if (!isValidKey(key)) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'was an invalid key = \"' +\n        key +\n        '\".  Firebase keys must be non-empty strings and ' +\n        'can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\").'\n    );\n  }\n};\n\nexport const validatePathString = function (\n  fnName: string,\n  argumentNumber: number,\n  pathString: string,\n  optional: boolean\n) {\n  if (optional && pathString === undefined) {\n    return;\n  }\n\n  if (!isValidPathString(pathString)) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'was an invalid path = \"' +\n        pathString +\n        '\". Paths must be non-empty strings and ' +\n        'can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\"'\n    );\n  }\n};\n\nexport const validateRootPathString = function (\n  fnName: string,\n  argumentNumber: number,\n  pathString: string,\n  optional: boolean\n) {\n  if (pathString) {\n    // Allow '/.info/' at the beginning.\n    pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n  }\n\n  validatePathString(fnName, argumentNumber, pathString, optional);\n};\n\nexport const validateWritablePath = function (fnName: string, path: Path) {\n  if (path.getFront() === '.info') {\n    throw new Error(fnName + \" failed = Can't modify data under /.info/\");\n  }\n};\n\nexport const validateUrl = function (\n  fnName: string,\n  argumentNumber: number,\n  parsedUrl: { repoInfo: RepoInfo; path: Path }\n) {\n  // TODO = Validate server better.\n  const pathString = parsedUrl.path.toString();\n  if (\n    !(typeof parsedUrl.repoInfo.host === 'string') ||\n    parsedUrl.repoInfo.host.length === 0 ||\n    (!isValidKey(parsedUrl.repoInfo.namespace) &&\n      parsedUrl.repoInfo.host.split(':')[0] !== 'localhost') ||\n    (pathString.length !== 0 && !isValidRootPathString(pathString))\n  ) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, false) +\n        'must be a valid firebase URL and ' +\n        'the path can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\".'\n    );\n  }\n};\n\nexport const validateCredential = function (\n  fnName: string,\n  argumentNumber: number,\n  cred: unknown,\n  optional: boolean\n) {\n  if (optional && cred === undefined) {\n    return;\n  }\n  if (!(typeof cred === 'string')) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'must be a valid credential (a string).'\n    );\n  }\n};\n\nexport const validateBoolean = function (\n  fnName: string,\n  argumentNumber: number,\n  bool: unknown,\n  optional: boolean\n) {\n  if (optional && bool === undefined) {\n    return;\n  }\n  if (typeof bool !== 'boolean') {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) + 'must be a boolean.'\n    );\n  }\n};\n\nexport const validateString = function (\n  fnName: string,\n  argumentNumber: number,\n  string: unknown,\n  optional: boolean\n) {\n  if (optional && string === undefined) {\n    return;\n  }\n  if (!(typeof string === 'string')) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'must be a valid string.'\n    );\n  }\n};\n\nexport const validateObject = function (\n  fnName: string,\n  argumentNumber: number,\n  obj: unknown,\n  optional: boolean\n) {\n  if (optional && obj === undefined) {\n    return;\n  }\n  if (!(obj && typeof obj === 'object') || obj === null) {\n    throw new Error(\n      errorPrefixFxn(fnName, argumentNumber, optional) +\n        'must be a valid object.'\n    );\n  }\n};\n\nexport const validateObjectContainsKey = function (\n  fnName: string,\n  argumentNumber: number,\n  obj: unknown,\n  key: string,\n  optional: boolean,\n  optType?: string\n) {\n  const objectContainsKey =\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    obj && typeof obj === 'object' && contains(obj as any, key);\n\n  if (!objectContainsKey) {\n    if (optional) {\n      return;\n    } else {\n      throw new Error(\n        errorPrefixFxn(fnName, argumentNumber, optional) +\n          'must contain the key \"' +\n          key +\n          '\"'\n      );\n    }\n  }\n\n  if (optType) {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const val = safeGet(obj as any, key);\n    if (\n      (optType === 'number' && !(typeof val === 'number')) ||\n      (optType === 'string' && !(typeof val === 'string')) ||\n      (optType === 'boolean' && !(typeof val === 'boolean')) ||\n      (optType === 'function' && !(typeof val === 'function')) ||\n      (optType === 'object' && !(typeof val === 'object') && val)\n    ) {\n      if (optional) {\n        throw new Error(\n          errorPrefixFxn(fnName, argumentNumber, optional) +\n            'contains invalid value for key \"' +\n            key +\n            '\" (must be of type \"' +\n            optType +\n            '\")'\n        );\n      } else {\n        throw new Error(\n          errorPrefixFxn(fnName, argumentNumber, optional) +\n            'must contain the key \"' +\n            key +\n            '\" with type \"' +\n            optType +\n            '\"'\n        );\n      }\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 { validateArgCount, validateCallback, Deferred } from '@firebase/util';\nimport {\n  validateWritablePath,\n  validateFirebaseDataArg,\n  validatePriority,\n  validateFirebaseMergeDataArg\n} from '../core/util/validation';\nimport { warn } from '../core/util/util';\n\nimport { Repo } from '../core/Repo';\nimport { Path } from '../core/util/Path';\nimport { Indexable } from '../core/util/misc';\n\n/**\n * @constructor\n */\nexport class OnDisconnect {\n  /**\n   * @param {!Repo} repo_\n   * @param {!Path} path_\n   */\n  constructor(private repo_: Repo, private path_: Path) {}\n\n  /**\n   * @param {function(?Error)=} onComplete\n   * @return {!firebase.Promise}\n   */\n  cancel(onComplete?: (a: Error | null) => void): Promise<void> {\n    validateArgCount('OnDisconnect.cancel', 0, 1, arguments.length);\n    validateCallback('OnDisconnect.cancel', 1, onComplete, true);\n    const deferred = new Deferred<void>();\n    this.repo_.onDisconnectCancel(\n      this.path_,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {function(?Error)=} onComplete\n   * @return {!firebase.Promise}\n   */\n  remove(onComplete?: (a: Error | null) => void): Promise<void> {\n    validateArgCount('OnDisconnect.remove', 0, 1, arguments.length);\n    validateWritablePath('OnDisconnect.remove', this.path_);\n    validateCallback('OnDisconnect.remove', 1, onComplete, true);\n    const deferred = new Deferred<void>();\n    this.repo_.onDisconnectSet(\n      this.path_,\n      null,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {*} value\n   * @param {function(?Error)=} onComplete\n   * @return {!firebase.Promise}\n   */\n  set(value: unknown, onComplete?: (a: Error | null) => void): Promise<void> {\n    validateArgCount('OnDisconnect.set', 1, 2, arguments.length);\n    validateWritablePath('OnDisconnect.set', this.path_);\n    validateFirebaseDataArg('OnDisconnect.set', 1, value, this.path_, false);\n    validateCallback('OnDisconnect.set', 2, onComplete, true);\n    const deferred = new Deferred<void>();\n    this.repo_.onDisconnectSet(\n      this.path_,\n      value,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {*} value\n   * @param {number|string|null} priority\n   * @param {function(?Error)=} onComplete\n   * @return {!firebase.Promise}\n   */\n  setWithPriority(\n    value: unknown,\n    priority: number | string | null,\n    onComplete?: (a: Error | null) => void\n  ): Promise<void> {\n    validateArgCount('OnDisconnect.setWithPriority', 2, 3, arguments.length);\n    validateWritablePath('OnDisconnect.setWithPriority', this.path_);\n    validateFirebaseDataArg(\n      'OnDisconnect.setWithPriority',\n      1,\n      value,\n      this.path_,\n      false\n    );\n    validatePriority('OnDisconnect.setWithPriority', 2, priority, false);\n    validateCallback('OnDisconnect.setWithPriority', 3, onComplete, true);\n\n    const deferred = new Deferred<void>();\n    this.repo_.onDisconnectSetWithPriority(\n      this.path_,\n      value,\n      priority,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {!Object} objectToMerge\n   * @param {function(?Error)=} onComplete\n   * @return {!firebase.Promise}\n   */\n  update(\n    objectToMerge: Indexable,\n    onComplete?: (a: Error | null) => void\n  ): Promise<void> {\n    validateArgCount('OnDisconnect.update', 1, 2, arguments.length);\n    validateWritablePath('OnDisconnect.update', this.path_);\n    if (Array.isArray(objectToMerge)) {\n      const newObjectToMerge: { [k: string]: unknown } = {};\n      for (let i = 0; i < objectToMerge.length; ++i) {\n        newObjectToMerge['' + i] = objectToMerge[i];\n      }\n      objectToMerge = newObjectToMerge;\n      warn(\n        'Passing an Array to firebase.database.onDisconnect().update() is deprecated. Use set() if you want to overwrite the ' +\n          'existing data, or an Object with integer keys if you really do want to only update some of the children.'\n      );\n    }\n    validateFirebaseMergeDataArg(\n      'OnDisconnect.update',\n      1,\n      objectToMerge,\n      this.path_,\n      false\n    );\n    validateCallback('OnDisconnect.update', 2, onComplete, true);\n    const deferred = new Deferred<void>();\n    this.repo_.onDisconnectUpdate(\n      this.path_,\n      objectToMerge,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\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 { DataSnapshot } from './DataSnapshot';\nimport { validateArgCount } from '@firebase/util';\n\nexport class TransactionResult {\n  /**\n   * A type for the resolve value of Firebase.transaction.\n   * @constructor\n   * @dict\n   * @param {boolean} committed\n   * @param {DataSnapshot} snapshot\n   */\n  constructor(public committed: boolean, public snapshot: DataSnapshot) {}\n\n  // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n  // for end-users\n  toJSON(): object {\n    validateArgCount('TransactionResult.toJSON', 0, 1, arguments.length);\n    return { committed: this.committed, snapshot: this.snapshot.toJSON() };\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 '@firebase/util';\n\n/**\n * Fancy ID generator that creates 20-character string identifiers with the\n * following properties:\n *\n * 1. They're based on timestamp so that they sort *after* any existing ids.\n * 2. They contain 72-bits of random data after the timestamp so that IDs won't\n *    collide with other clients' IDs.\n * 3. They sort *lexicographically* (so the timestamp is converted to characters\n *    that will sort properly).\n * 4. They're monotonically increasing. Even if you generate more than one in\n *    the same timestamp, the latter ones will sort after the former ones. We do\n *    this by using the previous random bits but \"incrementing\" them by 1 (only\n *    in the case of a timestamp collision).\n */\nexport const nextPushId = (function () {\n  // Modeled after base64 web-safe chars, but ordered by ASCII.\n  const PUSH_CHARS =\n    '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';\n\n  // Timestamp of last push, used to prevent local collisions if you push twice\n  // in one ms.\n  let lastPushTime = 0;\n\n  // We generate 72-bits of randomness which get turned into 12 characters and\n  // appended to the timestamp to prevent collisions with other clients. We\n  // store the last characters we generated because in the event of a collision,\n  // we'll use those same characters except \"incremented\" by one.\n  const lastRandChars: number[] = [];\n\n  return function (now: number) {\n    const duplicateTime = now === lastPushTime;\n    lastPushTime = now;\n\n    let i;\n    const timeStampChars = new Array(8);\n    for (i = 7; i >= 0; i--) {\n      timeStampChars[i] = PUSH_CHARS.charAt(now % 64);\n      // NOTE: Can't use << here because javascript will convert to int and lose\n      // the upper bits.\n      now = Math.floor(now / 64);\n    }\n    assert(now === 0, 'Cannot push at time == 0');\n\n    let id = timeStampChars.join('');\n\n    if (!duplicateTime) {\n      for (i = 0; i < 12; i++) {\n        lastRandChars[i] = Math.floor(Math.random() * 64);\n      }\n    } else {\n      // If the timestamp hasn't changed since last push, use the same random\n      // number, except incremented by 1.\n      for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {\n        lastRandChars[i] = 0;\n      }\n      lastRandChars[i]++;\n    }\n    for (i = 0; i < 12; i++) {\n      id += PUSH_CHARS.charAt(lastRandChars[i]);\n    }\n    assert(id.length === 20, 'nextPushId: Length should be 20.');\n\n    return id;\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 { Path } from '../util/Path';\nimport { Index } from './indexes/Index';\n\n/**\n * Node is an interface defining the common functionality for nodes in\n * a DataSnapshot.\n *\n * @interface\n */\nexport interface Node {\n  /**\n   * Whether this node is a leaf node.\n   * @return {boolean} Whether this is a leaf node.\n   */\n  isLeafNode(): boolean;\n\n  /**\n   * Gets the priority of the node.\n   * @return {!Node} The priority of the node.\n   */\n  getPriority(): Node;\n\n  /**\n   * Returns a duplicate node with the new priority.\n   * @param {!Node} newPriorityNode New priority to set for the node.\n   * @return {!Node} Node with new priority.\n   */\n  updatePriority(newPriorityNode: Node): Node;\n\n  /**\n   * Returns the specified immediate child, or null if it doesn't exist.\n   * @param {string} childName The name of the child to retrieve.\n   * @return {!Node} The retrieved child, or an empty node.\n   */\n  getImmediateChild(childName: string): Node;\n\n  /**\n   * Returns a child by path, or null if it doesn't exist.\n   * @param {!Path} path The path of the child to retrieve.\n   * @return {!Node} The retrieved child or an empty node.\n   */\n  getChild(path: Path): Node;\n\n  /**\n   * Returns the name of the child immediately prior to the specified childNode, or null.\n   * @param {!string} childName The name of the child to find the predecessor of.\n   * @param {!Node} childNode The node to find the predecessor of.\n   * @param {!Index} index The index to use to determine the predecessor\n   * @return {?string} The name of the predecessor child, or null if childNode is the first child.\n   */\n  getPredecessorChildName(\n    childName: string,\n    childNode: Node,\n    index: Index\n  ): string | null;\n\n  /**\n   * Returns a duplicate node, with the specified immediate child updated.\n   * Any value in the node will be removed.\n   * @param {string} childName The name of the child to update.\n   * @param {!Node} newChildNode The new child node\n   * @return {!Node} The updated node.\n   */\n  updateImmediateChild(childName: string, newChildNode: Node): Node;\n\n  /**\n   * Returns a duplicate node, with the specified child updated.  Any value will\n   * be removed.\n   * @param {!Path} path The path of the child to update.\n   * @param {!Node} newChildNode The new child node, which may be an empty node\n   * @return {!Node} The updated node.\n   */\n  updateChild(path: Path, newChildNode: Node): Node;\n\n  /**\n   * True if the immediate child specified exists\n   * @param {!string} childName\n   * @return {boolean}\n   */\n  hasChild(childName: string): boolean;\n\n  /**\n   * @return {boolean} True if this node has no value or children.\n   */\n  isEmpty(): boolean;\n\n  /**\n   * @return {number} The number of children of this node.\n   */\n  numChildren(): number;\n\n  /**\n   * Calls action for each child.\n   * @param {!Index} index\n   * @param {function(string, !Node)} action Action to be called for\n   * each child.  It's passed the child name and the child node.\n   * @return {*} The first truthy value return by action, or the last falsey one\n   */\n  forEachChild(index: Index, action: (a: string, b: Node) => void): unknown;\n\n  /**\n   * @param exportFormat True for export format (also wire protocol format).\n   * @return Value of this node as JSON.\n   */\n  val(exportFormat?: boolean): unknown;\n\n  /**\n   * @return {string} hash representing the node contents.\n   */\n  hash(): string;\n\n  /**\n   * @param {!Node} other Another node\n   * @return {!number} -1 for less than, 0 for equal, 1 for greater than other\n   */\n  compareTo(other: Node): number;\n\n  /**\n   * @param {!Node} other\n   * @return {boolean} Whether or not this snapshot equals other\n   */\n  equals(other: Node): boolean;\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {!Node} This node, with the specified index now available\n   */\n  withIndex(indexDefinition: Index): Node;\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {boolean}\n   */\n  isIndexed(indexDefinition: Index): boolean;\n}\n\n/**\n *\n * @param {!string} name\n * @param {!Node} node\n * @constructor\n * @struct\n */\nexport class NamedNode {\n  constructor(public name: string, public node: Node) {}\n\n  /**\n   *\n   * @param {!string} name\n   * @param {!Node} node\n   * @return {NamedNode}\n   */\n  static Wrap(name: string, node: Node) {\n    return new NamedNode(name, node);\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 { Node, NamedNode } from '../Node';\nimport { MIN_NAME, MAX_NAME } from '../../util/util';\nimport { Comparator } from '../../util/SortedMap';\n\n/**\n *\n * @constructor\n */\nexport abstract class Index {\n  /**\n   * @param {!NamedNode} a\n   * @param {!NamedNode} b\n   * @return {number}\n   */\n  abstract compare(a: NamedNode, b: NamedNode): number;\n\n  /**\n   * @param {!Node} node\n   * @return {boolean}\n   */\n  abstract isDefinedOn(node: Node): boolean;\n\n  /**\n   * @return {function(!NamedNode, !NamedNode):number} A standalone comparison function for\n   * this index\n   */\n  getCompare(): Comparator<NamedNode> {\n    return this.compare.bind(this);\n  }\n\n  /**\n   * Given a before and after value for a node, determine if the indexed value has changed. Even if they are different,\n   * it's possible that the changes are isolated to parts of the snapshot that are not indexed.\n   *\n   * @param {!Node} oldNode\n   * @param {!Node} newNode\n   * @return {boolean} True if the portion of the snapshot being indexed changed between oldNode and newNode\n   */\n  indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n    const oldWrapped = new NamedNode(MIN_NAME, oldNode);\n    const newWrapped = new NamedNode(MIN_NAME, newNode);\n    return this.compare(oldWrapped, newWrapped) !== 0;\n  }\n\n  /**\n   * @return {!NamedNode} a node wrapper that will sort equal to or less than\n   * any other node wrapper, using this index\n   */\n  minPost(): NamedNode {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return (NamedNode as any).MIN;\n  }\n\n  /**\n   * @return {!NamedNode} a node wrapper that will sort greater than or equal to\n   * any other node wrapper, using this index\n   */\n  abstract maxPost(): NamedNode;\n\n  /**\n   * @param {*} indexValue\n   * @param {string} name\n   * @return {!NamedNode}\n   */\n  abstract makePost(indexValue: unknown, name: string): NamedNode;\n\n  /**\n   * @return {!string} String representation for inclusion in a query spec\n   */\n  abstract toString(): string;\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 { Index } from './Index';\nimport { Node, NamedNode } from '../Node';\nimport { nameCompare, MAX_NAME } from '../../util/util';\nimport { assert, assertionError } from '@firebase/util';\nimport { ChildrenNode } from '../ChildrenNode';\n\nlet __EMPTY_NODE: ChildrenNode;\n\nexport class KeyIndex extends Index {\n  static get __EMPTY_NODE() {\n    return __EMPTY_NODE;\n  }\n\n  static set __EMPTY_NODE(val) {\n    __EMPTY_NODE = val;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  compare(a: NamedNode, b: NamedNode): number {\n    return nameCompare(a.name, b.name);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isDefinedOn(node: Node): boolean {\n    // We could probably return true here (since every node has a key), but it's never called\n    // so just leaving unimplemented for now.\n    throw assertionError('KeyIndex.isDefinedOn not expected to be called.');\n  }\n\n  /**\n   * @inheritDoc\n   */\n  indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n    return false; // The key for a node never changes.\n  }\n\n  /**\n   * @inheritDoc\n   */\n  minPost() {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return (NamedNode as any).MIN;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  maxPost(): NamedNode {\n    // TODO: This should really be created once and cached in a static property, but\n    // NamedNode isn't defined yet, so I can't use it in a static.  Bleh.\n    return new NamedNode(MAX_NAME, __EMPTY_NODE);\n  }\n\n  /**\n   * @param {*} indexValue\n   * @param {string} name\n   * @return {!NamedNode}\n   */\n  makePost(indexValue: string, name: string): NamedNode {\n    assert(\n      typeof indexValue === 'string',\n      'KeyIndex indexValue must always be a string.'\n    );\n    // We just use empty node, but it'll never be compared, since our comparator only looks at name.\n    return new NamedNode(indexValue, __EMPTY_NODE);\n  }\n\n  /**\n   * @return {!string} String representation for inclusion in a query spec\n   */\n  toString(): string {\n    return '.key';\n  }\n}\n\nexport const KEY_INDEX = new KeyIndex();\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, contains } from '@firebase/util';\nimport { doubleToIEEE754String } from '../util/util';\n\nimport { Node } from './Node';\nimport { Indexable } from '../util/misc';\n\nlet MAX_NODE: Node;\n\nexport function setMaxNode(val: Node) {\n  MAX_NODE = val;\n}\n\n/**\n * @param {(!string|!number)} priority\n * @return {!string}\n */\nexport const priorityHashText = function (priority: string | number): string {\n  if (typeof priority === 'number') {\n    return 'number:' + doubleToIEEE754String(priority);\n  } else {\n    return 'string:' + priority;\n  }\n};\n\n/**\n * Validates that a priority snapshot Node is valid.\n *\n * @param {!Node} priorityNode\n */\nexport const validatePriorityNode = function (priorityNode: Node) {\n  if (priorityNode.isLeafNode()) {\n    const val = priorityNode.val();\n    assert(\n      typeof val === 'string' ||\n        typeof val === 'number' ||\n        (typeof val === 'object' && contains(val as Indexable, '.sv')),\n      'Priority must be a string or number.'\n    );\n  } else {\n    assert(\n      priorityNode === MAX_NODE || priorityNode.isEmpty(),\n      'priority of unexpected type.'\n    );\n  }\n  // Don't call getPriority() on MAX_NODE to avoid hitting assertion.\n  assert(\n    priorityNode === MAX_NODE || priorityNode.getPriority().isEmpty(),\n    \"Priority nodes can't have a priority of their own.\"\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 '@firebase/util';\nimport { doubleToIEEE754String, sha1 } from '../util/util';\nimport { priorityHashText, validatePriorityNode } from './snap';\nimport { Node } from './Node';\nimport { Path } from '../util/Path';\nimport { Index } from './indexes/Index';\nimport { ChildrenNodeConstructor } from './ChildrenNode';\nimport { Indexable } from '../util/misc';\n\nlet __childrenNodeConstructor: ChildrenNodeConstructor;\n\n/**\n * LeafNode is a class for storing leaf nodes in a DataSnapshot.  It\n * implements Node and stores the value of the node (a string,\n * number, or boolean) accessible via getValue().\n */\nexport class LeafNode implements Node {\n  static set __childrenNodeConstructor(val: ChildrenNodeConstructor) {\n    __childrenNodeConstructor = val;\n  }\n\n  static get __childrenNodeConstructor() {\n    return __childrenNodeConstructor;\n  }\n\n  /**\n   * The sort order for comparing leaf nodes of different types. If two leaf nodes have\n   * the same type, the comparison falls back to their value\n   * @type {Array.<!string>}\n   * @const\n   */\n  static VALUE_TYPE_ORDER = ['object', 'boolean', 'number', 'string'];\n\n  private lazyHash_: string | null = null;\n\n  /**\n   * @implements {Node}\n   * @param {!(string|number|boolean|Object)} value_ The value to store in this leaf node.\n   *                                         The object type is possible in the event of a deferred value\n   * @param {!Node=} priorityNode_ The priority of this node.\n   */\n  constructor(\n    private readonly value_: string | number | boolean | Indexable,\n    private priorityNode_: Node = LeafNode.__childrenNodeConstructor.EMPTY_NODE\n  ) {\n    assert(\n      this.value_ !== undefined && this.value_ !== null,\n      \"LeafNode shouldn't be created with null/undefined value.\"\n    );\n\n    validatePriorityNode(this.priorityNode_);\n  }\n\n  /** @inheritDoc */\n  isLeafNode(): boolean {\n    return true;\n  }\n\n  /** @inheritDoc */\n  getPriority(): Node {\n    return this.priorityNode_;\n  }\n\n  /** @inheritDoc */\n  updatePriority(newPriorityNode: Node): Node {\n    return new LeafNode(this.value_, newPriorityNode);\n  }\n\n  /** @inheritDoc */\n  getImmediateChild(childName: string): Node {\n    // Hack to treat priority as a regular child\n    if (childName === '.priority') {\n      return this.priorityNode_;\n    } else {\n      return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\n    }\n  }\n\n  /** @inheritDoc */\n  getChild(path: Path): Node {\n    if (path.isEmpty()) {\n      return this;\n    } else if (path.getFront() === '.priority') {\n      return this.priorityNode_;\n    } else {\n      return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasChild(): boolean {\n    return false;\n  }\n\n  /** @inheritDoc */\n  getPredecessorChildName(childName: string, childNode: Node): null {\n    return null;\n  }\n\n  /** @inheritDoc */\n  updateImmediateChild(childName: string, newChildNode: Node): Node {\n    if (childName === '.priority') {\n      return this.updatePriority(newChildNode);\n    } else if (newChildNode.isEmpty() && childName !== '.priority') {\n      return this;\n    } else {\n      return LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateImmediateChild(\n        childName,\n        newChildNode\n      ).updatePriority(this.priorityNode_);\n    }\n  }\n\n  /** @inheritDoc */\n  updateChild(path: Path, newChildNode: Node): Node {\n    const front = path.getFront();\n    if (front === null) {\n      return newChildNode;\n    } else if (newChildNode.isEmpty() && front !== '.priority') {\n      return this;\n    } else {\n      assert(\n        front !== '.priority' || path.getLength() === 1,\n        '.priority must be the last token in a path'\n      );\n\n      return this.updateImmediateChild(\n        front,\n        LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(\n          path.popFront(),\n          newChildNode\n        )\n      );\n    }\n  }\n\n  /** @inheritDoc */\n  isEmpty(): boolean {\n    return false;\n  }\n\n  /** @inheritDoc */\n  numChildren(): number {\n    return 0;\n  }\n\n  /** @inheritDoc */\n  forEachChild(index: Index, action: (s: string, n: Node) => void): boolean {\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  val(exportFormat?: boolean): {} {\n    if (exportFormat && !this.getPriority().isEmpty()) {\n      return {\n        '.value': this.getValue(),\n        '.priority': this.getPriority().val()\n      };\n    } else {\n      return this.getValue();\n    }\n  }\n\n  /** @inheritDoc */\n  hash(): string {\n    if (this.lazyHash_ === null) {\n      let toHash = '';\n      if (!this.priorityNode_.isEmpty()) {\n        toHash +=\n          'priority:' +\n          priorityHashText(this.priorityNode_.val() as number | string) +\n          ':';\n      }\n\n      const type = typeof this.value_;\n      toHash += type + ':';\n      if (type === 'number') {\n        toHash += doubleToIEEE754String(this.value_ as number);\n      } else {\n        toHash += this.value_;\n      }\n      this.lazyHash_ = sha1(toHash);\n    }\n    return this.lazyHash_;\n  }\n\n  /**\n   * Returns the value of the leaf node.\n   * @return {Object|string|number|boolean} The value of the node.\n   */\n  getValue(): Indexable | string | number | boolean {\n    return this.value_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  compareTo(other: Node): number {\n    if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) {\n      return 1;\n    } else if (other instanceof LeafNode.__childrenNodeConstructor) {\n      return -1;\n    } else {\n      assert(other.isLeafNode(), 'Unknown node type');\n      return this.compareToLeafNode_(other as LeafNode);\n    }\n  }\n\n  /**\n   * Comparison specifically for two leaf nodes\n   * @param {!LeafNode} otherLeaf\n   * @return {!number}\n   * @private\n   */\n  private compareToLeafNode_(otherLeaf: LeafNode): number {\n    const otherLeafType = typeof otherLeaf.value_;\n    const thisLeafType = typeof this.value_;\n    const otherIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(otherLeafType);\n    const thisIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(thisLeafType);\n    assert(otherIndex >= 0, 'Unknown leaf type: ' + otherLeafType);\n    assert(thisIndex >= 0, 'Unknown leaf type: ' + thisLeafType);\n    if (otherIndex === thisIndex) {\n      // Same type, compare values\n      if (thisLeafType === 'object') {\n        // Deferred value nodes are all equal, but we should also never get to this point...\n        return 0;\n      } else {\n        // Note that this works because true > false, all others are number or string comparisons\n        if (this.value_ < otherLeaf.value_) {\n          return -1;\n        } else if (this.value_ === otherLeaf.value_) {\n          return 0;\n        } else {\n          return 1;\n        }\n      }\n    } else {\n      return thisIndex - otherIndex;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  withIndex(): Node {\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isIndexed(): boolean {\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  equals(other: Node): boolean {\n    /**\n     * @inheritDoc\n     */\n    if (other === this) {\n      return true;\n    } else if (other.isLeafNode()) {\n      const otherLeaf = other as LeafNode;\n      return (\n        this.value_ === otherLeaf.value_ &&\n        this.priorityNode_.equals(otherLeaf.priorityNode_)\n      );\n    } else {\n      return false;\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 { Index } from './Index';\nimport { nameCompare, MAX_NAME } from '../../util/util';\nimport { NamedNode, Node } from '../Node';\nimport { LeafNode } from '../LeafNode';\n\nlet nodeFromJSON: (a: unknown) => Node;\nlet MAX_NODE: Node;\n\nexport function setNodeFromJSON(val: (a: unknown) => Node) {\n  nodeFromJSON = val;\n}\n\nexport function setMaxNode(val: Node) {\n  MAX_NODE = val;\n}\n\n/**\n * @constructor\n * @extends {Index}\n * @private\n */\nexport class PriorityIndex extends Index {\n  /**\n   * @inheritDoc\n   */\n  compare(a: NamedNode, b: NamedNode): number {\n    const aPriority = a.node.getPriority();\n    const bPriority = b.node.getPriority();\n    const indexCmp = aPriority.compareTo(bPriority);\n    if (indexCmp === 0) {\n      return nameCompare(a.name, b.name);\n    } else {\n      return indexCmp;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isDefinedOn(node: Node): boolean {\n    return !node.getPriority().isEmpty();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n    return !oldNode.getPriority().equals(newNode.getPriority());\n  }\n\n  /**\n   * @inheritDoc\n   */\n  minPost(): NamedNode {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return (NamedNode as any).MIN;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  maxPost(): NamedNode {\n    return new NamedNode(MAX_NAME, new LeafNode('[PRIORITY-POST]', MAX_NODE));\n  }\n\n  /**\n   * @param {*} indexValue\n   * @param {string} name\n   * @return {!NamedNode}\n   */\n  makePost(indexValue: unknown, name: string): NamedNode {\n    const priorityNode = nodeFromJSON(indexValue);\n    return new NamedNode(name, new LeafNode('[PRIORITY-POST]', priorityNode));\n  }\n\n  /**\n   * @return {!string} String representation for inclusion in a query spec\n   */\n  toString(): string {\n    return '.priority';\n  }\n}\n\nexport const PRIORITY_INDEX = new PriorityIndex();\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 Implementation of an immutable SortedMap using a Left-leaning\n * Red-Black Tree, adapted from the implementation in Mugs\n * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen\n * (mads379@gmail.com).\n *\n * Original paper on Left-leaning Red-Black Trees:\n *   http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf\n *\n * Invariant 1: No red node has a red child\n * Invariant 2: Every leaf path has the same number of black nodes\n * Invariant 3: Only the left child can be red (left leaning)\n */\n\n// TODO: There are some improvements I'd like to make to improve memory / perf:\n//  * Create two prototypes, LLRedNode and LLBlackNode, instead of storing a\n//    color property in every node.\n// TODO: It would also be good (and possibly necessary) to create a base\n// interface for LLRBNode and LLRBEmptyNode.\n\nexport type Comparator<K> = (key1: K, key2: K) => number;\n\n/**\n * An iterator over an LLRBNode.\n */\nexport class SortedMapIterator<K, V, T> {\n  /** @private\n   * @type {Array.<!LLRBNode>}\n   */\n  private nodeStack_: Array<LLRBNode<K, V> | LLRBEmptyNode<K, V>> = [];\n\n  /**\n   * @template K, V, T\n   * @param {LLRBNode|LLRBEmptyNode} node Node to iterate.\n   * @param {?K} startKey\n   * @param {function(K, K): number} comparator\n   * @param {boolean} isReverse_ Whether or not to iterate in reverse\n   * @param {(function(K, V):T)=} resultGenerator_\n   */\n  constructor(\n    node: LLRBNode<K, V> | LLRBEmptyNode<K, V>,\n    startKey: K | null,\n    comparator: Comparator<K>,\n    private isReverse_: boolean,\n    private resultGenerator_: ((k: K, v: V) => T) | null = null\n  ) {\n    let cmp = 1;\n    while (!node.isEmpty()) {\n      node = node as LLRBNode<K, V>;\n      cmp = startKey ? comparator(node.key, startKey) : 1;\n      // flip the comparison if we're going in reverse\n      if (isReverse_) {\n        cmp *= -1;\n      }\n\n      if (cmp < 0) {\n        // This node is less than our start key. ignore it\n        if (this.isReverse_) {\n          node = node.left;\n        } else {\n          node = node.right;\n        }\n      } else if (cmp === 0) {\n        // This node is exactly equal to our start key. Push it on the stack, but stop iterating;\n        this.nodeStack_.push(node);\n        break;\n      } else {\n        // This node is greater than our start key, add it to the stack and move to the next one\n        this.nodeStack_.push(node);\n        if (this.isReverse_) {\n          node = node.right;\n        } else {\n          node = node.left;\n        }\n      }\n    }\n  }\n\n  getNext(): T {\n    if (this.nodeStack_.length === 0) {\n      return null;\n    }\n\n    let node = this.nodeStack_.pop();\n    let result: T;\n    if (this.resultGenerator_) {\n      result = this.resultGenerator_(node.key, node.value);\n    } else {\n      result = ({ key: node.key, value: node.value } as unknown) as T;\n    }\n\n    if (this.isReverse_) {\n      node = node.left;\n      while (!node.isEmpty()) {\n        this.nodeStack_.push(node);\n        node = node.right;\n      }\n    } else {\n      node = node.right;\n      while (!node.isEmpty()) {\n        this.nodeStack_.push(node);\n        node = node.left;\n      }\n    }\n\n    return result;\n  }\n\n  hasNext(): boolean {\n    return this.nodeStack_.length > 0;\n  }\n\n  peek(): T {\n    if (this.nodeStack_.length === 0) {\n      return null;\n    }\n\n    const node = this.nodeStack_[this.nodeStack_.length - 1];\n    if (this.resultGenerator_) {\n      return this.resultGenerator_(node.key, node.value);\n    } else {\n      return ({ key: node.key, value: node.value } as unknown) as T;\n    }\n  }\n}\n\n/**\n * Represents a node in a Left-leaning Red-Black tree.\n */\nexport class LLRBNode<K, V> {\n  color: boolean;\n  left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n  right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n\n  /**\n   * @template K, V\n   * @param {!K} key Key associated with this node.\n   * @param {!V} value Value associated with this node.\n   * @param {?boolean} color Whether this node is red.\n   * @param {?(LLRBNode|LLRBEmptyNode)=} left Left child.\n   * @param {?(LLRBNode|LLRBEmptyNode)=} right Right child.\n   */\n  constructor(\n    public key: K,\n    public value: V,\n    color: boolean | null,\n    left?: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n    right?: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n  ) {\n    this.color = color != null ? color : LLRBNode.RED;\n    this.left =\n      left != null ? left : (SortedMap.EMPTY_NODE as LLRBEmptyNode<K, V>);\n    this.right =\n      right != null ? right : (SortedMap.EMPTY_NODE as LLRBEmptyNode<K, V>);\n  }\n\n  static RED = true;\n  static BLACK = false;\n\n  /**\n   * Returns a copy of the current node, optionally replacing pieces of it.\n   *\n   * @param {?K} key New key for the node, or null.\n   * @param {?V} value New value for the node, or null.\n   * @param {?boolean} color New color for the node, or null.\n   * @param {?LLRBNode|LLRBEmptyNode} left New left child for the node, or null.\n   * @param {?LLRBNode|LLRBEmptyNode} right New right child for the node, or null.\n   * @return {!LLRBNode} The node copy.\n   */\n  copy(\n    key: K | null,\n    value: V | null,\n    color: boolean | null,\n    left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n    right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n  ): LLRBNode<K, V> {\n    return new LLRBNode(\n      key != null ? key : this.key,\n      value != null ? value : this.value,\n      color != null ? color : this.color,\n      left != null ? left : this.left,\n      right != null ? right : this.right\n    );\n  }\n\n  /**\n   * @return {number} The total number of nodes in the tree.\n   */\n  count(): number {\n    return this.left.count() + 1 + this.right.count();\n  }\n\n  /**\n   * @return {boolean} True if the tree is empty.\n   */\n  isEmpty(): boolean {\n    return false;\n  }\n\n  /**\n   * Traverses the tree in key order and calls the specified action function\n   * for each node.\n   *\n   * @param {function(!K, !V):*} action Callback function to be called for each\n   *   node.  If it returns true, traversal is aborted.\n   * @return {*} The first truthy value returned by action, or the last falsey\n   *   value returned by action\n   */\n  inorderTraversal(action: (k: K, v: V) => unknown): boolean {\n    return (\n      this.left.inorderTraversal(action) ||\n      !!action(this.key, this.value) ||\n      this.right.inorderTraversal(action)\n    );\n  }\n\n  /**\n   * Traverses the tree in reverse key order and calls the specified action function\n   * for each node.\n   *\n   * @param {function(!Object, !Object)} action Callback function to be called for each\n   * node.  If it returns true, traversal is aborted.\n   * @return {*} True if traversal was aborted.\n   */\n  reverseTraversal(action: (k: K, v: V) => void): boolean {\n    return (\n      this.right.reverseTraversal(action) ||\n      action(this.key, this.value) ||\n      this.left.reverseTraversal(action)\n    );\n  }\n\n  /**\n   * @return {!Object} The minimum node in the tree.\n   * @private\n   */\n  private min_(): LLRBNode<K, V> {\n    if (this.left.isEmpty()) {\n      return this;\n    } else {\n      return (this.left as LLRBNode<K, V>).min_();\n    }\n  }\n\n  /**\n   * @return {!K} The maximum key in the tree.\n   */\n  minKey(): K {\n    return this.min_().key;\n  }\n\n  /**\n   * @return {!K} The maximum key in the tree.\n   */\n  maxKey(): K {\n    if (this.right.isEmpty()) {\n      return this.key;\n    } else {\n      return this.right.maxKey();\n    }\n  }\n\n  /**\n   *\n   * @param {!Object} key Key to insert.\n   * @param {!Object} value Value to insert.\n   * @param {Comparator} comparator Comparator.\n   * @return {!LLRBNode} New tree, with the key/value added.\n   */\n  insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n    let n: LLRBNode<K, V> = this;\n    const cmp = comparator(key, n.key);\n    if (cmp < 0) {\n      n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);\n    } else if (cmp === 0) {\n      n = n.copy(null, value, null, null, null);\n    } else {\n      n = n.copy(\n        null,\n        null,\n        null,\n        null,\n        n.right.insert(key, value, comparator)\n      );\n    }\n    return n.fixUp_();\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode|LLRBEmptyNode} New tree, with the minimum key removed.\n   */\n  private removeMin_(): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n    if (this.left.isEmpty()) {\n      return SortedMap.EMPTY_NODE as LLRBEmptyNode<K, V>;\n    }\n    let n: LLRBNode<K, V> = this;\n    if (!n.left.isRed_() && !n.left.left.isRed_()) {\n      n = n.moveRedLeft_();\n    }\n    n = n.copy(null, null, null, (n.left as LLRBNode<K, V>).removeMin_(), null);\n    return n.fixUp_();\n  }\n\n  /**\n   * @param {!Object} key The key of the item to remove.\n   * @param {Comparator} comparator Comparator.\n   * @return {!LLRBNode|LLRBEmptyNode} New tree, with the specified item removed.\n   */\n  remove(\n    key: K,\n    comparator: Comparator<K>\n  ): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n    let n, smallest;\n    n = this;\n    if (comparator(key, n.key) < 0) {\n      if (!n.left.isEmpty() && !n.left.isRed_() && !n.left.left.isRed_()) {\n        n = n.moveRedLeft_();\n      }\n      n = n.copy(null, null, null, n.left.remove(key, comparator), null);\n    } else {\n      if (n.left.isRed_()) {\n        n = n.rotateRight_();\n      }\n      if (!n.right.isEmpty() && !n.right.isRed_() && !n.right.left.isRed_()) {\n        n = n.moveRedRight_();\n      }\n      if (comparator(key, n.key) === 0) {\n        if (n.right.isEmpty()) {\n          return SortedMap.EMPTY_NODE as LLRBEmptyNode<K, V>;\n        } else {\n          smallest = (n.right as LLRBNode<K, V>).min_();\n          n = n.copy(\n            smallest.key,\n            smallest.value,\n            null,\n            null,\n            (n.right as LLRBNode<K, V>).removeMin_()\n          );\n        }\n      }\n      n = n.copy(null, null, null, null, n.right.remove(key, comparator));\n    }\n    return n.fixUp_();\n  }\n\n  /**\n   * @private\n   * @return {boolean} Whether this is a RED node.\n   */\n  isRed_(): boolean {\n    return this.color;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree after performing any needed rotations.\n   */\n  private fixUp_(): LLRBNode<K, V> {\n    let n: LLRBNode<K, V> = this;\n    if (n.right.isRed_() && !n.left.isRed_()) {\n      n = n.rotateLeft_();\n    }\n    if (n.left.isRed_() && n.left.left.isRed_()) {\n      n = n.rotateRight_();\n    }\n    if (n.left.isRed_() && n.right.isRed_()) {\n      n = n.colorFlip_();\n    }\n    return n;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree, after moveRedLeft.\n   */\n  private moveRedLeft_(): LLRBNode<K, V> {\n    let n = this.colorFlip_();\n    if (n.right.left.isRed_()) {\n      n = n.copy(\n        null,\n        null,\n        null,\n        null,\n        (n.right as LLRBNode<K, V>).rotateRight_()\n      );\n      n = n.rotateLeft_();\n      n = n.colorFlip_();\n    }\n    return n;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree, after moveRedRight.\n   */\n  private moveRedRight_(): LLRBNode<K, V> {\n    let n = this.colorFlip_();\n    if (n.left.left.isRed_()) {\n      n = n.rotateRight_();\n      n = n.colorFlip_();\n    }\n    return n;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree, after rotateLeft.\n   */\n  private rotateLeft_(): LLRBNode<K, V> {\n    const nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\n    return this.right.copy(null, null, this.color, nl, null) as LLRBNode<K, V>;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree, after rotateRight.\n   */\n  private rotateRight_(): LLRBNode<K, V> {\n    const nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\n    return this.left.copy(null, null, this.color, null, nr) as LLRBNode<K, V>;\n  }\n\n  /**\n   * @private\n   * @return {!LLRBNode} New tree, after colorFlip.\n   */\n  private colorFlip_(): LLRBNode<K, V> {\n    const left = this.left.copy(null, null, !this.left.color, null, null);\n    const right = this.right.copy(null, null, !this.right.color, null, null);\n    return this.copy(null, null, !this.color, left, right);\n  }\n\n  /**\n   * For testing.\n   *\n   * @private\n   * @return {boolean} True if all is well.\n   */\n  private checkMaxDepth_(): boolean {\n    const blackDepth = this.check_();\n    return Math.pow(2.0, blackDepth) <= this.count() + 1;\n  }\n\n  /**\n   * @private\n   * @return {number} Not sure what this returns exactly. :-).\n   */\n  check_(): number {\n    if (this.isRed_() && this.left.isRed_()) {\n      throw new Error(\n        'Red node has red child(' + this.key + ',' + this.value + ')'\n      );\n    }\n    if (this.right.isRed_()) {\n      throw new Error(\n        'Right child of (' + this.key + ',' + this.value + ') is red'\n      );\n    }\n    const blackDepth = this.left.check_();\n    if (blackDepth !== this.right.check_()) {\n      throw new Error('Black depths differ');\n    } else {\n      return blackDepth + (this.isRed_() ? 0 : 1);\n    }\n  }\n}\n\n/**\n * Represents an empty node (a leaf node in the Red-Black Tree).\n */\nexport class LLRBEmptyNode<K, V> {\n  key: K;\n  value: V;\n  left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n  right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n  color: boolean;\n\n  /**\n   * Returns a copy of the current node.\n   *\n   * @return {!LLRBEmptyNode} The node copy.\n   */\n  copy(\n    key: K | null,\n    value: V | null,\n    color: boolean | null,\n    left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n    right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n  ): LLRBEmptyNode<K, V> {\n    return this;\n  }\n\n  /**\n   * Returns a copy of the tree, with the specified key/value added.\n   *\n   * @param {!K} key Key to be added.\n   * @param {!V} value Value to be added.\n   * @param {Comparator} comparator Comparator.\n   * @return {!LLRBNode} New tree, with item added.\n   */\n  insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n    return new LLRBNode(key, value, null);\n  }\n\n  /**\n   * Returns a copy of the tree, with the specified key removed.\n   *\n   * @param {!K} key The key to remove.\n   * @param {Comparator} comparator Comparator.\n   * @return {!LLRBEmptyNode} New tree, with item removed.\n   */\n  remove(key: K, comparator: Comparator<K>): LLRBEmptyNode<K, V> {\n    return this;\n  }\n\n  /**\n   * @return {number} The total number of nodes in the tree.\n   */\n  count(): number {\n    return 0;\n  }\n\n  /**\n   * @return {boolean} True if the tree is empty.\n   */\n  isEmpty(): boolean {\n    return true;\n  }\n\n  /**\n   * Traverses the tree in key order and calls the specified action function\n   * for each node.\n   *\n   * @param {function(!K, !V):*} action Callback function to be called for each\n   * node.  If it returns true, traversal is aborted.\n   * @return {boolean} True if traversal was aborted.\n   */\n  inorderTraversal(action: (k: K, v: V) => unknown): boolean {\n    return false;\n  }\n\n  /**\n   * Traverses the tree in reverse key order and calls the specified action function\n   * for each node.\n   *\n   * @param {function(!K, !V)} action Callback function to be called for each\n   * node.  If it returns true, traversal is aborted.\n   * @return {boolean} True if traversal was aborted.\n   */\n  reverseTraversal(action: (k: K, v: V) => void): boolean {\n    return false;\n  }\n\n  /**\n   * @return {null}\n   */\n  minKey(): null {\n    return null;\n  }\n\n  /**\n   * @return {null}\n   */\n  maxKey(): null {\n    return null;\n  }\n\n  /**\n   * @private\n   * @return {number} Not sure what this returns exactly. :-).\n   */\n  check_(): number {\n    return 0;\n  }\n\n  /**\n   * @private\n   * @return {boolean} Whether this node is red.\n   */\n  isRed_() {\n    return false;\n  }\n}\n\n/**\n * An immutable sorted map implementation, based on a Left-leaning Red-Black\n * tree.\n */\nexport class SortedMap<K, V> {\n  /**\n   * Always use the same empty node, to reduce memory.\n   * @const\n   */\n  static EMPTY_NODE = new LLRBEmptyNode();\n\n  /**\n   * @template K, V\n   * @param {function(K, K):number} comparator_ Key comparator.\n   * @param {LLRBNode=} root_ (Optional) Root node for the map.\n   */\n  constructor(\n    private comparator_: Comparator<K>,\n    private root_:\n      | LLRBNode<K, V>\n      | LLRBEmptyNode<K, V> = SortedMap.EMPTY_NODE as LLRBEmptyNode<K, V>\n  ) {}\n\n  /**\n   * Returns a copy of the map, with the specified key/value added or replaced.\n   * (TODO: We should perhaps rename this method to 'put')\n   *\n   * @param {!K} key Key to be added.\n   * @param {!V} value Value to be added.\n   * @return {!SortedMap.<K, V>} New map, with item added.\n   */\n  insert(key: K, value: V): SortedMap<K, V> {\n    return new SortedMap(\n      this.comparator_,\n      this.root_\n        .insert(key, value, this.comparator_)\n        .copy(null, null, LLRBNode.BLACK, null, null)\n    );\n  }\n\n  /**\n   * Returns a copy of the map, with the specified key removed.\n   *\n   * @param {!K} key The key to remove.\n   * @return {!SortedMap.<K, V>} New map, with item removed.\n   */\n  remove(key: K): SortedMap<K, V> {\n    return new SortedMap(\n      this.comparator_,\n      this.root_\n        .remove(key, this.comparator_)\n        .copy(null, null, LLRBNode.BLACK, null, null)\n    );\n  }\n\n  /**\n   * Returns the value of the node with the given key, or null.\n   *\n   * @param {!K} key The key to look up.\n   * @return {?V} The value of the node with the given key, or null if the\n   * key doesn't exist.\n   */\n  get(key: K): V | null {\n    let cmp;\n    let node = this.root_;\n    while (!node.isEmpty()) {\n      cmp = this.comparator_(key, node.key);\n      if (cmp === 0) {\n        return node.value;\n      } else if (cmp < 0) {\n        node = node.left;\n      } else if (cmp > 0) {\n        node = node.right;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Returns the key of the item *before* the specified key, or null if key is the first item.\n   * @param {K} key The key to find the predecessor of\n   * @return {?K} The predecessor key.\n   */\n  getPredecessorKey(key: K): K | null {\n    let cmp,\n      node = this.root_,\n      rightParent = null;\n    while (!node.isEmpty()) {\n      cmp = this.comparator_(key, node.key);\n      if (cmp === 0) {\n        if (!node.left.isEmpty()) {\n          node = node.left;\n          while (!node.right.isEmpty()) {\n            node = node.right;\n          }\n          return node.key;\n        } else if (rightParent) {\n          return rightParent.key;\n        } else {\n          return null; // first item.\n        }\n      } else if (cmp < 0) {\n        node = node.left;\n      } else if (cmp > 0) {\n        rightParent = node;\n        node = node.right;\n      }\n    }\n\n    throw new Error(\n      'Attempted to find predecessor key for a nonexistent key.  What gives?'\n    );\n  }\n\n  /**\n   * @return {boolean} True if the map is empty.\n   */\n  isEmpty(): boolean {\n    return this.root_.isEmpty();\n  }\n\n  /**\n   * @return {number} The total number of nodes in the map.\n   */\n  count(): number {\n    return this.root_.count();\n  }\n\n  /**\n   * @return {?K} The minimum key in the map.\n   */\n  minKey(): K | null {\n    return this.root_.minKey();\n  }\n\n  /**\n   * @return {?K} The maximum key in the map.\n   */\n  maxKey(): K | null {\n    return this.root_.maxKey();\n  }\n\n  /**\n   * Traverses the map in key order and calls the specified action function\n   * for each key/value pair.\n   *\n   * @param {function(!K, !V):*} action Callback function to be called\n   * for each key/value pair.  If action returns true, traversal is aborted.\n   * @return {*} The first truthy value returned by action, or the last falsey\n   *   value returned by action\n   */\n  inorderTraversal(action: (k: K, v: V) => unknown): boolean {\n    return this.root_.inorderTraversal(action);\n  }\n\n  /**\n   * Traverses the map in reverse key order and calls the specified action function\n   * for each key/value pair.\n   *\n   * @param {function(!Object, !Object)} action Callback function to be called\n   * for each key/value pair.  If action returns true, traversal is aborted.\n   * @return {*} True if the traversal was aborted.\n   */\n  reverseTraversal(action: (k: K, v: V) => void): boolean {\n    return this.root_.reverseTraversal(action);\n  }\n\n  /**\n   * Returns an iterator over the SortedMap.\n   * @template T\n   * @param {(function(K, V):T)=} resultGenerator\n   * @return {SortedMapIterator.<K, V, T>} The iterator.\n   */\n  getIterator<T>(\n    resultGenerator?: (k: K, v: V) => T\n  ): SortedMapIterator<K, V, T> {\n    return new SortedMapIterator(\n      this.root_,\n      null,\n      this.comparator_,\n      false,\n      resultGenerator\n    );\n  }\n\n  getIteratorFrom<T>(\n    key: K,\n    resultGenerator?: (k: K, v: V) => T\n  ): SortedMapIterator<K, V, T> {\n    return new SortedMapIterator(\n      this.root_,\n      key,\n      this.comparator_,\n      false,\n      resultGenerator\n    );\n  }\n\n  getReverseIteratorFrom<T>(\n    key: K,\n    resultGenerator?: (k: K, v: V) => T\n  ): SortedMapIterator<K, V, T> {\n    return new SortedMapIterator(\n      this.root_,\n      key,\n      this.comparator_,\n      true,\n      resultGenerator\n    );\n  }\n\n  getReverseIterator<T>(\n    resultGenerator?: (k: K, v: V) => T\n  ): SortedMapIterator<K, V, T> {\n    return new SortedMapIterator(\n      this.root_,\n      null,\n      this.comparator_,\n      true,\n      resultGenerator\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 { LLRBNode, SortedMap } from '../util/SortedMap';\n\nimport { NamedNode } from './Node';\n\nconst LOG_2 = Math.log(2);\n\n/**\n * @constructor\n */\nclass Base12Num {\n  count: number;\n  private current_: number;\n  private bits_: number;\n\n  /**\n   * @param {number} length\n   */\n  constructor(length: number) {\n    const logBase2 = (num: number) =>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      parseInt((Math.log(num) / LOG_2) as any, 10);\n    const bitMask = (bits: number) => parseInt(Array(bits + 1).join('1'), 2);\n    this.count = logBase2(length + 1);\n    this.current_ = this.count - 1;\n    const mask = bitMask(this.count);\n    this.bits_ = (length + 1) & mask;\n  }\n\n  /**\n   * @return {boolean}\n   */\n  nextBitIsOne(): boolean {\n    //noinspection JSBitwiseOperatorUsage\n    const result = !(this.bits_ & (0x1 << this.current_));\n    this.current_--;\n    return result;\n  }\n}\n\n/**\n * Takes a list of child nodes and constructs a SortedSet using the given comparison\n * function\n *\n * Uses the algorithm described in the paper linked here:\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458\n *\n * @template K, V\n * @param {Array.<!NamedNode>} childList Unsorted list of children\n * @param {function(!NamedNode, !NamedNode):number} cmp The comparison method to be used\n * @param {(function(NamedNode):K)=} keyFn An optional function to extract K from a node wrapper, if K's\n *                                                        type is not NamedNode\n * @param {(function(K, K):number)=} mapSortFn An optional override for comparator used by the generated sorted map\n * @return {SortedMap.<K, V>}\n */\nexport const buildChildSet = function <K, V>(\n  childList: NamedNode[],\n  cmp: (a: NamedNode, b: NamedNode) => number,\n  keyFn?: (a: NamedNode) => K,\n  mapSortFn?: (a: K, b: K) => number\n): SortedMap<K, V> {\n  childList.sort(cmp);\n\n  const buildBalancedTree = function (\n    low: number,\n    high: number\n  ): LLRBNode<K, V> | null {\n    const length = high - low;\n    let namedNode: NamedNode;\n    let key: K;\n    if (length === 0) {\n      return null;\n    } else if (length === 1) {\n      namedNode = childList[low];\n      key = keyFn ? keyFn(namedNode) : ((namedNode as unknown) as K);\n      return new LLRBNode(\n        key,\n        (namedNode.node as unknown) as V,\n        LLRBNode.BLACK,\n        null,\n        null\n      );\n    } else {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const middle = parseInt((length / 2) as any, 10) + low;\n      const left = buildBalancedTree(low, middle);\n      const right = buildBalancedTree(middle + 1, high);\n      namedNode = childList[middle];\n      key = keyFn ? keyFn(namedNode) : ((namedNode as unknown) as K);\n      return new LLRBNode(\n        key,\n        (namedNode.node as unknown) as V,\n        LLRBNode.BLACK,\n        left,\n        right\n      );\n    }\n  };\n\n  const buildFrom12Array = function (base12: Base12Num): LLRBNode<K, V> {\n    let node: LLRBNode<K, V> = null;\n    let root = null;\n    let index = childList.length;\n\n    const buildPennant = function (chunkSize: number, color: boolean) {\n      const low = index - chunkSize;\n      const high = index;\n      index -= chunkSize;\n      const childTree = buildBalancedTree(low + 1, high);\n      const namedNode = childList[low];\n      const key: K = keyFn ? keyFn(namedNode) : ((namedNode as unknown) as K);\n      attachPennant(\n        new LLRBNode(\n          key,\n          (namedNode.node as unknown) as V,\n          color,\n          null,\n          childTree\n        )\n      );\n    };\n\n    const attachPennant = function (pennant: LLRBNode<K, V>) {\n      if (node) {\n        node.left = pennant;\n        node = pennant;\n      } else {\n        root = pennant;\n        node = pennant;\n      }\n    };\n\n    for (let i = 0; i < base12.count; ++i) {\n      const isOne = base12.nextBitIsOne();\n      // The number of nodes taken in each slice is 2^(arr.length - (i + 1))\n      const chunkSize = Math.pow(2, base12.count - (i + 1));\n      if (isOne) {\n        buildPennant(chunkSize, LLRBNode.BLACK);\n      } else {\n        // current == 2\n        buildPennant(chunkSize, LLRBNode.BLACK);\n        buildPennant(chunkSize, LLRBNode.RED);\n      }\n    }\n    return root;\n  };\n\n  const base12 = new Base12Num(childList.length);\n  const root = buildFrom12Array(base12);\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  return new SortedMap<K, V>(mapSortFn || (cmp as any), root);\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, contains, map, safeGet } from '@firebase/util';\nimport { buildChildSet } from './childSet';\n\nimport { NamedNode, Node } from './Node';\nimport { PRIORITY_INDEX } from './indexes/PriorityIndex';\nimport { KEY_INDEX } from './indexes/KeyIndex';\nimport { SortedMap } from '../util/SortedMap';\nimport { Index } from './indexes/Index';\n\nlet _defaultIndexMap: IndexMap;\n\nconst fallbackObject = {};\n\nexport class IndexMap {\n  /**\n   * The default IndexMap for nodes without a priority\n   */\n  static get Default(): IndexMap {\n    assert(\n      fallbackObject && PRIORITY_INDEX,\n      'ChildrenNode.ts has not been loaded'\n    );\n    _defaultIndexMap =\n      _defaultIndexMap ||\n      new IndexMap(\n        { '.priority': fallbackObject },\n        { '.priority': PRIORITY_INDEX }\n      );\n    return _defaultIndexMap;\n  }\n\n  constructor(\n    private indexes_: {\n      [k: string]: SortedMap<NamedNode, Node> | /*FallbackType*/ object;\n    },\n    private indexSet_: { [k: string]: Index }\n  ) {}\n\n  get(indexKey: string): SortedMap<NamedNode, Node> | null {\n    const sortedMap = safeGet(this.indexes_, indexKey);\n    if (!sortedMap) {\n      throw new Error('No index defined for ' + indexKey);\n    }\n\n    if (sortedMap instanceof SortedMap) {\n      return sortedMap;\n    } else {\n      // The index exists, but it falls back to just name comparison. Return null so that the calling code uses the\n      // regular child map\n      return null;\n    }\n  }\n\n  hasIndex(indexDefinition: Index): boolean {\n    return contains(this.indexSet_, indexDefinition.toString());\n  }\n\n  addIndex(\n    indexDefinition: Index,\n    existingChildren: SortedMap<string, Node>\n  ): IndexMap {\n    assert(\n      indexDefinition !== KEY_INDEX,\n      \"KeyIndex always exists and isn't meant to be added to the IndexMap.\"\n    );\n    const childList = [];\n    let sawIndexedValue = false;\n    const iter = existingChildren.getIterator(NamedNode.Wrap);\n    let next = iter.getNext();\n    while (next) {\n      sawIndexedValue =\n        sawIndexedValue || indexDefinition.isDefinedOn(next.node);\n      childList.push(next);\n      next = iter.getNext();\n    }\n    let newIndex;\n    if (sawIndexedValue) {\n      newIndex = buildChildSet(childList, indexDefinition.getCompare());\n    } else {\n      newIndex = fallbackObject;\n    }\n    const indexName = indexDefinition.toString();\n    const newIndexSet = { ...this.indexSet_ };\n    newIndexSet[indexName] = indexDefinition;\n    const newIndexes = { ...this.indexes_ };\n    newIndexes[indexName] = newIndex;\n    return new IndexMap(newIndexes, newIndexSet);\n  }\n\n  /**\n   * Ensure that this node is properly tracked in any indexes that we're maintaining\n   */\n  addToIndexes(\n    namedNode: NamedNode,\n    existingChildren: SortedMap<string, Node>\n  ): IndexMap {\n    const newIndexes = map(\n      this.indexes_,\n      (indexedChildren: SortedMap<NamedNode, Node>, indexName: string) => {\n        const index = safeGet(this.indexSet_, indexName);\n        assert(index, 'Missing index implementation for ' + indexName);\n        if (indexedChildren === fallbackObject) {\n          // Check to see if we need to index everything\n          if (index.isDefinedOn(namedNode.node)) {\n            // We need to build this index\n            const childList = [];\n            const iter = existingChildren.getIterator(NamedNode.Wrap);\n            let next = iter.getNext();\n            while (next) {\n              if (next.name !== namedNode.name) {\n                childList.push(next);\n              }\n              next = iter.getNext();\n            }\n            childList.push(namedNode);\n            return buildChildSet(childList, index.getCompare());\n          } else {\n            // No change, this remains a fallback\n            return fallbackObject;\n          }\n        } else {\n          const existingSnap = existingChildren.get(namedNode.name);\n          let newChildren = indexedChildren;\n          if (existingSnap) {\n            newChildren = newChildren.remove(\n              new NamedNode(namedNode.name, existingSnap)\n            );\n          }\n          return newChildren.insert(namedNode, namedNode.node);\n        }\n      }\n    );\n    return new IndexMap(newIndexes, this.indexSet_);\n  }\n\n  /**\n   * Create a new IndexMap instance with the given value removed\n   */\n  removeFromIndexes(\n    namedNode: NamedNode,\n    existingChildren: SortedMap<string, Node>\n  ): IndexMap {\n    const newIndexes = map(\n      this.indexes_,\n      (indexedChildren: SortedMap<NamedNode, Node>) => {\n        if (indexedChildren === fallbackObject) {\n          // This is the fallback. Just return it, nothing to do in this case\n          return indexedChildren;\n        } else {\n          const existingSnap = existingChildren.get(namedNode.name);\n          if (existingSnap) {\n            return indexedChildren.remove(\n              new NamedNode(namedNode.name, existingSnap)\n            );\n          } else {\n            // No record of this child\n            return indexedChildren;\n          }\n        }\n      }\n    );\n    return new IndexMap(newIndexes, this.indexSet_);\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 { nameCompare } from '../util/util';\nimport { NamedNode } from './Node';\n\nexport function NAME_ONLY_COMPARATOR(left: NamedNode, right: NamedNode) {\n  return nameCompare(left.name, right.name);\n}\n\nexport function NAME_COMPARATOR(left: string, right: string) {\n  return nameCompare(left, right);\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 '@firebase/util';\nimport { sha1, MAX_NAME, MIN_NAME } from '../util/util';\nimport { SortedMap, SortedMapIterator } from '../util/SortedMap';\nimport { Node, NamedNode } from './Node';\nimport { validatePriorityNode, priorityHashText, setMaxNode } from './snap';\nimport {\n  PRIORITY_INDEX,\n  setMaxNode as setPriorityMaxNode\n} from './indexes/PriorityIndex';\nimport { KEY_INDEX, KeyIndex } from './indexes/KeyIndex';\nimport { IndexMap } from './IndexMap';\nimport { LeafNode } from './LeafNode';\nimport { NAME_COMPARATOR } from './comparators';\nimport { Index } from './indexes/Index';\nimport { Path } from '../util/Path';\n\nexport interface ChildrenNodeConstructor {\n  new (\n    children_: SortedMap<string, Node>,\n    priorityNode_: Node | null,\n    indexMap_: IndexMap\n  ): ChildrenNode;\n  EMPTY_NODE: ChildrenNode;\n}\n\n// TODO: For memory savings, don't store priorityNode_ if it's empty.\n\nlet EMPTY_NODE: ChildrenNode;\n\n/**\n * ChildrenNode is a class for storing internal nodes in a DataSnapshot\n * (i.e. nodes with children).  It implements Node and stores the\n * list of children in the children property, sorted by child name.\n *\n * @constructor\n * @implements {Node}\n */\nexport class ChildrenNode implements Node {\n  private lazyHash_: string | null = null;\n\n  static get EMPTY_NODE(): ChildrenNode {\n    return (\n      EMPTY_NODE ||\n      (EMPTY_NODE = new ChildrenNode(\n        new SortedMap<string, Node>(NAME_COMPARATOR),\n        null,\n        IndexMap.Default\n      ))\n    );\n  }\n\n  /**\n   *\n   * @param {!SortedMap.<string, !Node>} children_ List of children\n   * of this node..\n   * @param {?Node} priorityNode_ The priority of this node (as a snapshot node).\n   * @param {!IndexMap} indexMap_\n   */\n  constructor(\n    private readonly children_: SortedMap<string, Node>,\n    private readonly priorityNode_: Node | null,\n    private indexMap_: IndexMap\n  ) {\n    /**\n     * Note: The only reason we allow null priority is for EMPTY_NODE, since we can't use\n     * EMPTY_NODE as the priority of EMPTY_NODE.  We might want to consider making EMPTY_NODE its own\n     * class instead of an empty ChildrenNode.\n     */\n    if (this.priorityNode_) {\n      validatePriorityNode(this.priorityNode_);\n    }\n\n    if (this.children_.isEmpty()) {\n      assert(\n        !this.priorityNode_ || this.priorityNode_.isEmpty(),\n        'An empty node cannot have a priority'\n      );\n    }\n  }\n\n  /** @inheritDoc */\n  isLeafNode(): boolean {\n    return false;\n  }\n\n  /** @inheritDoc */\n  getPriority(): Node {\n    return this.priorityNode_ || EMPTY_NODE;\n  }\n\n  /** @inheritDoc */\n  updatePriority(newPriorityNode: Node): Node {\n    if (this.children_.isEmpty()) {\n      // Don't allow priorities on empty nodes\n      return this;\n    } else {\n      return new ChildrenNode(this.children_, newPriorityNode, this.indexMap_);\n    }\n  }\n\n  /** @inheritDoc */\n  getImmediateChild(childName: string): Node {\n    // Hack to treat priority as a regular child\n    if (childName === '.priority') {\n      return this.getPriority();\n    } else {\n      const child = this.children_.get(childName);\n      return child === null ? EMPTY_NODE : child;\n    }\n  }\n\n  /** @inheritDoc */\n  getChild(path: Path): Node {\n    const front = path.getFront();\n    if (front === null) {\n      return this;\n    }\n\n    return this.getImmediateChild(front).getChild(path.popFront());\n  }\n\n  /** @inheritDoc */\n  hasChild(childName: string): boolean {\n    return this.children_.get(childName) !== null;\n  }\n\n  /** @inheritDoc */\n  updateImmediateChild(childName: string, newChildNode: Node): Node {\n    assert(newChildNode, 'We should always be passing snapshot nodes');\n    if (childName === '.priority') {\n      return this.updatePriority(newChildNode);\n    } else {\n      const namedNode = new NamedNode(childName, newChildNode);\n      let newChildren, newIndexMap;\n      if (newChildNode.isEmpty()) {\n        newChildren = this.children_.remove(childName);\n        newIndexMap = this.indexMap_.removeFromIndexes(\n          namedNode,\n          this.children_\n        );\n      } else {\n        newChildren = this.children_.insert(childName, newChildNode);\n        newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_);\n      }\n\n      const newPriority = newChildren.isEmpty()\n        ? EMPTY_NODE\n        : this.priorityNode_;\n      return new ChildrenNode(newChildren, newPriority, newIndexMap);\n    }\n  }\n\n  /** @inheritDoc */\n  updateChild(path: Path, newChildNode: Node): Node {\n    const front = path.getFront();\n    if (front === null) {\n      return newChildNode;\n    } else {\n      assert(\n        path.getFront() !== '.priority' || path.getLength() === 1,\n        '.priority must be the last token in a path'\n      );\n      const newImmediateChild = this.getImmediateChild(front).updateChild(\n        path.popFront(),\n        newChildNode\n      );\n      return this.updateImmediateChild(front, newImmediateChild);\n    }\n  }\n\n  /** @inheritDoc */\n  isEmpty(): boolean {\n    return this.children_.isEmpty();\n  }\n\n  /** @inheritDoc */\n  numChildren(): number {\n    return this.children_.count();\n  }\n\n  /**\n   * @private\n   * @type {RegExp}\n   */\n  private static INTEGER_REGEXP_ = /^(0|[1-9]\\d*)$/;\n\n  /** @inheritDoc */\n  val(exportFormat?: boolean): object {\n    if (this.isEmpty()) {\n      return null;\n    }\n\n    const obj: { [k: string]: unknown } = {};\n    let numKeys = 0,\n      maxKey = 0,\n      allIntegerKeys = true;\n    this.forEachChild(PRIORITY_INDEX, (key: string, childNode: Node) => {\n      obj[key] = childNode.val(exportFormat);\n\n      numKeys++;\n      if (allIntegerKeys && ChildrenNode.INTEGER_REGEXP_.test(key)) {\n        maxKey = Math.max(maxKey, Number(key));\n      } else {\n        allIntegerKeys = false;\n      }\n    });\n\n    if (!exportFormat && allIntegerKeys && maxKey < 2 * numKeys) {\n      // convert to array.\n      const array: unknown[] = [];\n      // eslint-disable-next-line guard-for-in\n      for (const key in obj) {\n        array[(key as unknown) as number] = obj[key];\n      }\n\n      return array;\n    } else {\n      if (exportFormat && !this.getPriority().isEmpty()) {\n        obj['.priority'] = this.getPriority().val();\n      }\n      return obj;\n    }\n  }\n\n  /** @inheritDoc */\n  hash(): string {\n    if (this.lazyHash_ === null) {\n      let toHash = '';\n      if (!this.getPriority().isEmpty()) {\n        toHash +=\n          'priority:' +\n          priorityHashText(this.getPriority().val() as string | number) +\n          ':';\n      }\n\n      this.forEachChild(PRIORITY_INDEX, (key, childNode) => {\n        const childHash = childNode.hash();\n        if (childHash !== '') {\n          toHash += ':' + key + ':' + childHash;\n        }\n      });\n\n      this.lazyHash_ = toHash === '' ? '' : sha1(toHash);\n    }\n    return this.lazyHash_;\n  }\n\n  /** @inheritDoc */\n  getPredecessorChildName(\n    childName: string,\n    childNode: Node,\n    index: Index\n  ): string {\n    const idx = this.resolveIndex_(index);\n    if (idx) {\n      const predecessor = idx.getPredecessorKey(\n        new NamedNode(childName, childNode)\n      );\n      return predecessor ? predecessor.name : null;\n    } else {\n      return this.children_.getPredecessorKey(childName);\n    }\n  }\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {?string}\n   */\n  getFirstChildName(indexDefinition: Index): string | null {\n    const idx = this.resolveIndex_(indexDefinition);\n    if (idx) {\n      const minKey = idx.minKey();\n      return minKey && minKey.name;\n    } else {\n      return this.children_.minKey();\n    }\n  }\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {?NamedNode}\n   */\n  getFirstChild(indexDefinition: Index): NamedNode | null {\n    const minKey = this.getFirstChildName(indexDefinition);\n    if (minKey) {\n      return new NamedNode(minKey, this.children_.get(minKey));\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Given an index, return the key name of the largest value we have, according to that index\n   * @param {!Index} indexDefinition\n   * @return {?string}\n   */\n  getLastChildName(indexDefinition: Index): string | null {\n    const idx = this.resolveIndex_(indexDefinition);\n    if (idx) {\n      const maxKey = idx.maxKey();\n      return maxKey && maxKey.name;\n    } else {\n      return this.children_.maxKey();\n    }\n  }\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {?NamedNode}\n   */\n  getLastChild(indexDefinition: Index): NamedNode | null {\n    const maxKey = this.getLastChildName(indexDefinition);\n    if (maxKey) {\n      return new NamedNode(maxKey, this.children_.get(maxKey));\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachChild(\n    index: Index,\n    action: (key: string, node: Node) => boolean | void\n  ): boolean {\n    const idx = this.resolveIndex_(index);\n    if (idx) {\n      return idx.inorderTraversal(wrappedNode => {\n        return action(wrappedNode.name, wrappedNode.node);\n      });\n    } else {\n      return this.children_.inorderTraversal(action);\n    }\n  }\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {SortedMapIterator}\n   */\n  getIterator(\n    indexDefinition: Index\n  ): SortedMapIterator<string | NamedNode, Node, NamedNode> {\n    return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition);\n  }\n\n  /**\n   *\n   * @param {!NamedNode} startPost\n   * @param {!Index} indexDefinition\n   * @return {!SortedMapIterator}\n   */\n  getIteratorFrom(\n    startPost: NamedNode,\n    indexDefinition: Index\n  ): SortedMapIterator<string | NamedNode, Node, NamedNode> {\n    const idx = this.resolveIndex_(indexDefinition);\n    if (idx) {\n      return idx.getIteratorFrom(startPost, key => key);\n    } else {\n      const iterator = this.children_.getIteratorFrom(\n        startPost.name,\n        NamedNode.Wrap\n      );\n      let next = iterator.peek();\n      while (next != null && indexDefinition.compare(next, startPost) < 0) {\n        iterator.getNext();\n        next = iterator.peek();\n      }\n      return iterator;\n    }\n  }\n\n  /**\n   * @param {!Index} indexDefinition\n   * @return {!SortedMapIterator}\n   */\n  getReverseIterator(\n    indexDefinition: Index\n  ): SortedMapIterator<string | NamedNode, Node, NamedNode> {\n    return this.getReverseIteratorFrom(\n      indexDefinition.maxPost(),\n      indexDefinition\n    );\n  }\n\n  /**\n   * @param {!NamedNode} endPost\n   * @param {!Index} indexDefinition\n   * @return {!SortedMapIterator}\n   */\n  getReverseIteratorFrom(\n    endPost: NamedNode,\n    indexDefinition: Index\n  ): SortedMapIterator<string | NamedNode, Node, NamedNode> {\n    const idx = this.resolveIndex_(indexDefinition);\n    if (idx) {\n      return idx.getReverseIteratorFrom(endPost, key => {\n        return key;\n      });\n    } else {\n      const iterator = this.children_.getReverseIteratorFrom(\n        endPost.name,\n        NamedNode.Wrap\n      );\n      let next = iterator.peek();\n      while (next != null && indexDefinition.compare(next, endPost) > 0) {\n        iterator.getNext();\n        next = iterator.peek();\n      }\n      return iterator;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  compareTo(other: ChildrenNode): number {\n    if (this.isEmpty()) {\n      if (other.isEmpty()) {\n        return 0;\n      } else {\n        return -1;\n      }\n    } else if (other.isLeafNode() || other.isEmpty()) {\n      return 1;\n    } else if (other === MAX_NODE) {\n      return -1;\n    } else {\n      // Must be another node with children.\n      return 0;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  withIndex(indexDefinition: Index): Node {\n    if (\n      indexDefinition === KEY_INDEX ||\n      this.indexMap_.hasIndex(indexDefinition)\n    ) {\n      return this;\n    } else {\n      const newIndexMap = this.indexMap_.addIndex(\n        indexDefinition,\n        this.children_\n      );\n      return new ChildrenNode(this.children_, this.priorityNode_, newIndexMap);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isIndexed(index: Index): boolean {\n    return index === KEY_INDEX || this.indexMap_.hasIndex(index);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  equals(other: Node): boolean {\n    if (other === this) {\n      return true;\n    } else if (other.isLeafNode()) {\n      return false;\n    } else {\n      const otherChildrenNode = other as ChildrenNode;\n      if (!this.getPriority().equals(otherChildrenNode.getPriority())) {\n        return false;\n      } else if (\n        this.children_.count() === otherChildrenNode.children_.count()\n      ) {\n        const thisIter = this.getIterator(PRIORITY_INDEX);\n        const otherIter = otherChildrenNode.getIterator(PRIORITY_INDEX);\n        let thisCurrent = thisIter.getNext();\n        let otherCurrent = otherIter.getNext();\n        while (thisCurrent && otherCurrent) {\n          if (\n            thisCurrent.name !== otherCurrent.name ||\n            !thisCurrent.node.equals(otherCurrent.node)\n          ) {\n            return false;\n          }\n          thisCurrent = thisIter.getNext();\n          otherCurrent = otherIter.getNext();\n        }\n        return thisCurrent === null && otherCurrent === null;\n      } else {\n        return false;\n      }\n    }\n  }\n\n  /**\n   * Returns a SortedMap ordered by index, or null if the default (by-key) ordering can be used\n   * instead.\n   *\n   * @private\n   * @param {!Index} indexDefinition\n   * @return {?SortedMap.<NamedNode, Node>}\n   */\n  private resolveIndex_(\n    indexDefinition: Index\n  ): SortedMap<NamedNode, Node> | null {\n    if (indexDefinition === KEY_INDEX) {\n      return null;\n    } else {\n      return this.indexMap_.get(indexDefinition.toString());\n    }\n  }\n}\n\n/**\n * @constructor\n * @extends {ChildrenNode}\n * @private\n */\nexport class MaxNode extends ChildrenNode {\n  constructor() {\n    super(\n      new SortedMap<string, Node>(NAME_COMPARATOR),\n      ChildrenNode.EMPTY_NODE,\n      IndexMap.Default\n    );\n  }\n\n  compareTo(other: Node): number {\n    if (other === this) {\n      return 0;\n    } else {\n      return 1;\n    }\n  }\n\n  equals(other: Node): boolean {\n    // Not that we every compare it, but MAX_NODE is only ever equal to itself\n    return other === this;\n  }\n\n  getPriority(): MaxNode {\n    return this;\n  }\n\n  getImmediateChild(childName: string): ChildrenNode {\n    return ChildrenNode.EMPTY_NODE;\n  }\n\n  isEmpty(): boolean {\n    return false;\n  }\n}\n\n/**\n * Marker that will sort higher than any other snapshot.\n * @type {!MAX_NODE}\n * @const\n */\nexport const MAX_NODE = new MaxNode();\n\n/**\n * Document NamedNode extensions\n */\ndeclare module './Node' {\n  interface NamedNode {\n    MIN: NamedNode;\n    MAX: NamedNode;\n  }\n}\n\nObject.defineProperties(NamedNode, {\n  MIN: {\n    value: new NamedNode(MIN_NAME, ChildrenNode.EMPTY_NODE)\n  },\n  MAX: {\n    value: new NamedNode(MAX_NAME, MAX_NODE)\n  }\n});\n\n/**\n * Reference Extensions\n */\nKeyIndex.__EMPTY_NODE = ChildrenNode.EMPTY_NODE;\nLeafNode.__childrenNodeConstructor = ChildrenNode;\nsetMaxNode(MAX_NODE);\nsetPriorityMaxNode(MAX_NODE);\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 { ChildrenNode } from './ChildrenNode';\nimport { LeafNode } from './LeafNode';\nimport { NamedNode, Node } from './Node';\nimport { contains, assert } from '@firebase/util';\n\nimport { buildChildSet } from './childSet';\nimport { NAME_COMPARATOR, NAME_ONLY_COMPARATOR } from './comparators';\nimport { IndexMap } from './IndexMap';\nimport { PRIORITY_INDEX, setNodeFromJSON } from './indexes/PriorityIndex';\nimport { SortedMap } from '../util/SortedMap';\nimport { each } from '../util/util';\nimport { Indexable } from '../util/misc';\n\nconst USE_HINZE = true;\n\n/**\n * Constructs a snapshot node representing the passed JSON and returns it.\n * @param {*} json JSON to create a node for.\n * @param {?string|?number=} priority Optional priority to use.  This will be ignored if the\n * passed JSON contains a .priority property.\n * @return {!Node}\n */\nexport function nodeFromJSON(\n  json: unknown | null,\n  priority: unknown = null\n): Node {\n  if (json === null) {\n    return ChildrenNode.EMPTY_NODE;\n  }\n\n  if (typeof json === 'object' && '.priority' in json) {\n    priority = json['.priority'];\n  }\n\n  assert(\n    priority === null ||\n      typeof priority === 'string' ||\n      typeof priority === 'number' ||\n      (typeof priority === 'object' && '.sv' in (priority as object)),\n    'Invalid priority type found: ' + typeof priority\n  );\n\n  if (typeof json === 'object' && '.value' in json && json['.value'] !== null) {\n    json = json['.value'];\n  }\n\n  // Valid leaf nodes include non-objects or server-value wrapper objects\n  if (typeof json !== 'object' || '.sv' in json) {\n    const jsonLeaf = json as string | number | boolean | Indexable;\n    return new LeafNode(jsonLeaf, nodeFromJSON(priority));\n  }\n\n  if (!(json instanceof Array) && USE_HINZE) {\n    const children: NamedNode[] = [];\n    let childrenHavePriority = false;\n    const hinzeJsonObj = json;\n    each(hinzeJsonObj, (key, child) => {\n      if (key.substring(0, 1) !== '.') {\n        // Ignore metadata nodes\n        const childNode = nodeFromJSON(child);\n        if (!childNode.isEmpty()) {\n          childrenHavePriority =\n            childrenHavePriority || !childNode.getPriority().isEmpty();\n          children.push(new NamedNode(key, childNode));\n        }\n      }\n    });\n\n    if (children.length === 0) {\n      return ChildrenNode.EMPTY_NODE;\n    }\n\n    const childSet = buildChildSet(\n      children,\n      NAME_ONLY_COMPARATOR,\n      namedNode => namedNode.name,\n      NAME_COMPARATOR\n    ) as SortedMap<string, Node>;\n    if (childrenHavePriority) {\n      const sortedChildSet = buildChildSet(\n        children,\n        PRIORITY_INDEX.getCompare()\n      );\n      return new ChildrenNode(\n        childSet,\n        nodeFromJSON(priority),\n        new IndexMap(\n          { '.priority': sortedChildSet },\n          { '.priority': PRIORITY_INDEX }\n        )\n      );\n    } else {\n      return new ChildrenNode(\n        childSet,\n        nodeFromJSON(priority),\n        IndexMap.Default\n      );\n    }\n  } else {\n    let node: Node = ChildrenNode.EMPTY_NODE;\n    each(json, (key: string, childData: unknown) => {\n      if (contains(json as object, key)) {\n        if (key.substring(0, 1) !== '.') {\n          // ignore metadata nodes.\n          const childNode = nodeFromJSON(childData);\n          if (childNode.isLeafNode() || !childNode.isEmpty()) {\n            node = node.updateImmediateChild(key, childNode);\n          }\n        }\n      }\n    });\n\n    return node.updatePriority(nodeFromJSON(priority));\n  }\n}\n\nsetNodeFromJSON(nodeFromJSON);\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 { Index } from './Index';\nimport { NamedNode, Node } from '../Node';\nimport { nameCompare } from '../../util/util';\nimport { nodeFromJSON } from '../nodeFromJSON';\n\n/**\n * @constructor\n * @extends {Index}\n * @private\n */\nexport class ValueIndex extends Index {\n  /**\n   * @inheritDoc\n   */\n  compare(a: NamedNode, b: NamedNode): number {\n    const indexCmp = a.node.compareTo(b.node);\n    if (indexCmp === 0) {\n      return nameCompare(a.name, b.name);\n    } else {\n      return indexCmp;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isDefinedOn(node: Node): boolean {\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n    return !oldNode.equals(newNode);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  minPost(): NamedNode {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return (NamedNode as any).MIN;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  maxPost(): NamedNode {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return (NamedNode as any).MAX;\n  }\n\n  /**\n   * @param {*} indexValue\n   * @param {string} name\n   * @return {!NamedNode}\n   */\n  makePost(indexValue: object, name: string): NamedNode {\n    const valueNode = nodeFromJSON(indexValue);\n    return new NamedNode(name, valueNode);\n  }\n\n  /**\n   * @return {!string} String representation for inclusion in a query spec\n   */\n  toString(): string {\n    return '.value';\n  }\n}\n\nexport const VALUE_INDEX = new ValueIndex();\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 '@firebase/util';\nimport { nameCompare, MAX_NAME } from '../../util/util';\nimport { Index } from './Index';\nimport { ChildrenNode, MAX_NODE } from '../ChildrenNode';\nimport { NamedNode, Node } from '../Node';\nimport { nodeFromJSON } from '../nodeFromJSON';\nimport { Path } from '../../util/Path';\n\n/**\n * @param {!Path} indexPath\n * @constructor\n * @extends {Index}\n */\nexport class PathIndex extends Index {\n  constructor(private indexPath_: Path) {\n    super();\n\n    assert(\n      !indexPath_.isEmpty() && indexPath_.getFront() !== '.priority',\n      \"Can't create PathIndex with empty path or .priority key\"\n    );\n  }\n\n  /**\n   * @param {!Node} snap\n   * @return {!Node}\n   * @protected\n   */\n  protected extractChild(snap: Node): Node {\n    return snap.getChild(this.indexPath_);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isDefinedOn(node: Node): boolean {\n    return !node.getChild(this.indexPath_).isEmpty();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  compare(a: NamedNode, b: NamedNode): number {\n    const aChild = this.extractChild(a.node);\n    const bChild = this.extractChild(b.node);\n    const indexCmp = aChild.compareTo(bChild);\n    if (indexCmp === 0) {\n      return nameCompare(a.name, b.name);\n    } else {\n      return indexCmp;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  makePost(indexValue: object, name: string): NamedNode {\n    const valueNode = nodeFromJSON(indexValue);\n    const node = ChildrenNode.EMPTY_NODE.updateChild(\n      this.indexPath_,\n      valueNode\n    );\n    return new NamedNode(name, node);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  maxPost(): NamedNode {\n    const node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, MAX_NODE);\n    return new NamedNode(MAX_NAME, node);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  toString(): string {\n    return this.indexPath_.slice().join('/');\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 { validateArgCount, validateCallback } from '@firebase/util';\nimport { validatePathString } from '../core/util/validation';\nimport { Path } from '../core/util/Path';\nimport { PRIORITY_INDEX } from '../core/snap/indexes/PriorityIndex';\nimport { Node } from '../core/snap/Node';\nimport { Reference } from './Reference';\nimport { Index } from '../core/snap/indexes/Index';\nimport { ChildrenNode } from '../core/snap/ChildrenNode';\n\n/**\n * Class representing a firebase data snapshot.  It wraps a SnapshotNode and\n * surfaces the public methods (val, forEach, etc.) we want to expose.\n */\nexport class DataSnapshot {\n  /**\n   * @param {!Node} node_ A SnapshotNode to wrap.\n   * @param {!Reference} ref_ The ref of the location this snapshot came from.\n   * @param {!Index} index_ The iteration order for this snapshot\n   */\n  constructor(\n    private readonly node_: Node,\n    private readonly ref_: Reference,\n    private readonly index_: Index\n  ) {}\n\n  /**\n   * Retrieves the snapshot contents as JSON.  Returns null if the snapshot is\n   * empty.\n   *\n   * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\n   */\n  val(): unknown {\n    validateArgCount('DataSnapshot.val', 0, 0, arguments.length);\n    return this.node_.val();\n  }\n\n  /**\n   * Returns the snapshot contents as JSON, including priorities of node.  Suitable for exporting\n   * the entire node contents.\n   * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\n   */\n  exportVal(): unknown {\n    validateArgCount('DataSnapshot.exportVal', 0, 0, arguments.length);\n    return this.node_.val(true);\n  }\n\n  // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n  // for end-users\n  toJSON(): unknown {\n    // Optional spacer argument is unnecessary because we're depending on recursion rather than stringifying the content\n    validateArgCount('DataSnapshot.toJSON', 0, 1, arguments.length);\n    return this.exportVal();\n  }\n\n  /**\n   * Returns whether the snapshot contains a non-null value.\n   *\n   * @return {boolean} Whether the snapshot contains a non-null value, or is empty.\n   */\n  exists(): boolean {\n    validateArgCount('DataSnapshot.exists', 0, 0, arguments.length);\n    return !this.node_.isEmpty();\n  }\n\n  /**\n   * Returns a DataSnapshot of the specified child node's contents.\n   *\n   * @param {!string} childPathString Path to a child.\n   * @return {!DataSnapshot} DataSnapshot for child node.\n   */\n  child(childPathString: string): DataSnapshot {\n    validateArgCount('DataSnapshot.child', 0, 1, arguments.length);\n    // Ensure the childPath is a string (can be a number)\n    childPathString = String(childPathString);\n    validatePathString('DataSnapshot.child', 1, childPathString, false);\n\n    const childPath = new Path(childPathString);\n    const childRef = this.ref_.child(childPath);\n    return new DataSnapshot(\n      this.node_.getChild(childPath),\n      childRef,\n      PRIORITY_INDEX\n    );\n  }\n\n  /**\n   * Returns whether the snapshot contains a child at the specified path.\n   *\n   * @param {!string} childPathString Path to a child.\n   * @return {boolean} Whether the child exists.\n   */\n  hasChild(childPathString: string): boolean {\n    validateArgCount('DataSnapshot.hasChild', 1, 1, arguments.length);\n    validatePathString('DataSnapshot.hasChild', 1, childPathString, false);\n\n    const childPath = new Path(childPathString);\n    return !this.node_.getChild(childPath).isEmpty();\n  }\n\n  /**\n   * Returns the priority of the object, or null if no priority was set.\n   *\n   * @return {string|number|null} The priority.\n   */\n  getPriority(): string | number | null {\n    validateArgCount('DataSnapshot.getPriority', 0, 0, arguments.length);\n\n    // typecast here because we never return deferred values or internal priorities (MAX_PRIORITY)\n    return this.node_.getPriority().val() as string | number | null;\n  }\n\n  /**\n   * Iterates through child nodes and calls the specified action for each one.\n   *\n   * @param {function(!DataSnapshot)} action Callback function to be called\n   * for each child.\n   * @return {boolean} True if forEach was canceled by action returning true for\n   * one of the child nodes.\n   */\n  forEach(action: (d: DataSnapshot) => boolean | void): boolean {\n    validateArgCount('DataSnapshot.forEach', 1, 1, arguments.length);\n    validateCallback('DataSnapshot.forEach', 1, action, false);\n\n    if (this.node_.isLeafNode()) {\n      return false;\n    }\n\n    const childrenNode = this.node_ as ChildrenNode;\n    // Sanitize the return value to a boolean. ChildrenNode.forEachChild has a weird return type...\n    return !!childrenNode.forEachChild(this.index_, (key, node) => {\n      return action(\n        new DataSnapshot(node, this.ref_.child(key), PRIORITY_INDEX)\n      );\n    });\n  }\n\n  /**\n   * Returns whether this DataSnapshot has children.\n   * @return {boolean} True if the DataSnapshot contains 1 or more child nodes.\n   */\n  hasChildren(): boolean {\n    validateArgCount('DataSnapshot.hasChildren', 0, 0, arguments.length);\n\n    if (this.node_.isLeafNode()) {\n      return false;\n    } else {\n      return !this.node_.isEmpty();\n    }\n  }\n\n  get key() {\n    return this.ref_.getKey();\n  }\n\n  /**\n   * Returns the number of children for this DataSnapshot.\n   * @return {number} The number of children that this DataSnapshot contains.\n   */\n  numChildren(): number {\n    validateArgCount('DataSnapshot.numChildren', 0, 0, arguments.length);\n\n    return this.node_.numChildren();\n  }\n\n  /**\n   * @return {Reference} The Firebase reference for the location this snapshot's data came from.\n   */\n  getRef(): Reference {\n    validateArgCount('DataSnapshot.ref', 0, 0, arguments.length);\n\n    return this.ref_;\n  }\n\n  get ref() {\n    return this.getRef();\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 { stringify } from '@firebase/util';\nimport { Path } from '../util/Path';\nimport { EventRegistration } from './EventRegistration';\nimport { DataSnapshot } from '../../api/DataSnapshot';\n\n/**\n * Encapsulates the data needed to raise an event\n * @interface\n */\nexport interface Event {\n  /**\n   * @return {!Path}\n   */\n  getPath(): Path;\n\n  /**\n   * @return {!string}\n   */\n  getEventType(): string;\n\n  /**\n   * @return {!function()}\n   */\n  getEventRunner(): () => void;\n\n  /**\n   * @return {!string}\n   */\n  toString(): string;\n}\n\nexport type EventType =\n  | 'value'\n  | ' child_added'\n  | ' child_changed'\n  | ' child_moved'\n  | ' child_removed';\n\n/**\n * Encapsulates the data needed to raise an event\n * @implements {Event}\n */\nexport class DataEvent implements Event {\n  /**\n   * @param {!string} eventType One of: value, child_added, child_changed, child_moved, child_removed\n   * @param {!EventRegistration} eventRegistration The function to call to with the event data. User provided\n   * @param {!DataSnapshot} snapshot The data backing the event\n   * @param {?string=} prevName Optional, the name of the previous child for child_* events.\n   */\n  constructor(\n    public eventType: EventType,\n    public eventRegistration: EventRegistration,\n    public snapshot: DataSnapshot,\n    public prevName?: string | null\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  getPath(): Path {\n    const ref = this.snapshot.getRef();\n    if (this.eventType === 'value') {\n      return ref.path;\n    } else {\n      return ref.getParent().path;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventType(): string {\n    return this.eventType;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventRunner(): () => void {\n    return this.eventRegistration.getEventRunner(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  toString(): string {\n    return (\n      this.getPath().toString() +\n      ':' +\n      this.eventType +\n      ':' +\n      stringify(this.snapshot.exportVal())\n    );\n  }\n}\n\nexport class CancelEvent implements Event {\n  /**\n   * @param {EventRegistration} eventRegistration\n   * @param {Error} error\n   * @param {!Path} path\n   */\n  constructor(\n    public eventRegistration: EventRegistration,\n    public error: Error,\n    public path: Path\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  getPath(): Path {\n    return this.path;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventType(): string {\n    return 'cancel';\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventRunner(): () => void {\n    return this.eventRegistration.getEventRunner(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  toString(): string {\n    return this.path.toString() + ':cancel';\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 { DataSnapshot } from '../../api/DataSnapshot';\nimport { DataEvent, CancelEvent, Event, EventType } from './Event';\nimport { contains, assert } from '@firebase/util';\n\nimport { Path } from '../util/Path';\nimport { Change } from './Change';\nimport { Query } from '../../api/Query';\n\n/**\n * An EventRegistration is basically an event type ('value', 'child_added', etc.) and a callback\n * to be notified of that type of event.\n *\n * That said, it can also contain a cancel callback to be notified if the event is canceled.  And\n * currently, this code is organized around the idea that you would register multiple child_ callbacks\n * together, as a single EventRegistration.  Though currently we don't do that.\n */\nexport interface EventRegistration {\n  /**\n   * True if this container has a callback to trigger for this event type\n   * @param {!string} eventType\n   * @return {boolean}\n   */\n  respondsTo(eventType: string): boolean;\n\n  /**\n   * @param {!Change} change\n   * @param {!Query} query\n   * @return {!Event}\n   */\n  createEvent(change: Change, query: Query): Event;\n\n  /**\n   * Given event data, return a function to trigger the user's callback\n   * @param {!Event} eventData\n   * @return {function()}\n   */\n  getEventRunner(eventData: Event): () => void;\n\n  /**\n   * @param {!Error} error\n   * @param {!Path} path\n   * @return {?CancelEvent}\n   */\n  createCancelEvent(error: Error, path: Path): CancelEvent | null;\n\n  /**\n   * @param {!EventRegistration} other\n   * @return {boolean}\n   */\n  matches(other: EventRegistration): boolean;\n\n  /**\n   * False basically means this is a \"dummy\" callback container being used as a sentinel\n   * to remove all callback containers of a particular type.  (e.g. if the user does\n   * ref.off('value') without specifying a specific callback).\n   *\n   * (TODO: Rework this, since it's hacky)\n   *\n   * @return {boolean}\n   */\n  hasAnyCallback(): boolean;\n}\n\n/**\n * Represents registration for 'value' events.\n */\nexport class ValueEventRegistration implements EventRegistration {\n  /**\n   * @param {?function(!DataSnapshot)} callback_\n   * @param {?function(Error)} cancelCallback_\n   * @param {?Object} context_\n   */\n  constructor(\n    private callback_: ((d: DataSnapshot) => void) | null,\n    private cancelCallback_: ((e: Error) => void) | null,\n    private context_: {} | null\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  respondsTo(eventType: string): boolean {\n    return eventType === 'value';\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createEvent(change: Change, query: Query): DataEvent {\n    const index = query.getQueryParams().getIndex();\n    return new DataEvent(\n      'value',\n      this,\n      new DataSnapshot(change.snapshotNode, query.getRef(), index)\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n    const ctx = this.context_;\n    if (eventData.getEventType() === 'cancel') {\n      assert(\n        this.cancelCallback_,\n        'Raising a cancel event on a listener with no cancel callback'\n      );\n      const cancelCB = this.cancelCallback_;\n      return function () {\n        // We know that error exists, we checked above that this is a cancel event\n        cancelCB.call(ctx, (eventData as CancelEvent).error);\n      };\n    } else {\n      const cb = this.callback_;\n      return function () {\n        cb.call(ctx, (eventData as DataEvent).snapshot);\n      };\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createCancelEvent(error: Error, path: Path): CancelEvent | null {\n    if (this.cancelCallback_) {\n      return new CancelEvent(this, error, path);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  matches(other: EventRegistration): boolean {\n    if (!(other instanceof ValueEventRegistration)) {\n      return false;\n    } else if (!other.callback_ || !this.callback_) {\n      // If no callback specified, we consider it to match any callback.\n      return true;\n    } else {\n      return (\n        other.callback_ === this.callback_ && other.context_ === this.context_\n      );\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasAnyCallback(): boolean {\n    return this.callback_ !== null;\n  }\n}\n\n/**\n * Represents the registration of 1 or more child_xxx events.\n *\n * Currently, it is always exactly 1 child_xxx event, but the idea is we might let you\n * register a group of callbacks together in the future.\n *\n * @constructor\n * @implements {EventRegistration}\n */\nexport class ChildEventRegistration implements EventRegistration {\n  /**\n   * @param {?Object.<string, function(!DataSnapshot, ?string=)>} callbacks_\n   * @param {?function(Error)} cancelCallback_\n   * @param {Object=} context_\n   */\n  constructor(\n    private callbacks_: {\n      [k: string]: (d: DataSnapshot, s?: string | null) => void;\n    } | null,\n    private cancelCallback_: ((e: Error) => void) | null,\n    private context_?: {}\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  respondsTo(eventType: string): boolean {\n    let eventToCheck =\n      eventType === 'children_added' ? 'child_added' : eventType;\n    eventToCheck =\n      eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;\n    return contains(this.callbacks_, eventToCheck);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createCancelEvent(error: Error, path: Path): CancelEvent | null {\n    if (this.cancelCallback_) {\n      return new CancelEvent(this, error, path);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createEvent(change: Change, query: Query): DataEvent {\n    assert(change.childName != null, 'Child events should have a childName.');\n    const ref = query.getRef().child(/** @type {!string} */ change.childName);\n    const index = query.getQueryParams().getIndex();\n    return new DataEvent(\n      change.type as EventType,\n      this,\n      new DataSnapshot(change.snapshotNode, ref, index),\n      change.prevName\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n    const ctx = this.context_;\n    if (eventData.getEventType() === 'cancel') {\n      assert(\n        this.cancelCallback_,\n        'Raising a cancel event on a listener with no cancel callback'\n      );\n      const cancelCB = this.cancelCallback_;\n      return function () {\n        // We know that error exists, we checked above that this is a cancel event\n        cancelCB.call(ctx, (eventData as CancelEvent).error);\n      };\n    } else {\n      const cb = this.callbacks_[(eventData as DataEvent).eventType];\n      return function () {\n        cb.call(\n          ctx,\n          (eventData as DataEvent).snapshot,\n          (eventData as DataEvent).prevName\n        );\n      };\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  matches(other: EventRegistration): boolean {\n    if (other instanceof ChildEventRegistration) {\n      if (!this.callbacks_ || !other.callbacks_) {\n        return true;\n      } else if (this.context_ === other.context_) {\n        const otherKeys = Object.keys(other.callbacks_);\n        const thisKeys = Object.keys(this.callbacks_);\n        const otherCount = otherKeys.length;\n        const thisCount = thisKeys.length;\n        if (otherCount === thisCount) {\n          // If count is 1, do an exact match on eventType, if either is defined but null, it's a match.\n          // If event types don't match, not a match\n          // If count is not 1, exact match across all\n\n          if (otherCount === 1) {\n            const otherKey = otherKeys[0];\n            const thisKey = thisKeys[0];\n            return (\n              thisKey === otherKey &&\n              (!other.callbacks_[otherKey] ||\n                !this.callbacks_[thisKey] ||\n                other.callbacks_[otherKey] === this.callbacks_[thisKey])\n            );\n          } else {\n            // Exact match on each key.\n            return thisKeys.every(\n              eventType =>\n                other.callbacks_[eventType] === this.callbacks_[eventType]\n            );\n          }\n        }\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasAnyCallback(): boolean {\n    return this.callbacks_ !== null;\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 {\n  assert,\n  errorPrefix,\n  validateArgCount,\n  validateCallback,\n  validateContextObject,\n  Deferred\n} from '@firebase/util';\nimport { KEY_INDEX } from '../core/snap/indexes/KeyIndex';\nimport { PRIORITY_INDEX } from '../core/snap/indexes/PriorityIndex';\nimport { VALUE_INDEX } from '../core/snap/indexes/ValueIndex';\nimport { PathIndex } from '../core/snap/indexes/PathIndex';\nimport { MIN_NAME, MAX_NAME, ObjectToUniqueKey } from '../core/util/util';\nimport { Path } from '../core/util/Path';\nimport {\n  isValidPriority,\n  validateEventType,\n  validatePathString,\n  validateFirebaseDataArg,\n  validateKey\n} from '../core/util/validation';\n\nimport {\n  ValueEventRegistration,\n  ChildEventRegistration,\n  EventRegistration\n} from '../core/view/EventRegistration';\n\nimport { Repo } from '../core/Repo';\nimport { QueryParams } from '../core/view/QueryParams';\nimport { Reference } from './Reference';\nimport { DataSnapshot } from './DataSnapshot';\n\nlet __referenceConstructor: new (repo: Repo, path: Path) => Query;\n\nexport interface SnapshotCallback {\n  (a: DataSnapshot, b?: string | null): unknown;\n}\n\n/**\n * A Query represents a filter to be applied to a firebase location.  This object purely represents the\n * query expression (and exposes our public API to build the query).  The actual query logic is in ViewBase.js.\n *\n * Since every Firebase reference is a query, Firebase inherits from this object.\n */\nexport class Query {\n  static set __referenceConstructor(val) {\n    __referenceConstructor = val;\n  }\n\n  static get __referenceConstructor() {\n    assert(__referenceConstructor, 'Reference.ts has not been loaded');\n    return __referenceConstructor;\n  }\n\n  constructor(\n    public repo: Repo,\n    public path: Path,\n    private queryParams_: QueryParams,\n    private orderByCalled_: boolean\n  ) {}\n\n  /**\n   * Validates start/end values for queries.\n   * @param {!QueryParams} params\n   * @private\n   */\n  private static validateQueryEndpoints_(params: QueryParams) {\n    let startNode = null;\n    let endNode = null;\n    if (params.hasStart()) {\n      startNode = params.getIndexStartValue();\n    }\n    if (params.hasEnd()) {\n      endNode = params.getIndexEndValue();\n    }\n\n    if (params.getIndex() === KEY_INDEX) {\n      const tooManyArgsError =\n        'Query: When ordering by key, you may only pass one argument to ' +\n        'startAt(), endAt(), or equalTo().';\n      const wrongArgTypeError =\n        'Query: When ordering by key, the argument passed to startAt(), endAt(),' +\n        'or equalTo() must be a string.';\n      if (params.hasStart()) {\n        const startName = params.getIndexStartName();\n        if (startName !== MIN_NAME) {\n          throw new Error(tooManyArgsError);\n        } else if (typeof startNode !== 'string') {\n          throw new Error(wrongArgTypeError);\n        }\n      }\n      if (params.hasEnd()) {\n        const endName = params.getIndexEndName();\n        if (endName !== MAX_NAME) {\n          throw new Error(tooManyArgsError);\n        } else if (typeof endNode !== 'string') {\n          throw new Error(wrongArgTypeError);\n        }\n      }\n    } else if (params.getIndex() === PRIORITY_INDEX) {\n      if (\n        (startNode != null && !isValidPriority(startNode)) ||\n        (endNode != null && !isValidPriority(endNode))\n      ) {\n        throw new Error(\n          'Query: When ordering by priority, the first argument passed to startAt(), ' +\n            'endAt(), or equalTo() must be a valid priority value (null, a number, or a string).'\n        );\n      }\n    } else {\n      assert(\n        params.getIndex() instanceof PathIndex ||\n          params.getIndex() === VALUE_INDEX,\n        'unknown index type.'\n      );\n      if (\n        (startNode != null && typeof startNode === 'object') ||\n        (endNode != null && typeof endNode === 'object')\n      ) {\n        throw new Error(\n          'Query: First argument passed to startAt(), endAt(), or equalTo() cannot be ' +\n            'an object.'\n        );\n      }\n    }\n  }\n\n  /**\n   * Validates that limit* has been called with the correct combination of parameters\n   * @param {!QueryParams} params\n   * @private\n   */\n  private static validateLimit_(params: QueryParams) {\n    if (\n      params.hasStart() &&\n      params.hasEnd() &&\n      params.hasLimit() &&\n      !params.hasAnchoredLimit()\n    ) {\n      throw new Error(\n        \"Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.\"\n      );\n    }\n  }\n\n  /**\n   * Validates that no other order by call has been made\n   * @param {!string} fnName\n   * @private\n   */\n  private validateNoPreviousOrderByCall_(fnName: string) {\n    if (this.orderByCalled_ === true) {\n      throw new Error(fnName + \": You can't combine multiple orderBy calls.\");\n    }\n  }\n\n  /**\n   * @return {!QueryParams}\n   */\n  getQueryParams(): QueryParams {\n    return this.queryParams_;\n  }\n\n  /**\n   * @return {!Reference}\n   */\n  getRef(): Reference {\n    validateArgCount('Query.ref', 0, 0, arguments.length);\n    // This is a slight hack. We cannot goog.require('fb.api.Firebase'), since Firebase requires fb.api.Query.\n    // However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this\n    // method gets called.\n    return new Query.__referenceConstructor(this.repo, this.path) as Reference;\n  }\n\n  /**\n   * @param {!string} eventType\n   * @param {!function(DataSnapshot, string=)} callback\n   * @param {(function(Error)|Object)=} cancelCallbackOrContext\n   * @param {Object=} context\n   * @return {!function(DataSnapshot, string=)}\n   */\n  on(\n    eventType: string,\n    callback: SnapshotCallback,\n    cancelCallbackOrContext?: ((a: Error) => unknown) | object | null,\n    context?: object | null\n  ): SnapshotCallback {\n    validateArgCount('Query.on', 2, 4, arguments.length);\n    validateEventType('Query.on', 1, eventType, false);\n    validateCallback('Query.on', 2, callback, false);\n\n    const ret = Query.getCancelAndContextArgs_(\n      'Query.on',\n      cancelCallbackOrContext,\n      context\n    );\n\n    if (eventType === 'value') {\n      this.onValueEvent(callback, ret.cancel, ret.context);\n    } else {\n      const callbacks: { [k: string]: typeof callback } = {};\n      callbacks[eventType] = callback;\n      this.onChildEvent(callbacks, ret.cancel, ret.context);\n    }\n    return callback;\n  }\n\n  /**\n   * @param {!function(!DataSnapshot)} callback\n   * @param {?function(Error)} cancelCallback\n   * @param {?Object} context\n   * @protected\n   */\n  protected onValueEvent(\n    callback: (a: DataSnapshot) => void,\n    cancelCallback: ((a: Error) => void) | null,\n    context: object | null\n  ) {\n    const container = new ValueEventRegistration(\n      callback,\n      cancelCallback || null,\n      context || null\n    );\n    this.repo.addEventCallbackForQuery(this, container);\n  }\n\n  /**\n   * @param {!Object.<string, !function(!DataSnapshot, ?string)>} callbacks\n   * @param {?function(Error)} cancelCallback\n   * @param {?Object} context\n   * @protected\n   */\n  onChildEvent(\n    callbacks: { [k: string]: SnapshotCallback },\n    cancelCallback: ((a: Error) => unknown) | null,\n    context: object | null\n  ) {\n    const container = new ChildEventRegistration(\n      callbacks,\n      cancelCallback,\n      context\n    );\n    this.repo.addEventCallbackForQuery(this, container);\n  }\n\n  /**\n   * @param {string=} eventType\n   * @param {(function(!DataSnapshot, ?string=))=} callback\n   * @param {Object=} context\n   */\n  off(\n    eventType?: string,\n    callback?: SnapshotCallback,\n    context?: object | null\n  ): void {\n    validateArgCount('Query.off', 0, 3, arguments.length);\n    validateEventType('Query.off', 1, eventType, true);\n    validateCallback('Query.off', 2, callback, true);\n    validateContextObject('Query.off', 3, context, true);\n\n    let container: EventRegistration | null = null;\n    let callbacks: { [k: string]: typeof callback } | null = null;\n    if (eventType === 'value') {\n      const valueCallback = callback || null;\n      container = new ValueEventRegistration(\n        valueCallback,\n        null,\n        context || null\n      );\n    } else if (eventType) {\n      if (callback) {\n        callbacks = {};\n        callbacks[eventType] = callback;\n      }\n      container = new ChildEventRegistration(callbacks, null, context || null);\n    }\n    this.repo.removeEventCallbackForQuery(this, container);\n  }\n\n  /**\n   * Attaches a listener, waits for the first event, and then removes the listener\n   * @param {!string} eventType\n   * @param {!function(!DataSnapshot, string=)} userCallback\n   * @param failureCallbackOrContext\n   * @param context\n   * @return {!firebase.Promise}\n   */\n  once(\n    eventType: string,\n    userCallback?: SnapshotCallback,\n    failureCallbackOrContext?: ((a: Error) => void) | object | null,\n    context?: object | null\n  ): Promise<DataSnapshot> {\n    validateArgCount('Query.once', 1, 4, arguments.length);\n    validateEventType('Query.once', 1, eventType, false);\n    validateCallback('Query.once', 2, userCallback, true);\n\n    const ret = Query.getCancelAndContextArgs_(\n      'Query.once',\n      failureCallbackOrContext,\n      context\n    );\n\n    // TODO: Implement this more efficiently (in particular, use 'get' wire protocol for 'value' event)\n    // TODO: consider actually wiring the callbacks into the promise. We cannot do this without a breaking change\n    // because the API currently expects callbacks will be called synchronously if the data is cached, but this is\n    // against the Promise specification.\n    let firstCall = true;\n    const deferred = new Deferred<DataSnapshot>();\n\n    // A dummy error handler in case a user wasn't expecting promises\n    deferred.promise.catch(() => {});\n\n    const onceCallback = (snapshot: DataSnapshot) => {\n      // NOTE: Even though we unsubscribe, we may get called multiple times if a single action (e.g. set() with JSON)\n      // triggers multiple events (e.g. child_added or child_changed).\n      if (firstCall) {\n        firstCall = false;\n        this.off(eventType, onceCallback);\n\n        if (userCallback) {\n          userCallback.bind(ret.context)(snapshot);\n        }\n        deferred.resolve(snapshot);\n      }\n    };\n\n    this.on(\n      eventType,\n      onceCallback,\n      /*cancel=*/ err => {\n        this.off(eventType, onceCallback);\n\n        if (ret.cancel) {\n          ret.cancel.bind(ret.context)(err);\n        }\n        deferred.reject(err);\n      }\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * Set a limit and anchor it to the start of the window.\n   * @param {!number} limit\n   * @return {!Query}\n   */\n  limitToFirst(limit: number): Query {\n    validateArgCount('Query.limitToFirst', 1, 1, arguments.length);\n    if (\n      typeof limit !== 'number' ||\n      Math.floor(limit) !== limit ||\n      limit <= 0\n    ) {\n      throw new Error(\n        'Query.limitToFirst: First argument must be a positive integer.'\n      );\n    }\n    if (this.queryParams_.hasLimit()) {\n      throw new Error(\n        'Query.limitToFirst: Limit was already set (by another call to limit, ' +\n          'limitToFirst, or limitToLast).'\n      );\n    }\n\n    return new Query(\n      this.repo,\n      this.path,\n      this.queryParams_.limitToFirst(limit),\n      this.orderByCalled_\n    );\n  }\n\n  /**\n   * Set a limit and anchor it to the end of the window.\n   * @param {!number} limit\n   * @return {!Query}\n   */\n  limitToLast(limit: number): Query {\n    validateArgCount('Query.limitToLast', 1, 1, arguments.length);\n    if (\n      typeof limit !== 'number' ||\n      Math.floor(limit) !== limit ||\n      limit <= 0\n    ) {\n      throw new Error(\n        'Query.limitToLast: First argument must be a positive integer.'\n      );\n    }\n    if (this.queryParams_.hasLimit()) {\n      throw new Error(\n        'Query.limitToLast: Limit was already set (by another call to limit, ' +\n          'limitToFirst, or limitToLast).'\n      );\n    }\n\n    return new Query(\n      this.repo,\n      this.path,\n      this.queryParams_.limitToLast(limit),\n      this.orderByCalled_\n    );\n  }\n\n  /**\n   * Given a child path, return a new query ordered by the specified grandchild path.\n   * @param {!string} path\n   * @return {!Query}\n   */\n  orderByChild(path: string): Query {\n    validateArgCount('Query.orderByChild', 1, 1, arguments.length);\n    if (path === '$key') {\n      throw new Error(\n        'Query.orderByChild: \"$key\" is invalid.  Use Query.orderByKey() instead.'\n      );\n    } else if (path === '$priority') {\n      throw new Error(\n        'Query.orderByChild: \"$priority\" is invalid.  Use Query.orderByPriority() instead.'\n      );\n    } else if (path === '$value') {\n      throw new Error(\n        'Query.orderByChild: \"$value\" is invalid.  Use Query.orderByValue() instead.'\n      );\n    }\n    validatePathString('Query.orderByChild', 1, path, false);\n    this.validateNoPreviousOrderByCall_('Query.orderByChild');\n    const parsedPath = new Path(path);\n    if (parsedPath.isEmpty()) {\n      throw new Error(\n        'Query.orderByChild: cannot pass in empty path.  Use Query.orderByValue() instead.'\n      );\n    }\n    const index = new PathIndex(parsedPath);\n    const newParams = this.queryParams_.orderBy(index);\n    Query.validateQueryEndpoints_(newParams);\n\n    return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\n  }\n\n  /**\n   * Return a new query ordered by the KeyIndex\n   * @return {!Query}\n   */\n  orderByKey(): Query {\n    validateArgCount('Query.orderByKey', 0, 0, arguments.length);\n    this.validateNoPreviousOrderByCall_('Query.orderByKey');\n    const newParams = this.queryParams_.orderBy(KEY_INDEX);\n    Query.validateQueryEndpoints_(newParams);\n    return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\n  }\n\n  /**\n   * Return a new query ordered by the PriorityIndex\n   * @return {!Query}\n   */\n  orderByPriority(): Query {\n    validateArgCount('Query.orderByPriority', 0, 0, arguments.length);\n    this.validateNoPreviousOrderByCall_('Query.orderByPriority');\n    const newParams = this.queryParams_.orderBy(PRIORITY_INDEX);\n    Query.validateQueryEndpoints_(newParams);\n    return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\n  }\n\n  /**\n   * Return a new query ordered by the ValueIndex\n   * @return {!Query}\n   */\n  orderByValue(): Query {\n    validateArgCount('Query.orderByValue', 0, 0, arguments.length);\n    this.validateNoPreviousOrderByCall_('Query.orderByValue');\n    const newParams = this.queryParams_.orderBy(VALUE_INDEX);\n    Query.validateQueryEndpoints_(newParams);\n    return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\n  }\n\n  /**\n   * @param {number|string|boolean|null} value\n   * @param {?string=} name\n   * @return {!Query}\n   */\n  startAt(\n    value: number | string | boolean | null = null,\n    name?: string | null\n  ): Query {\n    validateArgCount('Query.startAt', 0, 2, arguments.length);\n    validateFirebaseDataArg('Query.startAt', 1, value, this.path, true);\n    validateKey('Query.startAt', 2, name, true);\n\n    const newParams = this.queryParams_.startAt(value, name);\n    Query.validateLimit_(newParams);\n    Query.validateQueryEndpoints_(newParams);\n    if (this.queryParams_.hasStart()) {\n      throw new Error(\n        'Query.startAt: Starting point was already set (by another call to startAt ' +\n          'or equalTo).'\n      );\n    }\n\n    // Calling with no params tells us to start at the beginning.\n    if (value === undefined) {\n      value = null;\n      name = null;\n    }\n    return new Query(this.repo, this.path, newParams, this.orderByCalled_);\n  }\n\n  /**\n   * @param {number|string|boolean|null} value\n   * @param {?string=} name\n   * @return {!Query}\n   */\n  endAt(\n    value: number | string | boolean | null = null,\n    name?: string | null\n  ): Query {\n    validateArgCount('Query.endAt', 0, 2, arguments.length);\n    validateFirebaseDataArg('Query.endAt', 1, value, this.path, true);\n    validateKey('Query.endAt', 2, name, true);\n\n    const newParams = this.queryParams_.endAt(value, name);\n    Query.validateLimit_(newParams);\n    Query.validateQueryEndpoints_(newParams);\n    if (this.queryParams_.hasEnd()) {\n      throw new Error(\n        'Query.endAt: Ending point was already set (by another call to endAt or ' +\n          'equalTo).'\n      );\n    }\n\n    return new Query(this.repo, this.path, newParams, this.orderByCalled_);\n  }\n\n  /**\n   * Load the selection of children with exactly the specified value, and, optionally,\n   * the specified name.\n   * @param {number|string|boolean|null} value\n   * @param {string=} name\n   * @return {!Query}\n   */\n  equalTo(value: number | string | boolean | null, name?: string) {\n    validateArgCount('Query.equalTo', 1, 2, arguments.length);\n    validateFirebaseDataArg('Query.equalTo', 1, value, this.path, false);\n    validateKey('Query.equalTo', 2, name, true);\n    if (this.queryParams_.hasStart()) {\n      throw new Error(\n        'Query.equalTo: Starting point was already set (by another call to startAt or ' +\n          'equalTo).'\n      );\n    }\n    if (this.queryParams_.hasEnd()) {\n      throw new Error(\n        'Query.equalTo: Ending point was already set (by another call to endAt or ' +\n          'equalTo).'\n      );\n    }\n    return this.startAt(value, name).endAt(value, name);\n  }\n\n  /**\n   * @return {!string} URL for this location.\n   */\n  toString(): string {\n    validateArgCount('Query.toString', 0, 0, arguments.length);\n\n    return this.repo.toString() + this.path.toUrlEncodedString();\n  }\n\n  // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n  // for end-users.\n  toJSON() {\n    // An optional spacer argument is unnecessary for a string.\n    validateArgCount('Query.toJSON', 0, 1, arguments.length);\n    return this.toString();\n  }\n\n  /**\n   * An object representation of the query parameters used by this Query.\n   * @return {!Object}\n   */\n  queryObject(): object {\n    return this.queryParams_.getQueryObject();\n  }\n\n  /**\n   * @return {!string}\n   */\n  queryIdentifier(): string {\n    const obj = this.queryObject();\n    const id = ObjectToUniqueKey(obj);\n    return id === '{}' ? 'default' : id;\n  }\n\n  /**\n   * Return true if this query and the provided query are equivalent; otherwise, return false.\n   * @param {Query} other\n   * @return {boolean}\n   */\n  isEqual(other: Query): boolean {\n    validateArgCount('Query.isEqual', 1, 1, arguments.length);\n    if (!(other instanceof Query)) {\n      const error =\n        'Query.isEqual failed: First argument must be an instance of firebase.database.Query.';\n      throw new Error(error);\n    }\n\n    const sameRepo = this.repo === other.repo;\n    const samePath = this.path.equals(other.path);\n    const sameQueryIdentifier =\n      this.queryIdentifier() === other.queryIdentifier();\n\n    return sameRepo && samePath && sameQueryIdentifier;\n  }\n\n  /**\n   * Helper used by .on and .once to extract the context and or cancel arguments.\n   * @param {!string} fnName The function name (on or once)\n   * @param {(function(Error)|Object)=} cancelOrContext\n   * @param {Object=} context\n   * @return {{cancel: ?function(Error), context: ?Object}}\n   * @private\n   */\n  private static getCancelAndContextArgs_(\n    fnName: string,\n    cancelOrContext?: ((a: Error) => void) | object | null,\n    context?: object | null\n  ): { cancel: ((a: Error) => void) | null; context: object | null } {\n    const ret: {\n      cancel: ((a: Error) => void) | null;\n      context: object | null;\n    } = { cancel: null, context: null };\n    if (cancelOrContext && context) {\n      ret.cancel = cancelOrContext as (a: Error) => void;\n      validateCallback(fnName, 3, ret.cancel, true);\n\n      ret.context = context;\n      validateContextObject(fnName, 4, ret.context, true);\n    } else if (cancelOrContext) {\n      // we have either a cancel callback or a context.\n      if (typeof cancelOrContext === 'object' && cancelOrContext !== null) {\n        // it's a context!\n        ret.context = cancelOrContext;\n      } else if (typeof cancelOrContext === 'function') {\n        ret.cancel = cancelOrContext as (a: Error) => void;\n      } else {\n        throw new Error(\n          errorPrefix(fnName, 3, true) +\n            ' must either be a cancel callback or a context object.'\n        );\n      }\n    }\n    return ret;\n  }\n\n  get ref(): Reference {\n    return this.getRef();\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 '@firebase/util';\nimport { Path } from './Path';\nimport { SparseSnapshotTree } from '../SparseSnapshotTree';\nimport { LeafNode } from '../snap/LeafNode';\nimport { nodeFromJSON } from '../snap/nodeFromJSON';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { Node } from '../snap/Node';\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { SyncTree } from '../SyncTree';\nimport { Indexable } from './misc';\n\n/* It's critical for performance that we do not calculate actual values from a SyncTree\n * unless and until the value is needed. Because we expose both a SyncTree and Node\n * version of deferred value resolution, we ned a wrapper class that will let us share\n * code.\n *\n * @see https://github.com/firebase/firebase-js-sdk/issues/2487\n */\ninterface ValueProvider {\n  getImmediateChild(childName: string): ValueProvider;\n  node(): Node;\n}\n\nclass ExistingValueProvider implements ValueProvider {\n  constructor(readonly node_: Node) {}\n\n  getImmediateChild(childName: string): ValueProvider {\n    const child = this.node_.getImmediateChild(childName);\n    return new ExistingValueProvider(child);\n  }\n\n  node(): Node {\n    return this.node_;\n  }\n}\n\nclass DeferredValueProvider implements ValueProvider {\n  private syncTree_: SyncTree;\n  private path_: Path;\n\n  constructor(syncTree: SyncTree, path: Path) {\n    this.syncTree_ = syncTree;\n    this.path_ = path;\n  }\n\n  getImmediateChild(childName: string): ValueProvider {\n    const childPath = this.path_.child(childName);\n    return new DeferredValueProvider(this.syncTree_, childPath);\n  }\n\n  node(): Node {\n    return this.syncTree_.calcCompleteEventCache(this.path_);\n  }\n}\n\n/**\n * Generate placeholders for deferred values.\n * @param {?Object} values\n * @return {!Object}\n */\nexport const generateWithValues = function (\n  values: {\n    [k: string]: unknown;\n  } | null\n): { [k: string]: unknown } {\n  values = values || {};\n  values['timestamp'] = values['timestamp'] || new Date().getTime();\n  return values;\n};\n\n/**\n * Value to use when firing local events. When writing server values, fire\n * local events with an approximate value, otherwise return value as-is.\n * @param {(Object|string|number|boolean)} value\n * @param {!Object} serverValues\n * @return {!(string|number|boolean)}\n */\nexport const resolveDeferredLeafValue = function (\n  value: { [k: string]: unknown } | string | number | boolean,\n  existingVal: ValueProvider,\n  serverValues: { [k: string]: unknown }\n): string | number | boolean {\n  if (!value || typeof value !== 'object') {\n    return value as string | number | boolean;\n  }\n  assert('.sv' in value, 'Unexpected leaf node or priority contents');\n\n  if (typeof value['.sv'] === 'string') {\n    return resolveScalarDeferredValue(value['.sv'], existingVal, serverValues);\n  } else if (typeof value['.sv'] === 'object') {\n    return resolveComplexDeferredValue(value['.sv'], existingVal, serverValues);\n  } else {\n    assert(false, 'Unexpected server value: ' + JSON.stringify(value, null, 2));\n  }\n};\n\nconst resolveScalarDeferredValue = function (\n  op: string,\n  existing: ValueProvider,\n  serverValues: { [k: string]: unknown }\n): string | number | boolean {\n  switch (op) {\n    case 'timestamp':\n      return serverValues['timestamp'] as string | number | boolean;\n    default:\n      assert(false, 'Unexpected server value: ' + op);\n  }\n};\n\nconst resolveComplexDeferredValue = function (\n  op: object,\n  existing: ValueProvider,\n  unused: { [k: string]: unknown }\n): string | number | boolean {\n  if (!op.hasOwnProperty('increment')) {\n    assert(false, 'Unexpected server value: ' + JSON.stringify(op, null, 2));\n  }\n  const delta = op['increment'];\n  if (typeof delta !== 'number') {\n    assert(false, 'Unexpected increment value: ' + delta);\n  }\n\n  const existingNode = existing.node();\n  assert(\n    existingNode !== null && typeof existingNode !== 'undefined',\n    'Expected ChildrenNode.EMPTY_NODE for nulls'\n  );\n\n  // Incrementing a non-number sets the value to the incremented amount\n  if (!existingNode.isLeafNode()) {\n    return delta;\n  }\n\n  const leaf = existingNode as LeafNode;\n  const existingVal = leaf.getValue();\n  if (typeof existingVal !== 'number') {\n    return delta;\n  }\n\n  // No need to do over/underflow arithmetic here because JS only handles floats under the covers\n  return existingVal + delta;\n};\n\n/**\n * Recursively replace all deferred values and priorities in the tree with the\n * specified generated replacement values.\n * @param {!Path} path path to which write is relative\n * @param {!Node} node new data written at path\n * @param {!SyncTree} syncTree current data\n * @param {!Object} serverValues\n * @return {!SparseSnapshotTree}\n */\nexport const resolveDeferredValueTree = function (\n  path: Path,\n  node: Node,\n  syncTree: SyncTree,\n  serverValues: Indexable\n): Node {\n  return resolveDeferredValue(\n    node,\n    new DeferredValueProvider(syncTree, path),\n    serverValues\n  );\n};\n\n/**\n * Recursively replace all deferred values and priorities in the node with the\n * specified generated replacement values.  If there are no server values in the node,\n * it'll be returned as-is.\n * @param {!Node} node\n * @param {!Object} serverValues\n * @return {!Node}\n */\nexport const resolveDeferredValueSnapshot = function (\n  node: Node,\n  existing: Node,\n  serverValues: Indexable\n): Node {\n  return resolveDeferredValue(\n    node,\n    new ExistingValueProvider(existing),\n    serverValues\n  );\n};\n\nfunction resolveDeferredValue(\n  node: Node,\n  existingVal: ValueProvider,\n  serverValues: Indexable\n): Node {\n  const rawPri = node.getPriority().val() as\n    | Indexable\n    | boolean\n    | null\n    | number\n    | string;\n  const priority = resolveDeferredLeafValue(\n    rawPri,\n    existingVal.getImmediateChild('.priority'),\n    serverValues\n  );\n  let newNode: Node;\n\n  if (node.isLeafNode()) {\n    const leafNode = node as LeafNode;\n    const value = resolveDeferredLeafValue(\n      leafNode.getValue(),\n      existingVal,\n      serverValues\n    );\n    if (\n      value !== leafNode.getValue() ||\n      priority !== leafNode.getPriority().val()\n    ) {\n      return new LeafNode(value, nodeFromJSON(priority));\n    } else {\n      return node;\n    }\n  } else {\n    const childrenNode = node as ChildrenNode;\n    newNode = childrenNode;\n    if (priority !== childrenNode.getPriority().val()) {\n      newNode = newNode.updatePriority(new LeafNode(priority));\n    }\n    childrenNode.forEachChild(PRIORITY_INDEX, (childName, childNode) => {\n      const newChildNode = resolveDeferredValue(\n        childNode,\n        existingVal.getImmediateChild(childName),\n        serverValues\n      );\n      if (newChildNode !== childNode) {\n        newNode = newNode.updateImmediateChild(childName, newChildNode);\n      }\n    });\n    return newNode;\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 { Path } from './util/Path';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { Node } from './snap/Node';\n\n/**\n * Helper class to store a sparse set of snapshots.\n */\nexport class SparseSnapshotTree {\n  private value: Node | null = null;\n\n  private readonly children: Map<string, SparseSnapshotTree> = new Map();\n\n  /**\n   * Gets the node stored at the given path if one exists.\n   *\n   * @param path Path to look up snapshot for.\n   * @return The retrieved node, or null.\n   */\n  find(path: Path): Node | null {\n    if (this.value != null) {\n      return this.value.getChild(path);\n    } else if (!path.isEmpty() && this.children.size > 0) {\n      const childKey = path.getFront();\n      path = path.popFront();\n      if (this.children.has(childKey)) {\n        const childTree = this.children.get(childKey);\n        return childTree.find(path);\n      } else {\n        return null;\n      }\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Stores the given node at the specified path. If there is already a node\n   * at a shallower path, it merges the new data into that snapshot node.\n   *\n   * @param path Path to look up snapshot for.\n   * @param data The new data, or null.\n   */\n  remember(path: Path, data: Node) {\n    if (path.isEmpty()) {\n      this.value = data;\n      this.children.clear();\n    } else if (this.value !== null) {\n      this.value = this.value.updateChild(path, data);\n    } else {\n      const childKey = path.getFront();\n      if (!this.children.has(childKey)) {\n        this.children.set(childKey, new SparseSnapshotTree());\n      }\n\n      const child = this.children.get(childKey);\n      path = path.popFront();\n      child.remember(path, data);\n    }\n  }\n\n  /**\n   * Purge the data at path from the cache.\n   *\n   * @param path Path to look up snapshot for.\n   * @return True if this node should now be removed.\n   */\n  forget(path: Path): boolean {\n    if (path.isEmpty()) {\n      this.value = null;\n      this.children.clear();\n      return true;\n    } else {\n      if (this.value !== null) {\n        if (this.value.isLeafNode()) {\n          // We're trying to forget a node that doesn't exist\n          return false;\n        } else {\n          const value = this.value;\n          this.value = null;\n\n          const self = this;\n          value.forEachChild(PRIORITY_INDEX, (key, tree) => {\n            self.remember(new Path(key), tree);\n          });\n\n          return this.forget(path);\n        }\n      } else if (this.children.size > 0) {\n        const childKey = path.getFront();\n        path = path.popFront();\n        if (this.children.has(childKey)) {\n          const safeToRemove = this.children.get(childKey).forget(path);\n          if (safeToRemove) {\n            this.children.delete(childKey);\n          }\n        }\n\n        return this.children.size === 0;\n      } else {\n        return true;\n      }\n    }\n  }\n\n  /**\n   * Recursively iterates through all of the stored tree and calls the\n   * callback on each one.\n   *\n   * @param prefixPath Path to look up node for.\n   * @param func The function to invoke for each tree.\n   */\n  forEachTree(prefixPath: Path, func: (a: Path, b: Node) => unknown) {\n    if (this.value !== null) {\n      func(prefixPath, this.value);\n    } else {\n      this.forEachChild((key, tree) => {\n        const path = new Path(prefixPath.toString() + '/' + key);\n        tree.forEachTree(path, func);\n      });\n    }\n  }\n\n  /**\n   * Iterates through each immediate child and triggers the callback.\n   *\n   * @param func The function to invoke for each child.\n   */\n  forEachChild(func: (a: string, b: SparseSnapshotTree) => void) {\n    this.children.forEach((tree, key) => {\n      func(key, tree);\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 '@firebase/util';\nimport { Path } from '../util/Path';\n\n/**\n *\n * @enum\n */\nexport enum OperationType {\n  OVERWRITE,\n  MERGE,\n  ACK_USER_WRITE,\n  LISTEN_COMPLETE\n}\n\n/**\n * @interface\n */\nexport interface Operation {\n  /**\n   * @type {!OperationSource}\n   */\n  source: OperationSource;\n\n  /**\n   * @type {!OperationType}\n   */\n  type: OperationType;\n\n  /**\n   * @type {!Path}\n   */\n  path: Path;\n\n  /**\n   * @param {string} childName\n   * @return {?Operation}\n   */\n  operationForChild(childName: string): Operation | null;\n}\n\n/**\n * @param {boolean} fromUser\n * @param {boolean} fromServer\n * @param {?string} queryId\n * @param {boolean} tagged\n * @constructor\n */\nexport class OperationSource {\n  constructor(\n    public fromUser: boolean,\n    public fromServer: boolean,\n    public queryId: string | null,\n    public tagged: boolean\n  ) {\n    assert(!tagged || fromServer, 'Tagged queries must be from server.');\n  }\n  /**\n   * @const\n   * @type {!OperationSource}\n   */\n  static User = new OperationSource(\n    /*fromUser=*/ true,\n    false,\n    null,\n    /*tagged=*/ false\n  );\n\n  /**\n   * @const\n   * @type {!OperationSource}\n   */\n  static Server = new OperationSource(\n    false,\n    /*fromServer=*/ true,\n    null,\n    /*tagged=*/ false\n  );\n\n  /**\n   * @param {string} queryId\n   * @return {!OperationSource}\n   */\n  static forServerTaggedQuery = function (queryId: string): OperationSource {\n    return new OperationSource(\n      false,\n      /*fromServer=*/ true,\n      queryId,\n      /*tagged=*/ true\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 '@firebase/util';\nimport { Path } from '../util/Path';\nimport { Operation, OperationSource, OperationType } from './Operation';\nimport { ImmutableTree } from '../util/ImmutableTree';\n\nexport class AckUserWrite implements Operation {\n  /** @inheritDoc */\n  type = OperationType.ACK_USER_WRITE;\n\n  /** @inheritDoc */\n  source = OperationSource.User;\n\n  /**\n   *\n   * @param {!Path} path\n   * @param {!ImmutableTree<!boolean>} affectedTree A tree containing true for each affected path. Affected paths can't overlap.\n   * @param {!boolean} revert\n   */\n  constructor(\n    /** @inheritDoc */ public path: Path,\n    /** @inheritDoc */ public affectedTree: ImmutableTree<boolean>,\n    /** @inheritDoc */ public revert: boolean\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  operationForChild(childName: string): AckUserWrite {\n    if (!this.path.isEmpty()) {\n      assert(\n        this.path.getFront() === childName,\n        'operationForChild called for unrelated child.'\n      );\n      return new AckUserWrite(\n        this.path.popFront(),\n        this.affectedTree,\n        this.revert\n      );\n    } else if (this.affectedTree.value != null) {\n      assert(\n        this.affectedTree.children.isEmpty(),\n        'affectedTree should not have overlapping affected paths.'\n      );\n      // All child locations are affected as well; just return same operation.\n      return this;\n    } else {\n      const childTree = this.affectedTree.subtree(new Path(childName));\n      return new AckUserWrite(Path.Empty, childTree, this.revert);\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 { SortedMap } from './SortedMap';\nimport { Path } from './Path';\nimport { stringCompare, each } from './util';\n\nlet emptyChildrenSingleton: SortedMap<string, ImmutableTree<null>>;\n\n/**\n * Singleton empty children collection.\n *\n * @const\n * @type {!SortedMap.<string, !ImmutableTree.<?>>}\n */\nconst EmptyChildren = (): SortedMap<string, ImmutableTree<null>> => {\n  if (!emptyChildrenSingleton) {\n    emptyChildrenSingleton = new SortedMap<string, ImmutableTree<null>>(\n      stringCompare\n    );\n  }\n  return emptyChildrenSingleton;\n};\n\n/**\n * A tree with immutable elements.\n */\nexport class ImmutableTree<T> {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  static Empty = new ImmutableTree<any>(null);\n\n  /**\n   * @template T\n   * @param {!Object.<string, !T>} obj\n   * @return {!ImmutableTree.<!T>}\n   */\n  static fromObject<T>(obj: { [k: string]: T }): ImmutableTree<T> {\n    let tree: ImmutableTree<T> = ImmutableTree.Empty;\n    each(obj, (childPath: string, childSnap: T) => {\n      tree = tree.set(new Path(childPath), childSnap);\n    });\n    return tree;\n  }\n\n  /**\n   * @template T\n   * @param {?T} value\n   * @param {SortedMap.<string, !ImmutableTree.<T>>=} children\n   */\n  constructor(\n    public readonly value: T | null,\n    public readonly children: SortedMap<\n      string,\n      ImmutableTree<T>\n    > = EmptyChildren()\n  ) {}\n\n  /**\n   * True if the value is empty and there are no children\n   * @return {boolean}\n   */\n  isEmpty(): boolean {\n    return this.value === null && this.children.isEmpty();\n  }\n\n  /**\n   * Given a path and predicate, return the first node and the path to that node\n   * where the predicate returns true.\n   *\n   * TODO Do a perf test -- If we're creating a bunch of {path: value:} objects\n   * on the way back out, it may be better to pass down a pathSoFar obj.\n   *\n   * @param {!Path} relativePath The remainder of the path\n   * @param {function(T):boolean} predicate The predicate to satisfy to return a\n   *   node\n   * @return {?{path:!Path, value:!T}}\n   */\n  findRootMostMatchingPathAndValue(\n    relativePath: Path,\n    predicate: (a: T) => boolean\n  ): { path: Path; value: T } | null {\n    if (this.value != null && predicate(this.value)) {\n      return { path: Path.Empty, value: this.value };\n    } else {\n      if (relativePath.isEmpty()) {\n        return null;\n      } else {\n        const front = relativePath.getFront();\n        const child = this.children.get(front);\n        if (child !== null) {\n          const childExistingPathAndValue = child.findRootMostMatchingPathAndValue(\n            relativePath.popFront(),\n            predicate\n          );\n          if (childExistingPathAndValue != null) {\n            const fullPath = new Path(front).child(\n              childExistingPathAndValue.path\n            );\n            return { path: fullPath, value: childExistingPathAndValue.value };\n          } else {\n            return null;\n          }\n        } else {\n          return null;\n        }\n      }\n    }\n  }\n\n  /**\n   * Find, if it exists, the shortest subpath of the given path that points a defined\n   * value in the tree\n   * @param {!Path} relativePath\n   * @return {?{path: !Path, value: !T}}\n   */\n  findRootMostValueAndPath(\n    relativePath: Path\n  ): { path: Path; value: T } | null {\n    return this.findRootMostMatchingPathAndValue(relativePath, () => true);\n  }\n\n  /**\n   * @param {!Path} relativePath\n   * @return {!ImmutableTree.<T>} The subtree at the given path\n   */\n  subtree(relativePath: Path): ImmutableTree<T> {\n    if (relativePath.isEmpty()) {\n      return this;\n    } else {\n      const front = relativePath.getFront();\n      const childTree = this.children.get(front);\n      if (childTree !== null) {\n        return childTree.subtree(relativePath.popFront());\n      } else {\n        return ImmutableTree.Empty;\n      }\n    }\n  }\n\n  /**\n   * Sets a value at the specified path.\n   *\n   * @param {!Path} relativePath Path to set value at.\n   * @param {?T} toSet Value to set.\n   * @return {!ImmutableTree.<T>} Resulting tree.\n   */\n  set(relativePath: Path, toSet: T | null): ImmutableTree<T> {\n    if (relativePath.isEmpty()) {\n      return new ImmutableTree(toSet, this.children);\n    } else {\n      const front = relativePath.getFront();\n      const child = this.children.get(front) || ImmutableTree.Empty;\n      const newChild = child.set(relativePath.popFront(), toSet);\n      const newChildren = this.children.insert(front, newChild);\n      return new ImmutableTree(this.value, newChildren);\n    }\n  }\n\n  /**\n   * Removes the value at the specified path.\n   *\n   * @param {!Path} relativePath Path to value to remove.\n   * @return {!ImmutableTree.<T>} Resulting tree.\n   */\n  remove(relativePath: Path): ImmutableTree<T> {\n    if (relativePath.isEmpty()) {\n      if (this.children.isEmpty()) {\n        return ImmutableTree.Empty;\n      } else {\n        return new ImmutableTree(null, this.children);\n      }\n    } else {\n      const front = relativePath.getFront();\n      const child = this.children.get(front);\n      if (child) {\n        const newChild = child.remove(relativePath.popFront());\n        let newChildren;\n        if (newChild.isEmpty()) {\n          newChildren = this.children.remove(front);\n        } else {\n          newChildren = this.children.insert(front, newChild);\n        }\n        if (this.value === null && newChildren.isEmpty()) {\n          return ImmutableTree.Empty;\n        } else {\n          return new ImmutableTree(this.value, newChildren);\n        }\n      } else {\n        return this;\n      }\n    }\n  }\n\n  /**\n   * Gets a value from the tree.\n   *\n   * @param {!Path} relativePath Path to get value for.\n   * @return {?T} Value at path, or null.\n   */\n  get(relativePath: Path): T | null {\n    if (relativePath.isEmpty()) {\n      return this.value;\n    } else {\n      const front = relativePath.getFront();\n      const child = this.children.get(front);\n      if (child) {\n        return child.get(relativePath.popFront());\n      } else {\n        return null;\n      }\n    }\n  }\n\n  /**\n   * Replace the subtree at the specified path with the given new tree.\n   *\n   * @param {!Path} relativePath Path to replace subtree for.\n   * @param {!ImmutableTree} newTree New tree.\n   * @return {!ImmutableTree} Resulting tree.\n   */\n  setTree(relativePath: Path, newTree: ImmutableTree<T>): ImmutableTree<T> {\n    if (relativePath.isEmpty()) {\n      return newTree;\n    } else {\n      const front = relativePath.getFront();\n      const child = this.children.get(front) || ImmutableTree.Empty;\n      const newChild = child.setTree(relativePath.popFront(), newTree);\n      let newChildren;\n      if (newChild.isEmpty()) {\n        newChildren = this.children.remove(front);\n      } else {\n        newChildren = this.children.insert(front, newChild);\n      }\n      return new ImmutableTree(this.value, newChildren);\n    }\n  }\n\n  /**\n   * Performs a depth first fold on this tree. Transforms a tree into a single\n   * value, given a function that operates on the path to a node, an optional\n   * current value, and a map of child names to folded subtrees\n   * @template V\n   * @param {function(Path, ?T, Object.<string, V>):V} fn\n   * @return {V}\n   */\n  fold<V>(fn: (path: Path, value: T, children: { [k: string]: V }) => V): V {\n    return this.fold_(Path.Empty, fn);\n  }\n\n  /**\n   * Recursive helper for public-facing fold() method\n   * @template V\n   * @param {!Path} pathSoFar\n   * @param {function(Path, ?T, Object.<string, V>):V} fn\n   * @return {V}\n   * @private\n   */\n  private fold_<V>(\n    pathSoFar: Path,\n    fn: (path: Path, value: T | null, children: { [k: string]: V }) => V\n  ): V {\n    const accum: { [k: string]: V } = {};\n    this.children.inorderTraversal(\n      (childKey: string, childTree: ImmutableTree<T>) => {\n        accum[childKey] = childTree.fold_(pathSoFar.child(childKey), fn);\n      }\n    );\n    return fn(pathSoFar, this.value, accum);\n  }\n\n  /**\n   * Find the first matching value on the given path. Return the result of applying f to it.\n   * @template V\n   * @param {!Path} path\n   * @param {!function(!Path, !T):?V} f\n   * @return {?V}\n   */\n  findOnPath<V>(path: Path, f: (path: Path, value: T) => V | null): V | null {\n    return this.findOnPath_(path, Path.Empty, f);\n  }\n\n  private findOnPath_<V>(\n    pathToFollow: Path,\n    pathSoFar: Path,\n    f: (path: Path, value: T) => V | null\n  ): V | null {\n    const result = this.value ? f(pathSoFar, this.value) : false;\n    if (result) {\n      return result;\n    } else {\n      if (pathToFollow.isEmpty()) {\n        return null;\n      } else {\n        const front = pathToFollow.getFront()!;\n        const nextChild = this.children.get(front);\n        if (nextChild) {\n          return nextChild.findOnPath_(\n            pathToFollow.popFront(),\n            pathSoFar.child(front),\n            f\n          );\n        } else {\n          return null;\n        }\n      }\n    }\n  }\n\n  /**\n   *\n   * @param {!Path} path\n   * @param {!function(!Path, !T)} f\n   * @returns {!ImmutableTree.<T>}\n   */\n  foreachOnPath(\n    path: Path,\n    f: (path: Path, value: T) => void\n  ): ImmutableTree<T> {\n    return this.foreachOnPath_(path, Path.Empty, f);\n  }\n\n  private foreachOnPath_(\n    pathToFollow: Path,\n    currentRelativePath: Path,\n    f: (path: Path, value: T) => void\n  ): ImmutableTree<T> {\n    if (pathToFollow.isEmpty()) {\n      return this;\n    } else {\n      if (this.value) {\n        f(currentRelativePath, this.value);\n      }\n      const front = pathToFollow.getFront();\n      const nextChild = this.children.get(front);\n      if (nextChild) {\n        return nextChild.foreachOnPath_(\n          pathToFollow.popFront(),\n          currentRelativePath.child(front),\n          f\n        );\n      } else {\n        return ImmutableTree.Empty;\n      }\n    }\n  }\n\n  /**\n   * Calls the given function for each node in the tree that has a value.\n   *\n   * @param {function(!Path, !T)} f A function to be called with\n   *   the path from the root of the tree to a node, and the value at that node.\n   *   Called in depth-first order.\n   */\n  foreach(f: (path: Path, value: T) => void) {\n    this.foreach_(Path.Empty, f);\n  }\n\n  private foreach_(\n    currentRelativePath: Path,\n    f: (path: Path, value: T) => void\n  ) {\n    this.children.inorderTraversal((childName, childTree) => {\n      childTree.foreach_(currentRelativePath.child(childName), f);\n    });\n    if (this.value) {\n      f(currentRelativePath, this.value);\n    }\n  }\n\n  /**\n   *\n   * @param {function(string, !T)} f\n   */\n  foreachChild(f: (name: string, value: T) => void) {\n    this.children.inorderTraversal(\n      (childName: string, childTree: ImmutableTree<T>) => {\n        if (childTree.value) {\n          f(childName, childTree.value);\n        }\n      }\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 { Path } from '../util/Path';\nimport { Operation, OperationSource, OperationType } from './Operation';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @constructor\n * @implements {Operation}\n */\nexport class ListenComplete implements Operation {\n  /** @inheritDoc */\n  type = OperationType.LISTEN_COMPLETE;\n\n  constructor(public source: OperationSource, public path: Path) {}\n\n  operationForChild(childName: string): ListenComplete {\n    if (this.path.isEmpty()) {\n      return new ListenComplete(this.source, Path.Empty);\n    } else {\n      return new ListenComplete(this.source, this.path.popFront());\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 { Operation, OperationSource, OperationType } from './Operation';\nimport { Path } from '../util/Path';\nimport { Node } from '../snap/Node';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @param {!Node} snap\n * @constructor\n * @implements {Operation}\n */\nexport class Overwrite implements Operation {\n  /** @inheritDoc */\n  type = OperationType.OVERWRITE;\n\n  constructor(\n    public source: OperationSource,\n    public path: Path,\n    public snap: Node\n  ) {}\n\n  operationForChild(childName: string): Overwrite {\n    if (this.path.isEmpty()) {\n      return new Overwrite(\n        this.source,\n        Path.Empty,\n        this.snap.getImmediateChild(childName)\n      );\n    } else {\n      return new Overwrite(this.source, this.path.popFront(), this.snap);\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 { Operation, OperationSource, OperationType } from './Operation';\nimport { Overwrite } from './Overwrite';\nimport { Path } from '../util/Path';\nimport { assert } from '@firebase/util';\nimport { ImmutableTree } from '../util/ImmutableTree';\nimport { Node } from '../snap/Node';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @param {!ImmutableTree.<!Node>} children\n * @constructor\n * @implements {Operation}\n */\nexport class Merge implements Operation {\n  /** @inheritDoc */\n  type = OperationType.MERGE;\n\n  constructor(\n    /** @inheritDoc */ public source: OperationSource,\n    /** @inheritDoc */ public path: Path,\n    /** @inheritDoc */ public children: ImmutableTree<Node>\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  operationForChild(childName: string): Operation {\n    if (this.path.isEmpty()) {\n      const childTree = this.children.subtree(new Path(childName));\n      if (childTree.isEmpty()) {\n        // This child is unaffected\n        return null;\n      } else if (childTree.value) {\n        // We have a snapshot for the child in question.  This becomes an overwrite of the child.\n        return new Overwrite(this.source, Path.Empty, childTree.value);\n      } else {\n        // This is a merge at a deeper level\n        return new Merge(this.source, Path.Empty, childTree);\n      }\n    } else {\n      assert(\n        this.path.getFront() === childName,\n        \"Can't get a merge for a child not on the path of the operation\"\n      );\n      return new Merge(this.source, this.path.popFront(), this.children);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  toString(): string {\n    return (\n      'Operation(' +\n      this.path +\n      ': ' +\n      this.source.toString() +\n      ' merge: ' +\n      this.children.toString() +\n      ')'\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 { Node } from '../snap/Node';\nimport { Path } from '../util/Path';\n\n/**\n * A cache node only stores complete children. Additionally it holds a flag whether the node can be considered fully\n * initialized in the sense that we know at one point in time this represented a valid state of the world, e.g.\n * initialized with data from the server, or a complete overwrite by the client. The filtered flag also tracks\n * whether a node potentially had children removed due to a filter.\n */\nexport class CacheNode {\n  /**\n   * @param {!Node} node_\n   * @param {boolean} fullyInitialized_\n   * @param {boolean} filtered_\n   */\n  constructor(\n    private node_: Node,\n    private fullyInitialized_: boolean,\n    private filtered_: boolean\n  ) {}\n\n  /**\n   * Returns whether this node was fully initialized with either server data or a complete overwrite by the client\n   * @return {boolean}\n   */\n  isFullyInitialized(): boolean {\n    return this.fullyInitialized_;\n  }\n\n  /**\n   * Returns whether this node is potentially missing children due to a filter applied to the node\n   * @return {boolean}\n   */\n  isFiltered(): boolean {\n    return this.filtered_;\n  }\n\n  /**\n   * @param {!Path} path\n   * @return {boolean}\n   */\n  isCompleteForPath(path: Path): boolean {\n    if (path.isEmpty()) {\n      return this.isFullyInitialized() && !this.filtered_;\n    }\n\n    const childKey = path.getFront();\n    return this.isCompleteForChild(childKey);\n  }\n\n  /**\n   * @param {!string} key\n   * @return {boolean}\n   */\n  isCompleteForChild(key: string): boolean {\n    return (\n      (this.isFullyInitialized() && !this.filtered_) || this.node_.hasChild(key)\n    );\n  }\n\n  /**\n   * @return {!Node}\n   */\n  getNode(): Node {\n    return this.node_;\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 { ChildrenNode } from '../snap/ChildrenNode';\nimport { CacheNode } from './CacheNode';\nimport { Node } from '../snap/Node';\n\n/**\n * Stores the data we have cached for a view.\n *\n * serverSnap is the cached server data, eventSnap is the cached event data (server data plus any local writes).\n *\n * @constructor\n */\nexport class ViewCache {\n  /**\n   *\n   * @param {!CacheNode} eventCache_\n   * @param {!CacheNode} serverCache_\n   */\n  constructor(\n    private readonly eventCache_: CacheNode,\n    private readonly serverCache_: CacheNode\n  ) {}\n\n  /**\n   * @const\n   * @type {ViewCache}\n   */\n  static Empty = new ViewCache(\n    new CacheNode(\n      ChildrenNode.EMPTY_NODE,\n      /*fullyInitialized=*/ false,\n      /*filtered=*/ false\n    ),\n    new CacheNode(\n      ChildrenNode.EMPTY_NODE,\n      /*fullyInitialized=*/ false,\n      /*filtered=*/ false\n    )\n  );\n\n  /**\n   * @param {!Node} eventSnap\n   * @param {boolean} complete\n   * @param {boolean} filtered\n   * @return {!ViewCache}\n   */\n  updateEventSnap(\n    eventSnap: Node,\n    complete: boolean,\n    filtered: boolean\n  ): ViewCache {\n    return new ViewCache(\n      new CacheNode(eventSnap, complete, filtered),\n      this.serverCache_\n    );\n  }\n\n  /**\n   * @param {!Node} serverSnap\n   * @param {boolean} complete\n   * @param {boolean} filtered\n   * @return {!ViewCache}\n   */\n  updateServerSnap(\n    serverSnap: Node,\n    complete: boolean,\n    filtered: boolean\n  ): ViewCache {\n    return new ViewCache(\n      this.eventCache_,\n      new CacheNode(serverSnap, complete, filtered)\n    );\n  }\n\n  /**\n   * @return {!CacheNode}\n   */\n  getEventCache(): CacheNode {\n    return this.eventCache_;\n  }\n\n  /**\n   * @return {?Node}\n   */\n  getCompleteEventSnap(): Node | null {\n    return this.eventCache_.isFullyInitialized()\n      ? this.eventCache_.getNode()\n      : null;\n  }\n\n  /**\n   * @return {!CacheNode}\n   */\n  getServerCache(): CacheNode {\n    return this.serverCache_;\n  }\n\n  /**\n   * @return {?Node}\n   */\n  getCompleteServerSnap(): Node | null {\n    return this.serverCache_.isFullyInitialized()\n      ? this.serverCache_.getNode()\n      : null;\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 { Node } from '../snap/Node';\n\n/**\n * @constructor\n * @struct\n * @param {!string} type The event type\n * @param {!Node} snapshotNode The data\n * @param {string=} childName The name for this child, if it's a child event\n * @param {Node=} oldSnap Used for intermediate processing of child changed events\n * @param {string=} prevName The name for the previous child, if applicable\n */\nexport class Change {\n  constructor(\n    public type: string,\n    public snapshotNode: Node,\n    public childName?: string,\n    public oldSnap?: Node,\n    public prevName?: string | null\n  ) {}\n\n  /**\n   * @param {!Node} snapshot\n   * @return {!Change}\n   */\n  static valueChange(snapshot: Node): Change {\n    return new Change(Change.VALUE, snapshot);\n  }\n\n  /**\n   * @param {string} childKey\n   * @param {!Node} snapshot\n   * @return {!Change}\n   */\n  static childAddedChange(childKey: string, snapshot: Node): Change {\n    return new Change(Change.CHILD_ADDED, snapshot, childKey);\n  }\n\n  /**\n   * @param {string} childKey\n   * @param {!Node} snapshot\n   * @return {!Change}\n   */\n  static childRemovedChange(childKey: string, snapshot: Node): Change {\n    return new Change(Change.CHILD_REMOVED, snapshot, childKey);\n  }\n\n  /**\n   * @param {string} childKey\n   * @param {!Node} newSnapshot\n   * @param {!Node} oldSnapshot\n   * @return {!Change}\n   */\n  static childChangedChange(\n    childKey: string,\n    newSnapshot: Node,\n    oldSnapshot: Node\n  ): Change {\n    return new Change(Change.CHILD_CHANGED, newSnapshot, childKey, oldSnapshot);\n  }\n\n  /**\n   * @param {string} childKey\n   * @param {!Node} snapshot\n   * @return {!Change}\n   */\n  static childMovedChange(childKey: string, snapshot: Node): Change {\n    return new Change(Change.CHILD_MOVED, snapshot, childKey);\n  }\n\n  //event types\n  /** Event type for a child added */\n  static CHILD_ADDED = 'child_added';\n\n  /** Event type for a child removed */\n  static CHILD_REMOVED = 'child_removed';\n\n  /** Event type for a child changed */\n  static CHILD_CHANGED = 'child_changed';\n\n  /** Event type for a child moved */\n  static CHILD_MOVED = 'child_moved';\n\n  /** Event type for a value change */\n  static VALUE = 'value';\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 '@firebase/util';\nimport { Change } from '../Change';\nimport { ChildrenNode } from '../../snap/ChildrenNode';\nimport { PRIORITY_INDEX } from '../../snap/indexes/PriorityIndex';\nimport { NodeFilter } from './NodeFilter';\nimport { Index } from '../../snap/indexes/Index';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\nimport { Node } from '../../snap/Node';\n\n/**\n * Doesn't really filter nodes but applies an index to the node and keeps track of any changes\n *\n * @constructor\n * @implements {NodeFilter}\n * @param {!Index} index\n */\nexport class IndexedFilter implements NodeFilter {\n  constructor(private readonly index_: Index) {}\n\n  updateChild(\n    snap: Node,\n    key: string,\n    newChild: Node,\n    affectedPath: Path,\n    source: CompleteChildSource,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    assert(\n      snap.isIndexed(this.index_),\n      'A node must be indexed if only a child is updated'\n    );\n    const oldChild = snap.getImmediateChild(key);\n    // Check if anything actually changed.\n    if (\n      oldChild.getChild(affectedPath).equals(newChild.getChild(affectedPath))\n    ) {\n      // There's an edge case where a child can enter or leave the view because affectedPath was set to null.\n      // In this case, affectedPath will appear null in both the old and new snapshots.  So we need\n      // to avoid treating these cases as \"nothing changed.\"\n      if (oldChild.isEmpty() === newChild.isEmpty()) {\n        // Nothing changed.\n\n        // This assert should be valid, but it's expensive (can dominate perf testing) so don't actually do it.\n        //assert(oldChild.equals(newChild), 'Old and new snapshots should be equal.');\n        return snap;\n      }\n    }\n\n    if (optChangeAccumulator != null) {\n      if (newChild.isEmpty()) {\n        if (snap.hasChild(key)) {\n          optChangeAccumulator.trackChildChange(\n            Change.childRemovedChange(key, oldChild)\n          );\n        } else {\n          assert(\n            snap.isLeafNode(),\n            'A child remove without an old child only makes sense on a leaf node'\n          );\n        }\n      } else if (oldChild.isEmpty()) {\n        optChangeAccumulator.trackChildChange(\n          Change.childAddedChange(key, newChild)\n        );\n      } else {\n        optChangeAccumulator.trackChildChange(\n          Change.childChangedChange(key, newChild, oldChild)\n        );\n      }\n    }\n    if (snap.isLeafNode() && newChild.isEmpty()) {\n      return snap;\n    } else {\n      // Make sure the node is indexed\n      return snap.updateImmediateChild(key, newChild).withIndex(this.index_);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updateFullNode(\n    oldSnap: Node,\n    newSnap: Node,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    if (optChangeAccumulator != null) {\n      if (!oldSnap.isLeafNode()) {\n        oldSnap.forEachChild(PRIORITY_INDEX, (key, childNode) => {\n          if (!newSnap.hasChild(key)) {\n            optChangeAccumulator.trackChildChange(\n              Change.childRemovedChange(key, childNode)\n            );\n          }\n        });\n      }\n      if (!newSnap.isLeafNode()) {\n        newSnap.forEachChild(PRIORITY_INDEX, (key, childNode) => {\n          if (oldSnap.hasChild(key)) {\n            const oldChild = oldSnap.getImmediateChild(key);\n            if (!oldChild.equals(childNode)) {\n              optChangeAccumulator.trackChildChange(\n                Change.childChangedChange(key, childNode, oldChild)\n              );\n            }\n          } else {\n            optChangeAccumulator.trackChildChange(\n              Change.childAddedChange(key, childNode)\n            );\n          }\n        });\n      }\n    }\n    return newSnap.withIndex(this.index_);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updatePriority(oldSnap: Node, newPriority: Node): Node {\n    if (oldSnap.isEmpty()) {\n      return ChildrenNode.EMPTY_NODE;\n    } else {\n      return oldSnap.updatePriority(newPriority);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  filtersNodes(): boolean {\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndexedFilter(): IndexedFilter {\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndex(): Index {\n    return this.index_;\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 { Change } from './Change';\nimport { assert, assertionError } from '@firebase/util';\n\nexport class ChildChangeAccumulator {\n  private readonly changeMap: Map<string, Change> = new Map();\n\n  trackChildChange(change: Change) {\n    const type = change.type;\n    const childKey = change.childName!;\n    assert(\n      type === Change.CHILD_ADDED ||\n        type === Change.CHILD_CHANGED ||\n        type === Change.CHILD_REMOVED,\n      'Only child changes supported for tracking'\n    );\n    assert(\n      childKey !== '.priority',\n      'Only non-priority child changes can be tracked.'\n    );\n    const oldChange = this.changeMap.get(childKey);\n    if (oldChange) {\n      const oldType = oldChange.type;\n      if (type === Change.CHILD_ADDED && oldType === Change.CHILD_REMOVED) {\n        this.changeMap.set(\n          childKey,\n          Change.childChangedChange(\n            childKey,\n            change.snapshotNode,\n            oldChange.snapshotNode\n          )\n        );\n      } else if (\n        type === Change.CHILD_REMOVED &&\n        oldType === Change.CHILD_ADDED\n      ) {\n        this.changeMap.delete(childKey);\n      } else if (\n        type === Change.CHILD_REMOVED &&\n        oldType === Change.CHILD_CHANGED\n      ) {\n        this.changeMap.set(\n          childKey,\n          Change.childRemovedChange(childKey, oldChange.oldSnap)\n        );\n      } else if (\n        type === Change.CHILD_CHANGED &&\n        oldType === Change.CHILD_ADDED\n      ) {\n        this.changeMap.set(\n          childKey,\n          Change.childAddedChange(childKey, change.snapshotNode)\n        );\n      } else if (\n        type === Change.CHILD_CHANGED &&\n        oldType === Change.CHILD_CHANGED\n      ) {\n        this.changeMap.set(\n          childKey,\n          Change.childChangedChange(\n            childKey,\n            change.snapshotNode,\n            oldChange.oldSnap\n          )\n        );\n      } else {\n        throw assertionError(\n          'Illegal combination of changes: ' +\n            change +\n            ' occurred after ' +\n            oldChange\n        );\n      }\n    } else {\n      this.changeMap.set(childKey, change);\n    }\n  }\n\n  getChanges(): Change[] {\n    return Array.from(this.changeMap.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\nimport { CacheNode } from './CacheNode';\nimport { NamedNode, Node } from '../snap/Node';\nimport { Index } from '../snap/indexes/Index';\nimport { WriteTreeRef } from '../WriteTree';\nimport { ViewCache } from './ViewCache';\n\n/**\n * Since updates to filtered nodes might require nodes to be pulled in from \"outside\" the node, this interface\n * can help to get complete children that can be pulled in.\n * A class implementing this interface takes potentially multiple sources (e.g. user writes, server data from\n * other views etc.) to try it's best to get a complete child that might be useful in pulling into the view.\n *\n * @interface\n */\nexport interface CompleteChildSource {\n  /**\n   * @param {!string} childKey\n   * @return {?Node}\n   */\n  getCompleteChild(childKey: string): Node | null;\n\n  /**\n   * @param {!Index} index\n   * @param {!NamedNode} child\n   * @param {boolean} reverse\n   * @return {?NamedNode}\n   */\n  getChildAfterChild(\n    index: Index,\n    child: NamedNode,\n    reverse: boolean\n  ): NamedNode | null;\n}\n\n/**\n * An implementation of CompleteChildSource that never returns any additional children\n *\n * @private\n * @constructor\n * @implements CompleteChildSource\n */\n// eslint-disable-next-line @typescript-eslint/class-name-casing\nexport class NoCompleteChildSource_ implements CompleteChildSource {\n  /**\n   * @inheritDoc\n   */\n  getCompleteChild(childKey?: string): Node | null {\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getChildAfterChild(\n    index?: Index,\n    child?: NamedNode,\n    reverse?: boolean\n  ): NamedNode | null {\n    return null;\n  }\n}\n\n/**\n * Singleton instance.\n * @const\n * @type {!CompleteChildSource}\n */\nexport const NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_();\n\n/**\n * An implementation of CompleteChildSource that uses a WriteTree in addition to any other server data or\n * old event caches available to calculate complete children.\n *\n *\n * @implements CompleteChildSource\n */\nexport class WriteTreeCompleteChildSource implements CompleteChildSource {\n  /**\n   * @param {!WriteTreeRef} writes_\n   * @param {!ViewCache} viewCache_\n   * @param {?Node} optCompleteServerCache_\n   */\n  constructor(\n    private writes_: WriteTreeRef,\n    private viewCache_: ViewCache,\n    private optCompleteServerCache_: Node | null = null\n  ) {}\n\n  /**\n   * @inheritDoc\n   */\n  getCompleteChild(childKey: string): Node | null {\n    const node = this.viewCache_.getEventCache();\n    if (node.isCompleteForChild(childKey)) {\n      return node.getNode().getImmediateChild(childKey);\n    } else {\n      const serverNode =\n        this.optCompleteServerCache_ != null\n          ? new CacheNode(this.optCompleteServerCache_, true, false)\n          : this.viewCache_.getServerCache();\n      return this.writes_.calcCompleteChild(childKey, serverNode);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getChildAfterChild(\n    index: Index,\n    child: NamedNode,\n    reverse: boolean\n  ): NamedNode | null {\n    const completeServerData =\n      this.optCompleteServerCache_ != null\n        ? this.optCompleteServerCache_\n        : this.viewCache_.getCompleteServerSnap();\n    const nodes = this.writes_.calcIndexedSlice(\n      completeServerData,\n      child,\n      1,\n      reverse,\n      index\n    );\n    if (nodes.length === 0) {\n      return null;\n    } else {\n      return nodes[0];\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 { Operation, OperationType } from '../operation/Operation';\nimport { assert, assertionError } from '@firebase/util';\nimport { ChildChangeAccumulator } from './ChildChangeAccumulator';\nimport { Change } from './Change';\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { KEY_INDEX } from '../snap/indexes/KeyIndex';\nimport { ImmutableTree } from '../util/ImmutableTree';\nimport { Path } from '../util/Path';\nimport {\n  WriteTreeCompleteChildSource,\n  NO_COMPLETE_CHILD_SOURCE,\n  CompleteChildSource\n} from './CompleteChildSource';\nimport { ViewCache } from './ViewCache';\nimport { NodeFilter } from './filter/NodeFilter';\nimport { WriteTreeRef } from '../WriteTree';\nimport { Overwrite } from '../operation/Overwrite';\nimport { Merge } from '../operation/Merge';\nimport { AckUserWrite } from '../operation/AckUserWrite';\nimport { Node } from '../snap/Node';\n\n/**\n * @constructor\n * @struct\n */\nexport class ProcessorResult {\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Array.<!Change>} changes\n   */\n  constructor(\n    public readonly viewCache: ViewCache,\n    public readonly changes: Change[]\n  ) {}\n}\n\n/**\n * @constructor\n */\nexport class ViewProcessor {\n  /**\n   * @param {!NodeFilter} filter_\n   */\n  constructor(private readonly filter_: NodeFilter) {}\n\n  /**\n   * @param {!ViewCache} viewCache\n   */\n  assertIndexed(viewCache: ViewCache) {\n    assert(\n      viewCache.getEventCache().getNode().isIndexed(this.filter_.getIndex()),\n      'Event snap not indexed'\n    );\n    assert(\n      viewCache.getServerCache().getNode().isIndexed(this.filter_.getIndex()),\n      'Server snap not indexed'\n    );\n  }\n\n  /**\n   * @param {!ViewCache} oldViewCache\n   * @param {!Operation} operation\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeCache\n   * @return {!ProcessorResult}\n   */\n  applyOperation(\n    oldViewCache: ViewCache,\n    operation: Operation,\n    writesCache: WriteTreeRef,\n    completeCache: Node | null\n  ): ProcessorResult {\n    const accumulator = new ChildChangeAccumulator();\n    let newViewCache, filterServerNode;\n    if (operation.type === OperationType.OVERWRITE) {\n      const overwrite = operation as Overwrite;\n      if (overwrite.source.fromUser) {\n        newViewCache = this.applyUserOverwrite_(\n          oldViewCache,\n          overwrite.path,\n          overwrite.snap,\n          writesCache,\n          completeCache,\n          accumulator\n        );\n      } else {\n        assert(overwrite.source.fromServer, 'Unknown source.');\n        // We filter the node if it's a tagged update or the node has been previously filtered  and the\n        // update is not at the root in which case it is ok (and necessary) to mark the node unfiltered\n        // again\n        filterServerNode =\n          overwrite.source.tagged ||\n          (oldViewCache.getServerCache().isFiltered() &&\n            !overwrite.path.isEmpty());\n        newViewCache = this.applyServerOverwrite_(\n          oldViewCache,\n          overwrite.path,\n          overwrite.snap,\n          writesCache,\n          completeCache,\n          filterServerNode,\n          accumulator\n        );\n      }\n    } else if (operation.type === OperationType.MERGE) {\n      const merge = operation as Merge;\n      if (merge.source.fromUser) {\n        newViewCache = this.applyUserMerge_(\n          oldViewCache,\n          merge.path,\n          merge.children,\n          writesCache,\n          completeCache,\n          accumulator\n        );\n      } else {\n        assert(merge.source.fromServer, 'Unknown source.');\n        // We filter the node if it's a tagged update or the node has been previously filtered\n        filterServerNode =\n          merge.source.tagged || oldViewCache.getServerCache().isFiltered();\n        newViewCache = this.applyServerMerge_(\n          oldViewCache,\n          merge.path,\n          merge.children,\n          writesCache,\n          completeCache,\n          filterServerNode,\n          accumulator\n        );\n      }\n    } else if (operation.type === OperationType.ACK_USER_WRITE) {\n      const ackUserWrite = operation as AckUserWrite;\n      if (!ackUserWrite.revert) {\n        newViewCache = this.ackUserWrite_(\n          oldViewCache,\n          ackUserWrite.path,\n          ackUserWrite.affectedTree,\n          writesCache,\n          completeCache,\n          accumulator\n        );\n      } else {\n        newViewCache = this.revertUserWrite_(\n          oldViewCache,\n          ackUserWrite.path,\n          writesCache,\n          completeCache,\n          accumulator\n        );\n      }\n    } else if (operation.type === OperationType.LISTEN_COMPLETE) {\n      newViewCache = this.listenComplete_(\n        oldViewCache,\n        operation.path,\n        writesCache,\n        accumulator\n      );\n    } else {\n      throw assertionError('Unknown operation type: ' + operation.type);\n    }\n    const changes = accumulator.getChanges();\n    ViewProcessor.maybeAddValueEvent_(oldViewCache, newViewCache, changes);\n    return new ProcessorResult(newViewCache, changes);\n  }\n\n  /**\n   * @param {!ViewCache} oldViewCache\n   * @param {!ViewCache} newViewCache\n   * @param {!Array.<!Change>} accumulator\n   * @private\n   */\n  private static maybeAddValueEvent_(\n    oldViewCache: ViewCache,\n    newViewCache: ViewCache,\n    accumulator: Change[]\n  ) {\n    const eventSnap = newViewCache.getEventCache();\n    if (eventSnap.isFullyInitialized()) {\n      const isLeafOrEmpty =\n        eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();\n      const oldCompleteSnap = oldViewCache.getCompleteEventSnap();\n      if (\n        accumulator.length > 0 ||\n        !oldViewCache.getEventCache().isFullyInitialized() ||\n        (isLeafOrEmpty &&\n          !eventSnap.getNode().equals(/** @type {!Node} */ oldCompleteSnap)) ||\n        !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())\n      ) {\n        accumulator.push(\n          Change.valueChange(\n            /** @type {!Node} */ newViewCache.getCompleteEventSnap()\n          )\n        );\n      }\n    }\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} changePath\n   * @param {!WriteTreeRef} writesCache\n   * @param {!CompleteChildSource} source\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private generateEventCacheAfterServerEvent_(\n    viewCache: ViewCache,\n    changePath: Path,\n    writesCache: WriteTreeRef,\n    source: CompleteChildSource,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    const oldEventSnap = viewCache.getEventCache();\n    if (writesCache.shadowingWrite(changePath) != null) {\n      // we have a shadowing write, ignore changes\n      return viewCache;\n    } else {\n      let newEventCache, serverNode;\n      if (changePath.isEmpty()) {\n        // TODO: figure out how this plays with \"sliding ack windows\"\n        assert(\n          viewCache.getServerCache().isFullyInitialized(),\n          'If change path is empty, we must have complete server data'\n        );\n        if (viewCache.getServerCache().isFiltered()) {\n          // We need to special case this, because we need to only apply writes to complete children, or\n          // we might end up raising events for incomplete children. If the server data is filtered deep\n          // writes cannot be guaranteed to be complete\n          const serverCache = viewCache.getCompleteServerSnap();\n          const completeChildren =\n            serverCache instanceof ChildrenNode\n              ? serverCache\n              : ChildrenNode.EMPTY_NODE;\n          const completeEventChildren = writesCache.calcCompleteEventChildren(\n            completeChildren\n          );\n          newEventCache = this.filter_.updateFullNode(\n            viewCache.getEventCache().getNode(),\n            completeEventChildren,\n            accumulator\n          );\n        } else {\n          const completeNode = writesCache.calcCompleteEventCache(\n            viewCache.getCompleteServerSnap()\n          );\n          newEventCache = this.filter_.updateFullNode(\n            viewCache.getEventCache().getNode(),\n            completeNode,\n            accumulator\n          );\n        }\n      } else {\n        const childKey = changePath.getFront();\n        if (childKey === '.priority') {\n          assert(\n            changePath.getLength() === 1,\n            \"Can't have a priority with additional path components\"\n          );\n          const oldEventNode = oldEventSnap.getNode();\n          serverNode = viewCache.getServerCache().getNode();\n          // we might have overwrites for this priority\n          const updatedPriority = writesCache.calcEventCacheAfterServerOverwrite(\n            changePath,\n            oldEventNode,\n            serverNode\n          );\n          if (updatedPriority != null) {\n            newEventCache = this.filter_.updatePriority(\n              oldEventNode,\n              updatedPriority\n            );\n          } else {\n            // priority didn't change, keep old node\n            newEventCache = oldEventSnap.getNode();\n          }\n        } else {\n          const childChangePath = changePath.popFront();\n          // update child\n          let newEventChild;\n          if (oldEventSnap.isCompleteForChild(childKey)) {\n            serverNode = viewCache.getServerCache().getNode();\n            const eventChildUpdate = writesCache.calcEventCacheAfterServerOverwrite(\n              changePath,\n              oldEventSnap.getNode(),\n              serverNode\n            );\n            if (eventChildUpdate != null) {\n              newEventChild = oldEventSnap\n                .getNode()\n                .getImmediateChild(childKey)\n                .updateChild(childChangePath, eventChildUpdate);\n            } else {\n              // Nothing changed, just keep the old child\n              newEventChild = oldEventSnap\n                .getNode()\n                .getImmediateChild(childKey);\n            }\n          } else {\n            newEventChild = writesCache.calcCompleteChild(\n              childKey,\n              viewCache.getServerCache()\n            );\n          }\n          if (newEventChild != null) {\n            newEventCache = this.filter_.updateChild(\n              oldEventSnap.getNode(),\n              childKey,\n              newEventChild,\n              childChangePath,\n              source,\n              accumulator\n            );\n          } else {\n            // no complete child available or no change\n            newEventCache = oldEventSnap.getNode();\n          }\n        }\n      }\n      return viewCache.updateEventSnap(\n        newEventCache,\n        oldEventSnap.isFullyInitialized() || changePath.isEmpty(),\n        this.filter_.filtersNodes()\n      );\n    }\n  }\n\n  /**\n   * @param {!ViewCache} oldViewCache\n   * @param {!Path} changePath\n   * @param {!Node} changedSnap\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeCache\n   * @param {boolean} filterServerNode\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  applyServerOverwrite_(\n    oldViewCache: ViewCache,\n    changePath: Path,\n    changedSnap: Node,\n    writesCache: WriteTreeRef,\n    completeCache: Node | null,\n    filterServerNode: boolean,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    const oldServerSnap = oldViewCache.getServerCache();\n    let newServerCache;\n    const serverFilter = filterServerNode\n      ? this.filter_\n      : this.filter_.getIndexedFilter();\n    if (changePath.isEmpty()) {\n      newServerCache = serverFilter.updateFullNode(\n        oldServerSnap.getNode(),\n        changedSnap,\n        null\n      );\n    } else if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) {\n      // we want to filter the server node, but we didn't filter the server node yet, so simulate a full update\n      const newServerNode = oldServerSnap\n        .getNode()\n        .updateChild(changePath, changedSnap);\n      newServerCache = serverFilter.updateFullNode(\n        oldServerSnap.getNode(),\n        newServerNode,\n        null\n      );\n    } else {\n      const childKey = changePath.getFront();\n      if (\n        !oldServerSnap.isCompleteForPath(changePath) &&\n        changePath.getLength() > 1\n      ) {\n        // We don't update incomplete nodes with updates intended for other listeners\n        return oldViewCache;\n      }\n      const childChangePath = changePath.popFront();\n      const childNode = oldServerSnap.getNode().getImmediateChild(childKey);\n      const newChildNode = childNode.updateChild(childChangePath, changedSnap);\n      if (childKey === '.priority') {\n        newServerCache = serverFilter.updatePriority(\n          oldServerSnap.getNode(),\n          newChildNode\n        );\n      } else {\n        newServerCache = serverFilter.updateChild(\n          oldServerSnap.getNode(),\n          childKey,\n          newChildNode,\n          childChangePath,\n          NO_COMPLETE_CHILD_SOURCE,\n          null\n        );\n      }\n    }\n    const newViewCache = oldViewCache.updateServerSnap(\n      newServerCache,\n      oldServerSnap.isFullyInitialized() || changePath.isEmpty(),\n      serverFilter.filtersNodes()\n    );\n    const source = new WriteTreeCompleteChildSource(\n      writesCache,\n      newViewCache,\n      completeCache\n    );\n    return this.generateEventCacheAfterServerEvent_(\n      newViewCache,\n      changePath,\n      writesCache,\n      source,\n      accumulator\n    );\n  }\n\n  /**\n   * @param {!ViewCache} oldViewCache\n   * @param {!Path} changePath\n   * @param {!Node} changedSnap\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeCache\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  applyUserOverwrite_(\n    oldViewCache: ViewCache,\n    changePath: Path,\n    changedSnap: Node,\n    writesCache: WriteTreeRef,\n    completeCache: Node | null,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    const oldEventSnap = oldViewCache.getEventCache();\n    let newViewCache, newEventCache;\n    const source = new WriteTreeCompleteChildSource(\n      writesCache,\n      oldViewCache,\n      completeCache\n    );\n    if (changePath.isEmpty()) {\n      newEventCache = this.filter_.updateFullNode(\n        oldViewCache.getEventCache().getNode(),\n        changedSnap,\n        accumulator\n      );\n      newViewCache = oldViewCache.updateEventSnap(\n        newEventCache,\n        true,\n        this.filter_.filtersNodes()\n      );\n    } else {\n      const childKey = changePath.getFront();\n      if (childKey === '.priority') {\n        newEventCache = this.filter_.updatePriority(\n          oldViewCache.getEventCache().getNode(),\n          changedSnap\n        );\n        newViewCache = oldViewCache.updateEventSnap(\n          newEventCache,\n          oldEventSnap.isFullyInitialized(),\n          oldEventSnap.isFiltered()\n        );\n      } else {\n        const childChangePath = changePath.popFront();\n        const oldChild = oldEventSnap.getNode().getImmediateChild(childKey);\n        let newChild;\n        if (childChangePath.isEmpty()) {\n          // Child overwrite, we can replace the child\n          newChild = changedSnap;\n        } else {\n          const childNode = source.getCompleteChild(childKey);\n          if (childNode != null) {\n            if (\n              childChangePath.getBack() === '.priority' &&\n              childNode.getChild(childChangePath.parent()).isEmpty()\n            ) {\n              // This is a priority update on an empty node. If this node exists on the server, the\n              // server will send down the priority in the update, so ignore for now\n              newChild = childNode;\n            } else {\n              newChild = childNode.updateChild(childChangePath, changedSnap);\n            }\n          } else {\n            // There is no complete child node available\n            newChild = ChildrenNode.EMPTY_NODE;\n          }\n        }\n        if (!oldChild.equals(newChild)) {\n          const newEventSnap = this.filter_.updateChild(\n            oldEventSnap.getNode(),\n            childKey,\n            newChild,\n            childChangePath,\n            source,\n            accumulator\n          );\n          newViewCache = oldViewCache.updateEventSnap(\n            newEventSnap,\n            oldEventSnap.isFullyInitialized(),\n            this.filter_.filtersNodes()\n          );\n        } else {\n          newViewCache = oldViewCache;\n        }\n      }\n    }\n    return newViewCache;\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {string} childKey\n   * @return {boolean}\n   * @private\n   */\n  private static cacheHasChild_(\n    viewCache: ViewCache,\n    childKey: string\n  ): boolean {\n    return viewCache.getEventCache().isCompleteForChild(childKey);\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} path\n   * @param {ImmutableTree.<!Node>} changedChildren\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} serverCache\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private applyUserMerge_(\n    viewCache: ViewCache,\n    path: Path,\n    changedChildren: ImmutableTree<Node>,\n    writesCache: WriteTreeRef,\n    serverCache: Node | null,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    // HACK: In the case of a limit query, there may be some changes that bump things out of the\n    // window leaving room for new items.  It's important we process these changes first, so we\n    // iterate the changes twice, first processing any that affect items currently in view.\n    // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\n    // and event snap.  I'm not sure if this will result in edge cases when a child is in one but\n    // not the other.\n    let curViewCache = viewCache;\n    changedChildren.foreach((relativePath, childNode) => {\n      const writePath = path.child(relativePath);\n      if (ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n        curViewCache = this.applyUserOverwrite_(\n          curViewCache,\n          writePath,\n          childNode,\n          writesCache,\n          serverCache,\n          accumulator\n        );\n      }\n    });\n\n    changedChildren.foreach((relativePath, childNode) => {\n      const writePath = path.child(relativePath);\n      if (!ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n        curViewCache = this.applyUserOverwrite_(\n          curViewCache,\n          writePath,\n          childNode,\n          writesCache,\n          serverCache,\n          accumulator\n        );\n      }\n    });\n\n    return curViewCache;\n  }\n\n  /**\n   * @param {!Node} node\n   * @param {ImmutableTree.<!Node>} merge\n   * @return {!Node}\n   * @private\n   */\n  private applyMerge_(node: Node, merge: ImmutableTree<Node>): Node {\n    merge.foreach((relativePath, childNode) => {\n      node = node.updateChild(relativePath, childNode);\n    });\n    return node;\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} path\n   * @param {!ImmutableTree.<!Node>} changedChildren\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} serverCache\n   * @param {boolean} filterServerNode\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private applyServerMerge_(\n    viewCache: ViewCache,\n    path: Path,\n    changedChildren: ImmutableTree<Node>,\n    writesCache: WriteTreeRef,\n    serverCache: Node | null,\n    filterServerNode: boolean,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    // If we don't have a cache yet, this merge was intended for a previously listen in the same location. Ignore it and\n    // wait for the complete data update coming soon.\n    if (\n      viewCache.getServerCache().getNode().isEmpty() &&\n      !viewCache.getServerCache().isFullyInitialized()\n    ) {\n      return viewCache;\n    }\n\n    // HACK: In the case of a limit query, there may be some changes that bump things out of the\n    // window leaving room for new items.  It's important we process these changes first, so we\n    // iterate the changes twice, first processing any that affect items currently in view.\n    // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\n    // and event snap.  I'm not sure if this will result in edge cases when a child is in one but\n    // not the other.\n    let curViewCache = viewCache;\n    let viewMergeTree;\n    if (path.isEmpty()) {\n      viewMergeTree = changedChildren;\n    } else {\n      viewMergeTree = ImmutableTree.Empty.setTree(path, changedChildren);\n    }\n    const serverNode = viewCache.getServerCache().getNode();\n    viewMergeTree.children.inorderTraversal((childKey, childTree) => {\n      if (serverNode.hasChild(childKey)) {\n        const serverChild = viewCache\n          .getServerCache()\n          .getNode()\n          .getImmediateChild(childKey);\n        const newChild = this.applyMerge_(serverChild, childTree);\n        curViewCache = this.applyServerOverwrite_(\n          curViewCache,\n          new Path(childKey),\n          newChild,\n          writesCache,\n          serverCache,\n          filterServerNode,\n          accumulator\n        );\n      }\n    });\n    viewMergeTree.children.inorderTraversal((childKey, childMergeTree) => {\n      const isUnknownDeepMerge =\n        !viewCache.getServerCache().isCompleteForChild(childKey) &&\n        childMergeTree.value == null;\n      if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {\n        const serverChild = viewCache\n          .getServerCache()\n          .getNode()\n          .getImmediateChild(childKey);\n        const newChild = this.applyMerge_(serverChild, childMergeTree);\n        curViewCache = this.applyServerOverwrite_(\n          curViewCache,\n          new Path(childKey),\n          newChild,\n          writesCache,\n          serverCache,\n          filterServerNode,\n          accumulator\n        );\n      }\n    });\n\n    return curViewCache;\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} ackPath\n   * @param {!ImmutableTree<!boolean>} affectedTree\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeCache\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private ackUserWrite_(\n    viewCache: ViewCache,\n    ackPath: Path,\n    affectedTree: ImmutableTree<boolean>,\n    writesCache: WriteTreeRef,\n    completeCache: Node | null,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    if (writesCache.shadowingWrite(ackPath) != null) {\n      return viewCache;\n    }\n\n    // Only filter server node if it is currently filtered\n    const filterServerNode = viewCache.getServerCache().isFiltered();\n\n    // Essentially we'll just get our existing server cache for the affected paths and re-apply it as a server update\n    // now that it won't be shadowed.\n    const serverCache = viewCache.getServerCache();\n    if (affectedTree.value != null) {\n      // This is an overwrite.\n      if (\n        (ackPath.isEmpty() && serverCache.isFullyInitialized()) ||\n        serverCache.isCompleteForPath(ackPath)\n      ) {\n        return this.applyServerOverwrite_(\n          viewCache,\n          ackPath,\n          serverCache.getNode().getChild(ackPath),\n          writesCache,\n          completeCache,\n          filterServerNode,\n          accumulator\n        );\n      } else if (ackPath.isEmpty()) {\n        // This is a goofy edge case where we are acking data at this location but don't have full data.  We\n        // should just re-apply whatever we have in our cache as a merge.\n        let changedChildren = ImmutableTree.Empty;\n        serverCache.getNode().forEachChild(KEY_INDEX, (name, node) => {\n          changedChildren = changedChildren.set(new Path(name), node);\n        });\n        return this.applyServerMerge_(\n          viewCache,\n          ackPath,\n          changedChildren,\n          writesCache,\n          completeCache,\n          filterServerNode,\n          accumulator\n        );\n      } else {\n        return viewCache;\n      }\n    } else {\n      // This is a merge.\n      let changedChildren = ImmutableTree.Empty;\n      affectedTree.foreach((mergePath, value) => {\n        const serverCachePath = ackPath.child(mergePath);\n        if (serverCache.isCompleteForPath(serverCachePath)) {\n          changedChildren = changedChildren.set(\n            mergePath,\n            serverCache.getNode().getChild(serverCachePath)\n          );\n        }\n      });\n      return this.applyServerMerge_(\n        viewCache,\n        ackPath,\n        changedChildren,\n        writesCache,\n        completeCache,\n        filterServerNode,\n        accumulator\n      );\n    }\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} path\n   * @param {!WriteTreeRef} writesCache\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private listenComplete_(\n    viewCache: ViewCache,\n    path: Path,\n    writesCache: WriteTreeRef,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    const oldServerNode = viewCache.getServerCache();\n    const newViewCache = viewCache.updateServerSnap(\n      oldServerNode.getNode(),\n      oldServerNode.isFullyInitialized() || path.isEmpty(),\n      oldServerNode.isFiltered()\n    );\n    return this.generateEventCacheAfterServerEvent_(\n      newViewCache,\n      path,\n      writesCache,\n      NO_COMPLETE_CHILD_SOURCE,\n      accumulator\n    );\n  }\n\n  /**\n   * @param {!ViewCache} viewCache\n   * @param {!Path} path\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeServerCache\n   * @param {!ChildChangeAccumulator} accumulator\n   * @return {!ViewCache}\n   * @private\n   */\n  private revertUserWrite_(\n    viewCache: ViewCache,\n    path: Path,\n    writesCache: WriteTreeRef,\n    completeServerCache: Node | null,\n    accumulator: ChildChangeAccumulator\n  ): ViewCache {\n    let complete;\n    if (writesCache.shadowingWrite(path) != null) {\n      return viewCache;\n    } else {\n      const source = new WriteTreeCompleteChildSource(\n        writesCache,\n        viewCache,\n        completeServerCache\n      );\n      const oldEventCache = viewCache.getEventCache().getNode();\n      let newEventCache;\n      if (path.isEmpty() || path.getFront() === '.priority') {\n        let newNode;\n        if (viewCache.getServerCache().isFullyInitialized()) {\n          newNode = writesCache.calcCompleteEventCache(\n            viewCache.getCompleteServerSnap()\n          );\n        } else {\n          const serverChildren = viewCache.getServerCache().getNode();\n          assert(\n            serverChildren instanceof ChildrenNode,\n            'serverChildren would be complete if leaf node'\n          );\n          newNode = writesCache.calcCompleteEventChildren(\n            serverChildren as ChildrenNode\n          );\n        }\n        newNode = newNode as Node;\n        newEventCache = this.filter_.updateFullNode(\n          oldEventCache,\n          newNode,\n          accumulator\n        );\n      } else {\n        const childKey = path.getFront();\n        let newChild = writesCache.calcCompleteChild(\n          childKey,\n          viewCache.getServerCache()\n        );\n        if (\n          newChild == null &&\n          viewCache.getServerCache().isCompleteForChild(childKey)\n        ) {\n          newChild = oldEventCache.getImmediateChild(childKey);\n        }\n        if (newChild != null) {\n          newEventCache = this.filter_.updateChild(\n            oldEventCache,\n            childKey,\n            newChild,\n            path.popFront(),\n            source,\n            accumulator\n          );\n        } else if (viewCache.getEventCache().getNode().hasChild(childKey)) {\n          // No complete child available, delete the existing one, if any\n          newEventCache = this.filter_.updateChild(\n            oldEventCache,\n            childKey,\n            ChildrenNode.EMPTY_NODE,\n            path.popFront(),\n            source,\n            accumulator\n          );\n        } else {\n          newEventCache = oldEventCache;\n        }\n        if (\n          newEventCache.isEmpty() &&\n          viewCache.getServerCache().isFullyInitialized()\n        ) {\n          // We might have reverted all child writes. Maybe the old event was a leaf node\n          complete = writesCache.calcCompleteEventCache(\n            viewCache.getCompleteServerSnap()\n          );\n          if (complete.isLeafNode()) {\n            newEventCache = this.filter_.updateFullNode(\n              newEventCache,\n              complete,\n              accumulator\n            );\n          }\n        }\n      }\n      complete =\n        viewCache.getServerCache().isFullyInitialized() ||\n        writesCache.shadowingWrite(Path.Empty) != null;\n      return viewCache.updateEventSnap(\n        newEventCache,\n        complete,\n        this.filter_.filtersNodes()\n      );\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 { NamedNode, Node } from '../snap/Node';\nimport { Change } from './Change';\nimport { assertionError } from '@firebase/util';\nimport { Query } from '../../api/Query';\nimport { Index } from '../snap/indexes/Index';\nimport { EventRegistration } from './EventRegistration';\nimport { Event } from './Event';\n\n/**\n * An EventGenerator is used to convert \"raw\" changes (Change) as computed by the\n * CacheDiffer into actual events (Event) that can be raised.  See generateEventsForChanges()\n * for details.\n *\n * @constructor\n */\nexport class EventGenerator {\n  private index_: Index;\n\n  /**\n   *\n   * @param {!Query} query_\n   */\n  constructor(private query_: Query) {\n    /**\n     * @private\n     * @type {!Index}\n     */\n    this.index_ = this.query_.getQueryParams().getIndex();\n  }\n\n  /**\n   * Given a set of raw changes (no moved events and prevName not specified yet), and a set of\n   * EventRegistrations that should be notified of these changes, generate the actual events to be raised.\n   *\n   * Notes:\n   *  - child_moved events will be synthesized at this time for any child_changed events that affect\n   *    our index.\n   *  - prevName will be calculated based on the index ordering.\n   *\n   * @param {!Array.<!Change>} changes\n   * @param {!Node} eventCache\n   * @param {!Array.<!EventRegistration>} eventRegistrations\n   * @return {!Array.<!Event>}\n   */\n  generateEventsForChanges(\n    changes: Change[],\n    eventCache: Node,\n    eventRegistrations: EventRegistration[]\n  ): Event[] {\n    const events: Event[] = [];\n    const moves: Change[] = [];\n\n    changes.forEach(change => {\n      if (\n        change.type === Change.CHILD_CHANGED &&\n        this.index_.indexedValueChanged(\n          change.oldSnap as Node,\n          change.snapshotNode\n        )\n      ) {\n        moves.push(\n          Change.childMovedChange(\n            change.childName as string,\n            change.snapshotNode\n          )\n        );\n      }\n    });\n\n    this.generateEventsForType_(\n      events,\n      Change.CHILD_REMOVED,\n      changes,\n      eventRegistrations,\n      eventCache\n    );\n    this.generateEventsForType_(\n      events,\n      Change.CHILD_ADDED,\n      changes,\n      eventRegistrations,\n      eventCache\n    );\n    this.generateEventsForType_(\n      events,\n      Change.CHILD_MOVED,\n      moves,\n      eventRegistrations,\n      eventCache\n    );\n    this.generateEventsForType_(\n      events,\n      Change.CHILD_CHANGED,\n      changes,\n      eventRegistrations,\n      eventCache\n    );\n    this.generateEventsForType_(\n      events,\n      Change.VALUE,\n      changes,\n      eventRegistrations,\n      eventCache\n    );\n\n    return events;\n  }\n\n  /**\n   * Given changes of a single change type, generate the corresponding events.\n   *\n   * @param {!Array.<!Event>} events\n   * @param {!string} eventType\n   * @param {!Array.<!Change>} changes\n   * @param {!Array.<!EventRegistration>} registrations\n   * @param {!Node} eventCache\n   * @private\n   */\n  private generateEventsForType_(\n    events: Event[],\n    eventType: string,\n    changes: Change[],\n    registrations: EventRegistration[],\n    eventCache: Node\n  ) {\n    const filteredChanges = changes.filter(change => change.type === eventType);\n\n    filteredChanges.sort(this.compareChanges_.bind(this));\n    filteredChanges.forEach(change => {\n      const materializedChange = this.materializeSingleChange_(\n        change,\n        eventCache\n      );\n      registrations.forEach(registration => {\n        if (registration.respondsTo(change.type)) {\n          events.push(\n            registration.createEvent(materializedChange, this.query_)\n          );\n        }\n      });\n    });\n  }\n\n  /**\n   * @param {!Change} change\n   * @param {!Node} eventCache\n   * @return {!Change}\n   * @private\n   */\n  private materializeSingleChange_(change: Change, eventCache: Node): Change {\n    if (change.type === 'value' || change.type === 'child_removed') {\n      return change;\n    } else {\n      change.prevName = eventCache.getPredecessorChildName(\n        /** @type {!string} */\n        change.childName,\n        change.snapshotNode,\n        this.index_\n      );\n      return change;\n    }\n  }\n\n  /**\n   * @param {!Change} a\n   * @param {!Change} b\n   * @return {number}\n   * @private\n   */\n  private compareChanges_(a: Change, b: Change) {\n    if (a.childName == null || b.childName == null) {\n      throw assertionError('Should only compare child_ events.');\n    }\n    const aWrapped = new NamedNode(a.childName, a.snapshotNode);\n    const bWrapped = new NamedNode(b.childName, b.snapshotNode);\n    return this.index_.compare(aWrapped, bWrapped);\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 { IndexedFilter } from './filter/IndexedFilter';\nimport { ViewProcessor } from './ViewProcessor';\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { CacheNode } from './CacheNode';\nimport { ViewCache } from './ViewCache';\nimport { EventGenerator } from './EventGenerator';\nimport { assert } from '@firebase/util';\nimport { Operation, OperationType } from '../operation/Operation';\nimport { Change } from './Change';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { Query } from '../../api/Query';\nimport { EventRegistration } from './EventRegistration';\nimport { Node } from '../snap/Node';\nimport { Path } from '../util/Path';\nimport { WriteTreeRef } from '../WriteTree';\nimport { CancelEvent, Event } from './Event';\n\n/**\n * A view represents a specific location and query that has 1 or more event registrations.\n *\n * It does several things:\n *  - Maintains the list of event registrations for this location/query.\n *  - Maintains a cache of the data visible for this location/query.\n *  - Applies new operations (via applyOperation), updates the cache, and based on the event\n *    registrations returns the set of events to be raised.\n * @constructor\n */\nexport class View {\n  private processor_: ViewProcessor;\n  private viewCache_: ViewCache;\n  private eventRegistrations_: EventRegistration[] = [];\n  private eventGenerator_: EventGenerator;\n\n  /**\n   *\n   * @param {!Query} query_\n   * @param {!ViewCache} initialViewCache\n   */\n  constructor(private query_: Query, initialViewCache: ViewCache) {\n    const params = this.query_.getQueryParams();\n\n    const indexFilter = new IndexedFilter(params.getIndex());\n    const filter = params.getNodeFilter();\n\n    /**\n     * @type {ViewProcessor}\n     * @private\n     */\n    this.processor_ = new ViewProcessor(filter);\n\n    const initialServerCache = initialViewCache.getServerCache();\n    const initialEventCache = initialViewCache.getEventCache();\n\n    // Don't filter server node with other filter than index, wait for tagged listen\n    const serverSnap = indexFilter.updateFullNode(\n      ChildrenNode.EMPTY_NODE,\n      initialServerCache.getNode(),\n      null\n    );\n    const eventSnap = filter.updateFullNode(\n      ChildrenNode.EMPTY_NODE,\n      initialEventCache.getNode(),\n      null\n    );\n    const newServerCache = new CacheNode(\n      serverSnap,\n      initialServerCache.isFullyInitialized(),\n      indexFilter.filtersNodes()\n    );\n    const newEventCache = new CacheNode(\n      eventSnap,\n      initialEventCache.isFullyInitialized(),\n      filter.filtersNodes()\n    );\n\n    /**\n     * @type {!ViewCache}\n     * @private\n     */\n    this.viewCache_ = new ViewCache(newEventCache, newServerCache);\n\n    /**\n     * @type {!EventGenerator}\n     * @private\n     */\n    this.eventGenerator_ = new EventGenerator(this.query_);\n  }\n\n  /**\n   * @return {!Query}\n   */\n  getQuery(): Query {\n    return this.query_;\n  }\n\n  /**\n   * @return {?Node}\n   */\n  getServerCache(): Node | null {\n    return this.viewCache_.getServerCache().getNode();\n  }\n\n  /**\n   * @param {!Path} path\n   * @return {?Node}\n   */\n  getCompleteServerCache(path: Path): Node | null {\n    const cache = this.viewCache_.getCompleteServerSnap();\n    if (cache) {\n      // If this isn't a \"loadsAllData\" view, then cache isn't actually a complete cache and\n      // we need to see if it contains the child we're interested in.\n      if (\n        this.query_.getQueryParams().loadsAllData() ||\n        (!path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty())\n      ) {\n        return cache.getChild(path);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @return {boolean}\n   */\n  isEmpty(): boolean {\n    return this.eventRegistrations_.length === 0;\n  }\n\n  /**\n   * @param {!EventRegistration} eventRegistration\n   */\n  addEventRegistration(eventRegistration: EventRegistration) {\n    this.eventRegistrations_.push(eventRegistration);\n  }\n\n  /**\n   * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\n   * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\n   * @return {!Array.<!Event>} Cancel events, if cancelError was provided.\n   */\n  removeEventRegistration(\n    eventRegistration: EventRegistration | null,\n    cancelError?: Error\n  ): Event[] {\n    const cancelEvents: CancelEvent[] = [];\n    if (cancelError) {\n      assert(\n        eventRegistration == null,\n        'A cancel should cancel all event registrations.'\n      );\n      const path = this.query_.path;\n      this.eventRegistrations_.forEach(registration => {\n        cancelError /** @type {!Error} */ = cancelError;\n        const maybeEvent = registration.createCancelEvent(cancelError, path);\n        if (maybeEvent) {\n          cancelEvents.push(maybeEvent);\n        }\n      });\n    }\n\n    if (eventRegistration) {\n      let remaining = [];\n      for (let i = 0; i < this.eventRegistrations_.length; ++i) {\n        const existing = this.eventRegistrations_[i];\n        if (!existing.matches(eventRegistration)) {\n          remaining.push(existing);\n        } else if (eventRegistration.hasAnyCallback()) {\n          // We're removing just this one\n          remaining = remaining.concat(this.eventRegistrations_.slice(i + 1));\n          break;\n        }\n      }\n      this.eventRegistrations_ = remaining;\n    } else {\n      this.eventRegistrations_ = [];\n    }\n    return cancelEvents;\n  }\n\n  /**\n   * Applies the given Operation, updates our cache, and returns the appropriate events.\n   *\n   * @param {!Operation} operation\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} completeServerCache\n   * @return {!Array.<!Event>}\n   */\n  applyOperation(\n    operation: Operation,\n    writesCache: WriteTreeRef,\n    completeServerCache: Node | null\n  ): Event[] {\n    if (\n      operation.type === OperationType.MERGE &&\n      operation.source.queryId !== null\n    ) {\n      assert(\n        this.viewCache_.getCompleteServerSnap(),\n        'We should always have a full cache before handling merges'\n      );\n      assert(\n        this.viewCache_.getCompleteEventSnap(),\n        'Missing event cache, even though we have a server cache'\n      );\n    }\n\n    const oldViewCache = this.viewCache_;\n    const result = this.processor_.applyOperation(\n      oldViewCache,\n      operation,\n      writesCache,\n      completeServerCache\n    );\n    this.processor_.assertIndexed(result.viewCache);\n\n    assert(\n      result.viewCache.getServerCache().isFullyInitialized() ||\n        !oldViewCache.getServerCache().isFullyInitialized(),\n      'Once a server snap is complete, it should never go back'\n    );\n\n    this.viewCache_ = result.viewCache;\n\n    return this.generateEventsForChanges_(\n      result.changes,\n      result.viewCache.getEventCache().getNode(),\n      null\n    );\n  }\n\n  /**\n   * @param {!EventRegistration} registration\n   * @return {!Array.<!Event>}\n   */\n  getInitialEvents(registration: EventRegistration): Event[] {\n    const eventSnap = this.viewCache_.getEventCache();\n    const initialChanges: Change[] = [];\n    if (!eventSnap.getNode().isLeafNode()) {\n      const eventNode = eventSnap.getNode() as ChildrenNode;\n      eventNode.forEachChild(PRIORITY_INDEX, (key, childNode) => {\n        initialChanges.push(Change.childAddedChange(key, childNode));\n      });\n    }\n    if (eventSnap.isFullyInitialized()) {\n      initialChanges.push(Change.valueChange(eventSnap.getNode()));\n    }\n    return this.generateEventsForChanges_(\n      initialChanges,\n      eventSnap.getNode(),\n      registration\n    );\n  }\n\n  /**\n   * @private\n   * @param {!Array.<!Change>} changes\n   * @param {!Node} eventCache\n   * @param {EventRegistration=} eventRegistration\n   * @return {!Array.<!Event>}\n   */\n  generateEventsForChanges_(\n    changes: Change[],\n    eventCache: Node,\n    eventRegistration?: EventRegistration\n  ): Event[] {\n    const registrations = eventRegistration\n      ? [eventRegistration]\n      : this.eventRegistrations_;\n    return this.eventGenerator_.generateEventsForChanges(\n      changes,\n      eventCache,\n      registrations\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 { CacheNode } from './view/CacheNode';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { assert } from '@firebase/util';\nimport { ViewCache } from './view/ViewCache';\nimport { View } from './view/View';\nimport { Operation } from './operation/Operation';\nimport { WriteTreeRef } from './WriteTree';\nimport { Query } from '../api/Query';\nimport { EventRegistration } from './view/EventRegistration';\nimport { Node } from './snap/Node';\nimport { Path } from './util/Path';\nimport { Event } from './view/Event';\nimport { Reference, ReferenceConstructor } from '../api/Reference';\n\nlet __referenceConstructor: ReferenceConstructor;\n\n/**\n * SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to\n * maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes\n * and user writes (set, transaction, update).\n *\n * It's responsible for:\n *  - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed).\n *  - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite,\n *    applyUserOverwrite, etc.)\n */\nexport class SyncPoint {\n  static set __referenceConstructor(val: ReferenceConstructor) {\n    assert(\n      !__referenceConstructor,\n      '__referenceConstructor has already been defined'\n    );\n    __referenceConstructor = val;\n  }\n\n  static get __referenceConstructor() {\n    assert(__referenceConstructor, 'Reference.ts has not been loaded');\n    return __referenceConstructor;\n  }\n\n  /**\n   * The Views being tracked at this location in the tree, stored as a map where the key is a\n   * queryId and the value is the View for that query.\n   *\n   * NOTE: This list will be quite small (usually 1, but perhaps 2 or 3; any more is an odd use case).\n   */\n  private readonly views: Map<string, View> = new Map();\n\n  isEmpty(): boolean {\n    return this.views.size === 0;\n  }\n\n  applyOperation(\n    operation: Operation,\n    writesCache: WriteTreeRef,\n    optCompleteServerCache: Node | null\n  ): Event[] {\n    const queryId = operation.source.queryId;\n    if (queryId !== null) {\n      const view = this.views.get(queryId);\n      assert(view != null, 'SyncTree gave us an op for an invalid query.');\n      return view.applyOperation(\n        operation,\n        writesCache,\n        optCompleteServerCache\n      );\n    } else {\n      let events: Event[] = [];\n\n      for (const view of this.views.values()) {\n        events = events.concat(\n          view.applyOperation(operation, writesCache, optCompleteServerCache)\n        );\n      }\n\n      return events;\n    }\n  }\n\n  /**\n   * Add an event callback for the specified query.\n   *\n   * @param {!Query} query\n   * @param {!EventRegistration} eventRegistration\n   * @param {!WriteTreeRef} writesCache\n   * @param {?Node} serverCache Complete server cache, if we have it.\n   * @param {boolean} serverCacheComplete\n   * @return {!Array.<!Event>} Events to raise.\n   */\n  addEventRegistration(\n    query: Query,\n    eventRegistration: EventRegistration,\n    writesCache: WriteTreeRef,\n    serverCache: Node | null,\n    serverCacheComplete: boolean\n  ): Event[] {\n    const queryId = query.queryIdentifier();\n    let view = this.views.get(queryId);\n    if (!view) {\n      // TODO: make writesCache take flag for complete server node\n      let eventCache = writesCache.calcCompleteEventCache(\n        serverCacheComplete ? serverCache : null\n      );\n      let eventCacheComplete = false;\n      if (eventCache) {\n        eventCacheComplete = true;\n      } else if (serverCache instanceof ChildrenNode) {\n        eventCache = writesCache.calcCompleteEventChildren(serverCache);\n        eventCacheComplete = false;\n      } else {\n        eventCache = ChildrenNode.EMPTY_NODE;\n        eventCacheComplete = false;\n      }\n      const viewCache = new ViewCache(\n        new CacheNode(\n          /** @type {!Node} */ eventCache,\n          eventCacheComplete,\n          false\n        ),\n        new CacheNode(\n          /** @type {!Node} */ serverCache,\n          serverCacheComplete,\n          false\n        )\n      );\n      view = new View(query, viewCache);\n      this.views.set(queryId, view);\n    }\n\n    // This is guaranteed to exist now, we just created anything that was missing\n    view.addEventRegistration(eventRegistration);\n    return view.getInitialEvents(eventRegistration);\n  }\n\n  /**\n   * Remove event callback(s).  Return cancelEvents if a cancelError is specified.\n   *\n   * If query is the default query, we'll check all views for the specified eventRegistration.\n   * If eventRegistration is null, we'll remove all callbacks for the specified view(s).\n   *\n   * @param {!Query} query\n   * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\n   * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\n   * @return {{removed:!Array.<!Query>, events:!Array.<!Event>}} removed queries and any cancel events\n   */\n  removeEventRegistration(\n    query: Query,\n    eventRegistration: EventRegistration | null,\n    cancelError?: Error\n  ): { removed: Query[]; events: Event[] } {\n    const queryId = query.queryIdentifier();\n    const removed: Query[] = [];\n    let cancelEvents: Event[] = [];\n    const hadCompleteView = this.hasCompleteView();\n    if (queryId === 'default') {\n      // When you do ref.off(...), we search all views for the registration to remove.\n      for (const [viewQueryId, view] of this.views.entries()) {\n        cancelEvents = cancelEvents.concat(\n          view.removeEventRegistration(eventRegistration, cancelError)\n        );\n        if (view.isEmpty()) {\n          this.views.delete(viewQueryId);\n\n          // We'll deal with complete views later.\n          if (!view.getQuery().getQueryParams().loadsAllData()) {\n            removed.push(view.getQuery());\n          }\n        }\n      }\n    } else {\n      // remove the callback from the specific view.\n      const view = this.views.get(queryId);\n      if (view) {\n        cancelEvents = cancelEvents.concat(\n          view.removeEventRegistration(eventRegistration, cancelError)\n        );\n        if (view.isEmpty()) {\n          this.views.delete(queryId);\n\n          // We'll deal with complete views later.\n          if (!view.getQuery().getQueryParams().loadsAllData()) {\n            removed.push(view.getQuery());\n          }\n        }\n      }\n    }\n\n    if (hadCompleteView && !this.hasCompleteView()) {\n      // We removed our last complete view.\n      removed.push(\n        new SyncPoint.__referenceConstructor(query.repo, query.path)\n      );\n    }\n\n    return { removed, events: cancelEvents };\n  }\n\n  getQueryViews(): View[] {\n    const result = [];\n    for (const view of this.views.values()) {\n      if (!view.getQuery().getQueryParams().loadsAllData()) {\n        result.push(view);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @param path The path to the desired complete snapshot\n   * @return A complete cache, if it exists\n   */\n  getCompleteServerCache(path: Path): Node | null {\n    let serverCache: Node | null = null;\n    for (const view of this.views.values()) {\n      serverCache = serverCache || view.getCompleteServerCache(path);\n    }\n    return serverCache;\n  }\n\n  viewForQuery(query: Query): View | null {\n    const params = query.getQueryParams();\n    if (params.loadsAllData()) {\n      return this.getCompleteView();\n    } else {\n      const queryId = query.queryIdentifier();\n      return this.views.get(queryId);\n    }\n  }\n\n  viewExistsForQuery(query: Query): boolean {\n    return this.viewForQuery(query) != null;\n  }\n\n  hasCompleteView(): boolean {\n    return this.getCompleteView() != null;\n  }\n\n  getCompleteView(): View | null {\n    for (const view of this.views.values()) {\n      if (view.getQuery().getQueryParams().loadsAllData()) {\n        return view;\n      }\n    }\n    return null;\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 { ImmutableTree } from './util/ImmutableTree';\nimport { Path } from './util/Path';\nimport { Node, NamedNode } from './snap/Node';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { assert } from '@firebase/util';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { each } from './util/util';\n\n/**\n * This class holds a collection of writes that can be applied to nodes in unison. It abstracts away the logic with\n * dealing with priority writes and multiple nested writes. At any given path there is only allowed to be one write\n * modifying that path. Any write to an existing path or shadowing an existing path will modify that existing write\n * to reflect the write added.\n */\nexport class CompoundWrite {\n  constructor(private writeTree_: ImmutableTree<Node>) {}\n\n  static Empty = new CompoundWrite(new ImmutableTree(null));\n\n  addWrite(path: Path, node: Node): CompoundWrite {\n    if (path.isEmpty()) {\n      return new CompoundWrite(new ImmutableTree(node));\n    } else {\n      const rootmost = this.writeTree_.findRootMostValueAndPath(path);\n      if (rootmost != null) {\n        const rootMostPath = rootmost.path;\n        let value = rootmost.value;\n        const relativePath = Path.relativePath(rootMostPath, path);\n        value = value.updateChild(relativePath, node);\n        return new CompoundWrite(this.writeTree_.set(rootMostPath, value));\n      } else {\n        const subtree = new ImmutableTree(node);\n        const newWriteTree = this.writeTree_.setTree(path, subtree);\n        return new CompoundWrite(newWriteTree);\n      }\n    }\n  }\n\n  addWrites(path: Path, updates: { [name: string]: Node }): CompoundWrite {\n    let newWrite = this as CompoundWrite;\n    each(updates, (childKey: string, node: Node) => {\n      newWrite = newWrite.addWrite(path.child(childKey), node);\n    });\n    return newWrite;\n  }\n\n  /**\n   * Will remove a write at the given path and deeper paths. This will <em>not</em> modify a write at a higher\n   * location, which must be removed by calling this method with that path.\n   *\n   * @param path The path at which a write and all deeper writes should be removed\n   * @return {!CompoundWrite} The new CompoundWrite with the removed path\n   */\n  removeWrite(path: Path): CompoundWrite {\n    if (path.isEmpty()) {\n      return CompoundWrite.Empty;\n    } else {\n      const newWriteTree = this.writeTree_.setTree(path, ImmutableTree.Empty);\n      return new CompoundWrite(newWriteTree);\n    }\n  }\n\n  /**\n   * Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be\n   * considered \"complete\".\n   *\n   * @param path The path to check for\n   * @return Whether there is a complete write at that path\n   */\n  hasCompleteWrite(path: Path): boolean {\n    return this.getCompleteNode(path) != null;\n  }\n\n  /**\n   * Returns a node for a path if and only if the node is a \"complete\" overwrite at that path. This will not aggregate\n   * writes from deeper paths, but will return child nodes from a more shallow path.\n   *\n   * @param path The path to get a complete write\n   * @return The node if complete at that path, or null otherwise.\n   */\n  getCompleteNode(path: Path): Node | null {\n    const rootmost = this.writeTree_.findRootMostValueAndPath(path);\n    if (rootmost != null) {\n      return this.writeTree_\n        .get(rootmost.path)\n        .getChild(Path.relativePath(rootmost.path, path));\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Returns all children that are guaranteed to be a complete overwrite.\n   *\n   * @return A list of all complete children.\n   */\n  getCompleteChildren(): NamedNode[] {\n    const children: NamedNode[] = [];\n    const node = this.writeTree_.value;\n    if (node != null) {\n      // If it's a leaf node, it has no children; so nothing to do.\n      if (!node.isLeafNode()) {\n        (node as ChildrenNode).forEachChild(\n          PRIORITY_INDEX,\n          (childName, childNode) => {\n            children.push(new NamedNode(childName, childNode));\n          }\n        );\n      }\n    } else {\n      this.writeTree_.children.inorderTraversal((childName, childTree) => {\n        if (childTree.value != null) {\n          children.push(new NamedNode(childName, childTree.value));\n        }\n      });\n    }\n    return children;\n  }\n\n  childCompoundWrite(path: Path): CompoundWrite {\n    if (path.isEmpty()) {\n      return this;\n    } else {\n      const shadowingNode = this.getCompleteNode(path);\n      if (shadowingNode != null) {\n        return new CompoundWrite(new ImmutableTree(shadowingNode));\n      } else {\n        return new CompoundWrite(this.writeTree_.subtree(path));\n      }\n    }\n  }\n\n  /**\n   * Returns true if this CompoundWrite is empty and therefore does not modify any nodes.\n   * @return Whether this CompoundWrite is empty\n   */\n  isEmpty(): boolean {\n    return this.writeTree_.isEmpty();\n  }\n\n  /**\n   * Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the\n   * node\n   * @param node The node to apply this CompoundWrite to\n   * @return The node with all writes applied\n   */\n  apply(node: Node): Node {\n    return applySubtreeWrite(Path.Empty, this.writeTree_, node);\n  }\n}\n\nfunction applySubtreeWrite(\n  relativePath: Path,\n  writeTree: ImmutableTree<Node>,\n  node: Node\n): Node {\n  if (writeTree.value != null) {\n    // Since there a write is always a leaf, we're done here\n    return node.updateChild(relativePath, writeTree.value);\n  } else {\n    let priorityWrite = null;\n    writeTree.children.inorderTraversal((childKey, childTree) => {\n      if (childKey === '.priority') {\n        // Apply priorities at the end so we don't update priorities for either empty nodes or forget\n        // to apply priorities to empty nodes that are later filled\n        assert(\n          childTree.value !== null,\n          'Priority writes must always be leaf nodes'\n        );\n        priorityWrite = childTree.value;\n      } else {\n        node = applySubtreeWrite(relativePath.child(childKey), childTree, node);\n      }\n    });\n    // If there was a priority write, we only apply it if the node is not empty\n    if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) {\n      node = node.updateChild(relativePath.child('.priority'), priorityWrite);\n    }\n    return node;\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 { safeGet, assert, assertionError } from '@firebase/util';\n\nimport { Path } from './util/Path';\nimport { CompoundWrite } from './CompoundWrite';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { NamedNode, Node } from './snap/Node';\nimport { CacheNode } from './view/CacheNode';\nimport { Index } from './snap/indexes/Index';\nimport { each } from './util/util';\n\n/**\n * Defines a single user-initiated write operation. May be the result of a set(), transaction(), or update() call. In\n * the case of a set() or transaction, snap wil be non-null.  In the case of an update(), children will be non-null.\n */\nexport interface WriteRecord {\n  writeId: number;\n  path: Path;\n  snap?: Node | null;\n  children?: { [k: string]: Node } | null;\n  visible: boolean;\n}\n\n/**\n * WriteTree tracks all pending user-initiated writes and has methods to calculate the result of merging them\n * with underlying server data (to create \"event cache\" data).  Pending writes are added with addOverwrite()\n * and addMerge(), and removed with removeWrite().\n *\n * @constructor\n */\nexport class WriteTree {\n  /**\n   * A tree tracking the result of applying all visible writes.  This does not include transactions with\n   * applyLocally=false or writes that are completely shadowed by other writes.\n   *\n   * @type {!CompoundWrite}\n   * @private\n   */\n  private visibleWrites_: CompoundWrite = CompoundWrite.Empty;\n\n  /**\n   * A list of all pending writes, regardless of visibility and shadowed-ness.  Used to calculate arbitrary\n   * sets of the changed data, such as hidden writes (from transactions) or changes with certain writes excluded (also\n   * used by transactions).\n   *\n   * @type {!Array.<!WriteRecord>}\n   * @private\n   */\n  private allWrites_: WriteRecord[] = [];\n\n  private lastWriteId_ = -1;\n\n  /**\n   * Create a new WriteTreeRef for the given path. For use with a new sync point at the given path.\n   *\n   * @param {!Path} path\n   * @return {!WriteTreeRef}\n   */\n  childWrites(path: Path): WriteTreeRef {\n    return new WriteTreeRef(path, this);\n  }\n\n  /**\n   * Record a new overwrite from user code.\n   *\n   * @param {!Path} path\n   * @param {!Node} snap\n   * @param {!number} writeId\n   * @param {boolean=} visible This is set to false by some transactions. It should be excluded from event caches\n   */\n  addOverwrite(path: Path, snap: Node, writeId: number, visible?: boolean) {\n    assert(\n      writeId > this.lastWriteId_,\n      'Stacking an older write on top of newer ones'\n    );\n    if (visible === undefined) {\n      visible = true;\n    }\n    this.allWrites_.push({\n      path,\n      snap,\n      writeId,\n      visible\n    });\n\n    if (visible) {\n      this.visibleWrites_ = this.visibleWrites_.addWrite(path, snap);\n    }\n    this.lastWriteId_ = writeId;\n  }\n\n  /**\n   * Record a new merge from user code.\n   *\n   * @param {!Path} path\n   * @param {!Object.<string, !Node>} changedChildren\n   * @param {!number} writeId\n   */\n  addMerge(\n    path: Path,\n    changedChildren: { [k: string]: Node },\n    writeId: number\n  ) {\n    assert(\n      writeId > this.lastWriteId_,\n      'Stacking an older merge on top of newer ones'\n    );\n    this.allWrites_.push({\n      path,\n      children: changedChildren,\n      writeId,\n      visible: true\n    });\n\n    this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);\n    this.lastWriteId_ = writeId;\n  }\n\n  /**\n   * @param {!number} writeId\n   * @return {?WriteRecord}\n   */\n  getWrite(writeId: number): WriteRecord | null {\n    for (let i = 0; i < this.allWrites_.length; i++) {\n      const record = this.allWrites_[i];\n      if (record.writeId === writeId) {\n        return record;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Remove a write (either an overwrite or merge) that has been successfully acknowledge by the server. Recalculates\n   * the tree if necessary.  We return true if it may have been visible, meaning views need to reevaluate.\n   *\n   * @param {!number} writeId\n   * @return {boolean} true if the write may have been visible (meaning we'll need to reevaluate / raise\n   * events as a result).\n   */\n  removeWrite(writeId: number): boolean {\n    // Note: disabling this check. It could be a transaction that preempted another transaction, and thus was applied\n    // out of order.\n    //const validClear = revert || this.allWrites_.length === 0 || writeId <= this.allWrites_[0].writeId;\n    //assert(validClear, \"Either we don't have this write, or it's the first one in the queue\");\n\n    const idx = this.allWrites_.findIndex(s => {\n      return s.writeId === writeId;\n    });\n    assert(idx >= 0, 'removeWrite called with nonexistent writeId.');\n    const writeToRemove = this.allWrites_[idx];\n    this.allWrites_.splice(idx, 1);\n\n    let removedWriteWasVisible = writeToRemove.visible;\n    let removedWriteOverlapsWithOtherWrites = false;\n\n    let i = this.allWrites_.length - 1;\n\n    while (removedWriteWasVisible && i >= 0) {\n      const currentWrite = this.allWrites_[i];\n      if (currentWrite.visible) {\n        if (\n          i >= idx &&\n          this.recordContainsPath_(currentWrite, writeToRemove.path)\n        ) {\n          // The removed write was completely shadowed by a subsequent write.\n          removedWriteWasVisible = false;\n        } else if (writeToRemove.path.contains(currentWrite.path)) {\n          // Either we're covering some writes or they're covering part of us (depending on which came first).\n          removedWriteOverlapsWithOtherWrites = true;\n        }\n      }\n      i--;\n    }\n\n    if (!removedWriteWasVisible) {\n      return false;\n    } else if (removedWriteOverlapsWithOtherWrites) {\n      // There's some shadowing going on. Just rebuild the visible writes from scratch.\n      this.resetTree_();\n      return true;\n    } else {\n      // There's no shadowing.  We can safely just remove the write(s) from visibleWrites.\n      if (writeToRemove.snap) {\n        this.visibleWrites_ = this.visibleWrites_.removeWrite(\n          writeToRemove.path\n        );\n      } else {\n        const children = writeToRemove.children;\n        each(children, (childName: string) => {\n          this.visibleWrites_ = this.visibleWrites_.removeWrite(\n            writeToRemove.path.child(childName)\n          );\n        });\n      }\n      return true;\n    }\n  }\n\n  /**\n   * Return a complete snapshot for the given path if there's visible write data at that path, else null.\n   * No server data is considered.\n   *\n   * @param {!Path} path\n   * @return {?Node}\n   */\n  getCompleteWriteData(path: Path): Node | null {\n    return this.visibleWrites_.getCompleteNode(path);\n  }\n\n  /**\n   * Given optional, underlying server data, and an optional set of constraints (exclude some sets, include hidden\n   * writes), attempt to calculate a complete snapshot for the given path\n   *\n   * @param {!Path} treePath\n   * @param {?Node} completeServerCache\n   * @param {Array.<number>=} writeIdsToExclude An optional set to be excluded\n   * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\n   * @return {?Node}\n   */\n  calcCompleteEventCache(\n    treePath: Path,\n    completeServerCache: Node | null,\n    writeIdsToExclude?: number[],\n    includeHiddenWrites?: boolean\n  ): Node | null {\n    if (!writeIdsToExclude && !includeHiddenWrites) {\n      const shadowingNode = this.visibleWrites_.getCompleteNode(treePath);\n      if (shadowingNode != null) {\n        return shadowingNode;\n      } else {\n        const subMerge = this.visibleWrites_.childCompoundWrite(treePath);\n        if (subMerge.isEmpty()) {\n          return completeServerCache;\n        } else if (\n          completeServerCache == null &&\n          !subMerge.hasCompleteWrite(Path.Empty)\n        ) {\n          // We wouldn't have a complete snapshot, since there's no underlying data and no complete shadow\n          return null;\n        } else {\n          const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\n          return subMerge.apply(layeredCache);\n        }\n      }\n    } else {\n      const merge = this.visibleWrites_.childCompoundWrite(treePath);\n      if (!includeHiddenWrites && merge.isEmpty()) {\n        return completeServerCache;\n      } else {\n        // If the server cache is null, and we don't have a complete cache, we need to return null\n        if (\n          !includeHiddenWrites &&\n          completeServerCache == null &&\n          !merge.hasCompleteWrite(Path.Empty)\n        ) {\n          return null;\n        } else {\n          const filter = function (write: WriteRecord) {\n            return (\n              (write.visible || includeHiddenWrites) &&\n              (!writeIdsToExclude ||\n                !~writeIdsToExclude.indexOf(write.writeId)) &&\n              (write.path.contains(treePath) || treePath.contains(write.path))\n            );\n          };\n          const mergeAtPath = WriteTree.layerTree_(\n            this.allWrites_,\n            filter,\n            treePath\n          );\n          const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\n          return mergeAtPath.apply(layeredCache);\n        }\n      }\n    }\n  }\n\n  /**\n   * With optional, underlying server data, attempt to return a children node of children that we have complete data for.\n   * Used when creating new views, to pre-fill their complete event children snapshot.\n   *\n   * @param {!Path} treePath\n   * @param {?ChildrenNode} completeServerChildren\n   * @return {!ChildrenNode}\n   */\n  calcCompleteEventChildren(\n    treePath: Path,\n    completeServerChildren: ChildrenNode | null\n  ) {\n    let completeChildren = ChildrenNode.EMPTY_NODE as Node;\n    const topLevelSet = this.visibleWrites_.getCompleteNode(treePath);\n    if (topLevelSet) {\n      if (!topLevelSet.isLeafNode()) {\n        // we're shadowing everything. Return the children.\n        topLevelSet.forEachChild(PRIORITY_INDEX, (childName, childSnap) => {\n          completeChildren = completeChildren.updateImmediateChild(\n            childName,\n            childSnap\n          );\n        });\n      }\n      return completeChildren;\n    } else if (completeServerChildren) {\n      // Layer any children we have on top of this\n      // We know we don't have a top-level set, so just enumerate existing children\n      const merge = this.visibleWrites_.childCompoundWrite(treePath);\n      completeServerChildren.forEachChild(\n        PRIORITY_INDEX,\n        (childName, childNode) => {\n          const node = merge\n            .childCompoundWrite(new Path(childName))\n            .apply(childNode);\n          completeChildren = completeChildren.updateImmediateChild(\n            childName,\n            node\n          );\n        }\n      );\n      // Add any complete children we have from the set\n      merge.getCompleteChildren().forEach(namedNode => {\n        completeChildren = completeChildren.updateImmediateChild(\n          namedNode.name,\n          namedNode.node\n        );\n      });\n      return completeChildren;\n    } else {\n      // We don't have anything to layer on top of. Layer on any children we have\n      // Note that we can return an empty snap if we have a defined delete\n      const merge = this.visibleWrites_.childCompoundWrite(treePath);\n      merge.getCompleteChildren().forEach(namedNode => {\n        completeChildren = completeChildren.updateImmediateChild(\n          namedNode.name,\n          namedNode.node\n        );\n      });\n      return completeChildren;\n    }\n  }\n\n  /**\n   * Given that the underlying server data has updated, determine what, if anything, needs to be\n   * applied to the event cache.\n   *\n   * Possibilities:\n   *\n   * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\n   *\n   * 2. Some write is completely shadowing. No events to be raised\n   *\n   * 3. Is partially shadowed. Events\n   *\n   * Either existingEventSnap or existingServerSnap must exist\n   *\n   * @param {!Path} treePath\n   * @param {!Path} childPath\n   * @param {?Node} existingEventSnap\n   * @param {?Node} existingServerSnap\n   * @return {?Node}\n   */\n  calcEventCacheAfterServerOverwrite(\n    treePath: Path,\n    childPath: Path,\n    existingEventSnap: Node | null,\n    existingServerSnap: Node | null\n  ): Node | null {\n    assert(\n      existingEventSnap || existingServerSnap,\n      'Either existingEventSnap or existingServerSnap must exist'\n    );\n    const path = treePath.child(childPath);\n    if (this.visibleWrites_.hasCompleteWrite(path)) {\n      // At this point we can probably guarantee that we're in case 2, meaning no events\n      // May need to check visibility while doing the findRootMostValueAndPath call\n      return null;\n    } else {\n      // No complete shadowing. We're either partially shadowing or not shadowing at all.\n      const childMerge = this.visibleWrites_.childCompoundWrite(path);\n      if (childMerge.isEmpty()) {\n        // We're not shadowing at all. Case 1\n        return existingServerSnap.getChild(childPath);\n      } else {\n        // This could be more efficient if the serverNode + updates doesn't change the eventSnap\n        // However this is tricky to find out, since user updates don't necessary change the server\n        // snap, e.g. priority updates on empty nodes, or deep deletes. Another special case is if the server\n        // adds nodes, but doesn't change any existing writes. It is therefore not enough to\n        // only check if the updates change the serverNode.\n        // Maybe check if the merge tree contains these special cases and only do a full overwrite in that case?\n        return childMerge.apply(existingServerSnap.getChild(childPath));\n      }\n    }\n  }\n\n  /**\n   * Returns a complete child for a given server snap after applying all user writes or null if there is no\n   * complete child for this ChildKey.\n   *\n   * @param {!Path} treePath\n   * @param {!string} childKey\n   * @param {!CacheNode} existingServerSnap\n   * @return {?Node}\n   */\n  calcCompleteChild(\n    treePath: Path,\n    childKey: string,\n    existingServerSnap: CacheNode\n  ): Node | null {\n    const path = treePath.child(childKey);\n    const shadowingNode = this.visibleWrites_.getCompleteNode(path);\n    if (shadowingNode != null) {\n      return shadowingNode;\n    } else {\n      if (existingServerSnap.isCompleteForChild(childKey)) {\n        const childMerge = this.visibleWrites_.childCompoundWrite(path);\n        return childMerge.apply(\n          existingServerSnap.getNode().getImmediateChild(childKey)\n        );\n      } else {\n        return null;\n      }\n    }\n  }\n\n  /**\n   * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\n   * a higher path, this will return the child of that write relative to the write and this path.\n   * Returns null if there is no write at this path.\n   */\n  shadowingWrite(path: Path): Node | null {\n    return this.visibleWrites_.getCompleteNode(path);\n  }\n\n  /**\n   * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\n   * the window, but may now be in the window.\n   */\n  calcIndexedSlice(\n    treePath: Path,\n    completeServerData: Node | null,\n    startPost: NamedNode,\n    count: number,\n    reverse: boolean,\n    index: Index\n  ): NamedNode[] {\n    let toIterate: Node;\n    const merge = this.visibleWrites_.childCompoundWrite(treePath);\n    const shadowingNode = merge.getCompleteNode(Path.Empty);\n    if (shadowingNode != null) {\n      toIterate = shadowingNode;\n    } else if (completeServerData != null) {\n      toIterate = merge.apply(completeServerData);\n    } else {\n      // no children to iterate on\n      return [];\n    }\n    toIterate = toIterate.withIndex(index);\n    if (!toIterate.isEmpty() && !toIterate.isLeafNode()) {\n      const nodes = [];\n      const cmp = index.getCompare();\n      const iter = reverse\n        ? (toIterate as ChildrenNode).getReverseIteratorFrom(startPost, index)\n        : (toIterate as ChildrenNode).getIteratorFrom(startPost, index);\n      let next = iter.getNext();\n      while (next && nodes.length < count) {\n        if (cmp(next, startPost) !== 0) {\n          nodes.push(next);\n        }\n        next = iter.getNext();\n      }\n      return nodes;\n    } else {\n      return [];\n    }\n  }\n\n  private recordContainsPath_(writeRecord: WriteRecord, path: Path): boolean {\n    if (writeRecord.snap) {\n      return writeRecord.path.contains(path);\n    } else {\n      for (const childName in writeRecord.children) {\n        if (\n          writeRecord.children.hasOwnProperty(childName) &&\n          writeRecord.path.child(childName).contains(path)\n        ) {\n          return true;\n        }\n      }\n      return false;\n    }\n  }\n\n  /**\n   * Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots\n   */\n  private resetTree_() {\n    this.visibleWrites_ = WriteTree.layerTree_(\n      this.allWrites_,\n      WriteTree.DefaultFilter_,\n      Path.Empty\n    );\n    if (this.allWrites_.length > 0) {\n      this.lastWriteId_ = this.allWrites_[this.allWrites_.length - 1].writeId;\n    } else {\n      this.lastWriteId_ = -1;\n    }\n  }\n\n  /**\n   * The default filter used when constructing the tree. Keep everything that's visible.\n   */\n  private static DefaultFilter_(write: WriteRecord) {\n    return write.visible;\n  }\n\n  /**\n   * Static method. Given an array of WriteRecords, a filter for which ones to include, and a path, construct the tree of\n   * event data at that path.\n   */\n  private static layerTree_(\n    writes: WriteRecord[],\n    filter: (w: WriteRecord) => boolean,\n    treeRoot: Path\n  ): CompoundWrite {\n    let compoundWrite = CompoundWrite.Empty;\n    for (let i = 0; i < writes.length; ++i) {\n      const write = writes[i];\n      // Theory, a later set will either:\n      // a) abort a relevant transaction, so no need to worry about excluding it from calculating that transaction\n      // b) not be relevant to a transaction (separate branch), so again will not affect the data for that transaction\n      if (filter(write)) {\n        const writePath = write.path;\n        let relativePath;\n        if (write.snap) {\n          if (treeRoot.contains(writePath)) {\n            relativePath = Path.relativePath(treeRoot, writePath);\n            compoundWrite = compoundWrite.addWrite(relativePath, write.snap);\n          } else if (writePath.contains(treeRoot)) {\n            relativePath = Path.relativePath(writePath, treeRoot);\n            compoundWrite = compoundWrite.addWrite(\n              Path.Empty,\n              write.snap.getChild(relativePath)\n            );\n          } else {\n            // There is no overlap between root path and write path, ignore write\n          }\n        } else if (write.children) {\n          if (treeRoot.contains(writePath)) {\n            relativePath = Path.relativePath(treeRoot, writePath);\n            compoundWrite = compoundWrite.addWrites(\n              relativePath,\n              write.children\n            );\n          } else if (writePath.contains(treeRoot)) {\n            relativePath = Path.relativePath(writePath, treeRoot);\n            if (relativePath.isEmpty()) {\n              compoundWrite = compoundWrite.addWrites(\n                Path.Empty,\n                write.children\n              );\n            } else {\n              const child = safeGet(write.children, relativePath.getFront());\n              if (child) {\n                // There exists a child in this node that matches the root path\n                const deepNode = child.getChild(relativePath.popFront());\n                compoundWrite = compoundWrite.addWrite(Path.Empty, deepNode);\n              }\n            }\n          } else {\n            // There is no overlap between root path and write path, ignore write\n          }\n        } else {\n          throw assertionError('WriteRecord should have .snap or .children');\n        }\n      }\n    }\n    return compoundWrite;\n  }\n}\n\n/**\n * A WriteTreeRef wraps a WriteTree and a path, for convenient access to a particular subtree.  All of the methods\n * just proxy to the underlying WriteTree.\n *\n * @constructor\n */\nexport class WriteTreeRef {\n  /**\n   * The path to this particular write tree ref. Used for calling methods on writeTree_ while exposing a simpler\n   * interface to callers.\n   *\n   * @type {!Path}\n   * @private\n   * @const\n   */\n  private readonly treePath_: Path;\n\n  /**\n   * * A reference to the actual tree of write data. All methods are pass-through to the tree, but with the appropriate\n   * path prefixed.\n   *\n   * This lets us make cheap references to points in the tree for sync points without having to copy and maintain all of\n   * the data.\n   *\n   * @type {!WriteTree}\n   * @private\n   * @const\n   */\n  private readonly writeTree_: WriteTree;\n\n  /**\n   * @param {!Path} path\n   * @param {!WriteTree} writeTree\n   */\n  constructor(path: Path, writeTree: WriteTree) {\n    this.treePath_ = path;\n    this.writeTree_ = writeTree;\n  }\n\n  /**\n   * If possible, returns a complete event cache, using the underlying server data if possible. In addition, can be used\n   * to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned node\n   * can lead to a more expensive calculation.\n   *\n   * @param {?Node} completeServerCache\n   * @param {Array.<number>=} writeIdsToExclude Optional writes to exclude.\n   * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\n   * @return {?Node}\n   */\n  calcCompleteEventCache(\n    completeServerCache: Node | null,\n    writeIdsToExclude?: number[],\n    includeHiddenWrites?: boolean\n  ): Node | null {\n    return this.writeTree_.calcCompleteEventCache(\n      this.treePath_,\n      completeServerCache,\n      writeIdsToExclude,\n      includeHiddenWrites\n    );\n  }\n\n  /**\n   * If possible, returns a children node containing all of the complete children we have data for. The returned data is a\n   * mix of the given server data and write data.\n   *\n   * @param {?ChildrenNode} completeServerChildren\n   * @return {!ChildrenNode}\n   */\n  calcCompleteEventChildren(\n    completeServerChildren: ChildrenNode | null\n  ): ChildrenNode {\n    return this.writeTree_.calcCompleteEventChildren(\n      this.treePath_,\n      completeServerChildren\n    ) as ChildrenNode;\n  }\n\n  /**\n   * Given that either the underlying server data has updated or the outstanding writes have updated, determine what,\n   * if anything, needs to be applied to the event cache.\n   *\n   * Possibilities:\n   *\n   * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\n   *\n   * 2. Some write is completely shadowing. No events to be raised\n   *\n   * 3. Is partially shadowed. Events should be raised\n   *\n   * Either existingEventSnap or existingServerSnap must exist, this is validated via an assert\n   *\n   * @param {!Path} path\n   * @param {?Node} existingEventSnap\n   * @param {?Node} existingServerSnap\n   * @return {?Node}\n   */\n  calcEventCacheAfterServerOverwrite(\n    path: Path,\n    existingEventSnap: Node | null,\n    existingServerSnap: Node | null\n  ): Node | null {\n    return this.writeTree_.calcEventCacheAfterServerOverwrite(\n      this.treePath_,\n      path,\n      existingEventSnap,\n      existingServerSnap\n    );\n  }\n\n  /**\n   * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\n   * a higher path, this will return the child of that write relative to the write and this path.\n   * Returns null if there is no write at this path.\n   *\n   * @param {!Path} path\n   * @return {?Node}\n   */\n  shadowingWrite(path: Path): Node | null {\n    return this.writeTree_.shadowingWrite(this.treePath_.child(path));\n  }\n\n  /**\n   * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\n   * the window, but may now be in the window\n   *\n   * @param {?Node} completeServerData\n   * @param {!NamedNode} startPost\n   * @param {!number} count\n   * @param {boolean} reverse\n   * @param {!Index} index\n   * @return {!Array.<!NamedNode>}\n   */\n  calcIndexedSlice(\n    completeServerData: Node | null,\n    startPost: NamedNode,\n    count: number,\n    reverse: boolean,\n    index: Index\n  ): NamedNode[] {\n    return this.writeTree_.calcIndexedSlice(\n      this.treePath_,\n      completeServerData,\n      startPost,\n      count,\n      reverse,\n      index\n    );\n  }\n\n  /**\n   * Returns a complete child for a given server snap after applying all user writes or null if there is no\n   * complete child for this ChildKey.\n   *\n   * @param {!string} childKey\n   * @param {!CacheNode} existingServerCache\n   * @return {?Node}\n   */\n  calcCompleteChild(\n    childKey: string,\n    existingServerCache: CacheNode\n  ): Node | null {\n    return this.writeTree_.calcCompleteChild(\n      this.treePath_,\n      childKey,\n      existingServerCache\n    );\n  }\n\n  /**\n   * Return a WriteTreeRef for a child.\n   *\n   * @param {string} childName\n   * @return {!WriteTreeRef}\n   */\n  child(childName: string): WriteTreeRef {\n    return new WriteTreeRef(this.treePath_.child(childName), this.writeTree_);\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 '@firebase/util';\nimport { errorForServerCode, each } from './util/util';\nimport { AckUserWrite } from './operation/AckUserWrite';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { ImmutableTree } from './util/ImmutableTree';\nimport { ListenComplete } from './operation/ListenComplete';\nimport { Merge } from './operation/Merge';\nimport { Operation, OperationSource } from './operation/Operation';\nimport { Overwrite } from './operation/Overwrite';\nimport { Path } from './util/Path';\nimport { SyncPoint } from './SyncPoint';\nimport { WriteTree, WriteTreeRef } from './WriteTree';\nimport { Query } from '../api/Query';\nimport { Node } from './snap/Node';\nimport { Event } from './view/Event';\nimport { EventRegistration } from './view/EventRegistration';\nimport { View } from './view/View';\n\n/**\n * @typedef {{\n *   startListening: function(\n *     !Query,\n *     ?number,\n *     function():string,\n *     function(!string, *):!Array.<!Event>\n *   ):!Array.<!Event>,\n *\n *   stopListening: function(!Query, ?number)\n * }}\n */\nexport interface ListenProvider {\n  startListening(\n    query: Query,\n    tag: number | null,\n    hashFn: () => string,\n    onComplete: (a: string, b?: unknown) => Event[]\n  ): Event[];\n\n  stopListening(a: Query, b: number | null): void;\n}\n\n/**\n * SyncTree is the central class for managing event callback registration, data caching, views\n * (query processing), and event generation.  There are typically two SyncTree instances for\n * each Repo, one for the normal Firebase data, and one for the .info data.\n *\n * It has a number of responsibilities, including:\n *  - Tracking all user event callbacks (registered via addEventRegistration() and removeEventRegistration()).\n *  - Applying and caching data changes for user set(), transaction(), and update() calls\n *    (applyUserOverwrite(), applyUserMerge()).\n *  - Applying and caching data changes for server data changes (applyServerOverwrite(),\n *    applyServerMerge()).\n *  - Generating user-facing events for server and user changes (all of the apply* methods\n *    return the set of events that need to be raised as a result).\n *  - Maintaining the appropriate set of server listens to ensure we are always subscribed\n *    to the correct set of paths and queries to satisfy the current set of user event\n *    callbacks (listens are started/stopped using the provided listenProvider).\n *\n * NOTE: Although SyncTree tracks event callbacks and calculates events to raise, the actual\n * events are returned to the caller rather than raised synchronously.\n *\n * @constructor\n */\nexport class SyncTree {\n  /**\n   * Tree of SyncPoints.  There's a SyncPoint at any location that has 1 or more views.\n   */\n  private syncPointTree_: ImmutableTree<SyncPoint> = ImmutableTree.Empty;\n\n  /**\n   * A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).\n   */\n  private pendingWriteTree_ = new WriteTree();\n\n  private readonly tagToQueryMap: Map<number, string> = new Map();\n  private readonly queryToTagMap: Map<string, number> = new Map();\n\n  /**\n   * @param {!ListenProvider} listenProvider_ Used by SyncTree to start / stop listening\n   *   to server data.\n   */\n  constructor(private listenProvider_: ListenProvider) {}\n\n  /**\n   * Apply the data changes for a user-generated set() or transaction() call.\n   *\n   * @return Events to raise.\n   */\n  applyUserOverwrite(\n    path: Path,\n    newData: Node,\n    writeId: number,\n    visible?: boolean\n  ): Event[] {\n    // Record pending write.\n    this.pendingWriteTree_.addOverwrite(path, newData, writeId, visible);\n\n    if (!visible) {\n      return [];\n    } else {\n      return this.applyOperationToSyncPoints_(\n        new Overwrite(OperationSource.User, path, newData)\n      );\n    }\n  }\n\n  /**\n   * Apply the data from a user-generated update() call\n   *\n   * @return Events to raise.\n   */\n  applyUserMerge(\n    path: Path,\n    changedChildren: { [k: string]: Node },\n    writeId: number\n  ): Event[] {\n    // Record pending merge.\n    this.pendingWriteTree_.addMerge(path, changedChildren, writeId);\n\n    const changeTree = ImmutableTree.fromObject(changedChildren);\n\n    return this.applyOperationToSyncPoints_(\n      new Merge(OperationSource.User, path, changeTree)\n    );\n  }\n\n  /**\n   * Acknowledge a pending user write that was previously registered with applyUserOverwrite() or applyUserMerge().\n   *\n   * @param revert True if the given write failed and needs to be reverted\n   * @return Events to raise.\n   */\n  ackUserWrite(writeId: number, revert: boolean = false) {\n    const write = this.pendingWriteTree_.getWrite(writeId);\n    const needToReevaluate = this.pendingWriteTree_.removeWrite(writeId);\n    if (!needToReevaluate) {\n      return [];\n    } else {\n      let affectedTree = ImmutableTree.Empty;\n      if (write.snap != null) {\n        // overwrite\n        affectedTree = affectedTree.set(Path.Empty, true);\n      } else {\n        each(write.children, (pathString: string, node: Node) => {\n          affectedTree = affectedTree.set(new Path(pathString), node);\n        });\n      }\n      return this.applyOperationToSyncPoints_(\n        new AckUserWrite(write.path, affectedTree, revert)\n      );\n    }\n  }\n\n  /**\n   * Apply new server data for the specified path..\n   *\n   * @return Events to raise.\n   */\n  applyServerOverwrite(path: Path, newData: Node): Event[] {\n    return this.applyOperationToSyncPoints_(\n      new Overwrite(OperationSource.Server, path, newData)\n    );\n  }\n\n  /**\n   * Apply new server data to be merged in at the specified path.\n   *\n   * @return Events to raise.\n   */\n  applyServerMerge(\n    path: Path,\n    changedChildren: { [k: string]: Node }\n  ): Event[] {\n    const changeTree = ImmutableTree.fromObject(changedChildren);\n\n    return this.applyOperationToSyncPoints_(\n      new Merge(OperationSource.Server, path, changeTree)\n    );\n  }\n\n  /**\n   * Apply a listen complete for a query\n   *\n   * @return Events to raise.\n   */\n  applyListenComplete(path: Path): Event[] {\n    return this.applyOperationToSyncPoints_(\n      new ListenComplete(OperationSource.Server, path)\n    );\n  }\n\n  /**\n   * Apply new server data for the specified tagged query.\n   *\n   * @return Events to raise.\n   */\n  applyTaggedQueryOverwrite(path: Path, snap: Node, tag: number): Event[] {\n    const queryKey = this.queryKeyForTag_(tag);\n    if (queryKey != null) {\n      const r = SyncTree.parseQueryKey_(queryKey);\n      const queryPath = r.path,\n        queryId = r.queryId;\n      const relativePath = Path.relativePath(queryPath, path);\n      const op = new Overwrite(\n        OperationSource.forServerTaggedQuery(queryId),\n        relativePath,\n        snap\n      );\n      return this.applyTaggedOperation_(queryPath, op);\n    } else {\n      // Query must have been removed already\n      return [];\n    }\n  }\n\n  /**\n   * Apply server data to be merged in for the specified tagged query.\n   *\n   * @return Events to raise.\n   */\n  applyTaggedQueryMerge(\n    path: Path,\n    changedChildren: { [k: string]: Node },\n    tag: number\n  ): Event[] {\n    const queryKey = this.queryKeyForTag_(tag);\n    if (queryKey) {\n      const r = SyncTree.parseQueryKey_(queryKey);\n      const queryPath = r.path,\n        queryId = r.queryId;\n      const relativePath = Path.relativePath(queryPath, path);\n      const changeTree = ImmutableTree.fromObject(changedChildren);\n      const op = new Merge(\n        OperationSource.forServerTaggedQuery(queryId),\n        relativePath,\n        changeTree\n      );\n      return this.applyTaggedOperation_(queryPath, op);\n    } else {\n      // We've already removed the query. No big deal, ignore the update\n      return [];\n    }\n  }\n\n  /**\n   * Apply a listen complete for a tagged query\n   *\n   * @return Events to raise.\n   */\n  applyTaggedListenComplete(path: Path, tag: number): Event[] {\n    const queryKey = this.queryKeyForTag_(tag);\n    if (queryKey) {\n      const r = SyncTree.parseQueryKey_(queryKey);\n      const queryPath = r.path,\n        queryId = r.queryId;\n      const relativePath = Path.relativePath(queryPath, path);\n      const op = new ListenComplete(\n        OperationSource.forServerTaggedQuery(queryId),\n        relativePath\n      );\n      return this.applyTaggedOperation_(queryPath, op);\n    } else {\n      // We've already removed the query. No big deal, ignore the update\n      return [];\n    }\n  }\n\n  /**\n   * Add an event callback for the specified query.\n   *\n   * @return Events to raise.\n   */\n  addEventRegistration(\n    query: Query,\n    eventRegistration: EventRegistration\n  ): Event[] {\n    const path = query.path;\n\n    let serverCache: Node | null = null;\n    let foundAncestorDefaultView = false;\n    // Any covering writes will necessarily be at the root, so really all we need to find is the server cache.\n    // Consider optimizing this once there's a better understanding of what actual behavior will be.\n    this.syncPointTree_.foreachOnPath(path, (pathToSyncPoint, sp) => {\n      const relativePath = Path.relativePath(pathToSyncPoint, path);\n      serverCache = serverCache || sp.getCompleteServerCache(relativePath);\n      foundAncestorDefaultView =\n        foundAncestorDefaultView || sp.hasCompleteView();\n    });\n    let syncPoint = this.syncPointTree_.get(path);\n    if (!syncPoint) {\n      syncPoint = new SyncPoint();\n      this.syncPointTree_ = this.syncPointTree_.set(path, syncPoint);\n    } else {\n      foundAncestorDefaultView =\n        foundAncestorDefaultView || syncPoint.hasCompleteView();\n      serverCache = serverCache || syncPoint.getCompleteServerCache(Path.Empty);\n    }\n\n    let serverCacheComplete;\n    if (serverCache != null) {\n      serverCacheComplete = true;\n    } else {\n      serverCacheComplete = false;\n      serverCache = ChildrenNode.EMPTY_NODE;\n      const subtree = this.syncPointTree_.subtree(path);\n      subtree.foreachChild((childName, childSyncPoint) => {\n        const completeCache = childSyncPoint.getCompleteServerCache(Path.Empty);\n        if (completeCache) {\n          serverCache = serverCache.updateImmediateChild(\n            childName,\n            completeCache\n          );\n        }\n      });\n    }\n\n    const viewAlreadyExists = syncPoint.viewExistsForQuery(query);\n    if (!viewAlreadyExists && !query.getQueryParams().loadsAllData()) {\n      // We need to track a tag for this query\n      const queryKey = SyncTree.makeQueryKey_(query);\n      assert(\n        !this.queryToTagMap.has(queryKey),\n        'View does not exist, but we have a tag'\n      );\n      const tag = SyncTree.getNextQueryTag_();\n      this.queryToTagMap.set(queryKey, tag);\n      this.tagToQueryMap.set(tag, queryKey);\n    }\n    const writesCache = this.pendingWriteTree_.childWrites(path);\n    let events = syncPoint.addEventRegistration(\n      query,\n      eventRegistration,\n      writesCache,\n      serverCache,\n      serverCacheComplete\n    );\n    if (!viewAlreadyExists && !foundAncestorDefaultView) {\n      const view /** @type !View */ = syncPoint.viewForQuery(query);\n      events = events.concat(this.setupListener_(query, view));\n    }\n    return events;\n  }\n\n  /**\n   * Remove event callback(s).\n   *\n   * If query is the default query, we'll check all queries for the specified eventRegistration.\n   * If eventRegistration is null, we'll remove all callbacks for the specified query/queries.\n   *\n   * @param eventRegistration If null, all callbacks are removed.\n   * @param cancelError If a cancelError is provided, appropriate cancel events will be returned.\n   * @return Cancel events, if cancelError was provided.\n   */\n  removeEventRegistration(\n    query: Query,\n    eventRegistration: EventRegistration | null,\n    cancelError?: Error\n  ): Event[] {\n    // Find the syncPoint first. Then deal with whether or not it has matching listeners\n    const path = query.path;\n    const maybeSyncPoint = this.syncPointTree_.get(path);\n    let cancelEvents: Event[] = [];\n    // A removal on a default query affects all queries at that location. A removal on an indexed query, even one without\n    // other query constraints, does *not* affect all queries at that location. So this check must be for 'default', and\n    // not loadsAllData().\n    if (\n      maybeSyncPoint &&\n      (query.queryIdentifier() === 'default' ||\n        maybeSyncPoint.viewExistsForQuery(query))\n    ) {\n      /**\n       * @type {{removed: !Array.<!Query>, events: !Array.<!Event>}}\n       */\n      const removedAndEvents = maybeSyncPoint.removeEventRegistration(\n        query,\n        eventRegistration,\n        cancelError\n      );\n      if (maybeSyncPoint.isEmpty()) {\n        this.syncPointTree_ = this.syncPointTree_.remove(path);\n      }\n      const removed = removedAndEvents.removed;\n      cancelEvents = removedAndEvents.events;\n      // We may have just removed one of many listeners and can short-circuit this whole process\n      // We may also not have removed a default listener, in which case all of the descendant listeners should already be\n      // properly set up.\n      //\n      // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData(), instead of\n      // queryId === 'default'\n      const removingDefault =\n        -1 !==\n        removed.findIndex(query => {\n          return query.getQueryParams().loadsAllData();\n        });\n      const covered = this.syncPointTree_.findOnPath(\n        path,\n        (relativePath, parentSyncPoint) => {\n          return parentSyncPoint.hasCompleteView();\n        }\n      );\n\n      if (removingDefault && !covered) {\n        const subtree = this.syncPointTree_.subtree(path);\n        // There are potentially child listeners. Determine what if any listens we need to send before executing the\n        // removal\n        if (!subtree.isEmpty()) {\n          // We need to fold over our subtree and collect the listeners to send\n          const newViews = this.collectDistinctViewsForSubTree_(subtree);\n\n          // Ok, we've collected all the listens we need. Set them up.\n          for (let i = 0; i < newViews.length; ++i) {\n            const view = newViews[i],\n              newQuery = view.getQuery();\n            const listener = this.createListenerForView_(view);\n            this.listenProvider_.startListening(\n              SyncTree.queryForListening_(newQuery),\n              this.tagForQuery_(newQuery),\n              listener.hashFn,\n              listener.onComplete\n            );\n          }\n        } else {\n          // There's nothing below us, so nothing we need to start listening on\n        }\n      }\n      // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query\n      // The above block has us covered in terms of making sure we're set up on listens lower in the tree.\n      // Also, note that if we have a cancelError, it's already been removed at the provider level.\n      if (!covered && removed.length > 0 && !cancelError) {\n        // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one\n        // default. Otherwise, we need to iterate through and cancel each individual query\n        if (removingDefault) {\n          // We don't tag default listeners\n          const defaultTag: number | null = null;\n          this.listenProvider_.stopListening(\n            SyncTree.queryForListening_(query),\n            defaultTag\n          );\n        } else {\n          removed.forEach((queryToRemove: Query) => {\n            const tagToRemove = this.queryToTagMap.get(\n              SyncTree.makeQueryKey_(queryToRemove)\n            );\n            this.listenProvider_.stopListening(\n              SyncTree.queryForListening_(queryToRemove),\n              tagToRemove\n            );\n          });\n        }\n      }\n      // Now, clear all of the tags we're tracking for the removed listens\n      this.removeTags_(removed);\n    } else {\n      // No-op, this listener must've been already removed\n    }\n    return cancelEvents;\n  }\n\n  /**\n   * Returns a complete cache, if we have one, of the data at a particular path. If the location does not have a\n   * listener above it, we will get a false \"null\". This shouldn't be a problem because transactions will always\n   * have a listener above, and atomic operations would correctly show a jitter of <increment value> ->\n   *     <incremented total> as the write is applied locally and then acknowledged at the server.\n   *\n   * Note: this method will *include* hidden writes from transaction with applyLocally set to false.\n   *\n   * @param path The path to the data we want\n   * @param writeIdsToExclude A specific set to be excluded\n   */\n  calcCompleteEventCache(path: Path, writeIdsToExclude?: number[]): Node {\n    const includeHiddenSets = true;\n    const writeTree = this.pendingWriteTree_;\n    const serverCache = this.syncPointTree_.findOnPath(\n      path,\n      (pathSoFar, syncPoint) => {\n        const relativePath = Path.relativePath(pathSoFar, path);\n        const serverCache = syncPoint.getCompleteServerCache(relativePath);\n        if (serverCache) {\n          return serverCache;\n        }\n      }\n    );\n    return writeTree.calcCompleteEventCache(\n      path,\n      serverCache,\n      writeIdsToExclude,\n      includeHiddenSets\n    );\n  }\n\n  /**\n   * This collapses multiple unfiltered views into a single view, since we only need a single\n   * listener for them.\n   */\n  private collectDistinctViewsForSubTree_(\n    subtree: ImmutableTree<SyncPoint>\n  ): View[] {\n    return subtree.fold<View[]>(\n      (relativePath, maybeChildSyncPoint, childMap) => {\n        if (maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {\n          const completeView = maybeChildSyncPoint.getCompleteView();\n          return [completeView];\n        } else {\n          // No complete view here, flatten any deeper listens into an array\n          let views: View[] = [];\n          if (maybeChildSyncPoint) {\n            views = maybeChildSyncPoint.getQueryViews();\n          }\n          each(childMap, (_key: string, childViews: View[]) => {\n            views = views.concat(childViews);\n          });\n          return views;\n        }\n      }\n    );\n  }\n\n  private removeTags_(queries: Query[]) {\n    for (let j = 0; j < queries.length; ++j) {\n      const removedQuery = queries[j];\n      if (!removedQuery.getQueryParams().loadsAllData()) {\n        // We should have a tag for this\n        const removedQueryKey = SyncTree.makeQueryKey_(removedQuery);\n        const removedQueryTag = this.queryToTagMap.get(removedQueryKey);\n        this.queryToTagMap.delete(removedQueryKey);\n        this.tagToQueryMap.delete(removedQueryTag);\n      }\n    }\n  }\n\n  /**\n   * Normalizes a query to a query we send the server for listening\n   *\n   * @return The normalized query\n   */\n  private static queryForListening_(query: Query): Query {\n    if (\n      query.getQueryParams().loadsAllData() &&\n      !query.getQueryParams().isDefault()\n    ) {\n      // We treat queries that load all data as default queries\n      // Cast is necessary because ref() technically returns Firebase which is actually fb.api.Firebase which inherits\n      // from Query\n      return query.getRef()!;\n    } else {\n      return query;\n    }\n  }\n\n  /**\n   * For a given new listen, manage the de-duplication of outstanding subscriptions.\n   *\n   * @return This method can return events to support synchronous data sources\n   */\n  private setupListener_(query: Query, view: View): Event[] {\n    const path = query.path;\n    const tag = this.tagForQuery_(query);\n    const listener = this.createListenerForView_(view);\n\n    const events = this.listenProvider_.startListening(\n      SyncTree.queryForListening_(query),\n      tag,\n      listener.hashFn,\n      listener.onComplete\n    );\n\n    const subtree = this.syncPointTree_.subtree(path);\n    // The root of this subtree has our query. We're here because we definitely need to send a listen for that, but we\n    // may need to shadow other listens as well.\n    if (tag) {\n      assert(\n        !subtree.value.hasCompleteView(),\n        \"If we're adding a query, it shouldn't be shadowed\"\n      );\n    } else {\n      // Shadow everything at or below this location, this is a default listener.\n      const queriesToStop = subtree.fold<Query[]>(\n        (relativePath, maybeChildSyncPoint, childMap) => {\n          if (\n            !relativePath.isEmpty() &&\n            maybeChildSyncPoint &&\n            maybeChildSyncPoint.hasCompleteView()\n          ) {\n            return [maybeChildSyncPoint.getCompleteView().getQuery()];\n          } else {\n            // No default listener here, flatten any deeper queries into an array\n            let queries: Query[] = [];\n            if (maybeChildSyncPoint) {\n              queries = queries.concat(\n                maybeChildSyncPoint.getQueryViews().map(view => view.getQuery())\n              );\n            }\n            each(childMap, (_key: string, childQueries: Query[]) => {\n              queries = queries.concat(childQueries);\n            });\n            return queries;\n          }\n        }\n      );\n      for (let i = 0; i < queriesToStop.length; ++i) {\n        const queryToStop = queriesToStop[i];\n        this.listenProvider_.stopListening(\n          SyncTree.queryForListening_(queryToStop),\n          this.tagForQuery_(queryToStop)\n        );\n      }\n    }\n    return events;\n  }\n\n  private createListenerForView_(\n    view: View\n  ): { hashFn(): string; onComplete(a: string, b?: unknown): Event[] } {\n    const query = view.getQuery();\n    const tag = this.tagForQuery_(query);\n\n    return {\n      hashFn: () => {\n        const cache = view.getServerCache() || ChildrenNode.EMPTY_NODE;\n        return cache.hash();\n      },\n      onComplete: (status: string): Event[] => {\n        if (status === 'ok') {\n          if (tag) {\n            return this.applyTaggedListenComplete(query.path, tag);\n          } else {\n            return this.applyListenComplete(query.path);\n          }\n        } else {\n          // If a listen failed, kill all of the listeners here, not just the one that triggered the error.\n          // Note that this may need to be scoped to just this listener if we change permissions on filtered children\n          const error = errorForServerCode(status, query);\n          return this.removeEventRegistration(\n            query,\n            /*eventRegistration*/ null,\n            error\n          );\n        }\n      }\n    };\n  }\n\n  /**\n   * Given a query, computes a \"queryKey\" suitable for use in our queryToTagMap_.\n   */\n  private static makeQueryKey_(query: Query): string {\n    return query.path.toString() + '$' + query.queryIdentifier();\n  }\n\n  /**\n   * Given a queryKey (created by makeQueryKey), parse it back into a path and queryId.\n   */\n  private static parseQueryKey_(\n    queryKey: string\n  ): { queryId: string; path: Path } {\n    const splitIndex = queryKey.indexOf('$');\n    assert(\n      splitIndex !== -1 && splitIndex < queryKey.length - 1,\n      'Bad queryKey.'\n    );\n    return {\n      queryId: queryKey.substr(splitIndex + 1),\n      path: new Path(queryKey.substr(0, splitIndex))\n    };\n  }\n\n  /**\n   * Return the query associated with the given tag, if we have one\n   */\n  private queryKeyForTag_(tag: number): string | null {\n    return this.tagToQueryMap.get(tag);\n  }\n\n  /**\n   * Return the tag associated with the given query.\n   */\n  private tagForQuery_(query: Query): number | null {\n    const queryKey = SyncTree.makeQueryKey_(query);\n    return this.queryToTagMap.get(queryKey);\n  }\n\n  /**\n   * Static tracker for next query tag.\n   */\n  private static nextQueryTag_ = 1;\n\n  /**\n   * Static accessor for query tags.\n   */\n  private static getNextQueryTag_(): number {\n    return SyncTree.nextQueryTag_++;\n  }\n\n  /**\n   * A helper method to apply tagged operations\n   */\n  private applyTaggedOperation_(\n    queryPath: Path,\n    operation: Operation\n  ): Event[] {\n    const syncPoint = this.syncPointTree_.get(queryPath);\n    assert(syncPoint, \"Missing sync point for query tag that we're tracking\");\n    const writesCache = this.pendingWriteTree_.childWrites(queryPath);\n    return syncPoint.applyOperation(\n      operation,\n      writesCache,\n      /*serverCache=*/ null\n    );\n  }\n\n  /**\n   * A helper method that visits all descendant and ancestor SyncPoints, applying the operation.\n   *\n   * NOTES:\n   * - Descendant SyncPoints will be visited first (since we raise events depth-first).\n   *\n   * - We call applyOperation() on each SyncPoint passing three things:\n   *   1. A version of the Operation that has been made relative to the SyncPoint location.\n   *   2. A WriteTreeRef of any writes we have cached at the SyncPoint location.\n   *   3. A snapshot Node with cached server data, if we have it.\n   *\n   * - We concatenate all of the events returned by each SyncPoint and return the result.\n   */\n  private applyOperationToSyncPoints_(operation: Operation): Event[] {\n    return this.applyOperationHelper_(\n      operation,\n      this.syncPointTree_,\n      /*serverCache=*/ null,\n      this.pendingWriteTree_.childWrites(Path.Empty)\n    );\n  }\n\n  /**\n   * Recursive helper for applyOperationToSyncPoints_\n   */\n  private applyOperationHelper_(\n    operation: Operation,\n    syncPointTree: ImmutableTree<SyncPoint>,\n    serverCache: Node | null,\n    writesCache: WriteTreeRef\n  ): Event[] {\n    if (operation.path.isEmpty()) {\n      return this.applyOperationDescendantsHelper_(\n        operation,\n        syncPointTree,\n        serverCache,\n        writesCache\n      );\n    } else {\n      const syncPoint = syncPointTree.get(Path.Empty);\n\n      // If we don't have cached server data, see if we can get it from this SyncPoint.\n      if (serverCache == null && syncPoint != null) {\n        serverCache = syncPoint.getCompleteServerCache(Path.Empty);\n      }\n\n      let events: Event[] = [];\n      const childName = operation.path.getFront();\n      const childOperation = operation.operationForChild(childName);\n      const childTree = syncPointTree.children.get(childName);\n      if (childTree && childOperation) {\n        const childServerCache = serverCache\n          ? serverCache.getImmediateChild(childName)\n          : null;\n        const childWritesCache = writesCache.child(childName);\n        events = events.concat(\n          this.applyOperationHelper_(\n            childOperation,\n            childTree,\n            childServerCache,\n            childWritesCache\n          )\n        );\n      }\n\n      if (syncPoint) {\n        events = events.concat(\n          syncPoint.applyOperation(operation, writesCache, serverCache)\n        );\n      }\n\n      return events;\n    }\n  }\n\n  /**\n   * Recursive helper for applyOperationToSyncPoints_\n   */\n  private applyOperationDescendantsHelper_(\n    operation: Operation,\n    syncPointTree: ImmutableTree<SyncPoint>,\n    serverCache: Node | null,\n    writesCache: WriteTreeRef\n  ): Event[] {\n    const syncPoint = syncPointTree.get(Path.Empty);\n\n    // If we don't have cached server data, see if we can get it from this SyncPoint.\n    if (serverCache == null && syncPoint != null) {\n      serverCache = syncPoint.getCompleteServerCache(Path.Empty);\n    }\n\n    let events: Event[] = [];\n    syncPointTree.children.inorderTraversal((childName, childTree) => {\n      const childServerCache = serverCache\n        ? serverCache.getImmediateChild(childName)\n        : null;\n      const childWritesCache = writesCache.child(childName);\n      const childOperation = operation.operationForChild(childName);\n      if (childOperation) {\n        events = events.concat(\n          this.applyOperationDescendantsHelper_(\n            childOperation,\n            childTree,\n            childServerCache,\n            childWritesCache\n          )\n        );\n      }\n    });\n\n    if (syncPoint) {\n      events = events.concat(\n        syncPoint.applyOperation(operation, writesCache, serverCache)\n      );\n    }\n\n    return events;\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 { ChildrenNode } from './snap/ChildrenNode';\nimport { Path } from './util/Path';\nimport { Node } from './snap/Node';\n\n/**\n * Mutable object which basically just stores a reference to the \"latest\" immutable snapshot.\n *\n * @constructor\n */\nexport class SnapshotHolder {\n  private rootNode_: Node = ChildrenNode.EMPTY_NODE;\n\n  getNode(path: Path): Node {\n    return this.rootNode_.getChild(path);\n  }\n\n  updateSnapshot(path: Path, newSnapshotNode: Node) {\n    this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode);\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 { deepCopy, contains } from '@firebase/util';\n\n/**\n * Tracks a collection of stats.\n *\n * @constructor\n */\nexport class StatsCollection {\n  private counters_: { [k: string]: number } = {};\n\n  incrementCounter(name: string, amount: number = 1) {\n    if (!contains(this.counters_, name)) {\n      this.counters_[name] = 0;\n    }\n\n    this.counters_[name] += amount;\n  }\n\n  get() {\n    return deepCopy(this.counters_);\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 { StatsCollection } from './StatsCollection';\nimport { RepoInfo } from '../RepoInfo';\n\nexport class StatsManager {\n  private static collections_: { [k: string]: StatsCollection } = {};\n  private static reporters_: { [k: string]: unknown } = {};\n\n  static getCollection(repoInfo: RepoInfo): StatsCollection {\n    const hashString = repoInfo.toString();\n\n    if (!this.collections_[hashString]) {\n      this.collections_[hashString] = new StatsCollection();\n    }\n\n    return this.collections_[hashString];\n  }\n\n  static getOrCreateReporter<T>(\n    repoInfo: RepoInfo,\n    creatorFunction: () => T\n  ): T {\n    const hashString = repoInfo.toString();\n\n    if (!this.reporters_[hashString]) {\n      this.reporters_[hashString] = creatorFunction();\n    }\n\n    return this.reporters_[hashString] as T;\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 { StatsCollection } from './StatsCollection';\nimport { each } from '../util/util';\n\n/**\n * Returns the delta from the previous call to get stats.\n *\n * @param collection_ The collection to \"listen\" to.\n * @constructor\n */\nexport class StatsListener {\n  private last_: { [k: string]: number } | null = null;\n\n  constructor(private collection_: StatsCollection) {}\n\n  get(): { [k: string]: number } {\n    const newStats = this.collection_.get();\n\n    const delta = { ...newStats };\n    if (this.last_) {\n      each(this.last_, (stat: string, value: number) => {\n        delta[stat] = delta[stat] - value;\n      });\n    }\n    this.last_ = newStats;\n\n    return delta;\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 { contains } from '@firebase/util';\nimport { setTimeoutNonBlocking, each } from '../util/util';\nimport { StatsListener } from './StatsListener';\nimport { StatsCollection } from './StatsCollection';\nimport { ServerActions } from '../ServerActions';\n\n// Assuming some apps may have a short amount of time on page, and a bulk of firebase operations probably\n// happen on page load, we try to report our first set of stats pretty quickly, but we wait at least 10\n// seconds to try to ensure the Firebase connection is established / settled.\nconst FIRST_STATS_MIN_TIME = 10 * 1000;\nconst FIRST_STATS_MAX_TIME = 30 * 1000;\n\n// We'll continue to report stats on average every 5 minutes.\nconst REPORT_STATS_INTERVAL = 5 * 60 * 1000;\n\n/**\n * @constructor\n */\nexport class StatsReporter {\n  private statsListener_: StatsListener;\n  private statsToReport_: { [k: string]: boolean } = {};\n\n  /**\n   * @param collection\n   * @param server_\n   */\n  constructor(collection: StatsCollection, private server_: ServerActions) {\n    this.statsListener_ = new StatsListener(collection);\n\n    const timeout =\n      FIRST_STATS_MIN_TIME +\n      (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random();\n    setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(timeout));\n  }\n\n  includeStat(stat: string) {\n    this.statsToReport_[stat] = true;\n  }\n\n  private reportStats_() {\n    const stats = this.statsListener_.get();\n    const reportedStats: typeof stats = {};\n    let haveStatsToReport = false;\n\n    each(stats, (stat: string, value: number) => {\n      if (value > 0 && contains(this.statsToReport_, stat)) {\n        reportedStats[stat] = value;\n        haveStatsToReport = true;\n      }\n    });\n\n    if (haveStatsToReport) {\n      this.server_.reportStats(reportedStats);\n    }\n\n    // queue our next run.\n    setTimeoutNonBlocking(\n      this.reportStats_.bind(this),\n      Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL)\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 { Path } from '../util/Path';\nimport { log, logger, exceptionGuard } from '../util/util';\nimport { Event } from './Event';\n\n/**\n * The event queue serves a few purposes:\n * 1. It ensures we maintain event order in the face of event callbacks doing operations that result in more\n *    events being queued.\n * 2. raiseQueuedEvents() handles being called reentrantly nicely.  That is, if in the course of raising events,\n *    raiseQueuedEvents() is called again, the \"inner\" call will pick up raising events where the \"outer\" call\n *    left off, ensuring that the events are still raised synchronously and in order.\n * 3. You can use raiseEventsAtPath and raiseEventsForChangedPath to ensure only relevant previously-queued\n *    events are raised synchronously.\n *\n * NOTE: This can all go away if/when we move to async events.\n *\n * @constructor\n */\nexport class EventQueue {\n  /**\n   * @private\n   * @type {!Array.<EventList>}\n   */\n  private eventLists_: EventList[] = [];\n\n  /**\n   * Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.\n   * @private\n   * @type {!number}\n   */\n  private recursionDepth_ = 0;\n\n  /**\n   * @param {!Array.<Event>} eventDataList The new events to queue.\n   */\n  queueEvents(eventDataList: Event[]) {\n    // We group events by path, storing them in a single EventList, to make it easier to skip over them quickly.\n    let currList = null;\n    for (let i = 0; i < eventDataList.length; i++) {\n      const eventData = eventDataList[i];\n      const eventPath = eventData.getPath();\n      if (currList !== null && !eventPath.equals(currList.getPath())) {\n        this.eventLists_.push(currList);\n        currList = null;\n      }\n\n      if (currList === null) {\n        currList = new EventList(eventPath);\n      }\n\n      currList.add(eventData);\n    }\n    if (currList) {\n      this.eventLists_.push(currList);\n    }\n  }\n\n  /**\n   * Queues the specified events and synchronously raises all events (including previously queued ones)\n   * for the specified path.\n   *\n   * It is assumed that the new events are all for the specified path.\n   *\n   * @param {!Path} path The path to raise events for.\n   * @param {!Array.<Event>} eventDataList The new events to raise.\n   */\n  raiseEventsAtPath(path: Path, eventDataList: Event[]) {\n    this.queueEvents(eventDataList);\n    this.raiseQueuedEventsMatchingPredicate_((eventPath: Path) =>\n      eventPath.equals(path)\n    );\n  }\n\n  /**\n   * Queues the specified events and synchronously raises all events (including previously queued ones) for\n   * locations related to the specified change path (i.e. all ancestors and descendants).\n   *\n   * It is assumed that the new events are all related (ancestor or descendant) to the specified path.\n   *\n   * @param {!Path} changedPath The path to raise events for.\n   * @param {!Array.<!Event>} eventDataList The events to raise\n   */\n  raiseEventsForChangedPath(changedPath: Path, eventDataList: Event[]) {\n    this.queueEvents(eventDataList);\n\n    this.raiseQueuedEventsMatchingPredicate_((eventPath: Path) => {\n      return eventPath.contains(changedPath) || changedPath.contains(eventPath);\n    });\n  }\n\n  /**\n   * @param {!function(!Path):boolean} predicate\n   * @private\n   */\n  private raiseQueuedEventsMatchingPredicate_(\n    predicate: (path: Path) => boolean\n  ) {\n    this.recursionDepth_++;\n\n    let sentAll = true;\n    for (let i = 0; i < this.eventLists_.length; i++) {\n      const eventList = this.eventLists_[i];\n      if (eventList) {\n        const eventPath = eventList.getPath();\n        if (predicate(eventPath)) {\n          this.eventLists_[i].raise();\n          this.eventLists_[i] = null;\n        } else {\n          sentAll = false;\n        }\n      }\n    }\n\n    if (sentAll) {\n      this.eventLists_ = [];\n    }\n\n    this.recursionDepth_--;\n  }\n}\n\n/**\n * @param {!Path} path\n * @constructor\n */\nexport class EventList {\n  /**\n   * @type {!Array.<Event>}\n   * @private\n   */\n  private events_: Event[] = [];\n\n  constructor(private readonly path_: Path) {}\n\n  /**\n   * @param {!Event} eventData\n   */\n  add(eventData: Event) {\n    this.events_.push(eventData);\n  }\n\n  /**\n   * Iterates through the list and raises each event\n   */\n  raise() {\n    for (let i = 0; i < this.events_.length; i++) {\n      const eventData = this.events_[i];\n      if (eventData !== null) {\n        this.events_[i] = null;\n        const eventFn = eventData.getEventRunner();\n        if (logger) {\n          log('event: ' + eventData.toString());\n        }\n        exceptionGuard(eventFn);\n      }\n    }\n  }\n\n  /**\n   * @return {!Path}\n   */\n  getPath(): Path {\n    return this.path_;\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 '@firebase/util';\n\n/**\n * Base class to be used if you want to emit events. Call the constructor with\n * the set of allowed event names.\n */\nexport abstract class EventEmitter {\n  private listeners_: {\n    [eventType: string]: Array<{\n      callback(...args: unknown[]): void;\n      context: unknown;\n    }>;\n  } = {};\n\n  /**\n   * @param {!Array.<string>} allowedEvents_\n   */\n  constructor(private allowedEvents_: string[]) {\n    assert(\n      Array.isArray(allowedEvents_) && allowedEvents_.length > 0,\n      'Requires a non-empty array'\n    );\n  }\n\n  /**\n   * To be overridden by derived classes in order to fire an initial event when\n   * somebody subscribes for data.\n   *\n   * @param {!string} eventType\n   * @return {Array.<*>} Array of parameters to trigger initial event with.\n   */\n  abstract getInitialEvent(eventType: string): unknown[];\n\n  /**\n   * To be called by derived classes to trigger events.\n   * @param {!string} eventType\n   * @param {...*} varArgs\n   */\n  protected trigger(eventType: string, ...varArgs: unknown[]) {\n    if (Array.isArray(this.listeners_[eventType])) {\n      // Clone the list, since callbacks could add/remove listeners.\n      const listeners = [...this.listeners_[eventType]];\n\n      for (let i = 0; i < listeners.length; i++) {\n        listeners[i].callback.apply(listeners[i].context, varArgs);\n      }\n    }\n  }\n\n  on(eventType: string, callback: (a: unknown) => void, context: unknown) {\n    this.validateEventType_(eventType);\n    this.listeners_[eventType] = this.listeners_[eventType] || [];\n    this.listeners_[eventType].push({ callback, context });\n\n    const eventData = this.getInitialEvent(eventType);\n    if (eventData) {\n      callback.apply(context, eventData);\n    }\n  }\n\n  off(eventType: string, callback: (a: unknown) => void, context: unknown) {\n    this.validateEventType_(eventType);\n    const listeners = this.listeners_[eventType] || [];\n    for (let i = 0; i < listeners.length; i++) {\n      if (\n        listeners[i].callback === callback &&\n        (!context || context === listeners[i].context)\n      ) {\n        listeners.splice(i, 1);\n        return;\n      }\n    }\n  }\n\n  private validateEventType_(eventType: string) {\n    assert(\n      this.allowedEvents_.find(et => {\n        return et === eventType;\n      }),\n      'Unknown event: ' + eventType\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 { EventEmitter } from './EventEmitter';\nimport { assert } from '@firebase/util';\n\ndeclare const document: Document;\n\n/**\n * @extends {EventEmitter}\n */\nexport class VisibilityMonitor extends EventEmitter {\n  private visible_: boolean;\n\n  static getInstance() {\n    return new VisibilityMonitor();\n  }\n\n  constructor() {\n    super(['visible']);\n    let hidden: string;\n    let visibilityChange: string;\n    if (\n      typeof document !== 'undefined' &&\n      typeof document.addEventListener !== 'undefined'\n    ) {\n      if (typeof document['hidden'] !== 'undefined') {\n        // Opera 12.10 and Firefox 18 and later support\n        visibilityChange = 'visibilitychange';\n        hidden = 'hidden';\n      } else if (typeof document['mozHidden'] !== 'undefined') {\n        visibilityChange = 'mozvisibilitychange';\n        hidden = 'mozHidden';\n      } else if (typeof document['msHidden'] !== 'undefined') {\n        visibilityChange = 'msvisibilitychange';\n        hidden = 'msHidden';\n      } else if (typeof document['webkitHidden'] !== 'undefined') {\n        visibilityChange = 'webkitvisibilitychange';\n        hidden = 'webkitHidden';\n      }\n    }\n\n    // Initially, we always assume we are visible. This ensures that in browsers\n    // without page visibility support or in cases where we are never visible\n    // (e.g. chrome extension), we act as if we are visible, i.e. don't delay\n    // reconnects\n    this.visible_ = true;\n\n    if (visibilityChange) {\n      document.addEventListener(\n        visibilityChange,\n        () => {\n          const visible = !document[hidden];\n          if (visible !== this.visible_) {\n            this.visible_ = visible;\n            this.trigger('visible', visible);\n          }\n        },\n        false\n      );\n    }\n  }\n\n  /**\n   * @param {!string} eventType\n   * @return {Array.<boolean>}\n   */\n  getInitialEvent(eventType: string): boolean[] {\n    assert(eventType === 'visible', 'Unknown event type: ' + eventType);\n    return [this.visible_];\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, isMobileCordova } from '@firebase/util';\nimport { EventEmitter } from './EventEmitter';\n\n/**\n * Monitors online state (as reported by window.online/offline events).\n *\n * The expectation is that this could have many false positives (thinks we are online\n * when we're not), but no false negatives.  So we can safely use it to determine when\n * we definitely cannot reach the internet.\n *\n * @extends {EventEmitter}\n */\nexport class OnlineMonitor extends EventEmitter {\n  private online_ = true;\n\n  static getInstance() {\n    return new OnlineMonitor();\n  }\n\n  constructor() {\n    super(['online']);\n\n    // We've had repeated complaints that Cordova apps can get stuck \"offline\", e.g.\n    // https://forum.ionicframework.com/t/firebase-connection-is-lost-and-never-come-back/43810\n    // It would seem that the 'online' event does not always fire consistently. So we disable it\n    // for Cordova.\n    if (\n      typeof window !== 'undefined' &&\n      typeof window.addEventListener !== 'undefined' &&\n      !isMobileCordova()\n    ) {\n      window.addEventListener(\n        'online',\n        () => {\n          if (!this.online_) {\n            this.online_ = true;\n            this.trigger('online', true);\n          }\n        },\n        false\n      );\n\n      window.addEventListener(\n        'offline',\n        () => {\n          if (this.online_) {\n            this.online_ = false;\n            this.trigger('online', false);\n          }\n        },\n        false\n      );\n    }\n  }\n\n  /**\n   * @param {!string} eventType\n   * @return {Array.<boolean>}\n   */\n  getInitialEvent(eventType: string): boolean[] {\n    assert(eventType === 'online', 'Unknown event type: ' + eventType);\n    return [this.online_];\n  }\n\n  /**\n   * @return {boolean}\n   */\n  currentlyOnline(): boolean {\n    return this.online_;\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 { exceptionGuard } from '../../core/util/util';\n\n/**\n * This class ensures the packets from the server arrive in order\n * This class takes data from the server and ensures it gets passed into the callbacks in order.\n * @constructor\n */\nexport class PacketReceiver {\n  pendingResponses: unknown[] = [];\n  currentResponseNum = 0;\n  closeAfterResponse = -1;\n  onClose: (() => void) | null = null;\n\n  /**\n   * @param onMessage_\n   */\n  constructor(private onMessage_: (a: {}) => void) {}\n\n  closeAfter(responseNum: number, callback: () => void) {\n    this.closeAfterResponse = responseNum;\n    this.onClose = callback;\n    if (this.closeAfterResponse < this.currentResponseNum) {\n      this.onClose();\n      this.onClose = null;\n    }\n  }\n\n  /**\n   * Each message from the server comes with a response number, and an array of data. The responseNumber\n   * allows us to ensure that we process them in the right order, since we can't be guaranteed that all\n   * browsers will respond in the same order as the requests we sent\n   * @param {number} requestNum\n   * @param {Array} data\n   */\n  handleResponse(requestNum: number, data: unknown[]) {\n    this.pendingResponses[requestNum] = data;\n    while (this.pendingResponses[this.currentResponseNum]) {\n      const toProcess = this.pendingResponses[\n        this.currentResponseNum\n      ] as unknown[];\n      delete this.pendingResponses[this.currentResponseNum];\n      for (let i = 0; i < toProcess.length; ++i) {\n        if (toProcess[i]) {\n          exceptionGuard(() => {\n            this.onMessage_(toProcess[i]);\n          });\n        }\n      }\n      if (this.currentResponseNum === this.closeAfterResponse) {\n        if (this.onClose) {\n          this.onClose();\n          this.onClose = null;\n        }\n        break;\n      }\n      this.currentResponseNum++;\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 {\n  executeWhenDOMReady,\n  isChromeExtensionContentScript,\n  isWindowsStoreApp,\n  log,\n  logWrapper,\n  LUIDGenerator,\n  splitStringBySize\n} from '../core/util/util';\nimport { StatsManager } from '../core/stats/StatsManager';\nimport { PacketReceiver } from './polling/PacketReceiver';\nimport {\n  APPLICATION_ID_PARAM,\n  FORGE_DOMAIN,\n  FORGE_REF,\n  LAST_SESSION_PARAM,\n  LONG_POLLING,\n  PROTOCOL_VERSION,\n  REFERER_PARAM,\n  TRANSPORT_SESSION_PARAM,\n  VERSION_PARAM\n} from './Constants';\nimport { base64Encode, stringify, isNodeSdk } from '@firebase/util';\n\nimport { Transport } from './Transport';\nimport { RepoInfo } from '../core/RepoInfo';\nimport { StatsCollection } from '../core/stats/StatsCollection';\n\n// URL query parameters associated with longpolling\nexport const FIREBASE_LONGPOLL_START_PARAM = 'start';\nexport const FIREBASE_LONGPOLL_CLOSE_COMMAND = 'close';\nexport const FIREBASE_LONGPOLL_COMMAND_CB_NAME = 'pLPCommand';\nexport const FIREBASE_LONGPOLL_DATA_CB_NAME = 'pRTLPCB';\nexport const FIREBASE_LONGPOLL_ID_PARAM = 'id';\nexport const FIREBASE_LONGPOLL_PW_PARAM = 'pw';\nexport const FIREBASE_LONGPOLL_SERIAL_PARAM = 'ser';\nexport const FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = 'cb';\nexport const FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = 'seg';\nexport const FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = 'ts';\nexport const FIREBASE_LONGPOLL_DATA_PARAM = 'd';\nexport const FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = 'disconn';\nexport const FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = 'dframe';\n\n//Data size constants.\n//TODO: Perf: the maximum length actually differs from browser to browser.\n// We should check what browser we're on and set accordingly.\nconst MAX_URL_DATA_SIZE = 1870;\nconst SEG_HEADER_SIZE = 30; //ie: &seg=8299234&ts=982389123&d=\nconst MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;\n\n/**\n * Keepalive period\n * send a fresh request at minimum every 25 seconds. Opera has a maximum request\n * length of 30 seconds that we can't exceed.\n * @const\n * @type {number}\n */\nconst KEEPALIVE_REQUEST_INTERVAL = 25000;\n\n/**\n * How long to wait before aborting a long-polling connection attempt.\n * @const\n * @type {number}\n */\nconst LP_CONNECT_TIMEOUT = 30000;\n\n/**\n * This class manages a single long-polling connection.\n *\n * @constructor\n * @implements {Transport}\n */\nexport class BrowserPollConnection implements Transport {\n  bytesSent = 0;\n  bytesReceived = 0;\n  urlFn: (params: object) => string;\n  scriptTagHolder: FirebaseIFrameScriptHolder;\n  myDisconnFrame: HTMLIFrameElement;\n  curSegmentNum: number;\n  myPacketOrderer: PacketReceiver;\n  id: string;\n  password: string;\n  private log_: (...a: unknown[]) => void;\n  private stats_: StatsCollection;\n  private everConnected_ = false;\n  private isClosed_: boolean;\n  private connectTimeoutTimer_: number | null;\n  private onDisconnect_: ((a?: boolean) => void) | null;\n\n  /**\n   * @param connId An identifier for this connection, used for logging\n   * @param repoInfo The info for the endpoint to send data to.\n   * @param applicationId The Firebase App ID for this project.\n   * @param transportSessionId Optional transportSessionid if we are reconnecting for an existing\n   *                                         transport session\n   * @param lastSessionId Optional lastSessionId if the PersistentConnection has already created a\n   *                                     connection previously\n   */\n  constructor(\n    public connId: string,\n    public repoInfo: RepoInfo,\n    private applicationId?: string,\n    public transportSessionId?: string,\n    public lastSessionId?: string\n  ) {\n    this.log_ = logWrapper(connId);\n    this.stats_ = StatsManager.getCollection(repoInfo);\n    this.urlFn = (params: { [k: string]: string }) =>\n      repoInfo.connectionURL(LONG_POLLING, params);\n  }\n\n  /**\n   *\n   * @param {function(Object)} onMessage Callback when messages arrive\n   * @param {function()} onDisconnect Callback with connection lost.\n   */\n  open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void) {\n    this.curSegmentNum = 0;\n    this.onDisconnect_ = onDisconnect;\n    this.myPacketOrderer = new PacketReceiver(onMessage);\n    this.isClosed_ = false;\n\n    this.connectTimeoutTimer_ = setTimeout(() => {\n      this.log_('Timed out trying to connect.');\n      // Make sure we clear the host cache\n      this.onClosed_();\n      this.connectTimeoutTimer_ = null;\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    }, Math.floor(LP_CONNECT_TIMEOUT)) as any;\n\n    // Ensure we delay the creation of the iframe until the DOM is loaded.\n    executeWhenDOMReady(() => {\n      if (this.isClosed_) {\n        return;\n      }\n\n      //Set up a callback that gets triggered once a connection is set up.\n      this.scriptTagHolder = new FirebaseIFrameScriptHolder(\n        (...args) => {\n          const [command, arg1, arg2, arg3, arg4] = args;\n          this.incrementIncomingBytes_(args);\n          if (!this.scriptTagHolder) {\n            return; // we closed the connection.\n          }\n\n          if (this.connectTimeoutTimer_) {\n            clearTimeout(this.connectTimeoutTimer_);\n            this.connectTimeoutTimer_ = null;\n          }\n          this.everConnected_ = true;\n          if (command === FIREBASE_LONGPOLL_START_PARAM) {\n            this.id = arg1 as string;\n            this.password = arg2 as string;\n          } else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) {\n            // Don't clear the host cache. We got a response from the server, so we know it's reachable\n            if (arg1) {\n              // We aren't expecting any more data (other than what the server's already in the process of sending us\n              // through our already open polls), so don't send any more.\n              this.scriptTagHolder.sendNewPolls = false;\n\n              // arg1 in this case is the last response number sent by the server. We should try to receive\n              // all of the responses up to this one before closing\n              this.myPacketOrderer.closeAfter(arg1 as number, () => {\n                this.onClosed_();\n              });\n            } else {\n              this.onClosed_();\n            }\n          } else {\n            throw new Error('Unrecognized command received: ' + command);\n          }\n        },\n        (...args) => {\n          const [pN, data] = args;\n          this.incrementIncomingBytes_(args);\n          this.myPacketOrderer.handleResponse(pN as number, data as unknown[]);\n        },\n        () => {\n          this.onClosed_();\n        },\n        this.urlFn\n      );\n\n      //Send the initial request to connect. The serial number is simply to keep the browser from pulling previous results\n      //from cache.\n      const urlParams: { [k: string]: string | number } = {};\n      urlParams[FIREBASE_LONGPOLL_START_PARAM] = 't';\n      urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(\n        Math.random() * 100000000\n      );\n      if (this.scriptTagHolder.uniqueCallbackIdentifier) {\n        urlParams[\n          FIREBASE_LONGPOLL_CALLBACK_ID_PARAM\n        ] = this.scriptTagHolder.uniqueCallbackIdentifier;\n      }\n      urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\n      if (this.transportSessionId) {\n        urlParams[TRANSPORT_SESSION_PARAM] = this.transportSessionId;\n      }\n      if (this.lastSessionId) {\n        urlParams[LAST_SESSION_PARAM] = this.lastSessionId;\n      }\n      if (this.applicationId) {\n        urlParams[APPLICATION_ID_PARAM] = this.applicationId;\n      }\n      if (\n        typeof location !== 'undefined' &&\n        location.href &&\n        location.href.indexOf(FORGE_DOMAIN) !== -1\n      ) {\n        urlParams[REFERER_PARAM] = FORGE_REF;\n      }\n      const connectURL = this.urlFn(urlParams);\n      this.log_('Connecting via long-poll to ' + connectURL);\n      this.scriptTagHolder.addTag(connectURL, () => {\n        /* do nothing */\n      });\n    });\n  }\n\n  /**\n   * Call this when a handshake has completed successfully and we want to consider the connection established\n   */\n  start() {\n    this.scriptTagHolder.startLongPoll(this.id, this.password);\n    this.addDisconnectPingFrame(this.id, this.password);\n  }\n\n  private static forceAllow_: boolean;\n\n  /**\n   * Forces long polling to be considered as a potential transport\n   */\n  static forceAllow() {\n    BrowserPollConnection.forceAllow_ = true;\n  }\n\n  private static forceDisallow_: boolean;\n\n  /**\n   * Forces longpolling to not be considered as a potential transport\n   */\n  static forceDisallow() {\n    BrowserPollConnection.forceDisallow_ = true;\n  }\n\n  // Static method, use string literal so it can be accessed in a generic way\n  static isAvailable() {\n    if (isNodeSdk()) {\n      return false;\n    } else if (BrowserPollConnection.forceAllow_) {\n      return true;\n    } else {\n      // NOTE: In React-Native there's normally no 'document', but if you debug a React-Native app in\n      // the Chrome debugger, 'document' is defined, but document.createElement is null (2015/06/08).\n      return (\n        !BrowserPollConnection.forceDisallow_ &&\n        typeof document !== 'undefined' &&\n        document.createElement != null &&\n        !isChromeExtensionContentScript() &&\n        !isWindowsStoreApp()\n      );\n    }\n  }\n\n  /**\n   * No-op for polling\n   */\n  markConnectionHealthy() {}\n\n  /**\n   * Stops polling and cleans up the iframe\n   * @private\n   */\n  private shutdown_() {\n    this.isClosed_ = true;\n\n    if (this.scriptTagHolder) {\n      this.scriptTagHolder.close();\n      this.scriptTagHolder = null;\n    }\n\n    //remove the disconnect frame, which will trigger an XHR call to the server to tell it we're leaving.\n    if (this.myDisconnFrame) {\n      document.body.removeChild(this.myDisconnFrame);\n      this.myDisconnFrame = null;\n    }\n\n    if (this.connectTimeoutTimer_) {\n      clearTimeout(this.connectTimeoutTimer_);\n      this.connectTimeoutTimer_ = null;\n    }\n  }\n\n  /**\n   * Triggered when this transport is closed\n   * @private\n   */\n  private onClosed_() {\n    if (!this.isClosed_) {\n      this.log_('Longpoll is closing itself');\n      this.shutdown_();\n\n      if (this.onDisconnect_) {\n        this.onDisconnect_(this.everConnected_);\n        this.onDisconnect_ = null;\n      }\n    }\n  }\n\n  /**\n   * External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server\n   * that we've left.\n   */\n  close() {\n    if (!this.isClosed_) {\n      this.log_('Longpoll is being closed.');\n      this.shutdown_();\n    }\n  }\n\n  /**\n   * Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then\n   * broken into chunks (since URLs have a small maximum length).\n   * @param {!Object} data The JSON data to transmit.\n   */\n  send(data: {}) {\n    const dataStr = stringify(data);\n    this.bytesSent += dataStr.length;\n    this.stats_.incrementCounter('bytes_sent', dataStr.length);\n\n    //first, lets get the base64-encoded data\n    const base64data = base64Encode(dataStr);\n\n    //We can only fit a certain amount in each URL, so we need to split this request\n    //up into multiple pieces if it doesn't fit in one request.\n    const dataSegs = splitStringBySize(base64data, MAX_PAYLOAD_SIZE);\n\n    //Enqueue each segment for transmission. We assign each chunk a sequential ID and a total number\n    //of segments so that we can reassemble the packet on the server.\n    for (let i = 0; i < dataSegs.length; i++) {\n      this.scriptTagHolder.enqueueSegment(\n        this.curSegmentNum,\n        dataSegs.length,\n        dataSegs[i]\n      );\n      this.curSegmentNum++;\n    }\n  }\n\n  /**\n   * This is how we notify the server that we're leaving.\n   * We aren't able to send requests with DHTML on a window close event, but we can\n   * trigger XHR requests in some browsers (everything but Opera basically).\n   * @param {!string} id\n   * @param {!string} pw\n   */\n  addDisconnectPingFrame(id: string, pw: string) {\n    if (isNodeSdk()) {\n      return;\n    }\n    this.myDisconnFrame = document.createElement('iframe');\n    const urlParams: { [k: string]: string } = {};\n    urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = 't';\n    urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id;\n    urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw;\n    this.myDisconnFrame.src = this.urlFn(urlParams);\n    this.myDisconnFrame.style.display = 'none';\n\n    document.body.appendChild(this.myDisconnFrame);\n  }\n\n  /**\n   * Used to track the bytes received by this client\n   * @param {*} args\n   * @private\n   */\n  private incrementIncomingBytes_(args: unknown) {\n    // TODO: This is an annoying perf hit just to track the number of incoming bytes.  Maybe it should be opt-in.\n    const bytesReceived = stringify(args).length;\n    this.bytesReceived += bytesReceived;\n    this.stats_.incrementCounter('bytes_received', bytesReceived);\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/interface-name-prefix\nexport interface IFrameElement extends HTMLIFrameElement {\n  doc: Document;\n}\n\n/*********************************************************************************************\n * A wrapper around an iframe that is used as a long-polling script holder.\n * @constructor\n *********************************************************************************************/\nexport class FirebaseIFrameScriptHolder {\n  //We maintain a count of all of the outstanding requests, because if we have too many active at once it can cause\n  //problems in some browsers.\n  outstandingRequests = new Set<number>();\n\n  //A queue of the pending segments waiting for transmission to the server.\n  pendingSegs: Array<{ seg: number; ts: number; d: unknown }> = [];\n\n  //A serial number. We use this for two things:\n  // 1) A way to ensure the browser doesn't cache responses to polls\n  // 2) A way to make the server aware when long-polls arrive in a different order than we started them. The\n  //    server needs to release both polls in this case or it will cause problems in Opera since Opera can only execute\n  //    JSONP code in the order it was added to the iframe.\n  currentSerial = Math.floor(Math.random() * 100000000);\n\n  // This gets set to false when we're \"closing down\" the connection (e.g. we're switching transports but there's still\n  // incoming data from the server that we're waiting for).\n  sendNewPolls = true;\n\n  uniqueCallbackIdentifier: number;\n  myIFrame: IFrameElement;\n  alive: boolean;\n  myID: string;\n  myPW: string;\n  commandCB: (command: string, ...args: unknown[]) => void;\n  onMessageCB: (...args: unknown[]) => void;\n\n  /**\n   * @param commandCB - The callback to be called when control commands are recevied from the server.\n   * @param onMessageCB - The callback to be triggered when responses arrive from the server.\n   * @param onDisconnect - The callback to be triggered when this tag holder is closed\n   * @param urlFn - A function that provides the URL of the endpoint to send data to.\n   */\n  constructor(\n    commandCB: (command: string, ...args: unknown[]) => void,\n    onMessageCB: (...args: unknown[]) => void,\n    public onDisconnect: () => void,\n    public urlFn: (a: object) => string\n  ) {\n    if (!isNodeSdk()) {\n      //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the\n      //iframes where we put the long-polling script tags. We have two callbacks:\n      //   1) Command Callback - Triggered for control issues, like starting a connection.\n      //   2) Message Callback - Triggered when new data arrives.\n      this.uniqueCallbackIdentifier = LUIDGenerator();\n      window[\n        FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier\n      ] = commandCB;\n      window[\n        FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier\n      ] = onMessageCB;\n\n      //Create an iframe for us to add script tags to.\n      this.myIFrame = FirebaseIFrameScriptHolder.createIFrame_();\n\n      // Set the iframe's contents.\n      let script = '';\n      // if we set a javascript url, it's IE and we need to set the document domain. The javascript url is sufficient\n      // for ie9, but ie8 needs to do it again in the document itself.\n      if (\n        this.myIFrame.src &&\n        this.myIFrame.src.substr(0, 'javascript:'.length) === 'javascript:'\n      ) {\n        const currentDomain = document.domain;\n        script = '<script>document.domain=\"' + currentDomain + '\";</script>';\n      }\n      const iframeContents = '<html><body>' + script + '</body></html>';\n      try {\n        this.myIFrame.doc.open();\n        this.myIFrame.doc.write(iframeContents);\n        this.myIFrame.doc.close();\n      } catch (e) {\n        log('frame writing exception');\n        if (e.stack) {\n          log(e.stack);\n        }\n        log(e);\n      }\n    } else {\n      this.commandCB = commandCB;\n      this.onMessageCB = onMessageCB;\n    }\n  }\n\n  /**\n   * Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can\n   * actually use.\n   * @private\n   * @return {Element}\n   */\n  private static createIFrame_(): IFrameElement {\n    const iframe = document.createElement('iframe') as IFrameElement;\n    iframe.style.display = 'none';\n\n    // This is necessary in order to initialize the document inside the iframe\n    if (document.body) {\n      document.body.appendChild(iframe);\n      try {\n        // If document.domain has been modified in IE, this will throw an error, and we need to set the\n        // domain of the iframe's document manually. We can do this via a javascript: url as the src attribute\n        // Also note that we must do this *after* the iframe has been appended to the page. Otherwise it doesn't work.\n        const a = iframe.contentWindow.document;\n        if (!a) {\n          // Apologies for the log-spam, I need to do something to keep closure from optimizing out the assignment above.\n          log('No IE domain setting required');\n        }\n      } catch (e) {\n        const domain = document.domain;\n        iframe.src =\n          \"javascript:void((function(){document.open();document.domain='\" +\n          domain +\n          \"';document.close();})())\";\n      }\n    } else {\n      // LongPollConnection attempts to delay initialization until the document is ready, so hopefully this\n      // never gets hit.\n      throw 'Document body has not initialized. Wait to initialize Firebase until after the document is ready.';\n    }\n\n    // Get the document of the iframe in a browser-specific way.\n    if (iframe.contentDocument) {\n      iframe.doc = iframe.contentDocument; // Firefox, Opera, Safari\n    } else if (iframe.contentWindow) {\n      iframe.doc = iframe.contentWindow.document; // Internet Explorer\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    } else if ((iframe as any).document) {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      iframe.doc = (iframe as any).document; //others?\n    }\n\n    return iframe;\n  }\n\n  /**\n   * Cancel all outstanding queries and remove the frame.\n   */\n  close() {\n    //Mark this iframe as dead, so no new requests are sent.\n    this.alive = false;\n\n    if (this.myIFrame) {\n      //We have to actually remove all of the html inside this iframe before removing it from the\n      //window, or IE will continue loading and executing the script tags we've already added, which\n      //can lead to some errors being thrown. Setting innerHTML seems to be the easiest way to do this.\n      this.myIFrame.doc.body.innerHTML = '';\n      setTimeout(() => {\n        if (this.myIFrame !== null) {\n          document.body.removeChild(this.myIFrame);\n          this.myIFrame = null;\n        }\n      }, Math.floor(0));\n    }\n\n    // Protect from being called recursively.\n    const onDisconnect = this.onDisconnect;\n    if (onDisconnect) {\n      this.onDisconnect = null;\n      onDisconnect();\n    }\n  }\n\n  /**\n   * Actually start the long-polling session by adding the first script tag(s) to the iframe.\n   * @param {!string} id - The ID of this connection\n   * @param {!string} pw - The password for this connection\n   */\n  startLongPoll(id: string, pw: string) {\n    this.myID = id;\n    this.myPW = pw;\n    this.alive = true;\n\n    //send the initial request. If there are requests queued, make sure that we transmit as many as we are currently able to.\n    while (this.newRequest_()) {}\n  }\n\n  /**\n   * This is called any time someone might want a script tag to be added. It adds a script tag when there aren't\n   * too many outstanding requests and we are still alive.\n   *\n   * If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if\n   * needed.\n   */\n  private newRequest_() {\n    // We keep one outstanding request open all the time to receive data, but if we need to send data\n    // (pendingSegs.length > 0) then we create a new request to send the data.  The server will automatically\n    // close the old request.\n    if (\n      this.alive &&\n      this.sendNewPolls &&\n      this.outstandingRequests.size < (this.pendingSegs.length > 0 ? 2 : 1)\n    ) {\n      //construct our url\n      this.currentSerial++;\n      const urlParams: { [k: string]: string | number } = {};\n      urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\n      urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\n      urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial;\n      let theURL = this.urlFn(urlParams);\n      //Now add as much data as we can.\n      let curDataString = '';\n      let i = 0;\n\n      while (this.pendingSegs.length > 0) {\n        //first, lets see if the next segment will fit.\n        const nextSeg = this.pendingSegs[0];\n        if (\n          (nextSeg.d as unknown[]).length +\n            SEG_HEADER_SIZE +\n            curDataString.length <=\n          MAX_URL_DATA_SIZE\n        ) {\n          //great, the segment will fit. Lets append it.\n          const theSeg = this.pendingSegs.shift();\n          curDataString =\n            curDataString +\n            '&' +\n            FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM +\n            i +\n            '=' +\n            theSeg.seg +\n            '&' +\n            FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET +\n            i +\n            '=' +\n            theSeg.ts +\n            '&' +\n            FIREBASE_LONGPOLL_DATA_PARAM +\n            i +\n            '=' +\n            theSeg.d;\n          i++;\n        } else {\n          break;\n        }\n      }\n\n      theURL = theURL + curDataString;\n      this.addLongPollTag_(theURL, this.currentSerial);\n\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Queue a packet for transmission to the server.\n   * @param segnum - A sequential id for this packet segment used for reassembly\n   * @param totalsegs - The total number of segments in this packet\n   * @param data - The data for this segment.\n   */\n  enqueueSegment(segnum: number, totalsegs: number, data: unknown) {\n    //add this to the queue of segments to send.\n    this.pendingSegs.push({ seg: segnum, ts: totalsegs, d: data });\n\n    //send the data immediately if there isn't already data being transmitted, unless\n    //startLongPoll hasn't been called yet.\n    if (this.alive) {\n      this.newRequest_();\n    }\n  }\n\n  /**\n   * Add a script tag for a regular long-poll request.\n   * @param {!string} url - The URL of the script tag.\n   * @param {!number} serial - The serial number of the request.\n   * @private\n   */\n  private addLongPollTag_(url: string, serial: number) {\n    //remember that we sent this request.\n    this.outstandingRequests.add(serial);\n\n    const doNewRequest = () => {\n      this.outstandingRequests.delete(serial);\n      this.newRequest_();\n    };\n\n    // If this request doesn't return on its own accord (by the server sending us some data), we'll\n    // create a new one after the KEEPALIVE interval to make sure we always keep a fresh request open.\n    const keepaliveTimeout = setTimeout(\n      doNewRequest,\n      Math.floor(KEEPALIVE_REQUEST_INTERVAL)\n    );\n\n    const readyStateCB = () => {\n      // Request completed.  Cancel the keepalive.\n      clearTimeout(keepaliveTimeout);\n\n      // Trigger a new request so we can continue receiving data.\n      doNewRequest();\n    };\n\n    this.addTag(url, readyStateCB);\n  }\n\n  /**\n   * Add an arbitrary script tag to the iframe.\n   * @param {!string} url - The URL for the script tag source.\n   * @param {!function()} loadCB - A callback to be triggered once the script has loaded.\n   */\n  addTag(url: string, loadCB: () => void) {\n    if (isNodeSdk()) {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (this as any).doNodeLongPoll(url, loadCB);\n    } else {\n      setTimeout(() => {\n        try {\n          // if we're already closed, don't add this poll\n          if (!this.sendNewPolls) {\n            return;\n          }\n          const newScript = this.myIFrame.doc.createElement('script');\n          newScript.type = 'text/javascript';\n          newScript.async = true;\n          newScript.src = url;\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          newScript.onload = (newScript as any).onreadystatechange = function () {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            const rstate = (newScript as any).readyState;\n            if (!rstate || rstate === 'loaded' || rstate === 'complete') {\n              // eslint-disable-next-line @typescript-eslint/no-explicit-any\n              newScript.onload = (newScript as any).onreadystatechange = null;\n              if (newScript.parentNode) {\n                newScript.parentNode.removeChild(newScript);\n              }\n              loadCB();\n            }\n          };\n          newScript.onerror = () => {\n            log('Long-poll script failed to load: ' + url);\n            this.sendNewPolls = false;\n            this.close();\n          };\n          this.myIFrame.doc.body.appendChild(newScript);\n        } catch (e) {\n          // TODO: we should make this error visible somehow\n        }\n      }, Math.floor(1));\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\n/** The semver (www.semver.org) version of the SDK. */\nexport let SDK_VERSION = '';\n\n// SDK_VERSION should be set before any database instance is created\nexport function setSDKVersion(version: string): void {\n  SDK_VERSION = 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 { RepoInfo } from '../core/RepoInfo';\nimport {\n  assert,\n  CONSTANTS as ENV_CONSTANTS,\n  jsonEval,\n  stringify,\n  isNodeSdk\n} from '@firebase/util';\nimport { logWrapper, splitStringBySize } from '../core/util/util';\nimport { StatsManager } from '../core/stats/StatsManager';\nimport {\n  FORGE_DOMAIN,\n  FORGE_REF,\n  LAST_SESSION_PARAM,\n  PROTOCOL_VERSION,\n  REFERER_PARAM,\n  TRANSPORT_SESSION_PARAM,\n  VERSION_PARAM,\n  WEBSOCKET\n} from './Constants';\nimport { PersistentStorage } from '../core/storage/storage';\nimport { Transport } from './Transport';\nimport { StatsCollection } from '../core/stats/StatsCollection';\nimport { SDK_VERSION } from '../core/version';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const MozWebSocket: any;\n\nconst WEBSOCKET_MAX_FRAME_SIZE = 16384;\nconst WEBSOCKET_KEEPALIVE_INTERVAL = 45000;\n\nlet WebSocketImpl = null;\nif (typeof MozWebSocket !== 'undefined') {\n  WebSocketImpl = MozWebSocket;\n} else if (typeof WebSocket !== 'undefined') {\n  WebSocketImpl = WebSocket;\n}\n\nexport function setWebSocketImpl(impl) {\n  WebSocketImpl = impl;\n}\n\n/**\n * Create a new websocket connection with the given callbacks.\n * @constructor\n * @implements {Transport}\n */\nexport class WebSocketConnection implements Transport {\n  keepaliveTimer: number | null = null;\n  frames: string[] | null = null;\n  totalFrames = 0;\n  bytesSent = 0;\n  bytesReceived = 0;\n  connURL: string;\n  onDisconnect: (a?: boolean) => void;\n  onMessage: (msg: {}) => void;\n  mySock: WebSocket | null;\n  private log_: (...a: unknown[]) => void;\n  private stats_: StatsCollection;\n  private everConnected_: boolean;\n  private isClosed_: boolean;\n\n  /**\n   * @param connId identifier for this transport\n   * @param repoInfo The info for the websocket endpoint.\n   * @param applicationId The Firebase App ID for this project.\n   * @param transportSessionId Optional transportSessionId if this is connecting to an existing transport\n   *                                         session\n   * @param lastSessionId Optional lastSessionId if there was a previous connection\n   */\n  constructor(\n    public connId: string,\n    repoInfo: RepoInfo,\n    private applicationId?: string,\n    transportSessionId?: string,\n    lastSessionId?: string\n  ) {\n    this.log_ = logWrapper(this.connId);\n    this.stats_ = StatsManager.getCollection(repoInfo);\n    this.connURL = WebSocketConnection.connectionURL_(\n      repoInfo,\n      transportSessionId,\n      lastSessionId\n    );\n  }\n\n  /**\n   * @param {RepoInfo} repoInfo The info for the websocket endpoint.\n   * @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport\n   *                                         session\n   * @param {string=} lastSessionId Optional lastSessionId if there was a previous connection\n   * @return {string} connection url\n   * @private\n   */\n  private static connectionURL_(\n    repoInfo: RepoInfo,\n    transportSessionId?: string,\n    lastSessionId?: string\n  ): string {\n    const urlParams: { [k: string]: string } = {};\n    urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\n\n    if (\n      !isNodeSdk() &&\n      typeof location !== 'undefined' &&\n      location.href &&\n      location.href.indexOf(FORGE_DOMAIN) !== -1\n    ) {\n      urlParams[REFERER_PARAM] = FORGE_REF;\n    }\n    if (transportSessionId) {\n      urlParams[TRANSPORT_SESSION_PARAM] = transportSessionId;\n    }\n    if (lastSessionId) {\n      urlParams[LAST_SESSION_PARAM] = lastSessionId;\n    }\n    return repoInfo.connectionURL(WEBSOCKET, urlParams);\n  }\n\n  /**\n   *\n   * @param onMessage Callback when messages arrive\n   * @param onDisconnect Callback with connection lost.\n   */\n  open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void) {\n    this.onDisconnect = onDisconnect;\n    this.onMessage = onMessage;\n\n    this.log_('Websocket connecting to ' + this.connURL);\n\n    this.everConnected_ = false;\n    // Assume failure until proven otherwise.\n    PersistentStorage.set('previous_websocket_failure', true);\n\n    try {\n      if (isNodeSdk()) {\n        const device = ENV_CONSTANTS.NODE_ADMIN ? 'AdminNode' : 'Node';\n        // UA Format: Firebase/<wire_protocol>/<sdk_version>/<platform>/<device>\n        const options: { [k: string]: object } = {\n          headers: {\n            'User-Agent': `Firebase/${PROTOCOL_VERSION}/${SDK_VERSION}/${process.platform}/${device}`,\n            'X-Firebase-GMPID': this.applicationId || ''\n          }\n        };\n\n        // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.\n        const env = process['env'];\n        const proxy =\n          this.connURL.indexOf('wss://') === 0\n            ? env['HTTPS_PROXY'] || env['https_proxy']\n            : env['HTTP_PROXY'] || env['http_proxy'];\n\n        if (proxy) {\n          options['proxy'] = { origin: proxy };\n        }\n\n        this.mySock = new WebSocketImpl(this.connURL, [], options);\n      } else {\n        const options: { [k: string]: object } = {\n          headers: {\n            'X-Firebase-GMPID': this.applicationId || ''\n          }\n        };\n        this.mySock = new WebSocketImpl(this.connURL, [], options);\n      }\n    } catch (e) {\n      this.log_('Error instantiating WebSocket.');\n      const error = e.message || e.data;\n      if (error) {\n        this.log_(error);\n      }\n      this.onClosed_();\n      return;\n    }\n\n    this.mySock.onopen = () => {\n      this.log_('Websocket connected.');\n      this.everConnected_ = true;\n    };\n\n    this.mySock.onclose = () => {\n      this.log_('Websocket connection was disconnected.');\n      this.mySock = null;\n      this.onClosed_();\n    };\n\n    this.mySock.onmessage = m => {\n      this.handleIncomingFrame(m as {});\n    };\n\n    this.mySock.onerror = e => {\n      this.log_('WebSocket error.  Closing connection.');\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const error = (e as any).message || (e as any).data;\n      if (error) {\n        this.log_(error);\n      }\n      this.onClosed_();\n    };\n  }\n\n  /**\n   * No-op for websockets, we don't need to do anything once the connection is confirmed as open\n   */\n  start() {}\n\n  static forceDisallow_: boolean;\n\n  static forceDisallow() {\n    WebSocketConnection.forceDisallow_ = true;\n  }\n\n  static isAvailable(): boolean {\n    let isOldAndroid = false;\n    if (typeof navigator !== 'undefined' && navigator.userAgent) {\n      const oldAndroidRegex = /Android ([0-9]{0,}\\.[0-9]{0,})/;\n      const oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex);\n      if (oldAndroidMatch && oldAndroidMatch.length > 1) {\n        if (parseFloat(oldAndroidMatch[1]) < 4.4) {\n          isOldAndroid = true;\n        }\n      }\n    }\n\n    return (\n      !isOldAndroid &&\n      WebSocketImpl !== null &&\n      !WebSocketConnection.forceDisallow_\n    );\n  }\n\n  /**\n   * Number of response before we consider the connection \"healthy.\"\n   * @type {number}\n   */\n  static responsesRequiredToBeHealthy = 2;\n\n  /**\n   * Time to wait for the connection te become healthy before giving up.\n   * @type {number}\n   */\n  static healthyTimeout = 30000;\n\n  /**\n   * Returns true if we previously failed to connect with this transport.\n   * @return {boolean}\n   */\n  static previouslyFailed(): boolean {\n    // If our persistent storage is actually only in-memory storage,\n    // we default to assuming that it previously failed to be safe.\n    return (\n      PersistentStorage.isInMemoryStorage ||\n      PersistentStorage.get('previous_websocket_failure') === true\n    );\n  }\n\n  markConnectionHealthy() {\n    PersistentStorage.remove('previous_websocket_failure');\n  }\n\n  private appendFrame_(data: string) {\n    this.frames.push(data);\n    if (this.frames.length === this.totalFrames) {\n      const fullMess = this.frames.join('');\n      this.frames = null;\n      const jsonMess = jsonEval(fullMess) as object;\n\n      //handle the message\n      this.onMessage(jsonMess);\n    }\n  }\n\n  /**\n   * @param {number} frameCount The number of frames we are expecting from the server\n   * @private\n   */\n  private handleNewFrameCount_(frameCount: number) {\n    this.totalFrames = frameCount;\n    this.frames = [];\n  }\n\n  /**\n   * Attempts to parse a frame count out of some text. If it can't, assumes a value of 1\n   * @param {!String} data\n   * @return {?String} Any remaining data to be process, or null if there is none\n   * @private\n   */\n  private extractFrameCount_(data: string): string | null {\n    assert(this.frames === null, 'We already have a frame buffer');\n    // TODO: The server is only supposed to send up to 9999 frames (i.e. length <= 4), but that isn't being enforced\n    // currently.  So allowing larger frame counts (length <= 6).  See https://app.asana.com/0/search/8688598998380/8237608042508\n    if (data.length <= 6) {\n      const frameCount = Number(data);\n      if (!isNaN(frameCount)) {\n        this.handleNewFrameCount_(frameCount);\n        return null;\n      }\n    }\n    this.handleNewFrameCount_(1);\n    return data;\n  }\n\n  /**\n   * Process a websocket frame that has arrived from the server.\n   * @param mess The frame data\n   */\n  handleIncomingFrame(mess: { [k: string]: unknown }) {\n    if (this.mySock === null) {\n      return; // Chrome apparently delivers incoming packets even after we .close() the connection sometimes.\n    }\n    const data = mess['data'] as string;\n    this.bytesReceived += data.length;\n    this.stats_.incrementCounter('bytes_received', data.length);\n\n    this.resetKeepAlive();\n\n    if (this.frames !== null) {\n      // we're buffering\n      this.appendFrame_(data);\n    } else {\n      // try to parse out a frame count, otherwise, assume 1 and process it\n      const remainingData = this.extractFrameCount_(data);\n      if (remainingData !== null) {\n        this.appendFrame_(remainingData);\n      }\n    }\n  }\n\n  /**\n   * Send a message to the server\n   * @param {Object} data The JSON object to transmit\n   */\n  send(data: {}) {\n    this.resetKeepAlive();\n\n    const dataStr = stringify(data);\n    this.bytesSent += dataStr.length;\n    this.stats_.incrementCounter('bytes_sent', dataStr.length);\n\n    //We can only fit a certain amount in each websocket frame, so we need to split this request\n    //up into multiple pieces if it doesn't fit in one request.\n\n    const dataSegs = splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE);\n\n    //Send the length header\n    if (dataSegs.length > 1) {\n      this.sendString_(String(dataSegs.length));\n    }\n\n    //Send the actual data in segments.\n    for (let i = 0; i < dataSegs.length; i++) {\n      this.sendString_(dataSegs[i]);\n    }\n  }\n\n  private shutdown_() {\n    this.isClosed_ = true;\n    if (this.keepaliveTimer) {\n      clearInterval(this.keepaliveTimer);\n      this.keepaliveTimer = null;\n    }\n\n    if (this.mySock) {\n      this.mySock.close();\n      this.mySock = null;\n    }\n  }\n\n  private onClosed_() {\n    if (!this.isClosed_) {\n      this.log_('WebSocket is closing itself');\n      this.shutdown_();\n\n      // since this is an internal close, trigger the close listener\n      if (this.onDisconnect) {\n        this.onDisconnect(this.everConnected_);\n        this.onDisconnect = null;\n      }\n    }\n  }\n\n  /**\n   * External-facing close handler.\n   * Close the websocket and kill the connection.\n   */\n  close() {\n    if (!this.isClosed_) {\n      this.log_('WebSocket is being closed');\n      this.shutdown_();\n    }\n  }\n\n  /**\n   * Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after\n   * the last activity.\n   */\n  resetKeepAlive() {\n    clearInterval(this.keepaliveTimer);\n    this.keepaliveTimer = setInterval(() => {\n      //If there has been no websocket activity for a while, send a no-op\n      if (this.mySock) {\n        this.sendString_('0');\n      }\n      this.resetKeepAlive();\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL)) as any;\n  }\n\n  /**\n   * Send a string over the websocket.\n   *\n   * @param {string} str String to send.\n   * @private\n   */\n  private sendString_(str: string) {\n    // Firefox seems to sometimes throw exceptions (NS_ERROR_UNEXPECTED) from websocket .send()\n    // calls for some unknown reason.  We treat these as an error and disconnect.\n    // See https://app.asana.com/0/58926111402292/68021340250410\n    try {\n      this.mySock.send(str);\n    } catch (e) {\n      this.log_(\n        'Exception thrown from WebSocket.send():',\n        e.message || e.data,\n        'Closing connection.'\n      );\n      setTimeout(this.onClosed_.bind(this), 0);\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 { BrowserPollConnection } from './BrowserPollConnection';\nimport { WebSocketConnection } from './WebSocketConnection';\nimport { warn } from '../core/util/util';\nimport { TransportConstructor } from './Transport';\nimport { RepoInfo } from '../core/RepoInfo';\n\n/**\n * Currently simplistic, this class manages what transport a Connection should use at various stages of its\n * lifecycle.\n *\n * It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if\n * they are available.\n * @constructor\n */\nexport class TransportManager {\n  private transports_: TransportConstructor[];\n\n  /**\n   * @const\n   * @type {!Array.<function(new:Transport, string, RepoInfo, string=)>}\n   */\n  static get ALL_TRANSPORTS() {\n    return [BrowserPollConnection, WebSocketConnection];\n  }\n\n  /**\n   * @param {!RepoInfo} repoInfo Metadata around the namespace we're connecting to\n   */\n  constructor(repoInfo: RepoInfo) {\n    this.initTransports_(repoInfo);\n  }\n\n  /**\n   * @param {!RepoInfo} repoInfo\n   * @private\n   */\n  private initTransports_(repoInfo: RepoInfo) {\n    const isWebSocketsAvailable: boolean =\n      WebSocketConnection && WebSocketConnection['isAvailable']();\n    let isSkipPollConnection =\n      isWebSocketsAvailable && !WebSocketConnection.previouslyFailed();\n\n    if (repoInfo.webSocketOnly) {\n      if (!isWebSocketsAvailable) {\n        warn(\n          \"wss:// URL used, but browser isn't known to support websockets.  Trying anyway.\"\n        );\n      }\n\n      isSkipPollConnection = true;\n    }\n\n    if (isSkipPollConnection) {\n      this.transports_ = [WebSocketConnection];\n    } else {\n      const transports = (this.transports_ = [] as TransportConstructor[]);\n      for (const transport of TransportManager.ALL_TRANSPORTS) {\n        if (transport && transport['isAvailable']()) {\n          transports.push(transport);\n        }\n      }\n    }\n  }\n\n  /**\n   * @return {function(new:Transport, !string, !RepoInfo, string=, string=)} The constructor for the\n   * initial transport to use\n   */\n  initialTransport(): TransportConstructor {\n    if (this.transports_.length > 0) {\n      return this.transports_[0];\n    } else {\n      throw new Error('No transports available');\n    }\n  }\n\n  /**\n   * @return {?function(new:Transport, function(),function(), string=)} The constructor for the next\n   * transport, or null\n   */\n  upgradeTransport(): TransportConstructor | null {\n    if (this.transports_.length > 1) {\n      return this.transports_[1];\n    } else {\n      return null;\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 {\n  error,\n  logWrapper,\n  requireKey,\n  setTimeoutNonBlocking,\n  warn\n} from '../core/util/util';\nimport { PersistentStorage } from '../core/storage/storage';\nimport { PROTOCOL_VERSION } from './Constants';\nimport { TransportManager } from './TransportManager';\nimport { RepoInfo } from '../core/RepoInfo';\nimport { Transport, TransportConstructor } from './Transport';\nimport { Indexable } from '../core/util/misc';\n\n// Abort upgrade attempt if it takes longer than 60s.\nconst UPGRADE_TIMEOUT = 60000;\n\n// For some transports (WebSockets), we need to \"validate\" the transport by exchanging a few requests and responses.\n// If we haven't sent enough requests within 5s, we'll start sending noop ping requests.\nconst DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5000;\n\n// If the initial data sent triggers a lot of bandwidth (i.e. it's a large put or a listen for a large amount of data)\n// then we may not be able to exchange our ping/pong requests within the healthy timeout.  So if we reach the timeout\n// but we've sent/received enough bytes, we don't cancel the connection.\nconst BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024;\nconst BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024;\n\nconst enum RealtimeState {\n  CONNECTING,\n  CONNECTED,\n  DISCONNECTED\n}\n\nconst MESSAGE_TYPE = 't';\nconst MESSAGE_DATA = 'd';\nconst CONTROL_SHUTDOWN = 's';\nconst CONTROL_RESET = 'r';\nconst CONTROL_ERROR = 'e';\nconst CONTROL_PONG = 'o';\nconst SWITCH_ACK = 'a';\nconst END_TRANSMISSION = 'n';\nconst PING = 'p';\n\nconst SERVER_HELLO = 'h';\n\n/**\n * Creates a new real-time connection to the server using whichever method works\n * best in the current browser.\n *\n * @constructor\n */\nexport class Connection {\n  connectionCount = 0;\n  pendingDataMessages: unknown[] = [];\n  sessionId: string;\n\n  private conn_: Transport;\n  private healthyTimeout_: number;\n  private isHealthy_: boolean;\n  private log_: (...args: unknown[]) => void;\n  private primaryResponsesRequired_: number;\n  private rx_: Transport;\n  private secondaryConn_: Transport;\n  private secondaryResponsesRequired_: number;\n  private state_ = RealtimeState.CONNECTING;\n  private transportManager_: TransportManager;\n  private tx_: Transport;\n\n  /**\n   * @param id - an id for this connection\n   * @param repoInfo_ - the info for the endpoint to connect to\n   * @param applicationId_ - the Firebase App ID for this project\n   * @param onMessage_ - the callback to be triggered when a server-push message arrives\n   * @param onReady_ - the callback to be triggered when this connection is ready to send messages.\n   * @param onDisconnect_ - the callback to be triggered when a connection was lost\n   * @param onKill_ - the callback to be triggered when this connection has permanently shut down.\n   * @param lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server\n   */\n  constructor(\n    public id: string,\n    private repoInfo_: RepoInfo,\n    private applicationId_: string | undefined,\n    private onMessage_: (a: {}) => void,\n    private onReady_: (a: number, b: string) => void,\n    private onDisconnect_: () => void,\n    private onKill_: (a: string) => void,\n    public lastSessionId?: string\n  ) {\n    this.log_ = logWrapper('c:' + this.id + ':');\n    this.transportManager_ = new TransportManager(repoInfo_);\n    this.log_('Connection created');\n    this.start_();\n  }\n\n  /**\n   * Starts a connection attempt\n   * @private\n   */\n  private start_(): void {\n    const conn = this.transportManager_.initialTransport();\n    this.conn_ = new conn(\n      this.nextTransportId_(),\n      this.repoInfo_,\n      this.applicationId_,\n      undefined,\n      this.lastSessionId\n    );\n\n    // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n    // can consider the transport healthy.\n    this.primaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\n\n    const onMessageReceived = this.connReceiver_(this.conn_);\n    const onConnectionLost = this.disconnReceiver_(this.conn_);\n    this.tx_ = this.conn_;\n    this.rx_ = this.conn_;\n    this.secondaryConn_ = null;\n    this.isHealthy_ = false;\n\n    /*\n     * Firefox doesn't like when code from one iframe tries to create another iframe by way of the parent frame.\n     * This can occur in the case of a redirect, i.e. we guessed wrong on what server to connect to and received a reset.\n     * Somehow, setTimeout seems to make this ok. That doesn't make sense from a security perspective, since you should\n     * still have the context of your originating frame.\n     */\n    setTimeout(() => {\n      // this.conn_ gets set to null in some of the tests. Check to make sure it still exists before using it\n      this.conn_ && this.conn_.open(onMessageReceived, onConnectionLost);\n    }, Math.floor(0));\n\n    const healthyTimeoutMS = conn['healthyTimeout'] || 0;\n    if (healthyTimeoutMS > 0) {\n      this.healthyTimeout_ = setTimeoutNonBlocking(() => {\n        this.healthyTimeout_ = null;\n        if (!this.isHealthy_) {\n          if (\n            this.conn_ &&\n            this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE\n          ) {\n            this.log_(\n              'Connection exceeded healthy timeout but has received ' +\n                this.conn_.bytesReceived +\n                ' bytes.  Marking connection healthy.'\n            );\n            this.isHealthy_ = true;\n            this.conn_.markConnectionHealthy();\n          } else if (\n            this.conn_ &&\n            this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE\n          ) {\n            this.log_(\n              'Connection exceeded healthy timeout but has sent ' +\n                this.conn_.bytesSent +\n                ' bytes.  Leaving connection alive.'\n            );\n            // NOTE: We don't want to mark it healthy, since we have no guarantee that the bytes have made it to\n            // the server.\n          } else {\n            this.log_('Closing unhealthy connection after timeout.');\n            this.close();\n          }\n        }\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      }, Math.floor(healthyTimeoutMS)) as any;\n    }\n  }\n\n  /**\n   * @return {!string}\n   * @private\n   */\n  private nextTransportId_(): string {\n    return 'c:' + this.id + ':' + this.connectionCount++;\n  }\n\n  private disconnReceiver_(conn) {\n    return everConnected => {\n      if (conn === this.conn_) {\n        this.onConnectionLost_(everConnected);\n      } else if (conn === this.secondaryConn_) {\n        this.log_('Secondary connection lost.');\n        this.onSecondaryConnectionLost_();\n      } else {\n        this.log_('closing an old connection');\n      }\n    };\n  }\n\n  private connReceiver_(conn: Transport) {\n    return (message: Indexable) => {\n      if (this.state_ !== RealtimeState.DISCONNECTED) {\n        if (conn === this.rx_) {\n          this.onPrimaryMessageReceived_(message);\n        } else if (conn === this.secondaryConn_) {\n          this.onSecondaryMessageReceived_(message);\n        } else {\n          this.log_('message on old connection');\n        }\n      }\n    };\n  }\n\n  /**\n   *\n   * @param {Object} dataMsg An arbitrary data message to be sent to the server\n   */\n  sendRequest(dataMsg: object) {\n    // wrap in a data message envelope and send it on\n    const msg = { t: 'd', d: dataMsg };\n    this.sendData_(msg);\n  }\n\n  tryCleanupConnection() {\n    if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) {\n      this.log_(\n        'cleaning up and promoting a connection: ' + this.secondaryConn_.connId\n      );\n      this.conn_ = this.secondaryConn_;\n      this.secondaryConn_ = null;\n      // the server will shutdown the old connection\n    }\n  }\n\n  private onSecondaryControl_(controlData: { [k: string]: unknown }) {\n    if (MESSAGE_TYPE in controlData) {\n      const cmd = controlData[MESSAGE_TYPE] as string;\n      if (cmd === SWITCH_ACK) {\n        this.upgradeIfSecondaryHealthy_();\n      } else if (cmd === CONTROL_RESET) {\n        // Most likely the session wasn't valid. Abandon the switch attempt\n        this.log_('Got a reset on secondary, closing it');\n        this.secondaryConn_.close();\n        // If we were already using this connection for something, than we need to fully close\n        if (\n          this.tx_ === this.secondaryConn_ ||\n          this.rx_ === this.secondaryConn_\n        ) {\n          this.close();\n        }\n      } else if (cmd === CONTROL_PONG) {\n        this.log_('got pong on secondary.');\n        this.secondaryResponsesRequired_--;\n        this.upgradeIfSecondaryHealthy_();\n      }\n    }\n  }\n\n  private onSecondaryMessageReceived_(parsedData: Indexable) {\n    const layer: string = requireKey('t', parsedData) as string;\n    const data: unknown = requireKey('d', parsedData);\n    if (layer === 'c') {\n      this.onSecondaryControl_(data as Indexable);\n    } else if (layer === 'd') {\n      // got a data message, but we're still second connection. Need to buffer it up\n      this.pendingDataMessages.push(data);\n    } else {\n      throw new Error('Unknown protocol layer: ' + layer);\n    }\n  }\n\n  private upgradeIfSecondaryHealthy_() {\n    if (this.secondaryResponsesRequired_ <= 0) {\n      this.log_('Secondary connection is healthy.');\n      this.isHealthy_ = true;\n      this.secondaryConn_.markConnectionHealthy();\n      this.proceedWithUpgrade_();\n    } else {\n      // Send a ping to make sure the connection is healthy.\n      this.log_('sending ping on secondary.');\n      this.secondaryConn_.send({ t: 'c', d: { t: PING, d: {} } });\n    }\n  }\n\n  private proceedWithUpgrade_() {\n    // tell this connection to consider itself open\n    this.secondaryConn_.start();\n    // send ack\n    this.log_('sending client ack on secondary');\n    this.secondaryConn_.send({ t: 'c', d: { t: SWITCH_ACK, d: {} } });\n\n    // send end packet on primary transport, switch to sending on this one\n    // can receive on this one, buffer responses until end received on primary transport\n    this.log_('Ending transmission on primary');\n    this.conn_.send({ t: 'c', d: { t: END_TRANSMISSION, d: {} } });\n    this.tx_ = this.secondaryConn_;\n\n    this.tryCleanupConnection();\n  }\n\n  private onPrimaryMessageReceived_(parsedData: { [k: string]: unknown }) {\n    // Must refer to parsedData properties in quotes, so closure doesn't touch them.\n    const layer: string = requireKey('t', parsedData) as string;\n    const data: unknown = requireKey('d', parsedData);\n    if (layer === 'c') {\n      this.onControl_(data as { [k: string]: unknown });\n    } else if (layer === 'd') {\n      this.onDataMessage_(data);\n    }\n  }\n\n  private onDataMessage_(message: unknown) {\n    this.onPrimaryResponse_();\n\n    // We don't do anything with data messages, just kick them up a level\n    this.onMessage_(message);\n  }\n\n  private onPrimaryResponse_() {\n    if (!this.isHealthy_) {\n      this.primaryResponsesRequired_--;\n      if (this.primaryResponsesRequired_ <= 0) {\n        this.log_('Primary connection is healthy.');\n        this.isHealthy_ = true;\n        this.conn_.markConnectionHealthy();\n      }\n    }\n  }\n\n  private onControl_(controlData: { [k: string]: unknown }) {\n    const cmd: string = requireKey(MESSAGE_TYPE, controlData) as string;\n    if (MESSAGE_DATA in controlData) {\n      const payload = controlData[MESSAGE_DATA];\n      if (cmd === SERVER_HELLO) {\n        this.onHandshake_(\n          payload as {\n            ts: number;\n            v: string;\n            h: string;\n            s: string;\n          }\n        );\n      } else if (cmd === END_TRANSMISSION) {\n        this.log_('recvd end transmission on primary');\n        this.rx_ = this.secondaryConn_;\n        for (let i = 0; i < this.pendingDataMessages.length; ++i) {\n          this.onDataMessage_(this.pendingDataMessages[i]);\n        }\n        this.pendingDataMessages = [];\n        this.tryCleanupConnection();\n      } else if (cmd === CONTROL_SHUTDOWN) {\n        // This was previously the 'onKill' callback passed to the lower-level connection\n        // payload in this case is the reason for the shutdown. Generally a human-readable error\n        this.onConnectionShutdown_(payload as string);\n      } else if (cmd === CONTROL_RESET) {\n        // payload in this case is the host we should contact\n        this.onReset_(payload as string);\n      } else if (cmd === CONTROL_ERROR) {\n        error('Server Error: ' + payload);\n      } else if (cmd === CONTROL_PONG) {\n        this.log_('got pong on primary.');\n        this.onPrimaryResponse_();\n        this.sendPingOnPrimaryIfNecessary_();\n      } else {\n        error('Unknown control packet command: ' + cmd);\n      }\n    }\n  }\n\n  /**\n   *\n   * @param {Object} handshake The handshake data returned from the server\n   * @private\n   */\n  private onHandshake_(handshake: {\n    ts: number;\n    v: string;\n    h: string;\n    s: string;\n  }): void {\n    const timestamp = handshake.ts;\n    const version = handshake.v;\n    const host = handshake.h;\n    this.sessionId = handshake.s;\n    this.repoInfo_.updateHost(host);\n    // if we've already closed the connection, then don't bother trying to progress further\n    if (this.state_ === RealtimeState.CONNECTING) {\n      this.conn_.start();\n      this.onConnectionEstablished_(this.conn_, timestamp);\n      if (PROTOCOL_VERSION !== version) {\n        warn('Protocol version mismatch detected');\n      }\n      // TODO: do we want to upgrade? when? maybe a delay?\n      this.tryStartUpgrade_();\n    }\n  }\n\n  private tryStartUpgrade_() {\n    const conn = this.transportManager_.upgradeTransport();\n    if (conn) {\n      this.startUpgrade_(conn);\n    }\n  }\n\n  private startUpgrade_(conn: TransportConstructor) {\n    this.secondaryConn_ = new conn(\n      this.nextTransportId_(),\n      this.repoInfo_,\n      this.applicationId_,\n      this.sessionId\n    );\n    // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n    // can consider the transport healthy.\n    this.secondaryResponsesRequired_ =\n      conn['responsesRequiredToBeHealthy'] || 0;\n\n    const onMessage = this.connReceiver_(this.secondaryConn_);\n    const onDisconnect = this.disconnReceiver_(this.secondaryConn_);\n    this.secondaryConn_.open(onMessage, onDisconnect);\n\n    // If we haven't successfully upgraded after UPGRADE_TIMEOUT, give up and kill the secondary.\n    setTimeoutNonBlocking(() => {\n      if (this.secondaryConn_) {\n        this.log_('Timed out trying to upgrade.');\n        this.secondaryConn_.close();\n      }\n    }, Math.floor(UPGRADE_TIMEOUT));\n  }\n\n  private onReset_(host: string) {\n    this.log_('Reset packet received.  New host: ' + host);\n    this.repoInfo_.updateHost(host);\n    // TODO: if we're already \"connected\", we need to trigger a disconnect at the next layer up.\n    // We don't currently support resets after the connection has already been established\n    if (this.state_ === RealtimeState.CONNECTED) {\n      this.close();\n    } else {\n      // Close whatever connections we have open and start again.\n      this.closeConnections_();\n      this.start_();\n    }\n  }\n\n  private onConnectionEstablished_(conn: Transport, timestamp: number) {\n    this.log_('Realtime connection established.');\n    this.conn_ = conn;\n    this.state_ = RealtimeState.CONNECTED;\n\n    if (this.onReady_) {\n      this.onReady_(timestamp, this.sessionId);\n      this.onReady_ = null;\n    }\n\n    // If after 5 seconds we haven't sent enough requests to the server to get the connection healthy,\n    // send some pings.\n    if (this.primaryResponsesRequired_ === 0) {\n      this.log_('Primary connection is healthy.');\n      this.isHealthy_ = true;\n    } else {\n      setTimeoutNonBlocking(() => {\n        this.sendPingOnPrimaryIfNecessary_();\n      }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS));\n    }\n  }\n\n  private sendPingOnPrimaryIfNecessary_() {\n    // If the connection isn't considered healthy yet, we'll send a noop ping packet request.\n    if (!this.isHealthy_ && this.state_ === RealtimeState.CONNECTED) {\n      this.log_('sending ping on primary.');\n      this.sendData_({ t: 'c', d: { t: PING, d: {} } });\n    }\n  }\n\n  private onSecondaryConnectionLost_() {\n    const conn = this.secondaryConn_;\n    this.secondaryConn_ = null;\n    if (this.tx_ === conn || this.rx_ === conn) {\n      // we are relying on this connection already in some capacity. Therefore, a failure is real\n      this.close();\n    }\n  }\n\n  /**\n   *\n   * @param {boolean} everConnected Whether or not the connection ever reached a server. Used to determine if\n   * we should flush the host cache\n   * @private\n   */\n  private onConnectionLost_(everConnected: boolean) {\n    this.conn_ = null;\n\n    // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting\n    // called on window close and RealtimeState.CONNECTING is no longer defined.  Just a guess.\n    if (!everConnected && this.state_ === RealtimeState.CONNECTING) {\n      this.log_('Realtime connection failed.');\n      // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away\n      if (this.repoInfo_.isCacheableHost()) {\n        PersistentStorage.remove('host:' + this.repoInfo_.host);\n        // reset the internal host to what we would show the user, i.e. <ns>.firebaseio.com\n        this.repoInfo_.internalHost = this.repoInfo_.host;\n      }\n    } else if (this.state_ === RealtimeState.CONNECTED) {\n      this.log_('Realtime connection lost.');\n    }\n\n    this.close();\n  }\n\n  /**\n   *\n   * @param {string} reason\n   * @private\n   */\n  private onConnectionShutdown_(reason: string) {\n    this.log_('Connection shutdown command received. Shutting down...');\n\n    if (this.onKill_) {\n      this.onKill_(reason);\n      this.onKill_ = null;\n    }\n\n    // We intentionally don't want to fire onDisconnect (kill is a different case),\n    // so clear the callback.\n    this.onDisconnect_ = null;\n\n    this.close();\n  }\n\n  private sendData_(data: object) {\n    if (this.state_ !== RealtimeState.CONNECTED) {\n      throw 'Connection is not connected';\n    } else {\n      this.tx_.send(data);\n    }\n  }\n\n  /**\n   * Cleans up this connection, calling the appropriate callbacks\n   */\n  close() {\n    if (this.state_ !== RealtimeState.DISCONNECTED) {\n      this.log_('Closing realtime connection.');\n      this.state_ = RealtimeState.DISCONNECTED;\n\n      this.closeConnections_();\n\n      if (this.onDisconnect_) {\n        this.onDisconnect_();\n        this.onDisconnect_ = null;\n      }\n    }\n  }\n\n  /**\n   *\n   * @private\n   */\n  private closeConnections_() {\n    this.log_('Shutting down all connections');\n    if (this.conn_) {\n      this.conn_.close();\n      this.conn_ = null;\n    }\n\n    if (this.secondaryConn_) {\n      this.secondaryConn_.close();\n      this.secondaryConn_ = null;\n    }\n\n    if (this.healthyTimeout_) {\n      clearTimeout(this.healthyTimeout_);\n      this.healthyTimeout_ = null;\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 { Query } from '../api/Query';\n\n/**\n * Interface defining the set of actions that can be performed against the Firebase server\n * (basically corresponds to our wire protocol).\n *\n * @interface\n */\nexport abstract class ServerActions {\n  /**\n   * @param {!Query} query\n   * @param {function():string} currentHashFn\n   * @param {?number} tag\n   * @param {function(string, *)} onComplete\n   */\n  abstract listen(\n    query: Query,\n    currentHashFn: () => string,\n    tag: number | null,\n    onComplete: (a: string, b: unknown) => void\n  ): void;\n\n  /**\n   * Remove a listen.\n   *\n   * @param {!Query} query\n   * @param {?number} tag\n   */\n  abstract unlisten(query: Query, tag: number | null): void;\n\n  /**\n   * @param {string} pathString\n   * @param {*} data\n   * @param {function(string, string)=} onComplete\n   * @param {string=} hash\n   */\n  put(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void,\n    hash?: string\n  ) {}\n\n  /**\n   * @param {string} pathString\n   * @param {*} data\n   * @param {function(string, ?string)} onComplete\n   * @param {string=} hash\n   */\n  merge(\n    pathString: string,\n    data: unknown,\n    onComplete: (a: string, b: string | null) => void,\n    hash?: string\n  ) {}\n\n  /**\n   * Refreshes the auth token for the current connection.\n   * @param {string} token The authentication token\n   */\n  refreshAuthToken(token: string) {}\n\n  /**\n   * @param {string} pathString\n   * @param {*} data\n   * @param {function(string, string)=} onComplete\n   */\n  onDisconnectPut(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void\n  ) {}\n\n  /**\n   * @param {string} pathString\n   * @param {*} data\n   * @param {function(string, string)=} onComplete\n   */\n  onDisconnectMerge(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void\n  ) {}\n\n  /**\n   * @param {string} pathString\n   * @param {function(string, string)=} onComplete\n   */\n  onDisconnectCancel(\n    pathString: string,\n    onComplete?: (a: string, b: string) => void\n  ) {}\n\n  /**\n   * @param {Object.<string, *>} stats\n   */\n  reportStats(stats: { [k: string]: unknown }) {}\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 {\n  contains,\n  isEmpty,\n  safeGet,\n  CONSTANTS,\n  stringify,\n  assert,\n  isAdmin,\n  isValidFormat,\n  isMobileCordova,\n  isReactNative,\n  isNodeSdk\n} from '@firebase/util';\n\nimport { error, log, logWrapper, warn, ObjectToUniqueKey } from './util/util';\nimport { Path } from './util/Path';\nimport { VisibilityMonitor } from './util/VisibilityMonitor';\nimport { OnlineMonitor } from './util/OnlineMonitor';\n\nimport { Connection } from '../realtime/Connection';\n\nimport { ServerActions } from './ServerActions';\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { RepoInfo } from './RepoInfo';\nimport { Query } from '../api/Query';\nimport { SDK_VERSION } from './version';\n\nconst RECONNECT_MIN_DELAY = 1000;\nconst RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858)\nconst RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server)\nconst RECONNECT_DELAY_MULTIPLIER = 1.3;\nconst RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec.\nconst SERVER_KILL_INTERRUPT_REASON = 'server_kill';\n\n// If auth fails repeatedly, we'll assume something is wrong and log a warning / back off.\nconst INVALID_AUTH_TOKEN_THRESHOLD = 3;\n\ninterface ListenSpec {\n  onComplete(s: string, p?: unknown): void;\n\n  hashFn(): string;\n\n  query: Query;\n  tag: number | null;\n}\n\ninterface OnDisconnectRequest {\n  pathString: string;\n  action: string;\n  data: unknown;\n  onComplete?: (a: string, b: string) => void;\n}\n\ninterface OutstandingPut {\n  action: string;\n  request: object;\n  queued?: boolean;\n  onComplete: (a: string, b?: string) => void;\n}\n\n/**\n * Firebase connection.  Abstracts wire protocol and handles reconnecting.\n *\n * NOTE: All JSON objects sent to the realtime connection must have property names enclosed\n * in quotes to make sure the closure compiler does not minify them.\n */\nexport class PersistentConnection extends ServerActions {\n  // Used for diagnostic logging.\n  id = PersistentConnection.nextPersistentConnectionId_++;\n  private log_ = logWrapper('p:' + this.id + ':');\n\n  private interruptReasons_: { [reason: string]: boolean } = {};\n  /** Map<path, Map<queryId, ListenSpec>> */\n  private readonly listens: Map<\n    /* path */ string,\n    Map</* queryId */ string, ListenSpec>\n  > = new Map();\n  private outstandingPuts_: OutstandingPut[] = [];\n  private outstandingPutCount_ = 0;\n  private onDisconnectRequestQueue_: OnDisconnectRequest[] = [];\n  private connected_ = false;\n  private reconnectDelay_ = RECONNECT_MIN_DELAY;\n  private maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT;\n  private securityDebugCallback_: ((a: object) => void) | null = null;\n  lastSessionId: string | null = null;\n\n  private establishConnectionTimer_: number | null = null;\n\n  private visible_: boolean = false;\n\n  // Before we get connected, we keep a queue of pending messages to send.\n  private requestCBHash_: { [k: number]: (a: unknown) => void } = {};\n  private requestNumber_ = 0;\n\n  private realtime_: {\n    sendRequest(a: object): void;\n    close(): void;\n  } | null = null;\n\n  private authToken_: string | null = null;\n  private forceTokenRefresh_ = false;\n  private invalidAuthTokenCount_ = 0;\n\n  private firstConnection_ = true;\n  private lastConnectionAttemptTime_: number | null = null;\n  private lastConnectionEstablishedTime_: number | null = null;\n\n  private static nextPersistentConnectionId_ = 0;\n\n  /**\n   * Counter for number of connections created. Mainly used for tagging in the logs\n   */\n  private static nextConnectionId_ = 0;\n\n  /**\n   * @implements {ServerActions}\n   * @param repoInfo_ Data about the namespace we are connecting to\n   * @param applicationId_ The Firebase App ID for this project\n   * @param onDataUpdate_ A callback for new data from the server\n   */\n  constructor(\n    private repoInfo_: RepoInfo,\n    private applicationId_: string,\n    private onDataUpdate_: (\n      a: string,\n      b: unknown,\n      c: boolean,\n      d: number | null\n    ) => void,\n    private onConnectStatus_: (a: boolean) => void,\n    private onServerInfoUpdate_: (a: unknown) => void,\n    private authTokenProvider_: AuthTokenProvider,\n    private authOverride_?: object | null\n  ) {\n    super();\n\n    if (authOverride_ && !isNodeSdk()) {\n      throw new Error(\n        'Auth override specified in options, but not supported on non Node.js platforms'\n      );\n    }\n    this.scheduleConnect_(0);\n\n    VisibilityMonitor.getInstance().on('visible', this.onVisible_, this);\n\n    if (repoInfo_.host.indexOf('fblocal') === -1) {\n      OnlineMonitor.getInstance().on('online', this.onOnline_, this);\n    }\n  }\n\n  protected sendRequest(\n    action: string,\n    body: unknown,\n    onResponse?: (a: unknown) => void\n  ) {\n    const curReqNum = ++this.requestNumber_;\n\n    const msg = { r: curReqNum, a: action, b: body };\n    this.log_(stringify(msg));\n    assert(\n      this.connected_,\n      \"sendRequest call when we're not connected not allowed.\"\n    );\n    this.realtime_.sendRequest(msg);\n    if (onResponse) {\n      this.requestCBHash_[curReqNum] = onResponse;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  listen(\n    query: Query,\n    currentHashFn: () => string,\n    tag: number | null,\n    onComplete: (a: string, b: unknown) => void\n  ) {\n    const queryId = query.queryIdentifier();\n    const pathString = query.path.toString();\n    this.log_('Listen called for ' + pathString + ' ' + queryId);\n    if (!this.listens.has(pathString)) {\n      this.listens.set(pathString, new Map());\n    }\n    assert(\n      query.getQueryParams().isDefault() ||\n        !query.getQueryParams().loadsAllData(),\n      'listen() called for non-default but complete query'\n    );\n    assert(\n      !this.listens.get(pathString)!.has(queryId),\n      'listen() called twice for same path/queryId.'\n    );\n    const listenSpec: ListenSpec = {\n      onComplete,\n      hashFn: currentHashFn,\n      query,\n      tag\n    };\n    this.listens.get(pathString)!.set(queryId, listenSpec);\n\n    if (this.connected_) {\n      this.sendListen_(listenSpec);\n    }\n  }\n\n  private sendListen_(listenSpec: ListenSpec) {\n    const query = listenSpec.query;\n    const pathString = query.path.toString();\n    const queryId = query.queryIdentifier();\n    this.log_('Listen on ' + pathString + ' for ' + queryId);\n    const req: { [k: string]: unknown } = { /*path*/ p: pathString };\n\n    const action = 'q';\n\n    // Only bother to send query if it's non-default.\n    if (listenSpec.tag) {\n      req['q'] = query.queryObject();\n      req['t'] = listenSpec.tag;\n    }\n\n    req[/*hash*/ 'h'] = listenSpec.hashFn();\n\n    this.sendRequest(action, req, (message: { [k: string]: unknown }) => {\n      const payload: unknown = message[/*data*/ 'd'];\n      const status = message[/*status*/ 's'] as string;\n\n      // print warnings in any case...\n      PersistentConnection.warnOnListenWarnings_(payload, query);\n\n      const currentListenSpec =\n        this.listens.get(pathString) &&\n        this.listens.get(pathString)!.get(queryId);\n      // only trigger actions if the listen hasn't been removed and readded\n      if (currentListenSpec === listenSpec) {\n        this.log_('listen response', message);\n\n        if (status !== 'ok') {\n          this.removeListen_(pathString, queryId);\n        }\n\n        if (listenSpec.onComplete) {\n          listenSpec.onComplete(status, payload);\n        }\n      }\n    });\n  }\n\n  private static warnOnListenWarnings_(payload: unknown, query: Query) {\n    if (payload && typeof payload === 'object' && contains(payload, 'w')) {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const warnings = safeGet(payload as any, 'w');\n      if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) {\n        const indexSpec =\n          '\".indexOn\": \"' + query.getQueryParams().getIndex().toString() + '\"';\n        const indexPath = query.path.toString();\n        warn(\n          `Using an unspecified index. Your data will be downloaded and ` +\n            `filtered on the client. Consider adding ${indexSpec} at ` +\n            `${indexPath} to your security rules for better performance.`\n        );\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  refreshAuthToken(token: string) {\n    this.authToken_ = token;\n    this.log_('Auth token refreshed');\n    if (this.authToken_) {\n      this.tryAuth();\n    } else {\n      //If we're connected we want to let the server know to unauthenticate us. If we're not connected, simply delete\n      //the credential so we dont become authenticated next time we connect.\n      if (this.connected_) {\n        this.sendRequest('unauth', {}, () => {});\n      }\n    }\n\n    this.reduceReconnectDelayIfAdminCredential_(token);\n  }\n\n  private reduceReconnectDelayIfAdminCredential_(credential: string) {\n    // NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client).\n    // Additionally, we don't bother resetting the max delay back to the default if auth fails / expires.\n    const isFirebaseSecret = credential && credential.length === 40;\n    if (isFirebaseSecret || isAdmin(credential)) {\n      this.log_(\n        'Admin auth credential detected.  Reducing max reconnect time.'\n      );\n      this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n    }\n  }\n\n  /**\n   * Attempts to authenticate with the given credentials. If the authentication attempt fails, it's triggered like\n   * a auth revoked (the connection is closed).\n   */\n  tryAuth() {\n    if (this.connected_ && this.authToken_) {\n      const token = this.authToken_;\n      const authMethod = isValidFormat(token) ? 'auth' : 'gauth';\n      const requestData: { [k: string]: unknown } = { cred: token };\n      if (this.authOverride_ === null) {\n        requestData['noauth'] = true;\n      } else if (typeof this.authOverride_ === 'object') {\n        requestData['authvar'] = this.authOverride_;\n      }\n      this.sendRequest(\n        authMethod,\n        requestData,\n        (res: { [k: string]: unknown }) => {\n          const status = res[/*status*/ 's'] as string;\n          const data = (res[/*data*/ 'd'] as string) || 'error';\n\n          if (this.authToken_ === token) {\n            if (status === 'ok') {\n              this.invalidAuthTokenCount_ = 0;\n            } else {\n              // Triggers reconnect and force refresh for auth token\n              this.onAuthRevoked_(status, data);\n            }\n          }\n        }\n      );\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  unlisten(query: Query, tag: number | null) {\n    const pathString = query.path.toString();\n    const queryId = query.queryIdentifier();\n\n    this.log_('Unlisten called for ' + pathString + ' ' + queryId);\n\n    assert(\n      query.getQueryParams().isDefault() ||\n        !query.getQueryParams().loadsAllData(),\n      'unlisten() called for non-default but complete query'\n    );\n    const listen = this.removeListen_(pathString, queryId);\n    if (listen && this.connected_) {\n      this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);\n    }\n  }\n\n  private sendUnlisten_(\n    pathString: string,\n    queryId: string,\n    queryObj: object,\n    tag: number | null\n  ) {\n    this.log_('Unlisten on ' + pathString + ' for ' + queryId);\n\n    const req: { [k: string]: unknown } = { /*path*/ p: pathString };\n    const action = 'n';\n    // Only bother sending queryId if it's non-default.\n    if (tag) {\n      req['q'] = queryObj;\n      req['t'] = tag;\n    }\n\n    this.sendRequest(action, req);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  onDisconnectPut(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void\n  ) {\n    if (this.connected_) {\n      this.sendOnDisconnect_('o', pathString, data, onComplete);\n    } else {\n      this.onDisconnectRequestQueue_.push({\n        pathString,\n        action: 'o',\n        data,\n        onComplete\n      });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  onDisconnectMerge(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void\n  ) {\n    if (this.connected_) {\n      this.sendOnDisconnect_('om', pathString, data, onComplete);\n    } else {\n      this.onDisconnectRequestQueue_.push({\n        pathString,\n        action: 'om',\n        data,\n        onComplete\n      });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  onDisconnectCancel(\n    pathString: string,\n    onComplete?: (a: string, b: string) => void\n  ) {\n    if (this.connected_) {\n      this.sendOnDisconnect_('oc', pathString, null, onComplete);\n    } else {\n      this.onDisconnectRequestQueue_.push({\n        pathString,\n        action: 'oc',\n        data: null,\n        onComplete\n      });\n    }\n  }\n\n  private sendOnDisconnect_(\n    action: string,\n    pathString: string,\n    data: unknown,\n    onComplete: (a: string, b: string) => void\n  ) {\n    const request = { /*path*/ p: pathString, /*data*/ d: data };\n    this.log_('onDisconnect ' + action, request);\n    this.sendRequest(action, request, (response: { [k: string]: unknown }) => {\n      if (onComplete) {\n        setTimeout(() => {\n          onComplete(\n            response[/*status*/ 's'] as string,\n            response[/* data */ 'd'] as string\n          );\n        }, Math.floor(0));\n      }\n    });\n  }\n\n  /**\n   * @inheritDoc\n   */\n  put(\n    pathString: string,\n    data: unknown,\n    onComplete?: (a: string, b: string) => void,\n    hash?: string\n  ) {\n    this.putInternal('p', pathString, data, onComplete, hash);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  merge(\n    pathString: string,\n    data: unknown,\n    onComplete: (a: string, b: string | null) => void,\n    hash?: string\n  ) {\n    this.putInternal('m', pathString, data, onComplete, hash);\n  }\n\n  putInternal(\n    action: string,\n    pathString: string,\n    data: unknown,\n    onComplete: (a: string, b: string | null) => void,\n    hash?: string\n  ) {\n    const request: { [k: string]: unknown } = {\n      /*path*/ p: pathString,\n      /*data*/ d: data\n    };\n\n    if (hash !== undefined) {\n      request[/*hash*/ 'h'] = hash;\n    }\n\n    // TODO: Only keep track of the most recent put for a given path?\n    this.outstandingPuts_.push({\n      action,\n      request,\n      onComplete\n    });\n\n    this.outstandingPutCount_++;\n    const index = this.outstandingPuts_.length - 1;\n\n    if (this.connected_) {\n      this.sendPut_(index);\n    } else {\n      this.log_('Buffering put: ' + pathString);\n    }\n  }\n\n  private sendPut_(index: number) {\n    const action = this.outstandingPuts_[index].action;\n    const request = this.outstandingPuts_[index].request;\n    const onComplete = this.outstandingPuts_[index].onComplete;\n    this.outstandingPuts_[index].queued = this.connected_;\n\n    this.sendRequest(action, request, (message: { [k: string]: unknown }) => {\n      this.log_(action + ' response', message);\n\n      delete this.outstandingPuts_[index];\n      this.outstandingPutCount_--;\n\n      // Clean up array occasionally.\n      if (this.outstandingPutCount_ === 0) {\n        this.outstandingPuts_ = [];\n      }\n\n      if (onComplete) {\n        onComplete(\n          message[/*status*/ 's'] as string,\n          message[/* data */ 'd'] as string\n        );\n      }\n    });\n  }\n\n  /**\n   * @inheritDoc\n   */\n  reportStats(stats: { [k: string]: unknown }) {\n    // If we're not connected, we just drop the stats.\n    if (this.connected_) {\n      const request = { /*counters*/ c: stats };\n      this.log_('reportStats', request);\n\n      this.sendRequest(/*stats*/ 's', request, result => {\n        const status = result[/*status*/ 's'];\n        if (status !== 'ok') {\n          const errorReason = result[/* data */ 'd'];\n          this.log_('reportStats', 'Error sending stats: ' + errorReason);\n        }\n      });\n    }\n  }\n\n  private onDataMessage_(message: { [k: string]: unknown }) {\n    if ('r' in message) {\n      // this is a response\n      this.log_('from server: ' + stringify(message));\n      const reqNum = message['r'] as string;\n      const onResponse = this.requestCBHash_[reqNum];\n      if (onResponse) {\n        delete this.requestCBHash_[reqNum];\n        onResponse(message[/*body*/ 'b']);\n      }\n    } else if ('error' in message) {\n      throw 'A server-side error has occurred: ' + message['error'];\n    } else if ('a' in message) {\n      // a and b are action and body, respectively\n      this.onDataPush_(message['a'] as string, message['b'] as {});\n    }\n  }\n\n  private onDataPush_(action: string, body: { [k: string]: unknown }) {\n    this.log_('handleServerMessage', action, body);\n    if (action === 'd') {\n      this.onDataUpdate_(\n        body[/*path*/ 'p'] as string,\n        body[/*data*/ 'd'],\n        /*isMerge*/ false,\n        body['t'] as number\n      );\n    } else if (action === 'm') {\n      this.onDataUpdate_(\n        body[/*path*/ 'p'] as string,\n        body[/*data*/ 'd'],\n        /*isMerge=*/ true,\n        body['t'] as number\n      );\n    } else if (action === 'c') {\n      this.onListenRevoked_(\n        body[/*path*/ 'p'] as string,\n        body[/*query*/ 'q'] as unknown[]\n      );\n    } else if (action === 'ac') {\n      this.onAuthRevoked_(\n        body[/*status code*/ 's'] as string,\n        body[/* explanation */ 'd'] as string\n      );\n    } else if (action === 'sd') {\n      this.onSecurityDebugPacket_(body);\n    } else {\n      error(\n        'Unrecognized action received from server: ' +\n          stringify(action) +\n          '\\nAre you using the latest client?'\n      );\n    }\n  }\n\n  private onReady_(timestamp: number, sessionId: string) {\n    this.log_('connection ready');\n    this.connected_ = true;\n    this.lastConnectionEstablishedTime_ = new Date().getTime();\n    this.handleTimestamp_(timestamp);\n    this.lastSessionId = sessionId;\n    if (this.firstConnection_) {\n      this.sendConnectStats_();\n    }\n    this.restoreState_();\n    this.firstConnection_ = false;\n    this.onConnectStatus_(true);\n  }\n\n  private scheduleConnect_(timeout: number) {\n    assert(\n      !this.realtime_,\n      \"Scheduling a connect when we're already connected/ing?\"\n    );\n\n    if (this.establishConnectionTimer_) {\n      clearTimeout(this.establishConnectionTimer_);\n    }\n\n    // NOTE: Even when timeout is 0, it's important to do a setTimeout to work around an infuriating \"Security Error\" in\n    // Firefox when trying to write to our long-polling iframe in some scenarios (e.g. Forge or our unit tests).\n\n    this.establishConnectionTimer_ = setTimeout(() => {\n      this.establishConnectionTimer_ = null;\n      this.establishConnection_();\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    }, Math.floor(timeout)) as any;\n  }\n\n  private onVisible_(visible: boolean) {\n    // NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine.\n    if (\n      visible &&\n      !this.visible_ &&\n      this.reconnectDelay_ === this.maxReconnectDelay_\n    ) {\n      this.log_('Window became visible.  Reducing delay.');\n      this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n\n      if (!this.realtime_) {\n        this.scheduleConnect_(0);\n      }\n    }\n    this.visible_ = visible;\n  }\n\n  private onOnline_(online: boolean) {\n    if (online) {\n      this.log_('Browser went online.');\n      this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n      if (!this.realtime_) {\n        this.scheduleConnect_(0);\n      }\n    } else {\n      this.log_('Browser went offline.  Killing connection.');\n      if (this.realtime_) {\n        this.realtime_.close();\n      }\n    }\n  }\n\n  private onRealtimeDisconnect_() {\n    this.log_('data client disconnected');\n    this.connected_ = false;\n    this.realtime_ = null;\n\n    // Since we don't know if our sent transactions succeeded or not, we need to cancel them.\n    this.cancelSentTransactions_();\n\n    // Clear out the pending requests.\n    this.requestCBHash_ = {};\n\n    if (this.shouldReconnect_()) {\n      if (!this.visible_) {\n        this.log_(\"Window isn't visible.  Delaying reconnect.\");\n        this.reconnectDelay_ = this.maxReconnectDelay_;\n        this.lastConnectionAttemptTime_ = new Date().getTime();\n      } else if (this.lastConnectionEstablishedTime_) {\n        // If we've been connected long enough, reset reconnect delay to minimum.\n        const timeSinceLastConnectSucceeded =\n          new Date().getTime() - this.lastConnectionEstablishedTime_;\n        if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT) {\n          this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n        }\n        this.lastConnectionEstablishedTime_ = null;\n      }\n\n      const timeSinceLastConnectAttempt =\n        new Date().getTime() - this.lastConnectionAttemptTime_;\n      let reconnectDelay = Math.max(\n        0,\n        this.reconnectDelay_ - timeSinceLastConnectAttempt\n      );\n      reconnectDelay = Math.random() * reconnectDelay;\n\n      this.log_('Trying to reconnect in ' + reconnectDelay + 'ms');\n      this.scheduleConnect_(reconnectDelay);\n\n      // Adjust reconnect delay for next time.\n      this.reconnectDelay_ = Math.min(\n        this.maxReconnectDelay_,\n        this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER\n      );\n    }\n    this.onConnectStatus_(false);\n  }\n\n  private establishConnection_() {\n    if (this.shouldReconnect_()) {\n      this.log_('Making a connection attempt');\n      this.lastConnectionAttemptTime_ = new Date().getTime();\n      this.lastConnectionEstablishedTime_ = null;\n      const onDataMessage = this.onDataMessage_.bind(this);\n      const onReady = this.onReady_.bind(this);\n      const onDisconnect = this.onRealtimeDisconnect_.bind(this);\n      const connId = this.id + ':' + PersistentConnection.nextConnectionId_++;\n      const self = this;\n      const lastSessionId = this.lastSessionId;\n      let canceled = false;\n      let connection: Connection | null = null;\n      const closeFn = function () {\n        if (connection) {\n          connection.close();\n        } else {\n          canceled = true;\n          onDisconnect();\n        }\n      };\n      const sendRequestFn = function (msg: object) {\n        assert(\n          connection,\n          \"sendRequest call when we're not connected not allowed.\"\n        );\n        connection.sendRequest(msg);\n      };\n\n      this.realtime_ = {\n        close: closeFn,\n        sendRequest: sendRequestFn\n      };\n\n      const forceRefresh = this.forceTokenRefresh_;\n      this.forceTokenRefresh_ = false;\n\n      // First fetch auth token, and establish connection after fetching the token was successful\n      this.authTokenProvider_\n        .getToken(forceRefresh)\n        .then(result => {\n          if (!canceled) {\n            log('getToken() completed. Creating connection.');\n            self.authToken_ = result && result.accessToken;\n            connection = new Connection(\n              connId,\n              self.repoInfo_,\n              self.applicationId_,\n              onDataMessage,\n              onReady,\n              onDisconnect,\n              /* onKill= */ reason => {\n                warn(reason + ' (' + self.repoInfo_.toString() + ')');\n                self.interrupt(SERVER_KILL_INTERRUPT_REASON);\n              },\n              lastSessionId\n            );\n          } else {\n            log('getToken() completed but was canceled');\n          }\n        })\n        .then(null, error => {\n          self.log_('Failed to get token: ' + error);\n          if (!canceled) {\n            if (CONSTANTS.NODE_ADMIN) {\n              // This may be a critical error for the Admin Node.js SDK, so log a warning.\n              // But getToken() may also just have temporarily failed, so we still want to\n              // continue retrying.\n              warn(error);\n            }\n            closeFn();\n          }\n        });\n    }\n  }\n\n  interrupt(reason: string) {\n    log('Interrupting connection for reason: ' + reason);\n    this.interruptReasons_[reason] = true;\n    if (this.realtime_) {\n      this.realtime_.close();\n    } else {\n      if (this.establishConnectionTimer_) {\n        clearTimeout(this.establishConnectionTimer_);\n        this.establishConnectionTimer_ = null;\n      }\n      if (this.connected_) {\n        this.onRealtimeDisconnect_();\n      }\n    }\n  }\n\n  resume(reason: string) {\n    log('Resuming connection for reason: ' + reason);\n    delete this.interruptReasons_[reason];\n    if (isEmpty(this.interruptReasons_)) {\n      this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n      if (!this.realtime_) {\n        this.scheduleConnect_(0);\n      }\n    }\n  }\n\n  private handleTimestamp_(timestamp: number) {\n    const delta = timestamp - new Date().getTime();\n    this.onServerInfoUpdate_({ serverTimeOffset: delta });\n  }\n\n  private cancelSentTransactions_() {\n    for (let i = 0; i < this.outstandingPuts_.length; i++) {\n      const put = this.outstandingPuts_[i];\n      if (put && /*hash*/ 'h' in put.request && put.queued) {\n        if (put.onComplete) {\n          put.onComplete('disconnect');\n        }\n\n        delete this.outstandingPuts_[i];\n        this.outstandingPutCount_--;\n      }\n    }\n\n    // Clean up array occasionally.\n    if (this.outstandingPutCount_ === 0) {\n      this.outstandingPuts_ = [];\n    }\n  }\n\n  private onListenRevoked_(pathString: string, query?: unknown[]) {\n    // Remove the listen and manufacture a \"permission_denied\" error for the failed listen.\n    let queryId;\n    if (!query) {\n      queryId = 'default';\n    } else {\n      queryId = query.map(q => ObjectToUniqueKey(q)).join('$');\n    }\n    const listen = this.removeListen_(pathString, queryId);\n    if (listen && listen.onComplete) {\n      listen.onComplete('permission_denied');\n    }\n  }\n\n  private removeListen_(pathString: string, queryId: string): ListenSpec {\n    const normalizedPathString = new Path(pathString).toString(); // normalize path.\n    let listen;\n    if (this.listens.has(normalizedPathString)) {\n      const map = this.listens.get(normalizedPathString)!;\n      listen = map.get(queryId);\n      map.delete(queryId);\n      if (map.size === 0) {\n        this.listens.delete(normalizedPathString);\n      }\n    } else {\n      // all listens for this path has already been removed\n      listen = undefined;\n    }\n    return listen;\n  }\n\n  private onAuthRevoked_(statusCode: string, explanation: string) {\n    log('Auth token revoked: ' + statusCode + '/' + explanation);\n    this.authToken_ = null;\n    this.forceTokenRefresh_ = true;\n    this.realtime_.close();\n    if (statusCode === 'invalid_token' || statusCode === 'permission_denied') {\n      // We'll wait a couple times before logging the warning / increasing the\n      // retry period since oauth tokens will report as \"invalid\" if they're\n      // just expired. Plus there may be transient issues that resolve themselves.\n      this.invalidAuthTokenCount_++;\n      if (this.invalidAuthTokenCount_ >= INVALID_AUTH_TOKEN_THRESHOLD) {\n        // Set a long reconnect delay because recovery is unlikely\n        this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n\n        // Notify the auth token provider that the token is invalid, which will log\n        // a warning\n        this.authTokenProvider_.notifyForInvalidToken();\n      }\n    }\n  }\n\n  private onSecurityDebugPacket_(body: { [k: string]: unknown }) {\n    if (this.securityDebugCallback_) {\n      this.securityDebugCallback_(body);\n    } else {\n      if ('msg' in body) {\n        console.log(\n          'FIREBASE: ' + (body['msg'] as string).replace('\\n', '\\nFIREBASE: ')\n        );\n      }\n    }\n  }\n\n  private restoreState_() {\n    //Re-authenticate ourselves if we have a credential stored.\n    this.tryAuth();\n\n    // Puts depend on having received the corresponding data update from the server before they complete, so we must\n    // make sure to send listens before puts.\n    for (const queries of this.listens.values()) {\n      for (const listenSpec of queries.values()) {\n        this.sendListen_(listenSpec);\n      }\n    }\n\n    for (let i = 0; i < this.outstandingPuts_.length; i++) {\n      if (this.outstandingPuts_[i]) {\n        this.sendPut_(i);\n      }\n    }\n\n    while (this.onDisconnectRequestQueue_.length) {\n      const request = this.onDisconnectRequestQueue_.shift();\n      this.sendOnDisconnect_(\n        request.action,\n        request.pathString,\n        request.data,\n        request.onComplete\n      );\n    }\n  }\n\n  /**\n   * Sends client stats for first connection\n   */\n  private sendConnectStats_() {\n    const stats: { [k: string]: number } = {};\n\n    let clientName = 'js';\n    if (CONSTANTS.NODE_ADMIN) {\n      clientName = 'admin_node';\n    } else if (CONSTANTS.NODE_CLIENT) {\n      clientName = 'node';\n    }\n\n    stats['sdk.' + clientName + '.' + SDK_VERSION.replace(/\\./g, '-')] = 1;\n\n    if (isMobileCordova()) {\n      stats['framework.cordova'] = 1;\n    } else if (isReactNative()) {\n      stats['framework.reactnative'] = 1;\n    }\n    this.reportStats(stats);\n  }\n\n  private shouldReconnect_(): boolean {\n    const online = OnlineMonitor.getInstance().currentlyOnline();\n    return isEmpty(this.interruptReasons_) && online;\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, jsonEval, safeGet, querystring } from '@firebase/util';\nimport { logWrapper, warn } from './util/util';\n\nimport { ServerActions } from './ServerActions';\nimport { RepoInfo } from './RepoInfo';\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { Query } from '../api/Query';\n\n/**\n * An implementation of ServerActions that communicates with the server via REST requests.\n * This is mostly useful for compatibility with crawlers, where we don't want to spin up a full\n * persistent connection (using WebSockets or long-polling)\n */\nexport class ReadonlyRestClient extends ServerActions {\n  reportStats(stats: { [k: string]: unknown }): void {\n    throw new Error('Method not implemented.');\n  }\n\n  /** @private {function(...[*])} */\n  private log_: (...args: unknown[]) => void = logWrapper('p:rest:');\n\n  /**\n   * We don't actually need to track listens, except to prevent us calling an onComplete for a listen\n   * that's been removed. :-/\n   *\n   * @private {!Object.<string, !Object>}\n   */\n  private listens_: { [k: string]: object } = {};\n\n  /**\n   * @param {!Query} query\n   * @param {?number=} tag\n   * @return {string}\n   * @private\n   */\n  static getListenId_(query: Query, tag?: number | null): string {\n    if (tag !== undefined) {\n      return 'tag$' + tag;\n    } else {\n      assert(\n        query.getQueryParams().isDefault(),\n        \"should have a tag if it's not a default query.\"\n      );\n      return query.path.toString();\n    }\n  }\n\n  /**\n   * @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to\n   * @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server\n   * @param {AuthTokenProvider} authTokenProvider_\n   * @implements {ServerActions}\n   */\n  constructor(\n    private repoInfo_: RepoInfo,\n    private onDataUpdate_: (\n      a: string,\n      b: unknown,\n      c: boolean,\n      d: number | null\n    ) => void,\n    private authTokenProvider_: AuthTokenProvider\n  ) {\n    super();\n  }\n\n  /** @inheritDoc */\n  listen(\n    query: Query,\n    currentHashFn: () => string,\n    tag: number | null,\n    onComplete: (a: string, b: unknown) => void\n  ) {\n    const pathString = query.path.toString();\n    this.log_(\n      'Listen called for ' + pathString + ' ' + query.queryIdentifier()\n    );\n\n    // Mark this listener so we can tell if it's removed.\n    const listenId = ReadonlyRestClient.getListenId_(query, tag);\n    const thisListen = {};\n    this.listens_[listenId] = thisListen;\n\n    const queryStringParameters = query\n      .getQueryParams()\n      .toRestQueryStringParameters();\n\n    this.restRequest_(\n      pathString + '.json',\n      queryStringParameters,\n      (error, result) => {\n        let data = result;\n\n        if (error === 404) {\n          data = null;\n          error = null;\n        }\n\n        if (error === null) {\n          this.onDataUpdate_(pathString, data, /*isMerge=*/ false, tag);\n        }\n\n        if (safeGet(this.listens_, listenId) === thisListen) {\n          let status;\n          if (!error) {\n            status = 'ok';\n          } else if (error === 401) {\n            status = 'permission_denied';\n          } else {\n            status = 'rest_error:' + error;\n          }\n\n          onComplete(status, null);\n        }\n      }\n    );\n  }\n\n  /** @inheritDoc */\n  unlisten(query: Query, tag: number | null) {\n    const listenId = ReadonlyRestClient.getListenId_(query, tag);\n    delete this.listens_[listenId];\n  }\n\n  /** @inheritDoc */\n  refreshAuthToken(token: string) {\n    // no-op since we just always call getToken.\n  }\n\n  /**\n   * Performs a REST request to the given path, with the provided query string parameters,\n   * and any auth credentials we have.\n   *\n   * @param {!string} pathString\n   * @param {!Object.<string, *>} queryStringParameters\n   * @param {?function(?number, *=)} callback\n   * @private\n   */\n  private restRequest_(\n    pathString: string,\n    queryStringParameters: { [k: string]: string | number } = {},\n    callback: ((a: number | null, b?: unknown) => void) | null\n  ) {\n    queryStringParameters['format'] = 'export';\n\n    this.authTokenProvider_\n      .getToken(/*forceRefresh=*/ false)\n      .then(authTokenData => {\n        const authToken = authTokenData && authTokenData.accessToken;\n        if (authToken) {\n          queryStringParameters['auth'] = authToken;\n        }\n\n        const url =\n          (this.repoInfo_.secure ? 'https://' : 'http://') +\n          this.repoInfo_.host +\n          pathString +\n          '?' +\n          'ns=' +\n          this.repoInfo_.namespace +\n          querystring(queryStringParameters);\n\n        this.log_('Sending REST request for ' + url);\n        const xhr = new XMLHttpRequest();\n        xhr.onreadystatechange = () => {\n          if (callback && xhr.readyState === 4) {\n            this.log_(\n              'REST Response for ' + url + ' received. status:',\n              xhr.status,\n              'response:',\n              xhr.responseText\n            );\n            let res = null;\n            if (xhr.status >= 200 && xhr.status < 300) {\n              try {\n                res = jsonEval(xhr.responseText);\n              } catch (e) {\n                warn(\n                  'Failed to parse JSON response for ' +\n                    url +\n                    ': ' +\n                    xhr.responseText\n                );\n              }\n              callback(null, res);\n            } else {\n              // 401 and 404 are expected.\n              if (xhr.status !== 401 && xhr.status !== 404) {\n                warn(\n                  'Got unsuccessful REST response for ' +\n                    url +\n                    ' Status: ' +\n                    xhr.status\n                );\n              }\n              callback(xhr.status);\n            }\n            callback = null;\n          }\n        };\n\n        xhr.open('GET', url, /*asynchronous=*/ true);\n        xhr.send();\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 {\n  generateWithValues,\n  resolveDeferredValueSnapshot,\n  resolveDeferredValueTree\n} from './util/ServerValues';\nimport { nodeFromJSON } from './snap/nodeFromJSON';\nimport { Path } from './util/Path';\nimport { SparseSnapshotTree } from './SparseSnapshotTree';\nimport { SyncTree } from './SyncTree';\nimport { SnapshotHolder } from './SnapshotHolder';\nimport { stringify, map, isEmpty } from '@firebase/util';\nimport { beingCrawled, each, exceptionGuard, warn, log } from './util/util';\n\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { StatsManager } from './stats/StatsManager';\nimport { StatsReporter } from './stats/StatsReporter';\nimport { StatsListener } from './stats/StatsListener';\nimport { EventQueue } from './view/EventQueue';\nimport { PersistentConnection } from './PersistentConnection';\nimport { ReadonlyRestClient } from './ReadonlyRestClient';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { RepoInfo } from './RepoInfo';\nimport { Database } from '../api/Database';\nimport { ServerActions } from './ServerActions';\nimport { Query } from '../api/Query';\nimport { EventRegistration } from './view/EventRegistration';\nimport { StatsCollection } from './stats/StatsCollection';\nimport { Event } from './view/Event';\nimport { Node } from './snap/Node';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\nimport { Indexable } from './util/misc';\n\nconst INTERRUPT_REASON = 'repo_interrupt';\n\n/**\n * A connection to a single data repository.\n */\nexport class Repo {\n  dataUpdateCount = 0;\n  private infoSyncTree_: SyncTree;\n  private serverSyncTree_: SyncTree;\n\n  private stats_: StatsCollection;\n  private statsListener_: StatsListener | null = null;\n  private eventQueue_ = new EventQueue();\n  private nextWriteId_ = 1;\n  private server_: ServerActions;\n  private statsReporter_: StatsReporter;\n  private transactionsInit_: () => void;\n  private infoData_: SnapshotHolder;\n  private abortTransactions_: (path: Path) => Path;\n  private rerunTransactions_: (changedPath: Path) => Path;\n  private interceptServerDataCallback_:\n    | ((a: string, b: unknown) => void)\n    | null = null;\n  private __database: Database;\n\n  /** A list of data pieces and paths to be set when this client disconnects. */\n  private onDisconnect_ = new SparseSnapshotTree();\n\n  // TODO: This should be @private but it's used by test_access.js and internal.js\n  persistentConnection_: PersistentConnection | null = null;\n\n  constructor(\n    public repoInfo_: RepoInfo,\n    forceRestClient: boolean,\n    public app: FirebaseApp,\n    authTokenProvider: AuthTokenProvider\n  ) {\n    this.stats_ = StatsManager.getCollection(repoInfo_);\n\n    if (forceRestClient || beingCrawled()) {\n      this.server_ = new ReadonlyRestClient(\n        this.repoInfo_,\n        this.onDataUpdate_.bind(this),\n        authTokenProvider\n      );\n\n      // Minor hack: Fire onConnect immediately, since there's no actual connection.\n      setTimeout(this.onConnectStatus_.bind(this, true), 0);\n    } else {\n      const authOverride = app.options['databaseAuthVariableOverride'];\n      // Validate authOverride\n      if (typeof authOverride !== 'undefined' && authOverride !== null) {\n        if (typeof authOverride !== 'object') {\n          throw new Error(\n            'Only objects are supported for option databaseAuthVariableOverride'\n          );\n        }\n        try {\n          stringify(authOverride);\n        } catch (e) {\n          throw new Error('Invalid authOverride provided: ' + e);\n        }\n      }\n\n      this.persistentConnection_ = new PersistentConnection(\n        this.repoInfo_,\n        app.options.appId,\n        this.onDataUpdate_.bind(this),\n        this.onConnectStatus_.bind(this),\n        this.onServerInfoUpdate_.bind(this),\n        authTokenProvider,\n        authOverride\n      );\n\n      this.server_ = this.persistentConnection_;\n    }\n\n    authTokenProvider.addTokenChangeListener(token => {\n      this.server_.refreshAuthToken(token);\n    });\n\n    // In the case of multiple Repos for the same repoInfo (i.e. there are multiple Firebase.Contexts being used),\n    // we only want to create one StatsReporter.  As such, we'll report stats over the first Repo created.\n    this.statsReporter_ = StatsManager.getOrCreateReporter(\n      repoInfo_,\n      () => new StatsReporter(this.stats_, this.server_)\n    );\n\n    this.transactionsInit_();\n\n    // Used for .info.\n    this.infoData_ = new SnapshotHolder();\n    this.infoSyncTree_ = new SyncTree({\n      startListening: (query, tag, currentHashFn, onComplete) => {\n        let infoEvents: Event[] = [];\n        const node = this.infoData_.getNode(query.path);\n        // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events\n        // on initial data...\n        if (!node.isEmpty()) {\n          infoEvents = this.infoSyncTree_.applyServerOverwrite(\n            query.path,\n            node\n          );\n          setTimeout(() => {\n            onComplete('ok');\n          }, 0);\n        }\n        return infoEvents;\n      },\n      stopListening: () => {}\n    });\n    this.updateInfo_('connected', false);\n\n    this.serverSyncTree_ = new SyncTree({\n      startListening: (query, tag, currentHashFn, onComplete) => {\n        this.server_.listen(query, currentHashFn, tag, (status, data) => {\n          const events = onComplete(status, data);\n          this.eventQueue_.raiseEventsForChangedPath(query.path, events);\n        });\n        // No synchronous events for network-backed sync trees\n        return [];\n      },\n      stopListening: (query, tag) => {\n        this.server_.unlisten(query, tag);\n      }\n    });\n  }\n\n  /**\n   * @return The URL corresponding to the root of this Firebase.\n   */\n  toString(): string {\n    return (\n      (this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host\n    );\n  }\n\n  /**\n   * @return The namespace represented by the repo.\n   */\n  name(): string {\n    return this.repoInfo_.namespace;\n  }\n\n  /**\n   * @return The time in milliseconds, taking the server offset into account if we have one.\n   */\n  serverTime(): number {\n    const offsetNode = this.infoData_.getNode(\n      new Path('.info/serverTimeOffset')\n    );\n    const offset = (offsetNode.val() as number) || 0;\n    return new Date().getTime() + offset;\n  }\n\n  /**\n   * Generate ServerValues using some variables from the repo object.\n   */\n  generateServerValues(): Indexable {\n    return generateWithValues({\n      timestamp: this.serverTime()\n    });\n  }\n\n  /**\n   * Called by realtime when we get new messages from the server.\n   */\n  private onDataUpdate_(\n    pathString: string,\n    data: unknown,\n    isMerge: boolean,\n    tag: number | null\n  ) {\n    // For testing.\n    this.dataUpdateCount++;\n    const path = new Path(pathString);\n    data = this.interceptServerDataCallback_\n      ? this.interceptServerDataCallback_(pathString, data)\n      : data;\n    let events = [];\n    if (tag) {\n      if (isMerge) {\n        const taggedChildren = map(\n          data as { [k: string]: unknown },\n          (raw: unknown) => nodeFromJSON(raw)\n        );\n        events = this.serverSyncTree_.applyTaggedQueryMerge(\n          path,\n          taggedChildren,\n          tag\n        );\n      } else {\n        const taggedSnap = nodeFromJSON(data);\n        events = this.serverSyncTree_.applyTaggedQueryOverwrite(\n          path,\n          taggedSnap,\n          tag\n        );\n      }\n    } else if (isMerge) {\n      const changedChildren = map(\n        data as { [k: string]: unknown },\n        (raw: unknown) => nodeFromJSON(raw)\n      );\n      events = this.serverSyncTree_.applyServerMerge(path, changedChildren);\n    } else {\n      const snap = nodeFromJSON(data);\n      events = this.serverSyncTree_.applyServerOverwrite(path, snap);\n    }\n    let affectedPath = path;\n    if (events.length > 0) {\n      // Since we have a listener outstanding for each transaction, receiving any events\n      // is a proxy for some change having occurred.\n      affectedPath = this.rerunTransactions_(path);\n    }\n    this.eventQueue_.raiseEventsForChangedPath(affectedPath, events);\n  }\n\n  // TODO: This should be @private but it's used by test_access.js and internal.js\n  interceptServerData_(callback: ((a: string, b: unknown) => unknown) | null) {\n    this.interceptServerDataCallback_ = callback;\n  }\n\n  private onConnectStatus_(connectStatus: boolean) {\n    this.updateInfo_('connected', connectStatus);\n    if (connectStatus === false) {\n      this.runOnDisconnectEvents_();\n    }\n  }\n\n  private onServerInfoUpdate_(updates: object) {\n    each(updates, (key: string, value: unknown) => {\n      this.updateInfo_(key, value);\n    });\n  }\n\n  private updateInfo_(pathString: string, value: unknown) {\n    const path = new Path('/.info/' + pathString);\n    const newNode = nodeFromJSON(value);\n    this.infoData_.updateSnapshot(path, newNode);\n    const events = this.infoSyncTree_.applyServerOverwrite(path, newNode);\n    this.eventQueue_.raiseEventsForChangedPath(path, events);\n  }\n\n  private getNextWriteId_(): number {\n    return this.nextWriteId_++;\n  }\n\n  setWithPriority(\n    path: Path,\n    newVal: unknown,\n    newPriority: number | string | null,\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    this.log_('set', {\n      path: path.toString(),\n      value: newVal,\n      priority: newPriority\n    });\n\n    // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or\n    // (b) store unresolved paths on JSON parse\n    const serverValues = this.generateServerValues();\n    const newNodeUnresolved = nodeFromJSON(newVal, newPriority);\n    const existing = this.serverSyncTree_.calcCompleteEventCache(path);\n    const newNode = resolveDeferredValueSnapshot(\n      newNodeUnresolved,\n      existing,\n      serverValues\n    );\n\n    const writeId = this.getNextWriteId_();\n    const events = this.serverSyncTree_.applyUserOverwrite(\n      path,\n      newNode,\n      writeId,\n      true\n    );\n    this.eventQueue_.queueEvents(events);\n    this.server_.put(\n      path.toString(),\n      newNodeUnresolved.val(/*export=*/ true),\n      (status, errorReason) => {\n        const success = status === 'ok';\n        if (!success) {\n          warn('set at ' + path + ' failed: ' + status);\n        }\n\n        const clearEvents = this.serverSyncTree_.ackUserWrite(\n          writeId,\n          !success\n        );\n        this.eventQueue_.raiseEventsForChangedPath(path, clearEvents);\n        this.callOnCompleteCallback(onComplete, status, errorReason);\n      }\n    );\n    const affectedPath = this.abortTransactions_(path);\n    this.rerunTransactions_(affectedPath);\n    // We queued the events above, so just flush the queue here\n    this.eventQueue_.raiseEventsForChangedPath(affectedPath, []);\n  }\n\n  update(\n    path: Path,\n    childrenToMerge: { [k: string]: unknown },\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    this.log_('update', { path: path.toString(), value: childrenToMerge });\n\n    // Start with our existing data and merge each child into it.\n    let empty = true;\n    const serverValues = this.generateServerValues();\n    const changedChildren: { [k: string]: Node } = {};\n    each(childrenToMerge, (changedKey: string, changedValue: unknown) => {\n      empty = false;\n      changedChildren[changedKey] = resolveDeferredValueTree(\n        path.child(changedKey),\n        nodeFromJSON(changedValue),\n        this.serverSyncTree_,\n        serverValues\n      );\n    });\n\n    if (!empty) {\n      const writeId = this.getNextWriteId_();\n      const events = this.serverSyncTree_.applyUserMerge(\n        path,\n        changedChildren,\n        writeId\n      );\n      this.eventQueue_.queueEvents(events);\n      this.server_.merge(\n        path.toString(),\n        childrenToMerge,\n        (status, errorReason) => {\n          const success = status === 'ok';\n          if (!success) {\n            warn('update at ' + path + ' failed: ' + status);\n          }\n\n          const clearEvents = this.serverSyncTree_.ackUserWrite(\n            writeId,\n            !success\n          );\n          const affectedPath =\n            clearEvents.length > 0 ? this.rerunTransactions_(path) : path;\n          this.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);\n          this.callOnCompleteCallback(onComplete, status, errorReason);\n        }\n      );\n\n      each(childrenToMerge, (changedPath: string) => {\n        const affectedPath = this.abortTransactions_(path.child(changedPath));\n        this.rerunTransactions_(affectedPath);\n      });\n\n      // We queued the events above, so just flush the queue here\n      this.eventQueue_.raiseEventsForChangedPath(path, []);\n    } else {\n      log(\"update() called with empty data.  Don't do anything.\");\n      this.callOnCompleteCallback(onComplete, 'ok');\n    }\n  }\n\n  /**\n   * Applies all of the changes stored up in the onDisconnect_ tree.\n   */\n  private runOnDisconnectEvents_() {\n    this.log_('onDisconnectEvents');\n\n    const serverValues = this.generateServerValues();\n    const resolvedOnDisconnectTree = new SparseSnapshotTree();\n    this.onDisconnect_.forEachTree(Path.Empty, (path, node) => {\n      const resolved = resolveDeferredValueTree(\n        path,\n        node,\n        this.serverSyncTree_,\n        serverValues\n      );\n      resolvedOnDisconnectTree.remember(path, resolved);\n    });\n    let events: Event[] = [];\n\n    resolvedOnDisconnectTree.forEachTree(Path.Empty, (path, snap) => {\n      events = events.concat(\n        this.serverSyncTree_.applyServerOverwrite(path, snap)\n      );\n      const affectedPath = this.abortTransactions_(path);\n      this.rerunTransactions_(affectedPath);\n    });\n\n    this.onDisconnect_ = new SparseSnapshotTree();\n    this.eventQueue_.raiseEventsForChangedPath(Path.Empty, events);\n  }\n\n  onDisconnectCancel(\n    path: Path,\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    this.server_.onDisconnectCancel(path.toString(), (status, errorReason) => {\n      if (status === 'ok') {\n        this.onDisconnect_.forget(path);\n      }\n      this.callOnCompleteCallback(onComplete, status, errorReason);\n    });\n  }\n\n  onDisconnectSet(\n    path: Path,\n    value: unknown,\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    const newNode = nodeFromJSON(value);\n    this.server_.onDisconnectPut(\n      path.toString(),\n      newNode.val(/*export=*/ true),\n      (status, errorReason) => {\n        if (status === 'ok') {\n          this.onDisconnect_.remember(path, newNode);\n        }\n        this.callOnCompleteCallback(onComplete, status, errorReason);\n      }\n    );\n  }\n\n  onDisconnectSetWithPriority(\n    path: Path,\n    value: unknown,\n    priority: unknown,\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    const newNode = nodeFromJSON(value, priority);\n    this.server_.onDisconnectPut(\n      path.toString(),\n      newNode.val(/*export=*/ true),\n      (status, errorReason) => {\n        if (status === 'ok') {\n          this.onDisconnect_.remember(path, newNode);\n        }\n        this.callOnCompleteCallback(onComplete, status, errorReason);\n      }\n    );\n  }\n\n  onDisconnectUpdate(\n    path: Path,\n    childrenToMerge: { [k: string]: unknown },\n    onComplete: ((status: Error | null, errorReason?: string) => void) | null\n  ) {\n    if (isEmpty(childrenToMerge)) {\n      log(\n        \"onDisconnect().update() called with empty data.  Don't do anything.\"\n      );\n      this.callOnCompleteCallback(onComplete, 'ok');\n      return;\n    }\n\n    this.server_.onDisconnectMerge(\n      path.toString(),\n      childrenToMerge,\n      (status, errorReason) => {\n        if (status === 'ok') {\n          each(childrenToMerge, (childName: string, childNode: unknown) => {\n            const newChildNode = nodeFromJSON(childNode);\n            this.onDisconnect_.remember(path.child(childName), newChildNode);\n          });\n        }\n        this.callOnCompleteCallback(onComplete, status, errorReason);\n      }\n    );\n  }\n\n  addEventCallbackForQuery(query: Query, eventRegistration: EventRegistration) {\n    let events;\n    if (query.path.getFront() === '.info') {\n      events = this.infoSyncTree_.addEventRegistration(\n        query,\n        eventRegistration\n      );\n    } else {\n      events = this.serverSyncTree_.addEventRegistration(\n        query,\n        eventRegistration\n      );\n    }\n    this.eventQueue_.raiseEventsAtPath(query.path, events);\n  }\n\n  removeEventCallbackForQuery(\n    query: Query,\n    eventRegistration: EventRegistration\n  ) {\n    // These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof\n    // a little bit by handling the return values anyways.\n    let events;\n    if (query.path.getFront() === '.info') {\n      events = this.infoSyncTree_.removeEventRegistration(\n        query,\n        eventRegistration\n      );\n    } else {\n      events = this.serverSyncTree_.removeEventRegistration(\n        query,\n        eventRegistration\n      );\n    }\n    this.eventQueue_.raiseEventsAtPath(query.path, events);\n  }\n\n  interrupt() {\n    if (this.persistentConnection_) {\n      this.persistentConnection_.interrupt(INTERRUPT_REASON);\n    }\n  }\n\n  resume() {\n    if (this.persistentConnection_) {\n      this.persistentConnection_.resume(INTERRUPT_REASON);\n    }\n  }\n\n  stats(showDelta: boolean = false) {\n    if (typeof console === 'undefined') {\n      return;\n    }\n\n    let stats: { [k: string]: unknown };\n    if (showDelta) {\n      if (!this.statsListener_) {\n        this.statsListener_ = new StatsListener(this.stats_);\n      }\n      stats = this.statsListener_.get();\n    } else {\n      stats = this.stats_.get();\n    }\n\n    const longestName = Object.keys(stats).reduce(\n      (previousValue, currentValue) =>\n        Math.max(currentValue.length, previousValue),\n      0\n    );\n\n    each(stats, (stat: string, value: unknown) => {\n      let paddedStat = stat;\n      // pad stat names to be the same length (plus 2 extra spaces).\n      for (let i = stat.length; i < longestName + 2; i++) {\n        paddedStat += ' ';\n      }\n      console.log(paddedStat + value);\n    });\n  }\n\n  statsIncrementCounter(metric: string) {\n    this.stats_.incrementCounter(metric);\n    this.statsReporter_.includeStat(metric);\n  }\n\n  private log_(...varArgs: unknown[]) {\n    let prefix = '';\n    if (this.persistentConnection_) {\n      prefix = this.persistentConnection_.id + ':';\n    }\n    log(prefix, ...varArgs);\n  }\n\n  callOnCompleteCallback(\n    callback: ((status: Error | null, errorReason?: string) => void) | null,\n    status: string,\n    errorReason?: string | null\n  ) {\n    if (callback) {\n      exceptionGuard(() => {\n        if (status === 'ok') {\n          callback(null);\n        } else {\n          const code = (status || 'error').toUpperCase();\n          let message = code;\n          if (errorReason) {\n            message += ': ' + errorReason;\n          }\n\n          const error = new Error(message);\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          (error as any).code = code;\n          callback(error);\n        }\n      });\n    }\n  }\n\n  get database(): Database {\n    return this.__database || (this.__database = new Database(this));\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 { IndexedFilter } from './IndexedFilter';\nimport { PRIORITY_INDEX } from '../../snap/indexes/PriorityIndex';\nimport { NamedNode, Node } from '../../../core/snap/Node';\nimport { ChildrenNode } from '../../snap/ChildrenNode';\nimport { NodeFilter } from './NodeFilter';\nimport { QueryParams } from '../QueryParams';\nimport { Index } from '../../snap/indexes/Index';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\n\n/**\n * Filters nodes by range and uses an IndexFilter to track any changes after filtering the node\n *\n * @constructor\n * @implements {NodeFilter}\n */\nexport class RangedFilter implements NodeFilter {\n  /**\n   * @type {!IndexedFilter}\n   * @const\n   * @private\n   */\n  private indexedFilter_: IndexedFilter;\n\n  /**\n   * @const\n   * @type {!Index}\n   * @private\n   */\n  private index_: Index;\n\n  /**\n   * @const\n   * @type {!NamedNode}\n   * @private\n   */\n  private startPost_: NamedNode;\n\n  /**\n   * @const\n   * @type {!NamedNode}\n   * @private\n   */\n  private endPost_: NamedNode;\n\n  /**\n   * @param {!QueryParams} params\n   */\n  constructor(params: QueryParams) {\n    this.indexedFilter_ = new IndexedFilter(params.getIndex());\n    this.index_ = params.getIndex();\n    this.startPost_ = RangedFilter.getStartPost_(params);\n    this.endPost_ = RangedFilter.getEndPost_(params);\n  }\n\n  /**\n   * @return {!NamedNode}\n   */\n  getStartPost(): NamedNode {\n    return this.startPost_;\n  }\n\n  /**\n   * @return {!NamedNode}\n   */\n  getEndPost(): NamedNode {\n    return this.endPost_;\n  }\n\n  /**\n   * @param {!NamedNode} node\n   * @return {boolean}\n   */\n  matches(node: NamedNode): boolean {\n    return (\n      this.index_.compare(this.getStartPost(), node) <= 0 &&\n      this.index_.compare(node, this.getEndPost()) <= 0\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updateChild(\n    snap: Node,\n    key: string,\n    newChild: Node,\n    affectedPath: Path,\n    source: CompleteChildSource,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    if (!this.matches(new NamedNode(key, newChild))) {\n      newChild = ChildrenNode.EMPTY_NODE;\n    }\n    return this.indexedFilter_.updateChild(\n      snap,\n      key,\n      newChild,\n      affectedPath,\n      source,\n      optChangeAccumulator\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updateFullNode(\n    oldSnap: Node,\n    newSnap: Node,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    if (newSnap.isLeafNode()) {\n      // Make sure we have a children node with the correct index, not a leaf node;\n      newSnap = ChildrenNode.EMPTY_NODE;\n    }\n    let filtered = newSnap.withIndex(this.index_);\n    // Don't support priorities on queries\n    filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);\n    const self = this;\n    newSnap.forEachChild(PRIORITY_INDEX, (key, childNode) => {\n      if (!self.matches(new NamedNode(key, childNode))) {\n        filtered = filtered.updateImmediateChild(key, ChildrenNode.EMPTY_NODE);\n      }\n    });\n    return this.indexedFilter_.updateFullNode(\n      oldSnap,\n      filtered,\n      optChangeAccumulator\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updatePriority(oldSnap: Node, newPriority: Node): Node {\n    // Don't support priorities on queries\n    return oldSnap;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  filtersNodes(): boolean {\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndexedFilter(): IndexedFilter {\n    return this.indexedFilter_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndex(): Index {\n    return this.index_;\n  }\n\n  /**\n   * @param {!QueryParams} params\n   * @return {!NamedNode}\n   * @private\n   */\n  private static getStartPost_(params: QueryParams): NamedNode {\n    if (params.hasStart()) {\n      const startName = params.getIndexStartName();\n      return params.getIndex().makePost(params.getIndexStartValue(), startName);\n    } else {\n      return params.getIndex().minPost();\n    }\n  }\n\n  /**\n   * @param {!QueryParams} params\n   * @return {!NamedNode}\n   * @private\n   */\n  private static getEndPost_(params: QueryParams): NamedNode {\n    if (params.hasEnd()) {\n      const endName = params.getIndexEndName();\n      return params.getIndex().makePost(params.getIndexEndValue(), endName);\n    } else {\n      return params.getIndex().maxPost();\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 { RangedFilter } from './RangedFilter';\nimport { ChildrenNode } from '../../snap/ChildrenNode';\nimport { Node, NamedNode } from '../../snap/Node';\nimport { assert } from '@firebase/util';\nimport { Change } from '../Change';\nimport { NodeFilter } from './NodeFilter';\nimport { Index } from '../../snap/indexes/Index';\nimport { IndexedFilter } from './IndexedFilter';\nimport { QueryParams } from '../QueryParams';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\n\n/**\n * Applies a limit and a range to a node and uses RangedFilter to do the heavy lifting where possible\n *\n * @constructor\n * @implements {NodeFilter}\n */\nexport class LimitedFilter implements NodeFilter {\n  /**\n   * @const\n   * @type {RangedFilter}\n   * @private\n   */\n  private readonly rangedFilter_: RangedFilter;\n\n  /**\n   * @const\n   * @type {!Index}\n   * @private\n   */\n  private readonly index_: Index;\n\n  /**\n   * @const\n   * @type {number}\n   * @private\n   */\n  private readonly limit_: number;\n\n  /**\n   * @const\n   * @type {boolean}\n   * @private\n   */\n  private readonly reverse_: boolean;\n\n  /**\n   * @param {!QueryParams} params\n   */\n  constructor(params: QueryParams) {\n    this.rangedFilter_ = new RangedFilter(params);\n    this.index_ = params.getIndex();\n    this.limit_ = params.getLimit();\n    this.reverse_ = !params.isViewFromLeft();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updateChild(\n    snap: Node,\n    key: string,\n    newChild: Node,\n    affectedPath: Path,\n    source: CompleteChildSource,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {\n      newChild = ChildrenNode.EMPTY_NODE;\n    }\n    if (snap.getImmediateChild(key).equals(newChild)) {\n      // No change\n      return snap;\n    } else if (snap.numChildren() < this.limit_) {\n      return this.rangedFilter_\n        .getIndexedFilter()\n        .updateChild(\n          snap,\n          key,\n          newChild,\n          affectedPath,\n          source,\n          optChangeAccumulator\n        );\n    } else {\n      return this.fullLimitUpdateChild_(\n        snap,\n        key,\n        newChild,\n        source,\n        optChangeAccumulator\n      );\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updateFullNode(\n    oldSnap: Node,\n    newSnap: Node,\n    optChangeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    let filtered;\n    if (newSnap.isLeafNode() || newSnap.isEmpty()) {\n      // Make sure we have a children node with the correct index, not a leaf node;\n      filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n    } else {\n      if (\n        this.limit_ * 2 < newSnap.numChildren() &&\n        newSnap.isIndexed(this.index_)\n      ) {\n        // Easier to build up a snapshot, since what we're given has more than twice the elements we want\n        filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n        // anchor to the startPost, endPost, or last element as appropriate\n        let iterator;\n        if (this.reverse_) {\n          iterator = (newSnap as ChildrenNode).getReverseIteratorFrom(\n            this.rangedFilter_.getEndPost(),\n            this.index_\n          );\n        } else {\n          iterator = (newSnap as ChildrenNode).getIteratorFrom(\n            this.rangedFilter_.getStartPost(),\n            this.index_\n          );\n        }\n        let count = 0;\n        while (iterator.hasNext() && count < this.limit_) {\n          const next = iterator.getNext();\n          let inRange;\n          if (this.reverse_) {\n            inRange =\n              this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;\n          } else {\n            inRange =\n              this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;\n          }\n          if (inRange) {\n            filtered = filtered.updateImmediateChild(next.name, next.node);\n            count++;\n          } else {\n            // if we have reached the end post, we cannot keep adding elemments\n            break;\n          }\n        }\n      } else {\n        // The snap contains less than twice the limit. Faster to delete from the snap than build up a new one\n        filtered = newSnap.withIndex(this.index_);\n        // Don't support priorities on queries\n        filtered = filtered.updatePriority(\n          ChildrenNode.EMPTY_NODE\n        ) as ChildrenNode;\n        let startPost;\n        let endPost;\n        let cmp;\n        let iterator;\n        if (this.reverse_) {\n          iterator = filtered.getReverseIterator(this.index_);\n          startPost = this.rangedFilter_.getEndPost();\n          endPost = this.rangedFilter_.getStartPost();\n          const indexCompare = this.index_.getCompare();\n          cmp = (a: NamedNode, b: NamedNode) => indexCompare(b, a);\n        } else {\n          iterator = filtered.getIterator(this.index_);\n          startPost = this.rangedFilter_.getStartPost();\n          endPost = this.rangedFilter_.getEndPost();\n          cmp = this.index_.getCompare();\n        }\n\n        let count = 0;\n        let foundStartPost = false;\n        while (iterator.hasNext()) {\n          const next = iterator.getNext();\n          if (!foundStartPost && cmp(startPost, next) <= 0) {\n            // start adding\n            foundStartPost = true;\n          }\n          const inRange =\n            foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;\n          if (inRange) {\n            count++;\n          } else {\n            filtered = filtered.updateImmediateChild(\n              next.name,\n              ChildrenNode.EMPTY_NODE\n            );\n          }\n        }\n      }\n    }\n    return this.rangedFilter_\n      .getIndexedFilter()\n      .updateFullNode(oldSnap, filtered, optChangeAccumulator);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  updatePriority(oldSnap: Node, newPriority: Node): Node {\n    // Don't support priorities on queries\n    return oldSnap;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  filtersNodes(): boolean {\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndexedFilter(): IndexedFilter {\n    return this.rangedFilter_.getIndexedFilter();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getIndex(): Index {\n    return this.index_;\n  }\n\n  /**\n   * @param {!Node} snap\n   * @param {string} childKey\n   * @param {!Node} childSnap\n   * @param {!CompleteChildSource} source\n   * @param {?ChildChangeAccumulator} changeAccumulator\n   * @return {!Node}\n   * @private\n   */\n  private fullLimitUpdateChild_(\n    snap: Node,\n    childKey: string,\n    childSnap: Node,\n    source: CompleteChildSource,\n    changeAccumulator: ChildChangeAccumulator | null\n  ): Node {\n    // TODO: rename all cache stuff etc to general snap terminology\n    let cmp;\n    if (this.reverse_) {\n      const indexCmp = this.index_.getCompare();\n      cmp = (a: NamedNode, b: NamedNode) => indexCmp(b, a);\n    } else {\n      cmp = this.index_.getCompare();\n    }\n    const oldEventCache = snap as ChildrenNode;\n    assert(oldEventCache.numChildren() === this.limit_, '');\n    const newChildNamedNode = new NamedNode(childKey, childSnap);\n    const windowBoundary = this.reverse_\n      ? oldEventCache.getFirstChild(this.index_)\n      : (oldEventCache.getLastChild(this.index_) as NamedNode);\n    const inRange = this.rangedFilter_.matches(newChildNamedNode);\n    if (oldEventCache.hasChild(childKey)) {\n      const oldChildSnap = oldEventCache.getImmediateChild(childKey);\n      let nextChild = source.getChildAfterChild(\n        this.index_,\n        windowBoundary,\n        this.reverse_\n      );\n      while (\n        nextChild != null &&\n        (nextChild.name === childKey || oldEventCache.hasChild(nextChild.name))\n      ) {\n        // There is a weird edge case where a node is updated as part of a merge in the write tree, but hasn't\n        // been applied to the limited filter yet. Ignore this next child which will be updated later in\n        // the limited filter...\n        nextChild = source.getChildAfterChild(\n          this.index_,\n          nextChild,\n          this.reverse_\n        );\n      }\n      const compareNext =\n        nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);\n      const remainsInWindow =\n        inRange && !childSnap.isEmpty() && compareNext >= 0;\n      if (remainsInWindow) {\n        if (changeAccumulator != null) {\n          changeAccumulator.trackChildChange(\n            Change.childChangedChange(childKey, childSnap, oldChildSnap)\n          );\n        }\n        return oldEventCache.updateImmediateChild(childKey, childSnap);\n      } else {\n        if (changeAccumulator != null) {\n          changeAccumulator.trackChildChange(\n            Change.childRemovedChange(childKey, oldChildSnap)\n          );\n        }\n        const newEventCache = oldEventCache.updateImmediateChild(\n          childKey,\n          ChildrenNode.EMPTY_NODE\n        );\n        const nextChildInRange =\n          nextChild != null && this.rangedFilter_.matches(nextChild);\n        if (nextChildInRange) {\n          if (changeAccumulator != null) {\n            changeAccumulator.trackChildChange(\n              Change.childAddedChange(nextChild.name, nextChild.node)\n            );\n          }\n          return newEventCache.updateImmediateChild(\n            nextChild.name,\n            nextChild.node\n          );\n        } else {\n          return newEventCache;\n        }\n      }\n    } else if (childSnap.isEmpty()) {\n      // we're deleting a node, but it was not in the window, so ignore it\n      return snap;\n    } else if (inRange) {\n      if (cmp(windowBoundary, newChildNamedNode) >= 0) {\n        if (changeAccumulator != null) {\n          changeAccumulator.trackChildChange(\n            Change.childRemovedChange(windowBoundary.name, windowBoundary.node)\n          );\n          changeAccumulator.trackChildChange(\n            Change.childAddedChange(childKey, childSnap)\n          );\n        }\n        return oldEventCache\n          .updateImmediateChild(childKey, childSnap)\n          .updateImmediateChild(windowBoundary.name, ChildrenNode.EMPTY_NODE);\n      } else {\n        return snap;\n      }\n    } else {\n      return snap;\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, stringify } from '@firebase/util';\nimport { MIN_NAME, MAX_NAME } from '../util/util';\nimport { KEY_INDEX } from '../snap/indexes/KeyIndex';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { VALUE_INDEX } from '../snap/indexes/ValueIndex';\nimport { PathIndex } from '../snap/indexes/PathIndex';\nimport { IndexedFilter } from './filter/IndexedFilter';\nimport { LimitedFilter } from './filter/LimitedFilter';\nimport { RangedFilter } from './filter/RangedFilter';\nimport { NodeFilter } from './filter/NodeFilter';\nimport { Index } from '../snap/indexes/Index';\n\n/**\n * This class is an immutable-from-the-public-api struct containing a set of query parameters defining a\n * range to be returned for a particular location. It is assumed that validation of parameters is done at the\n * user-facing API level, so it is not done here.\n * @constructor\n */\nexport class QueryParams {\n  private limitSet_ = false;\n  private startSet_ = false;\n  private startNameSet_ = false;\n  private endSet_ = false;\n  private endNameSet_ = false;\n\n  private limit_ = 0;\n  private viewFrom_ = '';\n  private indexStartValue_: unknown | null = null;\n  private indexStartName_ = '';\n  private indexEndValue_: unknown | null = null;\n  private indexEndName_ = '';\n\n  private index_ = PRIORITY_INDEX;\n\n  /**\n   * Wire Protocol Constants\n   * @const\n   * @enum {string}\n   * @private\n   */\n  private static readonly WIRE_PROTOCOL_CONSTANTS_ = {\n    INDEX_START_VALUE: 'sp',\n    INDEX_START_NAME: 'sn',\n    INDEX_END_VALUE: 'ep',\n    INDEX_END_NAME: 'en',\n    LIMIT: 'l',\n    VIEW_FROM: 'vf',\n    VIEW_FROM_LEFT: 'l',\n    VIEW_FROM_RIGHT: 'r',\n    INDEX: 'i'\n  };\n\n  /**\n   * REST Query Constants\n   * @const\n   * @enum {string}\n   * @private\n   */\n  private static readonly REST_QUERY_CONSTANTS_ = {\n    ORDER_BY: 'orderBy',\n    PRIORITY_INDEX: '$priority',\n    VALUE_INDEX: '$value',\n    KEY_INDEX: '$key',\n    START_AT: 'startAt',\n    END_AT: 'endAt',\n    LIMIT_TO_FIRST: 'limitToFirst',\n    LIMIT_TO_LAST: 'limitToLast'\n  };\n\n  /**\n   * Default, empty query parameters\n   * @type {!QueryParams}\n   * @const\n   */\n  static readonly DEFAULT = new QueryParams();\n\n  /**\n   * @return {boolean}\n   */\n  hasStart(): boolean {\n    return this.startSet_;\n  }\n\n  /**\n   * @return {boolean} True if it would return from left.\n   */\n  isViewFromLeft(): boolean {\n    if (this.viewFrom_ === '') {\n      // limit(), rather than limitToFirst or limitToLast was called.\n      // This means that only one of startSet_ and endSet_ is true. Use them\n      // to calculate which side of the view to anchor to. If neither is set,\n      // anchor to the end.\n      return this.startSet_;\n    } else {\n      return (\n        this.viewFrom_ === QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT\n      );\n    }\n  }\n\n  /**\n   * Only valid to call if hasStart() returns true\n   * @return {*}\n   */\n  getIndexStartValue(): unknown {\n    assert(this.startSet_, 'Only valid if start has been set');\n    return this.indexStartValue_;\n  }\n\n  /**\n   * Only valid to call if hasStart() returns true.\n   * Returns the starting key name for the range defined by these query parameters\n   * @return {!string}\n   */\n  getIndexStartName(): string {\n    assert(this.startSet_, 'Only valid if start has been set');\n    if (this.startNameSet_) {\n      return this.indexStartName_;\n    } else {\n      return MIN_NAME;\n    }\n  }\n\n  /**\n   * @return {boolean}\n   */\n  hasEnd(): boolean {\n    return this.endSet_;\n  }\n\n  /**\n   * Only valid to call if hasEnd() returns true.\n   * @return {*}\n   */\n  getIndexEndValue(): unknown {\n    assert(this.endSet_, 'Only valid if end has been set');\n    return this.indexEndValue_;\n  }\n\n  /**\n   * Only valid to call if hasEnd() returns true.\n   * Returns the end key name for the range defined by these query parameters\n   * @return {!string}\n   */\n  getIndexEndName(): string {\n    assert(this.endSet_, 'Only valid if end has been set');\n    if (this.endNameSet_) {\n      return this.indexEndName_;\n    } else {\n      return MAX_NAME;\n    }\n  }\n\n  /**\n   * @return {boolean}\n   */\n  hasLimit(): boolean {\n    return this.limitSet_;\n  }\n\n  /**\n   * @return {boolean} True if a limit has been set and it has been explicitly anchored\n   */\n  hasAnchoredLimit(): boolean {\n    return this.limitSet_ && this.viewFrom_ !== '';\n  }\n\n  /**\n   * Only valid to call if hasLimit() returns true\n   * @return {!number}\n   */\n  getLimit(): number {\n    assert(this.limitSet_, 'Only valid if limit has been set');\n    return this.limit_;\n  }\n\n  /**\n   * @return {!Index}\n   */\n  getIndex(): Index {\n    return this.index_;\n  }\n\n  /**\n   * @return {!QueryParams}\n   * @private\n   */\n  private copy_(): QueryParams {\n    const copy = new QueryParams();\n    copy.limitSet_ = this.limitSet_;\n    copy.limit_ = this.limit_;\n    copy.startSet_ = this.startSet_;\n    copy.indexStartValue_ = this.indexStartValue_;\n    copy.startNameSet_ = this.startNameSet_;\n    copy.indexStartName_ = this.indexStartName_;\n    copy.endSet_ = this.endSet_;\n    copy.indexEndValue_ = this.indexEndValue_;\n    copy.endNameSet_ = this.endNameSet_;\n    copy.indexEndName_ = this.indexEndName_;\n    copy.index_ = this.index_;\n    copy.viewFrom_ = this.viewFrom_;\n    return copy;\n  }\n\n  /**\n   * @param {!number} newLimit\n   * @return {!QueryParams}\n   */\n  limit(newLimit: number): QueryParams {\n    const newParams = this.copy_();\n    newParams.limitSet_ = true;\n    newParams.limit_ = newLimit;\n    newParams.viewFrom_ = '';\n    return newParams;\n  }\n\n  /**\n   * @param {!number} newLimit\n   * @return {!QueryParams}\n   */\n  limitToFirst(newLimit: number): QueryParams {\n    const newParams = this.copy_();\n    newParams.limitSet_ = true;\n    newParams.limit_ = newLimit;\n    newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\n    return newParams;\n  }\n\n  /**\n   * @param {!number} newLimit\n   * @return {!QueryParams}\n   */\n  limitToLast(newLimit: number): QueryParams {\n    const newParams = this.copy_();\n    newParams.limitSet_ = true;\n    newParams.limit_ = newLimit;\n    newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_RIGHT;\n    return newParams;\n  }\n\n  /**\n   * @param {*} indexValue\n   * @param {?string=} key\n   * @return {!QueryParams}\n   */\n  startAt(indexValue: unknown, key?: string | null): QueryParams {\n    const newParams = this.copy_();\n    newParams.startSet_ = true;\n    if (indexValue === undefined) {\n      indexValue = null;\n    }\n    newParams.indexStartValue_ = indexValue;\n    if (key != null) {\n      newParams.startNameSet_ = true;\n      newParams.indexStartName_ = key;\n    } else {\n      newParams.startNameSet_ = false;\n      newParams.indexStartName_ = '';\n    }\n    return newParams;\n  }\n\n  /**\n   * @param {*} indexValue\n   * @param {?string=} key\n   * @return {!QueryParams}\n   */\n  endAt(indexValue: unknown, key?: string | null): QueryParams {\n    const newParams = this.copy_();\n    newParams.endSet_ = true;\n    if (indexValue === undefined) {\n      indexValue = null;\n    }\n    newParams.indexEndValue_ = indexValue;\n    if (key !== undefined) {\n      newParams.endNameSet_ = true;\n      newParams.indexEndName_ = key;\n    } else {\n      newParams.endNameSet_ = false;\n      newParams.indexEndName_ = '';\n    }\n    return newParams;\n  }\n\n  /**\n   * @param {!Index} index\n   * @return {!QueryParams}\n   */\n  orderBy(index: Index): QueryParams {\n    const newParams = this.copy_();\n    newParams.index_ = index;\n    return newParams;\n  }\n\n  /**\n   * @return {!Object}\n   */\n  getQueryObject(): {} {\n    const WIRE_PROTOCOL_CONSTANTS = QueryParams.WIRE_PROTOCOL_CONSTANTS_;\n    const obj: { [k: string]: unknown } = {};\n    if (this.startSet_) {\n      obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE] = this.indexStartValue_;\n      if (this.startNameSet_) {\n        obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME] = this.indexStartName_;\n      }\n    }\n    if (this.endSet_) {\n      obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE] = this.indexEndValue_;\n      if (this.endNameSet_) {\n        obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME] = this.indexEndName_;\n      }\n    }\n    if (this.limitSet_) {\n      obj[WIRE_PROTOCOL_CONSTANTS.LIMIT] = this.limit_;\n      let viewFrom = this.viewFrom_;\n      if (viewFrom === '') {\n        if (this.isViewFromLeft()) {\n          viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT;\n        } else {\n          viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT;\n        }\n      }\n      obj[WIRE_PROTOCOL_CONSTANTS.VIEW_FROM] = viewFrom;\n    }\n    // For now, priority index is the default, so we only specify if it's some other index\n    if (this.index_ !== PRIORITY_INDEX) {\n      obj[WIRE_PROTOCOL_CONSTANTS.INDEX] = this.index_.toString();\n    }\n    return obj;\n  }\n\n  /**\n   * @return {boolean}\n   */\n  loadsAllData(): boolean {\n    return !(this.startSet_ || this.endSet_ || this.limitSet_);\n  }\n\n  /**\n   * @return {boolean}\n   */\n  isDefault(): boolean {\n    return this.loadsAllData() && this.index_ === PRIORITY_INDEX;\n  }\n\n  /**\n   * @return {!NodeFilter}\n   */\n  getNodeFilter(): NodeFilter {\n    if (this.loadsAllData()) {\n      return new IndexedFilter(this.getIndex());\n    } else if (this.hasLimit()) {\n      return new LimitedFilter(this);\n    } else {\n      return new RangedFilter(this);\n    }\n  }\n\n  /**\n   * Returns a set of REST query string parameters representing this query.\n   *\n   * @return {!Object.<string,*>} query string parameters\n   */\n  toRestQueryStringParameters(): { [k: string]: string | number } {\n    const REST_CONSTANTS = QueryParams.REST_QUERY_CONSTANTS_;\n    const qs: { [k: string]: string | number } = {};\n\n    if (this.isDefault()) {\n      return qs;\n    }\n\n    let orderBy;\n    if (this.index_ === PRIORITY_INDEX) {\n      orderBy = REST_CONSTANTS.PRIORITY_INDEX;\n    } else if (this.index_ === VALUE_INDEX) {\n      orderBy = REST_CONSTANTS.VALUE_INDEX;\n    } else if (this.index_ === KEY_INDEX) {\n      orderBy = REST_CONSTANTS.KEY_INDEX;\n    } else {\n      assert(this.index_ instanceof PathIndex, 'Unrecognized index type!');\n      orderBy = this.index_.toString();\n    }\n    qs[REST_CONSTANTS.ORDER_BY] = stringify(orderBy);\n\n    if (this.startSet_) {\n      qs[REST_CONSTANTS.START_AT] = stringify(this.indexStartValue_);\n      if (this.startNameSet_) {\n        qs[REST_CONSTANTS.START_AT] += ',' + stringify(this.indexStartName_);\n      }\n    }\n\n    if (this.endSet_) {\n      qs[REST_CONSTANTS.END_AT] = stringify(this.indexEndValue_);\n      if (this.endNameSet_) {\n        qs[REST_CONSTANTS.END_AT] += ',' + stringify(this.indexEndName_);\n      }\n    }\n\n    if (this.limitSet_) {\n      if (this.isViewFromLeft()) {\n        qs[REST_CONSTANTS.LIMIT_TO_FIRST] = this.limit_;\n      } else {\n        qs[REST_CONSTANTS.LIMIT_TO_LAST] = this.limit_;\n      }\n    }\n\n    return qs;\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 { OnDisconnect } from './onDisconnect';\nimport { TransactionResult } from './TransactionResult';\nimport { warn } from '../core/util/util';\nimport { nextPushId } from '../core/util/NextPushId';\nimport { Query } from './Query';\nimport { Repo } from '../core/Repo';\nimport { Path } from '../core/util/Path';\nimport { QueryParams } from '../core/view/QueryParams';\nimport {\n  validateRootPathString,\n  validatePathString,\n  validateFirebaseMergeDataArg,\n  validateBoolean,\n  validatePriority,\n  validateFirebaseDataArg,\n  validateWritablePath\n} from '../core/util/validation';\nimport { validateArgCount, validateCallback, Deferred } from '@firebase/util';\n\nimport { SyncPoint } from '../core/SyncPoint';\nimport { Database } from './Database';\nimport { DataSnapshot } from './DataSnapshot';\nimport * as types from '@firebase/database-types';\n\nexport interface ReferenceConstructor {\n  new (repo: Repo, path: Path): Reference;\n}\n\nexport class Reference extends Query {\n  then: Promise<Reference>['then'];\n  catch: Promise<Reference>['catch'];\n\n  /**\n   * Call options:\n   *   new Reference(Repo, Path) or\n   *   new Reference(url: string, string|RepoManager)\n   *\n   * Externally - this is the firebase.database.Reference type.\n   *\n   * @param {!Repo} repo\n   * @param {(!Path)} path\n   * @extends {Query}\n   */\n  constructor(repo: Repo, path: Path) {\n    if (!(repo instanceof Repo)) {\n      throw new Error(\n        'new Reference() no longer supported - use app.database().'\n      );\n    }\n\n    // call Query's constructor, passing in the repo and path.\n    super(repo, path, QueryParams.DEFAULT, false);\n  }\n\n  /** @return {?string} */\n  getKey(): string | null {\n    validateArgCount('Reference.key', 0, 0, arguments.length);\n\n    if (this.path.isEmpty()) {\n      return null;\n    } else {\n      return this.path.getBack();\n    }\n  }\n\n  /**\n   * @param {!(string|Path)} pathString\n   * @return {!Reference}\n   */\n  child(pathString: string | Path): Reference {\n    validateArgCount('Reference.child', 1, 1, arguments.length);\n    if (typeof pathString === 'number') {\n      pathString = String(pathString);\n    } else if (!(pathString instanceof Path)) {\n      if (this.path.getFront() === null) {\n        validateRootPathString('Reference.child', 1, pathString, false);\n      } else {\n        validatePathString('Reference.child', 1, pathString, false);\n      }\n    }\n\n    return new Reference(this.repo, this.path.child(pathString));\n  }\n\n  /** @return {?Reference} */\n  getParent(): Reference | null {\n    validateArgCount('Reference.parent', 0, 0, arguments.length);\n\n    const parentPath = this.path.parent();\n    return parentPath === null ? null : new Reference(this.repo, parentPath);\n  }\n\n  /** @return {!Reference} */\n  getRoot(): Reference {\n    validateArgCount('Reference.root', 0, 0, arguments.length);\n\n    let ref: Reference = this;\n    while (ref.getParent() !== null) {\n      ref = ref.getParent();\n    }\n    return ref;\n  }\n\n  /** @return {!Database} */\n  databaseProp(): Database {\n    return this.repo.database;\n  }\n\n  /**\n   * @param {*} newVal\n   * @param {function(?Error)=} onComplete\n   * @return {!Promise}\n   */\n  set(\n    newVal: unknown,\n    onComplete?: (a: Error | null) => void\n  ): Promise<unknown> {\n    validateArgCount('Reference.set', 1, 2, arguments.length);\n    validateWritablePath('Reference.set', this.path);\n    validateFirebaseDataArg('Reference.set', 1, newVal, this.path, false);\n    validateCallback('Reference.set', 2, onComplete, true);\n\n    const deferred = new Deferred();\n    this.repo.setWithPriority(\n      this.path,\n      newVal,\n      /*priority=*/ null,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {!Object} objectToMerge\n   * @param {function(?Error)=} onComplete\n   * @return {!Promise}\n   */\n  update(\n    objectToMerge: object,\n    onComplete?: (a: Error | null) => void\n  ): Promise<unknown> {\n    validateArgCount('Reference.update', 1, 2, arguments.length);\n    validateWritablePath('Reference.update', this.path);\n\n    if (Array.isArray(objectToMerge)) {\n      const newObjectToMerge: { [k: string]: unknown } = {};\n      for (let i = 0; i < objectToMerge.length; ++i) {\n        newObjectToMerge['' + i] = objectToMerge[i];\n      }\n      objectToMerge = newObjectToMerge;\n      warn(\n        'Passing an Array to Firebase.update() is deprecated. ' +\n          'Use set() if you want to overwrite the existing data, or ' +\n          'an Object with integer keys if you really do want to ' +\n          'only update some of the children.'\n      );\n    }\n    validateFirebaseMergeDataArg(\n      'Reference.update',\n      1,\n      objectToMerge,\n      this.path,\n      false\n    );\n    validateCallback('Reference.update', 2, onComplete, true);\n    const deferred = new Deferred();\n    this.repo.update(\n      this.path,\n      objectToMerge as { [k: string]: unknown },\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {*} newVal\n   * @param {string|number|null} newPriority\n   * @param {function(?Error)=} onComplete\n   * @return {!Promise}\n   */\n  setWithPriority(\n    newVal: unknown,\n    newPriority: string | number | null,\n    onComplete?: (a: Error | null) => void\n  ): Promise<unknown> {\n    validateArgCount('Reference.setWithPriority', 2, 3, arguments.length);\n    validateWritablePath('Reference.setWithPriority', this.path);\n    validateFirebaseDataArg(\n      'Reference.setWithPriority',\n      1,\n      newVal,\n      this.path,\n      false\n    );\n    validatePriority('Reference.setWithPriority', 2, newPriority, false);\n    validateCallback('Reference.setWithPriority', 3, onComplete, true);\n\n    if (this.getKey() === '.length' || this.getKey() === '.keys') {\n      throw (\n        'Reference.setWithPriority failed: ' +\n        this.getKey() +\n        ' is a read-only object.'\n      );\n    }\n\n    const deferred = new Deferred();\n    this.repo.setWithPriority(\n      this.path,\n      newVal,\n      newPriority,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {function(?Error)=} onComplete\n   * @return {!Promise}\n   */\n  remove(onComplete?: (a: Error | null) => void): Promise<unknown> {\n    validateArgCount('Reference.remove', 0, 1, arguments.length);\n    validateWritablePath('Reference.remove', this.path);\n    validateCallback('Reference.remove', 1, onComplete, true);\n\n    return this.set(null, onComplete);\n  }\n\n  /**\n   * @param {function(*):*} transactionUpdate\n   * @param {(function(?Error, boolean, ?DataSnapshot))=} onComplete\n   * @param {boolean=} applyLocally\n   * @return {!Promise}\n   */\n  transaction(\n    transactionUpdate: (a: unknown) => unknown,\n    onComplete?: (a: Error | null, b: boolean, c: DataSnapshot | null) => void,\n    applyLocally?: boolean\n  ): Promise<TransactionResult> {\n    validateArgCount('Reference.transaction', 1, 3, arguments.length);\n    validateWritablePath('Reference.transaction', this.path);\n    validateCallback('Reference.transaction', 1, transactionUpdate, false);\n    validateCallback('Reference.transaction', 2, onComplete, true);\n    // NOTE: applyLocally is an internal-only option for now.  We need to decide if we want to keep it and how\n    // to expose it.\n    validateBoolean('Reference.transaction', 3, applyLocally, true);\n\n    if (this.getKey() === '.length' || this.getKey() === '.keys') {\n      throw (\n        'Reference.transaction failed: ' +\n        this.getKey() +\n        ' is a read-only object.'\n      );\n    }\n\n    if (applyLocally === undefined) {\n      applyLocally = true;\n    }\n\n    const deferred = new Deferred<TransactionResult>();\n    if (typeof onComplete === 'function') {\n      deferred.promise.catch(() => {});\n    }\n\n    const promiseComplete = function (\n      error: Error,\n      committed: boolean,\n      snapshot: DataSnapshot\n    ) {\n      if (error) {\n        deferred.reject(error);\n      } else {\n        deferred.resolve(new TransactionResult(committed, snapshot));\n      }\n      if (typeof onComplete === 'function') {\n        onComplete(error, committed, snapshot);\n      }\n    };\n    this.repo.startTransaction(\n      this.path,\n      transactionUpdate,\n      promiseComplete,\n      applyLocally\n    );\n\n    return deferred.promise;\n  }\n\n  /**\n   * @param {string|number|null} priority\n   * @param {function(?Error)=} onComplete\n   * @return {!Promise}\n   */\n  setPriority(\n    priority: string | number | null,\n    onComplete?: (a: Error | null) => void\n  ): Promise<unknown> {\n    validateArgCount('Reference.setPriority', 1, 2, arguments.length);\n    validateWritablePath('Reference.setPriority', this.path);\n    validatePriority('Reference.setPriority', 1, priority, false);\n    validateCallback('Reference.setPriority', 2, onComplete, true);\n\n    const deferred = new Deferred();\n    this.repo.setWithPriority(\n      this.path.child('.priority'),\n      priority,\n      null,\n      deferred.wrapCallback(onComplete)\n    );\n    return deferred.promise;\n  }\n\n  /**\n   * @param {*=} value\n   * @param {function(?Error)=} onComplete\n   * @return {!Reference}\n   */\n  push(value?: unknown, onComplete?: (a: Error | null) => void): Reference {\n    validateArgCount('Reference.push', 0, 2, arguments.length);\n    validateWritablePath('Reference.push', this.path);\n    validateFirebaseDataArg('Reference.push', 1, value, this.path, true);\n    validateCallback('Reference.push', 2, onComplete, true);\n\n    const now = this.repo.serverTime();\n    const name = nextPushId(now);\n\n    // push() returns a ThennableReference whose promise is fulfilled with a regular Reference.\n    // We use child() to create handles to two different references. The first is turned into a\n    // ThennableReference below by adding then() and catch() methods and is used as the\n    // return value of push(). The second remains a regular Reference and is used as the fulfilled\n    // value of the first ThennableReference.\n    const thennablePushRef = this.child(name);\n    const pushRef = this.child(name);\n\n    let promise;\n    if (value != null) {\n      promise = thennablePushRef.set(value, onComplete).then(() => pushRef);\n    } else {\n      promise = Promise.resolve(pushRef);\n    }\n\n    thennablePushRef.then = promise.then.bind(promise);\n    thennablePushRef.catch = promise.then.bind(promise, undefined);\n\n    if (typeof onComplete === 'function') {\n      promise.catch(() => {});\n    }\n\n    return thennablePushRef;\n  }\n\n  /**\n   * @return {!OnDisconnect}\n   */\n  onDisconnect(): OnDisconnect {\n    validateWritablePath('Reference.onDisconnect', this.path);\n    return new OnDisconnect(this.repo, this.path);\n  }\n\n  get database(): Database {\n    return this.databaseProp();\n  }\n\n  get key(): string | null {\n    return this.getKey();\n  }\n\n  get parent(): Reference | null {\n    return this.getParent();\n  }\n\n  get root(): Reference {\n    return this.getRoot();\n  }\n}\n\n/**\n * Define reference constructor in various modules\n *\n * We are doing this here to avoid several circular\n * dependency issues\n */\nQuery.__referenceConstructor = Reference;\nSyncPoint.__referenceConstructor = Reference;\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, contains, safeGet } from '@firebase/util';\nimport { Path } from './Path';\n\nimport { each } from './util';\n\n/**\n * Node in a Tree.\n */\nexport class TreeNode<T> {\n  // TODO: Consider making accessors that create children and value lazily or\n  // separate Internal / Leaf 'types'.\n  children: { [name: string]: TreeNode<T> } = {};\n  childCount = 0;\n  value: T | null = null;\n}\n\n/**\n * A light-weight tree, traversable by path.  Nodes can have both values and children.\n * Nodes are not enumerated (by forEachChild) unless they have a value or non-empty\n * children.\n */\nexport class Tree<T> {\n  /**\n   * @template T\n   * @param {string=} name_ Optional name of the node.\n   * @param {Tree=} parent_ Optional parent node.\n   * @param {TreeNode=} node_ Optional node to wrap.\n   */\n  constructor(\n    private name_: string = '',\n    private parent_: Tree<T> | null = null,\n    private node_: TreeNode<T> = new TreeNode<T>()\n  ) {}\n\n  /**\n   * Returns a sub-Tree for the given path.\n   *\n   * @param {!(string|Path)} pathObj Path to look up.\n   * @return {!Tree.<T>} Tree for path.\n   */\n  subTree(pathObj: string | Path): Tree<T> {\n    // TODO: Require pathObj to be Path?\n    let path = pathObj instanceof Path ? pathObj : new Path(pathObj);\n    let child = this as Tree<T>,\n      next = path.getFront();\n    while (next !== null) {\n      const childNode = safeGet(child.node_.children, next) || new TreeNode();\n      child = new Tree(next, child, childNode);\n      path = path.popFront();\n      next = path.getFront();\n    }\n\n    return child;\n  }\n\n  /**\n   * Returns the data associated with this tree node.\n   *\n   * @return {?T} The data or null if no data exists.\n   */\n  getValue(): T | null {\n    return this.node_.value;\n  }\n\n  /**\n   * Sets data to this tree node.\n   *\n   * @param {!T} value Value to set.\n   */\n  setValue(value: T) {\n    assert(typeof value !== 'undefined', 'Cannot set value to undefined');\n    this.node_.value = value;\n    this.updateParents_();\n  }\n\n  /**\n   * Clears the contents of the tree node (its value and all children).\n   */\n  clear() {\n    this.node_.value = null;\n    this.node_.children = {};\n    this.node_.childCount = 0;\n    this.updateParents_();\n  }\n\n  /**\n   * @return {boolean} Whether the tree has any children.\n   */\n  hasChildren(): boolean {\n    return this.node_.childCount > 0;\n  }\n\n  /**\n   * @return {boolean} Whether the tree is empty (no value or children).\n   */\n  isEmpty(): boolean {\n    return this.getValue() === null && !this.hasChildren();\n  }\n\n  /**\n   * Calls action for each child of this tree node.\n   *\n   * @param {function(!Tree.<T>)} action Action to be called for each child.\n   */\n  forEachChild(action: (tree: Tree<T>) => void) {\n    each(this.node_.children, (child: string, childTree: TreeNode<T>) => {\n      action(new Tree<T>(child, this, childTree));\n    });\n  }\n\n  /**\n   * Does a depth-first traversal of this node's descendants, calling action for each one.\n   *\n   * @param {function(!Tree.<T>)} action Action to be called for each child.\n   * @param {boolean=} includeSelf Whether to call action on this node as well. Defaults to\n   *   false.\n   * @param {boolean=} childrenFirst Whether to call action on children before calling it on\n   *   parent.\n   */\n  forEachDescendant(\n    action: (tree: Tree<T>) => void,\n    includeSelf?: boolean,\n    childrenFirst?: boolean\n  ) {\n    if (includeSelf && !childrenFirst) {\n      action(this);\n    }\n\n    this.forEachChild(child => {\n      child.forEachDescendant(action, /*includeSelf=*/ true, childrenFirst);\n    });\n\n    if (includeSelf && childrenFirst) {\n      action(this);\n    }\n  }\n\n  /**\n   * Calls action on each ancestor node.\n   *\n   * @param {function(!Tree.<T>)} action Action to be called on each parent; return\n   *   true to abort.\n   * @param {boolean=} includeSelf Whether to call action on this node as well.\n   * @return {boolean} true if the action callback returned true.\n   */\n  forEachAncestor(\n    action: (tree: Tree<T>) => unknown,\n    includeSelf?: boolean\n  ): boolean {\n    let node = includeSelf ? this : this.parent();\n    while (node !== null) {\n      if (action(node)) {\n        return true;\n      }\n      node = node.parent();\n    }\n    return false;\n  }\n\n  /**\n   * Does a depth-first traversal of this node's descendants.  When a descendant with a value\n   * is found, action is called on it and traversal does not continue inside the node.\n   * Action is *not* called on this node.\n   *\n   * @param {function(!Tree.<T>)} action Action to be called for each child.\n   */\n  forEachImmediateDescendantWithValue(action: (tree: Tree<T>) => void) {\n    this.forEachChild(child => {\n      if (child.getValue() !== null) {\n        action(child);\n      } else {\n        child.forEachImmediateDescendantWithValue(action);\n      }\n    });\n  }\n\n  /**\n   * @return {!Path} The path of this tree node, as a Path.\n   */\n  path(): Path {\n    return new Path(\n      this.parent_ === null\n        ? this.name_\n        : this.parent_.path() + '/' + this.name_\n    );\n  }\n\n  /**\n   * @return {string} The name of the tree node.\n   */\n  name(): string {\n    return this.name_;\n  }\n\n  /**\n   * @return {?Tree} The parent tree node, or null if this is the root of the tree.\n   */\n  parent(): Tree<T> | null {\n    return this.parent_;\n  }\n\n  /**\n   * Adds or removes this child from its parent based on whether it's empty or not.\n   *\n   * @private\n   */\n  private updateParents_() {\n    if (this.parent_ !== null) {\n      this.parent_.updateChild_(this.name_, this);\n    }\n  }\n\n  /**\n   * Adds or removes the passed child to this tree node, depending on whether it's empty.\n   *\n   * @param {string} childName The name of the child to update.\n   * @param {!Tree.<T>} child The child to update.\n   * @private\n   */\n  private updateChild_(childName: string, child: Tree<T>) {\n    const childEmpty = child.isEmpty();\n    const childExists = contains(this.node_.children, childName);\n    if (childEmpty && childExists) {\n      delete this.node_.children[childName];\n      this.node_.childCount--;\n      this.updateParents_();\n    } else if (!childEmpty && !childExists) {\n      this.node_.children[childName] = child.node_;\n      this.node_.childCount++;\n      this.updateParents_();\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, contains, safeGet } from '@firebase/util';\nimport { Reference } from '../api/Reference';\nimport { DataSnapshot } from '../api/DataSnapshot';\nimport { Path } from './util/Path';\nimport { Tree } from './util/Tree';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { Node } from './snap/Node';\nimport { LUIDGenerator, warn, exceptionGuard } from './util/util';\nimport { resolveDeferredValueSnapshot } from './util/ServerValues';\nimport { isValidPriority, validateFirebaseData } from './util/validation';\n\nimport { nodeFromJSON } from './snap/nodeFromJSON';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { Repo } from './Repo';\nimport { Event } from './view/Event';\n\n// TODO: This is pretty messy.  Ideally, a lot of this would move into FirebaseData, or a transaction-specific\n// component used by FirebaseData, but it has ties to user callbacks (transaction update and onComplete) as well\n// as the realtime connection (to send transactions to the server).  So that all needs to be decoupled first.\n// For now it's part of Repo, but in its own file.\n\n/**\n * @enum {number}\n */\nexport enum TransactionStatus {\n  // We've run the transaction and updated transactionResultData_ with the result, but it isn't currently sent to the\n  // server. A transaction will go from RUN -> SENT -> RUN if it comes back from the server as rejected due to\n  // mismatched hash.\n  RUN,\n\n  // We've run the transaction and sent it to the server and it's currently outstanding (hasn't come back as accepted\n  // or rejected yet).\n  SENT,\n\n  // Temporary state used to mark completed transactions (whether successful or aborted).  The transaction will be\n  // removed when we get a chance to prune completed ones.\n  COMPLETED,\n\n  // Used when an already-sent transaction needs to be aborted (e.g. due to a conflicting set() call that was made).\n  // If it comes back as unsuccessful, we'll abort it.\n  SENT_NEEDS_ABORT,\n\n  // Temporary state used to mark transactions that need to be aborted.\n  NEEDS_ABORT\n}\n\n/**\n * If a transaction does not succeed after 25 retries, we abort it.  Among other things this ensure that if there's\n * ever a bug causing a mismatch between client / server hashes for some data, we won't retry indefinitely.\n * @type {number}\n * @const\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo as any).MAX_TRANSACTION_RETRIES_ = 25;\n\n/**\n * @typedef {{\n *   path: !Path,\n *   update: function(*):*,\n *   onComplete: ?function(?Error, boolean, ?DataSnapshot),\n *   status: ?TransactionStatus,\n *   order: !number,\n *   applyLocally: boolean,\n *   retryCount: !number,\n *   unwatcher: function(),\n *   abortReason: ?string,\n *   currentWriteId: !number,\n *   currentInputSnapshot: ?Node,\n *   currentOutputSnapshotRaw: ?Node,\n *   currentOutputSnapshotResolved: ?Node\n * }}\n */\ninterface Transaction {\n  path: Path;\n  update: (a: unknown) => unknown;\n  onComplete: (a: Error | null, b: boolean, c: DataSnapshot | null) => void;\n  status: TransactionStatus;\n  order: number;\n  applyLocally: boolean;\n  retryCount: number;\n  unwatcher: () => void;\n  abortReason: string | null;\n  currentWriteId: number;\n  currentInputSnapshot: Node | null;\n  currentOutputSnapshotRaw: Node | null;\n  currentOutputSnapshotResolved: Node | null;\n}\n\n/**\n * Setup the transaction data structures\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).transactionsInit_ = function () {\n  /**\n   * Stores queues of outstanding transactions for Firebase locations.\n   *\n   * @type {!Tree.<Array.<!Transaction>>}\n   * @private\n   */\n  this.transactionQueueTree_ = new Tree<Transaction[]>();\n};\n\ndeclare module './Repo' {\n  interface Repo {\n    startTransaction(\n      path: Path,\n      transactionUpdate: (a: unknown) => void,\n      onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n      applyLocally: boolean\n    ): void;\n  }\n}\n\n/**\n * Creates a new transaction, adds it to the transactions we're tracking, and sends it to the server if possible.\n *\n * @param {!Path} path Path at which to do transaction.\n * @param {function(*):*} transactionUpdate Update callback.\n * @param {?function(?Error, boolean, ?DataSnapshot)} onComplete Completion callback.\n * @param {boolean} applyLocally Whether or not to make intermediate results visible\n */\nRepo.prototype.startTransaction = function (\n  path: Path,\n  transactionUpdate: (a: unknown) => unknown,\n  onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n  applyLocally: boolean\n) {\n  this.log_('transaction on ' + path);\n\n  // Add a watch to make sure we get server updates.\n  const valueCallback = function () {};\n  const watchRef = new Reference(this, path);\n  watchRef.on('value', valueCallback);\n  const unwatcher = function () {\n    watchRef.off('value', valueCallback);\n  };\n\n  // Initialize transaction.\n  const transaction: Transaction = {\n    path,\n    update: transactionUpdate,\n    onComplete,\n\n    // One of TransactionStatus enums.\n    status: null,\n\n    // Used when combining transactions at different locations to figure out which one goes first.\n    order: LUIDGenerator(),\n\n    // Whether to raise local events for this transaction.\n    applyLocally,\n\n    // Count of how many times we've retried the transaction.\n    retryCount: 0,\n\n    // Function to call to clean up our .on() listener.\n    unwatcher,\n\n    // Stores why a transaction was aborted.\n    abortReason: null,\n\n    currentWriteId: null,\n\n    currentInputSnapshot: null,\n\n    currentOutputSnapshotRaw: null,\n\n    currentOutputSnapshotResolved: null\n  };\n\n  // Run transaction initially.\n  const currentState = this.getLatestState_(path);\n  transaction.currentInputSnapshot = currentState;\n  const newVal = transaction.update(currentState.val());\n  if (newVal === undefined) {\n    // Abort transaction.\n    transaction.unwatcher();\n    transaction.currentOutputSnapshotRaw = null;\n    transaction.currentOutputSnapshotResolved = null;\n    if (transaction.onComplete) {\n      // We just set the input snapshot, so this cast should be safe\n      const snapshot = new DataSnapshot(\n        transaction.currentInputSnapshot,\n        new Reference(this, transaction.path),\n        PRIORITY_INDEX\n      );\n      transaction.onComplete(null, false, snapshot);\n    }\n  } else {\n    validateFirebaseData(\n      'transaction failed: Data returned ',\n      newVal,\n      transaction.path\n    );\n\n    // Mark as run and add to our queue.\n    transaction.status = TransactionStatus.RUN;\n    const queueNode = this.transactionQueueTree_.subTree(path);\n    const nodeQueue = queueNode.getValue() || [];\n    nodeQueue.push(transaction);\n\n    queueNode.setValue(nodeQueue);\n\n    // Update visibleData and raise events\n    // Note: We intentionally raise events after updating all of our transaction state, since the user could\n    // start new transactions from the event callbacks.\n    let priorityForNode;\n    if (\n      typeof newVal === 'object' &&\n      newVal !== null &&\n      contains(newVal, '.priority')\n    ) {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      priorityForNode = safeGet(newVal as any, '.priority');\n      assert(\n        isValidPriority(priorityForNode),\n        'Invalid priority returned by transaction. ' +\n          'Priority must be a valid string, finite number, server value, or null.'\n      );\n    } else {\n      const currentNode =\n        this.serverSyncTree_.calcCompleteEventCache(path) ||\n        ChildrenNode.EMPTY_NODE;\n      priorityForNode = currentNode.getPriority().val();\n    }\n    priorityForNode /** @type {null|number|string} */ = priorityForNode;\n\n    const serverValues = this.generateServerValues();\n    const newNodeUnresolved = nodeFromJSON(newVal, priorityForNode);\n    const newNode = resolveDeferredValueSnapshot(\n      newNodeUnresolved,\n      currentState,\n      serverValues\n    );\n    transaction.currentOutputSnapshotRaw = newNodeUnresolved;\n    transaction.currentOutputSnapshotResolved = newNode;\n    transaction.currentWriteId = this.getNextWriteId_();\n\n    const events = this.serverSyncTree_.applyUserOverwrite(\n      path,\n      newNode,\n      transaction.currentWriteId,\n      transaction.applyLocally\n    );\n    this.eventQueue_.raiseEventsForChangedPath(path, events);\n\n    this.sendReadyTransactions_();\n  }\n};\n\n/**\n * @param {!Path} path\n * @param {Array.<number>=} excludeSets A specific set to exclude\n * @return {Node}\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).getLatestState_ = function (\n  path: Path,\n  excludeSets?: number[]\n): Node {\n  return (\n    this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) ||\n    ChildrenNode.EMPTY_NODE\n  );\n};\n\n/**\n * Sends any already-run transactions that aren't waiting for outstanding transactions to\n * complete.\n *\n * Externally it's called with no arguments, but it calls itself recursively with a particular\n * transactionQueueTree node to recurse through the tree.\n *\n * @param {Tree.<Array.<Transaction>>=} node  transactionQueueTree node to start at.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).sendReadyTransactions_ = function (\n  node: Tree<Transaction[]> = this.transactionQueueTree_\n) {\n  // Before recursing, make sure any completed transactions are removed.\n  if (!node) {\n    this.pruneCompletedTransactionsBelowNode_(node);\n  }\n\n  if (node.getValue() !== null) {\n    const queue = this.buildTransactionQueue_(node);\n    assert(queue.length > 0, 'Sending zero length transaction queue');\n\n    const allRun = queue.every(\n      (transaction: Transaction) => transaction.status === TransactionStatus.RUN\n    );\n\n    // If they're all run (and not sent), we can send them.  Else, we must wait.\n    if (allRun) {\n      this.sendTransactionQueue_(node.path(), queue);\n    }\n  } else if (node.hasChildren()) {\n    node.forEachChild(childNode => {\n      this.sendReadyTransactions_(childNode);\n    });\n  }\n};\n\n/**\n * Given a list of run transactions, send them to the server and then handle the result (success or failure).\n *\n * @param {!Path} path The location of the queue.\n * @param {!Array.<Transaction>} queue Queue of transactions under the specified location.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).sendTransactionQueue_ = function (\n  path: Path,\n  queue: Transaction[]\n) {\n  // Mark transactions as sent and increment retry count!\n  const setsToIgnore = queue.map(txn => {\n    return txn.currentWriteId;\n  });\n  const latestState = this.getLatestState_(path, setsToIgnore);\n  let snapToSend = latestState;\n  const latestHash = latestState.hash();\n  for (let i = 0; i < queue.length; i++) {\n    const txn = queue[i];\n    assert(\n      txn.status === TransactionStatus.RUN,\n      'tryToSendTransactionQueue_: items in queue should all be run.'\n    );\n    txn.status = TransactionStatus.SENT;\n    txn.retryCount++;\n    const relativePath = Path.relativePath(path, txn.path);\n    // If we've gotten to this point, the output snapshot must be defined.\n    snapToSend = snapToSend.updateChild(\n      relativePath /** @type {!Node} */,\n      txn.currentOutputSnapshotRaw\n    );\n  }\n\n  const dataToSend = snapToSend.val(true);\n  const pathToSend = path;\n\n  // Send the put.\n  this.server_.put(\n    pathToSend.toString(),\n    dataToSend,\n    (status: string) => {\n      this.log_('transaction put response', {\n        path: pathToSend.toString(),\n        status\n      });\n\n      let events: Event[] = [];\n      if (status === 'ok') {\n        // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n        // the callback could trigger more transactions or sets.\n        const callbacks = [];\n        for (let i = 0; i < queue.length; i++) {\n          queue[i].status = TransactionStatus.COMPLETED;\n          events = events.concat(\n            this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId)\n          );\n          if (queue[i].onComplete) {\n            // We never unset the output snapshot, and given that this transaction is complete, it should be set\n            const node = queue[i].currentOutputSnapshotResolved as Node;\n            const ref = new Reference(this, queue[i].path);\n            const snapshot = new DataSnapshot(node, ref, PRIORITY_INDEX);\n            callbacks.push(\n              queue[i].onComplete.bind(null, null, true, snapshot)\n            );\n          }\n          queue[i].unwatcher();\n        }\n\n        // Now remove the completed transactions.\n        this.pruneCompletedTransactionsBelowNode_(\n          this.transactionQueueTree_.subTree(path)\n        );\n        // There may be pending transactions that we can now send.\n        this.sendReadyTransactions_();\n\n        this.eventQueue_.raiseEventsForChangedPath(path, events);\n\n        // Finally, trigger onComplete callbacks.\n        for (let i = 0; i < callbacks.length; i++) {\n          exceptionGuard(callbacks[i]);\n        }\n      } else {\n        // transactions are no longer sent.  Update their status appropriately.\n        if (status === 'datastale') {\n          for (let i = 0; i < queue.length; i++) {\n            if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) {\n              queue[i].status = TransactionStatus.NEEDS_ABORT;\n            } else {\n              queue[i].status = TransactionStatus.RUN;\n            }\n          }\n        } else {\n          warn(\n            'transaction at ' + pathToSend.toString() + ' failed: ' + status\n          );\n          for (let i = 0; i < queue.length; i++) {\n            queue[i].status = TransactionStatus.NEEDS_ABORT;\n            queue[i].abortReason = status;\n          }\n        }\n\n        this.rerunTransactions_(path);\n      }\n    },\n    latestHash\n  );\n};\n\n/**\n * Finds all transactions dependent on the data at changedPath and reruns them.\n *\n * Should be called any time cached data changes.\n *\n * Return the highest path that was affected by rerunning transactions.  This is the path at which events need to\n * be raised for.\n *\n * @param {!Path} changedPath The path in mergedData that changed.\n * @return {!Path} The rootmost path that was affected by rerunning transactions.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).rerunTransactions_ = function (\n  changedPath: Path\n): Path {\n  const rootMostTransactionNode = this.getAncestorTransactionNode_(changedPath);\n  const path = rootMostTransactionNode.path();\n\n  const queue = this.buildTransactionQueue_(rootMostTransactionNode);\n  this.rerunTransactionQueue_(queue, path);\n\n  return path;\n};\n\n/**\n * Does all the work of rerunning transactions (as well as cleans up aborted transactions and whatnot).\n *\n * @param {Array.<Transaction>} queue The queue of transactions to run.\n * @param {!Path} path The path the queue is for.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).rerunTransactionQueue_ = function (\n  queue: Transaction[],\n  path: Path\n) {\n  if (queue.length === 0) {\n    return; // Nothing to do!\n  }\n\n  // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n  // the callback could trigger more transactions or sets.\n  const callbacks = [];\n  let events: Event[] = [];\n  // Ignore all of the sets we're going to re-run.\n  const txnsToRerun = queue.filter(q => {\n    return q.status === TransactionStatus.RUN;\n  });\n  const setsToIgnore = txnsToRerun.map(q => {\n    return q.currentWriteId;\n  });\n  for (let i = 0; i < queue.length; i++) {\n    const transaction = queue[i];\n    const relativePath = Path.relativePath(path, transaction.path);\n    let abortTransaction = false,\n      abortReason;\n    assert(\n      relativePath !== null,\n      'rerunTransactionsUnderNode_: relativePath should not be null.'\n    );\n\n    if (transaction.status === TransactionStatus.NEEDS_ABORT) {\n      abortTransaction = true;\n      abortReason = transaction.abortReason;\n      events = events.concat(\n        this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n      );\n    } else if (transaction.status === TransactionStatus.RUN) {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      if (transaction.retryCount >= (Repo as any).MAX_TRANSACTION_RETRIES_) {\n        abortTransaction = true;\n        abortReason = 'maxretry';\n        events = events.concat(\n          this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n        );\n      } else {\n        // This code reruns a transaction\n        const currentNode = this.getLatestState_(\n          transaction.path,\n          setsToIgnore\n        );\n        transaction.currentInputSnapshot = currentNode;\n        const newData = queue[i].update(currentNode.val());\n        if (newData !== undefined) {\n          validateFirebaseData(\n            'transaction failed: Data returned ',\n            newData,\n            transaction.path\n          );\n          let newDataNode = nodeFromJSON(newData);\n          const hasExplicitPriority =\n            typeof newData === 'object' &&\n            newData != null &&\n            contains(newData, '.priority');\n          if (!hasExplicitPriority) {\n            // Keep the old priority if there wasn't a priority explicitly specified.\n            newDataNode = newDataNode.updatePriority(currentNode.getPriority());\n          }\n\n          const oldWriteId = transaction.currentWriteId;\n          const serverValues = this.generateServerValues();\n          const newNodeResolved = resolveDeferredValueSnapshot(\n            newDataNode,\n            currentNode,\n            serverValues\n          );\n\n          transaction.currentOutputSnapshotRaw = newDataNode;\n          transaction.currentOutputSnapshotResolved = newNodeResolved;\n          transaction.currentWriteId = this.getNextWriteId_();\n          // Mutates setsToIgnore in place\n          setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1);\n          events = events.concat(\n            this.serverSyncTree_.applyUserOverwrite(\n              transaction.path,\n              newNodeResolved,\n              transaction.currentWriteId,\n              transaction.applyLocally\n            )\n          );\n          events = events.concat(\n            this.serverSyncTree_.ackUserWrite(oldWriteId, true)\n          );\n        } else {\n          abortTransaction = true;\n          abortReason = 'nodata';\n          events = events.concat(\n            this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n          );\n        }\n      }\n    }\n    this.eventQueue_.raiseEventsForChangedPath(path, events);\n    events = [];\n    if (abortTransaction) {\n      // Abort.\n      queue[i].status = TransactionStatus.COMPLETED;\n\n      // Removing a listener can trigger pruning which can muck with mergedData/visibleData (as it prunes data).\n      // So defer the unwatcher until we're done.\n      (function (unwatcher) {\n        setTimeout(unwatcher, Math.floor(0));\n      })(queue[i].unwatcher);\n\n      if (queue[i].onComplete) {\n        if (abortReason === 'nodata') {\n          const ref = new Reference(this, queue[i].path);\n          // We set this field immediately, so it's safe to cast to an actual snapshot\n          const lastInput /** @type {!Node} */ = queue[i].currentInputSnapshot;\n          const snapshot = new DataSnapshot(lastInput, ref, PRIORITY_INDEX);\n          callbacks.push(queue[i].onComplete.bind(null, null, false, snapshot));\n        } else {\n          callbacks.push(\n            queue[i].onComplete.bind(null, new Error(abortReason), false, null)\n          );\n        }\n      }\n    }\n  }\n\n  // Clean up completed transactions.\n  this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_);\n\n  // Now fire callbacks, now that we're in a good, known state.\n  for (let i = 0; i < callbacks.length; i++) {\n    exceptionGuard(callbacks[i]);\n  }\n\n  // Try to send the transaction result to the server.\n  this.sendReadyTransactions_();\n};\n\n/**\n * Returns the rootmost ancestor node of the specified path that has a pending transaction on it, or just returns\n * the node for the given path if there are no pending transactions on any ancestor.\n *\n * @param {!Path} path The location to start at.\n * @return {!Tree.<Array.<!Transaction>>} The rootmost node with a transaction.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).getAncestorTransactionNode_ = function (\n  path: Path\n): Tree<Transaction[]> {\n  let front;\n\n  // Start at the root and walk deeper into the tree towards path until we find a node with pending transactions.\n  let transactionNode = this.transactionQueueTree_;\n  front = path.getFront();\n  while (front !== null && transactionNode.getValue() === null) {\n    transactionNode = transactionNode.subTree(front);\n    path = path.popFront();\n    front = path.getFront();\n  }\n\n  return transactionNode;\n};\n\n/**\n * Builds the queue of all transactions at or below the specified transactionNode.\n *\n * @param {!Tree.<Array.<Transaction>>} transactionNode\n * @return {Array.<Transaction>} The generated queue.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).buildTransactionQueue_ = function (\n  transactionNode: Tree<Transaction[]>\n): Transaction[] {\n  // Walk any child transaction queues and aggregate them into a single queue.\n  const transactionQueue: Transaction[] = [];\n  this.aggregateTransactionQueuesForNode_(transactionNode, transactionQueue);\n\n  // Sort them by the order the transactions were created.\n  transactionQueue.sort((a, b) => {\n    return a.order - b.order;\n  });\n\n  return transactionQueue;\n};\n\n/**\n * @param {!Tree.<Array.<Transaction>>} node\n * @param {Array.<Transaction>} queue\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).aggregateTransactionQueuesForNode_ = function (\n  node: Tree<Transaction[]>,\n  queue: Transaction[]\n) {\n  const nodeQueue = node.getValue();\n  if (nodeQueue !== null) {\n    for (let i = 0; i < nodeQueue.length; i++) {\n      queue.push(nodeQueue[i]);\n    }\n  }\n\n  node.forEachChild(child => {\n    this.aggregateTransactionQueuesForNode_(child, queue);\n  });\n};\n\n/**\n * Remove COMPLETED transactions at or below this node in the transactionQueueTree_.\n *\n * @param {!Tree.<Array.<!Transaction>>} node\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).pruneCompletedTransactionsBelowNode_ = function (\n  node: Tree<Transaction[]>\n) {\n  const queue = node.getValue();\n  if (queue) {\n    let to = 0;\n    for (let from = 0; from < queue.length; from++) {\n      if (queue[from].status !== TransactionStatus.COMPLETED) {\n        queue[to] = queue[from];\n        to++;\n      }\n    }\n    queue.length = to;\n    node.setValue(queue.length > 0 ? queue : null);\n  }\n\n  node.forEachChild(childNode => {\n    this.pruneCompletedTransactionsBelowNode_(childNode);\n  });\n};\n\n/**\n * Aborts all transactions on ancestors or descendants of the specified path.  Called when doing a set() or update()\n * since we consider them incompatible with transactions.\n *\n * @param {!Path} path Path for which we want to abort related transactions.\n * @return {!Path}\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).abortTransactions_ = function (path: Path): Path {\n  const affectedPath = this.getAncestorTransactionNode_(path).path();\n\n  const transactionNode = this.transactionQueueTree_.subTree(path);\n\n  transactionNode.forEachAncestor((node: Tree<Transaction[]>) => {\n    this.abortTransactionsOnNode_(node);\n  });\n\n  this.abortTransactionsOnNode_(transactionNode);\n\n  transactionNode.forEachDescendant((node: Tree<Transaction[]>) => {\n    this.abortTransactionsOnNode_(node);\n  });\n\n  return affectedPath;\n};\n\n/**\n * Abort transactions stored in this transaction queue node.\n *\n * @param {!Tree.<Array.<Transaction>>} node Node to abort transactions for.\n * @private\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Repo.prototype as any).abortTransactionsOnNode_ = function (\n  node: Tree<Transaction[]>\n) {\n  const queue = node.getValue();\n  if (queue !== null) {\n    // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n    // the callback could trigger more transactions or sets.\n    const callbacks = [];\n\n    // Go through queue.  Any already-sent transactions must be marked for abort, while the unsent ones\n    // can be immediately aborted and removed.\n    let events: Event[] = [];\n    let lastSent = -1;\n    for (let i = 0; i < queue.length; i++) {\n      if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) {\n        // Already marked.  No action needed.\n      } else if (queue[i].status === TransactionStatus.SENT) {\n        assert(\n          lastSent === i - 1,\n          'All SENT items should be at beginning of queue.'\n        );\n        lastSent = i;\n        // Mark transaction for abort when it comes back.\n        queue[i].status = TransactionStatus.SENT_NEEDS_ABORT;\n        queue[i].abortReason = 'set';\n      } else {\n        assert(\n          queue[i].status === TransactionStatus.RUN,\n          'Unexpected transaction status in abort'\n        );\n        // We can abort it immediately.\n        queue[i].unwatcher();\n        events = events.concat(\n          this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true)\n        );\n        if (queue[i].onComplete) {\n          const snapshot: DataSnapshot | null = null;\n          callbacks.push(\n            queue[i].onComplete.bind(null, new Error('set'), false, snapshot)\n          );\n        }\n      }\n    }\n    if (lastSent === -1) {\n      // We're not waiting for any sent transactions.  We can clear the queue.\n      node.setValue(null);\n    } else {\n      // Remove the transactions we aborted.\n      queue.length = lastSent + 1;\n    }\n\n    // Now fire the callbacks.\n    this.eventQueue_.raiseEventsForChangedPath(node.path(), events);\n    for (let i = 0; i < callbacks.length; i++) {\n      exceptionGuard(callbacks[i]);\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 { FirebaseAuthTokenData } from '@firebase/app-types/private';\nimport {\n  FirebaseAuthInternal,\n  FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\nimport { log, warn } from './util/util';\nimport { FirebaseApp } from '@firebase/app-types';\n\nexport interface AuthTokenProvider {\n  getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;\n  addTokenChangeListener(listener: (token: string | null) => void): void;\n  removeTokenChangeListener(listener: (token: string | null) => void): void;\n  notifyForInvalidToken(): void;\n}\n\n/**\n * Abstraction around FirebaseApp's token fetching capabilities.\n */\nexport class FirebaseAuthTokenProvider implements AuthTokenProvider {\n  private auth_: FirebaseAuthInternal | null = null;\n  constructor(\n    private app_: FirebaseApp,\n    private authProvider_: Provider<FirebaseAuthInternalName>\n  ) {\n    this.auth_ = authProvider_.getImmediate({ optional: true });\n    if (!this.auth_) {\n      authProvider_.get().then(auth => (this.auth_ = auth));\n    }\n  }\n\n  /**\n   * @param {boolean} forceRefresh\n   * @return {!Promise<FirebaseAuthTokenData>}\n   */\n  getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData> {\n    if (!this.auth_) {\n      return Promise.resolve(null);\n    }\n\n    return this.auth_.getToken(forceRefresh).catch(error => {\n      // TODO: Need to figure out all the cases this is raised and whether\n      // this makes sense.\n      if (error && error.code === 'auth/token-not-initialized') {\n        log('Got auth/token-not-initialized error.  Treating as null token.');\n        return null;\n      } else {\n        return Promise.reject(error);\n      }\n    });\n  }\n\n  addTokenChangeListener(listener: (token: string | null) => void): void {\n    // TODO: We might want to wrap the listener and call it with no args to\n    // avoid a leaky abstraction, but that makes removing the listener harder.\n    if (this.auth_) {\n      this.auth_.addAuthTokenListener(listener);\n    } else {\n      setTimeout(() => listener(null), 0);\n      this.authProvider_\n        .get()\n        .then(auth => auth.addAuthTokenListener(listener));\n    }\n  }\n\n  removeTokenChangeListener(listener: (token: string | null) => void): void {\n    this.authProvider_\n      .get()\n      .then(auth => auth.removeAuthTokenListener(listener));\n  }\n\n  notifyForInvalidToken(): void {\n    let errorMessage =\n      'Provided authentication credentials for the app named \"' +\n      this.app_.name +\n      '\" are invalid. This usually indicates your app was not ' +\n      'initialized correctly. ';\n    if ('credential' in this.app_.options) {\n      errorMessage +=\n        'Make sure the \"credential\" property provided to initializeApp() ' +\n        'is authorized to access the specified \"databaseURL\" and is from the correct ' +\n        'project.';\n    } else if ('serviceAccount' in this.app_.options) {\n      errorMessage +=\n        'Make sure the \"serviceAccount\" property provided to initializeApp() ' +\n        'is authorized to access the specified \"databaseURL\" and is from the correct ' +\n        'project.';\n    } else {\n      errorMessage +=\n        'Make sure the \"apiKey\" and \"databaseURL\" properties provided to ' +\n        'initializeApp() match the values provided for your app at ' +\n        'https://console.firebase.google.com/.';\n    }\n    warn(errorMessage);\n  }\n}\n\n/* Auth token provider that the Admin SDK uses to connect to the Emulator. */\nexport class EmulatorAdminTokenProvider implements AuthTokenProvider {\n  private static EMULATOR_AUTH_TOKEN = 'owner';\n\n  getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData> {\n    return Promise.resolve({\n      accessToken: EmulatorAdminTokenProvider.EMULATOR_AUTH_TOKEN\n    });\n  }\n\n  addTokenChangeListener(listener: (token: string | null) => void): void {\n    // Invoke the listener immediately to match the behavior in Firebase Auth\n    // (see packages/auth/src/auth.js#L1807)\n    listener(EmulatorAdminTokenProvider.EMULATOR_AUTH_TOKEN);\n  }\n\n  removeTokenChangeListener(listener: (token: string | null) => void): void {}\n\n  notifyForInvalidToken(): void {}\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 { FirebaseApp } from '@firebase/app-types';\nimport { safeGet, CONSTANTS } from '@firebase/util';\nimport { Repo } from './Repo';\nimport { fatal } from './util/util';\nimport { parseRepoInfo } from './util/libs/parser';\nimport { validateUrl } from './util/validation';\nimport './Repo_transaction';\nimport { Database } from '../api/Database';\nimport { RepoInfo } from './RepoInfo';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\nimport {\n  AuthTokenProvider,\n  EmulatorAdminTokenProvider,\n  FirebaseAuthTokenProvider\n} from './AuthTokenProvider';\n\n/** @const {string} */\nconst DATABASE_URL_OPTION = 'databaseURL';\n\n/**\n * This variable is also defined in the firebase node.js admin SDK. Before\n * modifying this definition, consult the definition in:\n *\n * https://github.com/firebase/firebase-admin-node\n *\n * and make sure the two are consistent.\n */\nconst FIREBASE_DATABASE_EMULATOR_HOST_VAR = 'FIREBASE_DATABASE_EMULATOR_HOST';\n\nlet _staticInstance: RepoManager;\n\n/**\n * Creates and caches Repo instances.\n */\nexport class RepoManager {\n  /**\n   * @private {!Object.<string, Object<string, !fb.core.Repo>>}\n   */\n  private repos_: {\n    [appName: string]: {\n      [dbUrl: string]: Repo;\n    };\n  } = {};\n\n  /**\n   * If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).\n   * @private {boolean}\n   */\n  private useRestClient_: boolean = false;\n\n  static getInstance(): RepoManager {\n    if (!_staticInstance) {\n      _staticInstance = new RepoManager();\n    }\n    return _staticInstance;\n  }\n\n  // TODO(koss): Remove these functions unless used in tests?\n  interrupt() {\n    for (const appName of Object.keys(this.repos_)) {\n      for (const dbUrl of Object.keys(this.repos_[appName])) {\n        this.repos_[appName][dbUrl].interrupt();\n      }\n    }\n  }\n\n  resume() {\n    for (const appName of Object.keys(this.repos_)) {\n      for (const dbUrl of Object.keys(this.repos_[appName])) {\n        this.repos_[appName][dbUrl].resume();\n      }\n    }\n  }\n\n  /**\n   * This function should only ever be called to CREATE a new database instance.\n   *\n   * @param {!FirebaseApp} app\n   * @return {!Database}\n   */\n  databaseFromApp(\n    app: FirebaseApp,\n    authProvider: Provider<FirebaseAuthInternalName>,\n    url?: string\n  ): Database {\n    let dbUrl: string | undefined = url || app.options[DATABASE_URL_OPTION];\n    if (dbUrl === undefined) {\n      fatal(\n        \"Can't determine Firebase Database URL.  Be sure to include \" +\n          DATABASE_URL_OPTION +\n          ' option when calling firebase.initializeApp().'\n      );\n    }\n\n    let parsedUrl = parseRepoInfo(dbUrl);\n    let repoInfo = parsedUrl.repoInfo;\n\n    let isEmulator: boolean;\n\n    let dbEmulatorHost: string | undefined = undefined;\n    if (typeof process !== 'undefined') {\n      dbEmulatorHost = process.env[FIREBASE_DATABASE_EMULATOR_HOST_VAR];\n    }\n\n    if (dbEmulatorHost) {\n      isEmulator = true;\n      dbUrl = `http://${dbEmulatorHost}?ns=${repoInfo.namespace}`;\n      parsedUrl = parseRepoInfo(dbUrl);\n      repoInfo = parsedUrl.repoInfo;\n    } else {\n      isEmulator = !parsedUrl.repoInfo.secure;\n    }\n\n    const authTokenProvider =\n      CONSTANTS.NODE_ADMIN && isEmulator\n        ? new EmulatorAdminTokenProvider()\n        : new FirebaseAuthTokenProvider(app, authProvider);\n\n    validateUrl('Invalid Firebase Database URL', 1, parsedUrl);\n    if (!parsedUrl.path.isEmpty()) {\n      fatal(\n        'Database URL must point to the root of a Firebase Database ' +\n          '(not including a child path).'\n      );\n    }\n\n    const repo = this.createRepo(repoInfo, app, authTokenProvider);\n\n    return repo.database;\n  }\n\n  /**\n   * Remove the repo and make sure it is disconnected.\n   *\n   * @param {!Repo} repo\n   */\n  deleteRepo(repo: Repo) {\n    const appRepos = safeGet(this.repos_, repo.app.name);\n    // This should never happen...\n    if (!appRepos || safeGet(appRepos, repo.repoInfo_.toURLString()) !== repo) {\n      fatal(\n        `Database ${repo.app.name}(${repo.repoInfo_}) has already been deleted.`\n      );\n    }\n    repo.interrupt();\n    delete appRepos[repo.repoInfo_.toURLString()];\n  }\n\n  /**\n   * Ensures a repo doesn't already exist and then creates one using the\n   * provided app.\n   *\n   * @param {!RepoInfo} repoInfo The metadata about the Repo\n   * @param {!FirebaseApp} app\n   * @return {!Repo} The Repo object for the specified server / repoName.\n   */\n  createRepo(\n    repoInfo: RepoInfo,\n    app: FirebaseApp,\n    authTokenProvider: AuthTokenProvider\n  ): Repo {\n    let appRepos = safeGet(this.repos_, app.name);\n\n    if (!appRepos) {\n      appRepos = {};\n      this.repos_[app.name] = appRepos;\n    }\n\n    let repo = safeGet(appRepos, repoInfo.toURLString());\n    if (repo) {\n      fatal(\n        'Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.'\n      );\n    }\n    repo = new Repo(repoInfo, this.useRestClient_, app, authTokenProvider);\n    appRepos[repoInfo.toURLString()] = repo;\n\n    return repo;\n  }\n\n  /**\n   * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.\n   * @param {boolean} forceRestClient\n   */\n  forceRestClient(forceRestClient: boolean) {\n    this.useRestClient_ = forceRestClient;\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 { fatal } from '../core/util/util';\nimport { parseRepoInfo } from '../core/util/libs/parser';\nimport { Path } from '../core/util/Path';\nimport { Reference } from './Reference';\nimport { Repo } from '../core/Repo';\nimport { RepoManager } from '../core/RepoManager';\nimport { validateArgCount } from '@firebase/util';\nimport { validateUrl } from '../core/util/validation';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { RepoInfo } from '../core/RepoInfo';\nimport { FirebaseDatabase } from '@firebase/database-types';\n\n/**\n * Class representing a firebase database.\n * @implements {FirebaseService}\n */\nexport class Database implements FirebaseService {\n  INTERNAL: DatabaseInternals;\n  private root_: Reference;\n\n  static readonly ServerValue = {\n    TIMESTAMP: {\n      '.sv': 'timestamp'\n    },\n    increment: (delta: number) => {\n      return {\n        '.sv': {\n          'increment': delta\n        }\n      };\n    }\n  };\n\n  /**\n   * The constructor should not be called by users of our public API.\n   * @param {!Repo} repo_\n   */\n  constructor(private repo_: Repo) {\n    if (!(repo_ instanceof Repo)) {\n      fatal(\n        \"Don't call new Database() directly - please use firebase.database().\"\n      );\n    }\n\n    /** @type {Reference} */\n    this.root_ = new Reference(repo_, Path.Empty);\n\n    this.INTERNAL = new DatabaseInternals(this);\n  }\n\n  get app(): FirebaseApp {\n    return this.repo_.app;\n  }\n\n  /**\n   * Returns a reference to the root or to the path specified in the provided\n   * argument.\n   *\n   * @param {string|Reference=} path The relative string path or an existing\n   * Reference to a database location.\n   * @throws If a Reference is provided, throws if it does not belong to the\n   * same project.\n   * @return {!Reference} Firebase reference.\n   */\n  ref(path?: string): Reference;\n  ref(path?: Reference): Reference;\n  ref(path?: string | Reference): Reference {\n    this.checkDeleted_('ref');\n    validateArgCount('database.ref', 0, 1, arguments.length);\n\n    if (path instanceof Reference) {\n      return this.refFromURL(path.toString());\n    }\n\n    return path !== undefined ? this.root_.child(path) : this.root_;\n  }\n\n  /**\n   * Returns a reference to the root or the path specified in url.\n   * We throw a exception if the url is not in the same domain as the\n   * current repo.\n   * @param {string} url\n   * @return {!Reference} Firebase reference.\n   */\n  refFromURL(url: string): Reference {\n    /** @const {string} */\n    const apiName = 'database.refFromURL';\n    this.checkDeleted_(apiName);\n    validateArgCount(apiName, 1, 1, arguments.length);\n    const parsedURL = parseRepoInfo(url);\n    validateUrl(apiName, 1, parsedURL);\n\n    const repoInfo = parsedURL.repoInfo;\n    if (repoInfo.host !== (this.repo_.repoInfo_ as RepoInfo).host) {\n      fatal(\n        apiName +\n          ': Host name does not match the current database: ' +\n          '(found ' +\n          repoInfo.host +\n          ' but expected ' +\n          (this.repo_.repoInfo_ as RepoInfo).host +\n          ')'\n      );\n    }\n\n    return this.ref(parsedURL.path.toString());\n  }\n\n  /**\n   * @param {string} apiName\n   */\n  private checkDeleted_(apiName: string) {\n    if (this.repo_ === null) {\n      fatal('Cannot call ' + apiName + ' on a deleted database.');\n    }\n  }\n\n  // Make individual repo go offline.\n  goOffline() {\n    validateArgCount('database.goOffline', 0, 0, arguments.length);\n    this.checkDeleted_('goOffline');\n    this.repo_.interrupt();\n  }\n\n  goOnline() {\n    validateArgCount('database.goOnline', 0, 0, arguments.length);\n    this.checkDeleted_('goOnline');\n    this.repo_.resume();\n  }\n}\n\nexport class DatabaseInternals {\n  /** @param {!Database} database */\n  constructor(public database: Database) {}\n\n  /** @return {Promise<void>} */\n  async delete(): Promise<void> {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    (this.database as any).checkDeleted_('delete');\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    RepoManager.getInstance().deleteRepo((this.database as any).repo_ as Repo);\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    (this.database as any).repo_ = null;\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    (this.database as any).root_ = null;\n    this.database.INTERNAL = null;\n    this.database = null;\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 { WebSocketConnection } from '../realtime/WebSocketConnection';\nimport { BrowserPollConnection } from '../realtime/BrowserPollConnection';\nimport { Reference } from './Reference';\n\n/**\n * INTERNAL methods for internal-use only (tests, etc.).\n *\n * Customers shouldn't use these or else should be aware that they could break at any time.\n *\n * @const\n */\n\nexport const forceLongPolling = function () {\n  WebSocketConnection.forceDisallow();\n  BrowserPollConnection.forceAllow();\n};\n\nexport const forceWebSockets = function () {\n  BrowserPollConnection.forceDisallow();\n};\n\n/* Used by App Manager */\nexport const isWebSocketsAvailable = function (): boolean {\n  return WebSocketConnection['isAvailable']();\n};\n\nexport const setSecurityDebugCallback = function (\n  ref: Reference,\n  callback: (a: object) => void\n) {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  (ref.repo.persistentConnection_ as any).securityDebugCallback_ = callback;\n};\n\nexport const stats = function (ref: Reference, showDelta?: boolean) {\n  ref.repo.stats(showDelta);\n};\n\nexport const statsIncrementCounter = function (ref: Reference, metric: string) {\n  ref.repo.statsIncrementCounter(metric);\n};\n\nexport const dataUpdateCount = function (ref: Reference): number {\n  return ref.repo.dataUpdateCount;\n};\n\nexport const interceptServerData = function (\n  ref: Reference,\n  callback: ((a: string, b: unknown) => void) | null\n) {\n  return ref.repo.interceptServerData_(callback);\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 { RepoInfo } from '../core/RepoInfo';\nimport { PersistentConnection } from '../core/PersistentConnection';\nimport { RepoManager } from '../core/RepoManager';\nimport { Connection } from '../realtime/Connection';\nimport { Query } from './Query';\n\nexport const DataConnection = PersistentConnection;\n\n/**\n * @param {!string} pathString\n * @param {function(*)} onComplete\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(PersistentConnection.prototype as any).simpleListen = function (\n  pathString: string,\n  onComplete: (a: unknown) => void\n) {\n  this.sendRequest('q', { p: pathString }, onComplete);\n};\n\n/**\n * @param {*} data\n * @param {function(*)} onEcho\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(PersistentConnection.prototype as any).echo = function (\n  data: unknown,\n  onEcho: (a: unknown) => void\n) {\n  this.sendRequest('echo', { d: data }, onEcho);\n};\n\n// RealTimeConnection properties that we use in tests.\nexport const RealTimeConnection = Connection;\n\n/**\n * @param {function(): string} newHash\n * @return {function()}\n */\nexport const hijackHash = function (newHash: () => string) {\n  const oldPut = PersistentConnection.prototype.put;\n  PersistentConnection.prototype.put = function (\n    pathString,\n    data,\n    onComplete,\n    hash\n  ) {\n    if (hash !== undefined) {\n      hash = newHash();\n    }\n    oldPut.call(this, pathString, data, onComplete, hash);\n  };\n  return function () {\n    PersistentConnection.prototype.put = oldPut;\n  };\n};\n\n/**\n * @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}\n */\nexport const ConnectionTarget = RepoInfo;\n\n/**\n * @param {!Query} query\n * @return {!string}\n */\nexport const queryIdentifier = function (query: Query) {\n  return query.queryIdentifier();\n};\n\n/**\n * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.\n *\n * @param {boolean} forceRestClient\n */\nexport const forceRestClient = function (forceRestClient: boolean) {\n  RepoManager.getInstance().forceRestClient(forceRestClient);\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 { Logger, LogLevel, LogLevelString } from '@firebase/logger';\nimport { SDK_VERSION } from '../core/version';\nimport { formatJSON } from '../platform/format_json';\n\nexport { LogLevel };\n\nconst logClient = new Logger('@firebase/firestore');\n\n// Helper methods are needed because variables can't be exported as read/write\nexport function getLogLevel(): LogLevel {\n  return logClient.logLevel;\n}\n\nexport function setLogLevel(newLevel: LogLevelString | LogLevel): void {\n  logClient.setLogLevel(newLevel);\n}\n\nexport function logDebug(msg: string, ...obj: unknown[]): void {\n  if (logClient.logLevel <= LogLevel.DEBUG) {\n    const args = obj.map(argToString);\n    logClient.debug(`Firestore (${SDK_VERSION}): ${msg}`, ...args);\n  }\n}\n\nexport function logError(msg: string, ...obj: unknown[]): void {\n  if (logClient.logLevel <= LogLevel.ERROR) {\n    const args = obj.map(argToString);\n    logClient.error(`Firestore (${SDK_VERSION}): ${msg}`, ...args);\n  }\n}\n\nexport function logWarn(msg: string, ...obj: unknown[]): void {\n  if (logClient.logLevel <= LogLevel.WARN) {\n    const args = obj.map(argToString);\n    logClient.warn(`Firestore (${SDK_VERSION}): ${msg}`, ...args);\n  }\n}\n\n/**\n * Converts an additional log parameter to a string representation.\n */\nfunction argToString(obj: unknown): string | unknown {\n  if (typeof obj === 'string') {\n    return obj;\n  } else {\n    try {\n      return formatJSON(obj);\n    } catch (e) {\n      // Converting to JSON failed, just log the object directly\n      return obj;\n    }\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\n/** Formats an object as a JSON string, suitable for logging. */\nexport function formatJSON(value: unknown): string {\n  return JSON.stringify(value);\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 { SDK_VERSION } from '../core/version';\nimport { logError } from './log';\n\n/**\n * Unconditionally fails, throwing an Error with the given message.\n * Messages are stripped in production builds.\n *\n * Returns `never` and can be used in expressions:\n * @example\n * let futureVar = fail('not implemented yet');\n */\nexport function fail(failure: string = 'Unexpected state'): never {\n  // Log the failure in addition to throw an exception, just in case the\n  // exception is swallowed.\n  const message =\n    `FIRESTORE (${SDK_VERSION}) INTERNAL ASSERTION FAILED: ` + failure;\n  logError(message);\n\n  // NOTE: We don't use FirestoreError here because these are internal failures\n  // that cannot be handled by the user. (Also it would create a circular\n  // dependency between the error and assert modules which doesn't work.)\n  throw new Error(message);\n}\n\n/**\n * Fails if the given assertion condition is false, throwing an Error with the\n * given message if it did.\n *\n * Messages are stripped in production builds.\n */\nexport function hardAssert(\n  assertion: boolean,\n  message?: string\n): asserts assertion {\n  if (!assertion) {\n    fail(message);\n  }\n}\n\n/**\n * Fails if the given assertion condition is false, throwing an Error with the\n * given message if it did.\n *\n * The code of callsites invoking this function are stripped out in production\n * builds. Any side-effects of code within the debugAssert() invocation will not\n * happen in this case.\n */\nexport function debugAssert(\n  assertion: boolean,\n  message: string\n): asserts assertion {\n  if (!assertion) {\n    fail(message);\n  }\n}\n\n/**\n * Casts `obj` to `T`. In non-production builds, verifies that `obj` is an\n * instance of `T` before casting.\n */\nexport function debugCast<T>(\n  obj: object,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  constructor: { new (...args: any[]): T }\n): T | never {\n  debugAssert(\n    obj instanceof constructor,\n    `Expected type '${constructor.name}', but was '${obj.constructor.name}'`\n  );\n  return obj as T;\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 { debugAssert } from '../../util/assert';\n\n/**\n * Generates `nBytes` of random bytes.\n *\n * If `nBytes < 0` , an error will be thrown.\n */\nexport function randomBytes(nBytes: number): Uint8Array {\n  debugAssert(nBytes >= 0, `Expecting non-negative nBytes, got: ${nBytes}`);\n\n  // Polyfills for IE and WebWorker by using `self` and `msCrypto` when `crypto` is not available.\n  const crypto =\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    typeof self !== 'undefined' && (self.crypto || (self as any)['msCrypto']);\n  const bytes = new Uint8Array(nBytes);\n  if (crypto) {\n    crypto.getRandomValues(bytes);\n  } else {\n    // Falls back to Math.random\n    for (let i = 0; i < nBytes; i++) {\n      bytes[i] = Math.floor(Math.random() * 256);\n    }\n  }\n  return bytes;\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 { debugAssert } from './assert';\nimport { randomBytes } from '../platform/random_bytes';\n\nexport type EventHandler<E> = (value: E) => void;\nexport interface Indexable {\n  [k: string]: unknown;\n}\n\nexport class AutoId {\n  static newId(): string {\n    // Alphanumeric characters\n    const chars =\n      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n    // The largest byte value that is a multiple of `char.length`.\n    const maxMultiple = Math.floor(256 / chars.length) * chars.length;\n    debugAssert(\n      0 < maxMultiple && maxMultiple < 256,\n      `Expect maxMultiple to be (0, 256), but got ${maxMultiple}`\n    );\n\n    let autoId = '';\n    const targetLength = 20;\n    while (autoId.length < targetLength) {\n      const bytes = randomBytes(40);\n      for (let i = 0; i < bytes.length; ++i) {\n        // Only accept values that are [0, maxMultiple), this ensures they can\n        // be evenly mapped to indices of `chars` via a modulo operation.\n        if (autoId.length < targetLength && bytes[i] < maxMultiple) {\n          autoId += chars.charAt(bytes[i] % chars.length);\n        }\n      }\n    }\n    debugAssert(autoId.length === targetLength, 'Invalid auto ID: ' + autoId);\n\n    return autoId;\n  }\n}\n\nexport function primitiveComparator<T>(left: T, right: T): number {\n  if (left < right) {\n    return -1;\n  }\n  if (left > right) {\n    return 1;\n  }\n  return 0;\n}\n\nexport interface Equatable<T> {\n  isEqual(other: T): boolean;\n}\n\n/** Helper to compare arrays using isEqual(). */\nexport function arrayEquals<T>(\n  left: T[],\n  right: T[],\n  comparator: (l: T, r: T) => boolean\n): boolean {\n  if (left.length !== right.length) {\n    return false;\n  }\n  return left.every((value, index) => comparator(value, right[index]));\n}\n/**\n * Returns the immediate lexicographically-following string. This is useful to\n * construct an inclusive range for indexeddb iterators.\n */\nexport function immediateSuccessor(s: string): string {\n  // Return the input string, with an additional NUL byte appended.\n  return s + '\\0';\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 { primitiveComparator } from '../util/misc';\n\nexport class DatabaseInfo {\n  /**\n   * Constructs a DatabaseInfo using the provided host, databaseId and\n   * persistenceKey.\n   *\n   * @param databaseId The database to use.\n   * @param persistenceKey A unique identifier for this Firestore's local\n   * storage (used in conjunction with the databaseId).\n   * @param host The Firestore backend host to connect to.\n   * @param ssl Whether to use SSL when connecting.\n   * @param forceLongPolling Whether to use the forceLongPolling option\n   * when using WebChannel as the network transport.\n   */\n  constructor(\n    readonly databaseId: DatabaseId,\n    readonly persistenceKey: string,\n    readonly host: string,\n    readonly ssl: boolean,\n    readonly forceLongPolling: boolean\n  ) {}\n}\n\n/** The default database name for a project. */\nconst DEFAULT_DATABASE_NAME = '(default)';\n\n/** Represents the database ID a Firestore client is associated with. */\nexport class DatabaseId {\n  readonly database: string;\n  constructor(readonly projectId: string, database?: string) {\n    this.database = database ? database : DEFAULT_DATABASE_NAME;\n  }\n\n  get isDefaultDatabase(): boolean {\n    return this.database === DEFAULT_DATABASE_NAME;\n  }\n\n  isEqual(other: {}): boolean {\n    return (\n      other instanceof DatabaseId &&\n      other.projectId === this.projectId &&\n      other.database === this.database\n    );\n  }\n\n  compareTo(other: DatabaseId): number {\n    return (\n      primitiveComparator(this.projectId, other.projectId) ||\n      primitiveComparator(this.database, other.database)\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 { debugAssert } from './assert';\n\nexport interface Dict<V> {\n  [stringKey: string]: V;\n}\n\nexport function objectSize<V>(obj: object): number {\n  let count = 0;\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      count++;\n    }\n  }\n  return count;\n}\n\nexport function forEach<V>(\n  obj: Dict<V>,\n  fn: (key: string, val: V) => void\n): void {\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      fn(key, obj[key]);\n    }\n  }\n}\n\nexport function isEmpty<V>(obj: Dict<V>): boolean {\n  debugAssert(\n    obj != null && typeof obj === 'object',\n    'isEmpty() expects object parameter.'\n  );\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      return false;\n    }\n  }\n  return 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\nimport { forEach, isEmpty } from './obj';\n\ntype Entry<K, V> = [K, V];\n\n/**\n * A map implementation that uses objects as keys. Objects must have an\n * associated equals function and must be immutable. Entries in the map are\n * stored together with the key being produced from the mapKeyFn. This map\n * automatically handles collisions of keys.\n */\nexport class ObjectMap<KeyType, ValueType> {\n  /**\n   * The inner map for a key -> value pair. Due to the possibility of\n   * collisions we keep a list of entries that we do a linear search through\n   * to find an actual match. Note that collisions should be rare, so we still\n   * expect near constant time lookups in practice.\n   */\n  private inner: {\n    [canonicalId: string]: Array<Entry<KeyType, ValueType>>;\n  } = {};\n\n  constructor(\n    private mapKeyFn: (key: KeyType) => string,\n    private equalsFn: (l: KeyType, r: KeyType) => boolean\n  ) {}\n\n  /** Get a value for this key, or undefined if it does not exist. */\n  get(key: KeyType): ValueType | undefined {\n    const id = this.mapKeyFn(key);\n    const matches = this.inner[id];\n    if (matches === undefined) {\n      return undefined;\n    }\n    for (const [otherKey, value] of matches) {\n      if (this.equalsFn(otherKey, key)) {\n        return value;\n      }\n    }\n    return undefined;\n  }\n\n  has(key: KeyType): boolean {\n    return this.get(key) !== undefined;\n  }\n\n  /** Put this key and value in the map. */\n  set(key: KeyType, value: ValueType): void {\n    const id = this.mapKeyFn(key);\n    const matches = this.inner[id];\n    if (matches === undefined) {\n      this.inner[id] = [[key, value]];\n      return;\n    }\n    for (let i = 0; i < matches.length; i++) {\n      if (this.equalsFn(matches[i][0], key)) {\n        matches[i] = [key, value];\n        return;\n      }\n    }\n    matches.push([key, value]);\n  }\n\n  /**\n   * Remove this key from the map. Returns a boolean if anything was deleted.\n   */\n  delete(key: KeyType): boolean {\n    const id = this.mapKeyFn(key);\n    const matches = this.inner[id];\n    if (matches === undefined) {\n      return false;\n    }\n    for (let i = 0; i < matches.length; i++) {\n      if (this.equalsFn(matches[i][0], key)) {\n        if (matches.length === 1) {\n          delete this.inner[id];\n        } else {\n          matches.splice(i, 1);\n        }\n        return true;\n      }\n    }\n    return false;\n  }\n\n  forEach(fn: (key: KeyType, val: ValueType) => void): void {\n    forEach(this.inner, (_, entries) => {\n      for (const [k, v] of entries) {\n        fn(k, v);\n      }\n    });\n  }\n\n  isEmpty(): boolean {\n    return isEmpty(this.inner);\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 * as firestore from '@firebase/firestore-types';\n\n/**\n * Error Codes describing the different ways Firestore can fail. These come\n * directly from GRPC.\n */\nexport type Code = firestore.FirestoreErrorCode;\n\nexport const Code = {\n  // Causes are copied from:\n  // https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h\n  /** Not an error; returned on success. */\n  OK: 'ok' as Code,\n\n  /** The operation was cancelled (typically by the caller). */\n  CANCELLED: 'cancelled' as Code,\n\n  /** Unknown error or an error from a different error domain. */\n  UNKNOWN: 'unknown' as Code,\n\n  /**\n   * Client specified an invalid argument. Note that this differs from\n   * FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are\n   * problematic regardless of the state of the system (e.g., a malformed file\n   * name).\n   */\n  INVALID_ARGUMENT: 'invalid-argument' as Code,\n\n  /**\n   * Deadline expired before operation could complete. For operations that\n   * change the state of the system, this error may be returned even if the\n   * operation has completed successfully. For example, a successful response\n   * from a server could have been delayed long enough for the deadline to\n   * expire.\n   */\n  DEADLINE_EXCEEDED: 'deadline-exceeded' as Code,\n\n  /** Some requested entity (e.g., file or directory) was not found. */\n  NOT_FOUND: 'not-found' as Code,\n\n  /**\n   * Some entity that we attempted to create (e.g., file or directory) already\n   * exists.\n   */\n  ALREADY_EXISTS: 'already-exists' as Code,\n\n  /**\n   * The caller does not have permission to execute the specified operation.\n   * PERMISSION_DENIED must not be used for rejections caused by exhausting\n   * some resource (use RESOURCE_EXHAUSTED instead for those errors).\n   * PERMISSION_DENIED must not be used if the caller can not be identified\n   * (use UNAUTHENTICATED instead for those errors).\n   */\n  PERMISSION_DENIED: 'permission-denied' as Code,\n\n  /**\n   * The request does not have valid authentication credentials for the\n   * operation.\n   */\n  UNAUTHENTICATED: 'unauthenticated' as Code,\n\n  /**\n   * Some resource has been exhausted, perhaps a per-user quota, or perhaps the\n   * entire file system is out of space.\n   */\n  RESOURCE_EXHAUSTED: 'resource-exhausted' as Code,\n\n  /**\n   * Operation was rejected because the system is not in a state required for\n   * the operation's execution. For example, directory to be deleted may be\n   * non-empty, an rmdir operation is applied to a non-directory, etc.\n   *\n   * A litmus test that may help a service implementor in deciding\n   * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:\n   *  (a) Use UNAVAILABLE if the client can retry just the failing call.\n   *  (b) Use ABORTED if the client should retry at a higher-level\n   *      (e.g., restarting a read-modify-write sequence).\n   *  (c) Use FAILED_PRECONDITION if the client should not retry until\n   *      the system state has been explicitly fixed. E.g., if an \"rmdir\"\n   *      fails because the directory is non-empty, FAILED_PRECONDITION\n   *      should be returned since the client should not retry unless\n   *      they have first fixed up the directory by deleting files from it.\n   *  (d) Use FAILED_PRECONDITION if the client performs conditional\n   *      REST Get/Update/Delete on a resource and the resource on the\n   *      server does not match the condition. E.g., conflicting\n   *      read-modify-write on the same resource.\n   */\n  FAILED_PRECONDITION: 'failed-precondition' as Code,\n\n  /**\n   * The operation was aborted, typically due to a concurrency issue like\n   * sequencer check failures, transaction aborts, etc.\n   *\n   * See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,\n   * and UNAVAILABLE.\n   */\n  ABORTED: 'aborted' as Code,\n\n  /**\n   * Operation was attempted past the valid range. E.g., seeking or reading\n   * past end of file.\n   *\n   * Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed\n   * if the system state changes. For example, a 32-bit file system will\n   * generate INVALID_ARGUMENT if asked to read at an offset that is not in the\n   * range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from\n   * an offset past the current file size.\n   *\n   * There is a fair bit of overlap between FAILED_PRECONDITION and\n   * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)\n   * when it applies so that callers who are iterating through a space can\n   * easily look for an OUT_OF_RANGE error to detect when they are done.\n   */\n  OUT_OF_RANGE: 'out-of-range' as Code,\n\n  /** Operation is not implemented or not supported/enabled in this service. */\n  UNIMPLEMENTED: 'unimplemented' as Code,\n\n  /**\n   * Internal errors. Means some invariants expected by underlying System has\n   * been broken. If you see one of these errors, Something is very broken.\n   */\n  INTERNAL: 'internal' as Code,\n\n  /**\n   * The service is currently unavailable. This is a most likely a transient\n   * condition and may be corrected by retrying with a backoff.\n   *\n   * See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,\n   * and UNAVAILABLE.\n   */\n  UNAVAILABLE: 'unavailable' as Code,\n\n  /** Unrecoverable data loss or corruption. */\n  DATA_LOSS: 'data-loss' as Code\n};\n\n/**\n * An error class used for Firestore-generated errors. Ideally we should be\n * using FirebaseError, but integrating with it is overly arduous at the moment,\n * so we define our own compatible error class (with a `name` of 'FirebaseError'\n * and compatible `code` and `message` fields.)\n */\nexport class FirestoreError extends Error implements firestore.FirestoreError {\n  name = 'FirebaseError';\n  stack?: string;\n\n  constructor(readonly code: Code, readonly message: string) {\n    super(message);\n\n    // HACK: We write a toString property directly because Error is not a real\n    // class and so inheritance does not work correctly. We could alternatively\n    // do the same \"back-door inheritance\" trick that FirebaseError does.\n    this.toString = () => `${this.name}: [code=${this.code}]: ${this.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\nimport { Code, FirestoreError } from '../util/error';\nimport { primitiveComparator } from '../util/misc';\n\n// The earlist date supported by Firestore timestamps (0001-01-01T00:00:00Z).\nconst MIN_SECONDS = -62135596800;\n\nexport class Timestamp {\n  static now(): Timestamp {\n    return Timestamp.fromMillis(Date.now());\n  }\n\n  static fromDate(date: Date): Timestamp {\n    return Timestamp.fromMillis(date.getTime());\n  }\n\n  static fromMillis(milliseconds: number): Timestamp {\n    const seconds = Math.floor(milliseconds / 1000);\n    const nanos = (milliseconds - seconds * 1000) * 1e6;\n    return new Timestamp(seconds, nanos);\n  }\n\n  constructor(readonly seconds: number, readonly nanoseconds: number) {\n    if (nanoseconds < 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Timestamp nanoseconds out of range: ' + nanoseconds\n      );\n    }\n    if (nanoseconds >= 1e9) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Timestamp nanoseconds out of range: ' + nanoseconds\n      );\n    }\n    if (seconds < MIN_SECONDS) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Timestamp seconds out of range: ' + seconds\n      );\n    }\n    // This will break in the year 10,000.\n    if (seconds >= 253402300800) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Timestamp seconds out of range: ' + seconds\n      );\n    }\n  }\n\n  toDate(): Date {\n    return new Date(this.toMillis());\n  }\n\n  toMillis(): number {\n    return this.seconds * 1000 + this.nanoseconds / 1e6;\n  }\n\n  _compareTo(other: Timestamp): number {\n    if (this.seconds === other.seconds) {\n      return primitiveComparator(this.nanoseconds, other.nanoseconds);\n    }\n    return primitiveComparator(this.seconds, other.seconds);\n  }\n\n  isEqual(other: Timestamp): boolean {\n    return (\n      other.seconds === this.seconds && other.nanoseconds === this.nanoseconds\n    );\n  }\n\n  toString(): string {\n    return (\n      'Timestamp(seconds=' +\n      this.seconds +\n      ', nanoseconds=' +\n      this.nanoseconds +\n      ')'\n    );\n  }\n\n  valueOf(): string {\n    // This method returns a string of the form <seconds>.<nanoseconds> where <seconds> is\n    // translated to have a non-negative value and both <seconds> and <nanoseconds> are left-padded\n    // with zeroes to be a consistent length. Strings with this format then have a lexiographical\n    // ordering that matches the expected ordering. The <seconds> translation is done to avoid\n    // having a leading negative sign (i.e. a leading '-' character) in its string representation,\n    // which would affect its lexiographical ordering.\n    const adjustedSeconds = this.seconds - MIN_SECONDS;\n    // Note: Up to 12 decimal digits are required to represent all valid 'seconds' values.\n    const formattedSeconds = String(adjustedSeconds).padStart(12, '0');\n    const formattedNanoseconds = String(this.nanoseconds).padStart(9, '0');\n    return formattedSeconds + '.' + formattedNanoseconds;\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 { Timestamp } from '../api/timestamp';\n\n/**\n * A version of a document in Firestore. This corresponds to the version\n * timestamp, such as update_time or read_time.\n */\nexport class SnapshotVersion {\n  static fromTimestamp(value: Timestamp): SnapshotVersion {\n    return new SnapshotVersion(value);\n  }\n\n  static min(): SnapshotVersion {\n    return new SnapshotVersion(new Timestamp(0, 0));\n  }\n\n  private constructor(private timestamp: Timestamp) {}\n\n  compareTo(other: SnapshotVersion): number {\n    return this.timestamp._compareTo(other.timestamp);\n  }\n\n  isEqual(other: SnapshotVersion): boolean {\n    return this.timestamp.isEqual(other.timestamp);\n  }\n\n  /** Returns a number representation of the version for use in spec tests. */\n  toMicroseconds(): number {\n    // Convert to microseconds.\n    return this.timestamp.seconds * 1e6 + this.timestamp.nanoseconds / 1000;\n  }\n\n  toString(): string {\n    return 'SnapshotVersion(' + this.timestamp.toString() + ')';\n  }\n\n  toTimestamp(): Timestamp {\n    return this.timestamp;\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 { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\n\nexport const DOCUMENT_KEY_NAME = '__name__';\n\n/**\n * Path represents an ordered sequence of string segments.\n */\nabstract class BasePath<B extends BasePath<B>> {\n  private segments: string[];\n  private offset: number;\n  private len: number;\n\n  constructor(segments: string[], offset?: number, length?: number) {\n    if (offset === undefined) {\n      offset = 0;\n    } else if (offset > segments.length) {\n      fail('offset ' + offset + ' out of range ' + segments.length);\n    }\n\n    if (length === undefined) {\n      length = segments.length - offset;\n    } else if (length > segments.length - offset) {\n      fail('length ' + length + ' out of range ' + (segments.length - offset));\n    }\n    this.segments = segments;\n    this.offset = offset;\n    this.len = length;\n  }\n\n  /**\n   * Abstract constructor method to construct an instance of B with the given\n   * parameters.\n   */\n  protected abstract construct(\n    segments: string[],\n    offset?: number,\n    length?: number\n  ): B;\n\n  /**\n   * Returns a String representation.\n   *\n   * Implementing classes are required to provide deterministic implementations as\n   * the String representation is used to obtain canonical Query IDs.\n   */\n  abstract toString(): string;\n\n  get length(): number {\n    return this.len;\n  }\n\n  isEqual(other: B): boolean {\n    return BasePath.comparator(this, other) === 0;\n  }\n\n  child(nameOrPath: string | B): B {\n    const segments = this.segments.slice(this.offset, this.limit());\n    if (nameOrPath instanceof BasePath) {\n      nameOrPath.forEach(segment => {\n        segments.push(segment);\n      });\n    } else {\n      segments.push(nameOrPath);\n    }\n    return this.construct(segments);\n  }\n\n  /** The index of one past the last segment of the path. */\n  private limit(): number {\n    return this.offset + this.length;\n  }\n\n  popFirst(size?: number): B {\n    size = size === undefined ? 1 : size;\n    debugAssert(\n      this.length >= size,\n      \"Can't call popFirst() with less segments\"\n    );\n    return this.construct(\n      this.segments,\n      this.offset + size,\n      this.length - size\n    );\n  }\n\n  popLast(): B {\n    debugAssert(!this.isEmpty(), \"Can't call popLast() on empty path\");\n    return this.construct(this.segments, this.offset, this.length - 1);\n  }\n\n  firstSegment(): string {\n    debugAssert(!this.isEmpty(), \"Can't call firstSegment() on empty path\");\n    return this.segments[this.offset];\n  }\n\n  lastSegment(): string {\n    return this.get(this.length - 1);\n  }\n\n  get(index: number): string {\n    debugAssert(index < this.length, 'Index out of range');\n    return this.segments[this.offset + index];\n  }\n\n  isEmpty(): boolean {\n    return this.length === 0;\n  }\n\n  isPrefixOf(other: this): boolean {\n    if (other.length < this.length) {\n      return false;\n    }\n\n    for (let i = 0; i < this.length; i++) {\n      if (this.get(i) !== other.get(i)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  isImmediateParentOf(potentialChild: this): boolean {\n    if (this.length + 1 !== potentialChild.length) {\n      return false;\n    }\n\n    for (let i = 0; i < this.length; i++) {\n      if (this.get(i) !== potentialChild.get(i)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  forEach(fn: (segment: string) => void): void {\n    for (let i = this.offset, end = this.limit(); i < end; i++) {\n      fn(this.segments[i]);\n    }\n  }\n\n  toArray(): string[] {\n    return this.segments.slice(this.offset, this.limit());\n  }\n\n  static comparator<T extends BasePath<T>>(\n    p1: BasePath<T>,\n    p2: BasePath<T>\n  ): number {\n    const len = Math.min(p1.length, p2.length);\n    for (let i = 0; i < len; i++) {\n      const left = p1.get(i);\n      const right = p2.get(i);\n      if (left < right) {\n        return -1;\n      }\n      if (left > right) {\n        return 1;\n      }\n    }\n    if (p1.length < p2.length) {\n      return -1;\n    }\n    if (p1.length > p2.length) {\n      return 1;\n    }\n    return 0;\n  }\n}\n\n/**\n * A slash-separated path for navigating resources (documents and collections)\n * within Firestore.\n */\nexport class ResourcePath extends BasePath<ResourcePath> {\n  protected construct(\n    segments: string[],\n    offset?: number,\n    length?: number\n  ): ResourcePath {\n    return new ResourcePath(segments, offset, length);\n  }\n\n  canonicalString(): string {\n    // NOTE: The client is ignorant of any path segments containing escape\n    // sequences (e.g. __id123__) and just passes them through raw (they exist\n    // for legacy reasons and should not be used frequently).\n\n    return this.toArray().join('/');\n  }\n\n  toString(): string {\n    return this.canonicalString();\n  }\n\n  /**\n   * Creates a resource path from the given slash-delimited string.\n   */\n  static fromString(path: string): ResourcePath {\n    // NOTE: The client is ignorant of any path segments containing escape\n    // sequences (e.g. __id123__) and just passes them through raw (they exist\n    // for legacy reasons and should not be used frequently).\n\n    if (path.indexOf('//') >= 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid path (${path}). Paths must not contain // in them.`\n      );\n    }\n\n    // We may still have an empty segment at the beginning or end if they had a\n    // leading or trailing slash (which we allow).\n    const segments = path.split('/').filter(segment => segment.length > 0);\n\n    return new ResourcePath(segments);\n  }\n\n  static emptyPath(): ResourcePath {\n    return new ResourcePath([]);\n  }\n}\n\nconst identifierRegExp = /^[_a-zA-Z][_a-zA-Z0-9]*$/;\n\n/** A dot-separated path for navigating sub-objects within a document. */\nexport class FieldPath extends BasePath<FieldPath> {\n  protected construct(\n    segments: string[],\n    offset?: number,\n    length?: number\n  ): FieldPath {\n    return new FieldPath(segments, offset, length);\n  }\n\n  /**\n   * Returns true if the string could be used as a segment in a field path\n   * without escaping.\n   */\n  private static isValidIdentifier(segment: string): boolean {\n    return identifierRegExp.test(segment);\n  }\n\n  canonicalString(): string {\n    return this.toArray()\n      .map(str => {\n        str = str.replace('\\\\', '\\\\\\\\').replace('`', '\\\\`');\n        if (!FieldPath.isValidIdentifier(str)) {\n          str = '`' + str + '`';\n        }\n        return str;\n      })\n      .join('.');\n  }\n\n  toString(): string {\n    return this.canonicalString();\n  }\n\n  /**\n   * Returns true if this field references the key of a document.\n   */\n  isKeyField(): boolean {\n    return this.length === 1 && this.get(0) === DOCUMENT_KEY_NAME;\n  }\n\n  /**\n   * The field designating the key of a document.\n   */\n  static keyField(): FieldPath {\n    return new FieldPath([DOCUMENT_KEY_NAME]);\n  }\n\n  /**\n   * Parses a field string from the given server-formatted string.\n   *\n   * - Splitting the empty string is not allowed (for now at least).\n   * - Empty segments within the string (e.g. if there are two consecutive\n   *   separators) are not allowed.\n   *\n   * TODO(b/37244157): we should make this more strict. Right now, it allows\n   * non-identifier path components, even if they aren't escaped.\n   */\n  static fromServerFormat(path: string): FieldPath {\n    const segments: string[] = [];\n    let current = '';\n    let i = 0;\n\n    const addCurrentSegment = (): void => {\n      if (current.length === 0) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid field path (${path}). Paths must not be empty, begin ` +\n            `with '.', end with '.', or contain '..'`\n        );\n      }\n      segments.push(current);\n      current = '';\n    };\n\n    let inBackticks = false;\n\n    while (i < path.length) {\n      const c = path[i];\n      if (c === '\\\\') {\n        if (i + 1 === path.length) {\n          throw new FirestoreError(\n            Code.INVALID_ARGUMENT,\n            'Path has trailing escape character: ' + path\n          );\n        }\n        const next = path[i + 1];\n        if (!(next === '\\\\' || next === '.' || next === '`')) {\n          throw new FirestoreError(\n            Code.INVALID_ARGUMENT,\n            'Path has invalid escape sequence: ' + path\n          );\n        }\n        current += next;\n        i += 2;\n      } else if (c === '`') {\n        inBackticks = !inBackticks;\n        i++;\n      } else if (c === '.' && !inBackticks) {\n        addCurrentSegment();\n        i++;\n      } else {\n        current += c;\n        i++;\n      }\n    }\n    addCurrentSegment();\n\n    if (inBackticks) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Unterminated ` in path: ' + path\n      );\n    }\n\n    return new FieldPath(segments);\n  }\n\n  static emptyPath(): FieldPath {\n    return new FieldPath([]);\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 { debugAssert } from '../util/assert';\n\nimport { ResourcePath } from './path';\n\nexport class DocumentKey {\n  constructor(readonly path: ResourcePath) {\n    debugAssert(\n      DocumentKey.isDocumentKey(path),\n      'Invalid DocumentKey with an odd number of segments: ' +\n        path.toArray().join('/')\n    );\n  }\n\n  static fromName(name: string): DocumentKey {\n    return new DocumentKey(ResourcePath.fromString(name).popFirst(5));\n  }\n\n  /** Returns true if the document is in the specified collectionId. */\n  hasCollectionId(collectionId: string): boolean {\n    return (\n      this.path.length >= 2 &&\n      this.path.get(this.path.length - 2) === collectionId\n    );\n  }\n\n  isEqual(other: DocumentKey | null): boolean {\n    return (\n      other !== null && ResourcePath.comparator(this.path, other.path) === 0\n    );\n  }\n\n  toString(): string {\n    return this.path.toString();\n  }\n\n  static comparator(k1: DocumentKey, k2: DocumentKey): number {\n    return ResourcePath.comparator(k1.path, k2.path);\n  }\n\n  static isDocumentKey(path: ResourcePath): boolean {\n    return path.length % 2 === 0;\n  }\n\n  /**\n   * Creates and returns a new document key with the given segments.\n   *\n   * @param segments The segments of the path to the document\n   * @return A new instance of DocumentKey\n   */\n  static fromSegments(segments: string[]): DocumentKey {\n    return new DocumentKey(new ResourcePath(segments.slice()));\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// An Object whose keys and values are strings.\nexport interface StringMap {\n  [key: string]: string;\n}\n\n/**\n * Returns whether a variable is either undefined or null.\n */\nexport function isNullOrUndefined(value: unknown): value is null | undefined {\n  return value === null || value === undefined;\n}\n\n/** Returns whether the value represents -0. */\nexport function isNegativeZero(value: number): boolean {\n  // Detect if the value is -0.0. Based on polyfill from\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n  return value === -0 && 1 / value === 1 / -0;\n}\n\n/**\n * Returns whether a value is an integer and in the safe integer range\n * @param value The value to test for being an integer and in the safe range\n */\nexport function isSafeInteger(value: unknown): boolean {\n  return (\n    typeof value === 'number' &&\n    Number.isInteger(value) &&\n    !isNegativeZero(value) &&\n    value <= Number.MAX_SAFE_INTEGER &&\n    value >= Number.MIN_SAFE_INTEGER\n  );\n}\n\n/** The subset of the browser's Window interface used by the SDK. */\nexport interface WindowLike {\n  readonly localStorage: Storage;\n  readonly indexedDB: IDBFactory | null;\n  addEventListener(type: string, listener: EventListener): void;\n  removeEventListener(type: string, listener: EventListener): void;\n}\n\n/** The subset of the browser's Document interface used by the SDK. */\nexport interface DocumentLike {\n  readonly visibilityState: VisibilityState;\n  addEventListener(type: string, listener: EventListener): void;\n  removeEventListener(type: string, listener: EventListener): void;\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 { DocumentKey } from '../model/document_key';\nimport { ResourcePath } from '../model/path';\nimport { isNullOrUndefined } from '../util/types';\nimport {\n  Bound,\n  boundEquals,\n  canonifyBound,\n  canonifyFilter,\n  filterEquals,\n  stringifyFilter,\n  OrderBy,\n  orderByEquals,\n  stringifyOrderBy,\n  canonifyOrderBy,\n  Filter\n} from './query';\nimport { debugCast } from '../util/assert';\n\n/**\n * A Target represents the WatchTarget representation of a Query, which is used\n * by the LocalStore and the RemoteStore to keep track of and to execute\n * backend queries. While a Query can represent multiple Targets, each Targets\n * maps to a single WatchTarget in RemoteStore and a single TargetData entry\n * in persistence.\n */\nexport interface Target {\n  readonly path: ResourcePath;\n  readonly collectionGroup: string | null;\n  readonly orderBy: OrderBy[];\n  readonly filters: Filter[];\n  readonly limit: number | null;\n  readonly startAt: Bound | null;\n  readonly endAt: Bound | null;\n}\n\n// Visible for testing\nexport class TargetImpl implements Target {\n  memoizedCanonicalId: string | null = null;\n  constructor(\n    readonly path: ResourcePath,\n    readonly collectionGroup: string | null = null,\n    readonly orderBy: OrderBy[] = [],\n    readonly filters: Filter[] = [],\n    readonly limit: number | null = null,\n    readonly startAt: Bound | null = null,\n    readonly endAt: Bound | null = null\n  ) {}\n}\n\n/**\n * Initializes a Target with a path and optional additional query constraints.\n * Path must currently be empty if this is a collection group query.\n *\n * NOTE: you should always construct `Target` from `Query.toTarget` instead of\n * using this factory method, because `Query` provides an implicit `orderBy`\n * property.\n */\nexport function newTarget(\n  path: ResourcePath,\n  collectionGroup: string | null = null,\n  orderBy: OrderBy[] = [],\n  filters: Filter[] = [],\n  limit: number | null = null,\n  startAt: Bound | null = null,\n  endAt: Bound | null = null\n): Target {\n  return new TargetImpl(\n    path,\n    collectionGroup,\n    orderBy,\n    filters,\n    limit,\n    startAt,\n    endAt\n  );\n}\n\nexport function canonifyTarget(target: Target): string {\n  const targetImpl = debugCast(target, TargetImpl);\n\n  if (targetImpl.memoizedCanonicalId === null) {\n    let canonicalId = targetImpl.path.canonicalString();\n    if (targetImpl.collectionGroup !== null) {\n      canonicalId += '|cg:' + targetImpl.collectionGroup;\n    }\n    canonicalId += '|f:';\n    canonicalId += targetImpl.filters.map(f => canonifyFilter(f)).join(',');\n    canonicalId += '|ob:';\n    canonicalId += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');\n\n    if (!isNullOrUndefined(targetImpl.limit)) {\n      canonicalId += '|l:';\n      canonicalId += targetImpl.limit!;\n    }\n    if (targetImpl.startAt) {\n      canonicalId += '|lb:';\n      canonicalId += canonifyBound(targetImpl.startAt);\n    }\n    if (targetImpl.endAt) {\n      canonicalId += '|ub:';\n      canonicalId += canonifyBound(targetImpl.endAt);\n    }\n    targetImpl.memoizedCanonicalId = canonicalId;\n  }\n  return targetImpl.memoizedCanonicalId;\n}\n\nexport function stringifyTarget(target: Target): string {\n  let str = target.path.canonicalString();\n  if (target.collectionGroup !== null) {\n    str += ' collectionGroup=' + target.collectionGroup;\n  }\n  if (target.filters.length > 0) {\n    str += `, filters: [${target.filters\n      .map(f => stringifyFilter(f))\n      .join(', ')}]`;\n  }\n  if (!isNullOrUndefined(target.limit)) {\n    str += ', limit: ' + target.limit;\n  }\n  if (target.orderBy.length > 0) {\n    str += `, orderBy: [${target.orderBy\n      .map(o => stringifyOrderBy(o))\n      .join(', ')}]`;\n  }\n  if (target.startAt) {\n    str += ', startAt: ' + canonifyBound(target.startAt);\n  }\n  if (target.endAt) {\n    str += ', endAt: ' + canonifyBound(target.endAt);\n  }\n  return `Target(${str})`;\n}\n\nexport function targetEquals(left: Target, right: Target): boolean {\n  if (left.limit !== right.limit) {\n    return false;\n  }\n\n  if (left.orderBy.length !== right.orderBy.length) {\n    return false;\n  }\n\n  for (let i = 0; i < left.orderBy.length; i++) {\n    if (!orderByEquals(left.orderBy[i], right.orderBy[i])) {\n      return false;\n    }\n  }\n\n  if (left.filters.length !== right.filters.length) {\n    return false;\n  }\n\n  for (let i = 0; i < left.filters.length; i++) {\n    if (!filterEquals(left.filters[i], right.filters[i])) {\n      return false;\n    }\n  }\n\n  if (left.collectionGroup !== right.collectionGroup) {\n    return false;\n  }\n\n  if (!left.path.isEqual(right.path)) {\n    return false;\n  }\n\n  if (!boundEquals(left.startAt, right.startAt)) {\n    return false;\n  }\n\n  return boundEquals(left.endAt, right.endAt);\n}\n\nexport function isDocumentTarget(target: Target): boolean {\n  return (\n    DocumentKey.isDocumentKey(target.path) &&\n    target.collectionGroup === null &&\n    target.filters.length === 0\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 * as api from '../protos/firestore_proto_api';\n\nimport { compareDocumentsByField, Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport {\n  arrayValueContains,\n  canonicalId,\n  isArray,\n  isNanValue,\n  isNullValue,\n  isReferenceValue,\n  typeOrder,\n  valueCompare,\n  valueEquals\n} from '../model/values';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { isNullOrUndefined } from '../util/types';\nimport {\n  canonifyTarget,\n  newTarget,\n  stringifyTarget,\n  Target,\n  targetEquals\n} from './target';\nimport { cast } from '../../lite/src/api/util';\n\nexport const enum LimitType {\n  First = 'F',\n  Last = 'L'\n}\n\n/**\n * The Query interface defines all external properties of a query.\n *\n * QueryImpl implements this interface to provide memoization for `queryOrderBy`\n * and `queryToTarget`.\n */\nexport interface Query {\n  readonly path: ResourcePath;\n  readonly collectionGroup: string | null;\n  readonly explicitOrderBy: OrderBy[];\n  readonly filters: Filter[];\n  readonly limit: number | null;\n  readonly limitType: LimitType;\n  readonly startAt: Bound | null;\n  readonly endAt: Bound | null;\n\n  hasLimitToFirst(): boolean;\n  hasLimitToLast(): boolean;\n  getFirstOrderByField(): FieldPath | null;\n  getInequalityFilterField(): FieldPath | null;\n  asCollectionQueryAtPath(path: ResourcePath): Query;\n\n  /**\n   * Returns true if this query does not specify any query constraints that\n   * could remove results.\n   */\n  matchesAllDocuments(): boolean;\n\n  // Checks if any of the provided Operators are included in the query and\n  // returns the first one that is, or null if none are.\n  findFilterOperator(operators: Operator[]): Operator | null;\n}\n\n/**\n * Query encapsulates all the query attributes we support in the SDK. It can\n * be run against the LocalStore, as well as be converted to a `Target` to\n * query the RemoteStore results.\n *\n * Visible for testing.\n */\nexport class QueryImpl implements Query {\n  memoizedOrderBy: OrderBy[] | null = null;\n\n  // The corresponding `Target` of this `Query` instance.\n  memoizedTarget: Target | null = null;\n\n  /**\n   * Initializes a Query with a path and optional additional query constraints.\n   * Path must currently be empty if this is a collection group query.\n   */\n  constructor(\n    readonly path: ResourcePath,\n    readonly collectionGroup: string | null = null,\n    readonly explicitOrderBy: OrderBy[] = [],\n    readonly filters: Filter[] = [],\n    readonly limit: number | null = null,\n    readonly limitType: LimitType = LimitType.First,\n    readonly startAt: Bound | null = null,\n    readonly endAt: Bound | null = null\n  ) {\n    if (this.startAt) {\n      debugAssert(\n        this.startAt.position.length <= queryOrderBy(this).length,\n        'Bound is longer than orderBy'\n      );\n    }\n    if (this.endAt) {\n      debugAssert(\n        this.endAt.position.length <= queryOrderBy(this).length,\n        'Bound is longer than orderBy'\n      );\n    }\n  }\n\n  /**\n   * Helper to convert a collection group query into a collection query at a\n   * specific path. This is used when executing collection group queries, since\n   * we have to split the query into a set of collection queries at multiple\n   * paths.\n   */\n  asCollectionQueryAtPath(path: ResourcePath): Query {\n    return new QueryImpl(\n      path,\n      /*collectionGroup=*/ null,\n      this.explicitOrderBy.slice(),\n      this.filters.slice(),\n      this.limit,\n      this.limitType,\n      this.startAt,\n      this.endAt\n    );\n  }\n\n  matchesAllDocuments(): boolean {\n    return (\n      this.filters.length === 0 &&\n      this.limit === null &&\n      this.startAt == null &&\n      this.endAt == null &&\n      (this.explicitOrderBy.length === 0 ||\n        (this.explicitOrderBy.length === 1 &&\n          this.explicitOrderBy[0].field.isKeyField()))\n    );\n  }\n\n  hasLimitToFirst(): boolean {\n    return !isNullOrUndefined(this.limit) && this.limitType === LimitType.First;\n  }\n\n  hasLimitToLast(): boolean {\n    return !isNullOrUndefined(this.limit) && this.limitType === LimitType.Last;\n  }\n\n  getFirstOrderByField(): FieldPath | null {\n    return this.explicitOrderBy.length > 0\n      ? this.explicitOrderBy[0].field\n      : null;\n  }\n\n  getInequalityFilterField(): FieldPath | null {\n    for (const filter of this.filters) {\n      debugAssert(\n        filter instanceof FieldFilter,\n        'Only FieldFilters are supported'\n      );\n      if (filter.isInequality()) {\n        return filter.field;\n      }\n    }\n    return null;\n  }\n\n  findFilterOperator(operators: Operator[]): Operator | null {\n    for (const filter of this.filters) {\n      debugAssert(\n        filter instanceof FieldFilter,\n        'Only FieldFilters are supported'\n      );\n      if (operators.indexOf(filter.op) >= 0) {\n        return filter.op;\n      }\n    }\n    return null;\n  }\n}\n\n/** Creates a new Query instance with the options provided. */\nexport function newQuery(\n  path: ResourcePath,\n  collectionGroup: string | null,\n  explicitOrderBy: OrderBy[],\n  filters: Filter[],\n  limit: number | null,\n  limitType: LimitType,\n  startAt: Bound | null,\n  endAt: Bound | null\n): Query {\n  return new QueryImpl(\n    path,\n    collectionGroup,\n    explicitOrderBy,\n    filters,\n    limit,\n    limitType,\n    startAt,\n    endAt\n  );\n}\n\n/** Creates a new Query for a query that matches all documents at `path` */\nexport function newQueryForPath(path: ResourcePath): Query {\n  return new QueryImpl(path);\n}\n\n/**\n * Creates a new Query for a collection group query that matches all documents\n * within the provided collection group.\n */\nexport function newQueryForCollectionGroup(collectionId: string): Query {\n  return new QueryImpl(ResourcePath.emptyPath(), collectionId);\n}\n\n/**\n * Returns whether the query matches a single document by path (rather than a\n * collection).\n */\nexport function isDocumentQuery(query: Query): boolean {\n  return (\n    DocumentKey.isDocumentKey(query.path) &&\n    query.collectionGroup === null &&\n    query.filters.length === 0\n  );\n}\n\n/**\n * Returns whether the query matches a collection group rather than a specific\n * collection.\n */\nexport function isCollectionGroupQuery(query: Query): boolean {\n  return query.collectionGroup !== null;\n}\n\n/**\n * Returns the implicit order by constraint that is used to execute the Query,\n * which can be different from the order by constraints the user provided (e.g.\n * the SDK and backend always orders by `__name__`).\n */\nexport function queryOrderBy(query: Query): OrderBy[] {\n  const queryImpl = cast(query, QueryImpl);\n  if (queryImpl.memoizedOrderBy === null) {\n    queryImpl.memoizedOrderBy = [];\n\n    const inequalityField = queryImpl.getInequalityFilterField();\n    const firstOrderByField = queryImpl.getFirstOrderByField();\n    if (inequalityField !== null && firstOrderByField === null) {\n      // In order to implicitly add key ordering, we must also add the\n      // inequality filter field for it to be a valid query.\n      // Note that the default inequality field and key ordering is ascending.\n      if (!inequalityField.isKeyField()) {\n        queryImpl.memoizedOrderBy.push(new OrderBy(inequalityField));\n      }\n      queryImpl.memoizedOrderBy.push(\n        new OrderBy(FieldPath.keyField(), Direction.ASCENDING)\n      );\n    } else {\n      debugAssert(\n        inequalityField === null ||\n          (firstOrderByField !== null &&\n            inequalityField.isEqual(firstOrderByField)),\n        'First orderBy should match inequality field.'\n      );\n      let foundKeyOrdering = false;\n      for (const orderBy of queryImpl.explicitOrderBy) {\n        queryImpl.memoizedOrderBy.push(orderBy);\n        if (orderBy.field.isKeyField()) {\n          foundKeyOrdering = true;\n        }\n      }\n      if (!foundKeyOrdering) {\n        // The order of the implicit key ordering always matches the last\n        // explicit order by\n        const lastDirection =\n          queryImpl.explicitOrderBy.length > 0\n            ? queryImpl.explicitOrderBy[queryImpl.explicitOrderBy.length - 1]\n                .dir\n            : Direction.ASCENDING;\n        queryImpl.memoizedOrderBy.push(\n          new OrderBy(FieldPath.keyField(), lastDirection)\n        );\n      }\n    }\n  }\n  return queryImpl.memoizedOrderBy;\n}\n\n/**\n * Converts this `Query` instance to it's corresponding `Target` representation.\n */\nexport function queryToTarget(query: Query): Target {\n  const queryImpl = cast(query, QueryImpl);\n  if (!queryImpl.memoizedTarget) {\n    if (queryImpl.limitType === LimitType.First) {\n      queryImpl.memoizedTarget = newTarget(\n        queryImpl.path,\n        queryImpl.collectionGroup,\n        queryOrderBy(queryImpl),\n        queryImpl.filters,\n        queryImpl.limit,\n        queryImpl.startAt,\n        queryImpl.endAt\n      );\n    } else {\n      // Flip the orderBy directions since we want the last results\n      const orderBys = [] as OrderBy[];\n      for (const orderBy of queryOrderBy(queryImpl)) {\n        const dir =\n          orderBy.dir === Direction.DESCENDING\n            ? Direction.ASCENDING\n            : Direction.DESCENDING;\n        orderBys.push(new OrderBy(orderBy.field, dir));\n      }\n\n      // We need to swap the cursors to match the now-flipped query ordering.\n      const startAt = queryImpl.endAt\n        ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.before)\n        : null;\n      const endAt = queryImpl.startAt\n        ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.before)\n        : null;\n\n      // Now return as a LimitType.First query.\n      queryImpl.memoizedTarget = newTarget(\n        queryImpl.path,\n        queryImpl.collectionGroup,\n        orderBys,\n        queryImpl.filters,\n        queryImpl.limit,\n        startAt,\n        endAt\n      );\n    }\n  }\n  return queryImpl.memoizedTarget!;\n}\n\nexport function queryWithAddedFilter(query: Query, filter: Filter): Query {\n  debugAssert(\n    query.getInequalityFilterField() == null ||\n      !(filter instanceof FieldFilter) ||\n      !filter.isInequality() ||\n      filter.field.isEqual(query.getInequalityFilterField()!),\n    'Query must only have one inequality field.'\n  );\n\n  debugAssert(\n    !isDocumentQuery(query),\n    'No filtering allowed for document query'\n  );\n\n  const newFilters = query.filters.concat([filter]);\n  return new QueryImpl(\n    query.path,\n    query.collectionGroup,\n    query.explicitOrderBy.slice(),\n    newFilters,\n    query.limit,\n    query.limitType,\n    query.startAt,\n    query.endAt\n  );\n}\n\nexport function queryWithAddedOrderBy(query: Query, orderBy: OrderBy): Query {\n  debugAssert(\n    !query.startAt && !query.endAt,\n    'Bounds must be set after orderBy'\n  );\n  // TODO(dimond): validate that orderBy does not list the same key twice.\n  const newOrderBy = query.explicitOrderBy.concat([orderBy]);\n  return new QueryImpl(\n    query.path,\n    query.collectionGroup,\n    newOrderBy,\n    query.filters.slice(),\n    query.limit,\n    query.limitType,\n    query.startAt,\n    query.endAt\n  );\n}\n\nexport function queryWithLimit(\n  query: Query,\n  limit: number,\n  limitType: LimitType\n): Query {\n  return new QueryImpl(\n    query.path,\n    query.collectionGroup,\n    query.explicitOrderBy.slice(),\n    query.filters.slice(),\n    limit,\n    limitType,\n    query.startAt,\n    query.endAt\n  );\n}\n\nexport function queryWithStartAt(query: Query, bound: Bound): Query {\n  return new QueryImpl(\n    query.path,\n    query.collectionGroup,\n    query.explicitOrderBy.slice(),\n    query.filters.slice(),\n    query.limit,\n    query.limitType,\n    bound,\n    query.endAt\n  );\n}\n\nexport function queryWithEndAt(query: Query, bound: Bound): Query {\n  return new QueryImpl(\n    query.path,\n    query.collectionGroup,\n    query.explicitOrderBy.slice(),\n    query.filters.slice(),\n    query.limit,\n    query.limitType,\n    query.startAt,\n    bound\n  );\n}\n\nexport function queryEquals(left: Query, right: Query): boolean {\n  return (\n    targetEquals(queryToTarget(left), queryToTarget(right)) &&\n    left.limitType === right.limitType\n  );\n}\n\n// TODO(b/29183165): This is used to get a unique string from a query to, for\n// example, use as a dictionary key, but the implementation is subject to\n// collisions. Make it collision-free.\nexport function canonifyQuery(query: Query): string {\n  return `${canonifyTarget(queryToTarget(query))}|lt:${query.limitType}`;\n}\n\nexport function stringifyQuery(query: Query): string {\n  return `Query(target=${stringifyTarget(queryToTarget(query))}; limitType=${\n    query.limitType\n  })`;\n}\n\n/** Returns whether `doc` matches the constraints of `query`. */\nexport function queryMatches(query: Query, doc: Document): boolean {\n  return (\n    queryMatchesPathAndCollectionGroup(query, doc) &&\n    queryMatchesOrderBy(query, doc) &&\n    queryMatchesFilters(query, doc) &&\n    queryMatchesBounds(query, doc)\n  );\n}\n\nfunction queryMatchesPathAndCollectionGroup(\n  query: Query,\n  doc: Document\n): boolean {\n  const docPath = doc.key.path;\n  if (query.collectionGroup !== null) {\n    // NOTE: this.path is currently always empty since we don't expose Collection\n    // Group queries rooted at a document path yet.\n    return (\n      doc.key.hasCollectionId(query.collectionGroup) &&\n      query.path.isPrefixOf(docPath)\n    );\n  } else if (DocumentKey.isDocumentKey(query.path)) {\n    // exact match for document queries\n    return query.path.isEqual(docPath);\n  } else {\n    // shallow ancestor queries by default\n    return query.path.isImmediateParentOf(docPath);\n  }\n}\n\n/**\n * A document must have a value for every ordering clause in order to show up\n * in the results.\n */\nfunction queryMatchesOrderBy(query: Query, doc: Document): boolean {\n  for (const orderBy of query.explicitOrderBy) {\n    // order by key always matches\n    if (!orderBy.field.isKeyField() && doc.field(orderBy.field) === null) {\n      return false;\n    }\n  }\n  return true;\n}\n\nfunction queryMatchesFilters(query: Query, doc: Document): boolean {\n  for (const filter of query.filters) {\n    if (!filter.matches(doc)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n/** Makes sure a document is within the bounds, if provided. */\nfunction queryMatchesBounds(query: Query, doc: Document): boolean {\n  if (\n    query.startAt &&\n    !sortsBeforeDocument(query.startAt, queryOrderBy(query), doc)\n  ) {\n    return false;\n  }\n  if (\n    query.endAt &&\n    sortsBeforeDocument(query.endAt, queryOrderBy(query), doc)\n  ) {\n    return false;\n  }\n  return true;\n}\n\n/**\n * Returns a new comparator function that can be used to compare two documents\n * based on the Query's ordering constraint.\n */\nexport function newQueryComparator(\n  query: Query\n): (d1: Document, d2: Document) => number {\n  return (d1: Document, d2: Document): number => {\n    let comparedOnKeyField = false;\n    for (const orderBy of queryOrderBy(query)) {\n      const comp = compareDocs(orderBy, d1, d2);\n      if (comp !== 0) {\n        return comp;\n      }\n      comparedOnKeyField = comparedOnKeyField || orderBy.field.isKeyField();\n    }\n    // Assert that we actually compared by key\n    debugAssert(\n      comparedOnKeyField,\n      \"orderBy used that doesn't compare on key field\"\n    );\n    return 0;\n  };\n}\n\nexport abstract class Filter {\n  abstract matches(doc: Document): boolean;\n}\n\nexport const enum Operator {\n  LESS_THAN = '<',\n  LESS_THAN_OR_EQUAL = '<=',\n  EQUAL = '==',\n  NOT_EQUAL = '!=',\n  GREATER_THAN = '>',\n  GREATER_THAN_OR_EQUAL = '>=',\n  ARRAY_CONTAINS = 'array-contains',\n  IN = 'in',\n  NOT_IN = 'not-in',\n  ARRAY_CONTAINS_ANY = 'array-contains-any'\n}\n\nexport class FieldFilter extends Filter {\n  protected constructor(\n    public field: FieldPath,\n    public op: Operator,\n    public value: api.Value\n  ) {\n    super();\n  }\n\n  /**\n   * Creates a filter based on the provided arguments.\n   */\n  static create(field: FieldPath, op: Operator, value: api.Value): FieldFilter {\n    if (field.isKeyField()) {\n      if (op === Operator.IN || op === Operator.NOT_IN) {\n        return this.createKeyFieldInFilter(field, op, value);\n      } else {\n        debugAssert(\n          isReferenceValue(value),\n          'Comparing on key, but filter value not a RefValue'\n        );\n        debugAssert(\n          op !== Operator.ARRAY_CONTAINS && op !== Operator.ARRAY_CONTAINS_ANY,\n          `'${op.toString()}' queries don't make sense on document keys.`\n        );\n        return new KeyFieldFilter(field, op, value);\n      }\n    } else if (isNullValue(value)) {\n      if (op !== Operator.EQUAL && op !== Operator.NOT_EQUAL) {\n        // TODO(ne-queries): Update error message to include != comparison.\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          'Invalid query. Null supports only equality comparisons.'\n        );\n      }\n      return new FieldFilter(field, op, value);\n    } else if (isNanValue(value)) {\n      if (op !== Operator.EQUAL && op !== Operator.NOT_EQUAL) {\n        // TODO(ne-queries): Update error message to include != comparison.\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          'Invalid query. NaN supports only equality comparisons.'\n        );\n      }\n      return new FieldFilter(field, op, value);\n    } else if (op === Operator.ARRAY_CONTAINS) {\n      return new ArrayContainsFilter(field, value);\n    } else if (op === Operator.IN) {\n      debugAssert(\n        isArray(value),\n        'IN filter has invalid value: ' + value.toString()\n      );\n      return new InFilter(field, value);\n    } else if (op === Operator.NOT_IN) {\n      debugAssert(\n        isArray(value),\n        'NOT_IN filter has invalid value: ' + value.toString()\n      );\n      return new NotInFilter(field, value);\n    } else if (op === Operator.ARRAY_CONTAINS_ANY) {\n      debugAssert(\n        isArray(value),\n        'ARRAY_CONTAINS_ANY filter has invalid value: ' + value.toString()\n      );\n      return new ArrayContainsAnyFilter(field, value);\n    } else {\n      return new FieldFilter(field, op, value);\n    }\n  }\n\n  private static createKeyFieldInFilter(\n    field: FieldPath,\n    op: Operator.IN | Operator.NOT_IN,\n    value: api.Value\n  ): FieldFilter {\n    debugAssert(\n      isArray(value),\n      `Comparing on key with ${op.toString()}` +\n        ', but filter value not an ArrayValue'\n    );\n    debugAssert(\n      (value.arrayValue.values || []).every(elem => isReferenceValue(elem)),\n      `Comparing on key with ${op.toString()}` +\n        ', but an array value was not a RefValue'\n    );\n\n    return op === Operator.IN\n      ? new KeyFieldInFilter(field, value)\n      : new KeyFieldNotInFilter(field, value);\n  }\n\n  matches(doc: Document): boolean {\n    const other = doc.field(this.field);\n    // Types do not have to match in NOT_EQUAL filters.\n    if (this.op === Operator.NOT_EQUAL) {\n      return (\n        other !== null &&\n        this.matchesComparison(valueCompare(other!, this.value))\n      );\n    }\n\n    // Only compare types with matching backend order (such as double and int).\n    return (\n      other !== null &&\n      typeOrder(this.value) === typeOrder(other) &&\n      this.matchesComparison(valueCompare(other, this.value))\n    );\n  }\n\n  protected matchesComparison(comparison: number): boolean {\n    switch (this.op) {\n      case Operator.LESS_THAN:\n        return comparison < 0;\n      case Operator.LESS_THAN_OR_EQUAL:\n        return comparison <= 0;\n      case Operator.EQUAL:\n        return comparison === 0;\n      case Operator.NOT_EQUAL:\n        return comparison !== 0;\n      case Operator.GREATER_THAN:\n        return comparison > 0;\n      case Operator.GREATER_THAN_OR_EQUAL:\n        return comparison >= 0;\n      default:\n        return fail('Unknown FieldFilter operator: ' + this.op);\n    }\n  }\n\n  isInequality(): boolean {\n    return (\n      [\n        Operator.LESS_THAN,\n        Operator.LESS_THAN_OR_EQUAL,\n        Operator.GREATER_THAN,\n        Operator.GREATER_THAN_OR_EQUAL,\n        Operator.NOT_EQUAL\n      ].indexOf(this.op) >= 0\n    );\n  }\n}\n\nexport function canonifyFilter(filter: Filter): string {\n  debugAssert(\n    filter instanceof FieldFilter,\n    'canonifyFilter() only supports FieldFilters'\n  );\n  // TODO(b/29183165): Technically, this won't be unique if two values have\n  // the same description, such as the int 3 and the string \"3\". So we should\n  // add the types in here somehow, too.\n  return (\n    filter.field.canonicalString() +\n    filter.op.toString() +\n    canonicalId(filter.value)\n  );\n}\n\nexport function filterEquals(f1: Filter, f2: Filter): boolean {\n  debugAssert(\n    f1 instanceof FieldFilter && f2 instanceof FieldFilter,\n    'Only FieldFilters can be compared'\n  );\n\n  return (\n    f1.op === f2.op &&\n    f1.field.isEqual(f2.field) &&\n    valueEquals(f1.value, f2.value)\n  );\n}\n\n/** Returns a debug description for `filter`. */\nexport function stringifyFilter(filter: Filter): string {\n  debugAssert(\n    filter instanceof FieldFilter,\n    'stringifyFilter() only supports FieldFilters'\n  );\n  return `${filter.field.canonicalString()} ${filter.op} ${canonicalId(\n    filter.value\n  )}`;\n}\n\n/** Filter that matches on key fields (i.e. '__name__'). */\nexport class KeyFieldFilter extends FieldFilter {\n  private readonly key: DocumentKey;\n\n  constructor(field: FieldPath, op: Operator, value: api.Value) {\n    super(field, op, value);\n    debugAssert(\n      isReferenceValue(value),\n      'KeyFieldFilter expects a ReferenceValue'\n    );\n    this.key = DocumentKey.fromName(value.referenceValue);\n  }\n\n  matches(doc: Document): boolean {\n    const comparison = DocumentKey.comparator(doc.key, this.key);\n    return this.matchesComparison(comparison);\n  }\n}\n\n/** Filter that matches on key fields within an array. */\nexport class KeyFieldInFilter extends FieldFilter {\n  private readonly keys: DocumentKey[];\n\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.IN, value);\n    this.keys = extractDocumentKeysFromArrayValue(Operator.IN, value);\n  }\n\n  matches(doc: Document): boolean {\n    return this.keys.some(key => key.isEqual(doc.key));\n  }\n}\n\n/** Filter that matches on key fields not present within an array. */\nexport class KeyFieldNotInFilter extends FieldFilter {\n  private readonly keys: DocumentKey[];\n\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.NOT_IN, value);\n    this.keys = extractDocumentKeysFromArrayValue(Operator.NOT_IN, value);\n  }\n\n  matches(doc: Document): boolean {\n    return !this.keys.some(key => key.isEqual(doc.key));\n  }\n}\n\nfunction extractDocumentKeysFromArrayValue(\n  op: Operator.IN | Operator.NOT_IN,\n  value: api.Value\n): DocumentKey[] {\n  debugAssert(\n    isArray(value),\n    'KeyFieldInFilter/KeyFieldNotInFilter expects an ArrayValue'\n  );\n  return (value.arrayValue?.values || []).map(v => {\n    debugAssert(\n      isReferenceValue(v),\n      `Comparing on key with ${op.toString()}, but an array value was not ` +\n        `a ReferenceValue`\n    );\n    return DocumentKey.fromName(v.referenceValue);\n  });\n}\n\n/** A Filter that implements the array-contains operator. */\nexport class ArrayContainsFilter extends FieldFilter {\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.ARRAY_CONTAINS, value);\n  }\n\n  matches(doc: Document): boolean {\n    const other = doc.field(this.field);\n    return isArray(other) && arrayValueContains(other.arrayValue, this.value);\n  }\n}\n\n/** A Filter that implements the IN operator. */\nexport class InFilter extends FieldFilter {\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.IN, value);\n    debugAssert(isArray(value), 'InFilter expects an ArrayValue');\n  }\n\n  matches(doc: Document): boolean {\n    const other = doc.field(this.field);\n    return other !== null && arrayValueContains(this.value.arrayValue!, other);\n  }\n}\n\n/** A Filter that implements the not-in operator. */\nexport class NotInFilter extends FieldFilter {\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.NOT_IN, value);\n    debugAssert(isArray(value), 'NotInFilter expects an ArrayValue');\n  }\n\n  matches(doc: Document): boolean {\n    const other = doc.field(this.field);\n    return other !== null && !arrayValueContains(this.value.arrayValue!, other);\n  }\n}\n\n/** A Filter that implements the array-contains-any operator. */\nexport class ArrayContainsAnyFilter extends FieldFilter {\n  constructor(field: FieldPath, value: api.Value) {\n    super(field, Operator.ARRAY_CONTAINS_ANY, value);\n    debugAssert(isArray(value), 'ArrayContainsAnyFilter expects an ArrayValue');\n  }\n\n  matches(doc: Document): boolean {\n    const other = doc.field(this.field);\n    if (!isArray(other) || !other.arrayValue.values) {\n      return false;\n    }\n    return other.arrayValue.values.some(val =>\n      arrayValueContains(this.value.arrayValue!, val)\n    );\n  }\n}\n\n/**\n * The direction of sorting in an order by.\n */\nexport const enum Direction {\n  ASCENDING = 'asc',\n  DESCENDING = 'desc'\n}\n\n/**\n * Represents a bound of a query.\n *\n * The bound is specified with the given components representing a position and\n * whether it's just before or just after the position (relative to whatever the\n * query order is).\n *\n * The position represents a logical index position for a query. It's a prefix\n * of values for the (potentially implicit) order by clauses of a query.\n *\n * Bound provides a function to determine whether a document comes before or\n * after a bound. This is influenced by whether the position is just before or\n * just after the provided values.\n */\nexport class Bound {\n  constructor(readonly position: api.Value[], readonly before: boolean) {}\n}\n\nexport function canonifyBound(bound: Bound): string {\n  // TODO(b/29183165): Make this collision robust.\n  return `${bound.before ? 'b' : 'a'}:${bound.position\n    .map(p => canonicalId(p))\n    .join(',')}`;\n}\n\n/**\n * Returns true if a document sorts before a bound using the provided sort\n * order.\n */\nexport function sortsBeforeDocument(\n  bound: Bound,\n  orderBy: OrderBy[],\n  doc: Document\n): boolean {\n  debugAssert(\n    bound.position.length <= orderBy.length,\n    \"Bound has more components than query's orderBy\"\n  );\n  let comparison = 0;\n  for (let i = 0; i < bound.position.length; i++) {\n    const orderByComponent = orderBy[i];\n    const component = bound.position[i];\n    if (orderByComponent.field.isKeyField()) {\n      debugAssert(\n        isReferenceValue(component),\n        'Bound has a non-key value where the key path is being used.'\n      );\n      comparison = DocumentKey.comparator(\n        DocumentKey.fromName(component.referenceValue),\n        doc.key\n      );\n    } else {\n      const docValue = doc.field(orderByComponent.field);\n      debugAssert(\n        docValue !== null,\n        'Field should exist since document matched the orderBy already.'\n      );\n      comparison = valueCompare(component, docValue);\n    }\n    if (orderByComponent.dir === Direction.DESCENDING) {\n      comparison = comparison * -1;\n    }\n    if (comparison !== 0) {\n      break;\n    }\n  }\n  return bound.before ? comparison <= 0 : comparison < 0;\n}\n\nexport function boundEquals(left: Bound | null, right: Bound | null): boolean {\n  if (left === null) {\n    return right === null;\n  } else if (right === null) {\n    return false;\n  }\n\n  if (\n    left.before !== right.before ||\n    left.position.length !== right.position.length\n  ) {\n    return false;\n  }\n  for (let i = 0; i < left.position.length; i++) {\n    const leftPosition = left.position[i];\n    const rightPosition = right.position[i];\n    if (!valueEquals(leftPosition, rightPosition)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n/**\n * An ordering on a field, in some Direction. Direction defaults to ASCENDING.\n */\nexport class OrderBy {\n  constructor(\n    readonly field: FieldPath,\n    readonly dir: Direction = Direction.ASCENDING\n  ) {}\n}\n\nexport function compareDocs(\n  orderBy: OrderBy,\n  d1: Document,\n  d2: Document\n): number {\n  const comparison = orderBy.field.isKeyField()\n    ? DocumentKey.comparator(d1.key, d2.key)\n    : compareDocumentsByField(orderBy.field, d1, d2);\n  switch (orderBy.dir) {\n    case Direction.ASCENDING:\n      return comparison;\n    case Direction.DESCENDING:\n      return -1 * comparison;\n    default:\n      return fail('Unknown direction: ' + orderBy.dir);\n  }\n}\n\nexport function canonifyOrderBy(orderBy: OrderBy): string {\n  // TODO(b/29183165): Make this collision robust.\n  return orderBy.field.canonicalString() + orderBy.dir;\n}\n\nexport function stringifyOrderBy(orderBy: OrderBy): string {\n  return `${orderBy.field.canonicalString()} (${orderBy.dir})`;\n}\n\nexport function orderByEquals(left: OrderBy, right: OrderBy): boolean {\n  return left.dir === right.dir && left.field.isEqual(right.field);\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 { decodeBase64, encodeBase64 } from '../platform/base64';\nimport { primitiveComparator } from './misc';\n\n/**\n * Immutable class that represents a \"proto\" byte string.\n *\n * Proto byte strings can either be Base64-encoded strings or Uint8Arrays when\n * sent on the wire. This class abstracts away this differentiation by holding\n * the proto byte string in a common class that must be converted into a string\n * before being sent as a proto.\n */\nexport class ByteString {\n  static readonly EMPTY_BYTE_STRING = new ByteString('');\n\n  private constructor(private readonly binaryString: string) {}\n\n  static fromBase64String(base64: string): ByteString {\n    const binaryString = decodeBase64(base64);\n    return new ByteString(binaryString);\n  }\n\n  static fromUint8Array(array: Uint8Array): ByteString {\n    const binaryString = binaryStringFromUint8Array(array);\n    return new ByteString(binaryString);\n  }\n\n  toBase64(): string {\n    return encodeBase64(this.binaryString);\n  }\n\n  toUint8Array(): Uint8Array {\n    return uint8ArrayFromBinaryString(this.binaryString);\n  }\n\n  approximateByteSize(): number {\n    return this.binaryString.length * 2;\n  }\n\n  compareTo(other: ByteString): number {\n    return primitiveComparator(this.binaryString, other.binaryString);\n  }\n\n  isEqual(other: ByteString): boolean {\n    return this.binaryString === other.binaryString;\n  }\n}\n\n/**\n * Helper function to convert an Uint8array to a binary string.\n */\nexport function binaryStringFromUint8Array(array: Uint8Array): string {\n  let binaryString = '';\n  for (let i = 0; i < array.length; ++i) {\n    binaryString += String.fromCharCode(array[i]);\n  }\n  return binaryString;\n}\n\n/**\n * Helper function to convert a binary string to an Uint8Array.\n */\nexport function uint8ArrayFromBinaryString(binaryString: string): Uint8Array {\n  const buffer = new Uint8Array(binaryString.length);\n  for (let i = 0; i < binaryString.length; i++) {\n    buffer[i] = binaryString.charCodeAt(i);\n  }\n  return buffer;\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/** Converts a Base64 encoded string to a binary string. */\nexport function decodeBase64(encoded: string): string {\n  return atob(encoded);\n}\n\n/** Converts a binary string to a Base64 encoded string. */\nexport function encodeBase64(raw: string): string {\n  return btoa(raw);\n}\n\n/** True if and only if the Base64 conversion functions are available. */\nexport function isBase64Available(): boolean {\n  return typeof atob !== 'undefined';\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 { fail } from '../util/assert';\nimport { Code } from '../util/error';\nimport { logError } from '../util/log';\n\n/**\n * Error Codes describing the different ways GRPC can fail. These are copied\n * directly from GRPC's sources here:\n *\n * https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h\n *\n * Important! The names of these identifiers matter because the string forms\n * are used for reverse lookups from the webchannel stream. Do NOT change the\n * names of these identifiers or change this into a const enum.\n */\nenum RpcCode {\n  OK = 0,\n  CANCELLED = 1,\n  UNKNOWN = 2,\n  INVALID_ARGUMENT = 3,\n  DEADLINE_EXCEEDED = 4,\n  NOT_FOUND = 5,\n  ALREADY_EXISTS = 6,\n  PERMISSION_DENIED = 7,\n  UNAUTHENTICATED = 16,\n  RESOURCE_EXHAUSTED = 8,\n  FAILED_PRECONDITION = 9,\n  ABORTED = 10,\n  OUT_OF_RANGE = 11,\n  UNIMPLEMENTED = 12,\n  INTERNAL = 13,\n  UNAVAILABLE = 14,\n  DATA_LOSS = 15\n}\n\n/**\n * Determines whether an error code represents a permanent error when received\n * in response to a non-write operation.\n *\n * See isPermanentWriteError for classifying write errors.\n */\nexport function isPermanentError(code: Code): boolean {\n  switch (code) {\n    case Code.OK:\n      return fail('Treated status OK as error');\n    case Code.CANCELLED:\n    case Code.UNKNOWN:\n    case Code.DEADLINE_EXCEEDED:\n    case Code.RESOURCE_EXHAUSTED:\n    case Code.INTERNAL:\n    case Code.UNAVAILABLE:\n    // Unauthenticated means something went wrong with our token and we need\n    // to retry with new credentials which will happen automatically.\n    case Code.UNAUTHENTICATED:\n      return false;\n    case Code.INVALID_ARGUMENT:\n    case Code.NOT_FOUND:\n    case Code.ALREADY_EXISTS:\n    case Code.PERMISSION_DENIED:\n    case Code.FAILED_PRECONDITION:\n    // Aborted might be retried in some scenarios, but that is dependant on\n    // the context and should handled individually by the calling code.\n    // See https://cloud.google.com/apis/design/errors.\n    case Code.ABORTED:\n    case Code.OUT_OF_RANGE:\n    case Code.UNIMPLEMENTED:\n    case Code.DATA_LOSS:\n      return true;\n    default:\n      return fail('Unknown status code: ' + code);\n  }\n}\n\n/**\n * Determines whether an error code represents a permanent error when received\n * in response to a write operation.\n *\n * Write operations must be handled specially because as of b/119437764, ABORTED\n * errors on the write stream should be retried too (even though ABORTED errors\n * are not generally retryable).\n *\n * Note that during the initial handshake on the write stream an ABORTED error\n * signals that we should discard our stream token (i.e. it is permanent). This\n * means a handshake error should be classified with isPermanentError, above.\n */\nexport function isPermanentWriteError(code: Code): boolean {\n  return isPermanentError(code) && code !== Code.ABORTED;\n}\n\n/**\n * Maps an error Code from a GRPC status identifier like 'NOT_FOUND'.\n *\n * @returns The Code equivalent to the given status string or undefined if\n *     there is no match.\n */\nexport function mapCodeFromRpcStatus(status: string): Code | undefined {\n  // lookup by string\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const code: RpcCode = RpcCode[status as any] as any;\n  if (code === undefined) {\n    return undefined;\n  }\n\n  return mapCodeFromRpcCode(code);\n}\n\n/**\n * Maps an error Code from GRPC status code number, like 0, 1, or 14. These\n * are not the same as HTTP status codes.\n *\n * @returns The Code equivalent to the given GRPC status code. Fails if there\n *     is no match.\n */\nexport function mapCodeFromRpcCode(code: number | undefined): Code {\n  if (code === undefined) {\n    // This shouldn't normally happen, but in certain error cases (like trying\n    // to send invalid proto messages) we may get an error with no GRPC code.\n    logError('GRPC error has no .code');\n    return Code.UNKNOWN;\n  }\n\n  switch (code) {\n    case RpcCode.OK:\n      return Code.OK;\n    case RpcCode.CANCELLED:\n      return Code.CANCELLED;\n    case RpcCode.UNKNOWN:\n      return Code.UNKNOWN;\n    case RpcCode.DEADLINE_EXCEEDED:\n      return Code.DEADLINE_EXCEEDED;\n    case RpcCode.RESOURCE_EXHAUSTED:\n      return Code.RESOURCE_EXHAUSTED;\n    case RpcCode.INTERNAL:\n      return Code.INTERNAL;\n    case RpcCode.UNAVAILABLE:\n      return Code.UNAVAILABLE;\n    case RpcCode.UNAUTHENTICATED:\n      return Code.UNAUTHENTICATED;\n    case RpcCode.INVALID_ARGUMENT:\n      return Code.INVALID_ARGUMENT;\n    case RpcCode.NOT_FOUND:\n      return Code.NOT_FOUND;\n    case RpcCode.ALREADY_EXISTS:\n      return Code.ALREADY_EXISTS;\n    case RpcCode.PERMISSION_DENIED:\n      return Code.PERMISSION_DENIED;\n    case RpcCode.FAILED_PRECONDITION:\n      return Code.FAILED_PRECONDITION;\n    case RpcCode.ABORTED:\n      return Code.ABORTED;\n    case RpcCode.OUT_OF_RANGE:\n      return Code.OUT_OF_RANGE;\n    case RpcCode.UNIMPLEMENTED:\n      return Code.UNIMPLEMENTED;\n    case RpcCode.DATA_LOSS:\n      return Code.DATA_LOSS;\n    default:\n      return fail('Unknown status code: ' + code);\n  }\n}\n\n/**\n * Maps an RPC code from a Code. This is the reverse operation from\n * mapCodeFromRpcCode and should really only be used in tests.\n */\nexport function mapRpcCodeFromCode(code: Code | undefined): number {\n  if (code === undefined) {\n    return RpcCode.OK;\n  }\n\n  switch (code) {\n    case Code.OK:\n      return RpcCode.OK;\n    case Code.CANCELLED:\n      return RpcCode.CANCELLED;\n    case Code.UNKNOWN:\n      return RpcCode.UNKNOWN;\n    case Code.DEADLINE_EXCEEDED:\n      return RpcCode.DEADLINE_EXCEEDED;\n    case Code.RESOURCE_EXHAUSTED:\n      return RpcCode.RESOURCE_EXHAUSTED;\n    case Code.INTERNAL:\n      return RpcCode.INTERNAL;\n    case Code.UNAVAILABLE:\n      return RpcCode.UNAVAILABLE;\n    case Code.UNAUTHENTICATED:\n      return RpcCode.UNAUTHENTICATED;\n    case Code.INVALID_ARGUMENT:\n      return RpcCode.INVALID_ARGUMENT;\n    case Code.NOT_FOUND:\n      return RpcCode.NOT_FOUND;\n    case Code.ALREADY_EXISTS:\n      return RpcCode.ALREADY_EXISTS;\n    case Code.PERMISSION_DENIED:\n      return RpcCode.PERMISSION_DENIED;\n    case Code.FAILED_PRECONDITION:\n      return RpcCode.FAILED_PRECONDITION;\n    case Code.ABORTED:\n      return RpcCode.ABORTED;\n    case Code.OUT_OF_RANGE:\n      return RpcCode.OUT_OF_RANGE;\n    case Code.UNIMPLEMENTED:\n      return RpcCode.UNIMPLEMENTED;\n    case Code.DATA_LOSS:\n      return RpcCode.DATA_LOSS;\n    default:\n      return fail('Unknown status code: ' + code);\n  }\n}\n\n/**\n * Converts an HTTP Status Code to the equivalent error code.\n *\n * @param status An HTTP Status Code, like 200, 404, 503, etc.\n * @returns The equivalent Code. Unknown status codes are mapped to\n *     Code.UNKNOWN.\n */\nexport function mapCodeFromHttpStatus(status?: number): Code {\n  if (status === undefined) {\n    logError('RPC_ERROR', 'HTTP error has no status');\n    return Code.UNKNOWN;\n  }\n\n  // The canonical error codes for Google APIs [1] specify mapping onto HTTP\n  // status codes but the mapping is not bijective. In each case of ambiguity\n  // this function chooses a primary error.\n  //\n  // [1]\n  // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto\n  switch (status) {\n    case 200: // OK\n      return Code.OK;\n\n    case 400: // Bad Request\n      return Code.FAILED_PRECONDITION;\n    // Other possibilities based on the forward mapping\n    // return Code.INVALID_ARGUMENT;\n    // return Code.OUT_OF_RANGE;\n\n    case 401: // Unauthorized\n      return Code.UNAUTHENTICATED;\n\n    case 403: // Forbidden\n      return Code.PERMISSION_DENIED;\n\n    case 404: // Not Found\n      return Code.NOT_FOUND;\n\n    case 409: // Conflict\n      return Code.ABORTED;\n    // Other possibilities:\n    // return Code.ALREADY_EXISTS;\n\n    case 416: // Range Not Satisfiable\n      return Code.OUT_OF_RANGE;\n\n    case 429: // Too Many Requests\n      return Code.RESOURCE_EXHAUSTED;\n\n    case 499: // Client Closed Request\n      return Code.CANCELLED;\n\n    case 500: // Internal Server Error\n      return Code.UNKNOWN;\n    // Other possibilities:\n    // return Code.INTERNAL;\n    // return Code.DATA_LOSS;\n\n    case 501: // Unimplemented\n      return Code.UNIMPLEMENTED;\n\n    case 503: // Service Unavailable\n      return Code.UNAVAILABLE;\n\n    case 504: // Gateway Timeout\n      return Code.DEADLINE_EXCEEDED;\n\n    default:\n      if (status >= 200 && status < 300) {\n        return Code.OK;\n      }\n      if (status >= 400 && status < 500) {\n        return Code.FAILED_PRECONDITION;\n      }\n      if (status >= 500 && status < 600) {\n        return Code.INTERNAL;\n      }\n      return Code.UNKNOWN;\n  }\n}\n\n/**\n * Converts an HTTP response's error status to the equivalent error code.\n *\n * @param status An HTTP error response status (\"FAILED_PRECONDITION\",\n * \"UNKNOWN\", etc.)\n * @returns The equivalent Code. Non-matching responses are mapped to\n *     Code.UNKNOWN.\n */\nexport function mapCodeFromHttpResponseErrorStatus(status: string): Code {\n  const serverError = status.toLowerCase().replace('_', '-');\n  return Object.values(Code).indexOf(serverError as Code) >= 0\n    ? (serverError as Code)\n    : Code.UNKNOWN;\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { Target } from '../core/target';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { ByteString } from '../util/byte_string';\n\n/** An enumeration of the different purposes we have for targets. */\nexport const enum TargetPurpose {\n  /** A regular, normal query target. */\n  Listen,\n\n  /**\n   * The query target was used to refill a query after an existence filter mismatch.\n   */\n  ExistenceFilterMismatch,\n\n  /** The query target was used to resolve a limbo document. */\n  LimboResolution\n}\n\n/**\n * An immutable set of metadata that the local store tracks for each target.\n */\nexport class TargetData {\n  constructor(\n    /** The target being listened to. */\n    readonly target: Target,\n    /**\n     * The target ID to which the target corresponds; Assigned by the\n     * LocalStore for user listens and by the SyncEngine for limbo watches.\n     */\n    readonly targetId: TargetId,\n    /** The purpose of the target. */\n    readonly purpose: TargetPurpose,\n    /**\n     * The sequence number of the last transaction during which this target data\n     * was modified.\n     */\n    readonly sequenceNumber: ListenSequenceNumber,\n    /** The latest snapshot version seen for this target. */\n    readonly snapshotVersion: SnapshotVersion = SnapshotVersion.min(),\n    /**\n     * The maximum snapshot version at which the associated view\n     * contained no limbo documents.\n     */\n    readonly lastLimboFreeSnapshotVersion: SnapshotVersion = SnapshotVersion.min(),\n    /**\n     * An opaque, server-assigned token that allows watching a target to be\n     * resumed after disconnecting without retransmitting all the data that\n     * matches the target. The resume token essentially identifies a point in\n     * time from which the server should resume sending results.\n     */\n    readonly resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING\n  ) {}\n\n  /** Creates a new target data instance with an updated sequence number. */\n  withSequenceNumber(sequenceNumber: number): TargetData {\n    return new TargetData(\n      this.target,\n      this.targetId,\n      this.purpose,\n      sequenceNumber,\n      this.snapshotVersion,\n      this.lastLimboFreeSnapshotVersion,\n      this.resumeToken\n    );\n  }\n\n  /**\n   * Creates a new target data instance with an updated resume token and\n   * snapshot version.\n   */\n  withResumeToken(\n    resumeToken: ByteString,\n    snapshotVersion: SnapshotVersion\n  ): TargetData {\n    return new TargetData(\n      this.target,\n      this.targetId,\n      this.purpose,\n      this.sequenceNumber,\n      snapshotVersion,\n      this.lastLimboFreeSnapshotVersion,\n      resumeToken\n    );\n  }\n\n  /**\n   * Creates a new target data instance with an updated last limbo free\n   * snapshot version number.\n   */\n  withLastLimboFreeSnapshotVersion(\n    lastLimboFreeSnapshotVersion: SnapshotVersion\n  ): TargetData {\n    return new TargetData(\n      this.target,\n      this.targetId,\n      this.purpose,\n      this.sequenceNumber,\n      this.snapshotVersion,\n      lastLimboFreeSnapshotVersion,\n      this.resumeToken\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\nexport class ExistenceFilter {\n  // TODO(b/33078163): just use simplest form of existence filter for now\n  constructor(public count: number) {}\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 { debugAssert, fail } from './assert';\n\n/*\n * Implementation of an immutable SortedMap using a Left-leaning\n * Red-Black Tree, adapted from the implementation in Mugs\n * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen\n * (mads379@gmail.com).\n *\n * Original paper on Left-leaning Red-Black Trees:\n *   http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf\n *\n * Invariant 1: No red node has a red child\n * Invariant 2: Every leaf path has the same number of black nodes\n * Invariant 3: Only the left child can be red (left leaning)\n */\n\nexport type Comparator<K> = (key1: K, key2: K) => number;\n\nexport interface Entry<K, V> {\n  key: K;\n  value: V;\n}\n\n// An immutable sorted map implementation, based on a Left-leaning Red-Black\n// tree.\nexport class SortedMap<K, V> {\n  // visible for testing\n  root: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n\n  constructor(\n    public comparator: Comparator<K>,\n    root?: LLRBNode<K, V> | LLRBEmptyNode<K, V>\n  ) {\n    this.root = root ? root : LLRBNode.EMPTY;\n  }\n\n  // Returns a copy of the map, with the specified key/value added or replaced.\n  insert(key: K, value: V): SortedMap<K, V> {\n    return new SortedMap<K, V>(\n      this.comparator,\n      this.root\n        .insert(key, value, this.comparator)\n        .copy(null, null, LLRBNode.BLACK, null, null)\n    );\n  }\n\n  // Returns a copy of the map, with the specified key removed.\n  remove(key: K): SortedMap<K, V> {\n    return new SortedMap<K, V>(\n      this.comparator,\n      this.root\n        .remove(key, this.comparator)\n        .copy(null, null, LLRBNode.BLACK, null, null)\n    );\n  }\n\n  // Returns the value of the node with the given key, or null.\n  get(key: K): V | null {\n    let node = this.root;\n    while (!node.isEmpty()) {\n      const cmp = this.comparator(key, node.key);\n      if (cmp === 0) {\n        return node.value;\n      } else if (cmp < 0) {\n        node = node.left;\n      } else if (cmp > 0) {\n        node = node.right;\n      }\n    }\n    return null;\n  }\n\n  // Returns the index of the element in this sorted map, or -1 if it doesn't\n  // exist.\n  indexOf(key: K): number {\n    // Number of nodes that were pruned when descending right\n    let prunedNodes = 0;\n    let node = this.root;\n    while (!node.isEmpty()) {\n      const cmp = this.comparator(key, node.key);\n      if (cmp === 0) {\n        return prunedNodes + node.left.size;\n      } else if (cmp < 0) {\n        node = node.left;\n      } else {\n        // Count all nodes left of the node plus the node itself\n        prunedNodes += node.left.size + 1;\n        node = node.right;\n      }\n    }\n    // Node not found\n    return -1;\n  }\n\n  isEmpty(): boolean {\n    return this.root.isEmpty();\n  }\n\n  // Returns the total number of nodes in the map.\n  get size(): number {\n    return this.root.size;\n  }\n\n  // Returns the minimum key in the map.\n  minKey(): K | null {\n    return this.root.minKey();\n  }\n\n  // Returns the maximum key in the map.\n  maxKey(): K | null {\n    return this.root.maxKey();\n  }\n\n  // Traverses the map in key order and calls the specified action function\n  // for each key/value pair. If action returns true, traversal is aborted.\n  // Returns the first truthy value returned by action, or the last falsey\n  // value returned by action.\n  inorderTraversal<T>(action: (k: K, v: V) => T): T {\n    return (this.root as LLRBNode<K, V>).inorderTraversal(action);\n  }\n\n  forEach(fn: (k: K, v: V) => void): void {\n    this.inorderTraversal((k, v) => {\n      fn(k, v);\n      return false;\n    });\n  }\n\n  toString(): string {\n    const descriptions: string[] = [];\n    this.inorderTraversal((k, v) => {\n      descriptions.push(`${k}:${v}`);\n      return false;\n    });\n    return `{${descriptions.join(', ')}}`;\n  }\n\n  // Traverses the map in reverse key order and calls the specified action\n  // function for each key/value pair. If action returns true, traversal is\n  // aborted.\n  // Returns the first truthy value returned by action, or the last falsey\n  // value returned by action.\n  reverseTraversal<T>(action: (k: K, v: V) => T): T {\n    return (this.root as LLRBNode<K, V>).reverseTraversal(action);\n  }\n\n  // Returns an iterator over the SortedMap.\n  getIterator(): SortedMapIterator<K, V> {\n    return new SortedMapIterator<K, V>(this.root, null, this.comparator, false);\n  }\n\n  getIteratorFrom(key: K): SortedMapIterator<K, V> {\n    return new SortedMapIterator<K, V>(this.root, key, this.comparator, false);\n  }\n\n  getReverseIterator(): SortedMapIterator<K, V> {\n    return new SortedMapIterator<K, V>(this.root, null, this.comparator, true);\n  }\n\n  getReverseIteratorFrom(key: K): SortedMapIterator<K, V> {\n    return new SortedMapIterator<K, V>(this.root, key, this.comparator, true);\n  }\n} // end SortedMap\n\n// An iterator over an LLRBNode.\nexport class SortedMapIterator<K, V> {\n  private isReverse: boolean;\n  private nodeStack: Array<LLRBNode<K, V> | LLRBEmptyNode<K, V>>;\n\n  constructor(\n    node: LLRBNode<K, V> | LLRBEmptyNode<K, V>,\n    startKey: K | null,\n    comparator: Comparator<K>,\n    isReverse: boolean\n  ) {\n    this.isReverse = isReverse;\n    this.nodeStack = [];\n\n    let cmp = 1;\n    while (!node.isEmpty()) {\n      cmp = startKey ? comparator(node.key, startKey) : 1;\n      // flip the comparison if we're going in reverse\n      if (isReverse) {\n        cmp *= -1;\n      }\n\n      if (cmp < 0) {\n        // This node is less than our start key. ignore it\n        if (this.isReverse) {\n          node = node.left;\n        } else {\n          node = node.right;\n        }\n      } else if (cmp === 0) {\n        // This node is exactly equal to our start key. Push it on the stack,\n        // but stop iterating;\n        this.nodeStack.push(node);\n        break;\n      } else {\n        // This node is greater than our start key, add it to the stack and move\n        // to the next one\n        this.nodeStack.push(node);\n        if (this.isReverse) {\n          node = node.right;\n        } else {\n          node = node.left;\n        }\n      }\n    }\n  }\n\n  getNext(): Entry<K, V> {\n    debugAssert(\n      this.nodeStack.length > 0,\n      'getNext() called on iterator when hasNext() is false.'\n    );\n\n    let node = this.nodeStack.pop()!;\n    const result = { key: node.key, value: node.value };\n\n    if (this.isReverse) {\n      node = node.left;\n      while (!node.isEmpty()) {\n        this.nodeStack.push(node);\n        node = node.right;\n      }\n    } else {\n      node = node.right;\n      while (!node.isEmpty()) {\n        this.nodeStack.push(node);\n        node = node.left;\n      }\n    }\n\n    return result;\n  }\n\n  hasNext(): boolean {\n    return this.nodeStack.length > 0;\n  }\n\n  peek(): Entry<K, V> | null {\n    if (this.nodeStack.length === 0) {\n      return null;\n    }\n\n    const node = this.nodeStack[this.nodeStack.length - 1];\n    return { key: node.key, value: node.value };\n  }\n} // end SortedMapIterator\n\n// Represents a node in a Left-leaning Red-Black tree.\nexport class LLRBNode<K, V> {\n  readonly color: boolean;\n  readonly left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n  readonly right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n  readonly size: number;\n\n  // Empty node is shared between all LLRB trees.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  static EMPTY: LLRBEmptyNode<any, any> = null as any;\n\n  static RED = true;\n  static BLACK = false;\n\n  constructor(\n    public key: K,\n    public value: V,\n    color?: boolean,\n    left?: LLRBNode<K, V> | LLRBEmptyNode<K, V>,\n    right?: LLRBNode<K, V> | LLRBEmptyNode<K, V>\n  ) {\n    this.color = color != null ? color : LLRBNode.RED;\n    this.left = left != null ? left : LLRBNode.EMPTY;\n    this.right = right != null ? right : LLRBNode.EMPTY;\n    this.size = this.left.size + 1 + this.right.size;\n  }\n\n  // Returns a copy of the current node, optionally replacing pieces of it.\n  copy(\n    key: K | null,\n    value: V | null,\n    color: boolean | null,\n    left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n    right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n  ): LLRBNode<K, V> {\n    return new LLRBNode<K, V>(\n      key != null ? key : this.key,\n      value != null ? value : this.value,\n      color != null ? color : this.color,\n      left != null ? left : this.left,\n      right != null ? right : this.right\n    );\n  }\n\n  isEmpty(): boolean {\n    return false;\n  }\n\n  // Traverses the tree in key order and calls the specified action function\n  // for each node. If action returns true, traversal is aborted.\n  // Returns the first truthy value returned by action, or the last falsey\n  // value returned by action.\n  inorderTraversal<T>(action: (k: K, v: V) => T): T {\n    return (\n      (this.left as LLRBNode<K, V>).inorderTraversal(action) ||\n      action(this.key, this.value) ||\n      (this.right as LLRBNode<K, V>).inorderTraversal(action)\n    );\n  }\n\n  // Traverses the tree in reverse key order and calls the specified action\n  // function for each node. If action returns true, traversal is aborted.\n  // Returns the first truthy value returned by action, or the last falsey\n  // value returned by action.\n  reverseTraversal<T>(action: (k: K, v: V) => T): T {\n    return (\n      (this.right as LLRBNode<K, V>).reverseTraversal(action) ||\n      action(this.key, this.value) ||\n      (this.left as LLRBNode<K, V>).reverseTraversal(action)\n    );\n  }\n\n  // Returns the minimum node in the tree.\n  private min(): LLRBNode<K, V> {\n    if (this.left.isEmpty()) {\n      return this;\n    } else {\n      return (this.left as LLRBNode<K, V>).min();\n    }\n  }\n\n  // Returns the maximum key in the tree.\n  minKey(): K | null {\n    return this.min().key;\n  }\n\n  // Returns the maximum key in the tree.\n  maxKey(): K | null {\n    if (this.right.isEmpty()) {\n      return this.key;\n    } else {\n      return this.right.maxKey();\n    }\n  }\n\n  // Returns new tree, with the key/value added.\n  insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n    let n: LLRBNode<K, V> = this;\n    const cmp = comparator(key, n.key);\n    if (cmp < 0) {\n      n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);\n    } else if (cmp === 0) {\n      n = n.copy(null, value, null, null, null);\n    } else {\n      n = n.copy(\n        null,\n        null,\n        null,\n        null,\n        n.right.insert(key, value, comparator)\n      );\n    }\n    return n.fixUp();\n  }\n\n  private removeMin(): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n    if (this.left.isEmpty()) {\n      return LLRBNode.EMPTY;\n    }\n    let n: LLRBNode<K, V> = this;\n    if (!n.left.isRed() && !n.left.left.isRed()) {\n      n = n.moveRedLeft();\n    }\n    n = n.copy(null, null, null, (n.left as LLRBNode<K, V>).removeMin(), null);\n    return n.fixUp();\n  }\n\n  // Returns new tree, with the specified item removed.\n  remove(\n    key: K,\n    comparator: Comparator<K>\n  ): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n    let smallest: LLRBNode<K, V>;\n    let n: LLRBNode<K, V> = this;\n    if (comparator(key, n.key) < 0) {\n      if (!n.left.isEmpty() && !n.left.isRed() && !n.left.left.isRed()) {\n        n = n.moveRedLeft();\n      }\n      n = n.copy(null, null, null, n.left.remove(key, comparator), null);\n    } else {\n      if (n.left.isRed()) {\n        n = n.rotateRight();\n      }\n      if (!n.right.isEmpty() && !n.right.isRed() && !n.right.left.isRed()) {\n        n = n.moveRedRight();\n      }\n      if (comparator(key, n.key) === 0) {\n        if (n.right.isEmpty()) {\n          return LLRBNode.EMPTY;\n        } else {\n          smallest = (n.right as LLRBNode<K, V>).min();\n          n = n.copy(\n            smallest.key,\n            smallest.value,\n            null,\n            null,\n            (n.right as LLRBNode<K, V>).removeMin()\n          );\n        }\n      }\n      n = n.copy(null, null, null, null, n.right.remove(key, comparator));\n    }\n    return n.fixUp();\n  }\n\n  isRed(): boolean {\n    return this.color;\n  }\n\n  // Returns new tree after performing any needed rotations.\n  private fixUp(): LLRBNode<K, V> {\n    let n: LLRBNode<K, V> = this;\n    if (n.right.isRed() && !n.left.isRed()) {\n      n = n.rotateLeft();\n    }\n    if (n.left.isRed() && n.left.left.isRed()) {\n      n = n.rotateRight();\n    }\n    if (n.left.isRed() && n.right.isRed()) {\n      n = n.colorFlip();\n    }\n    return n;\n  }\n\n  private moveRedLeft(): LLRBNode<K, V> {\n    let n = this.colorFlip();\n    if (n.right.left.isRed()) {\n      n = n.copy(\n        null,\n        null,\n        null,\n        null,\n        (n.right as LLRBNode<K, V>).rotateRight()\n      );\n      n = n.rotateLeft();\n      n = n.colorFlip();\n    }\n    return n;\n  }\n\n  private moveRedRight(): LLRBNode<K, V> {\n    let n = this.colorFlip();\n    if (n.left.left.isRed()) {\n      n = n.rotateRight();\n      n = n.colorFlip();\n    }\n    return n;\n  }\n\n  private rotateLeft(): LLRBNode<K, V> {\n    const nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\n    return (this.right as LLRBNode<K, V>).copy(\n      null,\n      null,\n      this.color,\n      nl,\n      null\n    );\n  }\n\n  private rotateRight(): LLRBNode<K, V> {\n    const nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\n    return (this.left as LLRBNode<K, V>).copy(null, null, this.color, null, nr);\n  }\n\n  private colorFlip(): LLRBNode<K, V> {\n    const left = this.left.copy(null, null, !this.left.color, null, null);\n    const right = this.right.copy(null, null, !this.right.color, null, null);\n    return this.copy(null, null, !this.color, left, right);\n  }\n\n  // For testing.\n  checkMaxDepth(): boolean {\n    const blackDepth = this.check();\n    if (Math.pow(2.0, blackDepth) <= this.size + 1) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  // In a balanced RB tree, the black-depth (number of black nodes) from root to\n  // leaves is equal on both sides.  This function verifies that or asserts.\n  protected check(): number {\n    if (this.isRed() && this.left.isRed()) {\n      throw fail('Red node has red child(' + this.key + ',' + this.value + ')');\n    }\n    if (this.right.isRed()) {\n      throw fail('Right child of (' + this.key + ',' + this.value + ') is red');\n    }\n    const blackDepth = (this.left as LLRBNode<K, V>).check();\n    if (blackDepth !== (this.right as LLRBNode<K, V>).check()) {\n      throw fail('Black depths differ');\n    } else {\n      return blackDepth + (this.isRed() ? 0 : 1);\n    }\n  }\n} // end LLRBNode\n\n// Represents an empty node (a leaf node in the Red-Black Tree).\nexport class LLRBEmptyNode<K, V> {\n  get key(): never {\n    throw fail('LLRBEmptyNode has no key.');\n  }\n  get value(): never {\n    throw fail('LLRBEmptyNode has no value.');\n  }\n  get color(): never {\n    throw fail('LLRBEmptyNode has no color.');\n  }\n  get left(): never {\n    throw fail('LLRBEmptyNode has no left child.');\n  }\n  get right(): never {\n    throw fail('LLRBEmptyNode has no right child.');\n  }\n  size = 0;\n\n  // Returns a copy of the current node.\n  copy(\n    key: K | null,\n    value: V | null,\n    color: boolean | null,\n    left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n    right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n  ): LLRBEmptyNode<K, V> {\n    return this;\n  }\n\n  // Returns a copy of the tree, with the specified key/value added.\n  insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n    return new LLRBNode<K, V>(key, value);\n  }\n\n  // Returns a copy of the tree, with the specified key removed.\n  remove(key: K, comparator: Comparator<K>): LLRBEmptyNode<K, V> {\n    return this;\n  }\n\n  isEmpty(): boolean {\n    return true;\n  }\n\n  inorderTraversal(action: (k: K, v: V) => boolean): boolean {\n    return false;\n  }\n\n  reverseTraversal(action: (k: K, v: V) => boolean): boolean {\n    return false;\n  }\n\n  minKey(): K | null {\n    return null;\n  }\n\n  maxKey(): K | null {\n    return null;\n  }\n\n  isRed(): boolean {\n    return false;\n  }\n\n  // For testing.\n  checkMaxDepth(): boolean {\n    return true;\n  }\n\n  protected check(): 0 {\n    return 0;\n  }\n} // end LLRBEmptyNode\n\nLLRBNode.EMPTY = new LLRBEmptyNode<unknown, unknown>();\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 { SortedMap, SortedMapIterator } from './sorted_map';\n\n/**\n * SortedSet is an immutable (copy-on-write) collection that holds elements\n * in order specified by the provided comparator.\n *\n * NOTE: if provided comparator returns 0 for two elements, we consider them to\n * be equal!\n */\nexport class SortedSet<T> {\n  private data: SortedMap<T, boolean>;\n\n  constructor(private comparator: (left: T, right: T) => number) {\n    this.data = new SortedMap<T, boolean>(this.comparator);\n  }\n\n  has(elem: T): boolean {\n    return this.data.get(elem) !== null;\n  }\n\n  first(): T | null {\n    return this.data.minKey();\n  }\n\n  last(): T | null {\n    return this.data.maxKey();\n  }\n\n  get size(): number {\n    return this.data.size;\n  }\n\n  indexOf(elem: T): number {\n    return this.data.indexOf(elem);\n  }\n\n  /** Iterates elements in order defined by \"comparator\" */\n  forEach(cb: (elem: T) => void): void {\n    this.data.inorderTraversal((k: T, v: boolean) => {\n      cb(k);\n      return false;\n    });\n  }\n\n  /** Iterates over `elem`s such that: range[0] <= elem < range[1]. */\n  forEachInRange(range: [T, T], cb: (elem: T) => void): void {\n    const iter = this.data.getIteratorFrom(range[0]);\n    while (iter.hasNext()) {\n      const elem = iter.getNext();\n      if (this.comparator(elem.key, range[1]) >= 0) {\n        return;\n      }\n      cb(elem.key);\n    }\n  }\n\n  /**\n   * Iterates over `elem`s such that: start <= elem until false is returned.\n   */\n  forEachWhile(cb: (elem: T) => boolean, start?: T): void {\n    let iter: SortedMapIterator<T, boolean>;\n    if (start !== undefined) {\n      iter = this.data.getIteratorFrom(start);\n    } else {\n      iter = this.data.getIterator();\n    }\n    while (iter.hasNext()) {\n      const elem = iter.getNext();\n      const result = cb(elem.key);\n      if (!result) {\n        return;\n      }\n    }\n  }\n\n  /** Finds the least element greater than or equal to `elem`. */\n  firstAfterOrEqual(elem: T): T | null {\n    const iter = this.data.getIteratorFrom(elem);\n    return iter.hasNext() ? iter.getNext().key : null;\n  }\n\n  getIterator(): SortedSetIterator<T> {\n    return new SortedSetIterator<T>(this.data.getIterator());\n  }\n\n  getIteratorFrom(key: T): SortedSetIterator<T> {\n    return new SortedSetIterator<T>(this.data.getIteratorFrom(key));\n  }\n\n  /** Inserts or updates an element */\n  add(elem: T): SortedSet<T> {\n    return this.copy(this.data.remove(elem).insert(elem, true));\n  }\n\n  /** Deletes an element */\n  delete(elem: T): SortedSet<T> {\n    if (!this.has(elem)) {\n      return this;\n    }\n    return this.copy(this.data.remove(elem));\n  }\n\n  isEmpty(): boolean {\n    return this.data.isEmpty();\n  }\n\n  unionWith(other: SortedSet<T>): SortedSet<T> {\n    let result: SortedSet<T> = this;\n\n    // Make sure `result` always refers to the larger one of the two sets.\n    if (result.size < other.size) {\n      result = other;\n      other = this;\n    }\n\n    other.forEach(elem => {\n      result = result.add(elem);\n    });\n    return result;\n  }\n\n  isEqual(other: SortedSet<T>): boolean {\n    if (!(other instanceof SortedSet)) {\n      return false;\n    }\n    if (this.size !== other.size) {\n      return false;\n    }\n\n    const thisIt = this.data.getIterator();\n    const otherIt = other.data.getIterator();\n    while (thisIt.hasNext()) {\n      const thisElem = thisIt.getNext().key;\n      const otherElem = otherIt.getNext().key;\n      if (this.comparator(thisElem, otherElem) !== 0) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  toArray(): T[] {\n    const res: T[] = [];\n    this.forEach(targetId => {\n      res.push(targetId);\n    });\n    return res;\n  }\n\n  toString(): string {\n    const result: T[] = [];\n    this.forEach(elem => result.push(elem));\n    return 'SortedSet(' + result.toString() + ')';\n  }\n\n  private copy(data: SortedMap<T, boolean>): SortedSet<T> {\n    const result = new SortedSet(this.comparator);\n    result.data = data;\n    return result;\n  }\n}\n\nexport class SortedSetIterator<T> {\n  constructor(private iter: SortedMapIterator<T, boolean>) {}\n\n  getNext(): T {\n    return this.iter.getNext().key;\n  }\n\n  hasNext(): boolean {\n    return this.iter.hasNext();\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { TargetId } from '../core/types';\nimport { primitiveComparator } from '../util/misc';\nimport { Document, MaybeDocument } from './document';\nimport { DocumentKey } from './document_key';\n\n/** Miscellaneous collection types / constants. */\nexport interface DocumentSizeEntry {\n  maybeDocument: MaybeDocument;\n  size: number;\n}\n\nexport type MaybeDocumentMap = SortedMap<DocumentKey, MaybeDocument>;\nconst EMPTY_MAYBE_DOCUMENT_MAP = new SortedMap<DocumentKey, MaybeDocument>(\n  DocumentKey.comparator\n);\nexport function maybeDocumentMap(): MaybeDocumentMap {\n  return EMPTY_MAYBE_DOCUMENT_MAP;\n}\n\nexport type NullableMaybeDocumentMap = SortedMap<\n  DocumentKey,\n  MaybeDocument | null\n>;\n\nexport function nullableMaybeDocumentMap(): NullableMaybeDocumentMap {\n  return maybeDocumentMap();\n}\n\nexport interface DocumentSizeEntries {\n  maybeDocuments: NullableMaybeDocumentMap;\n  sizeMap: SortedMap<DocumentKey, number>;\n}\n\nexport type DocumentMap = SortedMap<DocumentKey, Document>;\nconst EMPTY_DOCUMENT_MAP = new SortedMap<DocumentKey, Document>(\n  DocumentKey.comparator\n);\nexport function documentMap(): DocumentMap {\n  return EMPTY_DOCUMENT_MAP;\n}\n\nexport type DocumentVersionMap = SortedMap<DocumentKey, SnapshotVersion>;\nconst EMPTY_DOCUMENT_VERSION_MAP = new SortedMap<DocumentKey, SnapshotVersion>(\n  DocumentKey.comparator\n);\nexport function documentVersionMap(): DocumentVersionMap {\n  return EMPTY_DOCUMENT_VERSION_MAP;\n}\n\nexport type DocumentKeySet = SortedSet<DocumentKey>;\nconst EMPTY_DOCUMENT_KEY_SET = new SortedSet(DocumentKey.comparator);\nexport function documentKeySet(...keys: DocumentKey[]): DocumentKeySet {\n  let set = EMPTY_DOCUMENT_KEY_SET;\n  for (const key of keys) {\n    set = set.add(key);\n  }\n  return set;\n}\n\nexport type TargetIdSet = SortedSet<TargetId>;\nconst EMPTY_TARGET_ID_SET = new SortedSet<TargetId>(primitiveComparator);\nexport function targetIdSet(): SortedSet<TargetId> {\n  return EMPTY_TARGET_ID_SET;\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 { SortedMap } from '../util/sorted_map';\n\nimport { documentMap } from './collections';\nimport { Document } from './document';\nimport { DocumentComparator } from './document_comparator';\nimport { DocumentKey } from './document_key';\n\n/**\n * DocumentSet is an immutable (copy-on-write) collection that holds documents\n * in order specified by the provided comparator. We always add a document key\n * comparator on top of what is provided to guarantee document equality based on\n * the key.\n */\n\nexport class DocumentSet {\n  /**\n   * Returns an empty copy of the existing DocumentSet, using the same\n   * comparator.\n   */\n  static emptySet(oldSet: DocumentSet): DocumentSet {\n    return new DocumentSet(oldSet.comparator);\n  }\n\n  private comparator: DocumentComparator;\n  private keyedMap: SortedMap<DocumentKey, Document>;\n  private sortedSet: SortedMap<Document, null>;\n\n  /** The default ordering is by key if the comparator is omitted */\n  constructor(comp?: DocumentComparator) {\n    // We are adding document key comparator to the end as it's the only\n    // guaranteed unique property of a document.\n    if (comp) {\n      this.comparator = (d1: Document, d2: Document) =>\n        comp(d1, d2) || DocumentKey.comparator(d1.key, d2.key);\n    } else {\n      this.comparator = (d1: Document, d2: Document) =>\n        DocumentKey.comparator(d1.key, d2.key);\n    }\n\n    this.keyedMap = documentMap();\n    this.sortedSet = new SortedMap<Document, null>(this.comparator);\n  }\n\n  has(key: DocumentKey): boolean {\n    return this.keyedMap.get(key) != null;\n  }\n\n  get(key: DocumentKey): Document | null {\n    return this.keyedMap.get(key);\n  }\n\n  first(): Document | null {\n    return this.sortedSet.minKey();\n  }\n\n  last(): Document | null {\n    return this.sortedSet.maxKey();\n  }\n\n  isEmpty(): boolean {\n    return this.sortedSet.isEmpty();\n  }\n\n  /**\n   * Returns the index of the provided key in the document set, or -1 if the\n   * document key is not present in the set;\n   */\n  indexOf(key: DocumentKey): number {\n    const doc = this.keyedMap.get(key);\n    return doc ? this.sortedSet.indexOf(doc) : -1;\n  }\n\n  get size(): number {\n    return this.sortedSet.size;\n  }\n\n  /** Iterates documents in order defined by \"comparator\" */\n  forEach(cb: (doc: Document) => void): void {\n    this.sortedSet.inorderTraversal((k, v) => {\n      cb(k);\n      return false;\n    });\n  }\n\n  /** Inserts or updates a document with the same key */\n  add(doc: Document): DocumentSet {\n    // First remove the element if we have it.\n    const set = this.delete(doc.key);\n    return set.copy(\n      set.keyedMap.insert(doc.key, doc),\n      set.sortedSet.insert(doc, null)\n    );\n  }\n\n  /** Deletes a document with a given key */\n  delete(key: DocumentKey): DocumentSet {\n    const doc = this.get(key);\n    if (!doc) {\n      return this;\n    }\n\n    return this.copy(this.keyedMap.remove(key), this.sortedSet.remove(doc));\n  }\n\n  isEqual(other: DocumentSet | null | undefined): boolean {\n    if (!(other instanceof DocumentSet)) {\n      return false;\n    }\n    if (this.size !== other.size) {\n      return false;\n    }\n\n    const thisIt = this.sortedSet.getIterator();\n    const otherIt = other.sortedSet.getIterator();\n    while (thisIt.hasNext()) {\n      const thisDoc = thisIt.getNext().key;\n      const otherDoc = otherIt.getNext().key;\n      if (!thisDoc.isEqual(otherDoc)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  toString(): string {\n    const docStrings: string[] = [];\n    this.forEach(doc => {\n      docStrings.push(doc.toString());\n    });\n    if (docStrings.length === 0) {\n      return 'DocumentSet ()';\n    } else {\n      return 'DocumentSet (\\n  ' + docStrings.join('  \\n') + '\\n)';\n    }\n  }\n\n  private copy(\n    keyedMap: SortedMap<DocumentKey, Document>,\n    sortedSet: SortedMap<Document, null>\n  ): DocumentSet {\n    const newSet = new DocumentSet();\n    newSet.comparator = this.comparator;\n    newSet.keyedMap = keyedMap;\n    newSet.sortedSet = sortedSet;\n    return newSet;\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 { Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DocumentSet } from '../model/document_set';\nimport { fail } from '../util/assert';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { DocumentKeySet } from '../model/collections';\nimport { Query, queryEquals } from './query';\n\nexport const enum ChangeType {\n  Added,\n  Removed,\n  Modified,\n  Metadata\n}\n\nexport interface DocumentViewChange {\n  type: ChangeType;\n  doc: Document;\n}\n\nexport const enum SyncState {\n  Local,\n  Synced\n}\n\n/**\n * DocumentChangeSet keeps track of a set of changes to docs in a query, merging\n * duplicate events for the same doc.\n */\nexport class DocumentChangeSet {\n  private changeMap = new SortedMap<DocumentKey, DocumentViewChange>(\n    DocumentKey.comparator\n  );\n\n  track(change: DocumentViewChange): void {\n    const key = change.doc.key;\n    const oldChange = this.changeMap.get(key);\n    if (!oldChange) {\n      this.changeMap = this.changeMap.insert(key, change);\n      return;\n    }\n\n    // Merge the new change with the existing change.\n    if (\n      change.type !== ChangeType.Added &&\n      oldChange.type === ChangeType.Metadata\n    ) {\n      this.changeMap = this.changeMap.insert(key, change);\n    } else if (\n      change.type === ChangeType.Metadata &&\n      oldChange.type !== ChangeType.Removed\n    ) {\n      this.changeMap = this.changeMap.insert(key, {\n        type: oldChange.type,\n        doc: change.doc\n      });\n    } else if (\n      change.type === ChangeType.Modified &&\n      oldChange.type === ChangeType.Modified\n    ) {\n      this.changeMap = this.changeMap.insert(key, {\n        type: ChangeType.Modified,\n        doc: change.doc\n      });\n    } else if (\n      change.type === ChangeType.Modified &&\n      oldChange.type === ChangeType.Added\n    ) {\n      this.changeMap = this.changeMap.insert(key, {\n        type: ChangeType.Added,\n        doc: change.doc\n      });\n    } else if (\n      change.type === ChangeType.Removed &&\n      oldChange.type === ChangeType.Added\n    ) {\n      this.changeMap = this.changeMap.remove(key);\n    } else if (\n      change.type === ChangeType.Removed &&\n      oldChange.type === ChangeType.Modified\n    ) {\n      this.changeMap = this.changeMap.insert(key, {\n        type: ChangeType.Removed,\n        doc: oldChange.doc\n      });\n    } else if (\n      change.type === ChangeType.Added &&\n      oldChange.type === ChangeType.Removed\n    ) {\n      this.changeMap = this.changeMap.insert(key, {\n        type: ChangeType.Modified,\n        doc: change.doc\n      });\n    } else {\n      // This includes these cases, which don't make sense:\n      // Added->Added\n      // Removed->Removed\n      // Modified->Added\n      // Removed->Modified\n      // Metadata->Added\n      // Removed->Metadata\n      fail(\n        'unsupported combination of changes: ' +\n          JSON.stringify(change) +\n          ' after ' +\n          JSON.stringify(oldChange)\n      );\n    }\n  }\n\n  getChanges(): DocumentViewChange[] {\n    const changes: DocumentViewChange[] = [];\n    this.changeMap.inorderTraversal(\n      (key: DocumentKey, change: DocumentViewChange) => {\n        changes.push(change);\n      }\n    );\n    return changes;\n  }\n}\n\nexport class ViewSnapshot {\n  constructor(\n    readonly query: Query,\n    readonly docs: DocumentSet,\n    readonly oldDocs: DocumentSet,\n    readonly docChanges: DocumentViewChange[],\n    readonly mutatedKeys: DocumentKeySet,\n    readonly fromCache: boolean,\n    readonly syncStateChanged: boolean,\n    readonly excludesMetadataChanges: boolean\n  ) {}\n\n  /** Returns a view snapshot as if all documents in the snapshot were added. */\n  static fromInitialDocuments(\n    query: Query,\n    documents: DocumentSet,\n    mutatedKeys: DocumentKeySet,\n    fromCache: boolean\n  ): ViewSnapshot {\n    const changes: DocumentViewChange[] = [];\n    documents.forEach(doc => {\n      changes.push({ type: ChangeType.Added, doc });\n    });\n\n    return new ViewSnapshot(\n      query,\n      documents,\n      DocumentSet.emptySet(documents),\n      changes,\n      mutatedKeys,\n      fromCache,\n      /* syncStateChanged= */ true,\n      /* excludesMetadataChanges= */ false\n    );\n  }\n\n  get hasPendingWrites(): boolean {\n    return !this.mutatedKeys.isEmpty();\n  }\n\n  isEqual(other: ViewSnapshot): boolean {\n    if (\n      this.fromCache !== other.fromCache ||\n      this.syncStateChanged !== other.syncStateChanged ||\n      !this.mutatedKeys.isEqual(other.mutatedKeys) ||\n      !queryEquals(this.query, other.query) ||\n      !this.docs.isEqual(other.docs) ||\n      !this.oldDocs.isEqual(other.oldDocs)\n    ) {\n      return false;\n    }\n    const changes: DocumentViewChange[] = this.docChanges;\n    const otherChanges: DocumentViewChange[] = other.docChanges;\n    if (changes.length !== otherChanges.length) {\n      return false;\n    }\n    for (let i = 0; i < changes.length; i++) {\n      if (\n        changes[i].type !== otherChanges[i].type ||\n        !changes[i].doc.isEqual(otherChanges[i].doc)\n      ) {\n        return false;\n      }\n    }\n    return true;\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport {\n  documentKeySet,\n  DocumentKeySet,\n  maybeDocumentMap,\n  MaybeDocumentMap,\n  targetIdSet\n} from '../model/collections';\nimport { SortedSet } from '../util/sorted_set';\nimport { ByteString } from '../util/byte_string';\n\n/**\n * An event from the RemoteStore. It is split into targetChanges (changes to the\n * state or the set of documents in our watched targets) and documentUpdates\n * (changes to the actual documents).\n */\nexport class RemoteEvent {\n  constructor(\n    /**\n     * The snapshot version this event brings us up to, or MIN if not set.\n     */\n    readonly snapshotVersion: SnapshotVersion,\n    /**\n     * A map from target to changes to the target. See TargetChange.\n     */\n    readonly targetChanges: Map<TargetId, TargetChange>,\n    /**\n     * A set of targets that is known to be inconsistent. Listens for these\n     * targets should be re-established without resume tokens.\n     */\n    readonly targetMismatches: SortedSet<TargetId>,\n    /**\n     * A set of which documents have changed or been deleted, along with the\n     * doc's new values (if not deleted).\n     */\n    readonly documentUpdates: MaybeDocumentMap,\n    /**\n     * A set of which document updates are due only to limbo resolution targets.\n     */\n    readonly resolvedLimboDocuments: DocumentKeySet\n  ) {}\n\n  /**\n   * HACK: Views require RemoteEvents in order to determine whether the view is\n   * CURRENT, but secondary tabs don't receive remote events. So this method is\n   * used to create a synthesized RemoteEvent that can be used to apply a\n   * CURRENT status change to a View, for queries executed in a different tab.\n   */\n  // PORTING NOTE: Multi-tab only\n  static createSynthesizedRemoteEventForCurrentChange(\n    targetId: TargetId,\n    current: boolean\n  ): RemoteEvent {\n    const targetChanges = new Map<TargetId, TargetChange>();\n    targetChanges.set(\n      targetId,\n      TargetChange.createSynthesizedTargetChangeForCurrentChange(\n        targetId,\n        current\n      )\n    );\n    return new RemoteEvent(\n      SnapshotVersion.min(),\n      targetChanges,\n      targetIdSet(),\n      maybeDocumentMap(),\n      documentKeySet()\n    );\n  }\n}\n\n/**\n * A TargetChange specifies the set of changes for a specific target as part of\n * a RemoteEvent. These changes track which documents are added, modified or\n * removed, as well as the target's resume token and whether the target is\n * marked CURRENT.\n * The actual changes *to* documents are not part of the TargetChange since\n * documents may be part of multiple targets.\n */\nexport class TargetChange {\n  constructor(\n    /**\n     * An opaque, server-assigned token that allows watching a query to be resumed\n     * after disconnecting without retransmitting all the data that matches the\n     * query. The resume token essentially identifies a point in time from which\n     * the server should resume sending results.\n     */\n    readonly resumeToken: ByteString,\n    /**\n     * The \"current\" (synced) status of this target. Note that \"current\"\n     * has special meaning in the RPC protocol that implies that a target is\n     * both up-to-date and consistent with the rest of the watch stream.\n     */\n    readonly current: boolean,\n    /**\n     * The set of documents that were newly assigned to this target as part of\n     * this remote event.\n     */\n    readonly addedDocuments: DocumentKeySet,\n    /**\n     * The set of documents that were already assigned to this target but received\n     * an update during this remote event.\n     */\n    readonly modifiedDocuments: DocumentKeySet,\n    /**\n     * The set of documents that were removed from this target as part of this\n     * remote event.\n     */\n    readonly removedDocuments: DocumentKeySet\n  ) {}\n\n  /**\n   * This method is used to create a synthesized TargetChanges that can be used to\n   * apply a CURRENT status change to a View (for queries executed in a different\n   * tab) or for new queries (to raise snapshots with correct CURRENT status).\n   */\n  static createSynthesizedTargetChangeForCurrentChange(\n    targetId: TargetId,\n    current: boolean\n  ): TargetChange {\n    return new TargetChange(\n      ByteString.EMPTY_BYTE_STRING,\n      current,\n      documentKeySet(),\n      documentKeySet(),\n      documentKeySet()\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport { ChangeType } from '../core/view_snapshot';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport {\n  documentKeySet,\n  DocumentKeySet,\n  maybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { ExistenceFilter } from './existence_filter';\nimport { RemoteEvent, TargetChange } from './remote_event';\nimport { ByteString } from '../util/byte_string';\nimport { isDocumentTarget } from '../core/target';\n\n/**\n * Internal representation of the watcher API protocol buffers.\n */\nexport type WatchChange =\n  | DocumentWatchChange\n  | WatchTargetChange\n  | ExistenceFilterChange;\n\n/**\n * Represents a changed document and a list of target ids to which this change\n * applies.\n *\n * If document has been deleted NoDocument will be provided.\n */\nexport class DocumentWatchChange {\n  constructor(\n    /** The new document applies to all of these targets. */\n    public updatedTargetIds: TargetId[],\n    /** The new document is removed from all of these targets. */\n    public removedTargetIds: TargetId[],\n    /** The key of the document for this change. */\n    public key: DocumentKey,\n    /**\n     * The new document or NoDocument if it was deleted. Is null if the\n     * document went out of view without the server sending a new document.\n     */\n    public newDoc: MaybeDocument | null\n  ) {}\n}\n\nexport class ExistenceFilterChange {\n  constructor(\n    public targetId: TargetId,\n    public existenceFilter: ExistenceFilter\n  ) {}\n}\n\nexport const enum WatchTargetChangeState {\n  NoChange,\n  Added,\n  Removed,\n  Current,\n  Reset\n}\n\nexport class WatchTargetChange {\n  constructor(\n    /** What kind of change occurred to the watch target. */\n    public state: WatchTargetChangeState,\n    /** The target IDs that were added/removed/set. */\n    public targetIds: TargetId[],\n    /**\n     * An opaque, server-assigned token that allows watching a target to be\n     * resumed after disconnecting without retransmitting all the data that\n     * matches the target. The resume token essentially identifies a point in\n     * time from which the server should resume sending results.\n     */\n    public resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING,\n    /** An RPC error indicating why the watch failed. */\n    public cause: FirestoreError | null = null\n  ) {}\n}\n\n/** Tracks the internal state of a Watch target. */\nclass TargetState {\n  /**\n   * The number of pending responses (adds or removes) that we are waiting on.\n   * We only consider targets active that have no pending responses.\n   */\n  private pendingResponses = 0;\n\n  /**\n   * Keeps track of the document changes since the last raised snapshot.\n   *\n   * These changes are continuously updated as we receive document updates and\n   * always reflect the current set of changes against the last issued snapshot.\n   */\n  private documentChanges: SortedMap<\n    DocumentKey,\n    ChangeType\n  > = snapshotChangesMap();\n\n  /** See public getters for explanations of these fields. */\n  private _resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING;\n  private _current = false;\n\n  /**\n   * Whether this target state should be included in the next snapshot. We\n   * initialize to true so that newly-added targets are included in the next\n   * RemoteEvent.\n   */\n  private _hasPendingChanges = true;\n\n  /**\n   * Whether this target has been marked 'current'.\n   *\n   * 'Current' has special meaning in the RPC protocol: It implies that the\n   * Watch backend has sent us all changes up to the point at which the target\n   * was added and that the target is consistent with the rest of the watch\n   * stream.\n   */\n  get current(): boolean {\n    return this._current;\n  }\n\n  /** The last resume token sent to us for this target. */\n  get resumeToken(): ByteString {\n    return this._resumeToken;\n  }\n\n  /** Whether this target has pending target adds or target removes. */\n  get isPending(): boolean {\n    return this.pendingResponses !== 0;\n  }\n\n  /** Whether we have modified any state that should trigger a snapshot. */\n  get hasPendingChanges(): boolean {\n    return this._hasPendingChanges;\n  }\n\n  /**\n   * Applies the resume token to the TargetChange, but only when it has a new\n   * value. Empty resumeTokens are discarded.\n   */\n  updateResumeToken(resumeToken: ByteString): void {\n    if (resumeToken.approximateByteSize() > 0) {\n      this._hasPendingChanges = true;\n      this._resumeToken = resumeToken;\n    }\n  }\n\n  /**\n   * Creates a target change from the current set of changes.\n   *\n   * To reset the document changes after raising this snapshot, call\n   * `clearPendingChanges()`.\n   */\n  toTargetChange(): TargetChange {\n    let addedDocuments = documentKeySet();\n    let modifiedDocuments = documentKeySet();\n    let removedDocuments = documentKeySet();\n\n    this.documentChanges.forEach((key, changeType) => {\n      switch (changeType) {\n        case ChangeType.Added:\n          addedDocuments = addedDocuments.add(key);\n          break;\n        case ChangeType.Modified:\n          modifiedDocuments = modifiedDocuments.add(key);\n          break;\n        case ChangeType.Removed:\n          removedDocuments = removedDocuments.add(key);\n          break;\n        default:\n          fail('Encountered invalid change type: ' + changeType);\n      }\n    });\n\n    return new TargetChange(\n      this._resumeToken,\n      this._current,\n      addedDocuments,\n      modifiedDocuments,\n      removedDocuments\n    );\n  }\n\n  /**\n   * Resets the document changes and sets `hasPendingChanges` to false.\n   */\n  clearPendingChanges(): void {\n    this._hasPendingChanges = false;\n    this.documentChanges = snapshotChangesMap();\n  }\n\n  addDocumentChange(key: DocumentKey, changeType: ChangeType): void {\n    this._hasPendingChanges = true;\n    this.documentChanges = this.documentChanges.insert(key, changeType);\n  }\n\n  removeDocumentChange(key: DocumentKey): void {\n    this._hasPendingChanges = true;\n    this.documentChanges = this.documentChanges.remove(key);\n  }\n\n  recordPendingTargetRequest(): void {\n    this.pendingResponses += 1;\n  }\n\n  recordTargetResponse(): void {\n    this.pendingResponses -= 1;\n  }\n\n  markCurrent(): void {\n    this._hasPendingChanges = true;\n    this._current = true;\n  }\n}\n\n/**\n * Interface implemented by RemoteStore to expose target metadata to the\n * WatchChangeAggregator.\n */\nexport interface TargetMetadataProvider {\n  /**\n   * Returns the set of remote document keys for the given target ID as of the\n   * last raised snapshot.\n   */\n  getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet;\n\n  /**\n   * Returns the TargetData for an active target ID or 'null' if this target\n   * has become inactive\n   */\n  getTargetDataForTarget(targetId: TargetId): TargetData | null;\n}\n\nconst LOG_TAG = 'WatchChangeAggregator';\n\n/**\n * A helper class to accumulate watch changes into a RemoteEvent.\n */\nexport class WatchChangeAggregator {\n  constructor(private metadataProvider: TargetMetadataProvider) {}\n\n  /** The internal state of all tracked targets. */\n  private targetStates = new Map<TargetId, TargetState>();\n\n  /** Keeps track of the documents to update since the last raised snapshot. */\n  private pendingDocumentUpdates = maybeDocumentMap();\n\n  /** A mapping of document keys to their set of target IDs. */\n  private pendingDocumentTargetMapping = documentTargetMap();\n\n  /**\n   * A list of targets with existence filter mismatches. These targets are\n   * known to be inconsistent and their listens needs to be re-established by\n   * RemoteStore.\n   */\n  private pendingTargetResets = new SortedSet<TargetId>(primitiveComparator);\n\n  /**\n   * Processes and adds the DocumentWatchChange to the current set of changes.\n   */\n  handleDocumentChange(docChange: DocumentWatchChange): void {\n    for (const targetId of docChange.updatedTargetIds) {\n      if (docChange.newDoc instanceof Document) {\n        this.addDocumentToTarget(targetId, docChange.newDoc);\n      } else if (docChange.newDoc instanceof NoDocument) {\n        this.removeDocumentFromTarget(\n          targetId,\n          docChange.key,\n          docChange.newDoc\n        );\n      }\n    }\n\n    for (const targetId of docChange.removedTargetIds) {\n      this.removeDocumentFromTarget(targetId, docChange.key, docChange.newDoc);\n    }\n  }\n\n  /** Processes and adds the WatchTargetChange to the current set of changes. */\n  handleTargetChange(targetChange: WatchTargetChange): void {\n    this.forEachTarget(targetChange, targetId => {\n      const targetState = this.ensureTargetState(targetId);\n      switch (targetChange.state) {\n        case WatchTargetChangeState.NoChange:\n          if (this.isActiveTarget(targetId)) {\n            targetState.updateResumeToken(targetChange.resumeToken);\n          }\n          break;\n        case WatchTargetChangeState.Added:\n          // We need to decrement the number of pending acks needed from watch\n          // for this targetId.\n          targetState.recordTargetResponse();\n          if (!targetState.isPending) {\n            // We have a freshly added target, so we need to reset any state\n            // that we had previously. This can happen e.g. when remove and add\n            // back a target for existence filter mismatches.\n            targetState.clearPendingChanges();\n          }\n          targetState.updateResumeToken(targetChange.resumeToken);\n          break;\n        case WatchTargetChangeState.Removed:\n          // We need to keep track of removed targets to we can post-filter and\n          // remove any target changes.\n          // We need to decrement the number of pending acks needed from watch\n          // for this targetId.\n          targetState.recordTargetResponse();\n          if (!targetState.isPending) {\n            this.removeTarget(targetId);\n          }\n          debugAssert(\n            !targetChange.cause,\n            'WatchChangeAggregator does not handle errored targets'\n          );\n          break;\n        case WatchTargetChangeState.Current:\n          if (this.isActiveTarget(targetId)) {\n            targetState.markCurrent();\n            targetState.updateResumeToken(targetChange.resumeToken);\n          }\n          break;\n        case WatchTargetChangeState.Reset:\n          if (this.isActiveTarget(targetId)) {\n            // Reset the target and synthesizes removes for all existing\n            // documents. The backend will re-add any documents that still\n            // match the target before it sends the next global snapshot.\n            this.resetTarget(targetId);\n            targetState.updateResumeToken(targetChange.resumeToken);\n          }\n          break;\n        default:\n          fail('Unknown target watch change state: ' + targetChange.state);\n      }\n    });\n  }\n\n  /**\n   * Iterates over all targetIds that the watch change applies to: either the\n   * targetIds explicitly listed in the change or the targetIds of all currently\n   * active targets.\n   */\n  forEachTarget(\n    targetChange: WatchTargetChange,\n    fn: (targetId: TargetId) => void\n  ): void {\n    if (targetChange.targetIds.length > 0) {\n      targetChange.targetIds.forEach(fn);\n    } else {\n      this.targetStates.forEach((_, targetId) => {\n        if (this.isActiveTarget(targetId)) {\n          fn(targetId);\n        }\n      });\n    }\n  }\n\n  /**\n   * Handles existence filters and synthesizes deletes for filter mismatches.\n   * Targets that are invalidated by filter mismatches are added to\n   * `pendingTargetResets`.\n   */\n  handleExistenceFilter(watchChange: ExistenceFilterChange): void {\n    const targetId = watchChange.targetId;\n    const expectedCount = watchChange.existenceFilter.count;\n\n    const targetData = this.targetDataForActiveTarget(targetId);\n    if (targetData) {\n      const target = targetData.target;\n      if (isDocumentTarget(target)) {\n        if (expectedCount === 0) {\n          // The existence filter told us the document does not exist. We deduce\n          // that this document does not exist and apply a deleted document to\n          // our updates. Without applying this deleted document there might be\n          // another query that will raise this document as part of a snapshot\n          // until it is resolved, essentially exposing inconsistency between\n          // queries.\n          const key = new DocumentKey(target.path);\n          this.removeDocumentFromTarget(\n            targetId,\n            key,\n            new NoDocument(key, SnapshotVersion.min())\n          );\n        } else {\n          hardAssert(\n            expectedCount === 1,\n            'Single document existence filter with count: ' + expectedCount\n          );\n        }\n      } else {\n        const currentSize = this.getCurrentDocumentCountForTarget(targetId);\n        if (currentSize !== expectedCount) {\n          // Existence filter mismatch: We reset the mapping and raise a new\n          // snapshot with `isFromCache:true`.\n          this.resetTarget(targetId);\n          this.pendingTargetResets = this.pendingTargetResets.add(targetId);\n        }\n      }\n    }\n  }\n\n  /**\n   * Converts the currently accumulated state into a remote event at the\n   * provided snapshot version. Resets the accumulated changes before returning.\n   */\n  createRemoteEvent(snapshotVersion: SnapshotVersion): RemoteEvent {\n    const targetChanges = new Map<TargetId, TargetChange>();\n\n    this.targetStates.forEach((targetState, targetId) => {\n      const targetData = this.targetDataForActiveTarget(targetId);\n      if (targetData) {\n        if (targetState.current && isDocumentTarget(targetData.target)) {\n          // Document queries for document that don't exist can produce an empty\n          // result set. To update our local cache, we synthesize a document\n          // delete if we have not previously received the document. This\n          // resolves the limbo state of the document, removing it from\n          // limboDocumentRefs.\n          //\n          // TODO(dimond): Ideally we would have an explicit lookup target\n          // instead resulting in an explicit delete message and we could\n          // remove this special logic.\n          const key = new DocumentKey(targetData.target.path);\n          if (\n            this.pendingDocumentUpdates.get(key) === null &&\n            !this.targetContainsDocument(targetId, key)\n          ) {\n            this.removeDocumentFromTarget(\n              targetId,\n              key,\n              new NoDocument(key, snapshotVersion)\n            );\n          }\n        }\n\n        if (targetState.hasPendingChanges) {\n          targetChanges.set(targetId, targetState.toTargetChange());\n          targetState.clearPendingChanges();\n        }\n      }\n    });\n\n    let resolvedLimboDocuments = documentKeySet();\n\n    // We extract the set of limbo-only document updates as the GC logic\n    // special-cases documents that do not appear in the target cache.\n    //\n    // TODO(gsoltis): Expand on this comment once GC is available in the JS\n    // client.\n    this.pendingDocumentTargetMapping.forEach((key, targets) => {\n      let isOnlyLimboTarget = true;\n\n      targets.forEachWhile(targetId => {\n        const targetData = this.targetDataForActiveTarget(targetId);\n        if (\n          targetData &&\n          targetData.purpose !== TargetPurpose.LimboResolution\n        ) {\n          isOnlyLimboTarget = false;\n          return false;\n        }\n\n        return true;\n      });\n\n      if (isOnlyLimboTarget) {\n        resolvedLimboDocuments = resolvedLimboDocuments.add(key);\n      }\n    });\n\n    const remoteEvent = new RemoteEvent(\n      snapshotVersion,\n      targetChanges,\n      this.pendingTargetResets,\n      this.pendingDocumentUpdates,\n      resolvedLimboDocuments\n    );\n\n    this.pendingDocumentUpdates = maybeDocumentMap();\n    this.pendingDocumentTargetMapping = documentTargetMap();\n    this.pendingTargetResets = new SortedSet<TargetId>(primitiveComparator);\n\n    return remoteEvent;\n  }\n\n  /**\n   * Adds the provided document to the internal list of document updates and\n   * its document key to the given target's mapping.\n   */\n  // Visible for testing.\n  addDocumentToTarget(targetId: TargetId, document: MaybeDocument): void {\n    if (!this.isActiveTarget(targetId)) {\n      return;\n    }\n\n    const changeType = this.targetContainsDocument(targetId, document.key)\n      ? ChangeType.Modified\n      : ChangeType.Added;\n\n    const targetState = this.ensureTargetState(targetId);\n    targetState.addDocumentChange(document.key, changeType);\n\n    this.pendingDocumentUpdates = this.pendingDocumentUpdates.insert(\n      document.key,\n      document\n    );\n\n    this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n      document.key,\n      this.ensureDocumentTargetMapping(document.key).add(targetId)\n    );\n  }\n\n  /**\n   * Removes the provided document from the target mapping. If the\n   * document no longer matches the target, but the document's state is still\n   * known (e.g. we know that the document was deleted or we received the change\n   * that caused the filter mismatch), the new document can be provided\n   * to update the remote document cache.\n   */\n  // Visible for testing.\n  removeDocumentFromTarget(\n    targetId: TargetId,\n    key: DocumentKey,\n    updatedDocument: MaybeDocument | null\n  ): void {\n    if (!this.isActiveTarget(targetId)) {\n      return;\n    }\n\n    const targetState = this.ensureTargetState(targetId);\n    if (this.targetContainsDocument(targetId, key)) {\n      targetState.addDocumentChange(key, ChangeType.Removed);\n    } else {\n      // The document may have entered and left the target before we raised a\n      // snapshot, so we can just ignore the change.\n      targetState.removeDocumentChange(key);\n    }\n\n    this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n      key,\n      this.ensureDocumentTargetMapping(key).delete(targetId)\n    );\n\n    if (updatedDocument) {\n      this.pendingDocumentUpdates = this.pendingDocumentUpdates.insert(\n        key,\n        updatedDocument\n      );\n    }\n  }\n\n  removeTarget(targetId: TargetId): void {\n    this.targetStates.delete(targetId);\n  }\n\n  /**\n   * Returns the current count of documents in the target. This includes both\n   * the number of documents that the LocalStore considers to be part of the\n   * target as well as any accumulated changes.\n   */\n  private getCurrentDocumentCountForTarget(targetId: TargetId): number {\n    const targetState = this.ensureTargetState(targetId);\n    const targetChange = targetState.toTargetChange();\n    return (\n      this.metadataProvider.getRemoteKeysForTarget(targetId).size +\n      targetChange.addedDocuments.size -\n      targetChange.removedDocuments.size\n    );\n  }\n\n  /**\n   * Increment the number of acks needed from watch before we can consider the\n   * server to be 'in-sync' with the client's active targets.\n   */\n  recordPendingTargetRequest(targetId: TargetId): void {\n    // For each request we get we need to record we need a response for it.\n    const targetState = this.ensureTargetState(targetId);\n    targetState.recordPendingTargetRequest();\n  }\n\n  private ensureTargetState(targetId: TargetId): TargetState {\n    let result = this.targetStates.get(targetId);\n    if (!result) {\n      result = new TargetState();\n      this.targetStates.set(targetId, result);\n    }\n    return result;\n  }\n\n  private ensureDocumentTargetMapping(key: DocumentKey): SortedSet<TargetId> {\n    let targetMapping = this.pendingDocumentTargetMapping.get(key);\n\n    if (!targetMapping) {\n      targetMapping = new SortedSet<TargetId>(primitiveComparator);\n      this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n        key,\n        targetMapping\n      );\n    }\n\n    return targetMapping;\n  }\n\n  /**\n   * Verifies that the user is still interested in this target (by calling\n   * `getTargetDataForTarget()`) and that we are not waiting for pending ADDs\n   * from watch.\n   */\n  protected isActiveTarget(targetId: TargetId): boolean {\n    const targetActive = this.targetDataForActiveTarget(targetId) !== null;\n    if (!targetActive) {\n      logDebug(LOG_TAG, 'Detected inactive target', targetId);\n    }\n    return targetActive;\n  }\n\n  /**\n   * Returns the TargetData for an active target (i.e. a target that the user\n   * is still interested in that has no outstanding target change requests).\n   */\n  protected targetDataForActiveTarget(targetId: TargetId): TargetData | null {\n    const targetState = this.targetStates.get(targetId);\n    return targetState && targetState.isPending\n      ? null\n      : this.metadataProvider.getTargetDataForTarget(targetId);\n  }\n\n  /**\n   * Resets the state of a Watch target to its initial state (e.g. sets\n   * 'current' to false, clears the resume token and removes its target mapping\n   * from all documents).\n   */\n  private resetTarget(targetId: TargetId): void {\n    debugAssert(\n      !this.targetStates.get(targetId)!.isPending,\n      'Should only reset active targets'\n    );\n    this.targetStates.set(targetId, new TargetState());\n\n    // Trigger removal for any documents currently mapped to this target.\n    // These removals will be part of the initial snapshot if Watch does not\n    // resend these documents.\n    const existingKeys = this.metadataProvider.getRemoteKeysForTarget(targetId);\n    existingKeys.forEach(key => {\n      this.removeDocumentFromTarget(targetId, key, /*updatedDocument=*/ null);\n    });\n  }\n  /**\n   * Returns whether the LocalStore considers the document to be part of the\n   * specified target.\n   */\n  private targetContainsDocument(\n    targetId: TargetId,\n    key: DocumentKey\n  ): boolean {\n    const existingKeys = this.metadataProvider.getRemoteKeysForTarget(targetId);\n    return existingKeys.has(key);\n  }\n}\n\nfunction documentTargetMap(): SortedMap<DocumentKey, SortedSet<TargetId>> {\n  return new SortedMap<DocumentKey, SortedSet<TargetId>>(\n    DocumentKey.comparator\n  );\n}\n\nfunction snapshotChangesMap(): SortedMap<DocumentKey, ChangeType> {\n  return new SortedMap<DocumentKey, ChangeType>(DocumentKey.comparator);\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 * as api from '../protos/firestore_proto_api';\nimport { Timestamp } from '../api/timestamp';\nimport { normalizeTimestamp } from './values';\n\n/**\n * Represents a locally-applied ServerTimestamp.\n *\n * Server Timestamps are backed by MapValues that contain an internal field\n * `__type__` with a value of `server_timestamp`. The previous value and local\n * write time are stored in its `__previous_value__` and `__local_write_time__`\n * fields respectively.\n *\n * Notes:\n * - ServerTimestampValue instances are created as the result of applying a\n *   TransformMutation (see TransformMutation.applyTo()). They can only exist in\n *   the local view of a document. Therefore they do not need to be parsed or\n *   serialized.\n * - When evaluated locally (e.g. for snapshot.data()), they by default\n *   evaluate to `null`. This behavior can be configured by passing custom\n *   FieldValueOptions to value().\n * - With respect to other ServerTimestampValues, they sort by their\n *   localWriteTime.\n */\n\nconst SERVER_TIMESTAMP_SENTINEL = 'server_timestamp';\nconst TYPE_KEY = '__type__';\nconst PREVIOUS_VALUE_KEY = '__previous_value__';\nconst LOCAL_WRITE_TIME_KEY = '__local_write_time__';\n\nexport function isServerTimestamp(value: api.Value | null): boolean {\n  const type = (value?.mapValue?.fields || {})[TYPE_KEY]?.stringValue;\n  return type === SERVER_TIMESTAMP_SENTINEL;\n}\n\n/**\n * Creates a new ServerTimestamp proto value (using the internal format).\n */\nexport function serverTimestamp(\n  localWriteTime: Timestamp,\n  previousValue: api.Value | null\n): api.Value {\n  const mapValue: api.MapValue = {\n    fields: {\n      [TYPE_KEY]: {\n        stringValue: SERVER_TIMESTAMP_SENTINEL\n      },\n      [LOCAL_WRITE_TIME_KEY]: {\n        timestampValue: {\n          seconds: localWriteTime.seconds,\n          nanos: localWriteTime.nanoseconds\n        }\n      }\n    }\n  };\n\n  if (previousValue) {\n    mapValue.fields![PREVIOUS_VALUE_KEY] = previousValue;\n  }\n\n  return { mapValue };\n}\n\n/**\n * Returns the value of the field before this ServerTimestamp was set.\n *\n * Preserving the previous values allows the user to display the last resoled\n * value until the backend responds with the timestamp.\n */\nexport function getPreviousValue(value: api.Value): api.Value | null {\n  const previousValue = value.mapValue!.fields![PREVIOUS_VALUE_KEY];\n\n  if (isServerTimestamp(previousValue)) {\n    return getPreviousValue(previousValue);\n  }\n  return previousValue;\n}\n\n/**\n * Returns the local time at which this timestamp was first set.\n */\nexport function getLocalWriteTime(value: api.Value): Timestamp {\n  const localWriteTime = normalizeTimestamp(\n    value.mapValue!.fields![LOCAL_WRITE_TIME_KEY].timestampValue!\n  );\n  return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);\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 * as api from '../protos/firestore_proto_api';\n\nimport { TypeOrder } from './object_value';\nimport { fail, hardAssert } from '../util/assert';\nimport { forEach, objectSize } from '../util/obj';\nimport { ByteString } from '../util/byte_string';\nimport { isNegativeZero } from '../util/types';\nimport { DocumentKey } from './document_key';\nimport { arrayEquals, primitiveComparator } from '../util/misc';\nimport { DatabaseId } from '../core/database_info';\nimport {\n  getLocalWriteTime,\n  getPreviousValue,\n  isServerTimestamp\n} from './server_timestamps';\n\n// A RegExp matching ISO 8601 UTC timestamps with optional fraction.\nconst ISO_TIMESTAMP_REG_EXP = new RegExp(\n  /^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.(\\d+))?Z$/\n);\n\n/** Extracts the backend's type order for the provided value. */\nexport function typeOrder(value: api.Value): TypeOrder {\n  if ('nullValue' in value) {\n    return TypeOrder.NullValue;\n  } else if ('booleanValue' in value) {\n    return TypeOrder.BooleanValue;\n  } else if ('integerValue' in value || 'doubleValue' in value) {\n    return TypeOrder.NumberValue;\n  } else if ('timestampValue' in value) {\n    return TypeOrder.TimestampValue;\n  } else if ('stringValue' in value) {\n    return TypeOrder.StringValue;\n  } else if ('bytesValue' in value) {\n    return TypeOrder.BlobValue;\n  } else if ('referenceValue' in value) {\n    return TypeOrder.RefValue;\n  } else if ('geoPointValue' in value) {\n    return TypeOrder.GeoPointValue;\n  } else if ('arrayValue' in value) {\n    return TypeOrder.ArrayValue;\n  } else if ('mapValue' in value) {\n    if (isServerTimestamp(value)) {\n      return TypeOrder.ServerTimestampValue;\n    }\n    return TypeOrder.ObjectValue;\n  } else {\n    return fail('Invalid value type: ' + JSON.stringify(value));\n  }\n}\n\n/** Tests `left` and `right` for equality based on the backend semantics. */\nexport function valueEquals(left: api.Value, right: api.Value): boolean {\n  const leftType = typeOrder(left);\n  const rightType = typeOrder(right);\n  if (leftType !== rightType) {\n    return false;\n  }\n\n  switch (leftType) {\n    case TypeOrder.NullValue:\n      return true;\n    case TypeOrder.BooleanValue:\n      return left.booleanValue === right.booleanValue;\n    case TypeOrder.ServerTimestampValue:\n      return getLocalWriteTime(left).isEqual(getLocalWriteTime(right));\n    case TypeOrder.TimestampValue:\n      return timestampEquals(left, right);\n    case TypeOrder.StringValue:\n      return left.stringValue === right.stringValue;\n    case TypeOrder.BlobValue:\n      return blobEquals(left, right);\n    case TypeOrder.RefValue:\n      return left.referenceValue === right.referenceValue;\n    case TypeOrder.GeoPointValue:\n      return geoPointEquals(left, right);\n    case TypeOrder.NumberValue:\n      return numberEquals(left, right);\n    case TypeOrder.ArrayValue:\n      return arrayEquals(\n        left.arrayValue!.values || [],\n        right.arrayValue!.values || [],\n        valueEquals\n      );\n    case TypeOrder.ObjectValue:\n      return objectEquals(left, right);\n    default:\n      return fail('Unexpected value type: ' + JSON.stringify(left));\n  }\n}\n\nfunction timestampEquals(left: api.Value, right: api.Value): boolean {\n  if (\n    typeof left.timestampValue === 'string' &&\n    typeof right.timestampValue === 'string' &&\n    left.timestampValue.length === right.timestampValue.length\n  ) {\n    // Use string equality for ISO 8601 timestamps\n    return left.timestampValue === right.timestampValue;\n  }\n\n  const leftTimestamp = normalizeTimestamp(left.timestampValue!);\n  const rightTimestamp = normalizeTimestamp(right.timestampValue!);\n  return (\n    leftTimestamp.seconds === rightTimestamp.seconds &&\n    leftTimestamp.nanos === rightTimestamp.nanos\n  );\n}\n\nfunction geoPointEquals(left: api.Value, right: api.Value): boolean {\n  return (\n    normalizeNumber(left.geoPointValue!.latitude) ===\n      normalizeNumber(right.geoPointValue!.latitude) &&\n    normalizeNumber(left.geoPointValue!.longitude) ===\n      normalizeNumber(right.geoPointValue!.longitude)\n  );\n}\n\nfunction blobEquals(left: api.Value, right: api.Value): boolean {\n  return normalizeByteString(left.bytesValue!).isEqual(\n    normalizeByteString(right.bytesValue!)\n  );\n}\n\nexport function numberEquals(left: api.Value, right: api.Value): boolean {\n  if ('integerValue' in left && 'integerValue' in right) {\n    return (\n      normalizeNumber(left.integerValue) === normalizeNumber(right.integerValue)\n    );\n  } else if ('doubleValue' in left && 'doubleValue' in right) {\n    const n1 = normalizeNumber(left.doubleValue!);\n    const n2 = normalizeNumber(right.doubleValue!);\n\n    if (n1 === n2) {\n      return isNegativeZero(n1) === isNegativeZero(n2);\n    } else {\n      return isNaN(n1) && isNaN(n2);\n    }\n  }\n\n  return false;\n}\n\nfunction objectEquals(left: api.Value, right: api.Value): boolean {\n  const leftMap = left.mapValue!.fields || {};\n  const rightMap = right.mapValue!.fields || {};\n\n  if (objectSize(leftMap) !== objectSize(rightMap)) {\n    return false;\n  }\n\n  for (const key in leftMap) {\n    if (leftMap.hasOwnProperty(key)) {\n      if (\n        rightMap[key] === undefined ||\n        !valueEquals(leftMap[key], rightMap[key])\n      ) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\n/** Returns true if the ArrayValue contains the specified element. */\nexport function arrayValueContains(\n  haystack: api.ArrayValue,\n  needle: api.Value\n): boolean {\n  return (\n    (haystack.values || []).find(v => valueEquals(v, needle)) !== undefined\n  );\n}\n\nexport function valueCompare(left: api.Value, right: api.Value): number {\n  const leftType = typeOrder(left);\n  const rightType = typeOrder(right);\n\n  if (leftType !== rightType) {\n    return primitiveComparator(leftType, rightType);\n  }\n\n  switch (leftType) {\n    case TypeOrder.NullValue:\n      return 0;\n    case TypeOrder.BooleanValue:\n      return primitiveComparator(left.booleanValue!, right.booleanValue!);\n    case TypeOrder.NumberValue:\n      return compareNumbers(left, right);\n    case TypeOrder.TimestampValue:\n      return compareTimestamps(left.timestampValue!, right.timestampValue!);\n    case TypeOrder.ServerTimestampValue:\n      return compareTimestamps(\n        getLocalWriteTime(left),\n        getLocalWriteTime(right)\n      );\n    case TypeOrder.StringValue:\n      return primitiveComparator(left.stringValue!, right.stringValue!);\n    case TypeOrder.BlobValue:\n      return compareBlobs(left.bytesValue!, right.bytesValue!);\n    case TypeOrder.RefValue:\n      return compareReferences(left.referenceValue!, right.referenceValue!);\n    case TypeOrder.GeoPointValue:\n      return compareGeoPoints(left.geoPointValue!, right.geoPointValue!);\n    case TypeOrder.ArrayValue:\n      return compareArrays(left.arrayValue!, right.arrayValue!);\n    case TypeOrder.ObjectValue:\n      return compareMaps(left.mapValue!, right.mapValue!);\n    default:\n      throw fail('Invalid value type: ' + leftType);\n  }\n}\n\nfunction compareNumbers(left: api.Value, right: api.Value): number {\n  const leftNumber = normalizeNumber(left.integerValue || left.doubleValue);\n  const rightNumber = normalizeNumber(right.integerValue || right.doubleValue);\n\n  if (leftNumber < rightNumber) {\n    return -1;\n  } else if (leftNumber > rightNumber) {\n    return 1;\n  } else if (leftNumber === rightNumber) {\n    return 0;\n  } else {\n    // one or both are NaN.\n    if (isNaN(leftNumber)) {\n      return isNaN(rightNumber) ? 0 : -1;\n    } else {\n      return 1;\n    }\n  }\n}\n\nfunction compareTimestamps(left: api.Timestamp, right: api.Timestamp): number {\n  if (\n    typeof left === 'string' &&\n    typeof right === 'string' &&\n    left.length === right.length\n  ) {\n    return primitiveComparator(left, right);\n  }\n\n  const leftTimestamp = normalizeTimestamp(left);\n  const rightTimestamp = normalizeTimestamp(right);\n\n  const comparison = primitiveComparator(\n    leftTimestamp.seconds,\n    rightTimestamp.seconds\n  );\n  if (comparison !== 0) {\n    return comparison;\n  }\n  return primitiveComparator(leftTimestamp.nanos, rightTimestamp.nanos);\n}\n\nfunction compareReferences(leftPath: string, rightPath: string): number {\n  const leftSegments = leftPath.split('/');\n  const rightSegments = rightPath.split('/');\n  for (let i = 0; i < leftSegments.length && i < rightSegments.length; i++) {\n    const comparison = primitiveComparator(leftSegments[i], rightSegments[i]);\n    if (comparison !== 0) {\n      return comparison;\n    }\n  }\n  return primitiveComparator(leftSegments.length, rightSegments.length);\n}\n\nfunction compareGeoPoints(left: api.LatLng, right: api.LatLng): number {\n  const comparison = primitiveComparator(\n    normalizeNumber(left.latitude),\n    normalizeNumber(right.latitude)\n  );\n  if (comparison !== 0) {\n    return comparison;\n  }\n  return primitiveComparator(\n    normalizeNumber(left.longitude),\n    normalizeNumber(right.longitude)\n  );\n}\n\nfunction compareBlobs(\n  left: string | Uint8Array,\n  right: string | Uint8Array\n): number {\n  const leftBytes = normalizeByteString(left);\n  const rightBytes = normalizeByteString(right);\n  return leftBytes.compareTo(rightBytes);\n}\n\nfunction compareArrays(left: api.ArrayValue, right: api.ArrayValue): number {\n  const leftArray = left.values || [];\n  const rightArray = right.values || [];\n\n  for (let i = 0; i < leftArray.length && i < rightArray.length; ++i) {\n    const compare = valueCompare(leftArray[i], rightArray[i]);\n    if (compare) {\n      return compare;\n    }\n  }\n  return primitiveComparator(leftArray.length, rightArray.length);\n}\n\nfunction compareMaps(left: api.MapValue, right: api.MapValue): number {\n  const leftMap = left.fields || {};\n  const leftKeys = Object.keys(leftMap);\n  const rightMap = right.fields || {};\n  const rightKeys = Object.keys(rightMap);\n\n  // Even though MapValues are likely sorted correctly based on their insertion\n  // order (e.g. when received from the backend), local modifications can bring\n  // elements out of order. We need to re-sort the elements to ensure that\n  // canonical IDs are independent of insertion order.\n  leftKeys.sort();\n  rightKeys.sort();\n\n  for (let i = 0; i < leftKeys.length && i < rightKeys.length; ++i) {\n    const keyCompare = primitiveComparator(leftKeys[i], rightKeys[i]);\n    if (keyCompare !== 0) {\n      return keyCompare;\n    }\n    const compare = valueCompare(leftMap[leftKeys[i]], rightMap[rightKeys[i]]);\n    if (compare !== 0) {\n      return compare;\n    }\n  }\n\n  return primitiveComparator(leftKeys.length, rightKeys.length);\n}\n\n/**\n * Generates the canonical ID for the provided field value (as used in Target\n * serialization).\n */\nexport function canonicalId(value: api.Value): string {\n  return canonifyValue(value);\n}\n\nfunction canonifyValue(value: api.Value): string {\n  if ('nullValue' in value) {\n    return 'null';\n  } else if ('booleanValue' in value) {\n    return '' + value.booleanValue!;\n  } else if ('integerValue' in value) {\n    return '' + value.integerValue!;\n  } else if ('doubleValue' in value) {\n    return '' + value.doubleValue!;\n  } else if ('timestampValue' in value) {\n    return canonifyTimestamp(value.timestampValue!);\n  } else if ('stringValue' in value) {\n    return value.stringValue!;\n  } else if ('bytesValue' in value) {\n    return canonifyByteString(value.bytesValue!);\n  } else if ('referenceValue' in value) {\n    return canonifyReference(value.referenceValue!);\n  } else if ('geoPointValue' in value) {\n    return canonifyGeoPoint(value.geoPointValue!);\n  } else if ('arrayValue' in value) {\n    return canonifyArray(value.arrayValue!);\n  } else if ('mapValue' in value) {\n    return canonifyMap(value.mapValue!);\n  } else {\n    return fail('Invalid value type: ' + JSON.stringify(value));\n  }\n}\n\nfunction canonifyByteString(byteString: string | Uint8Array): string {\n  return normalizeByteString(byteString).toBase64();\n}\n\nfunction canonifyTimestamp(timestamp: api.Timestamp): string {\n  const normalizedTimestamp = normalizeTimestamp(timestamp);\n  return `time(${normalizedTimestamp.seconds},${normalizedTimestamp.nanos})`;\n}\n\nfunction canonifyGeoPoint(geoPoint: api.LatLng): string {\n  return `geo(${geoPoint.latitude},${geoPoint.longitude})`;\n}\n\nfunction canonifyReference(referenceValue: string): string {\n  return DocumentKey.fromName(referenceValue).toString();\n}\n\nfunction canonifyMap(mapValue: api.MapValue): string {\n  // Iteration order in JavaScript is not guaranteed. To ensure that we generate\n  // matching canonical IDs for identical maps, we need to sort the keys.\n  const sortedKeys = Object.keys(mapValue.fields || {}).sort();\n\n  let result = '{';\n  let first = true;\n  for (const key of sortedKeys) {\n    if (!first) {\n      result += ',';\n    } else {\n      first = false;\n    }\n    result += `${key}:${canonifyValue(mapValue.fields![key])}`;\n  }\n  return result + '}';\n}\n\nfunction canonifyArray(arrayValue: api.ArrayValue): string {\n  let result = '[';\n  let first = true;\n  for (const value of arrayValue.values || []) {\n    if (!first) {\n      result += ',';\n    } else {\n      first = false;\n    }\n    result += canonifyValue(value);\n  }\n  return result + ']';\n}\n\n/**\n * Returns an approximate (and wildly inaccurate) in-memory size for the field\n * value.\n *\n * The memory size takes into account only the actual user data as it resides\n * in memory and ignores object overhead.\n */\nexport function estimateByteSize(value: api.Value): number {\n  switch (typeOrder(value)) {\n    case TypeOrder.NullValue:\n      return 4;\n    case TypeOrder.BooleanValue:\n      return 4;\n    case TypeOrder.NumberValue:\n      return 8;\n    case TypeOrder.TimestampValue:\n      // Timestamps are made up of two distinct numbers (seconds + nanoseconds)\n      return 16;\n    case TypeOrder.ServerTimestampValue:\n      const previousValue = getPreviousValue(value);\n      return previousValue ? 16 + estimateByteSize(previousValue) : 16;\n    case TypeOrder.StringValue:\n      // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures:\n      // \"JavaScript's String type is [...] a set of elements of 16-bit unsigned\n      // integer values\"\n      return value.stringValue!.length * 2;\n    case TypeOrder.BlobValue:\n      return normalizeByteString(value.bytesValue!).approximateByteSize();\n    case TypeOrder.RefValue:\n      return value.referenceValue!.length;\n    case TypeOrder.GeoPointValue:\n      // GeoPoints are made up of two distinct numbers (latitude + longitude)\n      return 16;\n    case TypeOrder.ArrayValue:\n      return estimateArrayByteSize(value.arrayValue!);\n    case TypeOrder.ObjectValue:\n      return estimateMapByteSize(value.mapValue!);\n    default:\n      throw fail('Invalid value type: ' + JSON.stringify(value));\n  }\n}\n\nfunction estimateMapByteSize(mapValue: api.MapValue): number {\n  let size = 0;\n  forEach(mapValue.fields || {}, (key, val) => {\n    size += key.length + estimateByteSize(val);\n  });\n  return size;\n}\n\nfunction estimateArrayByteSize(arrayValue: api.ArrayValue): number {\n  return (arrayValue.values || []).reduce(\n    (previousSize, value) => previousSize + estimateByteSize(value),\n    0\n  );\n}\n\n/**\n * Converts the possible Proto values for a timestamp value into a \"seconds and\n * nanos\" representation.\n */\nexport function normalizeTimestamp(\n  date: api.Timestamp\n): { seconds: number; nanos: number } {\n  hardAssert(!!date, 'Cannot normalize null or undefined timestamp.');\n\n  // The json interface (for the browser) will return an iso timestamp string,\n  // while the proto js library (for node) will return a\n  // google.protobuf.Timestamp instance.\n  if (typeof date === 'string') {\n    // The date string can have higher precision (nanos) than the Date class\n    // (millis), so we do some custom parsing here.\n\n    // Parse the nanos right out of the string.\n    let nanos = 0;\n    const fraction = ISO_TIMESTAMP_REG_EXP.exec(date);\n    hardAssert(!!fraction, 'invalid timestamp: ' + date);\n    if (fraction[1]) {\n      // Pad the fraction out to 9 digits (nanos).\n      let nanoStr = fraction[1];\n      nanoStr = (nanoStr + '000000000').substr(0, 9);\n      nanos = Number(nanoStr);\n    }\n\n    // Parse the date to get the seconds.\n    const parsedDate = new Date(date);\n    const seconds = Math.floor(parsedDate.getTime() / 1000);\n\n    return { seconds, nanos };\n  } else {\n    // TODO(b/37282237): Use strings for Proto3 timestamps\n    // assert(!this.options.useProto3Json,\n    //   'The timestamp instance format requires Proto JS.');\n    const seconds = normalizeNumber(date.seconds);\n    const nanos = normalizeNumber(date.nanos);\n    return { seconds, nanos };\n  }\n}\n\n/**\n * Converts the possible Proto types for numbers into a JavaScript number.\n * Returns 0 if the value is not numeric.\n */\nexport function normalizeNumber(value: number | string | undefined): number {\n  // TODO(bjornick): Handle int64 greater than 53 bits.\n  if (typeof value === 'number') {\n    return value;\n  } else if (typeof value === 'string') {\n    return Number(value);\n  } else {\n    return 0;\n  }\n}\n\n/** Converts the possible Proto types for Blobs into a ByteString. */\nexport function normalizeByteString(blob: string | Uint8Array): ByteString {\n  if (typeof blob === 'string') {\n    return ByteString.fromBase64String(blob);\n  } else {\n    return ByteString.fromUint8Array(blob);\n  }\n}\n\n/** Returns a reference value for the provided database and key. */\nexport function refValue(databaseId: DatabaseId, key: DocumentKey): api.Value {\n  return {\n    referenceValue: `projects/${databaseId.projectId}/databases/${\n      databaseId.database\n    }/documents/${key.path.canonicalString()}`\n  };\n}\n\n/** Returns true if `value` is an IntegerValue . */\nexport function isInteger(\n  value?: api.Value | null\n): value is { integerValue: string | number } {\n  return !!value && 'integerValue' in value;\n}\n\n/** Returns true if `value` is a DoubleValue. */\nexport function isDouble(\n  value?: api.Value | null\n): value is { doubleValue: string | number } {\n  return !!value && 'doubleValue' in value;\n}\n\n/** Returns true if `value` is either an IntegerValue or a DoubleValue. */\nexport function isNumber(value?: api.Value | null): boolean {\n  return isInteger(value) || isDouble(value);\n}\n\n/** Returns true if `value` is an ArrayValue. */\nexport function isArray(\n  value?: api.Value | null\n): value is { arrayValue: api.ArrayValue } {\n  return !!value && 'arrayValue' in value;\n}\n\n/** Returns true if `value` is a ReferenceValue. */\nexport function isReferenceValue(\n  value?: api.Value | null\n): value is { referenceValue: string } {\n  return !!value && 'referenceValue' in value;\n}\n\n/** Returns true if `value` is a NullValue. */\nexport function isNullValue(\n  value?: api.Value | null\n): value is { nullValue: 'NULL_VALUE' } {\n  return !!value && 'nullValue' in value;\n}\n\n/** Returns true if `value` is NaN. */\nexport function isNanValue(\n  value?: api.Value | null\n): value is { doubleValue: 'NaN' | number } {\n  return !!value && 'doubleValue' in value && isNaN(Number(value.doubleValue));\n}\n\n/** Returns true if `value` is a MapValue. */\nexport function isMapValue(\n  value?: api.Value | null\n): value is { mapValue: api.MapValue } {\n  return !!value && 'mapValue' in value;\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 { Blob } from '../api/blob';\nimport { Timestamp } from '../api/timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport {\n  Bound,\n  Direction,\n  FieldFilter,\n  Filter,\n  LimitType,\n  newQuery,\n  newQueryForPath,\n  Operator,\n  OrderBy,\n  queryToTarget\n} from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { isDocumentTarget, Target } from '../core/target';\nimport { TargetId } from '../core/types';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { ObjectValue } from '../model/object_value';\nimport {\n  DeleteMutation,\n  FieldMask,\n  FieldTransform,\n  Mutation,\n  MutationResult,\n  PatchMutation,\n  Precondition,\n  SetMutation,\n  TransformMutation,\n  VerifyMutation\n} from '../model/mutation';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { ByteString } from '../util/byte_string';\nimport {\n  isNegativeZero,\n  isNullOrUndefined,\n  isSafeInteger\n} from '../util/types';\nimport {\n  ArrayRemoveTransformOperation,\n  ArrayUnionTransformOperation,\n  NumericIncrementTransformOperation,\n  ServerTimestampTransform,\n  TransformOperation\n} from '../model/transform_operation';\nimport { ExistenceFilter } from './existence_filter';\nimport { mapCodeFromRpcCode } from './rpc_error';\nimport {\n  DocumentWatchChange,\n  ExistenceFilterChange,\n  WatchChange,\n  WatchTargetChange,\n  WatchTargetChangeState\n} from './watch_change';\nimport { isNanValue, isNullValue, normalizeTimestamp } from '../model/values';\nimport {\n  TargetChangeTargetChangeType,\n  WriteResult\n} from '../protos/firestore_proto_api';\n\nconst DIRECTIONS = (() => {\n  const dirs: { [dir: string]: api.OrderDirection } = {};\n  dirs[Direction.ASCENDING] = 'ASCENDING';\n  dirs[Direction.DESCENDING] = 'DESCENDING';\n  return dirs;\n})();\n\nconst OPERATORS = (() => {\n  const ops: { [op: string]: api.FieldFilterOp } = {};\n  ops[Operator.LESS_THAN] = 'LESS_THAN';\n  ops[Operator.LESS_THAN_OR_EQUAL] = 'LESS_THAN_OR_EQUAL';\n  ops[Operator.GREATER_THAN] = 'GREATER_THAN';\n  ops[Operator.GREATER_THAN_OR_EQUAL] = 'GREATER_THAN_OR_EQUAL';\n  ops[Operator.EQUAL] = 'EQUAL';\n  ops[Operator.NOT_EQUAL] = 'NOT_EQUAL';\n  ops[Operator.ARRAY_CONTAINS] = 'ARRAY_CONTAINS';\n  ops[Operator.IN] = 'IN';\n  ops[Operator.NOT_IN] = 'NOT_IN';\n  ops[Operator.ARRAY_CONTAINS_ANY] = 'ARRAY_CONTAINS_ANY';\n  return ops;\n})();\n\nfunction assertPresent(value: unknown, description: string): asserts value {\n  debugAssert(!isNullOrUndefined(value), description + ' is missing');\n}\n\n/**\n * This class generates JsonObject values for the Datastore API suitable for\n * sending to either GRPC stub methods or via the JSON/HTTP REST API.\n *\n * The serializer supports both Protobuf.js and Proto3 JSON formats. By\n * setting `useProto3Json` to true, the serializer will use the Proto3 JSON\n * format.\n *\n * For a description of the Proto3 JSON format check\n * https://developers.google.com/protocol-buffers/docs/proto3#json\n *\n * TODO(klimt): We can remove the databaseId argument if we keep the full\n * resource name in documents.\n */\nexport class JsonProtoSerializer {\n  constructor(\n    readonly databaseId: DatabaseId,\n    readonly useProto3Json: boolean\n  ) {}\n}\n\nfunction fromRpcStatus(status: api.Status): FirestoreError {\n  const code =\n    status.code === undefined ? Code.UNKNOWN : mapCodeFromRpcCode(status.code);\n  return new FirestoreError(code, status.message || '');\n}\n\n/**\n * Returns a value for a number (or null) that's appropriate to put into\n * a google.protobuf.Int32Value proto.\n * DO NOT USE THIS FOR ANYTHING ELSE.\n * This method cheats. It's typed as returning \"number\" because that's what\n * our generated proto interfaces say Int32Value must be. But GRPC actually\n * expects a { value: <number> } struct.\n */\nfunction toInt32Proto(\n  serializer: JsonProtoSerializer,\n  val: number | null\n): number | { value: number } | null {\n  if (serializer.useProto3Json || isNullOrUndefined(val)) {\n    return val;\n  } else {\n    return { value: val };\n  }\n}\n\n/**\n * Returns a number (or null) from a google.protobuf.Int32Value proto.\n */\nfunction fromInt32Proto(\n  val: number | { value: number } | undefined\n): number | null {\n  let result;\n  if (typeof val === 'object') {\n    result = val.value;\n  } else {\n    result = val;\n  }\n  return isNullOrUndefined(result) ? null : result;\n}\n\n/**\n * Returns an IntegerValue for `value`.\n */\nexport function toInteger(value: number): api.Value {\n  return { integerValue: '' + value };\n}\n\n/**\n * Returns an DoubleValue for `value` that is encoded based the serializer's\n * `useProto3Json` setting.\n */\nexport function toDouble(\n  serializer: JsonProtoSerializer,\n  value: number\n): api.Value {\n  if (serializer.useProto3Json) {\n    if (isNaN(value)) {\n      return { doubleValue: 'NaN' };\n    } else if (value === Infinity) {\n      return { doubleValue: 'Infinity' };\n    } else if (value === -Infinity) {\n      return { doubleValue: '-Infinity' };\n    }\n  }\n  return { doubleValue: isNegativeZero(value) ? '-0' : value };\n}\n\n/**\n * Returns a value for a number that's appropriate to put into a proto.\n * The return value is an IntegerValue if it can safely represent the value,\n * otherwise a DoubleValue is returned.\n */\nexport function toNumber(\n  serializer: JsonProtoSerializer,\n  value: number\n): api.Value {\n  return isSafeInteger(value) ? toInteger(value) : toDouble(serializer, value);\n}\n\n/**\n * Returns a value for a Date that's appropriate to put into a proto.\n */\nexport function toTimestamp(\n  serializer: JsonProtoSerializer,\n  timestamp: Timestamp\n): api.Timestamp {\n  if (serializer.useProto3Json) {\n    // Serialize to ISO-8601 date format, but with full nano resolution.\n    // Since JS Date has only millis, let's only use it for the seconds and\n    // then manually add the fractions to the end.\n    const jsDateStr = new Date(timestamp.seconds * 1000).toISOString();\n    // Remove .xxx frac part and Z in the end.\n    const strUntilSeconds = jsDateStr.replace(/\\.\\d*/, '').replace('Z', '');\n    // Pad the fraction out to 9 digits (nanos).\n    const nanoStr = ('000000000' + timestamp.nanoseconds).slice(-9);\n\n    return `${strUntilSeconds}.${nanoStr}Z`;\n  } else {\n    return {\n      seconds: '' + timestamp.seconds,\n      nanos: timestamp.nanoseconds\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    } as any;\n  }\n}\n\nfunction fromTimestamp(date: api.Timestamp): Timestamp {\n  const timestamp = normalizeTimestamp(date);\n  return new Timestamp(timestamp.seconds, timestamp.nanos);\n}\n\n/**\n * Returns a value for bytes that's appropriate to put in a proto.\n *\n * Visible for testing.\n */\nexport function toBytes(\n  serializer: JsonProtoSerializer,\n  bytes: Blob | ByteString\n): string | Uint8Array {\n  if (serializer.useProto3Json) {\n    return bytes.toBase64();\n  } else {\n    return bytes.toUint8Array();\n  }\n}\n\n/**\n * Returns a ByteString based on the proto string value.\n */\nexport function fromBytes(\n  serializer: JsonProtoSerializer,\n  value: string | Uint8Array | undefined\n): ByteString {\n  if (serializer.useProto3Json) {\n    hardAssert(\n      value === undefined || typeof value === 'string',\n      'value must be undefined or a string when using proto3 Json'\n    );\n    return ByteString.fromBase64String(value ? value : '');\n  } else {\n    hardAssert(\n      value === undefined || value instanceof Uint8Array,\n      'value must be undefined or Uint8Array'\n    );\n    return ByteString.fromUint8Array(value ? value : new Uint8Array());\n  }\n}\n\nexport function toVersion(\n  serializer: JsonProtoSerializer,\n  version: SnapshotVersion\n): api.Timestamp {\n  return toTimestamp(serializer, version.toTimestamp());\n}\n\nexport function fromVersion(version: api.Timestamp): SnapshotVersion {\n  hardAssert(!!version, \"Trying to deserialize version that isn't set\");\n  return SnapshotVersion.fromTimestamp(fromTimestamp(version));\n}\n\nexport function toResourceName(\n  databaseId: DatabaseId,\n  path: ResourcePath\n): string {\n  return fullyQualifiedPrefixPath(databaseId)\n    .child('documents')\n    .child(path)\n    .canonicalString();\n}\n\nfunction fromResourceName(name: string): ResourcePath {\n  const resource = ResourcePath.fromString(name);\n  hardAssert(\n    isValidResourceName(resource),\n    'Tried to deserialize invalid key ' + resource.toString()\n  );\n  return resource;\n}\n\nexport function toName(\n  serializer: JsonProtoSerializer,\n  key: DocumentKey\n): string {\n  return toResourceName(serializer.databaseId, key.path);\n}\n\nexport function fromName(\n  serializer: JsonProtoSerializer,\n  name: string\n): DocumentKey {\n  const resource = fromResourceName(name);\n  hardAssert(\n    resource.get(1) === serializer.databaseId.projectId,\n    'Tried to deserialize key from different project: ' +\n      resource.get(1) +\n      ' vs ' +\n      serializer.databaseId.projectId\n  );\n  hardAssert(\n    (!resource.get(3) && !serializer.databaseId.database) ||\n      resource.get(3) === serializer.databaseId.database,\n    'Tried to deserialize key from different database: ' +\n      resource.get(3) +\n      ' vs ' +\n      serializer.databaseId.database\n  );\n  return new DocumentKey(extractLocalPathFromResourceName(resource));\n}\n\nfunction toQueryPath(\n  serializer: JsonProtoSerializer,\n  path: ResourcePath\n): string {\n  return toResourceName(serializer.databaseId, path);\n}\n\nfunction fromQueryPath(name: string): ResourcePath {\n  const resourceName = fromResourceName(name);\n  // In v1beta1 queries for collections at the root did not have a trailing\n  // \"/documents\". In v1 all resource paths contain \"/documents\". Preserve the\n  // ability to read the v1beta1 form for compatibility with queries persisted\n  // in the local target cache.\n  if (resourceName.length === 4) {\n    return ResourcePath.emptyPath();\n  }\n  return extractLocalPathFromResourceName(resourceName);\n}\n\nexport function getEncodedDatabaseId(serializer: JsonProtoSerializer): string {\n  const path = new ResourcePath([\n    'projects',\n    serializer.databaseId.projectId,\n    'databases',\n    serializer.databaseId.database\n  ]);\n  return path.canonicalString();\n}\n\nfunction fullyQualifiedPrefixPath(databaseId: DatabaseId): ResourcePath {\n  return new ResourcePath([\n    'projects',\n    databaseId.projectId,\n    'databases',\n    databaseId.database\n  ]);\n}\n\nfunction extractLocalPathFromResourceName(\n  resourceName: ResourcePath\n): ResourcePath {\n  hardAssert(\n    resourceName.length > 4 && resourceName.get(4) === 'documents',\n    'tried to deserialize invalid key ' + resourceName.toString()\n  );\n  return resourceName.popFirst(5);\n}\n\n/** Creates an api.Document from key and fields (but no create/update time) */\nexport function toMutationDocument(\n  serializer: JsonProtoSerializer,\n  key: DocumentKey,\n  fields: ObjectValue\n): api.Document {\n  return {\n    name: toName(serializer, key),\n    fields: fields.proto.mapValue.fields\n  };\n}\n\nexport function toDocument(\n  serializer: JsonProtoSerializer,\n  document: Document\n): api.Document {\n  debugAssert(\n    !document.hasLocalMutations,\n    \"Can't serialize documents with mutations.\"\n  );\n  return {\n    name: toName(serializer, document.key),\n    fields: document.toProto().mapValue.fields,\n    updateTime: toTimestamp(serializer, document.version.toTimestamp())\n  };\n}\n\nexport function fromDocument(\n  serializer: JsonProtoSerializer,\n  document: api.Document,\n  hasCommittedMutations?: boolean\n): Document {\n  const key = fromName(serializer, document.name!);\n  const version = fromVersion(document.updateTime!);\n  const data = new ObjectValue({ mapValue: { fields: document.fields } });\n  return new Document(key, version, data, {\n    hasCommittedMutations: !!hasCommittedMutations\n  });\n}\n\nfunction fromFound(\n  serializer: JsonProtoSerializer,\n  doc: api.BatchGetDocumentsResponse\n): Document {\n  hardAssert(\n    !!doc.found,\n    'Tried to deserialize a found document from a missing document.'\n  );\n  assertPresent(doc.found.name, 'doc.found.name');\n  assertPresent(doc.found.updateTime, 'doc.found.updateTime');\n  const key = fromName(serializer, doc.found.name);\n  const version = fromVersion(doc.found.updateTime);\n  const data = new ObjectValue({ mapValue: { fields: doc.found.fields } });\n  return new Document(key, version, data, {});\n}\n\nfunction fromMissing(\n  serializer: JsonProtoSerializer,\n  result: api.BatchGetDocumentsResponse\n): NoDocument {\n  hardAssert(\n    !!result.missing,\n    'Tried to deserialize a missing document from a found document.'\n  );\n  hardAssert(\n    !!result.readTime,\n    'Tried to deserialize a missing document without a read time.'\n  );\n  const key = fromName(serializer, result.missing);\n  const version = fromVersion(result.readTime);\n  return new NoDocument(key, version);\n}\n\nexport function fromMaybeDocument(\n  serializer: JsonProtoSerializer,\n  result: api.BatchGetDocumentsResponse\n): MaybeDocument {\n  if ('found' in result) {\n    return fromFound(serializer, result);\n  } else if ('missing' in result) {\n    return fromMissing(serializer, result);\n  }\n  return fail('invalid batch get response: ' + JSON.stringify(result));\n}\n\nexport function fromWatchChange(\n  serializer: JsonProtoSerializer,\n  change: api.ListenResponse\n): WatchChange {\n  let watchChange: WatchChange;\n  if ('targetChange' in change) {\n    assertPresent(change.targetChange, 'targetChange');\n    // proto3 default value is unset in JSON (undefined), so use 'NO_CHANGE'\n    // if unset\n    const state = fromWatchTargetChangeState(\n      change.targetChange.targetChangeType || 'NO_CHANGE'\n    );\n    const targetIds: TargetId[] = change.targetChange.targetIds || [];\n\n    const resumeToken = fromBytes(serializer, change.targetChange.resumeToken);\n    const causeProto = change.targetChange!.cause;\n    const cause = causeProto && fromRpcStatus(causeProto);\n    watchChange = new WatchTargetChange(\n      state,\n      targetIds,\n      resumeToken,\n      cause || null\n    );\n  } else if ('documentChange' in change) {\n    assertPresent(change.documentChange, 'documentChange');\n    const entityChange = change.documentChange;\n    assertPresent(entityChange.document, 'documentChange.name');\n    assertPresent(entityChange.document.name, 'documentChange.document.name');\n    assertPresent(\n      entityChange.document.updateTime,\n      'documentChange.document.updateTime'\n    );\n    const key = fromName(serializer, entityChange.document.name);\n    const version = fromVersion(entityChange.document.updateTime);\n    const data = new ObjectValue({\n      mapValue: { fields: entityChange.document.fields }\n    });\n    const doc = new Document(key, version, data, {});\n    const updatedTargetIds = entityChange.targetIds || [];\n    const removedTargetIds = entityChange.removedTargetIds || [];\n    watchChange = new DocumentWatchChange(\n      updatedTargetIds,\n      removedTargetIds,\n      doc.key,\n      doc\n    );\n  } else if ('documentDelete' in change) {\n    assertPresent(change.documentDelete, 'documentDelete');\n    const docDelete = change.documentDelete;\n    assertPresent(docDelete.document, 'documentDelete.document');\n    const key = fromName(serializer, docDelete.document);\n    const version = docDelete.readTime\n      ? fromVersion(docDelete.readTime)\n      : SnapshotVersion.min();\n    const doc = new NoDocument(key, version);\n    const removedTargetIds = docDelete.removedTargetIds || [];\n    watchChange = new DocumentWatchChange([], removedTargetIds, doc.key, doc);\n  } else if ('documentRemove' in change) {\n    assertPresent(change.documentRemove, 'documentRemove');\n    const docRemove = change.documentRemove;\n    assertPresent(docRemove.document, 'documentRemove');\n    const key = fromName(serializer, docRemove.document);\n    const removedTargetIds = docRemove.removedTargetIds || [];\n    watchChange = new DocumentWatchChange([], removedTargetIds, key, null);\n  } else if ('filter' in change) {\n    // TODO(dimond): implement existence filter parsing with strategy.\n    assertPresent(change.filter, 'filter');\n    const filter = change.filter;\n    assertPresent(filter.targetId, 'filter.targetId');\n    const count = filter.count || 0;\n    const existenceFilter = new ExistenceFilter(count);\n    const targetId = filter.targetId;\n    watchChange = new ExistenceFilterChange(targetId, existenceFilter);\n  } else {\n    return fail('Unknown change type ' + JSON.stringify(change));\n  }\n  return watchChange;\n}\n\nfunction fromWatchTargetChangeState(\n  state: TargetChangeTargetChangeType\n): WatchTargetChangeState {\n  if (state === 'NO_CHANGE') {\n    return WatchTargetChangeState.NoChange;\n  } else if (state === 'ADD') {\n    return WatchTargetChangeState.Added;\n  } else if (state === 'REMOVE') {\n    return WatchTargetChangeState.Removed;\n  } else if (state === 'CURRENT') {\n    return WatchTargetChangeState.Current;\n  } else if (state === 'RESET') {\n    return WatchTargetChangeState.Reset;\n  } else {\n    return fail('Got unexpected TargetChange.state: ' + state);\n  }\n}\n\nexport function versionFromListenResponse(\n  change: api.ListenResponse\n): SnapshotVersion {\n  // We have only reached a consistent snapshot for the entire stream if there\n  // is a read_time set and it applies to all targets (i.e. the list of\n  // targets is empty). The backend is guaranteed to send such responses.\n  if (!('targetChange' in change)) {\n    return SnapshotVersion.min();\n  }\n  const targetChange = change.targetChange!;\n  if (targetChange.targetIds && targetChange.targetIds.length) {\n    return SnapshotVersion.min();\n  }\n  if (!targetChange.readTime) {\n    return SnapshotVersion.min();\n  }\n  return fromVersion(targetChange.readTime);\n}\n\nexport function toMutation(\n  serializer: JsonProtoSerializer,\n  mutation: Mutation\n): api.Write {\n  let result: api.Write;\n  if (mutation instanceof SetMutation) {\n    result = {\n      update: toMutationDocument(serializer, mutation.key, mutation.value)\n    };\n  } else if (mutation instanceof DeleteMutation) {\n    result = { delete: toName(serializer, mutation.key) };\n  } else if (mutation instanceof PatchMutation) {\n    result = {\n      update: toMutationDocument(serializer, mutation.key, mutation.data),\n      updateMask: toDocumentMask(mutation.fieldMask)\n    };\n  } else if (mutation instanceof TransformMutation) {\n    result = {\n      transform: {\n        document: toName(serializer, mutation.key),\n        fieldTransforms: mutation.fieldTransforms.map(transform =>\n          toFieldTransform(serializer, transform)\n        )\n      }\n    };\n  } else if (mutation instanceof VerifyMutation) {\n    result = {\n      verify: toName(serializer, mutation.key)\n    };\n  } else {\n    return fail('Unknown mutation type ' + mutation.type);\n  }\n\n  if (!mutation.precondition.isNone) {\n    result.currentDocument = toPrecondition(serializer, mutation.precondition);\n  }\n\n  return result;\n}\n\nexport function fromMutation(\n  serializer: JsonProtoSerializer,\n  proto: api.Write\n): Mutation {\n  const precondition = proto.currentDocument\n    ? fromPrecondition(proto.currentDocument)\n    : Precondition.none();\n\n  if (proto.update) {\n    assertPresent(proto.update.name, 'name');\n    const key = fromName(serializer, proto.update.name);\n    const value = new ObjectValue({\n      mapValue: { fields: proto.update.fields }\n    });\n    if (proto.updateMask) {\n      const fieldMask = fromDocumentMask(proto.updateMask);\n      return new PatchMutation(key, value, fieldMask, precondition);\n    } else {\n      return new SetMutation(key, value, precondition);\n    }\n  } else if (proto.delete) {\n    const key = fromName(serializer, proto.delete);\n    return new DeleteMutation(key, precondition);\n  } else if (proto.transform) {\n    const key = fromName(serializer, proto.transform.document!);\n    const fieldTransforms = proto.transform.fieldTransforms!.map(transform =>\n      fromFieldTransform(serializer, transform)\n    );\n    hardAssert(\n      precondition.exists === true,\n      'Transforms only support precondition \"exists == true\"'\n    );\n    return new TransformMutation(key, fieldTransforms);\n  } else if (proto.verify) {\n    const key = fromName(serializer, proto.verify);\n    return new VerifyMutation(key, precondition);\n  } else {\n    return fail('unknown mutation proto: ' + JSON.stringify(proto));\n  }\n}\n\nfunction toPrecondition(\n  serializer: JsonProtoSerializer,\n  precondition: Precondition\n): api.Precondition {\n  debugAssert(!precondition.isNone, \"Can't serialize an empty precondition\");\n  if (precondition.updateTime !== undefined) {\n    return {\n      updateTime: toVersion(serializer, precondition.updateTime)\n    };\n  } else if (precondition.exists !== undefined) {\n    return { exists: precondition.exists };\n  } else {\n    return fail('Unknown precondition');\n  }\n}\n\nfunction fromPrecondition(precondition: api.Precondition): Precondition {\n  if (precondition.updateTime !== undefined) {\n    return Precondition.updateTime(fromVersion(precondition.updateTime));\n  } else if (precondition.exists !== undefined) {\n    return Precondition.exists(precondition.exists);\n  } else {\n    return Precondition.none();\n  }\n}\n\nfunction fromWriteResult(\n  proto: WriteResult,\n  commitTime: api.Timestamp\n): MutationResult {\n  // NOTE: Deletes don't have an updateTime.\n  let version = proto.updateTime\n    ? fromVersion(proto.updateTime)\n    : fromVersion(commitTime);\n\n  if (version.isEqual(SnapshotVersion.min())) {\n    // The Firestore Emulator currently returns an update time of 0 for\n    // deletes of non-existing documents (rather than null). This breaks the\n    // test \"get deleted doc while offline with source=cache\" as NoDocuments\n    // with version 0 are filtered by IndexedDb's RemoteDocumentCache.\n    // TODO(#2149): Remove this when Emulator is fixed\n    version = fromVersion(commitTime);\n  }\n\n  let transformResults: api.Value[] | null = null;\n  if (proto.transformResults && proto.transformResults.length > 0) {\n    transformResults = proto.transformResults;\n  }\n  return new MutationResult(version, transformResults);\n}\n\nexport function fromWriteResults(\n  protos: WriteResult[] | undefined,\n  commitTime?: api.Timestamp\n): MutationResult[] {\n  if (protos && protos.length > 0) {\n    hardAssert(\n      commitTime !== undefined,\n      'Received a write result without a commit time'\n    );\n    return protos.map(proto => fromWriteResult(proto, commitTime));\n  } else {\n    return [];\n  }\n}\n\nfunction toFieldTransform(\n  serializer: JsonProtoSerializer,\n  fieldTransform: FieldTransform\n): api.FieldTransform {\n  const transform = fieldTransform.transform;\n  if (transform instanceof ServerTimestampTransform) {\n    return {\n      fieldPath: fieldTransform.field.canonicalString(),\n      setToServerValue: 'REQUEST_TIME'\n    };\n  } else if (transform instanceof ArrayUnionTransformOperation) {\n    return {\n      fieldPath: fieldTransform.field.canonicalString(),\n      appendMissingElements: {\n        values: transform.elements\n      }\n    };\n  } else if (transform instanceof ArrayRemoveTransformOperation) {\n    return {\n      fieldPath: fieldTransform.field.canonicalString(),\n      removeAllFromArray: {\n        values: transform.elements\n      }\n    };\n  } else if (transform instanceof NumericIncrementTransformOperation) {\n    return {\n      fieldPath: fieldTransform.field.canonicalString(),\n      increment: transform.operand\n    };\n  } else {\n    throw fail('Unknown transform: ' + fieldTransform.transform);\n  }\n}\n\nfunction fromFieldTransform(\n  serializer: JsonProtoSerializer,\n  proto: api.FieldTransform\n): FieldTransform {\n  let transform: TransformOperation | null = null;\n  if ('setToServerValue' in proto) {\n    hardAssert(\n      proto.setToServerValue === 'REQUEST_TIME',\n      'Unknown server value transform proto: ' + JSON.stringify(proto)\n    );\n    transform = new ServerTimestampTransform();\n  } else if ('appendMissingElements' in proto) {\n    const values = proto.appendMissingElements!.values || [];\n    transform = new ArrayUnionTransformOperation(values);\n  } else if ('removeAllFromArray' in proto) {\n    const values = proto.removeAllFromArray!.values || [];\n    transform = new ArrayRemoveTransformOperation(values);\n  } else if ('increment' in proto) {\n    transform = new NumericIncrementTransformOperation(\n      serializer,\n      proto.increment!\n    );\n  } else {\n    fail('Unknown transform proto: ' + JSON.stringify(proto));\n  }\n  const fieldPath = FieldPath.fromServerFormat(proto.fieldPath!);\n  return new FieldTransform(fieldPath, transform!);\n}\n\nexport function toDocumentsTarget(\n  serializer: JsonProtoSerializer,\n  target: Target\n): api.DocumentsTarget {\n  return { documents: [toQueryPath(serializer, target.path)] };\n}\n\nexport function fromDocumentsTarget(\n  documentsTarget: api.DocumentsTarget\n): Target {\n  const count = documentsTarget.documents!.length;\n  hardAssert(\n    count === 1,\n    'DocumentsTarget contained other than 1 document: ' + count\n  );\n  const name = documentsTarget.documents![0];\n  return queryToTarget(newQueryForPath(fromQueryPath(name)));\n}\n\nexport function toQueryTarget(\n  serializer: JsonProtoSerializer,\n  target: Target\n): api.QueryTarget {\n  // Dissect the path into parent, collectionId, and optional key filter.\n  const result: api.QueryTarget = { structuredQuery: {} };\n  const path = target.path;\n  if (target.collectionGroup !== null) {\n    debugAssert(\n      path.length % 2 === 0,\n      'Collection Group queries should be within a document path or root.'\n    );\n    result.parent = toQueryPath(serializer, path);\n    result.structuredQuery!.from = [\n      {\n        collectionId: target.collectionGroup,\n        allDescendants: true\n      }\n    ];\n  } else {\n    debugAssert(\n      path.length % 2 !== 0,\n      'Document queries with filters are not supported.'\n    );\n    result.parent = toQueryPath(serializer, path.popLast());\n    result.structuredQuery!.from = [{ collectionId: path.lastSegment() }];\n  }\n\n  const where = toFilter(target.filters);\n  if (where) {\n    result.structuredQuery!.where = where;\n  }\n\n  const orderBy = toOrder(target.orderBy);\n  if (orderBy) {\n    result.structuredQuery!.orderBy = orderBy;\n  }\n\n  const limit = toInt32Proto(serializer, target.limit);\n  if (limit !== null) {\n    result.structuredQuery!.limit = limit;\n  }\n\n  if (target.startAt) {\n    result.structuredQuery!.startAt = toCursor(target.startAt);\n  }\n  if (target.endAt) {\n    result.structuredQuery!.endAt = toCursor(target.endAt);\n  }\n\n  return result;\n}\n\nexport function fromQueryTarget(target: api.QueryTarget): Target {\n  let path = fromQueryPath(target.parent!);\n\n  const query = target.structuredQuery!;\n  const fromCount = query.from ? query.from.length : 0;\n  let collectionGroup: string | null = null;\n  if (fromCount > 0) {\n    hardAssert(\n      fromCount === 1,\n      'StructuredQuery.from with more than one collection is not supported.'\n    );\n    const from = query.from![0];\n    if (from.allDescendants) {\n      collectionGroup = from.collectionId!;\n    } else {\n      path = path.child(from.collectionId!);\n    }\n  }\n\n  let filterBy: Filter[] = [];\n  if (query.where) {\n    filterBy = fromFilter(query.where);\n  }\n\n  let orderBy: OrderBy[] = [];\n  if (query.orderBy) {\n    orderBy = fromOrder(query.orderBy);\n  }\n\n  let limit: number | null = null;\n  if (query.limit) {\n    limit = fromInt32Proto(query.limit);\n  }\n\n  let startAt: Bound | null = null;\n  if (query.startAt) {\n    startAt = fromCursor(query.startAt);\n  }\n\n  let endAt: Bound | null = null;\n  if (query.endAt) {\n    endAt = fromCursor(query.endAt);\n  }\n\n  return queryToTarget(\n    newQuery(\n      path,\n      collectionGroup,\n      orderBy,\n      filterBy,\n      limit,\n      LimitType.First,\n      startAt,\n      endAt\n    )\n  );\n}\n\nexport function toListenRequestLabels(\n  serializer: JsonProtoSerializer,\n  targetData: TargetData\n): api.ApiClientObjectMap<string> | null {\n  const value = toLabel(serializer, targetData.purpose);\n  if (value == null) {\n    return null;\n  } else {\n    return {\n      'goog-listen-tags': value\n    };\n  }\n}\n\nfunction toLabel(\n  serializer: JsonProtoSerializer,\n  purpose: TargetPurpose\n): string | null {\n  switch (purpose) {\n    case TargetPurpose.Listen:\n      return null;\n    case TargetPurpose.ExistenceFilterMismatch:\n      return 'existence-filter-mismatch';\n    case TargetPurpose.LimboResolution:\n      return 'limbo-document';\n    default:\n      return fail('Unrecognized query purpose: ' + purpose);\n  }\n}\n\nexport function toTarget(\n  serializer: JsonProtoSerializer,\n  targetData: TargetData\n): api.Target {\n  let result: api.Target;\n  const target = targetData.target;\n\n  if (isDocumentTarget(target)) {\n    result = { documents: toDocumentsTarget(serializer, target) };\n  } else {\n    result = { query: toQueryTarget(serializer, target) };\n  }\n\n  result.targetId = targetData.targetId;\n\n  if (targetData.resumeToken.approximateByteSize() > 0) {\n    result.resumeToken = toBytes(serializer, targetData.resumeToken);\n  }\n\n  return result;\n}\n\nfunction toFilter(filters: Filter[]): api.Filter | undefined {\n  if (filters.length === 0) {\n    return;\n  }\n  const protos = filters.map(filter => {\n    debugAssert(\n      filter instanceof FieldFilter,\n      'Only FieldFilters are supported'\n    );\n    return toUnaryOrFieldFilter(filter);\n  });\n  if (protos.length === 1) {\n    return protos[0];\n  }\n  return { compositeFilter: { op: 'AND', filters: protos } };\n}\n\nfunction fromFilter(filter: api.Filter | undefined): Filter[] {\n  if (!filter) {\n    return [];\n  } else if (filter.unaryFilter !== undefined) {\n    return [fromUnaryFilter(filter)];\n  } else if (filter.fieldFilter !== undefined) {\n    return [fromFieldFilter(filter)];\n  } else if (filter.compositeFilter !== undefined) {\n    return filter.compositeFilter\n      .filters!.map(f => fromFilter(f))\n      .reduce((accum, current) => accum.concat(current));\n  } else {\n    return fail('Unknown filter: ' + JSON.stringify(filter));\n  }\n}\n\nfunction toOrder(orderBys: OrderBy[]): api.Order[] | undefined {\n  if (orderBys.length === 0) {\n    return;\n  }\n  return orderBys.map(order => toPropertyOrder(order));\n}\n\nfunction fromOrder(orderBys: api.Order[]): OrderBy[] {\n  return orderBys.map(order => fromPropertyOrder(order));\n}\n\nfunction toCursor(cursor: Bound): api.Cursor {\n  return {\n    before: cursor.before,\n    values: cursor.position\n  };\n}\n\nfunction fromCursor(cursor: api.Cursor): Bound {\n  const before = !!cursor.before;\n  const position = cursor.values || [];\n  return new Bound(position, before);\n}\n\n// visible for testing\nexport function toDirection(dir: Direction): api.OrderDirection {\n  return DIRECTIONS[dir];\n}\n\n// visible for testing\nexport function fromDirection(\n  dir: api.OrderDirection | undefined\n): Direction | undefined {\n  switch (dir) {\n    case 'ASCENDING':\n      return Direction.ASCENDING;\n    case 'DESCENDING':\n      return Direction.DESCENDING;\n    default:\n      return undefined;\n  }\n}\n\n// visible for testing\nexport function toOperatorName(op: Operator): api.FieldFilterOp {\n  return OPERATORS[op];\n}\n\nexport function fromOperatorName(op: api.FieldFilterOp): Operator {\n  switch (op) {\n    case 'EQUAL':\n      return Operator.EQUAL;\n    case 'NOT_EQUAL':\n      return Operator.NOT_EQUAL;\n    case 'GREATER_THAN':\n      return Operator.GREATER_THAN;\n    case 'GREATER_THAN_OR_EQUAL':\n      return Operator.GREATER_THAN_OR_EQUAL;\n    case 'LESS_THAN':\n      return Operator.LESS_THAN;\n    case 'LESS_THAN_OR_EQUAL':\n      return Operator.LESS_THAN_OR_EQUAL;\n    case 'ARRAY_CONTAINS':\n      return Operator.ARRAY_CONTAINS;\n    case 'IN':\n      return Operator.IN;\n    case 'NOT_IN':\n      return Operator.NOT_IN;\n    case 'ARRAY_CONTAINS_ANY':\n      return Operator.ARRAY_CONTAINS_ANY;\n    case 'OPERATOR_UNSPECIFIED':\n      return fail('Unspecified operator');\n    default:\n      return fail('Unknown operator');\n  }\n}\n\nexport function toFieldPathReference(path: FieldPath): api.FieldReference {\n  return { fieldPath: path.canonicalString() };\n}\n\nexport function fromFieldPathReference(\n  fieldReference: api.FieldReference\n): FieldPath {\n  return FieldPath.fromServerFormat(fieldReference.fieldPath!);\n}\n\n// visible for testing\nexport function toPropertyOrder(orderBy: OrderBy): api.Order {\n  return {\n    field: toFieldPathReference(orderBy.field),\n    direction: toDirection(orderBy.dir)\n  };\n}\n\nexport function fromPropertyOrder(orderBy: api.Order): OrderBy {\n  return new OrderBy(\n    fromFieldPathReference(orderBy.field!),\n    fromDirection(orderBy.direction)\n  );\n}\n\nexport function fromFieldFilter(filter: api.Filter): Filter {\n  return FieldFilter.create(\n    fromFieldPathReference(filter.fieldFilter!.field!),\n    fromOperatorName(filter.fieldFilter!.op!),\n    filter.fieldFilter!.value!\n  );\n}\n\n// visible for testing\nexport function toUnaryOrFieldFilter(filter: FieldFilter): api.Filter {\n  if (filter.op === Operator.EQUAL) {\n    if (isNanValue(filter.value)) {\n      return {\n        unaryFilter: {\n          field: toFieldPathReference(filter.field),\n          op: 'IS_NAN'\n        }\n      };\n    } else if (isNullValue(filter.value)) {\n      return {\n        unaryFilter: {\n          field: toFieldPathReference(filter.field),\n          op: 'IS_NULL'\n        }\n      };\n    }\n  } else if (filter.op === Operator.NOT_EQUAL) {\n    if (isNanValue(filter.value)) {\n      return {\n        unaryFilter: {\n          field: toFieldPathReference(filter.field),\n          op: 'IS_NOT_NAN'\n        }\n      };\n    } else if (isNullValue(filter.value)) {\n      return {\n        unaryFilter: {\n          field: toFieldPathReference(filter.field),\n          op: 'IS_NOT_NULL'\n        }\n      };\n    }\n  }\n  return {\n    fieldFilter: {\n      field: toFieldPathReference(filter.field),\n      op: toOperatorName(filter.op),\n      value: filter.value\n    }\n  };\n}\n\nexport function fromUnaryFilter(filter: api.Filter): Filter {\n  switch (filter.unaryFilter!.op!) {\n    case 'IS_NAN':\n      const nanField = fromFieldPathReference(filter.unaryFilter!.field!);\n      return FieldFilter.create(nanField, Operator.EQUAL, {\n        doubleValue: NaN\n      });\n    case 'IS_NULL':\n      const nullField = fromFieldPathReference(filter.unaryFilter!.field!);\n      return FieldFilter.create(nullField, Operator.EQUAL, {\n        nullValue: 'NULL_VALUE'\n      });\n    case 'IS_NOT_NAN':\n      const notNanField = fromFieldPathReference(filter.unaryFilter!.field!);\n      return FieldFilter.create(notNanField, Operator.NOT_EQUAL, {\n        doubleValue: NaN\n      });\n    case 'IS_NOT_NULL':\n      const notNullField = fromFieldPathReference(filter.unaryFilter!.field!);\n      return FieldFilter.create(notNullField, Operator.NOT_EQUAL, {\n        nullValue: 'NULL_VALUE'\n      });\n    case 'OPERATOR_UNSPECIFIED':\n      return fail('Unspecified filter');\n    default:\n      return fail('Unknown filter');\n  }\n}\n\nexport function toDocumentMask(fieldMask: FieldMask): api.DocumentMask {\n  const canonicalFields: string[] = [];\n  fieldMask.fields.forEach(field =>\n    canonicalFields.push(field.canonicalString())\n  );\n  return {\n    fieldPaths: canonicalFields\n  };\n}\n\nexport function fromDocumentMask(proto: api.DocumentMask): FieldMask {\n  const paths = proto.fieldPaths || [];\n  return new FieldMask(paths.map(path => FieldPath.fromServerFormat(path)));\n}\n\nexport function isValidResourceName(path: ResourcePath): boolean {\n  // Resource names have at least 4 components (project ID, database ID)\n  return (\n    path.length >= 4 &&\n    path.get(0) === 'projects' &&\n    path.get(2) === 'databases'\n  );\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from '../api/timestamp';\nimport { debugAssert } from '../util/assert';\nimport { JsonProtoSerializer, toDouble, toInteger } from '../remote/serializer';\nimport {\n  isArray,\n  isInteger,\n  isNumber,\n  normalizeNumber,\n  valueEquals\n} from './values';\nimport { serverTimestamp } from './server_timestamps';\nimport { arrayEquals } from '../util/misc';\n\n/** Represents a transform within a TransformMutation. */\nexport class TransformOperation {\n  // Make sure that the structural type of `TransformOperation` is unique.\n  // See https://github.com/microsoft/TypeScript/issues/5451\n  private _ = undefined;\n}\n\n/**\n * Computes the local transform result against the provided `previousValue`,\n * optionally using the provided localWriteTime.\n */\nexport function applyTransformOperationToLocalView(\n  transform: TransformOperation,\n  previousValue: api.Value | null,\n  localWriteTime: Timestamp\n): api.Value {\n  if (transform instanceof ServerTimestampTransform) {\n    return serverTimestamp(localWriteTime, previousValue);\n  } else if (transform instanceof ArrayUnionTransformOperation) {\n    return applyArrayUnionTransformOperation(transform, previousValue);\n  } else if (transform instanceof ArrayRemoveTransformOperation) {\n    return applyArrayRemoveTransformOperation(transform, previousValue);\n  } else {\n    debugAssert(\n      transform instanceof NumericIncrementTransformOperation,\n      'Expected NumericIncrementTransformOperation but was: ' + transform\n    );\n    return applyNumericIncrementTransformOperationToLocalView(\n      transform,\n      previousValue\n    );\n  }\n}\n\n/**\n * Computes a final transform result after the transform has been acknowledged\n * by the server, potentially using the server-provided transformResult.\n */\nexport function applyTransformOperationToRemoteDocument(\n  transform: TransformOperation,\n  previousValue: api.Value | null,\n  transformResult: api.Value | null\n): api.Value {\n  // The server just sends null as the transform result for array operations,\n  // so we have to calculate a result the same as we do for local\n  // applications.\n  if (transform instanceof ArrayUnionTransformOperation) {\n    return applyArrayUnionTransformOperation(transform, previousValue);\n  } else if (transform instanceof ArrayRemoveTransformOperation) {\n    return applyArrayRemoveTransformOperation(transform, previousValue);\n  }\n\n  debugAssert(\n    transformResult !== null,\n    \"Didn't receive transformResult for non-array transform\"\n  );\n  return transformResult;\n}\n\n/**\n * If this transform operation is not idempotent, returns the base value to\n * persist for this transform. If a base value is returned, the transform\n * operation is always applied to this base value, even if document has\n * already been updated.\n *\n * Base values provide consistent behavior for non-idempotent transforms and\n * allow us to return the same latency-compensated value even if the backend\n * has already applied the transform operation. The base value is null for\n * idempotent transforms, as they can be re-played even if the backend has\n * already applied them.\n *\n * @return a base value to store along with the mutation, or null for\n * idempotent transforms.\n */\nexport function computeTransformOperationBaseValue(\n  transform: TransformOperation,\n  previousValue: api.Value | null\n): api.Value | null {\n  if (transform instanceof NumericIncrementTransformOperation) {\n    return isNumber(previousValue) ? previousValue! : { integerValue: 0 };\n  }\n  return null;\n}\n\nexport function transformOperationEquals(\n  left: TransformOperation,\n  right: TransformOperation\n): boolean {\n  if (\n    left instanceof ArrayUnionTransformOperation &&\n    right instanceof ArrayUnionTransformOperation\n  ) {\n    return arrayEquals(left.elements, right.elements, valueEquals);\n  } else if (\n    left instanceof ArrayRemoveTransformOperation &&\n    right instanceof ArrayRemoveTransformOperation\n  ) {\n    return arrayEquals(left.elements, right.elements, valueEquals);\n  } else if (\n    left instanceof NumericIncrementTransformOperation &&\n    right instanceof NumericIncrementTransformOperation\n  ) {\n    return valueEquals(left.operand, right.operand);\n  }\n\n  return (\n    left instanceof ServerTimestampTransform &&\n    right instanceof ServerTimestampTransform\n  );\n}\n\n/** Transforms a value into a server-generated timestamp. */\nexport class ServerTimestampTransform extends TransformOperation {}\n\n/** Transforms an array value via a union operation. */\nexport class ArrayUnionTransformOperation extends TransformOperation {\n  constructor(readonly elements: api.Value[]) {\n    super();\n  }\n}\n\nfunction applyArrayUnionTransformOperation(\n  transform: ArrayUnionTransformOperation,\n  previousValue: api.Value | null\n): api.Value {\n  const values = coercedFieldValuesArray(previousValue);\n  for (const toUnion of transform.elements) {\n    if (!values.some(element => valueEquals(element, toUnion))) {\n      values.push(toUnion);\n    }\n  }\n  return { arrayValue: { values } };\n}\n\n/** Transforms an array value via a remove operation. */\nexport class ArrayRemoveTransformOperation extends TransformOperation {\n  constructor(readonly elements: api.Value[]) {\n    super();\n  }\n}\n\nfunction applyArrayRemoveTransformOperation(\n  transform: ArrayRemoveTransformOperation,\n  previousValue: api.Value | null\n): api.Value {\n  let values = coercedFieldValuesArray(previousValue);\n  for (const toRemove of transform.elements) {\n    values = values.filter(element => !valueEquals(element, toRemove));\n  }\n  return { arrayValue: { values } };\n}\n\n/**\n * Implements the backend semantics for locally computed NUMERIC_ADD (increment)\n * transforms. Converts all field values to integers or doubles, but unlike the\n * backend does not cap integer values at 2^63. Instead, JavaScript number\n * arithmetic is used and precision loss can occur for values greater than 2^53.\n */\nexport class NumericIncrementTransformOperation extends TransformOperation {\n  constructor(\n    readonly serializer: JsonProtoSerializer,\n    readonly operand: api.Value\n  ) {\n    super();\n    debugAssert(\n      isNumber(operand),\n      'NumericIncrementTransform transform requires a NumberValue'\n    );\n  }\n}\n\nexport function applyNumericIncrementTransformOperationToLocalView(\n  transform: NumericIncrementTransformOperation,\n  previousValue: api.Value | null\n): api.Value {\n  // PORTING NOTE: Since JavaScript's integer arithmetic is limited to 53 bit\n  // precision and resolves overflows by reducing precision, we do not\n  // manually cap overflows at 2^63.\n  const baseValue = computeTransformOperationBaseValue(\n    transform,\n    previousValue\n  )!;\n  const sum = asNumber(baseValue) + asNumber(transform.operand);\n  if (isInteger(baseValue) && isInteger(transform.operand)) {\n    return toInteger(sum);\n  } else {\n    return toDouble(transform.serializer, sum);\n  }\n}\n\nfunction asNumber(value: api.Value): number {\n  return normalizeNumber(value.integerValue || value.doubleValue);\n}\n\nfunction coercedFieldValuesArray(value: api.Value | null): api.Value[] {\n  return isArray(value) && value.arrayValue.values\n    ? value.arrayValue.values.slice()\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 * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert, hardAssert } from '../util/assert';\n\nimport {\n  Document,\n  MaybeDocument,\n  NoDocument,\n  UnknownDocument\n} from './document';\nimport { DocumentKey } from './document_key';\nimport { ObjectValue, ObjectValueBuilder } from './object_value';\nimport { FieldPath } from './path';\nimport {\n  applyTransformOperationToLocalView,\n  applyTransformOperationToRemoteDocument,\n  computeTransformOperationBaseValue,\n  TransformOperation,\n  transformOperationEquals\n} from './transform_operation';\nimport { arrayEquals } from '../util/misc';\n\n/**\n * Provides a set of fields that can be used to partially patch a document.\n * FieldMask is used in conjunction with ObjectValue.\n * Examples:\n *   foo - Overwrites foo entirely with the provided value. If foo is not\n *         present in the companion ObjectValue, the field is deleted.\n *   foo.bar - Overwrites only the field bar of the object foo.\n *             If foo is not an object, foo is replaced with an object\n *             containing foo\n */\nexport class FieldMask {\n  constructor(readonly fields: FieldPath[]) {\n    // TODO(dimond): validation of FieldMask\n    // Sort the field mask to support `FieldMask.isEqual()` and assert below.\n    fields.sort(FieldPath.comparator);\n    debugAssert(\n      !fields.some((v, i) => i !== 0 && v.isEqual(fields[i - 1])),\n      'FieldMask contains field that is not unique: ' +\n        fields.find((v, i) => i !== 0 && v.isEqual(fields[i - 1]))!\n    );\n  }\n\n  /**\n   * Verifies that `fieldPath` is included by at least one field in this field\n   * mask.\n   *\n   * This is an O(n) operation, where `n` is the size of the field mask.\n   */\n  covers(fieldPath: FieldPath): boolean {\n    for (const fieldMaskPath of this.fields) {\n      if (fieldMaskPath.isPrefixOf(fieldPath)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  isEqual(other: FieldMask): boolean {\n    return arrayEquals(this.fields, other.fields, (l, r) => l.isEqual(r));\n  }\n}\n\n/** A field path and the TransformOperation to perform upon it. */\nexport class FieldTransform {\n  constructor(\n    readonly field: FieldPath,\n    readonly transform: TransformOperation\n  ) {}\n}\n\nexport function fieldTransformEquals(\n  left: FieldTransform,\n  right: FieldTransform\n): boolean {\n  return (\n    left.field.isEqual(right.field) &&\n    transformOperationEquals(left.transform, right.transform)\n  );\n}\n\n/** The result of successfully applying a mutation to the backend. */\nexport class MutationResult {\n  constructor(\n    /**\n     * The version at which the mutation was committed:\n     *\n     * - For most operations, this is the updateTime in the WriteResult.\n     * - For deletes, the commitTime of the WriteResponse (because deletes are\n     *   not stored and have no updateTime).\n     *\n     * Note that these versions can be different: No-op writes will not change\n     * the updateTime even though the commitTime advances.\n     */\n    readonly version: SnapshotVersion,\n    /**\n     * The resulting fields returned from the backend after a\n     * TransformMutation has been committed. Contains one FieldValue for each\n     * FieldTransform that was in the mutation.\n     *\n     * Will be null if the mutation was not a TransformMutation.\n     */\n    readonly transformResults: Array<api.Value | null> | null\n  ) {}\n}\n\nexport const enum MutationType {\n  Set,\n  Patch,\n  Transform,\n  Delete,\n  Verify\n}\n\n/**\n * Encodes a precondition for a mutation. This follows the model that the\n * backend accepts with the special case of an explicit \"empty\" precondition\n * (meaning no precondition).\n */\nexport class Precondition {\n  private constructor(\n    readonly updateTime?: SnapshotVersion,\n    readonly exists?: boolean\n  ) {\n    debugAssert(\n      updateTime === undefined || exists === undefined,\n      'Precondition can specify \"exists\" or \"updateTime\" but not both'\n    );\n  }\n\n  /** Creates a new empty Precondition. */\n  static none(): Precondition {\n    return new Precondition();\n  }\n\n  /** Creates a new Precondition with an exists flag. */\n  static exists(exists: boolean): Precondition {\n    return new Precondition(undefined, exists);\n  }\n\n  /** Creates a new Precondition based on a version a document exists at. */\n  static updateTime(version: SnapshotVersion): Precondition {\n    return new Precondition(version);\n  }\n\n  /** Returns whether this Precondition is empty. */\n  get isNone(): boolean {\n    return this.updateTime === undefined && this.exists === undefined;\n  }\n\n  isEqual(other: Precondition): boolean {\n    return (\n      this.exists === other.exists &&\n      (this.updateTime\n        ? !!other.updateTime && this.updateTime.isEqual(other.updateTime)\n        : !other.updateTime)\n    );\n  }\n}\n\n/**\n * Returns true if the preconditions is valid for the given document\n * (or null if no document is available).\n */\nexport function preconditionIsValidForDocument(\n  precondition: Precondition,\n  maybeDoc: MaybeDocument | null\n): boolean {\n  if (precondition.updateTime !== undefined) {\n    return (\n      maybeDoc instanceof Document &&\n      maybeDoc.version.isEqual(precondition.updateTime)\n    );\n  } else if (precondition.exists !== undefined) {\n    return precondition.exists === maybeDoc instanceof Document;\n  } else {\n    debugAssert(precondition.isNone, 'Precondition should be empty');\n    return true;\n  }\n}\n\n/**\n * A mutation describes a self-contained change to a document. Mutations can\n * create, replace, delete, and update subsets of documents.\n *\n * Mutations not only act on the value of the document but also its version.\n *\n * For local mutations (mutations that haven't been committed yet), we preserve\n * the existing version for Set, Patch, and Transform mutations. For Delete\n * mutations, we reset the version to 0.\n *\n * Here's the expected transition table.\n *\n * MUTATION           APPLIED TO            RESULTS IN\n *\n * SetMutation        Document(v3)          Document(v3)\n * SetMutation        NoDocument(v3)        Document(v0)\n * SetMutation        null                  Document(v0)\n * PatchMutation      Document(v3)          Document(v3)\n * PatchMutation      NoDocument(v3)        NoDocument(v3)\n * PatchMutation      null                  null\n * TransformMutation  Document(v3)          Document(v3)\n * TransformMutation  NoDocument(v3)        NoDocument(v3)\n * TransformMutation  null                  null\n * DeleteMutation     Document(v3)          NoDocument(v0)\n * DeleteMutation     NoDocument(v3)        NoDocument(v0)\n * DeleteMutation     null                  NoDocument(v0)\n *\n * For acknowledged mutations, we use the updateTime of the WriteResponse as\n * the resulting version for Set, Patch, and Transform mutations. As deletes\n * have no explicit update time, we use the commitTime of the WriteResponse for\n * Delete mutations.\n *\n * If a mutation is acknowledged by the backend but fails the precondition check\n * locally, we return an `UnknownDocument` and rely on Watch to send us the\n * updated version.\n *\n * Note that TransformMutations don't create Documents (in the case of being\n * applied to a NoDocument), even though they would on the backend. This is\n * because the client always combines the TransformMutation with a SetMutation\n * or PatchMutation and we only want to apply the transform if the prior\n * mutation resulted in a Document (always true for a SetMutation, but not\n * necessarily for a PatchMutation).\n *\n * ## Subclassing Notes\n *\n * Subclasses of Mutation need to implement applyToRemoteDocument() and\n * applyToLocalView() to implement the actual behavior of applying the mutation\n * to some source document.\n */\nexport abstract class Mutation {\n  abstract readonly type: MutationType;\n  abstract readonly key: DocumentKey;\n  abstract readonly precondition: Precondition;\n}\n\n/**\n * Applies this mutation to the given MaybeDocument or null for the purposes\n * of computing a new remote document. If the input document doesn't match the\n * expected state (e.g. it is null or outdated), an `UnknownDocument` can be\n * returned.\n *\n * @param mutation The mutation to apply.\n * @param maybeDoc The document to mutate. The input document can be null if\n *     the client has no knowledge of the pre-mutation state of the document.\n * @param mutationResult The result of applying the mutation from the backend.\n * @return The mutated document. The returned document may be an\n *     UnknownDocument if the mutation could not be applied to the locally\n *     cached base document.\n */\nexport function applyMutationToRemoteDocument(\n  mutation: Mutation,\n  maybeDoc: MaybeDocument | null,\n  mutationResult: MutationResult\n): MaybeDocument {\n  verifyMutationKeyMatches(mutation, maybeDoc);\n  if (mutation instanceof SetMutation) {\n    return applySetMutationToRemoteDocument(mutation, maybeDoc, mutationResult);\n  } else if (mutation instanceof PatchMutation) {\n    return applyPatchMutationToRemoteDocument(\n      mutation,\n      maybeDoc,\n      mutationResult\n    );\n  } else if (mutation instanceof TransformMutation) {\n    return applyTransformMutationToRemoteDocument(\n      mutation,\n      maybeDoc,\n      mutationResult\n    );\n  } else {\n    debugAssert(\n      mutation instanceof DeleteMutation,\n      'Unexpected mutation type: ' + mutation\n    );\n    return applyDeleteMutationToRemoteDocument(\n      mutation,\n      maybeDoc,\n      mutationResult\n    );\n  }\n}\n\n/**\n * Applies this mutation to the given MaybeDocument or null for the purposes\n * of computing the new local view of a document. Both the input and returned\n * documents can be null.\n *\n * @param mutation The mutation to apply.\n * @param maybeDoc The document to mutate. The input document can be null if\n *     the client has no knowledge of the pre-mutation state of the document.\n * @param baseDoc The state of the document prior to this mutation batch. The\n *     input document can be null if the client has no knowledge of the\n *     pre-mutation state of the document.\n * @param localWriteTime A timestamp indicating the local write time of the\n *     batch this mutation is a part of.\n * @return The mutated document. The returned document may be null, but only\n *     if maybeDoc was null and the mutation would not create a new document.\n */\nexport function applyMutationToLocalView(\n  mutation: Mutation,\n  maybeDoc: MaybeDocument | null,\n  baseDoc: MaybeDocument | null,\n  localWriteTime: Timestamp\n): MaybeDocument | null {\n  verifyMutationKeyMatches(mutation, maybeDoc);\n\n  if (mutation instanceof SetMutation) {\n    return applySetMutationToLocalView(mutation, maybeDoc);\n  } else if (mutation instanceof PatchMutation) {\n    return applyPatchMutationToLocalView(mutation, maybeDoc);\n  } else if (mutation instanceof TransformMutation) {\n    return applyTransformMutationToLocalView(\n      mutation,\n      maybeDoc,\n      localWriteTime,\n      baseDoc\n    );\n  } else {\n    debugAssert(\n      mutation instanceof DeleteMutation,\n      'Unexpected mutation type: ' + mutation\n    );\n    return applyDeleteMutationToLocalView(mutation, maybeDoc);\n  }\n}\n\n/**\n * If this mutation is not idempotent, returns the base value to persist with\n * this mutation. If a base value is returned, the mutation is always applied\n * to this base value, even if document has already been updated.\n *\n * The base value is a sparse object that consists of only the document\n * fields for which this mutation contains a non-idempotent transformation\n * (e.g. a numeric increment). The provided value guarantees consistent\n * behavior for non-idempotent transforms and allow us to return the same\n * latency-compensated value even if the backend has already applied the\n * mutation. The base value is null for idempotent mutations, as they can be\n * re-played even if the backend has already applied them.\n *\n * @return a base value to store along with the mutation, or null for\n * idempotent mutations.\n */\nexport function extractMutationBaseValue(\n  mutation: Mutation,\n  maybeDoc: MaybeDocument | null\n): ObjectValue | null {\n  if (mutation instanceof TransformMutation) {\n    return extractTransformMutationBaseValue(mutation, maybeDoc);\n  }\n  return null;\n}\n\nexport function mutationEquals(left: Mutation, right: Mutation): boolean {\n  if (left.type !== right.type) {\n    return false;\n  }\n\n  if (!left.key.isEqual(right.key)) {\n    return false;\n  }\n\n  if (!left.precondition.isEqual(right.precondition)) {\n    return false;\n  }\n\n  if (left.type === MutationType.Set) {\n    return (left as SetMutation).value.isEqual((right as SetMutation).value);\n  }\n\n  if (left.type === MutationType.Patch) {\n    return (\n      (left as PatchMutation).data.isEqual((right as PatchMutation).data) &&\n      (left as PatchMutation).fieldMask.isEqual(\n        (right as PatchMutation).fieldMask\n      )\n    );\n  }\n\n  if (left.type === MutationType.Transform) {\n    return arrayEquals(\n      (left as TransformMutation).fieldTransforms,\n      (left as TransformMutation).fieldTransforms,\n      (l, r) => fieldTransformEquals(l, r)\n    );\n  }\n\n  return true;\n}\n\nfunction verifyMutationKeyMatches(\n  mutation: Mutation,\n  maybeDoc: MaybeDocument | null\n): void {\n  if (maybeDoc != null) {\n    debugAssert(\n      maybeDoc.key.isEqual(mutation.key),\n      'Can only apply a mutation to a document with the same key'\n    );\n  }\n}\n\n/**\n * Returns the version from the given document for use as the result of a\n * mutation. Mutations are defined to return the version of the base document\n * only if it is an existing document. Deleted and unknown documents have a\n * post-mutation version of SnapshotVersion.min().\n */\nfunction getPostMutationVersion(\n  maybeDoc: MaybeDocument | null\n): SnapshotVersion {\n  if (maybeDoc instanceof Document) {\n    return maybeDoc.version;\n  } else {\n    return SnapshotVersion.min();\n  }\n}\n\n/**\n * A mutation that creates or replaces the document at the given key with the\n * object value contents.\n */\nexport class SetMutation extends Mutation {\n  constructor(\n    readonly key: DocumentKey,\n    readonly value: ObjectValue,\n    readonly precondition: Precondition\n  ) {\n    super();\n  }\n\n  readonly type: MutationType = MutationType.Set;\n}\n\nfunction applySetMutationToRemoteDocument(\n  mutation: SetMutation,\n  maybeDoc: MaybeDocument | null,\n  mutationResult: MutationResult\n): Document {\n  debugAssert(\n    mutationResult.transformResults == null,\n    'Transform results received by SetMutation.'\n  );\n\n  // Unlike applySetMutationToLocalView, if we're applying a mutation to a\n  // remote document the server has accepted the mutation so the precondition\n  // must have held.\n  return new Document(mutation.key, mutationResult.version, mutation.value, {\n    hasCommittedMutations: true\n  });\n}\n\nfunction applySetMutationToLocalView(\n  mutation: SetMutation,\n  maybeDoc: MaybeDocument | null\n): MaybeDocument | null {\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    return maybeDoc;\n  }\n\n  const version = getPostMutationVersion(maybeDoc);\n  return new Document(mutation.key, version, mutation.value, {\n    hasLocalMutations: true\n  });\n}\n\n/**\n * A mutation that modifies fields of the document at the given key with the\n * given values. The values are applied through a field mask:\n *\n *  * When a field is in both the mask and the values, the corresponding field\n *    is updated.\n *  * When a field is in neither the mask nor the values, the corresponding\n *    field is unmodified.\n *  * When a field is in the mask but not in the values, the corresponding field\n *    is deleted.\n *  * When a field is not in the mask but is in the values, the values map is\n *    ignored.\n */\nexport class PatchMutation extends Mutation {\n  constructor(\n    readonly key: DocumentKey,\n    readonly data: ObjectValue,\n    readonly fieldMask: FieldMask,\n    readonly precondition: Precondition\n  ) {\n    super();\n  }\n\n  readonly type: MutationType = MutationType.Patch;\n}\n\nfunction applyPatchMutationToRemoteDocument(\n  mutation: PatchMutation,\n  maybeDoc: MaybeDocument | null,\n  mutationResult: MutationResult\n): MaybeDocument {\n  debugAssert(\n    mutationResult.transformResults == null,\n    'Transform results received by PatchMutation.'\n  );\n\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    // Since the mutation was not rejected, we know that the  precondition\n    // matched on the backend. We therefore must not have the expected version\n    // of the document in our cache and return an UnknownDocument with the\n    // known updateTime.\n    return new UnknownDocument(mutation.key, mutationResult.version);\n  }\n\n  const newData = patchDocument(mutation, maybeDoc);\n  return new Document(mutation.key, mutationResult.version, newData, {\n    hasCommittedMutations: true\n  });\n}\n\nfunction applyPatchMutationToLocalView(\n  mutation: PatchMutation,\n  maybeDoc: MaybeDocument | null\n): MaybeDocument | null {\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    return maybeDoc;\n  }\n\n  const version = getPostMutationVersion(maybeDoc);\n  const newData = patchDocument(mutation, maybeDoc);\n  return new Document(mutation.key, version, newData, {\n    hasLocalMutations: true\n  });\n}\n\n/**\n * Patches the data of document if available or creates a new document. Note\n * that this does not check whether or not the precondition of this patch\n * holds.\n */\nfunction patchDocument(\n  mutation: PatchMutation,\n  maybeDoc: MaybeDocument | null\n): ObjectValue {\n  let data: ObjectValue;\n  if (maybeDoc instanceof Document) {\n    data = maybeDoc.data();\n  } else {\n    data = ObjectValue.empty();\n  }\n  return patchObject(mutation, data);\n}\n\nfunction patchObject(mutation: PatchMutation, data: ObjectValue): ObjectValue {\n  const builder = new ObjectValueBuilder(data);\n  mutation.fieldMask.fields.forEach(fieldPath => {\n    if (!fieldPath.isEmpty()) {\n      const newValue = mutation.data.field(fieldPath);\n      if (newValue !== null) {\n        builder.set(fieldPath, newValue);\n      } else {\n        builder.delete(fieldPath);\n      }\n    }\n  });\n  return builder.build();\n}\n\n/**\n * A mutation that modifies specific fields of the document with transform\n * operations. Currently the only supported transform is a server timestamp, but\n * IP Address, increment(n), etc. could be supported in the future.\n *\n * It is somewhat similar to a PatchMutation in that it patches specific fields\n * and has no effect when applied to a null or NoDocument (see comment on\n * Mutation for rationale).\n */\nexport class TransformMutation extends Mutation {\n  readonly type: MutationType = MutationType.Transform;\n\n  // NOTE: We set a precondition of exists: true as a safety-check, since we\n  // always combine TransformMutations with a SetMutation or PatchMutation which\n  // (if successful) should end up with an existing document.\n  readonly precondition = Precondition.exists(true);\n\n  constructor(\n    readonly key: DocumentKey,\n    readonly fieldTransforms: FieldTransform[]\n  ) {\n    super();\n  }\n}\n\nfunction applyTransformMutationToRemoteDocument(\n  mutation: TransformMutation,\n  maybeDoc: MaybeDocument | null,\n  mutationResult: MutationResult\n): Document | UnknownDocument {\n  hardAssert(\n    mutationResult.transformResults != null,\n    'Transform results missing for TransformMutation.'\n  );\n\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    // Since the mutation was not rejected, we know that the  precondition\n    // matched on the backend. We therefore must not have the expected version\n    // of the document in our cache and return an UnknownDocument with the\n    // known updateTime.\n    return new UnknownDocument(mutation.key, mutationResult.version);\n  }\n\n  const doc = requireDocument(mutation, maybeDoc);\n  const transformResults = serverTransformResults(\n    mutation.fieldTransforms,\n    maybeDoc,\n    mutationResult.transformResults!\n  );\n\n  const version = mutationResult.version;\n  const newData = transformObject(mutation, doc.data(), transformResults);\n  return new Document(mutation.key, version, newData, {\n    hasCommittedMutations: true\n  });\n}\n\nfunction applyTransformMutationToLocalView(\n  mutation: TransformMutation,\n  maybeDoc: MaybeDocument | null,\n  localWriteTime: Timestamp,\n  baseDoc: MaybeDocument | null\n): MaybeDocument | null {\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    return maybeDoc;\n  }\n\n  const doc = requireDocument(mutation, maybeDoc);\n  const transformResults = localTransformResults(\n    mutation.fieldTransforms,\n    localWriteTime,\n    maybeDoc,\n    baseDoc\n  );\n  const newData = transformObject(mutation, doc.data(), transformResults);\n  return new Document(mutation.key, doc.version, newData, {\n    hasLocalMutations: true\n  });\n}\n\nfunction extractTransformMutationBaseValue(\n  mutation: TransformMutation,\n  maybeDoc: MaybeDocument | null | Document\n): ObjectValue | null {\n  let baseObject: ObjectValueBuilder | null = null;\n  for (const fieldTransform of mutation.fieldTransforms) {\n    const existingValue =\n      maybeDoc instanceof Document\n        ? maybeDoc.field(fieldTransform.field)\n        : undefined;\n    const coercedValue = computeTransformOperationBaseValue(\n      fieldTransform.transform,\n      existingValue || null\n    );\n\n    if (coercedValue != null) {\n      if (baseObject == null) {\n        baseObject = new ObjectValueBuilder().set(\n          fieldTransform.field,\n          coercedValue\n        );\n      } else {\n        baseObject = baseObject.set(fieldTransform.field, coercedValue);\n      }\n    }\n  }\n  return baseObject ? baseObject.build() : null;\n}\n\n/**\n * Asserts that the given MaybeDocument is actually a Document and verifies\n * that it matches the key for this mutation. Since we only support\n * transformations with precondition exists this method is guaranteed to be\n * safe.\n */\nfunction requireDocument(\n  mutation: Mutation,\n  maybeDoc: MaybeDocument | null\n): Document {\n  debugAssert(\n    maybeDoc instanceof Document,\n    'Unknown MaybeDocument type ' + maybeDoc\n  );\n  debugAssert(\n    maybeDoc.key.isEqual(mutation.key),\n    'Can only transform a document with the same key'\n  );\n  return maybeDoc;\n}\n\n/**\n * Creates a list of \"transform results\" (a transform result is a field value\n * representing the result of applying a transform) for use after a\n * TransformMutation has been acknowledged by the server.\n *\n * @param fieldTransforms The field transforms to apply the result to.\n * @param baseDoc The document prior to applying this mutation batch.\n * @param serverTransformResults The transform results received by the server.\n * @return The transform results list.\n */\nfunction serverTransformResults(\n  fieldTransforms: FieldTransform[],\n  baseDoc: MaybeDocument | null,\n  serverTransformResults: Array<api.Value | null>\n): api.Value[] {\n  const transformResults: api.Value[] = [];\n  hardAssert(\n    fieldTransforms.length === serverTransformResults.length,\n    `server transform result count (${serverTransformResults.length}) ` +\n      `should match field transform count (${fieldTransforms.length})`\n  );\n\n  for (let i = 0; i < serverTransformResults.length; i++) {\n    const fieldTransform = fieldTransforms[i];\n    const transform = fieldTransform.transform;\n    let previousValue: api.Value | null = null;\n    if (baseDoc instanceof Document) {\n      previousValue = baseDoc.field(fieldTransform.field);\n    }\n    transformResults.push(\n      applyTransformOperationToRemoteDocument(\n        transform,\n        previousValue,\n        serverTransformResults[i]\n      )\n    );\n  }\n  return transformResults;\n}\n\n/**\n * Creates a list of \"transform results\" (a transform result is a field value\n * representing the result of applying a transform) for use when applying a\n * TransformMutation locally.\n *\n * @param fieldTransforms The field transforms to apply the result to.\n * @param localWriteTime The local time of the transform mutation (used to\n *     generate ServerTimestampValues).\n * @param maybeDoc The current state of the document after applying all\n *     previous mutations.\n * @param baseDoc The document prior to applying this mutation batch.\n * @return The transform results list.\n */\nfunction localTransformResults(\n  fieldTransforms: FieldTransform[],\n  localWriteTime: Timestamp,\n  maybeDoc: MaybeDocument | null,\n  baseDoc: MaybeDocument | null\n): api.Value[] {\n  const transformResults: api.Value[] = [];\n  for (const fieldTransform of fieldTransforms) {\n    const transform = fieldTransform.transform;\n\n    let previousValue: api.Value | null = null;\n    if (maybeDoc instanceof Document) {\n      previousValue = maybeDoc.field(fieldTransform.field);\n    }\n\n    if (previousValue === null && baseDoc instanceof Document) {\n      // If the current document does not contain a value for the mutated\n      // field, use the value that existed before applying this mutation\n      // batch. This solves an edge case where a PatchMutation clears the\n      // values in a nested map before the TransformMutation is applied.\n      previousValue = baseDoc.field(fieldTransform.field);\n    }\n\n    transformResults.push(\n      applyTransformOperationToLocalView(\n        transform,\n        previousValue,\n        localWriteTime\n      )\n    );\n  }\n  return transformResults;\n}\n\nfunction transformObject(\n  mutation: TransformMutation,\n  data: ObjectValue,\n  transformResults: api.Value[]\n): ObjectValue {\n  debugAssert(\n    transformResults.length === mutation.fieldTransforms.length,\n    'TransformResults length mismatch.'\n  );\n\n  const builder = new ObjectValueBuilder(data);\n  for (let i = 0; i < mutation.fieldTransforms.length; i++) {\n    const fieldTransform = mutation.fieldTransforms[i];\n    builder.set(fieldTransform.field, transformResults[i]);\n  }\n  return builder.build();\n}\n\n/** A mutation that deletes the document at the given key. */\nexport class DeleteMutation extends Mutation {\n  constructor(readonly key: DocumentKey, readonly precondition: Precondition) {\n    super();\n  }\n\n  readonly type: MutationType = MutationType.Delete;\n}\n\nfunction applyDeleteMutationToRemoteDocument(\n  mutation: DeleteMutation,\n  maybeDoc: MaybeDocument | null,\n  mutationResult: MutationResult\n): NoDocument {\n  debugAssert(\n    mutationResult.transformResults == null,\n    'Transform results received by DeleteMutation.'\n  );\n\n  // Unlike applyToLocalView, if we're applying a mutation to a remote\n  // document the server has accepted the mutation so the precondition must\n  // have held.\n\n  return new NoDocument(mutation.key, mutationResult.version, {\n    hasCommittedMutations: true\n  });\n}\n\nfunction applyDeleteMutationToLocalView(\n  mutation: DeleteMutation,\n  maybeDoc: MaybeDocument | null\n): MaybeDocument | null {\n  if (!preconditionIsValidForDocument(mutation.precondition, maybeDoc)) {\n    return maybeDoc;\n  }\n\n  if (maybeDoc) {\n    debugAssert(\n      maybeDoc.key.isEqual(mutation.key),\n      'Can only apply mutation to document with same key'\n    );\n  }\n  return new NoDocument(mutation.key, SnapshotVersion.min());\n}\n\n/**\n * A mutation that verifies the existence of the document at the given key with\n * the provided precondition.\n *\n * The `verify` operation is only used in Transactions, and this class serves\n * primarily to facilitate serialization into protos.\n */\nexport class VerifyMutation extends Mutation {\n  constructor(readonly key: DocumentKey, readonly precondition: Precondition) {\n    super();\n  }\n\n  readonly type: MutationType = MutationType.Verify;\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 * as api from '../protos/firestore_proto_api';\n\nimport { debugAssert } from '../util/assert';\nimport { FieldMask } from './mutation';\nimport { FieldPath } from './path';\nimport { isServerTimestamp } from './server_timestamps';\nimport { valueEquals, isMapValue, typeOrder } from './values';\nimport { forEach } from '../util/obj';\n\nexport interface JsonObject<T> {\n  [name: string]: T;\n}\n\nexport const enum TypeOrder {\n  // This order is based on the backend's ordering, but modified to support\n  // server timestamps.\n  NullValue = 0,\n  BooleanValue = 1,\n  NumberValue = 2,\n  TimestampValue = 3,\n  ServerTimestampValue = 4,\n  StringValue = 5,\n  BlobValue = 6,\n  RefValue = 7,\n  GeoPointValue = 8,\n  ArrayValue = 9,\n  ObjectValue = 10\n}\n\n/**\n * An ObjectValue represents a MapValue in the Firestore Proto and offers the\n * ability to add and remove fields (via the ObjectValueBuilder).\n */\nexport class ObjectValue {\n  constructor(readonly proto: { mapValue: api.MapValue }) {\n    debugAssert(\n      !isServerTimestamp(proto),\n      'ServerTimestamps should be converted to ServerTimestampValue'\n    );\n  }\n\n  static empty(): ObjectValue {\n    return new ObjectValue({ mapValue: {} });\n  }\n\n  /**\n   * Returns the value at the given path or null.\n   *\n   * @param path the path to search\n   * @return The value at the path or if there it doesn't exist.\n   */\n  field(path: FieldPath): api.Value | null {\n    if (path.isEmpty()) {\n      return this.proto;\n    } else {\n      let value: api.Value = this.proto;\n      for (let i = 0; i < path.length - 1; ++i) {\n        if (!value.mapValue!.fields) {\n          return null;\n        }\n        value = value.mapValue!.fields[path.get(i)];\n        if (!isMapValue(value)) {\n          return null;\n        }\n      }\n\n      value = (value.mapValue!.fields || {})[path.lastSegment()];\n      return value || null;\n    }\n  }\n\n  isEqual(other: ObjectValue): boolean {\n    return valueEquals(this.proto, other.proto);\n  }\n}\n\n/**\n * An Overlay, which contains an update to apply. Can either be Value proto, a\n * map of Overlay values (to represent additional nesting at the given key) or\n * `null` (to represent field deletes).\n */\ntype Overlay = Map<string, Overlay> | api.Value | null;\n\n/**\n * An ObjectValueBuilder provides APIs to set and delete fields from an\n * ObjectValue.\n */\nexport class ObjectValueBuilder {\n  /** A map that contains the accumulated changes in this builder. */\n  private overlayMap = new Map<string, Overlay>();\n\n  /**\n   * @param baseObject The object to mutate.\n   */\n  constructor(private readonly baseObject: ObjectValue = ObjectValue.empty()) {}\n\n  /**\n   * Sets the field to the provided value.\n   *\n   * @param path The field path to set.\n   * @param value The value to set.\n   * @return The current Builder instance.\n   */\n  set(path: FieldPath, value: api.Value): ObjectValueBuilder {\n    debugAssert(\n      !path.isEmpty(),\n      'Cannot set field for empty path on ObjectValue'\n    );\n    this.setOverlay(path, value);\n    return this;\n  }\n\n  /**\n   * Removes the field at the specified path. If there is no field at the\n   * specified path, nothing is changed.\n   *\n   * @param path The field path to remove.\n   * @return The current Builder instance.\n   */\n  delete(path: FieldPath): ObjectValueBuilder {\n    debugAssert(\n      !path.isEmpty(),\n      'Cannot delete field for empty path on ObjectValue'\n    );\n    this.setOverlay(path, null);\n    return this;\n  }\n\n  /**\n   * Adds `value` to the overlay map at `path`. Creates nested map entries if\n   * needed.\n   */\n  private setOverlay(path: FieldPath, value: api.Value | null): void {\n    let currentLevel = this.overlayMap;\n\n    for (let i = 0; i < path.length - 1; ++i) {\n      const currentSegment = path.get(i);\n      let currentValue = currentLevel.get(currentSegment);\n\n      if (currentValue instanceof Map) {\n        // Re-use a previously created map\n        currentLevel = currentValue;\n      } else if (\n        currentValue &&\n        typeOrder(currentValue) === TypeOrder.ObjectValue\n      ) {\n        // Convert the existing Protobuf MapValue into a map\n        currentValue = new Map<string, Overlay>(\n          Object.entries(currentValue.mapValue!.fields || {})\n        );\n        currentLevel.set(currentSegment, currentValue);\n        currentLevel = currentValue;\n      } else {\n        // Create an empty map to represent the current nesting level\n        currentValue = new Map<string, Overlay>();\n        currentLevel.set(currentSegment, currentValue);\n        currentLevel = currentValue;\n      }\n    }\n\n    currentLevel.set(path.lastSegment(), value);\n  }\n\n  /** Returns an ObjectValue with all mutations applied. */\n  build(): ObjectValue {\n    const mergedResult = this.applyOverlay(\n      FieldPath.emptyPath(),\n      this.overlayMap\n    );\n    if (mergedResult != null) {\n      return new ObjectValue(mergedResult);\n    } else {\n      return this.baseObject;\n    }\n  }\n\n  /**\n   * Applies any overlays from `currentOverlays` that exist at `currentPath`\n   * and returns the merged data at `currentPath` (or null if there were no\n   * changes).\n   *\n   * @param currentPath The path at the current nesting level. Can be set to\n   * FieldValue.emptyPath() to represent the root.\n   * @param currentOverlays The overlays at the current nesting level in the\n   * same format as `overlayMap`.\n   * @return The merged data at `currentPath` or null if no modifications\n   * were applied.\n   */\n  private applyOverlay(\n    currentPath: FieldPath,\n    currentOverlays: Map<string, Overlay>\n  ): { mapValue: api.MapValue } | null {\n    let modified = false;\n\n    const existingValue = this.baseObject.field(currentPath);\n    const resultAtPath = isMapValue(existingValue)\n      ? // If there is already data at the current path, base our\n        // modifications on top of the existing data.\n        { ...existingValue.mapValue.fields }\n      : {};\n\n    currentOverlays.forEach((value, pathSegment) => {\n      if (value instanceof Map) {\n        const nested = this.applyOverlay(currentPath.child(pathSegment), value);\n        if (nested != null) {\n          resultAtPath[pathSegment] = nested;\n          modified = true;\n        }\n      } else if (value !== null) {\n        resultAtPath[pathSegment] = value;\n        modified = true;\n      } else if (resultAtPath.hasOwnProperty(pathSegment)) {\n        delete resultAtPath[pathSegment];\n        modified = true;\n      }\n    });\n\n    return modified ? { mapValue: { fields: resultAtPath } } : null;\n  }\n}\n\n/**\n * Returns a FieldMask built from all fields in a MapValue.\n */\nexport function extractFieldMask(value: api.MapValue): FieldMask {\n  const fields: FieldPath[] = [];\n  forEach(value!.fields || {}, (key, value) => {\n    const currentPath = new FieldPath([key]);\n    if (isMapValue(value)) {\n      const nestedMask = extractFieldMask(value.mapValue!);\n      const nestedFields = nestedMask.fields;\n      if (nestedFields.length === 0) {\n        // Preserve the empty map by adding it to the FieldMask.\n        fields.push(currentPath);\n      } else {\n        // For nested and non-empty ObjectValues, add the FieldPath of the\n        // leaf nodes.\n        for (const nestedPath of nestedFields) {\n          fields.push(currentPath.child(nestedPath));\n        }\n      }\n    } else {\n      // For nested and non-empty ObjectValues, add the FieldPath of the leaf\n      // nodes.\n      fields.push(currentPath);\n    }\n  });\n  return new FieldMask(fields);\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 * as api from '../protos/firestore_proto_api';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { fail } from '../util/assert';\n\nimport { DocumentKey } from './document_key';\nimport { ObjectValue } from './object_value';\nimport { FieldPath } from './path';\nimport { valueCompare } from './values';\n\nexport interface DocumentOptions {\n  hasLocalMutations?: boolean;\n  hasCommittedMutations?: boolean;\n}\n\n/**\n * The result of a lookup for a given path may be an existing document or a\n * marker that this document does not exist at a given version.\n */\nexport abstract class MaybeDocument {\n  constructor(readonly key: DocumentKey, readonly version: SnapshotVersion) {}\n\n  /**\n   * Whether this document had a local mutation applied that has not yet been\n   * acknowledged by Watch.\n   */\n  abstract get hasPendingWrites(): boolean;\n\n  abstract isEqual(other: MaybeDocument | null | undefined): boolean;\n\n  abstract toString(): string;\n}\n\n/**\n * Represents a document in Firestore with a key, version, data and whether the\n * data has local mutations applied to it.\n */\nexport class Document extends MaybeDocument {\n  readonly hasLocalMutations: boolean;\n  readonly hasCommittedMutations: boolean;\n\n  constructor(\n    key: DocumentKey,\n    version: SnapshotVersion,\n    private readonly objectValue: ObjectValue,\n    options: DocumentOptions\n  ) {\n    super(key, version);\n    this.hasLocalMutations = !!options.hasLocalMutations;\n    this.hasCommittedMutations = !!options.hasCommittedMutations;\n  }\n\n  field(path: FieldPath): api.Value | null {\n    return this.objectValue.field(path);\n  }\n\n  data(): ObjectValue {\n    return this.objectValue;\n  }\n\n  toProto(): { mapValue: api.MapValue } {\n    return this.objectValue.proto;\n  }\n\n  isEqual(other: MaybeDocument | null | undefined): boolean {\n    return (\n      other instanceof Document &&\n      this.key.isEqual(other.key) &&\n      this.version.isEqual(other.version) &&\n      this.hasLocalMutations === other.hasLocalMutations &&\n      this.hasCommittedMutations === other.hasCommittedMutations &&\n      this.objectValue.isEqual(other.objectValue)\n    );\n  }\n\n  toString(): string {\n    return (\n      `Document(${this.key}, ${\n        this.version\n      }, ${this.objectValue.toString()}, ` +\n      `{hasLocalMutations: ${this.hasLocalMutations}}), ` +\n      `{hasCommittedMutations: ${this.hasCommittedMutations}})`\n    );\n  }\n\n  get hasPendingWrites(): boolean {\n    return this.hasLocalMutations || this.hasCommittedMutations;\n  }\n}\n\n/**\n * Compares the value for field `field` in the provided documents. Throws if\n * the field does not exist in both documents.\n */\nexport function compareDocumentsByField(\n  field: FieldPath,\n  d1: Document,\n  d2: Document\n): number {\n  const v1 = d1.field(field);\n  const v2 = d2.field(field);\n  if (v1 !== null && v2 !== null) {\n    return valueCompare(v1, v2);\n  } else {\n    return fail(\"Trying to compare documents on fields that don't exist\");\n  }\n}\n\n/**\n * A class representing a deleted document.\n * Version is set to 0 if we don't point to any specific time, otherwise it\n * denotes time we know it didn't exist at.\n */\nexport class NoDocument extends MaybeDocument {\n  readonly hasCommittedMutations: boolean;\n\n  constructor(\n    key: DocumentKey,\n    version: SnapshotVersion,\n    options?: DocumentOptions\n  ) {\n    super(key, version);\n    this.hasCommittedMutations = !!(options && options.hasCommittedMutations);\n  }\n\n  toString(): string {\n    return `NoDocument(${this.key}, ${this.version})`;\n  }\n\n  get hasPendingWrites(): boolean {\n    return this.hasCommittedMutations;\n  }\n\n  isEqual(other: MaybeDocument | null | undefined): boolean {\n    return (\n      other instanceof NoDocument &&\n      other.hasCommittedMutations === this.hasCommittedMutations &&\n      other.version.isEqual(this.version) &&\n      other.key.isEqual(this.key)\n    );\n  }\n}\n\n/**\n * A class representing an existing document whose data is unknown (e.g. a\n * document that was updated without a known base document).\n */\nexport class UnknownDocument extends MaybeDocument {\n  toString(): string {\n    return `UnknownDocument(${this.key}, ${this.version})`;\n  }\n\n  get hasPendingWrites(): boolean {\n    return true;\n  }\n\n  isEqual(other: MaybeDocument | null | undefined): boolean {\n    return (\n      other instanceof UnknownDocument &&\n      other.version.isEqual(this.version) &&\n      other.key.isEqual(this.key)\n    );\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 { Code, FirestoreError } from '../../../src/util/error';\n\n/**\n * Casts `obj` to `T`. Throws if  `obj` is not an instance of `T`.\n *\n * This cast is used in the Lite and Full SDK to verify instance types for\n * arguments passed to the public API.\n */\nexport function cast<T>(\n  obj: object,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  constructor: { new (...args: any[]): T }\n): T | never {\n  if (!(obj instanceof constructor)) {\n    if (constructor.name === obj.constructor.name) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Type does not match the expected instance. Did you pass ' +\n          `'${constructor.name}' from a different Firestore SDK?`\n      );\n    } else {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Expected type '${constructor.name}', but was '${obj.constructor.name}'`\n      );\n    }\n  }\n  return obj as T;\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { BatchId } from '../core/types';\nimport { debugAssert, hardAssert } from '../util/assert';\nimport { arrayEquals } from '../util/misc';\nimport {\n  documentKeySet,\n  DocumentKeySet,\n  DocumentVersionMap,\n  documentVersionMap,\n  MaybeDocumentMap\n} from './collections';\nimport { MaybeDocument } from './document';\nimport { DocumentKey } from './document_key';\nimport {\n  applyMutationToLocalView,\n  applyMutationToRemoteDocument,\n  Mutation,\n  mutationEquals,\n  MutationResult\n} from './mutation';\n\nexport const BATCHID_UNKNOWN = -1;\n\n/**\n * A batch of mutations that will be sent as one unit to the backend.\n */\nexport class MutationBatch {\n  /**\n   * @param batchId The unique ID of this mutation batch.\n   * @param localWriteTime The original write time of this mutation.\n   * @param baseMutations Mutations that are used to populate the base\n   * values when this mutation is applied locally. This can be used to locally\n   * overwrite values that are persisted in the remote document cache. Base\n   * mutations are never sent to the backend.\n   * @param mutations The user-provided mutations in this mutation batch.\n   * User-provided mutations are applied both locally and remotely on the\n   * backend.\n   */\n  constructor(\n    public batchId: BatchId,\n    public localWriteTime: Timestamp,\n    public baseMutations: Mutation[],\n    public mutations: Mutation[]\n  ) {\n    debugAssert(mutations.length > 0, 'Cannot create an empty mutation batch');\n  }\n\n  /**\n   * Applies all the mutations in this MutationBatch to the specified document\n   * to create a new remote document\n   *\n   * @param docKey The key of the document to apply mutations to.\n   * @param maybeDoc The document to apply mutations to.\n   * @param batchResult The result of applying the MutationBatch to the\n   * backend.\n   */\n  applyToRemoteDocument(\n    docKey: DocumentKey,\n    maybeDoc: MaybeDocument | null,\n    batchResult: MutationBatchResult\n  ): MaybeDocument | null {\n    if (maybeDoc) {\n      debugAssert(\n        maybeDoc.key.isEqual(docKey),\n        `applyToRemoteDocument: key ${docKey} should match maybeDoc key\n        ${maybeDoc.key}`\n      );\n    }\n\n    const mutationResults = batchResult.mutationResults;\n    debugAssert(\n      mutationResults.length === this.mutations.length,\n      `Mismatch between mutations length\n      (${this.mutations.length}) and mutation results length\n      (${mutationResults.length}).`\n    );\n\n    for (let i = 0; i < this.mutations.length; i++) {\n      const mutation = this.mutations[i];\n      if (mutation.key.isEqual(docKey)) {\n        const mutationResult = mutationResults[i];\n        maybeDoc = applyMutationToRemoteDocument(\n          mutation,\n          maybeDoc,\n          mutationResult\n        );\n      }\n    }\n    return maybeDoc;\n  }\n\n  /**\n   * Computes the local view of a document given all the mutations in this\n   * batch.\n   *\n   * @param docKey The key of the document to apply mutations to.\n   * @param maybeDoc The document to apply mutations to.\n   */\n  applyToLocalView(\n    docKey: DocumentKey,\n    maybeDoc: MaybeDocument | null\n  ): MaybeDocument | null {\n    if (maybeDoc) {\n      debugAssert(\n        maybeDoc.key.isEqual(docKey),\n        `applyToLocalDocument: key ${docKey} should match maybeDoc key\n        ${maybeDoc.key}`\n      );\n    }\n\n    // First, apply the base state. This allows us to apply non-idempotent\n    // transform against a consistent set of values.\n    for (const mutation of this.baseMutations) {\n      if (mutation.key.isEqual(docKey)) {\n        maybeDoc = applyMutationToLocalView(\n          mutation,\n          maybeDoc,\n          maybeDoc,\n          this.localWriteTime\n        );\n      }\n    }\n\n    const baseDoc = maybeDoc;\n\n    // Second, apply all user-provided mutations.\n    for (const mutation of this.mutations) {\n      if (mutation.key.isEqual(docKey)) {\n        maybeDoc = applyMutationToLocalView(\n          mutation,\n          maybeDoc,\n          baseDoc,\n          this.localWriteTime\n        );\n      }\n    }\n    return maybeDoc;\n  }\n\n  /**\n   * Computes the local view for all provided documents given the mutations in\n   * this batch.\n   */\n  applyToLocalDocumentSet(maybeDocs: MaybeDocumentMap): MaybeDocumentMap {\n    // TODO(mrschmidt): This implementation is O(n^2). If we apply the mutations\n    // directly (as done in `applyToLocalView()`), we can reduce the complexity\n    // to O(n).\n    let mutatedDocuments = maybeDocs;\n    this.mutations.forEach(m => {\n      const mutatedDocument = this.applyToLocalView(\n        m.key,\n        maybeDocs.get(m.key)\n      );\n      if (mutatedDocument) {\n        mutatedDocuments = mutatedDocuments.insert(m.key, mutatedDocument);\n      }\n    });\n    return mutatedDocuments;\n  }\n\n  keys(): DocumentKeySet {\n    return this.mutations.reduce(\n      (keys, m) => keys.add(m.key),\n      documentKeySet()\n    );\n  }\n\n  isEqual(other: MutationBatch): boolean {\n    return (\n      this.batchId === other.batchId &&\n      arrayEquals(this.mutations, other.mutations, (l, r) =>\n        mutationEquals(l, r)\n      ) &&\n      arrayEquals(this.baseMutations, other.baseMutations, (l, r) =>\n        mutationEquals(l, r)\n      )\n    );\n  }\n}\n\n/** The result of applying a mutation batch to the backend. */\nexport class MutationBatchResult {\n  private constructor(\n    readonly batch: MutationBatch,\n    readonly commitVersion: SnapshotVersion,\n    readonly mutationResults: MutationResult[],\n    /**\n     * A pre-computed mapping from each mutated document to the resulting\n     * version.\n     */\n    readonly docVersions: DocumentVersionMap\n  ) {}\n\n  /**\n   * Creates a new MutationBatchResult for the given batch and results. There\n   * must be one result for each mutation in the batch. This static factory\n   * caches a document=>version mapping (docVersions).\n   */\n  static from(\n    batch: MutationBatch,\n    commitVersion: SnapshotVersion,\n    results: MutationResult[]\n  ): MutationBatchResult {\n    hardAssert(\n      batch.mutations.length === results.length,\n      'Mutations sent ' +\n        batch.mutations.length +\n        ' must equal results received ' +\n        results.length\n    );\n\n    let versionMap = documentVersionMap();\n    const mutations = batch.mutations;\n    for (let i = 0; i < mutations.length; i++) {\n      versionMap = versionMap.insert(mutations[i].key, results[i].version);\n    }\n\n    return new MutationBatchResult(batch, commitVersion, results, versionMap);\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 { fail } from '../util/assert';\n\nexport type FulfilledHandler<T, R> =\n  | ((result: T) => R | PersistencePromise<R>)\n  | null;\nexport type RejectedHandler<R> =\n  | ((reason: Error) => R | PersistencePromise<R>)\n  | null;\nexport type Resolver<T> = (value?: T) => void;\nexport type Rejector = (error: Error) => void;\n\n/**\n * PersistencePromise<> is essentially a re-implementation of Promise<> except\n * it has a .next() method instead of .then() and .next() and .catch() callbacks\n * are executed synchronously when a PersistencePromise resolves rather than\n * asynchronously (Promise<> implementations use setImmediate() or similar).\n *\n * This is necessary to interoperate with IndexedDB which will automatically\n * commit transactions if control is returned to the event loop without\n * synchronously initiating another operation on the transaction.\n *\n * NOTE: .then() and .catch() only allow a single consumer, unlike normal\n * Promises.\n */\nexport class PersistencePromise<T> {\n  // NOTE: next/catchCallback will always point to our own wrapper functions,\n  // not the user's raw next() or catch() callbacks.\n  private nextCallback: FulfilledHandler<T, unknown> = null;\n  private catchCallback: RejectedHandler<unknown> = null;\n\n  // When the operation resolves, we'll set result or error and mark isDone.\n  private result: T | undefined = undefined;\n  private error: Error | undefined = undefined;\n  private isDone = false;\n\n  // Set to true when .then() or .catch() are called and prevents additional\n  // chaining.\n  private callbackAttached = false;\n\n  constructor(callback: (resolve: Resolver<T>, reject: Rejector) => void) {\n    callback(\n      value => {\n        this.isDone = true;\n        this.result = value;\n        if (this.nextCallback) {\n          // value should be defined unless T is Void, but we can't express\n          // that in the type system.\n          this.nextCallback(value!);\n        }\n      },\n      error => {\n        this.isDone = true;\n        this.error = error;\n        if (this.catchCallback) {\n          this.catchCallback(error);\n        }\n      }\n    );\n  }\n\n  catch<R>(\n    fn: (error: Error) => R | PersistencePromise<R>\n  ): PersistencePromise<R> {\n    return this.next(undefined, fn);\n  }\n\n  next<R>(\n    nextFn?: FulfilledHandler<T, R>,\n    catchFn?: RejectedHandler<R>\n  ): PersistencePromise<R> {\n    if (this.callbackAttached) {\n      fail('Called next() or catch() twice for PersistencePromise');\n    }\n    this.callbackAttached = true;\n    if (this.isDone) {\n      if (!this.error) {\n        return this.wrapSuccess(nextFn, this.result!);\n      } else {\n        return this.wrapFailure(catchFn, this.error);\n      }\n    } else {\n      return new PersistencePromise<R>((resolve, reject) => {\n        this.nextCallback = (value: T) => {\n          this.wrapSuccess(nextFn, value).next(resolve, reject);\n        };\n        this.catchCallback = (error: Error) => {\n          this.wrapFailure(catchFn, error).next(resolve, reject);\n        };\n      });\n    }\n  }\n\n  toPromise(): Promise<T> {\n    return new Promise((resolve, reject) => {\n      this.next(resolve, reject);\n    });\n  }\n\n  private wrapUserFunction<R>(\n    fn: () => R | PersistencePromise<R>\n  ): PersistencePromise<R> {\n    try {\n      const result = fn();\n      if (result instanceof PersistencePromise) {\n        return result;\n      } else {\n        return PersistencePromise.resolve(result);\n      }\n    } catch (e) {\n      return PersistencePromise.reject<R>(e);\n    }\n  }\n\n  private wrapSuccess<R>(\n    nextFn: FulfilledHandler<T, R> | undefined,\n    value: T\n  ): PersistencePromise<R> {\n    if (nextFn) {\n      return this.wrapUserFunction(() => nextFn(value));\n    } else {\n      // If there's no nextFn, then R must be the same as T\n      return PersistencePromise.resolve<R>((value as unknown) as R);\n    }\n  }\n\n  private wrapFailure<R>(\n    catchFn: RejectedHandler<R> | undefined,\n    error: Error\n  ): PersistencePromise<R> {\n    if (catchFn) {\n      return this.wrapUserFunction(() => catchFn(error));\n    } else {\n      return PersistencePromise.reject<R>(error);\n    }\n  }\n\n  static resolve(): PersistencePromise<void>;\n  static resolve<R>(result: R): PersistencePromise<R>;\n  static resolve<R>(result?: R): PersistencePromise<R | void> {\n    return new PersistencePromise<R | void>((resolve, reject) => {\n      resolve(result);\n    });\n  }\n\n  static reject<R>(error: Error): PersistencePromise<R> {\n    return new PersistencePromise<R>((resolve, reject) => {\n      reject(error);\n    });\n  }\n\n  static waitFor(\n    // Accept all Promise types in waitFor().\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    all: { forEach: (cb: (el: PersistencePromise<any>) => void) => void }\n  ): PersistencePromise<void> {\n    return new PersistencePromise<void>((resolve, reject) => {\n      let expectedCount = 0;\n      let resolvedCount = 0;\n      let done = false;\n\n      all.forEach(element => {\n        ++expectedCount;\n        element.next(\n          () => {\n            ++resolvedCount;\n            if (done && resolvedCount === expectedCount) {\n              resolve();\n            }\n          },\n          err => reject(err)\n        );\n      });\n\n      done = true;\n      if (resolvedCount === expectedCount) {\n        resolve();\n      }\n    });\n  }\n\n  /**\n   * Given an array of predicate functions that asynchronously evaluate to a\n   * boolean, implements a short-circuiting `or` between the results. Predicates\n   * will be evaluated until one of them returns `true`, then stop. The final\n   * result will be whether any of them returned `true`.\n   */\n  static or(\n    predicates: Array<() => PersistencePromise<boolean>>\n  ): PersistencePromise<boolean> {\n    let p: PersistencePromise<boolean> = PersistencePromise.resolve<boolean>(\n      false\n    );\n    for (const predicate of predicates) {\n      p = p.next(isTrue => {\n        if (isTrue) {\n          return PersistencePromise.resolve<boolean>(isTrue);\n        } else {\n          return predicate();\n        }\n      });\n    }\n    return p;\n  }\n\n  /**\n   * Given an iterable, call the given function on each element in the\n   * collection and wait for all of the resulting concurrent PersistencePromises\n   * to resolve.\n   */\n  static forEach<R, S>(\n    collection: { forEach: (cb: (r: R, s: S) => void) => void },\n    f:\n      | ((r: R, s: S) => PersistencePromise<void>)\n      | ((r: R) => PersistencePromise<void>)\n  ): PersistencePromise<void>;\n  static forEach<R>(\n    collection: { forEach: (cb: (r: R) => void) => void },\n    f: (r: R) => PersistencePromise<void>\n  ): PersistencePromise<void>;\n  static forEach<R, S>(\n    collection: { forEach: (cb: (r: R, s?: S) => void) => void },\n    f: (r: R, s?: S) => PersistencePromise<void>\n  ): PersistencePromise<void> {\n    const promises: Array<PersistencePromise<void>> = [];\n    collection.forEach((r, s) => {\n      promises.push(f.call(this, r, s));\n    });\n    return this.waitFor(promises);\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 { DocumentKeySet, NullableMaybeDocumentMap } from '../model/collections';\nimport { MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert } from '../util/assert';\nimport { ObjectMap } from '../util/obj_map';\n\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SnapshotVersion } from '../core/snapshot_version';\n\n/**\n * An in-memory buffer of entries to be written to a RemoteDocumentCache.\n * It can be used to batch up a set of changes to be written to the cache, but\n * additionally supports reading entries back with the `getEntry()` method,\n * falling back to the underlying RemoteDocumentCache if no entry is\n * buffered.\n *\n * Entries added to the cache *must* be read first. This is to facilitate\n * calculating the size delta of the pending changes.\n *\n * PORTING NOTE: This class was implemented then removed from other platforms.\n * If byte-counting ends up being needed on the other platforms, consider\n * porting this class as part of that implementation work.\n */\nexport abstract class RemoteDocumentChangeBuffer {\n  // A mapping of document key to the new cache entry that should be written (or null if any\n  // existing cache entry should be removed).\n  protected changes: ObjectMap<\n    DocumentKey,\n    MaybeDocument | null\n  > = new ObjectMap(\n    key => key.toString(),\n    (l, r) => l.isEqual(r)\n  );\n\n  // The read time to use for all added documents in this change buffer.\n  private _readTime: SnapshotVersion | undefined;\n\n  private changesApplied = false;\n\n  protected abstract getFromCache(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MaybeDocument | null>;\n\n  protected abstract getAllFromCache(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet\n  ): PersistencePromise<NullableMaybeDocumentMap>;\n\n  protected abstract applyChanges(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<void>;\n\n  protected set readTime(value: SnapshotVersion) {\n    // Right now (for simplicity) we just track a single readTime for all the\n    // added entries since we expect them to all be the same, but we could\n    // rework to store per-entry readTimes if necessary.\n    debugAssert(\n      this._readTime === undefined || this._readTime.isEqual(value),\n      'All changes in a RemoteDocumentChangeBuffer must have the same read time'\n    );\n    this._readTime = value;\n  }\n\n  protected get readTime(): SnapshotVersion {\n    debugAssert(\n      this._readTime !== undefined,\n      'Read time is not set. All removeEntry() calls must include a readTime if `trackRemovals` is used.'\n    );\n    return this._readTime;\n  }\n\n  /**\n   * Buffers a `RemoteDocumentCache.addEntry()` call.\n   *\n   * You can only modify documents that have already been retrieved via\n   * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).\n   */\n  addEntry(maybeDocument: MaybeDocument, readTime: SnapshotVersion): void {\n    this.assertNotApplied();\n    this.readTime = readTime;\n    this.changes.set(maybeDocument.key, maybeDocument);\n  }\n\n  /**\n   * Buffers a `RemoteDocumentCache.removeEntry()` call.\n   *\n   * You can only remove documents that have already been retrieved via\n   * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).\n   */\n  removeEntry(key: DocumentKey, readTime?: SnapshotVersion): void {\n    this.assertNotApplied();\n    if (readTime) {\n      this.readTime = readTime;\n    }\n    this.changes.set(key, null);\n  }\n\n  /**\n   * Looks up an entry in the cache. The buffered changes will first be checked,\n   * and if no buffered change applies, this will forward to\n   * `RemoteDocumentCache.getEntry()`.\n   *\n   * @param transaction The transaction in which to perform any persistence\n   *     operations.\n   * @param documentKey The key of the entry to look up.\n   * @return The cached Document or NoDocument entry, or null if we have nothing\n   * cached.\n   */\n  getEntry(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MaybeDocument | null> {\n    this.assertNotApplied();\n    const bufferedEntry = this.changes.get(documentKey);\n    if (bufferedEntry !== undefined) {\n      return PersistencePromise.resolve<MaybeDocument | null>(bufferedEntry);\n    } else {\n      return this.getFromCache(transaction, documentKey);\n    }\n  }\n\n  /**\n   * Looks up several entries in the cache, forwarding to\n   * `RemoteDocumentCache.getEntry()`.\n   *\n   * @param transaction The transaction in which to perform any persistence\n   *     operations.\n   * @param documentKeys The keys of the entries to look up.\n   * @return A map of cached `Document`s or `NoDocument`s, indexed by key. If an\n   *     entry cannot be found, the corresponding key will be mapped to a null\n   *     value.\n   */\n  getEntries(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet\n  ): PersistencePromise<NullableMaybeDocumentMap> {\n    return this.getAllFromCache(transaction, documentKeys);\n  }\n\n  /**\n   * Applies buffered changes to the underlying RemoteDocumentCache, using\n   * the provided transaction.\n   */\n  apply(transaction: PersistenceTransaction): PersistencePromise<void> {\n    this.assertNotApplied();\n    this.changesApplied = true;\n    return this.applyChanges(transaction);\n  }\n\n  /** Helper to assert this.changes is not null  */\n  protected assertNotApplied(): void {\n    debugAssert(!this.changesApplied, 'Changes have already been applied.');\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 { User } from '../auth/user';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { IndexManager } from './index_manager';\nimport { LocalStore } from './local_store';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { TargetData } from './target_data';\n\nexport const PRIMARY_LEASE_LOST_ERROR_MSG =\n  'The current tab is not in the required state to perform this operation. ' +\n  'It might be necessary to refresh the browser tab.';\n\n/**\n * A base class representing a persistence transaction, encapsulating both the\n * transaction's sequence numbers as well as a list of onCommitted listeners.\n *\n * When you call Persistence.runTransaction(), it will create a transaction and\n * pass it to your callback. You then pass it to any method that operates\n * on persistence.\n */\nexport abstract class PersistenceTransaction {\n  private readonly onCommittedListeners: Array<() => void> = [];\n\n  abstract readonly currentSequenceNumber: ListenSequenceNumber;\n\n  addOnCommittedListener(listener: () => void): void {\n    this.onCommittedListeners.push(listener);\n  }\n\n  raiseOnCommittedEvent(): void {\n    this.onCommittedListeners.forEach(listener => listener());\n  }\n}\n\n/** The different modes supported by `IndexedDbPersistence.runTransaction()`. */\nexport type PersistenceTransactionMode =\n  | 'readonly'\n  | 'readwrite'\n  | 'readwrite-primary';\n\n/**\n * Callback type for primary state notifications. This callback can be\n * registered with the persistence layer to get notified when we transition from\n * primary to secondary state and vice versa.\n *\n * Note: Instances can only toggle between Primary and Secondary state if\n * IndexedDB persistence is enabled and multiple clients are active. If this\n * listener is registered with MemoryPersistence, the callback will be called\n * exactly once marking the current instance as Primary.\n */\nexport type PrimaryStateListener = (isPrimary: boolean) => Promise<void>;\n\n/**\n * A ReferenceDelegate instance handles all of the hooks into the document-reference lifecycle. This\n * includes being added to a target, being removed from a target, being subject to mutation, and\n * being mutated by the user.\n *\n * Different implementations may do different things with each of these events. Not every\n * implementation needs to do something with every lifecycle hook.\n *\n * PORTING NOTE: since sequence numbers are attached to transactions in this\n * client, the ReferenceDelegate does not need to deal in transactional\n * semantics (onTransactionStarted/Committed()), nor does it need to track and\n * generate sequence numbers (getCurrentSequenceNumber()).\n */\nexport interface ReferenceDelegate {\n  /** Notify the delegate that the given document was added to a target. */\n  addReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    doc: DocumentKey\n  ): PersistencePromise<void>;\n\n  /** Notify the delegate that the given document was removed from a target. */\n  removeReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    doc: DocumentKey\n  ): PersistencePromise<void>;\n\n  /**\n   * Notify the delegate that a target was removed. The delegate may, but is not obligated to,\n   * actually delete the target and associated data.\n   */\n  removeTarget(\n    txn: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void>;\n\n  /**\n   * Notify the delegate that a document may no longer be part of any views or\n   * have any mutations associated.\n   */\n  markPotentiallyOrphaned(\n    txn: PersistenceTransaction,\n    doc: DocumentKey\n  ): PersistencePromise<void>;\n\n  /** Notify the delegate that a limbo document was updated. */\n  updateLimboDocument(\n    txn: PersistenceTransaction,\n    doc: DocumentKey\n  ): PersistencePromise<void>;\n}\n\n/**\n * Persistence is the lowest-level shared interface to persistent storage in\n * Firestore.\n *\n * Persistence is used to create MutationQueue and RemoteDocumentCache\n * instances backed by persistence (which might be in-memory or LevelDB).\n *\n * Persistence also exposes an API to create and run PersistenceTransactions\n * against persistence. All read / write operations must be wrapped in a\n * transaction. Implementations of PersistenceTransaction / Persistence only\n * need to guarantee that writes made against the transaction are not made to\n * durable storage until the transaction resolves its PersistencePromise.\n * Since memory-only storage components do not alter durable storage, they are\n * free to ignore the transaction.\n *\n * This contract is enough to allow the LocalStore be be written\n * independently of whether or not the stored state actually is durably\n * persisted. If persistent storage is enabled, writes are grouped together to\n * avoid inconsistent state that could cause crashes.\n *\n * Concretely, when persistent storage is enabled, the persistent versions of\n * MutationQueue, RemoteDocumentCache, and others (the mutators) will\n * defer their writes into a transaction. Once the local store has completed\n * one logical operation, it commits the transaction.\n *\n * When persistent storage is disabled, the non-persistent versions of the\n * mutators ignore the transaction. This short-cut is allowed because\n * memory-only storage leaves no state so it cannot be inconsistent.\n *\n * This simplifies the implementations of the mutators and allows memory-only\n * implementations to supplement the persistent ones without requiring any\n * special dual-store implementation of Persistence. The cost is that the\n * LocalStore needs to be slightly careful about the order of its reads and\n * writes in order to avoid relying on being able to read back uncommitted\n * writes.\n */\nexport interface Persistence {\n  /**\n   * Whether or not this persistence instance has been started.\n   */\n  readonly started: boolean;\n\n  readonly referenceDelegate: ReferenceDelegate;\n\n  /** Starts persistence. */\n  start(): Promise<void>;\n\n  /**\n   * Releases any resources held during eager shutdown.\n   */\n  shutdown(): Promise<void>;\n\n  /**\n   * Registers a listener that gets called when the database receives a\n   * version change event indicating that it has deleted.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  setDatabaseDeletedListener(\n    databaseDeletedListener: () => Promise<void>\n  ): void;\n\n  /**\n   * Adjusts the current network state in the client's metadata, potentially\n   * affecting the primary lease.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  setNetworkEnabled(networkEnabled: boolean): void;\n\n  /**\n   * Returns a MutationQueue representing the persisted mutations for the\n   * given user.\n   *\n   * Note: The implementation is free to return the same instance every time\n   * this is called for a given user. In particular, the memory-backed\n   * implementation does this to emulate the persisted implementation to the\n   * extent possible (e.g. in the case of uid switching from\n   * sally=>jack=>sally, sally's mutation queue will be preserved).\n   */\n  getMutationQueue(user: User): MutationQueue;\n\n  /**\n   * Returns a TargetCache representing the persisted cache of targets.\n   *\n   * Note: The implementation is free to return the same instance every time\n   * this is called. In particular, the memory-backed implementation does this\n   * to emulate the persisted implementation to the extent possible.\n   */\n  getTargetCache(): TargetCache;\n\n  /**\n   * Returns a RemoteDocumentCache representing the persisted cache of remote\n   * documents.\n   *\n   * Note: The implementation is free to return the same instance every time\n   * this is called. In particular, the memory-backed implementation does this\n   * to emulate the persisted implementation to the extent possible.\n   */\n  getRemoteDocumentCache(): RemoteDocumentCache;\n\n  /**\n   * Returns an IndexManager instance that manages our persisted query indexes.\n   *\n   * Note: The implementation is free to return the same instance every time\n   * this is called. In particular, the memory-backed implementation does this\n   * to emulate the persisted implementation to the extent possible.\n   */\n  getIndexManager(): IndexManager;\n\n  /**\n   * Performs an operation inside a persistence transaction. Any reads or writes\n   * against persistence must be performed within a transaction. Writes will be\n   * committed atomically once the transaction completes.\n   *\n   * Persistence operations are asynchronous and therefore the provided\n   * transactionOperation must return a PersistencePromise. When it is resolved,\n   * the transaction will be committed and the Promise returned by this method\n   * will resolve.\n   *\n   * @param action A description of the action performed by this transaction,\n   * used for logging.\n   * @param mode The underlying mode of the IndexedDb transaction. Can be\n   * 'readonly`, 'readwrite' or 'readwrite-primary'. Transactions marked\n   * 'readwrite-primary' can only be executed by the primary client. In this\n   * mode, the transactionOperation will not be run if the primary lease cannot\n   * be acquired and the returned promise will be rejected with a\n   * FAILED_PRECONDITION error.\n   * @param transactionOperation The operation to run inside a transaction.\n   * @return A promise that is resolved once the transaction completes.\n   */\n  runTransaction<T>(\n    action: string,\n    mode: PersistenceTransactionMode,\n    transactionOperation: (\n      transaction: PersistenceTransaction\n    ) => PersistencePromise<T>\n  ): Promise<T>;\n}\n\n/**\n * Interface implemented by the LRU scheduler to start(), stop() and restart\n * garbage collection.\n */\nexport interface GarbageCollectionScheduler {\n  readonly started: boolean;\n  start(localStore: LocalStore): void;\n  stop(): void;\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 {\n  isCollectionGroupQuery,\n  isDocumentQuery,\n  Query,\n  queryMatches\n} from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n  DocumentKeySet,\n  documentKeySet,\n  DocumentMap,\n  documentMap,\n  MaybeDocumentMap,\n  maybeDocumentMap,\n  NullableMaybeDocumentMap,\n  nullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { MutationBatch } from '../model/mutation_batch';\nimport { ResourcePath } from '../model/path';\n\nimport { debugAssert } from '../util/assert';\nimport { IndexManager } from './index_manager';\nimport { MutationQueue } from './mutation_queue';\nimport { applyMutationToLocalView, PatchMutation } from '../model/mutation';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\n\n/**\n * A readonly view of the local state of all documents we're tracking (i.e. we\n * have a cached version in remoteDocumentCache or local mutations for the\n * document). The view is computed by applying the mutations in the\n * MutationQueue to the RemoteDocumentCache.\n */\nexport class LocalDocumentsView {\n  constructor(\n    readonly remoteDocumentCache: RemoteDocumentCache,\n    readonly mutationQueue: MutationQueue,\n    readonly indexManager: IndexManager\n  ) {}\n\n  /**\n   * Get the local view of the document identified by `key`.\n   *\n   * @return Local view of the document or null if we don't have any cached\n   * state for it.\n   */\n  getDocument(\n    transaction: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<MaybeDocument | null> {\n    return this.mutationQueue\n      .getAllMutationBatchesAffectingDocumentKey(transaction, key)\n      .next(batches => this.getDocumentInternal(transaction, key, batches));\n  }\n\n  /** Internal version of `getDocument` that allows reusing batches. */\n  private getDocumentInternal(\n    transaction: PersistenceTransaction,\n    key: DocumentKey,\n    inBatches: MutationBatch[]\n  ): PersistencePromise<MaybeDocument | null> {\n    return this.remoteDocumentCache.getEntry(transaction, key).next(doc => {\n      for (const batch of inBatches) {\n        doc = batch.applyToLocalView(key, doc);\n      }\n      return doc;\n    });\n  }\n\n  // Returns the view of the given `docs` as they would appear after applying\n  // all mutations in the given `batches`.\n  private applyLocalMutationsToDocuments(\n    transaction: PersistenceTransaction,\n    docs: NullableMaybeDocumentMap,\n    batches: MutationBatch[]\n  ): NullableMaybeDocumentMap {\n    let results = nullableMaybeDocumentMap();\n    docs.forEach((key, localView) => {\n      for (const batch of batches) {\n        localView = batch.applyToLocalView(key, localView);\n      }\n      results = results.insert(key, localView);\n    });\n    return results;\n  }\n\n  /**\n   * Gets the local view of the documents identified by `keys`.\n   *\n   * If we don't have cached state for a document in `keys`, a NoDocument will\n   * be stored for that key in the resulting set.\n   */\n  getDocuments(\n    transaction: PersistenceTransaction,\n    keys: DocumentKeySet\n  ): PersistencePromise<MaybeDocumentMap> {\n    return this.remoteDocumentCache\n      .getEntries(transaction, keys)\n      .next(docs => this.getLocalViewOfDocuments(transaction, docs));\n  }\n\n  /**\n   * Similar to `getDocuments`, but creates the local view from the given\n   * `baseDocs` without retrieving documents from the local store.\n   */\n  getLocalViewOfDocuments(\n    transaction: PersistenceTransaction,\n    baseDocs: NullableMaybeDocumentMap\n  ): PersistencePromise<MaybeDocumentMap> {\n    return this.mutationQueue\n      .getAllMutationBatchesAffectingDocumentKeys(transaction, baseDocs)\n      .next(batches => {\n        const docs = this.applyLocalMutationsToDocuments(\n          transaction,\n          baseDocs,\n          batches\n        );\n        let results = maybeDocumentMap();\n        docs.forEach((key, maybeDoc) => {\n          // TODO(http://b/32275378): Don't conflate missing / deleted.\n          if (!maybeDoc) {\n            maybeDoc = new NoDocument(key, SnapshotVersion.min());\n          }\n          results = results.insert(key, maybeDoc);\n        });\n\n        return results;\n      });\n  }\n\n  /**\n   * Performs a query against the local view of all documents.\n   *\n   * @param transaction The persistence transaction.\n   * @param query The query to match documents against.\n   * @param sinceReadTime If not set to SnapshotVersion.min(), return only\n   *     documents that have been read since this snapshot version (exclusive).\n   */\n  getDocumentsMatchingQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<DocumentMap> {\n    if (isDocumentQuery(query)) {\n      return this.getDocumentsMatchingDocumentQuery(transaction, query.path);\n    } else if (isCollectionGroupQuery(query)) {\n      return this.getDocumentsMatchingCollectionGroupQuery(\n        transaction,\n        query,\n        sinceReadTime\n      );\n    } else {\n      return this.getDocumentsMatchingCollectionQuery(\n        transaction,\n        query,\n        sinceReadTime\n      );\n    }\n  }\n\n  private getDocumentsMatchingDocumentQuery(\n    transaction: PersistenceTransaction,\n    docPath: ResourcePath\n  ): PersistencePromise<DocumentMap> {\n    // Just do a simple document lookup.\n    return this.getDocument(transaction, new DocumentKey(docPath)).next(\n      maybeDoc => {\n        let result = documentMap();\n        if (maybeDoc instanceof Document) {\n          result = result.insert(maybeDoc.key, maybeDoc);\n        }\n        return result;\n      }\n    );\n  }\n\n  private getDocumentsMatchingCollectionGroupQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<DocumentMap> {\n    debugAssert(\n      query.path.isEmpty(),\n      'Currently we only support collection group queries at the root.'\n    );\n    const collectionId = query.collectionGroup!;\n    let results = documentMap();\n    return this.indexManager\n      .getCollectionParents(transaction, collectionId)\n      .next(parents => {\n        // Perform a collection query against each parent that contains the\n        // collectionId and aggregate the results.\n        return PersistencePromise.forEach(parents, (parent: ResourcePath) => {\n          const collectionQuery = query.asCollectionQueryAtPath(\n            parent.child(collectionId)\n          );\n          return this.getDocumentsMatchingCollectionQuery(\n            transaction,\n            collectionQuery,\n            sinceReadTime\n          ).next(r => {\n            r.forEach((key, doc) => {\n              results = results.insert(key, doc);\n            });\n          });\n        }).next(() => results);\n      });\n  }\n\n  private getDocumentsMatchingCollectionQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<DocumentMap> {\n    // Query the remote documents and overlay mutations.\n    let results: DocumentMap;\n    let mutationBatches: MutationBatch[];\n    return this.remoteDocumentCache\n      .getDocumentsMatchingQuery(transaction, query, sinceReadTime)\n      .next(queryResults => {\n        results = queryResults;\n        return this.mutationQueue.getAllMutationBatchesAffectingQuery(\n          transaction,\n          query\n        );\n      })\n      .next(matchingMutationBatches => {\n        mutationBatches = matchingMutationBatches;\n        // It is possible that a PatchMutation can make a document match a query, even if\n        // the version in the RemoteDocumentCache is not a match yet (waiting for server\n        // to ack). To handle this, we find all document keys affected by the PatchMutations\n        // that are not in `result` yet, and back fill them via `remoteDocumentCache.getEntries`,\n        // otherwise those `PatchMutations` will be ignored because no base document can be found,\n        // and lead to missing result for the query.\n        return this.addMissingBaseDocuments(\n          transaction,\n          mutationBatches,\n          results\n        ).next(mergedDocuments => {\n          results = mergedDocuments;\n\n          for (const batch of mutationBatches) {\n            for (const mutation of batch.mutations) {\n              const key = mutation.key;\n              const baseDoc = results.get(key);\n              const mutatedDoc = applyMutationToLocalView(\n                mutation,\n                baseDoc,\n                baseDoc,\n                batch.localWriteTime\n              );\n              if (mutatedDoc instanceof Document) {\n                results = results.insert(key, mutatedDoc);\n              } else {\n                results = results.remove(key);\n              }\n            }\n          }\n        });\n      })\n      .next(() => {\n        // Finally, filter out any documents that don't actually match\n        // the query.\n        results.forEach((key, doc) => {\n          if (!queryMatches(query, doc)) {\n            results = results.remove(key);\n          }\n        });\n\n        return results;\n      });\n  }\n\n  private addMissingBaseDocuments(\n    transaction: PersistenceTransaction,\n    matchingMutationBatches: MutationBatch[],\n    existingDocuments: DocumentMap\n  ): PersistencePromise<DocumentMap> {\n    let missingBaseDocEntriesForPatching = documentKeySet();\n    for (const batch of matchingMutationBatches) {\n      for (const mutation of batch.mutations) {\n        if (\n          mutation instanceof PatchMutation &&\n          existingDocuments.get(mutation.key) === null\n        ) {\n          missingBaseDocEntriesForPatching = missingBaseDocEntriesForPatching.add(\n            mutation.key\n          );\n        }\n      }\n    }\n\n    let mergedDocuments = existingDocuments;\n    return this.remoteDocumentCache\n      .getEntries(transaction, missingBaseDocEntriesForPatching)\n      .next(missingBaseDocs => {\n        missingBaseDocs.forEach((key, doc) => {\n          if (doc !== null && doc instanceof Document) {\n            mergedDocuments = mergedDocuments.insert(key, doc);\n          }\n        });\n        return mergedDocuments;\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 { TargetId } from '../core/types';\nimport { ChangeType, ViewSnapshot } from '../core/view_snapshot';\nimport { documentKeySet, DocumentKeySet } from '../model/collections';\n\n/**\n * A set of changes to what documents are currently in view and out of view for\n * a given query. These changes are sent to the LocalStore by the View (via\n * the SyncEngine) and are used to pin / unpin documents as appropriate.\n */\nexport class LocalViewChanges {\n  constructor(\n    readonly targetId: TargetId,\n    readonly fromCache: boolean,\n    readonly addedKeys: DocumentKeySet,\n    readonly removedKeys: DocumentKeySet\n  ) {}\n\n  static fromSnapshot(\n    targetId: TargetId,\n    viewSnapshot: ViewSnapshot\n  ): LocalViewChanges {\n    let addedKeys = documentKeySet();\n    let removedKeys = documentKeySet();\n\n    for (const docChange of viewSnapshot.docChanges) {\n      switch (docChange.type) {\n        case ChangeType.Added:\n          addedKeys = addedKeys.add(docChange.doc.key);\n          break;\n        case ChangeType.Removed:\n          removedKeys = removedKeys.add(docChange.doc.key);\n          break;\n        default:\n        // do nothing\n      }\n    }\n\n    return new LocalViewChanges(\n      targetId,\n      viewSnapshot.fromCache,\n      addedKeys,\n      removedKeys\n    );\n  }\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 { ListenSequenceNumber } from './types';\n\n/**\n * `SequenceNumberSyncer` defines the methods required to keep multiple instances of a\n * `ListenSequence` in sync.\n */\nexport interface SequenceNumberSyncer {\n  // Notify the syncer that a new sequence number has been used.\n  writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void;\n  // Setting this property allows the syncer to notify when a sequence number has been used, and\n  // and lets the ListenSequence adjust its internal previous value accordingly.\n  sequenceNumberHandler:\n    | ((sequenceNumber: ListenSequenceNumber) => void)\n    | null;\n}\n\n/**\n * `ListenSequence` is a monotonic sequence. It is initialized with a minimum value to\n * exceed. All subsequent calls to next will return increasing values. If provided with a\n * `SequenceNumberSyncer`, it will additionally bump its next value when told of a new value, as\n * well as write out sequence numbers that it produces via `next()`.\n */\nexport class ListenSequence {\n  static readonly INVALID: ListenSequenceNumber = -1;\n\n  private writeNewSequenceNumber?: (\n    newSequenceNumber: ListenSequenceNumber\n  ) => void;\n\n  constructor(\n    private previousValue: ListenSequenceNumber,\n    sequenceNumberSyncer?: SequenceNumberSyncer\n  ) {\n    if (sequenceNumberSyncer) {\n      sequenceNumberSyncer.sequenceNumberHandler = sequenceNumber =>\n        this.setPreviousValue(sequenceNumber);\n      this.writeNewSequenceNumber = sequenceNumber =>\n        sequenceNumberSyncer.writeSequenceNumber(sequenceNumber);\n    }\n  }\n\n  private setPreviousValue(\n    externalPreviousValue: ListenSequenceNumber\n  ): ListenSequenceNumber {\n    this.previousValue = Math.max(externalPreviousValue, this.previousValue);\n    return this.previousValue;\n  }\n\n  next(): ListenSequenceNumber {\n    const nextValue = ++this.previousValue;\n    if (this.writeNewSequenceNumber) {\n      this.writeNewSequenceNumber(nextValue);\n    }\n    return nextValue;\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 interface Resolver<R> {\n  (value?: R | Promise<R>): void;\n}\n\nexport interface Rejecter {\n  (reason?: Error): void;\n}\n\nexport class Deferred<R = void> {\n  promise: Promise<R>;\n  // Assigned synchronously in constructor by Promise constructor callback.\n  resolve!: Resolver<R>;\n  reject!: Rejecter;\n\n  constructor() {\n    this.promise = new Promise((resolve: Resolver<R>, reject: Rejecter) => {\n      this.resolve = resolve;\n      this.reject = reject;\n    });\n  }\n}\n\n/**\n * Takes an array of values and a function from a value to a Promise. The function is run on each\n * value sequentially, waiting for the previous promise to resolve before starting the next one.\n * The returned promise resolves once the function has been run on all values.\n */\nexport function sequence<T>(\n  values: T[],\n  fn: (value: T) => Promise<void>\n): Promise<void> {\n  let p = Promise.resolve();\n  for (const value of values) {\n    p = p.then(() => fn(value));\n  }\n  return p;\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 { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { logDebug } from '../util/log';\n\nconst LOG_TAG = 'ExponentialBackoff';\n\n/**\n * Initial backoff time in milliseconds after an error.\n * Set to 1s according to https://cloud.google.com/apis/design/errors.\n */\nconst DEFAULT_BACKOFF_INITIAL_DELAY_MS = 1000;\n\nconst DEFAULT_BACKOFF_FACTOR = 1.5;\n\n/** Maximum backoff time in milliseconds */\nconst DEFAULT_BACKOFF_MAX_DELAY_MS = 60 * 1000;\n\n/**\n * A helper for running delayed tasks following an exponential backoff curve\n * between attempts.\n *\n * Each delay is made up of a \"base\" delay which follows the exponential\n * backoff curve, and a +/- 50% \"jitter\" that is calculated and added to the\n * base delay. This prevents clients from accidentally synchronizing their\n * delays causing spikes of load to the backend.\n */\nexport class ExponentialBackoff {\n  private currentBaseMs: number = 0;\n  private timerPromise: DelayedOperation<void> | null = null;\n  /** The last backoff attempt, as epoch milliseconds. */\n  private lastAttemptTime = Date.now();\n\n  constructor(\n    /**\n     * The AsyncQueue to run backoff operations on.\n     */\n    private readonly queue: AsyncQueue,\n    /**\n     * The ID to use when scheduling backoff operations on the AsyncQueue.\n     */\n    private readonly timerId: TimerId,\n    /**\n     * The initial delay (used as the base delay on the first retry attempt).\n     * Note that jitter will still be applied, so the actual delay could be as\n     * little as 0.5*initialDelayMs.\n     */\n    private readonly initialDelayMs: number = DEFAULT_BACKOFF_INITIAL_DELAY_MS,\n    /**\n     * The multiplier to use to determine the extended base delay after each\n     * attempt.\n     */\n    private readonly backoffFactor: number = DEFAULT_BACKOFF_FACTOR,\n    /**\n     * The maximum base delay after which no further backoff is performed.\n     * Note that jitter will still be applied, so the actual delay could be as\n     * much as 1.5*maxDelayMs.\n     */\n    private readonly maxDelayMs: number = DEFAULT_BACKOFF_MAX_DELAY_MS\n  ) {\n    this.reset();\n  }\n\n  /**\n   * Resets the backoff delay.\n   *\n   * The very next backoffAndWait() will have no delay. If it is called again\n   * (i.e. due to an error), initialDelayMs (plus jitter) will be used, and\n   * subsequent ones will increase according to the backoffFactor.\n   */\n  reset(): void {\n    this.currentBaseMs = 0;\n  }\n\n  /**\n   * Resets the backoff delay to the maximum delay (e.g. for use after a\n   * RESOURCE_EXHAUSTED error).\n   */\n  resetToMax(): void {\n    this.currentBaseMs = this.maxDelayMs;\n  }\n\n  /**\n   * Returns a promise that resolves after currentDelayMs, and increases the\n   * delay for any subsequent attempts. If there was a pending backoff operation\n   * already, it will be canceled.\n   */\n  backoffAndRun(op: () => Promise<void>): void {\n    // Cancel any pending backoff operation.\n    this.cancel();\n\n    // First schedule using the current base (which may be 0 and should be\n    // honored as such).\n    const desiredDelayWithJitterMs = Math.floor(\n      this.currentBaseMs + this.jitterDelayMs()\n    );\n\n    // Guard against lastAttemptTime being in the future due to a clock change.\n    const delaySoFarMs = Math.max(0, Date.now() - this.lastAttemptTime);\n\n    // Guard against the backoff delay already being past.\n    const remainingDelayMs = Math.max(\n      0,\n      desiredDelayWithJitterMs - delaySoFarMs\n    );\n\n    if (remainingDelayMs > 0) {\n      logDebug(\n        LOG_TAG,\n        `Backing off for ${remainingDelayMs} ms ` +\n          `(base delay: ${this.currentBaseMs} ms, ` +\n          `delay with jitter: ${desiredDelayWithJitterMs} ms, ` +\n          `last attempt: ${delaySoFarMs} ms ago)`\n      );\n    }\n\n    this.timerPromise = this.queue.enqueueAfterDelay(\n      this.timerId,\n      remainingDelayMs,\n      () => {\n        this.lastAttemptTime = Date.now();\n        return op();\n      }\n    );\n\n    // Apply backoff factor to determine next delay and ensure it is within\n    // bounds.\n    this.currentBaseMs *= this.backoffFactor;\n    if (this.currentBaseMs < this.initialDelayMs) {\n      this.currentBaseMs = this.initialDelayMs;\n    }\n    if (this.currentBaseMs > this.maxDelayMs) {\n      this.currentBaseMs = this.maxDelayMs;\n    }\n  }\n\n  skipBackoff(): void {\n    if (this.timerPromise !== null) {\n      this.timerPromise.skipDelay();\n      this.timerPromise = null;\n    }\n  }\n\n  cancel(): void {\n    if (this.timerPromise !== null) {\n      this.timerPromise.cancel();\n      this.timerPromise = null;\n    }\n  }\n\n  /** Returns a random value in the range [-currentBaseMs/2, currentBaseMs/2] */\n  private jitterDelayMs(): number {\n    return (Math.random() - 0.5) * this.currentBaseMs;\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 { getUA } from '@firebase/util';\nimport { debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\nimport { Deferred } from '../util/promise';\nimport { PersistencePromise } from './persistence_promise';\n\n// References to `window` are guarded by SimpleDb.isAvailable()\n/* eslint-disable no-restricted-globals */\n\nconst LOG_TAG = 'SimpleDb';\n\n/**\n * The maximum number of retry attempts for an IndexedDb transaction that fails\n * with a DOMException.\n */\nconst TRANSACTION_RETRY_COUNT = 3;\n\n// The different modes supported by `SimpleDb.runTransaction()`\ntype SimpleDbTransactionMode = 'readonly' | 'readwrite';\n\nexport interface SimpleDbSchemaConverter {\n  createOrUpgrade(\n    db: IDBDatabase,\n    txn: IDBTransaction,\n    fromVersion: number,\n    toVersion: number\n  ): PersistencePromise<void>;\n}\n\n/**\n * Provides a wrapper around IndexedDb with a simplified interface that uses\n * Promise-like return values to chain operations. Real promises cannot be used\n * since .then() continuations are executed asynchronously (e.g. via\n * .setImmediate), which would cause IndexedDB to end the transaction.\n * See PersistencePromise for more details.\n */\nexport class SimpleDb {\n  private db?: IDBDatabase;\n  private versionchangelistener?: (event: IDBVersionChangeEvent) => void;\n\n  /** Deletes the specified database. */\n  static delete(name: string): Promise<void> {\n    logDebug(LOG_TAG, 'Removing database:', name);\n    return wrapRequest<void>(window.indexedDB.deleteDatabase(name)).toPromise();\n  }\n\n  /** Returns true if IndexedDB is available in the current environment. */\n  static isAvailable(): boolean {\n    if (typeof indexedDB === 'undefined') {\n      return false;\n    }\n\n    if (SimpleDb.isMockPersistence()) {\n      return true;\n    }\n\n    // We extensively use indexed array values and compound keys,\n    // which IE and Edge do not support. However, they still have indexedDB\n    // defined on the window, so we need to check for them here and make sure\n    // to return that persistence is not enabled for those browsers.\n    // For tracking support of this feature, see here:\n    // https://developer.microsoft.com/en-us/microsoft-edge/platform/status/indexeddbarraysandmultientrysupport/\n\n    // Check the UA string to find out the browser.\n    const ua = getUA();\n\n    // IE 10\n    // ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';\n\n    // IE 11\n    // ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';\n\n    // Edge\n    // ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,\n    // like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';\n\n    // iOS Safari: Disable for users running iOS version < 10.\n    const iOSVersion = SimpleDb.getIOSVersion(ua);\n    const isUnsupportedIOS = 0 < iOSVersion && iOSVersion < 10;\n\n    // Android browser: Disable for userse running version < 4.5.\n    const androidVersion = SimpleDb.getAndroidVersion(ua);\n    const isUnsupportedAndroid = 0 < androidVersion && androidVersion < 4.5;\n\n    if (\n      ua.indexOf('MSIE ') > 0 ||\n      ua.indexOf('Trident/') > 0 ||\n      ua.indexOf('Edge/') > 0 ||\n      isUnsupportedIOS ||\n      isUnsupportedAndroid\n    ) {\n      return false;\n    } else {\n      return true;\n    }\n  }\n\n  /**\n   * Returns true if the backing IndexedDB store is the Node IndexedDBShim\n   * (see https://github.com/axemclion/IndexedDBShim).\n   */\n  static isMockPersistence(): boolean {\n    return (\n      typeof process !== 'undefined' &&\n      process.env?.USE_MOCK_PERSISTENCE === 'YES'\n    );\n  }\n\n  /** Helper to get a typed SimpleDbStore from a transaction. */\n  static getStore<KeyType extends IDBValidKey, ValueType extends unknown>(\n    txn: SimpleDbTransaction,\n    store: string\n  ): SimpleDbStore<KeyType, ValueType> {\n    return txn.store<KeyType, ValueType>(store);\n  }\n\n  // visible for testing\n  /** Parse User Agent to determine iOS version. Returns -1 if not found. */\n  static getIOSVersion(ua: string): number {\n    const iOSVersionRegex = ua.match(/i(?:phone|pad|pod) os ([\\d_]+)/i);\n    const version = iOSVersionRegex\n      ? iOSVersionRegex[1].split('_').slice(0, 2).join('.')\n      : '-1';\n    return Number(version);\n  }\n\n  // visible for testing\n  /** Parse User Agent to determine Android version. Returns -1 if not found. */\n  static getAndroidVersion(ua: string): number {\n    const androidVersionRegex = ua.match(/Android ([\\d.]+)/i);\n    const version = androidVersionRegex\n      ? androidVersionRegex[1].split('.').slice(0, 2).join('.')\n      : '-1';\n    return Number(version);\n  }\n\n  /*\n   * Creates a new SimpleDb wrapper for IndexedDb database `name`.\n   *\n   * Note that `version` must not be a downgrade. IndexedDB does not support\n   * downgrading the schema version. We currently do not support any way to do\n   * versioning outside of IndexedDB's versioning mechanism, as only\n   * version-upgrade transactions are allowed to do things like create\n   * objectstores.\n   */\n  constructor(\n    private readonly name: string,\n    private readonly version: number,\n    private readonly schemaConverter: SimpleDbSchemaConverter\n  ) {\n    debugAssert(\n      SimpleDb.isAvailable(),\n      'IndexedDB not supported in current environment.'\n    );\n\n    const iOSVersion = SimpleDb.getIOSVersion(getUA());\n    // NOTE: According to https://bugs.webkit.org/show_bug.cgi?id=197050, the\n    // bug we're checking for should exist in iOS >= 12.2 and < 13, but for\n    // whatever reason it's much harder to hit after 12.2 so we only proactively\n    // log on 12.2.\n    if (iOSVersion === 12.2) {\n      logError(\n        'Firestore persistence suffers from a bug in iOS 12.2 ' +\n          'Safari that may cause your app to stop working. See ' +\n          'https://stackoverflow.com/q/56496296/110915 for details ' +\n          'and a potential workaround.'\n      );\n    }\n  }\n\n  /**\n   * Opens the specified database, creating or upgrading it if necessary.\n   */\n  async ensureDb(): Promise<IDBDatabase> {\n    if (!this.db) {\n      logDebug(LOG_TAG, 'Opening database:', this.name);\n      this.db = await new Promise<IDBDatabase>((resolve, reject) => {\n        // TODO(mikelehen): Investigate browser compatibility.\n        // https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB\n        // suggests IE9 and older WebKit browsers handle upgrade\n        // differently. They expect setVersion, as described here:\n        // https://developer.mozilla.org/en-US/docs/Web/API/IDBVersionChangeRequest/setVersion\n        const request = indexedDB.open(this.name, this.version);\n\n        request.onsuccess = (event: Event) => {\n          const db = (event.target as IDBOpenDBRequest).result;\n          resolve(db);\n        };\n\n        request.onblocked = () => {\n          reject(\n            new IndexedDbTransactionError(\n              'Cannot upgrade IndexedDB schema while another tab is open. ' +\n                'Close all tabs that access Firestore and reload this page to proceed.'\n            )\n          );\n        };\n\n        request.onerror = (event: Event) => {\n          const error: DOMException = (event.target as IDBOpenDBRequest).error!;\n          if (error.name === 'VersionError') {\n            reject(\n              new FirestoreError(\n                Code.FAILED_PRECONDITION,\n                'A newer version of the Firestore SDK was previously used and so the persisted ' +\n                  'data is not compatible with the version of the SDK you are now using. The SDK ' +\n                  'will operate with persistence disabled. If you need persistence, please ' +\n                  're-upgrade to a newer version of the SDK or else clear the persisted IndexedDB ' +\n                  'data for your app to start fresh.'\n              )\n            );\n          } else {\n            reject(new IndexedDbTransactionError(error));\n          }\n        };\n\n        request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n          logDebug(\n            LOG_TAG,\n            'Database \"' + this.name + '\" requires upgrade from version:',\n            event.oldVersion\n          );\n          const db = (event.target as IDBOpenDBRequest).result;\n          this.schemaConverter\n            .createOrUpgrade(\n              db,\n              request.transaction!,\n              event.oldVersion,\n              this.version\n            )\n            .next(() => {\n              logDebug(\n                LOG_TAG,\n                'Database upgrade to version ' + this.version + ' complete'\n              );\n            });\n        };\n      });\n    }\n\n    if (this.versionchangelistener) {\n      this.db.onversionchange = event => this.versionchangelistener!(event);\n    }\n    return this.db;\n  }\n\n  setVersionChangeListener(\n    versionChangeListener: (event: IDBVersionChangeEvent) => void\n  ): void {\n    this.versionchangelistener = versionChangeListener;\n    if (this.db) {\n      this.db.onversionchange = (event: IDBVersionChangeEvent) => {\n        return versionChangeListener(event);\n      };\n    }\n  }\n\n  async runTransaction<T>(\n    mode: SimpleDbTransactionMode,\n    objectStores: string[],\n    transactionFn: (transaction: SimpleDbTransaction) => PersistencePromise<T>\n  ): Promise<T> {\n    const readonly = mode === 'readonly';\n    let attemptNumber = 0;\n\n    while (true) {\n      ++attemptNumber;\n\n      try {\n        this.db = await this.ensureDb();\n\n        const transaction = SimpleDbTransaction.open(\n          this.db,\n          readonly ? 'readonly' : 'readwrite',\n          objectStores\n        );\n        const transactionFnResult = transactionFn(transaction)\n          .catch(error => {\n            // Abort the transaction if there was an error.\n            transaction.abort(error);\n            // We cannot actually recover, and calling `abort()` will cause the transaction's\n            // completion promise to be rejected. This in turn means that we won't use\n            // `transactionFnResult` below. We return a rejection here so that we don't add the\n            // possibility of returning `void` to the type of `transactionFnResult`.\n            return PersistencePromise.reject<T>(error);\n          })\n          .toPromise();\n\n        // As noted above, errors are propagated by aborting the transaction. So\n        // we swallow any error here to avoid the browser logging it as unhandled.\n        transactionFnResult.catch(() => {});\n\n        // Wait for the transaction to complete (i.e. IndexedDb's onsuccess event to\n        // fire), but still return the original transactionFnResult back to the\n        // caller.\n        await transaction.completionPromise;\n        return transactionFnResult;\n      } catch (error) {\n        // TODO(schmidt-sebastian): We could probably be smarter about this and\n        // not retry exceptions that are likely unrecoverable (such as quota\n        // exceeded errors).\n\n        // Note: We cannot use an instanceof check for FirestoreException, since the\n        // exception is wrapped in a generic error by our async/await handling.\n        const retryable =\n          error.name !== 'FirebaseError' &&\n          attemptNumber < TRANSACTION_RETRY_COUNT;\n        logDebug(\n          LOG_TAG,\n          'Transaction failed with error: %s. Retrying: %s.',\n          error.message,\n          retryable\n        );\n\n        this.close();\n\n        if (!retryable) {\n          return Promise.reject(error);\n        }\n      }\n    }\n  }\n\n  close(): void {\n    if (this.db) {\n      this.db.close();\n    }\n    this.db = undefined;\n  }\n}\n\n/**\n * A controller for iterating over a key range or index. It allows an iterate\n * callback to delete the currently-referenced object, or jump to a new key\n * within the key range or index.\n */\nexport class IterationController {\n  private shouldStop = false;\n  private nextKey: IDBValidKey | null = null;\n\n  constructor(private dbCursor: IDBCursorWithValue) {}\n\n  get isDone(): boolean {\n    return this.shouldStop;\n  }\n\n  get skipToKey(): IDBValidKey | null {\n    return this.nextKey;\n  }\n\n  set cursor(value: IDBCursorWithValue) {\n    this.dbCursor = value;\n  }\n\n  /**\n   * This function can be called to stop iteration at any point.\n   */\n  done(): void {\n    this.shouldStop = true;\n  }\n\n  /**\n   * This function can be called to skip to that next key, which could be\n   * an index or a primary key.\n   */\n  skip(key: IDBValidKey): void {\n    this.nextKey = key;\n  }\n\n  /**\n   * Delete the current cursor value from the object store.\n   *\n   * NOTE: You CANNOT do this with a keysOnly query.\n   */\n  delete(): PersistencePromise<void> {\n    return wrapRequest<void>(this.dbCursor.delete());\n  }\n}\n\n/**\n * Callback used with iterate() method.\n */\nexport type IterateCallback<KeyType, ValueType> = (\n  key: KeyType,\n  value: ValueType,\n  control: IterationController\n) => void | PersistencePromise<void>;\n\n/** Options available to the iterate() method. */\nexport interface IterateOptions {\n  /** Index to iterate over (else primary keys will be iterated) */\n  index?: string;\n\n  /** IndxedDB Range to iterate over (else entire store will be iterated) */\n  range?: IDBKeyRange;\n\n  /** If true, values aren't read while iterating. */\n  keysOnly?: boolean;\n\n  /** If true, iterate over the store in reverse. */\n  reverse?: boolean;\n}\n\n/** An error that wraps exceptions that thrown during IndexedDB execution. */\nexport class IndexedDbTransactionError extends FirestoreError {\n  name = 'IndexedDbTransactionError';\n\n  constructor(cause: Error | string) {\n    super(Code.UNAVAILABLE, 'IndexedDB transaction failed: ' + cause);\n  }\n}\n\n/** Verifies whether `e` is an IndexedDbTransactionError. */\nexport function isIndexedDbTransactionError(e: Error): boolean {\n  // Use name equality, as instanceof checks on errors don't work with errors\n  // that wrap other errors.\n  return e.name === 'IndexedDbTransactionError';\n}\n\n/**\n * Wraps an IDBTransaction and exposes a store() method to get a handle to a\n * specific object store.\n */\nexport class SimpleDbTransaction {\n  private aborted = false;\n\n  /**\n   * A promise that resolves with the result of the IndexedDb transaction.\n   */\n  private readonly completionDeferred = new Deferred<void>();\n\n  static open(\n    db: IDBDatabase,\n    mode: IDBTransactionMode,\n    objectStoreNames: string[]\n  ): SimpleDbTransaction {\n    try {\n      return new SimpleDbTransaction(db.transaction(objectStoreNames, mode));\n    } catch (e) {\n      throw new IndexedDbTransactionError(e);\n    }\n  }\n\n  constructor(private readonly transaction: IDBTransaction) {\n    this.transaction.oncomplete = () => {\n      this.completionDeferred.resolve();\n    };\n    this.transaction.onabort = () => {\n      if (transaction.error) {\n        this.completionDeferred.reject(\n          new IndexedDbTransactionError(transaction.error)\n        );\n      } else {\n        this.completionDeferred.resolve();\n      }\n    };\n    this.transaction.onerror = (event: Event) => {\n      const error = checkForAndReportiOSError(\n        (event.target as IDBRequest).error!\n      );\n      this.completionDeferred.reject(new IndexedDbTransactionError(error));\n    };\n  }\n\n  get completionPromise(): Promise<void> {\n    return this.completionDeferred.promise;\n  }\n\n  abort(error?: Error): void {\n    if (error) {\n      this.completionDeferred.reject(error);\n    }\n\n    if (!this.aborted) {\n      logDebug(\n        LOG_TAG,\n        'Aborting transaction:',\n        error ? error.message : 'Client-initiated abort'\n      );\n      this.aborted = true;\n      this.transaction.abort();\n    }\n  }\n\n  /**\n   * Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All\n   * operations performed on the SimpleDbStore happen within the context of this\n   * transaction and it cannot be used anymore once the transaction is\n   * completed.\n   *\n   * Note that we can't actually enforce that the KeyType and ValueType are\n   * correct, but they allow type safety through the rest of the consuming code.\n   */\n  store<KeyType extends IDBValidKey, ValueType extends unknown>(\n    storeName: string\n  ): SimpleDbStore<KeyType, ValueType> {\n    const store = this.transaction.objectStore(storeName);\n    debugAssert(!!store, 'Object store not part of transaction: ' + storeName);\n    return new SimpleDbStore<KeyType, ValueType>(store);\n  }\n}\n\n/**\n * A wrapper around an IDBObjectStore providing an API that:\n *\n * 1) Has generic KeyType / ValueType parameters to provide strongly-typed\n * methods for acting against the object store.\n * 2) Deals with IndexedDB's onsuccess / onerror event callbacks, making every\n * method return a PersistencePromise instead.\n * 3) Provides a higher-level API to avoid needing to do excessive wrapping of\n * intermediate IndexedDB types (IDBCursorWithValue, etc.)\n */\nexport class SimpleDbStore<\n  KeyType extends IDBValidKey,\n  ValueType extends unknown\n> {\n  constructor(private store: IDBObjectStore) {}\n\n  /**\n   * Writes a value into the Object Store.\n   *\n   * @param key Optional explicit key to use when writing the object, else the\n   * key will be auto-assigned (e.g. via the defined keyPath for the store).\n   * @param value The object to write.\n   */\n  put(value: ValueType): PersistencePromise<void>;\n  put(key: KeyType, value: ValueType): PersistencePromise<void>;\n  put(\n    keyOrValue: KeyType | ValueType,\n    value?: ValueType\n  ): PersistencePromise<void> {\n    let request;\n    if (value !== undefined) {\n      logDebug(LOG_TAG, 'PUT', this.store.name, keyOrValue, value);\n      request = this.store.put(value, keyOrValue as KeyType);\n    } else {\n      logDebug(LOG_TAG, 'PUT', this.store.name, '<auto-key>', keyOrValue);\n      request = this.store.put(keyOrValue as ValueType);\n    }\n    return wrapRequest<void>(request);\n  }\n\n  /**\n   * Adds a new value into an Object Store and returns the new key. Similar to\n   * IndexedDb's `add()`, this method will fail on primary key collisions.\n   *\n   * @param value The object to write.\n   * @return The key of the value to add.\n   */\n  add(value: ValueType): PersistencePromise<KeyType> {\n    logDebug(LOG_TAG, 'ADD', this.store.name, value, value);\n    const request = this.store.add(value as ValueType);\n    return wrapRequest<KeyType>(request);\n  }\n\n  /**\n   * Gets the object with the specified key from the specified store, or null\n   * if no object exists with the specified key.\n   *\n   * @key The key of the object to get.\n   * @return The object with the specified key or null if no object exists.\n   */\n  get(key: KeyType): PersistencePromise<ValueType | null> {\n    const request = this.store.get(key);\n    // We're doing an unsafe cast to ValueType.\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return wrapRequest<any>(request).next(result => {\n      // Normalize nonexistence to null.\n      if (result === undefined) {\n        result = null;\n      }\n      logDebug(LOG_TAG, 'GET', this.store.name, key, result);\n      return result;\n    });\n  }\n\n  delete(key: KeyType | IDBKeyRange): PersistencePromise<void> {\n    logDebug(LOG_TAG, 'DELETE', this.store.name, key);\n    const request = this.store.delete(key);\n    return wrapRequest<void>(request);\n  }\n\n  /**\n   * If we ever need more of the count variants, we can add overloads. For now,\n   * all we need is to count everything in a store.\n   *\n   * Returns the number of rows in the store.\n   */\n  count(): PersistencePromise<number> {\n    logDebug(LOG_TAG, 'COUNT', this.store.name);\n    const request = this.store.count();\n    return wrapRequest<number>(request);\n  }\n\n  loadAll(): PersistencePromise<ValueType[]>;\n  loadAll(range: IDBKeyRange): PersistencePromise<ValueType[]>;\n  loadAll(index: string, range: IDBKeyRange): PersistencePromise<ValueType[]>;\n  loadAll(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): PersistencePromise<ValueType[]> {\n    const cursor = this.cursor(this.options(indexOrRange, range));\n    const results: ValueType[] = [];\n    return this.iterateCursor(cursor, (key, value) => {\n      results.push(value);\n    }).next(() => {\n      return results;\n    });\n  }\n\n  deleteAll(): PersistencePromise<void>;\n  deleteAll(range: IDBKeyRange): PersistencePromise<void>;\n  deleteAll(index: string, range: IDBKeyRange): PersistencePromise<void>;\n  deleteAll(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): PersistencePromise<void> {\n    logDebug(LOG_TAG, 'DELETE ALL', this.store.name);\n    const options = this.options(indexOrRange, range);\n    options.keysOnly = false;\n    const cursor = this.cursor(options);\n    return this.iterateCursor(cursor, (key, value, control) => {\n      // NOTE: Calling delete() on a cursor is documented as more efficient than\n      // calling delete() on an object store with a single key\n      // (https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/delete),\n      // however, this requires us *not* to use a keysOnly cursor\n      // (https://developer.mozilla.org/en-US/docs/Web/API/IDBCursor/delete). We\n      // may want to compare the performance of each method.\n      return control.delete();\n    });\n  }\n\n  /**\n   * Iterates over keys and values in an object store.\n   *\n   * @param options Options specifying how to iterate the objects in the store.\n   * @param callback will be called for each iterated object. Iteration can be\n   * canceled at any point by calling the doneFn passed to the callback.\n   * The callback can return a PersistencePromise if it performs async\n   * operations but note that iteration will continue without waiting for them\n   * to complete.\n   * @returns A PersistencePromise that resolves once all PersistencePromises\n   * returned by callbacks resolve.\n   */\n  iterate(\n    callback: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void>;\n  iterate(\n    options: IterateOptions,\n    callback: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void>;\n  iterate(\n    optionsOrCallback: IterateOptions | IterateCallback<KeyType, ValueType>,\n    callback?: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void> {\n    let options;\n    if (!callback) {\n      options = {};\n      callback = optionsOrCallback as IterateCallback<KeyType, ValueType>;\n    } else {\n      options = optionsOrCallback as IterateOptions;\n    }\n    const cursor = this.cursor(options);\n    return this.iterateCursor(cursor, callback);\n  }\n\n  /**\n   * Iterates over a store, but waits for the given callback to complete for\n   * each entry before iterating the next entry. This allows the callback to do\n   * asynchronous work to determine if this iteration should continue.\n   *\n   * The provided callback should return `true` to continue iteration, and\n   * `false` otherwise.\n   */\n  iterateSerial(\n    callback: (k: KeyType, v: ValueType) => PersistencePromise<boolean>\n  ): PersistencePromise<void> {\n    const cursorRequest = this.cursor({});\n    return new PersistencePromise((resolve, reject) => {\n      cursorRequest.onerror = (event: Event) => {\n        const error = checkForAndReportiOSError(\n          (event.target as IDBRequest).error!\n        );\n        reject(error);\n      };\n      cursorRequest.onsuccess = (event: Event) => {\n        const cursor: IDBCursorWithValue = (event.target as IDBRequest).result;\n        if (!cursor) {\n          resolve();\n          return;\n        }\n\n        callback(cursor.primaryKey as KeyType, cursor.value).next(\n          shouldContinue => {\n            if (shouldContinue) {\n              cursor.continue();\n            } else {\n              resolve();\n            }\n          }\n        );\n      };\n    });\n  }\n\n  private iterateCursor(\n    cursorRequest: IDBRequest,\n    fn: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void> {\n    const results: Array<PersistencePromise<void>> = [];\n    return new PersistencePromise((resolve, reject) => {\n      cursorRequest.onerror = (event: Event) => {\n        reject((event.target as IDBRequest).error!);\n      };\n      cursorRequest.onsuccess = (event: Event) => {\n        const cursor: IDBCursorWithValue = (event.target as IDBRequest).result;\n        if (!cursor) {\n          resolve();\n          return;\n        }\n        const controller = new IterationController(cursor);\n        const userResult = fn(\n          cursor.primaryKey as KeyType,\n          cursor.value,\n          controller\n        );\n        if (userResult instanceof PersistencePromise) {\n          const userPromise: PersistencePromise<void> = userResult.catch(\n            err => {\n              controller.done();\n              return PersistencePromise.reject(err);\n            }\n          );\n          results.push(userPromise);\n        }\n        if (controller.isDone) {\n          resolve();\n        } else if (controller.skipToKey === null) {\n          cursor.continue();\n        } else {\n          cursor.continue(controller.skipToKey);\n        }\n      };\n    }).next(() => {\n      return PersistencePromise.waitFor(results);\n    });\n  }\n\n  private options(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): IterateOptions {\n    let indexName: string | undefined = undefined;\n    if (indexOrRange !== undefined) {\n      if (typeof indexOrRange === 'string') {\n        indexName = indexOrRange;\n      } else {\n        debugAssert(\n          range === undefined,\n          '3rd argument must not be defined if 2nd is a range.'\n        );\n        range = indexOrRange;\n      }\n    }\n    return { index: indexName, range };\n  }\n\n  private cursor(options: IterateOptions): IDBRequest {\n    let direction: IDBCursorDirection = 'next';\n    if (options.reverse) {\n      direction = 'prev';\n    }\n    if (options.index) {\n      const index = this.store.index(options.index);\n      if (options.keysOnly) {\n        return index.openKeyCursor(options.range, direction);\n      } else {\n        return index.openCursor(options.range, direction);\n      }\n    } else {\n      return this.store.openCursor(options.range, direction);\n    }\n  }\n}\n\n/**\n * Wraps an IDBRequest in a PersistencePromise, using the onsuccess / onerror\n * handlers to resolve / reject the PersistencePromise as appropriate.\n */\nfunction wrapRequest<R>(request: IDBRequest): PersistencePromise<R> {\n  return new PersistencePromise<R>((resolve, reject) => {\n    request.onsuccess = (event: Event) => {\n      const result = (event.target as IDBRequest).result;\n      resolve(result);\n    };\n\n    request.onerror = (event: Event) => {\n      const error = checkForAndReportiOSError(\n        (event.target as IDBRequest).error!\n      );\n      reject(error);\n    };\n  });\n}\n\n// Guard so we only report the error once.\nlet reportedIOSError = false;\nfunction checkForAndReportiOSError(error: DOMException): Error {\n  const iOSVersion = SimpleDb.getIOSVersion(getUA());\n  if (iOSVersion >= 12.2 && iOSVersion < 13) {\n    const IOS_ERROR =\n      'An internal error was encountered in the Indexed Database server';\n    if (error.message.indexOf(IOS_ERROR) >= 0) {\n      // Wrap error in a more descriptive one.\n      const newError = new FirestoreError(\n        'internal',\n        `IOS_INDEXEDDB_BUG1: IndexedDb has thrown '${IOS_ERROR}'. This is likely ` +\n          `due to an unavoidable bug in iOS. See https://stackoverflow.com/q/56496296/110915 ` +\n          `for details and a potential workaround.`\n      );\n      if (!reportedIOSError) {\n        reportedIOSError = true;\n        // Throw a global exception outside of this promise chain, for the user to\n        // potentially catch.\n        setTimeout(() => {\n          throw newError;\n        }, 0);\n      }\n      return newError;\n    }\n  }\n  return error;\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/** The Platform's 'window' implementation or null if not available. */\nexport function getWindow(): Window | null {\n  // `window` is not always available, e.g. in ReactNative and WebWorkers.\n  // eslint-disable-next-line no-restricted-globals\n  return typeof window !== 'undefined' ? window : null;\n}\n\n/** The Platform's 'document' implementation or null if not available. */\nexport function getDocument(): Document | null {\n  // `document` is not always available, e.g. in ReactNative and WebWorkers.\n  // eslint-disable-next-line no-restricted-globals\n  return typeof document !== 'undefined' ? document : 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\nimport { debugAssert, fail } from './assert';\nimport { Code, FirestoreError } from './error';\nimport { logDebug, logError } from './log';\nimport { Deferred } from './promise';\nimport { ExponentialBackoff } from '../remote/backoff';\nimport { isIndexedDbTransactionError } from '../local/simple_db';\nimport { getDocument } from '../platform/dom';\n\nconst LOG_TAG = 'AsyncQueue';\n\n// Accept any return type from setTimeout().\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype TimerHandle = any;\n\n/**\n * Wellknown \"timer\" IDs used when scheduling delayed operations on the\n * AsyncQueue. These IDs can then be used from tests to check for the presence\n * of operations or to run them early.\n *\n * The string values are used when encoding these timer IDs in JSON spec tests.\n */\nexport const enum TimerId {\n  /** All can be used with runDelayedOperationsEarly() to run all timers. */\n  All = 'all',\n\n  /**\n   * The following 4 timers are used in persistent_stream.ts for the listen and\n   * write streams. The \"Idle\" timer is used to close the stream due to\n   * inactivity. The \"ConnectionBackoff\" timer is used to restart a stream once\n   * the appropriate backoff delay has elapsed.\n   */\n  ListenStreamIdle = 'listen_stream_idle',\n  ListenStreamConnectionBackoff = 'listen_stream_connection_backoff',\n  WriteStreamIdle = 'write_stream_idle',\n  WriteStreamConnectionBackoff = 'write_stream_connection_backoff',\n\n  /**\n   * A timer used in online_state_tracker.ts to transition from\n   * OnlineState.Unknown to Offline after a set timeout, rather than waiting\n   * indefinitely for success or failure.\n   */\n  OnlineStateTimeout = 'online_state_timeout',\n\n  /**\n   * A timer used to update the client metadata in IndexedDb, which is used\n   * to determine the primary leaseholder.\n   */\n  ClientMetadataRefresh = 'client_metadata_refresh',\n\n  /** A timer used to periodically attempt LRU Garbage collection */\n  LruGarbageCollection = 'lru_garbage_collection',\n\n  /**\n   * A timer used to retry transactions. Since there can be multiple concurrent\n   * transactions, multiple of these may be in the queue at a given time.\n   */\n  TransactionRetry = 'transaction_retry',\n\n  /**\n   * A timer used to retry operations scheduled via retryable AsyncQueue\n   * operations.\n   */\n  AsyncQueueRetry = 'async_queue_retry'\n}\n\n/**\n * Represents an operation scheduled to be run in the future on an AsyncQueue.\n *\n * It is created via DelayedOperation.createAndSchedule().\n *\n * Supports cancellation (via cancel()) and early execution (via skipDelay()).\n *\n * Note: We implement `PromiseLike` instead of `Promise`, as the `Promise` type\n * in newer versions of TypeScript defines `finally`, which is not available in\n * IE.\n */\nexport class DelayedOperation<T extends unknown> implements PromiseLike<T> {\n  // handle for use with clearTimeout(), or null if the operation has been\n  // executed or canceled already.\n  private timerHandle: TimerHandle | null;\n\n  private readonly deferred = new Deferred<T>();\n\n  private constructor(\n    private readonly asyncQueue: AsyncQueue,\n    readonly timerId: TimerId,\n    readonly targetTimeMs: number,\n    private readonly op: () => Promise<T>,\n    private readonly removalCallback: (op: DelayedOperation<T>) => void\n  ) {\n    // It's normal for the deferred promise to be canceled (due to cancellation)\n    // and so we attach a dummy catch callback to avoid\n    // 'UnhandledPromiseRejectionWarning' log spam.\n    this.deferred.promise.catch(err => {});\n  }\n\n  /**\n   * Creates and returns a DelayedOperation that has been scheduled to be\n   * executed on the provided asyncQueue after the provided delayMs.\n   *\n   * @param asyncQueue The queue to schedule the operation on.\n   * @param id A Timer ID identifying the type of operation this is.\n   * @param delayMs The delay (ms) before the operation should be scheduled.\n   * @param op The operation to run.\n   * @param removalCallback A callback to be called synchronously once the\n   *   operation is executed or canceled, notifying the AsyncQueue to remove it\n   *   from its delayedOperations list.\n   *   PORTING NOTE: This exists to prevent making removeDelayedOperation() and\n   *   the DelayedOperation class public.\n   */\n  static createAndSchedule<R extends unknown>(\n    asyncQueue: AsyncQueue,\n    timerId: TimerId,\n    delayMs: number,\n    op: () => Promise<R>,\n    removalCallback: (op: DelayedOperation<R>) => void\n  ): DelayedOperation<R> {\n    const targetTime = Date.now() + delayMs;\n    const delayedOp = new DelayedOperation(\n      asyncQueue,\n      timerId,\n      targetTime,\n      op,\n      removalCallback\n    );\n    delayedOp.start(delayMs);\n    return delayedOp;\n  }\n\n  /**\n   * Starts the timer. This is called immediately after construction by\n   * createAndSchedule().\n   */\n  private start(delayMs: number): void {\n    this.timerHandle = setTimeout(() => this.handleDelayElapsed(), delayMs);\n  }\n\n  /**\n   * Queues the operation to run immediately (if it hasn't already been run or\n   * canceled).\n   */\n  skipDelay(): void {\n    return this.handleDelayElapsed();\n  }\n\n  /**\n   * Cancels the operation if it hasn't already been executed or canceled. The\n   * promise will be rejected.\n   *\n   * As long as the operation has not yet been run, calling cancel() provides a\n   * guarantee that the operation will not be run.\n   */\n  cancel(reason?: string): void {\n    if (this.timerHandle !== null) {\n      this.clearTimeout();\n      this.deferred.reject(\n        new FirestoreError(\n          Code.CANCELLED,\n          'Operation cancelled' + (reason ? ': ' + reason : '')\n        )\n      );\n    }\n  }\n\n  then = this.deferred.promise.then.bind(this.deferred.promise);\n\n  private handleDelayElapsed(): void {\n    this.asyncQueue.enqueueAndForget(() => {\n      if (this.timerHandle !== null) {\n        this.clearTimeout();\n        return this.op().then(result => {\n          return this.deferred.resolve(result);\n        });\n      } else {\n        return Promise.resolve();\n      }\n    });\n  }\n\n  private clearTimeout(): void {\n    if (this.timerHandle !== null) {\n      this.removalCallback(this);\n      clearTimeout(this.timerHandle);\n      this.timerHandle = null;\n    }\n  }\n}\n\nexport class AsyncQueue {\n  // The last promise in the queue.\n  private tail: Promise<unknown> = Promise.resolve();\n\n  // A list of retryable operations. Retryable operations are run in order and\n  // retried with backoff.\n  private retryableOps: Array<() => Promise<void>> = [];\n\n  // Is this AsyncQueue being shut down? Once it is set to true, it will not\n  // be changed again.\n  private _isShuttingDown: boolean = false;\n\n  // Operations scheduled to be queued in the future. Operations are\n  // automatically removed after they are run or canceled.\n  private delayedOperations: Array<DelayedOperation<unknown>> = [];\n\n  // visible for testing\n  failure: Error | null = null;\n\n  // Flag set while there's an outstanding AsyncQueue operation, used for\n  // assertion sanity-checks.\n  private operationInProgress = false;\n\n  // List of TimerIds to fast-forward delays for.\n  private timerIdsToSkip: TimerId[] = [];\n\n  // Backoff timer used to schedule retries for retryable operations\n  private backoff = new ExponentialBackoff(this, TimerId.AsyncQueueRetry);\n\n  // Visibility handler that triggers an immediate retry of all retryable\n  // operations. Meant to speed up recovery when we regain file system access\n  // after page comes into foreground.\n  private visibilityHandler: () => void = () => {\n    const document = getDocument();\n    if (document) {\n      logDebug(\n        LOG_TAG,\n        'Visibility state changed to  ',\n        document.visibilityState\n      );\n    }\n    this.backoff.skipBackoff();\n  };\n\n  constructor() {\n    const document = getDocument();\n    if (document && typeof document.addEventListener === 'function') {\n      document.addEventListener('visibilitychange', this.visibilityHandler);\n    }\n  }\n\n  // Is this AsyncQueue being shut down? If true, this instance will not enqueue\n  // any new operations, Promises from enqueue requests will not resolve.\n  get isShuttingDown(): boolean {\n    return this._isShuttingDown;\n  }\n\n  /**\n   * Adds a new operation to the queue without waiting for it to complete (i.e.\n   * we ignore the Promise result).\n   */\n  enqueueAndForget<T extends unknown>(op: () => Promise<T>): void {\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.enqueue(op);\n  }\n\n  /**\n   * Regardless if the queue has initialized shutdown, adds a new operation to the\n   * queue without waiting for it to complete (i.e. we ignore the Promise result).\n   */\n  enqueueAndForgetEvenAfterShutdown<T extends unknown>(\n    op: () => Promise<T>\n  ): void {\n    this.verifyNotFailed();\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.enqueueInternal(op);\n  }\n\n  /**\n   * Regardless if the queue has initialized shutdown, adds a new operation to the\n   * queue.\n   */\n  private enqueueEvenAfterShutdown<T extends unknown>(\n    op: () => Promise<T>\n  ): Promise<T> {\n    this.verifyNotFailed();\n    return this.enqueueInternal(op);\n  }\n\n  /**\n   * Adds a new operation to the queue and initialize the shut down of this queue.\n   * Returns a promise that will be resolved when the promise returned by the new\n   * operation is (with its value).\n   * Once this method is called, the only possible way to request running an operation\n   * is through `enqueueAndForgetEvenAfterShutdown`.\n   */\n  async enqueueAndInitiateShutdown(op: () => Promise<void>): Promise<void> {\n    this.verifyNotFailed();\n    if (!this._isShuttingDown) {\n      this._isShuttingDown = true;\n      const document = getDocument();\n      if (document && typeof document.removeEventListener === 'function') {\n        document.removeEventListener(\n          'visibilitychange',\n          this.visibilityHandler\n        );\n      }\n      await this.enqueueEvenAfterShutdown(op);\n    }\n  }\n\n  /**\n   * Adds a new operation to the queue. Returns a promise that will be resolved\n   * when the promise returned by the new operation is (with its value).\n   */\n  enqueue<T extends unknown>(op: () => Promise<T>): Promise<T> {\n    this.verifyNotFailed();\n    if (this._isShuttingDown) {\n      // Return a Promise which never resolves.\n      return new Promise<T>(resolve => {});\n    }\n    return this.enqueueInternal(op);\n  }\n\n  /**\n   * Enqueue a retryable operation.\n   *\n   * A retryable operation is rescheduled with backoff if it fails with a\n   * IndexedDbTransactionError (the error type used by SimpleDb). All\n   * retryable operations are executed in order and only run if all prior\n   * operations were retried successfully.\n   */\n  enqueueRetryable(op: () => Promise<void>): void {\n    this.retryableOps.push(op);\n    this.enqueueAndForget(() => this.retryNextOp());\n  }\n\n  /**\n   * Runs the next operation from the retryable queue. If the operation fails,\n   * reschedules with backoff.\n   */\n  private async retryNextOp(): Promise<void> {\n    if (this.retryableOps.length === 0) {\n      return;\n    }\n\n    try {\n      await this.retryableOps[0]();\n      this.retryableOps.shift();\n      this.backoff.reset();\n    } catch (e) {\n      if (isIndexedDbTransactionError(e)) {\n        logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);\n      } else {\n        throw e; // Failure will be handled by AsyncQueue\n      }\n    }\n\n    if (this.retryableOps.length > 0) {\n      // If there are additional operations, we re-schedule `retryNextOp()`.\n      // This is necessary to run retryable operations that failed during\n      // their initial attempt since we don't know whether they are already\n      // enqueued. If, for example, `op1`, `op2`, `op3` are enqueued and `op1`\n      // needs to  be re-run, we will run `op1`, `op1`, `op2` using the\n      // already enqueued calls to `retryNextOp()`. `op3()` will then run in the\n      // call scheduled here.\n      // Since `backoffAndRun()` cancels an existing backoff and schedules a\n      // new backoff on every call, there is only ever a single additional\n      // operation in the queue.\n      this.backoff.backoffAndRun(() => this.retryNextOp());\n    }\n  }\n\n  private enqueueInternal<T extends unknown>(op: () => Promise<T>): Promise<T> {\n    const newTail = this.tail.then(() => {\n      this.operationInProgress = true;\n      return op()\n        .catch((error: FirestoreError) => {\n          this.failure = error;\n          this.operationInProgress = false;\n          const message = getMessageOrStack(error);\n          logError('INTERNAL UNHANDLED ERROR: ', message);\n\n          // Re-throw the error so that this.tail becomes a rejected Promise and\n          // all further attempts to chain (via .then) will just short-circuit\n          // and return the rejected Promise.\n          throw error;\n        })\n        .then(result => {\n          this.operationInProgress = false;\n          return result;\n        });\n    });\n    this.tail = newTail;\n    return newTail;\n  }\n\n  /**\n   * Schedules an operation to be queued on the AsyncQueue once the specified\n   * `delayMs` has elapsed. The returned DelayedOperation can be used to cancel\n   * or fast-forward the operation prior to its running.\n   */\n  enqueueAfterDelay<T extends unknown>(\n    timerId: TimerId,\n    delayMs: number,\n    op: () => Promise<T>\n  ): DelayedOperation<T> {\n    this.verifyNotFailed();\n\n    debugAssert(\n      delayMs >= 0,\n      `Attempted to schedule an operation with a negative delay of ${delayMs}`\n    );\n\n    // Fast-forward delays for timerIds that have been overriden.\n    if (this.timerIdsToSkip.indexOf(timerId) > -1) {\n      delayMs = 0;\n    }\n\n    const delayedOp = DelayedOperation.createAndSchedule<T>(\n      this,\n      timerId,\n      delayMs,\n      op,\n      removedOp =>\n        this.removeDelayedOperation(removedOp as DelayedOperation<unknown>)\n    );\n    this.delayedOperations.push(delayedOp as DelayedOperation<unknown>);\n    return delayedOp;\n  }\n\n  private verifyNotFailed(): void {\n    if (this.failure) {\n      fail('AsyncQueue is already failed: ' + getMessageOrStack(this.failure));\n    }\n  }\n\n  /**\n   * Verifies there's an operation currently in-progress on the AsyncQueue.\n   * Unfortunately we can't verify that the running code is in the promise chain\n   * of that operation, so this isn't a foolproof check, but it should be enough\n   * to catch some bugs.\n   */\n  verifyOperationInProgress(): void {\n    debugAssert(\n      this.operationInProgress,\n      'verifyOpInProgress() called when no op in progress on this queue.'\n    );\n  }\n\n  /**\n   * Waits until all currently queued tasks are finished executing. Delayed\n   * operations are not run.\n   */\n  async drain(): Promise<void> {\n    // Operations in the queue prior to draining may have enqueued additional\n    // operations. Keep draining the queue until the tail is no longer advanced,\n    // which indicates that no more new operations were enqueued and that all\n    // operations were executed.\n    let currentTail: Promise<unknown>;\n    do {\n      currentTail = this.tail;\n      await currentTail;\n    } while (currentTail !== this.tail);\n  }\n\n  /**\n   * For Tests: Determine if a delayed operation with a particular TimerId\n   * exists.\n   */\n  containsDelayedOperation(timerId: TimerId): boolean {\n    for (const op of this.delayedOperations) {\n      if (op.timerId === timerId) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * For Tests: Runs some or all delayed operations early.\n   *\n   * @param lastTimerId Delayed operations up to and including this TimerId will\n   *  be drained. Pass TimerId.All to run all delayed operations.\n   * @returns a Promise that resolves once all operations have been run.\n   */\n  runAllDelayedOperationsUntil(lastTimerId: TimerId): Promise<void> {\n    // Note that draining may generate more delayed ops, so we do that first.\n    return this.drain().then(() => {\n      // Run ops in the same order they'd run if they ran naturally.\n      this.delayedOperations.sort((a, b) => a.targetTimeMs - b.targetTimeMs);\n\n      for (const op of this.delayedOperations) {\n        op.skipDelay();\n        if (lastTimerId !== TimerId.All && op.timerId === lastTimerId) {\n          break;\n        }\n      }\n\n      return this.drain();\n    });\n  }\n\n  /**\n   * For Tests: Skip all subsequent delays for a timer id.\n   */\n  skipDelaysForTimerId(timerId: TimerId): void {\n    this.timerIdsToSkip.push(timerId);\n  }\n\n  /** Called once a DelayedOperation is run or canceled. */\n  private removeDelayedOperation(op: DelayedOperation<unknown>): void {\n    // NOTE: indexOf / slice are O(n), but delayedOperations is expected to be small.\n    const index = this.delayedOperations.indexOf(op);\n    debugAssert(index >= 0, 'Delayed operation not found.');\n    this.delayedOperations.splice(index, 1);\n  }\n}\n\n/**\n * Returns a FirestoreError that can be surfaced to the user if the provided\n * error is an IndexedDbTransactionError. Re-throws the error otherwise.\n */\nexport function wrapInUserErrorIfRecoverable(\n  e: Error,\n  msg: string\n): FirestoreError {\n  logError(LOG_TAG, `${msg}: ${e}`);\n  if (isIndexedDbTransactionError(e)) {\n    return new FirestoreError(Code.UNAVAILABLE, `${msg}: ${e}`);\n  } else {\n    throw e;\n  }\n}\n\n/**\n * Chrome includes Error.message in Error.stack. Other browsers do not.\n * This returns expected output of message + stack when available.\n * @param error Error or FirestoreError\n */\nfunction getMessageOrStack(error: Error): string {\n  let message = error.message || '';\n  if (error.stack) {\n    if (error.stack.includes(error.message)) {\n      message = error.stack;\n    } else {\n      message = error.message + '\\n' + error.stack;\n    }\n  }\n  return message;\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 { ListenSequence } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { debugAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { getLogLevel, logDebug, LogLevel } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { ignoreIfPrimaryLeaseLoss, LocalStore } from './local_store';\nimport {\n  GarbageCollectionScheduler,\n  PersistenceTransaction\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetData } from './target_data';\nimport { isIndexedDbTransactionError } from './simple_db';\n\nconst LOG_TAG = 'LruGarbageCollector';\n\n/**\n * Persistence layers intending to use LRU Garbage collection should have reference delegates that\n * implement this interface. This interface defines the operations that the LRU garbage collector\n * needs from the persistence layer.\n */\nexport interface LruDelegate {\n  readonly garbageCollector: LruGarbageCollector;\n\n  /** Enumerates all the targets in the TargetCache. */\n  forEachTarget(\n    txn: PersistenceTransaction,\n    f: (target: TargetData) => void\n  ): PersistencePromise<void>;\n\n  getSequenceNumberCount(\n    txn: PersistenceTransaction\n  ): PersistencePromise<number>;\n\n  /**\n   * Enumerates sequence numbers for documents not associated with a target.\n   * Note that this may include duplicate sequence numbers.\n   */\n  forEachOrphanedDocumentSequenceNumber(\n    txn: PersistenceTransaction,\n    f: (sequenceNumber: ListenSequenceNumber) => void\n  ): PersistencePromise<void>;\n\n  /**\n   * Removes all targets that have a sequence number less than or equal to `upperBound`, and are not\n   * present in the `activeTargetIds` set.\n   *\n   * @return the number of targets removed.\n   */\n  removeTargets(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number>;\n\n  /**\n   * Removes all unreferenced documents from the cache that have a sequence number less than or\n   * equal to the given `upperBound`.\n   *\n   * @return the number of documents removed.\n   */\n  removeOrphanedDocuments(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber\n  ): PersistencePromise<number>;\n\n  getCacheSize(txn: PersistenceTransaction): PersistencePromise<number>;\n}\n\n/**\n * Describes a map whose keys are active target ids. We do not care about the type of the\n * values.\n */\nexport type ActiveTargets = SortedMap<TargetId, unknown>;\n\n// The type and comparator for the items contained in the SortedSet used in\n// place of a priority queue for the RollingSequenceNumberBuffer.\ntype BufferEntry = [ListenSequenceNumber, number];\nfunction bufferEntryComparator(\n  [aSequence, aIndex]: BufferEntry,\n  [bSequence, bIndex]: BufferEntry\n): number {\n  const seqCmp = primitiveComparator(aSequence, bSequence);\n  if (seqCmp === 0) {\n    // This order doesn't matter, but we can bias against churn by sorting\n    // entries created earlier as less than newer entries.\n    return primitiveComparator(aIndex, bIndex);\n  } else {\n    return seqCmp;\n  }\n}\n\n/**\n * Used to calculate the nth sequence number. Keeps a rolling buffer of the\n * lowest n values passed to `addElement`, and finally reports the largest of\n * them in `maxValue`.\n */\nclass RollingSequenceNumberBuffer {\n  private buffer: SortedSet<BufferEntry> = new SortedSet<BufferEntry>(\n    bufferEntryComparator\n  );\n\n  private previousIndex = 0;\n\n  constructor(private readonly maxElements: number) {}\n\n  private nextIndex(): number {\n    return ++this.previousIndex;\n  }\n\n  addElement(sequenceNumber: ListenSequenceNumber): void {\n    const entry: BufferEntry = [sequenceNumber, this.nextIndex()];\n    if (this.buffer.size < this.maxElements) {\n      this.buffer = this.buffer.add(entry);\n    } else {\n      const highestValue = this.buffer.last()!;\n      if (bufferEntryComparator(entry, highestValue) < 0) {\n        this.buffer = this.buffer.delete(highestValue).add(entry);\n      }\n    }\n  }\n\n  get maxValue(): ListenSequenceNumber {\n    // Guaranteed to be non-empty. If we decide we are not collecting any\n    // sequence numbers, nthSequenceNumber below short-circuits. If we have\n    // decided that we are collecting n sequence numbers, it's because n is some\n    // percentage of the existing sequence numbers. That means we should never\n    // be in a situation where we are collecting sequence numbers but don't\n    // actually have any.\n    return this.buffer.last()![0];\n  }\n}\n\n/**\n * Describes the results of a garbage collection run. `didRun` will be set to\n * `false` if collection was skipped (either it is disabled or the cache size\n * has not hit the threshold). If collection ran, the other fields will be\n * filled in with the details of the results.\n */\nexport interface LruResults {\n  readonly didRun: boolean;\n  readonly sequenceNumbersCollected: number;\n  readonly targetsRemoved: number;\n  readonly documentsRemoved: number;\n}\n\nconst GC_DID_NOT_RUN: LruResults = {\n  didRun: false,\n  sequenceNumbersCollected: 0,\n  targetsRemoved: 0,\n  documentsRemoved: 0\n};\n\nexport class LruParams {\n  static readonly COLLECTION_DISABLED = -1;\n  static readonly MINIMUM_CACHE_SIZE_BYTES = 1 * 1024 * 1024;\n  static readonly DEFAULT_CACHE_SIZE_BYTES = 40 * 1024 * 1024;\n  private static readonly DEFAULT_COLLECTION_PERCENTILE = 10;\n  private static readonly DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT = 1000;\n\n  static withCacheSize(cacheSize: number): LruParams {\n    return new LruParams(\n      cacheSize,\n      LruParams.DEFAULT_COLLECTION_PERCENTILE,\n      LruParams.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT\n    );\n  }\n\n  static readonly DEFAULT: LruParams = new LruParams(\n    LruParams.DEFAULT_CACHE_SIZE_BYTES,\n    LruParams.DEFAULT_COLLECTION_PERCENTILE,\n    LruParams.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT\n  );\n\n  static readonly DISABLED: LruParams = new LruParams(\n    LruParams.COLLECTION_DISABLED,\n    0,\n    0\n  );\n\n  constructor(\n    // When we attempt to collect, we will only do so if the cache size is greater than this\n    // threshold. Passing `COLLECTION_DISABLED` here will cause collection to always be skipped.\n    readonly cacheSizeCollectionThreshold: number,\n    // The percentage of sequence numbers that we will attempt to collect\n    readonly percentileToCollect: number,\n    // A cap on the total number of sequence numbers that will be collected. This prevents\n    // us from collecting a huge number of sequence numbers if the cache has grown very large.\n    readonly maximumSequenceNumbersToCollect: number\n  ) {}\n}\n\n/** How long we wait to try running LRU GC after SDK initialization. */\nconst INITIAL_GC_DELAY_MS = 1 * 60 * 1000;\n/** Minimum amount of time between GC checks, after the first one. */\nconst REGULAR_GC_DELAY_MS = 5 * 60 * 1000;\n\n/**\n * This class is responsible for the scheduling of LRU garbage collection. It handles checking\n * whether or not GC is enabled, as well as which delay to use before the next run.\n */\nexport class LruScheduler implements GarbageCollectionScheduler {\n  private hasRun: boolean = false;\n  private gcTask: DelayedOperation<void> | null;\n\n  constructor(\n    private readonly garbageCollector: LruGarbageCollector,\n    private readonly asyncQueue: AsyncQueue\n  ) {\n    this.gcTask = null;\n  }\n\n  start(localStore: LocalStore): void {\n    debugAssert(\n      this.gcTask === null,\n      'Cannot start an already started LruScheduler'\n    );\n    if (\n      this.garbageCollector.params.cacheSizeCollectionThreshold !==\n      LruParams.COLLECTION_DISABLED\n    ) {\n      this.scheduleGC(localStore);\n    }\n  }\n\n  stop(): void {\n    if (this.gcTask) {\n      this.gcTask.cancel();\n      this.gcTask = null;\n    }\n  }\n\n  get started(): boolean {\n    return this.gcTask !== null;\n  }\n\n  private scheduleGC(localStore: LocalStore): void {\n    debugAssert(\n      this.gcTask === null,\n      'Cannot schedule GC while a task is pending'\n    );\n    const delay = this.hasRun ? REGULAR_GC_DELAY_MS : INITIAL_GC_DELAY_MS;\n    logDebug(\n      'LruGarbageCollector',\n      `Garbage collection scheduled in ${delay}ms`\n    );\n    this.gcTask = this.asyncQueue.enqueueAfterDelay(\n      TimerId.LruGarbageCollection,\n      delay,\n      async () => {\n        this.gcTask = null;\n        this.hasRun = true;\n        try {\n          await localStore.collectGarbage(this.garbageCollector);\n        } catch (e) {\n          if (isIndexedDbTransactionError(e)) {\n            logDebug(\n              LOG_TAG,\n              'Ignoring IndexedDB error during garbage collection: ',\n              e\n            );\n          } else {\n            await ignoreIfPrimaryLeaseLoss(e);\n          }\n        }\n        await this.scheduleGC(localStore);\n      }\n    );\n  }\n}\n\n/** Implements the steps for LRU garbage collection. */\nexport class LruGarbageCollector {\n  constructor(\n    private readonly delegate: LruDelegate,\n    readonly params: LruParams\n  ) {}\n\n  /** Given a percentile of target to collect, returns the number of targets to collect. */\n  calculateTargetCount(\n    txn: PersistenceTransaction,\n    percentile: number\n  ): PersistencePromise<number> {\n    return this.delegate.getSequenceNumberCount(txn).next(targetCount => {\n      return Math.floor((percentile / 100.0) * targetCount);\n    });\n  }\n\n  /** Returns the nth sequence number, counting in order from the smallest. */\n  nthSequenceNumber(\n    txn: PersistenceTransaction,\n    n: number\n  ): PersistencePromise<ListenSequenceNumber> {\n    if (n === 0) {\n      return PersistencePromise.resolve(ListenSequence.INVALID);\n    }\n\n    const buffer = new RollingSequenceNumberBuffer(n);\n    return this.delegate\n      .forEachTarget(txn, target => buffer.addElement(target.sequenceNumber))\n      .next(() => {\n        return this.delegate.forEachOrphanedDocumentSequenceNumber(\n          txn,\n          sequenceNumber => buffer.addElement(sequenceNumber)\n        );\n      })\n      .next(() => buffer.maxValue);\n  }\n\n  /**\n   * Removes targets with a sequence number equal to or less than the given upper bound, and removes\n   * document associations with those targets.\n   */\n  removeTargets(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number> {\n    return this.delegate.removeTargets(txn, upperBound, activeTargetIds);\n  }\n\n  /**\n   * Removes documents that have a sequence number equal to or less than the upper bound and are not\n   * otherwise pinned.\n   */\n  removeOrphanedDocuments(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber\n  ): PersistencePromise<number> {\n    return this.delegate.removeOrphanedDocuments(txn, upperBound);\n  }\n\n  collect(\n    txn: PersistenceTransaction,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<LruResults> {\n    if (\n      this.params.cacheSizeCollectionThreshold === LruParams.COLLECTION_DISABLED\n    ) {\n      logDebug('LruGarbageCollector', 'Garbage collection skipped; disabled');\n      return PersistencePromise.resolve(GC_DID_NOT_RUN);\n    }\n\n    return this.getCacheSize(txn).next(cacheSize => {\n      if (cacheSize < this.params.cacheSizeCollectionThreshold) {\n        logDebug(\n          'LruGarbageCollector',\n          `Garbage collection skipped; Cache size ${cacheSize} ` +\n            `is lower than threshold ${this.params.cacheSizeCollectionThreshold}`\n        );\n        return GC_DID_NOT_RUN;\n      } else {\n        return this.runGarbageCollection(txn, activeTargetIds);\n      }\n    });\n  }\n\n  getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n    return this.delegate.getCacheSize(txn);\n  }\n\n  private runGarbageCollection(\n    txn: PersistenceTransaction,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<LruResults> {\n    let upperBoundSequenceNumber: number;\n    let sequenceNumbersToCollect: number, targetsRemoved: number;\n    // Timestamps for various pieces of the process\n    let countedTargetsTs: number,\n      foundUpperBoundTs: number,\n      removedTargetsTs: number,\n      removedDocumentsTs: number;\n    const startTs = Date.now();\n    return this.calculateTargetCount(txn, this.params.percentileToCollect)\n      .next(sequenceNumbers => {\n        // Cap at the configured max\n        if (sequenceNumbers > this.params.maximumSequenceNumbersToCollect) {\n          logDebug(\n            'LruGarbageCollector',\n            'Capping sequence numbers to collect down ' +\n              `to the maximum of ${this.params.maximumSequenceNumbersToCollect} ` +\n              `from ${sequenceNumbers}`\n          );\n          sequenceNumbersToCollect = this.params\n            .maximumSequenceNumbersToCollect;\n        } else {\n          sequenceNumbersToCollect = sequenceNumbers;\n        }\n        countedTargetsTs = Date.now();\n\n        return this.nthSequenceNumber(txn, sequenceNumbersToCollect);\n      })\n      .next(upperBound => {\n        upperBoundSequenceNumber = upperBound;\n        foundUpperBoundTs = Date.now();\n\n        return this.removeTargets(\n          txn,\n          upperBoundSequenceNumber,\n          activeTargetIds\n        );\n      })\n      .next(numTargetsRemoved => {\n        targetsRemoved = numTargetsRemoved;\n        removedTargetsTs = Date.now();\n\n        return this.removeOrphanedDocuments(txn, upperBoundSequenceNumber);\n      })\n      .next(documentsRemoved => {\n        removedDocumentsTs = Date.now();\n\n        if (getLogLevel() <= LogLevel.DEBUG) {\n          const desc =\n            'LRU Garbage Collection\\n' +\n            `\\tCounted targets in ${countedTargetsTs - startTs}ms\\n` +\n            `\\tDetermined least recently used ${sequenceNumbersToCollect} in ` +\n            `${foundUpperBoundTs - countedTargetsTs}ms\\n` +\n            `\\tRemoved ${targetsRemoved} targets in ` +\n            `${removedTargetsTs - foundUpperBoundTs}ms\\n` +\n            `\\tRemoved ${documentsRemoved} documents in ` +\n            `${removedDocumentsTs - removedTargetsTs}ms\\n` +\n            `Total Duration: ${removedDocumentsTs - startTs}ms`;\n          logDebug('LruGarbageCollector', desc);\n        }\n\n        return PersistencePromise.resolve<LruResults>({\n          didRun: true,\n          sequenceNumbersCollected: sequenceNumbersToCollect,\n          targetsRemoved,\n          documentsRemoved\n        });\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 { ResourcePath } from '../model/path';\nimport { fail, hardAssert } from '../util/assert';\n\n/**\n * Helpers for dealing with resource paths stored in IndexedDB.\n *\n * Resource paths in their canonical string form do not sort as the server\n * sorts them. Specifically the server splits paths into segments first and then\n * sorts, putting end-of-segment before any character. In a UTF-8 string\n * encoding the slash ('/') that denotes the end-of-segment naturally comes\n * after other characters so the intent here is to encode the path delimiters in\n * such a way that the resulting strings sort naturally.\n *\n * Resource paths are also used for prefix scans so it's important to\n * distinguish whole segments from any longer segments of which they might be a\n * prefix. For example, it's important to make it possible to scan documents in\n * a collection \"foo\" without encountering documents in a collection \"foobar\".\n *\n * Separate from the concerns about resource path ordering and separation,\n * On Android, SQLite imposes additional restrictions since it does not handle\n * keys with embedded NUL bytes particularly well. Rather than change the\n * implementation we keep the encoding identical to keep the ports similar.\n *\n * Taken together this means resource paths when encoded for storage in\n * IndexedDB have the following characteristics:\n *\n *   * Segment separators (\"/\") sort before everything else.\n *   * All paths have a trailing separator.\n *   * NUL bytes do not exist in the output, since IndexedDB doesn't treat them\n * well.\n *\n * Therefore resource paths are encoded into string form using the following\n * rules:\n *\n *   * '\\x01' is used as an escape character.\n *   * Path separators are encoded as \"\\x01\\x01\"\n *   * NUL bytes are encoded as \"\\x01\\x10\"\n *   * '\\x01' is encoded as \"\\x01\\x11\"\n *\n * This encoding leaves some room between path separators and the NUL byte\n * just in case we decide to support integer document ids after all.\n *\n * Note that characters treated specially by the backend ('.', '/', and '~')\n * are not treated specially here. This class assumes that any unescaping of\n * resource path strings into actual ResourcePath objects will handle these\n * characters there.\n */\nexport type EncodedResourcePath = string;\n\nconst escapeChar = '\\u0001';\nconst encodedSeparatorChar = '\\u0001';\nconst encodedNul = '\\u0010';\nconst encodedEscape = '\\u0011';\n\n/**\n * Encodes a resource path into a IndexedDb-compatible string form.\n */\nexport function encodeResourcePath(path: ResourcePath): EncodedResourcePath {\n  let result = '';\n  for (let i = 0; i < path.length; i++) {\n    if (result.length > 0) {\n      result = encodeSeparator(result);\n    }\n    result = encodeSegment(path.get(i), result);\n  }\n  return encodeSeparator(result);\n}\n\n/** Encodes a single segment of a resource path into the given result */\nfunction encodeSegment(segment: string, resultBuf: string): string {\n  let result = resultBuf;\n  const length = segment.length;\n  for (let i = 0; i < length; i++) {\n    const c = segment.charAt(i);\n    switch (c) {\n      case '\\0':\n        result += escapeChar + encodedNul;\n        break;\n      case escapeChar:\n        result += escapeChar + encodedEscape;\n        break;\n      default:\n        result += c;\n    }\n  }\n  return result;\n}\n\n/** Encodes a path separator into the given result */\nfunction encodeSeparator(result: string): string {\n  return result + escapeChar + encodedSeparatorChar;\n}\n\n/**\n * Decodes the given IndexedDb-compatible string form of a resource path into\n * a ResourcePath instance. Note that this method is not suitable for use with\n * decoding resource names from the server; those are One Platform format\n * strings.\n */\nexport function decodeResourcePath(path: EncodedResourcePath): ResourcePath {\n  // Event the empty path must encode as a path of at least length 2. A path\n  // with exactly 2 must be the empty path.\n  const length = path.length;\n  hardAssert(length >= 2, 'Invalid path ' + path);\n  if (length === 2) {\n    hardAssert(\n      path.charAt(0) === escapeChar && path.charAt(1) === encodedSeparatorChar,\n      'Non-empty path ' + path + ' had length 2'\n    );\n    return ResourcePath.emptyPath();\n  }\n\n  // Escape characters cannot exist past the second-to-last position in the\n  // source value.\n  const lastReasonableEscapeIndex = length - 2;\n\n  const segments: string[] = [];\n  let segmentBuilder = '';\n\n  for (let start = 0; start < length; ) {\n    // The last two characters of a valid encoded path must be a separator, so\n    // there must be an end to this segment.\n    const end = path.indexOf(escapeChar, start);\n    if (end < 0 || end > lastReasonableEscapeIndex) {\n      fail('Invalid encoded resource path: \"' + path + '\"');\n    }\n\n    const next = path.charAt(end + 1);\n    switch (next) {\n      case encodedSeparatorChar:\n        const currentPiece = path.substring(start, end);\n        let segment;\n        if (segmentBuilder.length === 0) {\n          // Avoid copying for the common case of a segment that excludes \\0\n          // and \\001\n          segment = currentPiece;\n        } else {\n          segmentBuilder += currentPiece;\n          segment = segmentBuilder;\n          segmentBuilder = '';\n        }\n        segments.push(segment);\n        break;\n      case encodedNul:\n        segmentBuilder += path.substring(start, end);\n        segmentBuilder += '\\0';\n        break;\n      case encodedEscape:\n        // The escape character can be used in the output to encode itself.\n        segmentBuilder += path.substring(start, end + 1);\n        break;\n      default:\n        fail('Invalid encoded resource path: \"' + path + '\"');\n    }\n\n    start = end + 2;\n  }\n\n  return new ResourcePath(segments);\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n  Document,\n  MaybeDocument,\n  NoDocument,\n  UnknownDocument\n} from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { MutationBatch } from '../model/mutation_batch';\nimport * as api from '../protos/firestore_proto_api';\nimport {\n  fromDocument,\n  fromDocumentsTarget,\n  fromMutation,\n  fromQueryTarget,\n  JsonProtoSerializer,\n  toDocument,\n  toDocumentsTarget,\n  toMutation,\n  toQueryTarget\n} from '../remote/serializer';\nimport { debugAssert, fail } from '../util/assert';\nimport { ByteString } from '../util/byte_string';\nimport { canonifyTarget, isDocumentTarget, Target } from '../core/target';\nimport {\n  DbMutationBatch,\n  DbNoDocument,\n  DbQuery,\n  DbRemoteDocument,\n  DbTarget,\n  DbTimestamp,\n  DbTimestampKey,\n  DbUnknownDocument\n} from './indexeddb_schema';\nimport { TargetData, TargetPurpose } from './target_data';\n\n/** Serializer for values stored in the LocalStore. */\nexport class LocalSerializer {\n  constructor(readonly remoteSerializer: JsonProtoSerializer) {}\n}\n\n/** Decodes a remote document from storage locally to a Document. */\nexport function fromDbRemoteDocument(\n  localSerializer: LocalSerializer,\n  remoteDoc: DbRemoteDocument\n): MaybeDocument {\n  if (remoteDoc.document) {\n    return fromDocument(\n      localSerializer.remoteSerializer,\n      remoteDoc.document,\n      !!remoteDoc.hasCommittedMutations\n    );\n  } else if (remoteDoc.noDocument) {\n    const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);\n    const version = fromDbTimestamp(remoteDoc.noDocument.readTime);\n    return new NoDocument(key, version, {\n      hasCommittedMutations: !!remoteDoc.hasCommittedMutations\n    });\n  } else if (remoteDoc.unknownDocument) {\n    const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);\n    const version = fromDbTimestamp(remoteDoc.unknownDocument.version);\n    return new UnknownDocument(key, version);\n  } else {\n    return fail('Unexpected DbRemoteDocument');\n  }\n}\n\n/** Encodes a document for storage locally. */\nexport function toDbRemoteDocument(\n  localSerializer: LocalSerializer,\n  maybeDoc: MaybeDocument,\n  readTime: SnapshotVersion\n): DbRemoteDocument {\n  const dbReadTime = toDbTimestampKey(readTime);\n  const parentPath = maybeDoc.key.path.popLast().toArray();\n  if (maybeDoc instanceof Document) {\n    const doc = toDocument(localSerializer.remoteSerializer, maybeDoc);\n    const hasCommittedMutations = maybeDoc.hasCommittedMutations;\n    return new DbRemoteDocument(\n      /* unknownDocument= */ null,\n      /* noDocument= */ null,\n      doc,\n      hasCommittedMutations,\n      dbReadTime,\n      parentPath\n    );\n  } else if (maybeDoc instanceof NoDocument) {\n    const path = maybeDoc.key.path.toArray();\n    const readTime = toDbTimestamp(maybeDoc.version);\n    const hasCommittedMutations = maybeDoc.hasCommittedMutations;\n    return new DbRemoteDocument(\n      /* unknownDocument= */ null,\n      new DbNoDocument(path, readTime),\n      /* document= */ null,\n      hasCommittedMutations,\n      dbReadTime,\n      parentPath\n    );\n  } else if (maybeDoc instanceof UnknownDocument) {\n    const path = maybeDoc.key.path.toArray();\n    const readTime = toDbTimestamp(maybeDoc.version);\n    return new DbRemoteDocument(\n      new DbUnknownDocument(path, readTime),\n      /* noDocument= */ null,\n      /* document= */ null,\n      /* hasCommittedMutations= */ true,\n      dbReadTime,\n      parentPath\n    );\n  } else {\n    return fail('Unexpected MaybeDocument');\n  }\n}\n\nexport function toDbTimestampKey(\n  snapshotVersion: SnapshotVersion\n): DbTimestampKey {\n  const timestamp = snapshotVersion.toTimestamp();\n  return [timestamp.seconds, timestamp.nanoseconds];\n}\n\nexport function fromDbTimestampKey(\n  dbTimestampKey: DbTimestampKey\n): SnapshotVersion {\n  const timestamp = new Timestamp(dbTimestampKey[0], dbTimestampKey[1]);\n  return SnapshotVersion.fromTimestamp(timestamp);\n}\n\nfunction toDbTimestamp(snapshotVersion: SnapshotVersion): DbTimestamp {\n  const timestamp = snapshotVersion.toTimestamp();\n  return new DbTimestamp(timestamp.seconds, timestamp.nanoseconds);\n}\n\nfunction fromDbTimestamp(dbTimestamp: DbTimestamp): SnapshotVersion {\n  const timestamp = new Timestamp(dbTimestamp.seconds, dbTimestamp.nanoseconds);\n  return SnapshotVersion.fromTimestamp(timestamp);\n}\n\n/** Encodes a batch of mutations into a DbMutationBatch for local storage. */\nexport function toDbMutationBatch(\n  localSerializer: LocalSerializer,\n  userId: string,\n  batch: MutationBatch\n): DbMutationBatch {\n  const serializedBaseMutations = batch.baseMutations.map(m =>\n    toMutation(localSerializer.remoteSerializer, m)\n  );\n  const serializedMutations = batch.mutations.map(m =>\n    toMutation(localSerializer.remoteSerializer, m)\n  );\n  return new DbMutationBatch(\n    userId,\n    batch.batchId,\n    batch.localWriteTime.toMillis(),\n    serializedBaseMutations,\n    serializedMutations\n  );\n}\n\n/** Decodes a DbMutationBatch into a MutationBatch */\nexport function fromDbMutationBatch(\n  localSerializer: LocalSerializer,\n  dbBatch: DbMutationBatch\n): MutationBatch {\n  const baseMutations = (dbBatch.baseMutations || []).map(m =>\n    fromMutation(localSerializer.remoteSerializer, m)\n  );\n  const mutations = dbBatch.mutations.map(m =>\n    fromMutation(localSerializer.remoteSerializer, m)\n  );\n  const timestamp = Timestamp.fromMillis(dbBatch.localWriteTimeMs);\n  return new MutationBatch(\n    dbBatch.batchId,\n    timestamp,\n    baseMutations,\n    mutations\n  );\n}\n\n/** Decodes a DbTarget into TargetData */\nexport function fromDbTarget(dbTarget: DbTarget): TargetData {\n  const version = fromDbTimestamp(dbTarget.readTime);\n  const lastLimboFreeSnapshotVersion =\n    dbTarget.lastLimboFreeSnapshotVersion !== undefined\n      ? fromDbTimestamp(dbTarget.lastLimboFreeSnapshotVersion)\n      : SnapshotVersion.min();\n\n  let target: Target;\n  if (isDocumentQuery(dbTarget.query)) {\n    target = fromDocumentsTarget(dbTarget.query);\n  } else {\n    target = fromQueryTarget(dbTarget.query);\n  }\n  return new TargetData(\n    target,\n    dbTarget.targetId,\n    TargetPurpose.Listen,\n    dbTarget.lastListenSequenceNumber,\n    version,\n    lastLimboFreeSnapshotVersion,\n    ByteString.fromBase64String(dbTarget.resumeToken)\n  );\n}\n\n/** Encodes TargetData into a DbTarget for storage locally. */\nexport function toDbTarget(\n  localSerializer: LocalSerializer,\n  targetData: TargetData\n): DbTarget {\n  debugAssert(\n    TargetPurpose.Listen === targetData.purpose,\n    'Only queries with purpose ' +\n      TargetPurpose.Listen +\n      ' may be stored, got ' +\n      targetData.purpose\n  );\n  const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);\n  const dbLastLimboFreeTimestamp = toDbTimestamp(\n    targetData.lastLimboFreeSnapshotVersion\n  );\n  let queryProto: DbQuery;\n  if (isDocumentTarget(targetData.target)) {\n    queryProto = toDocumentsTarget(\n      localSerializer.remoteSerializer,\n      targetData.target\n    );\n  } else {\n    queryProto = toQueryTarget(\n      localSerializer.remoteSerializer,\n      targetData.target\n    );\n  }\n\n  // We can't store the resumeToken as a ByteString in IndexedDb, so we\n  // convert it to a base64 string for storage.\n  const resumeToken = targetData.resumeToken.toBase64();\n\n  // lastListenSequenceNumber is always 0 until we do real GC.\n  return new DbTarget(\n    targetData.targetId,\n    canonifyTarget(targetData.target),\n    dbTimestamp,\n    resumeToken,\n    targetData.sequenceNumber,\n    dbLastLimboFreeTimestamp,\n    queryProto\n  );\n}\n\n/**\n * A helper function for figuring out what kind of query has been stored.\n */\nfunction isDocumentQuery(dbQuery: DbQuery): dbQuery is api.DocumentsTarget {\n  return (dbQuery as api.DocumentsTarget).documents !== undefined;\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 { Timestamp } from '../api/timestamp';\nimport { User } from '../auth/user';\nimport { isCollectionGroupQuery, isDocumentQuery, Query } from '../core/query';\nimport { BatchId } from '../core/types';\nimport { DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { BATCHID_UNKNOWN, MutationBatch } from '../model/mutation_batch';\nimport { ResourcePath } from '../model/path';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { decodeResourcePath } from './encoded_resource_path';\nimport { IndexManager } from './index_manager';\nimport {\n  IndexedDbPersistence,\n  IndexedDbTransaction\n} from './indexeddb_persistence';\nimport {\n  DbDocumentMutation,\n  DbDocumentMutationKey,\n  DbMutationBatch,\n  DbMutationBatchKey,\n  DbMutationQueue,\n  DbMutationQueueKey\n} from './indexeddb_schema';\nimport {\n  fromDbMutationBatch,\n  LocalSerializer,\n  toDbMutationBatch\n} from './local_serializer';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistenceTransaction, ReferenceDelegate } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbStore, SimpleDbTransaction } from './simple_db';\n\n/** A mutation queue for a specific user, backed by IndexedDB. */\nexport class IndexedDbMutationQueue implements MutationQueue {\n  /**\n   * Caches the document keys for pending mutation batches. If the mutation\n   * has been removed from IndexedDb, the cached value may continue to\n   * be used to retrieve the batch's document keys. To remove a cached value\n   * locally, `removeCachedMutationKeys()` should be invoked either directly\n   * or through `removeMutationBatches()`.\n   *\n   * With multi-tab, when the primary client acknowledges or rejects a mutation,\n   * this cache is used by secondary clients to invalidate the local\n   * view of the documents that were previously affected by the mutation.\n   */\n  // PORTING NOTE: Multi-tab only.\n  private documentKeysByBatchId = {} as { [batchId: number]: DocumentKeySet };\n\n  constructor(\n    /**\n     * The normalized userId (e.g. null UID => \"\" userId) used to store /\n     * retrieve mutations.\n     */\n    private userId: string,\n    private readonly serializer: LocalSerializer,\n    private readonly indexManager: IndexManager,\n    private readonly referenceDelegate: ReferenceDelegate\n  ) {}\n\n  /**\n   * Creates a new mutation queue for the given user.\n   * @param user The user for which to create a mutation queue.\n   * @param serializer The serializer to use when persisting to IndexedDb.\n   */\n  static forUser(\n    user: User,\n    serializer: LocalSerializer,\n    indexManager: IndexManager,\n    referenceDelegate: ReferenceDelegate\n  ): IndexedDbMutationQueue {\n    // TODO(mcg): Figure out what constraints there are on userIDs\n    // In particular, are there any reserved characters? are empty ids allowed?\n    // For the moment store these together in the same mutations table assuming\n    // that empty userIDs aren't allowed.\n    hardAssert(user.uid !== '', 'UserID must not be an empty string.');\n    const userId = user.isAuthenticated() ? user.uid! : '';\n    return new IndexedDbMutationQueue(\n      userId,\n      serializer,\n      indexManager,\n      referenceDelegate\n    );\n  }\n\n  checkEmpty(transaction: PersistenceTransaction): PersistencePromise<boolean> {\n    let empty = true;\n    const range = IDBKeyRange.bound(\n      [this.userId, Number.NEGATIVE_INFINITY],\n      [this.userId, Number.POSITIVE_INFINITY]\n    );\n    return mutationsStore(transaction)\n      .iterate(\n        { index: DbMutationBatch.userMutationsIndex, range },\n        (key, value, control) => {\n          empty = false;\n          control.done();\n        }\n      )\n      .next(() => empty);\n  }\n\n  addMutationBatch(\n    transaction: PersistenceTransaction,\n    localWriteTime: Timestamp,\n    baseMutations: Mutation[],\n    mutations: Mutation[]\n  ): PersistencePromise<MutationBatch> {\n    const documentStore = documentMutationsStore(transaction);\n    const mutationStore = mutationsStore(transaction);\n\n    // The IndexedDb implementation in Chrome (and Firefox) does not handle\n    // compound indices that include auto-generated keys correctly. To ensure\n    // that the index entry is added correctly in all browsers, we perform two\n    // writes: The first write is used to retrieve the next auto-generated Batch\n    // ID, and the second write populates the index and stores the actual\n    // mutation batch.\n    // See: https://bugs.chromium.org/p/chromium/issues/detail?id=701972\n\n    // We write an empty object to obtain key\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return mutationStore.add({} as any).next(batchId => {\n      hardAssert(\n        typeof batchId === 'number',\n        'Auto-generated key is not a number'\n      );\n\n      const batch = new MutationBatch(\n        batchId,\n        localWriteTime,\n        baseMutations,\n        mutations\n      );\n      const dbBatch = toDbMutationBatch(this.serializer, this.userId, batch);\n\n      const promises: Array<PersistencePromise<void>> = [];\n      let collectionParents = new SortedSet<ResourcePath>((l, r) =>\n        primitiveComparator(l.canonicalString(), r.canonicalString())\n      );\n      for (const mutation of mutations) {\n        const indexKey = DbDocumentMutation.key(\n          this.userId,\n          mutation.key.path,\n          batchId\n        );\n        collectionParents = collectionParents.add(mutation.key.path.popLast());\n        promises.push(mutationStore.put(dbBatch));\n        promises.push(\n          documentStore.put(indexKey, DbDocumentMutation.PLACEHOLDER)\n        );\n      }\n\n      collectionParents.forEach(parent => {\n        promises.push(\n          this.indexManager.addToCollectionParentIndex(transaction, parent)\n        );\n      });\n\n      transaction.addOnCommittedListener(() => {\n        this.documentKeysByBatchId[batchId] = batch.keys();\n      });\n\n      return PersistencePromise.waitFor(promises).next(() => batch);\n    });\n  }\n\n  lookupMutationBatch(\n    transaction: PersistenceTransaction,\n    batchId: BatchId\n  ): PersistencePromise<MutationBatch | null> {\n    return mutationsStore(transaction)\n      .get(batchId)\n      .next(dbBatch => {\n        if (dbBatch) {\n          hardAssert(\n            dbBatch.userId === this.userId,\n            `Unexpected user '${dbBatch.userId}' for mutation batch ${batchId}`\n          );\n          return fromDbMutationBatch(this.serializer, dbBatch);\n        }\n        return null;\n      });\n  }\n\n  /**\n   * Returns the document keys for the mutation batch with the given batchId.\n   * For primary clients, this method returns `null` after\n   * `removeMutationBatches()` has been called. Secondary clients return a\n   * cached result until `removeCachedMutationKeys()` is invoked.\n   */\n  // PORTING NOTE: Multi-tab only.\n  lookupMutationKeys(\n    transaction: PersistenceTransaction,\n    batchId: BatchId\n  ): PersistencePromise<DocumentKeySet | null> {\n    if (this.documentKeysByBatchId[batchId]) {\n      return PersistencePromise.resolve<DocumentKeySet | null>(\n        this.documentKeysByBatchId[batchId]\n      );\n    } else {\n      return this.lookupMutationBatch(transaction, batchId).next(batch => {\n        if (batch) {\n          const keys = batch.keys();\n          this.documentKeysByBatchId[batchId] = keys;\n          return keys;\n        } else {\n          return null;\n        }\n      });\n    }\n  }\n\n  getNextMutationBatchAfterBatchId(\n    transaction: PersistenceTransaction,\n    batchId: BatchId\n  ): PersistencePromise<MutationBatch | null> {\n    const nextBatchId = batchId + 1;\n\n    const range = IDBKeyRange.lowerBound([this.userId, nextBatchId]);\n    let foundBatch: MutationBatch | null = null;\n    return mutationsStore(transaction)\n      .iterate(\n        { index: DbMutationBatch.userMutationsIndex, range },\n        (key, dbBatch, control) => {\n          if (dbBatch.userId === this.userId) {\n            hardAssert(\n              dbBatch.batchId >= nextBatchId,\n              'Should have found mutation after ' + nextBatchId\n            );\n            foundBatch = fromDbMutationBatch(this.serializer, dbBatch);\n          }\n          control.done();\n        }\n      )\n      .next(() => foundBatch);\n  }\n\n  getHighestUnacknowledgedBatchId(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<BatchId> {\n    const range = IDBKeyRange.upperBound([\n      this.userId,\n      Number.POSITIVE_INFINITY\n    ]);\n\n    let batchId = BATCHID_UNKNOWN;\n    return mutationsStore(transaction)\n      .iterate(\n        { index: DbMutationBatch.userMutationsIndex, range, reverse: true },\n        (key, dbBatch, control) => {\n          batchId = dbBatch.batchId;\n          control.done();\n        }\n      )\n      .next(() => batchId);\n  }\n\n  getAllMutationBatches(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<MutationBatch[]> {\n    const range = IDBKeyRange.bound(\n      [this.userId, BATCHID_UNKNOWN],\n      [this.userId, Number.POSITIVE_INFINITY]\n    );\n    return mutationsStore(transaction)\n      .loadAll(DbMutationBatch.userMutationsIndex, range)\n      .next(dbBatches =>\n        dbBatches.map(dbBatch => fromDbMutationBatch(this.serializer, dbBatch))\n      );\n  }\n\n  getAllMutationBatchesAffectingDocumentKey(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MutationBatch[]> {\n    // Scan the document-mutation index starting with a prefix starting with\n    // the given documentKey.\n    const indexPrefix = DbDocumentMutation.prefixForPath(\n      this.userId,\n      documentKey.path\n    );\n    const indexStart = IDBKeyRange.lowerBound(indexPrefix);\n\n    const results: MutationBatch[] = [];\n    return documentMutationsStore(transaction)\n      .iterate({ range: indexStart }, (indexKey, _, control) => {\n        const [userID, encodedPath, batchId] = indexKey;\n\n        // Only consider rows matching exactly the specific key of\n        // interest. Note that because we order by path first, and we\n        // order terminators before path separators, we'll encounter all\n        // the index rows for documentKey contiguously. In particular, all\n        // the rows for documentKey will occur before any rows for\n        // documents nested in a subcollection beneath documentKey so we\n        // can stop as soon as we hit any such row.\n        const path = decodeResourcePath(encodedPath);\n        if (userID !== this.userId || !documentKey.path.isEqual(path)) {\n          control.done();\n          return;\n        }\n        // Look up the mutation batch in the store.\n        return mutationsStore(transaction)\n          .get(batchId)\n          .next(mutation => {\n            if (!mutation) {\n              throw fail(\n                'Dangling document-mutation reference found: ' +\n                  indexKey +\n                  ' which points to ' +\n                  batchId\n              );\n            }\n            hardAssert(\n              mutation.userId === this.userId,\n              `Unexpected user '${mutation.userId}' for mutation batch ${batchId}`\n            );\n            results.push(fromDbMutationBatch(this.serializer, mutation));\n          });\n      })\n      .next(() => results);\n  }\n\n  getAllMutationBatchesAffectingDocumentKeys(\n    transaction: PersistenceTransaction,\n    documentKeys: SortedMap<DocumentKey, unknown>\n  ): PersistencePromise<MutationBatch[]> {\n    let uniqueBatchIDs = new SortedSet<BatchId>(primitiveComparator);\n\n    const promises: Array<PersistencePromise<void>> = [];\n    documentKeys.forEach(documentKey => {\n      const indexStart = DbDocumentMutation.prefixForPath(\n        this.userId,\n        documentKey.path\n      );\n      const range = IDBKeyRange.lowerBound(indexStart);\n\n      const promise = documentMutationsStore(transaction).iterate(\n        { range },\n        (indexKey, _, control) => {\n          const [userID, encodedPath, batchID] = indexKey;\n\n          // Only consider rows matching exactly the specific key of\n          // interest. Note that because we order by path first, and we\n          // order terminators before path separators, we'll encounter all\n          // the index rows for documentKey contiguously. In particular, all\n          // the rows for documentKey will occur before any rows for\n          // documents nested in a subcollection beneath documentKey so we\n          // can stop as soon as we hit any such row.\n          const path = decodeResourcePath(encodedPath);\n          if (userID !== this.userId || !documentKey.path.isEqual(path)) {\n            control.done();\n            return;\n          }\n\n          uniqueBatchIDs = uniqueBatchIDs.add(batchID);\n        }\n      );\n\n      promises.push(promise);\n    });\n\n    return PersistencePromise.waitFor(promises).next(() =>\n      this.lookupMutationBatches(transaction, uniqueBatchIDs)\n    );\n  }\n\n  getAllMutationBatchesAffectingQuery(\n    transaction: PersistenceTransaction,\n    query: Query\n  ): PersistencePromise<MutationBatch[]> {\n    debugAssert(\n      !isDocumentQuery(query),\n      \"Document queries shouldn't go down this path\"\n    );\n    debugAssert(\n      !isCollectionGroupQuery(query),\n      'CollectionGroup queries should be handled in LocalDocumentsView'\n    );\n\n    const queryPath = query.path;\n    const immediateChildrenLength = queryPath.length + 1;\n\n    // TODO(mcg): Actually implement a single-collection query\n    //\n    // This is actually executing an ancestor query, traversing the whole\n    // subtree below the collection which can be horrifically inefficient for\n    // some structures. The right way to solve this is to implement the full\n    // value index, but that's not in the cards in the near future so this is\n    // the best we can do for the moment.\n    //\n    // Since we don't yet index the actual properties in the mutations, our\n    // current approach is to just return all mutation batches that affect\n    // documents in the collection being queried.\n    const indexPrefix = DbDocumentMutation.prefixForPath(\n      this.userId,\n      queryPath\n    );\n    const indexStart = IDBKeyRange.lowerBound(indexPrefix);\n\n    // Collect up unique batchIDs encountered during a scan of the index. Use a\n    // SortedSet to accumulate batch IDs so they can be traversed in order in a\n    // scan of the main table.\n    let uniqueBatchIDs = new SortedSet<BatchId>(primitiveComparator);\n    return documentMutationsStore(transaction)\n      .iterate({ range: indexStart }, (indexKey, _, control) => {\n        const [userID, encodedPath, batchID] = indexKey;\n        const path = decodeResourcePath(encodedPath);\n        if (userID !== this.userId || !queryPath.isPrefixOf(path)) {\n          control.done();\n          return;\n        }\n        // Rows with document keys more than one segment longer than the\n        // query path can't be matches. For example, a query on 'rooms'\n        // can't match the document /rooms/abc/messages/xyx.\n        // TODO(mcg): we'll need a different scanner when we implement\n        // ancestor queries.\n        if (path.length !== immediateChildrenLength) {\n          return;\n        }\n        uniqueBatchIDs = uniqueBatchIDs.add(batchID);\n      })\n      .next(() => this.lookupMutationBatches(transaction, uniqueBatchIDs));\n  }\n\n  private lookupMutationBatches(\n    transaction: PersistenceTransaction,\n    batchIDs: SortedSet<BatchId>\n  ): PersistencePromise<MutationBatch[]> {\n    const results: MutationBatch[] = [];\n    const promises: Array<PersistencePromise<void>> = [];\n    // TODO(rockwood): Implement this using iterate.\n    batchIDs.forEach(batchId => {\n      promises.push(\n        mutationsStore(transaction)\n          .get(batchId)\n          .next(mutation => {\n            if (mutation === null) {\n              throw fail(\n                'Dangling document-mutation reference found, ' +\n                  'which points to ' +\n                  batchId\n              );\n            }\n            hardAssert(\n              mutation.userId === this.userId,\n              `Unexpected user '${mutation.userId}' for mutation batch ${batchId}`\n            );\n            results.push(fromDbMutationBatch(this.serializer, mutation));\n          })\n      );\n    });\n    return PersistencePromise.waitFor(promises).next(() => results);\n  }\n\n  removeMutationBatch(\n    transaction: PersistenceTransaction,\n    batch: MutationBatch\n  ): PersistencePromise<void> {\n    return removeMutationBatch(\n      (transaction as IndexedDbTransaction).simpleDbTransaction,\n      this.userId,\n      batch\n    ).next(removedDocuments => {\n      transaction.addOnCommittedListener(() => {\n        this.removeCachedMutationKeys(batch.batchId);\n      });\n      return PersistencePromise.forEach(\n        removedDocuments,\n        (key: DocumentKey) => {\n          return this.referenceDelegate.markPotentiallyOrphaned(\n            transaction,\n            key\n          );\n        }\n      );\n    });\n  }\n\n  /**\n   * Clears the cached keys for a mutation batch. This method should be\n   * called by secondary clients after they process mutation updates.\n   *\n   * Note that this method does not have to be called from primary clients as\n   * the corresponding cache entries are cleared when an acknowledged or\n   * rejected batch is removed from the mutation queue.\n   */\n  // PORTING NOTE: Multi-tab only\n  removeCachedMutationKeys(batchId: BatchId): void {\n    delete this.documentKeysByBatchId[batchId];\n  }\n\n  performConsistencyCheck(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    return this.checkEmpty(txn).next(empty => {\n      if (!empty) {\n        return PersistencePromise.resolve();\n      }\n\n      // Verify that there are no entries in the documentMutations index if\n      // the queue is empty.\n      const startRange = IDBKeyRange.lowerBound(\n        DbDocumentMutation.prefixForUser(this.userId)\n      );\n      const danglingMutationReferences: ResourcePath[] = [];\n      return documentMutationsStore(txn)\n        .iterate({ range: startRange }, (key, _, control) => {\n          const userID = key[0];\n          if (userID !== this.userId) {\n            control.done();\n            return;\n          } else {\n            const path = decodeResourcePath(key[1]);\n            danglingMutationReferences.push(path);\n          }\n        })\n        .next(() => {\n          hardAssert(\n            danglingMutationReferences.length === 0,\n            'Document leak -- detected dangling mutation references when queue is empty. ' +\n              'Dangling keys: ' +\n              danglingMutationReferences.map(p => p.canonicalString())\n          );\n        });\n    });\n  }\n\n  containsKey(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    return mutationQueueContainsKey(txn, this.userId, key);\n  }\n\n  // PORTING NOTE: Multi-tab only (state is held in memory in other clients).\n  /** Returns the mutation queue's metadata from IndexedDb. */\n  private getMutationQueueMetadata(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<DbMutationQueue> {\n    return mutationQueuesStore(transaction)\n      .get(this.userId)\n      .next((metadata: DbMutationQueue | null) => {\n        return (\n          metadata ||\n          new DbMutationQueue(\n            this.userId,\n            BATCHID_UNKNOWN,\n            /*lastStreamToken=*/ ''\n          )\n        );\n      });\n  }\n}\n\n/**\n * @return true if the mutation queue for the given user contains a pending\n *         mutation for the given key.\n */\nfunction mutationQueueContainsKey(\n  txn: PersistenceTransaction,\n  userId: string,\n  key: DocumentKey\n): PersistencePromise<boolean> {\n  const indexKey = DbDocumentMutation.prefixForPath(userId, key.path);\n  const encodedPath = indexKey[1];\n  const startRange = IDBKeyRange.lowerBound(indexKey);\n  let containsKey = false;\n  return documentMutationsStore(txn)\n    .iterate({ range: startRange, keysOnly: true }, (key, value, control) => {\n      const [userID, keyPath, /*batchID*/ _] = key;\n      if (userID === userId && keyPath === encodedPath) {\n        containsKey = true;\n      }\n      control.done();\n    })\n    .next(() => containsKey);\n}\n\n/** Returns true if any mutation queue contains the given document. */\nexport function mutationQueuesContainKey(\n  txn: PersistenceTransaction,\n  docKey: DocumentKey\n): PersistencePromise<boolean> {\n  let found = false;\n  return mutationQueuesStore(txn)\n    .iterateSerial(userId => {\n      return mutationQueueContainsKey(txn, userId, docKey).next(containsKey => {\n        if (containsKey) {\n          found = true;\n        }\n        return PersistencePromise.resolve(!containsKey);\n      });\n    })\n    .next(() => found);\n}\n\n/**\n * Delete a mutation batch and the associated document mutations.\n * @return A PersistencePromise of the document mutations that were removed.\n */\nexport function removeMutationBatch(\n  txn: SimpleDbTransaction,\n  userId: string,\n  batch: MutationBatch\n): PersistencePromise<DocumentKey[]> {\n  const mutationStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n    DbMutationBatch.store\n  );\n  const indexTxn = txn.store<DbDocumentMutationKey, DbDocumentMutation>(\n    DbDocumentMutation.store\n  );\n  const promises: Array<PersistencePromise<void>> = [];\n\n  const range = IDBKeyRange.only(batch.batchId);\n  let numDeleted = 0;\n  const removePromise = mutationStore.iterate(\n    { range },\n    (key, value, control) => {\n      numDeleted++;\n      return control.delete();\n    }\n  );\n  promises.push(\n    removePromise.next(() => {\n      hardAssert(\n        numDeleted === 1,\n        'Dangling document-mutation reference found: Missing batch ' +\n          batch.batchId\n      );\n    })\n  );\n  const removedDocuments: DocumentKey[] = [];\n  for (const mutation of batch.mutations) {\n    const indexKey = DbDocumentMutation.key(\n      userId,\n      mutation.key.path,\n      batch.batchId\n    );\n    promises.push(indexTxn.delete(indexKey));\n    removedDocuments.push(mutation.key);\n  }\n  return PersistencePromise.waitFor(promises).next(() => removedDocuments);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutations object store.\n */\nfunction mutationsStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbMutationBatchKey, DbMutationBatch> {\n  return IndexedDbPersistence.getStore<DbMutationBatchKey, DbMutationBatch>(\n    txn,\n    DbMutationBatch.store\n  );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutationQueues object store.\n */\nfunction documentMutationsStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbDocumentMutationKey, DbDocumentMutation> {\n  return IndexedDbPersistence.getStore<\n    DbDocumentMutationKey,\n    DbDocumentMutation\n  >(txn, DbDocumentMutation.store);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutationQueues object store.\n */\nfunction mutationQueuesStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbMutationQueueKey, DbMutationQueue> {\n  return IndexedDbPersistence.getStore<DbMutationQueueKey, DbMutationQueue>(\n    txn,\n    DbMutationQueue.store\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 { isCollectionGroupQuery, Query, queryMatches } from '../core/query';\nimport {\n  DocumentKeySet,\n  DocumentMap,\n  documentMap,\n  DocumentSizeEntries,\n  DocumentSizeEntry,\n  MaybeDocumentMap,\n  maybeDocumentMap,\n  nullableMaybeDocumentMap,\n  NullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { ResourcePath } from '../model/path';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { IndexManager } from './index_manager';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport {\n  DbRemoteDocument,\n  DbRemoteDocumentGlobal,\n  DbRemoteDocumentGlobalKey,\n  DbRemoteDocumentKey\n} from './indexeddb_schema';\nimport {\n  fromDbRemoteDocument,\n  fromDbTimestampKey,\n  LocalSerializer,\n  toDbRemoteDocument,\n  toDbTimestampKey\n} from './local_serializer';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\nimport { IterateOptions, SimpleDbStore } from './simple_db';\nimport { ObjectMap } from '../util/obj_map';\n\nexport class IndexedDbRemoteDocumentCache implements RemoteDocumentCache {\n  /**\n   * @param {LocalSerializer} serializer The document serializer.\n   * @param {IndexManager} indexManager The query indexes that need to be maintained.\n   */\n  constructor(\n    readonly serializer: LocalSerializer,\n    private readonly indexManager: IndexManager\n  ) {}\n\n  /**\n   * Adds the supplied entries to the cache.\n   *\n   * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer\n   * returned by `newChangeBuffer()` to ensure proper accounting of metadata.\n   */\n  private addEntry(\n    transaction: PersistenceTransaction,\n    key: DocumentKey,\n    doc: DbRemoteDocument\n  ): PersistencePromise<void> {\n    const documentStore = remoteDocumentsStore(transaction);\n    return documentStore.put(dbKey(key), doc);\n  }\n\n  /**\n   * Removes a document from the cache.\n   *\n   * All calls of `removeEntry`  are required to go through the RemoteDocumentChangeBuffer\n   * returned by `newChangeBuffer()` to ensure proper accounting of metadata.\n   */\n  private removeEntry(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<void> {\n    const store = remoteDocumentsStore(transaction);\n    const key = dbKey(documentKey);\n    return store.delete(key);\n  }\n\n  /**\n   * Updates the current cache size.\n   *\n   * Callers to `addEntry()` and `removeEntry()` *must* call this afterwards to update the\n   * cache's metadata.\n   */\n  private updateMetadata(\n    transaction: PersistenceTransaction,\n    sizeDelta: number\n  ): PersistencePromise<void> {\n    return this.getMetadata(transaction).next(metadata => {\n      metadata.byteSize += sizeDelta;\n      return this.setMetadata(transaction, metadata);\n    });\n  }\n\n  getEntry(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MaybeDocument | null> {\n    return remoteDocumentsStore(transaction)\n      .get(dbKey(documentKey))\n      .next(dbRemoteDoc => {\n        return this.maybeDecodeDocument(dbRemoteDoc);\n      });\n  }\n\n  /**\n   * Looks up an entry in the cache.\n   *\n   * @param documentKey The key of the entry to look up.\n   * @return The cached MaybeDocument entry and its size, or null if we have nothing cached.\n   */\n  getSizedEntry(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<DocumentSizeEntry | null> {\n    return remoteDocumentsStore(transaction)\n      .get(dbKey(documentKey))\n      .next(dbRemoteDoc => {\n        const doc = this.maybeDecodeDocument(dbRemoteDoc);\n        return doc\n          ? {\n              maybeDocument: doc,\n              size: dbDocumentSize(dbRemoteDoc!)\n            }\n          : null;\n      });\n  }\n\n  getEntries(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet\n  ): PersistencePromise<NullableMaybeDocumentMap> {\n    let results = nullableMaybeDocumentMap();\n    return this.forEachDbEntry(\n      transaction,\n      documentKeys,\n      (key, dbRemoteDoc) => {\n        const doc = this.maybeDecodeDocument(dbRemoteDoc);\n        results = results.insert(key, doc);\n      }\n    ).next(() => results);\n  }\n\n  /**\n   * Looks up several entries in the cache.\n   *\n   * @param documentKeys The set of keys entries to look up.\n   * @return A map of MaybeDocuments indexed by key (if a document cannot be\n   *     found, the key will be mapped to null) and a map of sizes indexed by\n   *     key (zero if the key cannot be found).\n   */\n  getSizedEntries(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet\n  ): PersistencePromise<DocumentSizeEntries> {\n    let results = nullableMaybeDocumentMap();\n    let sizeMap = new SortedMap<DocumentKey, number>(DocumentKey.comparator);\n    return this.forEachDbEntry(\n      transaction,\n      documentKeys,\n      (key, dbRemoteDoc) => {\n        const doc = this.maybeDecodeDocument(dbRemoteDoc);\n        if (doc) {\n          results = results.insert(key, doc);\n          sizeMap = sizeMap.insert(key, dbDocumentSize(dbRemoteDoc!));\n        } else {\n          results = results.insert(key, null);\n          sizeMap = sizeMap.insert(key, 0);\n        }\n      }\n    ).next(() => {\n      return { maybeDocuments: results, sizeMap };\n    });\n  }\n\n  private forEachDbEntry(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet,\n    callback: (key: DocumentKey, doc: DbRemoteDocument | null) => void\n  ): PersistencePromise<void> {\n    if (documentKeys.isEmpty()) {\n      return PersistencePromise.resolve();\n    }\n\n    const range = IDBKeyRange.bound(\n      documentKeys.first()!.path.toArray(),\n      documentKeys.last()!.path.toArray()\n    );\n    const keyIter = documentKeys.getIterator();\n    let nextKey: DocumentKey | null = keyIter.getNext();\n\n    return remoteDocumentsStore(transaction)\n      .iterate({ range }, (potentialKeyRaw, dbRemoteDoc, control) => {\n        const potentialKey = DocumentKey.fromSegments(potentialKeyRaw);\n\n        // Go through keys not found in cache.\n        while (nextKey && DocumentKey.comparator(nextKey!, potentialKey) < 0) {\n          callback(nextKey!, null);\n          nextKey = keyIter.getNext();\n        }\n\n        if (nextKey && nextKey!.isEqual(potentialKey)) {\n          // Key found in cache.\n          callback(nextKey!, dbRemoteDoc);\n          nextKey = keyIter.hasNext() ? keyIter.getNext() : null;\n        }\n\n        // Skip to the next key (if there is one).\n        if (nextKey) {\n          control.skip(nextKey!.path.toArray());\n        } else {\n          control.done();\n        }\n      })\n      .next(() => {\n        // The rest of the keys are not in the cache. One case where `iterate`\n        // above won't go through them is when the cache is empty.\n        while (nextKey) {\n          callback(nextKey!, null);\n          nextKey = keyIter.hasNext() ? keyIter.getNext() : null;\n        }\n      });\n  }\n\n  getDocumentsMatchingQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<DocumentMap> {\n    debugAssert(\n      !isCollectionGroupQuery(query),\n      'CollectionGroup queries should be handled in LocalDocumentsView'\n    );\n    let results = documentMap();\n\n    const immediateChildrenPathLength = query.path.length + 1;\n\n    const iterationOptions: IterateOptions = {};\n    if (sinceReadTime.isEqual(SnapshotVersion.min())) {\n      // Documents are ordered by key, so we can use a prefix scan to narrow\n      // down the documents we need to match the query against.\n      const startKey = query.path.toArray();\n      iterationOptions.range = IDBKeyRange.lowerBound(startKey);\n    } else {\n      // Execute an index-free query and filter by read time. This is safe\n      // since all document changes to queries that have a\n      // lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.\n      const collectionKey = query.path.toArray();\n      const readTimeKey = toDbTimestampKey(sinceReadTime);\n      iterationOptions.range = IDBKeyRange.lowerBound(\n        [collectionKey, readTimeKey],\n        /* open= */ true\n      );\n      iterationOptions.index = DbRemoteDocument.collectionReadTimeIndex;\n    }\n\n    return remoteDocumentsStore(transaction)\n      .iterate(iterationOptions, (key, dbRemoteDoc, control) => {\n        // The query is actually returning any path that starts with the query\n        // path prefix which may include documents in subcollections. For\n        // example, a query on 'rooms' will return rooms/abc/messages/xyx but we\n        // shouldn't match it. Fix this by discarding rows with document keys\n        // more than one segment longer than the query path.\n        if (key.length !== immediateChildrenPathLength) {\n          return;\n        }\n\n        const maybeDoc = fromDbRemoteDocument(this.serializer, dbRemoteDoc);\n        if (!query.path.isPrefixOf(maybeDoc.key.path)) {\n          control.done();\n        } else if (\n          maybeDoc instanceof Document &&\n          queryMatches(query, maybeDoc)\n        ) {\n          results = results.insert(maybeDoc.key, maybeDoc);\n        }\n      })\n      .next(() => results);\n  }\n\n  /**\n   * Returns the set of documents that have changed since the specified read\n   * time.\n   */\n  // PORTING NOTE: This is only used for multi-tab synchronization.\n  getNewDocumentChanges(\n    transaction: PersistenceTransaction,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<{\n    changedDocs: MaybeDocumentMap;\n    readTime: SnapshotVersion;\n  }> {\n    let changedDocs = maybeDocumentMap();\n\n    let lastReadTime = toDbTimestampKey(sinceReadTime);\n\n    const documentsStore = remoteDocumentsStore(transaction);\n    const range = IDBKeyRange.lowerBound(lastReadTime, true);\n    return documentsStore\n      .iterate(\n        { index: DbRemoteDocument.readTimeIndex, range },\n        (_, dbRemoteDoc) => {\n          // Unlike `getEntry()` and others, `getNewDocumentChanges()` parses\n          // the documents directly since we want to keep sentinel deletes.\n          const doc = fromDbRemoteDocument(this.serializer, dbRemoteDoc);\n          changedDocs = changedDocs.insert(doc.key, doc);\n          lastReadTime = dbRemoteDoc.readTime!;\n        }\n      )\n      .next(() => {\n        return {\n          changedDocs,\n          readTime: fromDbTimestampKey(lastReadTime)\n        };\n      });\n  }\n\n  /**\n   * Returns the read time of the most recently read document in the cache, or\n   * SnapshotVersion.min() if not available.\n   */\n  // PORTING NOTE: This is only used for multi-tab synchronization.\n  getLastReadTime(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<SnapshotVersion> {\n    const documentsStore = remoteDocumentsStore(transaction);\n\n    // If there are no existing entries, we return SnapshotVersion.min().\n    let readTime = SnapshotVersion.min();\n\n    return documentsStore\n      .iterate(\n        { index: DbRemoteDocument.readTimeIndex, reverse: true },\n        (key, dbRemoteDoc, control) => {\n          if (dbRemoteDoc.readTime) {\n            readTime = fromDbTimestampKey(dbRemoteDoc.readTime);\n          }\n          control.done();\n        }\n      )\n      .next(() => readTime);\n  }\n\n  newChangeBuffer(options?: {\n    trackRemovals: boolean;\n  }): RemoteDocumentChangeBuffer {\n    return new IndexedDbRemoteDocumentCache.RemoteDocumentChangeBuffer(\n      this,\n      !!options && options.trackRemovals\n    );\n  }\n\n  getSize(txn: PersistenceTransaction): PersistencePromise<number> {\n    return this.getMetadata(txn).next(metadata => metadata.byteSize);\n  }\n\n  private getMetadata(\n    txn: PersistenceTransaction\n  ): PersistencePromise<DbRemoteDocumentGlobal> {\n    return documentGlobalStore(txn)\n      .get(DbRemoteDocumentGlobal.key)\n      .next(metadata => {\n        hardAssert(!!metadata, 'Missing document cache metadata');\n        return metadata!;\n      });\n  }\n\n  private setMetadata(\n    txn: PersistenceTransaction,\n    metadata: DbRemoteDocumentGlobal\n  ): PersistencePromise<void> {\n    return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);\n  }\n\n  /**\n   * Decodes `remoteDoc` and returns the document (or null, if the document\n   * corresponds to the format used for sentinel deletes).\n   */\n  private maybeDecodeDocument(\n    dbRemoteDoc: DbRemoteDocument | null\n  ): MaybeDocument | null {\n    if (dbRemoteDoc) {\n      const doc = fromDbRemoteDocument(this.serializer, dbRemoteDoc);\n      if (\n        doc instanceof NoDocument &&\n        doc.version.isEqual(SnapshotVersion.min())\n      ) {\n        // The document is a sentinel removal and should only be used in the\n        // `getNewDocumentChanges()`.\n        return null;\n      }\n\n      return doc;\n    }\n    return null;\n  }\n\n  /**\n   * Handles the details of adding and updating documents in the IndexedDbRemoteDocumentCache.\n   *\n   * Unlike the MemoryRemoteDocumentChangeBuffer, the IndexedDb implementation computes the size\n   * delta for all submitted changes. This avoids having to re-read all documents from IndexedDb\n   * when we apply the changes.\n   */\n  private static RemoteDocumentChangeBuffer = class extends RemoteDocumentChangeBuffer {\n    // A map of document sizes prior to applying the changes in this buffer.\n    protected documentSizes: ObjectMap<DocumentKey, number> = new ObjectMap(\n      key => key.toString(),\n      (l, r) => l.isEqual(r)\n    );\n\n    /**\n     * @param documentCache The IndexedDbRemoteDocumentCache to apply the changes to.\n     * @param trackRemovals Whether to create sentinel deletes that can be tracked by\n     * `getNewDocumentChanges()`.\n     */\n    constructor(\n      private readonly documentCache: IndexedDbRemoteDocumentCache,\n      private readonly trackRemovals: boolean\n    ) {\n      super();\n    }\n\n    protected applyChanges(\n      transaction: PersistenceTransaction\n    ): PersistencePromise<void> {\n      const promises: Array<PersistencePromise<void>> = [];\n\n      let sizeDelta = 0;\n\n      let collectionParents = new SortedSet<ResourcePath>((l, r) =>\n        primitiveComparator(l.canonicalString(), r.canonicalString())\n      );\n\n      this.changes.forEach((key, maybeDocument) => {\n        const previousSize = this.documentSizes.get(key);\n        debugAssert(\n          previousSize !== undefined,\n          `Cannot modify a document that wasn't read (for ${key})`\n        );\n        if (maybeDocument) {\n          debugAssert(\n            !this.readTime.isEqual(SnapshotVersion.min()),\n            'Cannot add a document with a read time of zero'\n          );\n          const doc = toDbRemoteDocument(\n            this.documentCache.serializer,\n            maybeDocument,\n            this.readTime\n          );\n          collectionParents = collectionParents.add(key.path.popLast());\n\n          const size = dbDocumentSize(doc);\n          sizeDelta += size - previousSize!;\n          promises.push(this.documentCache.addEntry(transaction, key, doc));\n        } else {\n          sizeDelta -= previousSize!;\n          if (this.trackRemovals) {\n            // In order to track removals, we store a \"sentinel delete\" in the\n            // RemoteDocumentCache. This entry is represented by a NoDocument\n            // with a version of 0 and ignored by `maybeDecodeDocument()` but\n            // preserved in `getNewDocumentChanges()`.\n            const deletedDoc = toDbRemoteDocument(\n              this.documentCache.serializer,\n              new NoDocument(key, SnapshotVersion.min()),\n              this.readTime\n            );\n            promises.push(\n              this.documentCache.addEntry(transaction, key, deletedDoc)\n            );\n          } else {\n            promises.push(this.documentCache.removeEntry(transaction, key));\n          }\n        }\n      });\n\n      collectionParents.forEach(parent => {\n        promises.push(\n          this.documentCache.indexManager.addToCollectionParentIndex(\n            transaction,\n            parent\n          )\n        );\n      });\n\n      promises.push(this.documentCache.updateMetadata(transaction, sizeDelta));\n\n      return PersistencePromise.waitFor(promises);\n    }\n\n    protected getFromCache(\n      transaction: PersistenceTransaction,\n      documentKey: DocumentKey\n    ): PersistencePromise<MaybeDocument | null> {\n      // Record the size of everything we load from the cache so we can compute a delta later.\n      return this.documentCache\n        .getSizedEntry(transaction, documentKey)\n        .next(getResult => {\n          if (getResult === null) {\n            this.documentSizes.set(documentKey, 0);\n            return null;\n          } else {\n            this.documentSizes.set(documentKey, getResult.size);\n            return getResult.maybeDocument;\n          }\n        });\n    }\n\n    protected getAllFromCache(\n      transaction: PersistenceTransaction,\n      documentKeys: DocumentKeySet\n    ): PersistencePromise<NullableMaybeDocumentMap> {\n      // Record the size of everything we load from the cache so we can compute\n      // a delta later.\n      return this.documentCache\n        .getSizedEntries(transaction, documentKeys)\n        .next(({ maybeDocuments, sizeMap }) => {\n          // Note: `getAllFromCache` returns two maps instead of a single map from\n          // keys to `DocumentSizeEntry`s. This is to allow returning the\n          // `NullableMaybeDocumentMap` directly, without a conversion.\n          sizeMap.forEach((documentKey, size) => {\n            this.documentSizes.set(documentKey, size);\n          });\n          return maybeDocuments;\n        });\n    }\n  };\n}\n\nfunction documentGlobalStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbRemoteDocumentGlobalKey, DbRemoteDocumentGlobal> {\n  return IndexedDbPersistence.getStore<\n    DbRemoteDocumentGlobalKey,\n    DbRemoteDocumentGlobal\n  >(txn, DbRemoteDocumentGlobal.store);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the remoteDocuments object store.\n */\nfunction remoteDocumentsStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbRemoteDocumentKey, DbRemoteDocument> {\n  return IndexedDbPersistence.getStore<DbRemoteDocumentKey, DbRemoteDocument>(\n    txn,\n    DbRemoteDocument.store\n  );\n}\n\nfunction dbKey(docKey: DocumentKey): DbRemoteDocumentKey {\n  return docKey.path.toArray();\n}\n\n/**\n * Retrusn an approximate size for the given document.\n */\nexport function dbDocumentSize(doc: DbRemoteDocument): number {\n  let value: unknown;\n  if (doc.document) {\n    value = doc.document;\n  } else if (doc.unknownDocument) {\n    value = doc.unknownDocument;\n  } else if (doc.noDocument) {\n    value = doc.noDocument;\n  } else {\n    throw fail('Unknown remote document type');\n  }\n  return JSON.stringify(value).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 { ResourcePath } from '../model/path';\nimport { debugAssert } from '../util/assert';\nimport { SortedSet } from '../util/sorted_set';\nimport { IndexManager } from './index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\n\n/**\n * An in-memory implementation of IndexManager.\n */\nexport class MemoryIndexManager implements IndexManager {\n  private collectionParentIndex = new MemoryCollectionParentIndex();\n\n  addToCollectionParentIndex(\n    transaction: PersistenceTransaction,\n    collectionPath: ResourcePath\n  ): PersistencePromise<void> {\n    this.collectionParentIndex.add(collectionPath);\n    return PersistencePromise.resolve();\n  }\n\n  getCollectionParents(\n    transaction: PersistenceTransaction,\n    collectionId: string\n  ): PersistencePromise<ResourcePath[]> {\n    return PersistencePromise.resolve(\n      this.collectionParentIndex.getEntries(collectionId)\n    );\n  }\n}\n\n/**\n * Internal implementation of the collection-parent index exposed by MemoryIndexManager.\n * Also used for in-memory caching by IndexedDbIndexManager and initial index population\n * in indexeddb_schema.ts\n */\nexport class MemoryCollectionParentIndex {\n  private index = {} as {\n    [collectionId: string]: SortedSet<ResourcePath>;\n  };\n\n  // Returns false if the entry already existed.\n  add(collectionPath: ResourcePath): boolean {\n    debugAssert(collectionPath.length % 2 === 1, 'Expected a collection path.');\n    const collectionId = collectionPath.lastSegment();\n    const parentPath = collectionPath.popLast();\n    const existingParents =\n      this.index[collectionId] ||\n      new SortedSet<ResourcePath>(ResourcePath.comparator);\n    const added = !existingParents.has(parentPath);\n    this.index[collectionId] = existingParents.add(parentPath);\n    return added;\n  }\n\n  has(collectionPath: ResourcePath): boolean {\n    const collectionId = collectionPath.lastSegment();\n    const parentPath = collectionPath.popLast();\n    const existingParents = this.index[collectionId];\n    return existingParents && existingParents.has(parentPath);\n  }\n\n  getEntries(collectionId: string): ResourcePath[] {\n    const parentPaths =\n      this.index[collectionId] ||\n      new SortedSet<ResourcePath>(ResourcePath.comparator);\n    return parentPaths.toArray();\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 { BatchId, ListenSequenceNumber, TargetId } from '../core/types';\nimport { ResourcePath } from '../model/path';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugAssert, hardAssert } from '../util/assert';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { BATCHID_UNKNOWN } from '../model/mutation_batch';\nimport {\n  decodeResourcePath,\n  EncodedResourcePath,\n  encodeResourcePath\n} from './encoded_resource_path';\nimport { removeMutationBatch } from './indexeddb_mutation_queue';\nimport { dbDocumentSize } from './indexeddb_remote_document_cache';\nimport {\n  fromDbMutationBatch,\n  fromDbTarget,\n  LocalSerializer,\n  toDbTarget\n} from './local_serializer';\nimport { MemoryCollectionParentIndex } from './memory_index_manager';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbSchemaConverter, SimpleDbTransaction } from './simple_db';\n\n/**\n * Schema Version for the Web client:\n * 1.  Initial version including Mutation Queue, Query Cache, and Remote\n *     Document Cache\n * 2.  Used to ensure a targetGlobal object exists and add targetCount to it. No\n *     longer required because migration 3 unconditionally clears it.\n * 3.  Dropped and re-created Query Cache to deal with cache corruption related\n *     to limbo resolution. Addresses\n *     https://github.com/firebase/firebase-ios-sdk/issues/1548\n * 4.  Multi-Tab Support.\n * 5.  Removal of held write acks.\n * 6.  Create document global for tracking document cache size.\n * 7.  Ensure every cached document has a sentinel row with a sequence number.\n * 8.  Add collection-parent index for Collection Group queries.\n * 9.  Change RemoteDocumentChanges store to be keyed by readTime rather than\n *     an auto-incrementing ID. This is required for Index-Free queries.\n * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.\n */\nexport const SCHEMA_VERSION = 10;\n\n/** Performs database creation and schema upgrades. */\nexport class SchemaConverter implements SimpleDbSchemaConverter {\n  constructor(private readonly serializer: LocalSerializer) {}\n\n  /**\n   * Performs database creation and schema upgrades.\n   *\n   * Note that in production, this method is only ever used to upgrade the schema\n   * to SCHEMA_VERSION. Different values of toVersion are only used for testing\n   * and local feature development.\n   */\n  createOrUpgrade(\n    db: IDBDatabase,\n    txn: IDBTransaction,\n    fromVersion: number,\n    toVersion: number\n  ): PersistencePromise<void> {\n    hardAssert(\n      fromVersion < toVersion &&\n        fromVersion >= 0 &&\n        toVersion <= SCHEMA_VERSION,\n      `Unexpected schema upgrade from v${fromVersion} to v${toVersion}.`\n    );\n\n    const simpleDbTransaction = new SimpleDbTransaction(txn);\n\n    if (fromVersion < 1 && toVersion >= 1) {\n      createPrimaryClientStore(db);\n      createMutationQueue(db);\n      createQueryCache(db);\n      createRemoteDocumentCache(db);\n    }\n\n    // Migration 2 to populate the targetGlobal object no longer needed since\n    // migration 3 unconditionally clears it.\n\n    let p = PersistencePromise.resolve();\n    if (fromVersion < 3 && toVersion >= 3) {\n      // Brand new clients don't need to drop and recreate--only clients that\n      // potentially have corrupt data.\n      if (fromVersion !== 0) {\n        dropQueryCache(db);\n        createQueryCache(db);\n      }\n      p = p.next(() => writeEmptyTargetGlobalEntry(simpleDbTransaction));\n    }\n\n    if (fromVersion < 4 && toVersion >= 4) {\n      if (fromVersion !== 0) {\n        // Schema version 3 uses auto-generated keys to generate globally unique\n        // mutation batch IDs (this was previously ensured internally by the\n        // client). To migrate to the new schema, we have to read all mutations\n        // and write them back out. We preserve the existing batch IDs to guarantee\n        // consistency with other object stores. Any further mutation batch IDs will\n        // be auto-generated.\n        p = p.next(() =>\n          upgradeMutationBatchSchemaAndMigrateData(db, simpleDbTransaction)\n        );\n      }\n\n      p = p.next(() => {\n        createClientMetadataStore(db);\n      });\n    }\n\n    if (fromVersion < 5 && toVersion >= 5) {\n      p = p.next(() => this.removeAcknowledgedMutations(simpleDbTransaction));\n    }\n\n    if (fromVersion < 6 && toVersion >= 6) {\n      p = p.next(() => {\n        createDocumentGlobalStore(db);\n        return this.addDocumentGlobal(simpleDbTransaction);\n      });\n    }\n\n    if (fromVersion < 7 && toVersion >= 7) {\n      p = p.next(() => this.ensureSequenceNumbers(simpleDbTransaction));\n    }\n\n    if (fromVersion < 8 && toVersion >= 8) {\n      p = p.next(() =>\n        this.createCollectionParentIndex(db, simpleDbTransaction)\n      );\n    }\n\n    if (fromVersion < 9 && toVersion >= 9) {\n      p = p.next(() => {\n        // Multi-Tab used to manage its own changelog, but this has been moved\n        // to the DbRemoteDocument object store itself. Since the previous change\n        // log only contained transient data, we can drop its object store.\n        dropRemoteDocumentChangesStore(db);\n        createRemoteDocumentReadTimeIndex(txn);\n      });\n    }\n\n    if (fromVersion < 10 && toVersion >= 10) {\n      p = p.next(() => this.rewriteCanonicalIds(simpleDbTransaction));\n    }\n    return p;\n  }\n\n  private addDocumentGlobal(\n    txn: SimpleDbTransaction\n  ): PersistencePromise<void> {\n    let byteCount = 0;\n    return txn\n      .store<DbRemoteDocumentKey, DbRemoteDocument>(DbRemoteDocument.store)\n      .iterate((_, doc) => {\n        byteCount += dbDocumentSize(doc);\n      })\n      .next(() => {\n        const metadata = new DbRemoteDocumentGlobal(byteCount);\n        return txn\n          .store<DbRemoteDocumentGlobalKey, DbRemoteDocumentGlobal>(\n            DbRemoteDocumentGlobal.store\n          )\n          .put(DbRemoteDocumentGlobal.key, metadata);\n      });\n  }\n\n  private removeAcknowledgedMutations(\n    txn: SimpleDbTransaction\n  ): PersistencePromise<void> {\n    const queuesStore = txn.store<DbMutationQueueKey, DbMutationQueue>(\n      DbMutationQueue.store\n    );\n    const mutationsStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n      DbMutationBatch.store\n    );\n\n    return queuesStore.loadAll().next(queues => {\n      return PersistencePromise.forEach(queues, (queue: DbMutationQueue) => {\n        const range = IDBKeyRange.bound(\n          [queue.userId, BATCHID_UNKNOWN],\n          [queue.userId, queue.lastAcknowledgedBatchId]\n        );\n\n        return mutationsStore\n          .loadAll(DbMutationBatch.userMutationsIndex, range)\n          .next(dbBatches => {\n            return PersistencePromise.forEach(\n              dbBatches,\n              (dbBatch: DbMutationBatch) => {\n                hardAssert(\n                  dbBatch.userId === queue.userId,\n                  `Cannot process batch ${dbBatch.batchId} from unexpected user`\n                );\n                const batch = fromDbMutationBatch(this.serializer, dbBatch);\n\n                return removeMutationBatch(\n                  txn,\n                  queue.userId,\n                  batch\n                ).next(() => {});\n              }\n            );\n          });\n      });\n    });\n  }\n\n  /**\n   * Ensures that every document in the remote document cache has a corresponding sentinel row\n   * with a sequence number. Missing rows are given the most recently used sequence number.\n   */\n  private ensureSequenceNumbers(\n    txn: SimpleDbTransaction\n  ): PersistencePromise<void> {\n    const documentTargetStore = txn.store<\n      DbTargetDocumentKey,\n      DbTargetDocument\n    >(DbTargetDocument.store);\n    const documentsStore = txn.store<DbRemoteDocumentKey, DbRemoteDocument>(\n      DbRemoteDocument.store\n    );\n    const globalTargetStore = txn.store<DbTargetGlobalKey, DbTargetGlobal>(\n      DbTargetGlobal.store\n    );\n\n    return globalTargetStore.get(DbTargetGlobal.key).next(metadata => {\n      debugAssert(\n        !!metadata,\n        'Metadata should have been written during the version 3 migration'\n      );\n      const writeSentinelKey = (\n        path: ResourcePath\n      ): PersistencePromise<void> => {\n        return documentTargetStore.put(\n          new DbTargetDocument(\n            0,\n            encodeResourcePath(path),\n            metadata!.highestListenSequenceNumber!\n          )\n        );\n      };\n\n      const promises: Array<PersistencePromise<void>> = [];\n      return documentsStore\n        .iterate((key, doc) => {\n          const path = new ResourcePath(key);\n          const docSentinelKey = sentinelKey(path);\n          promises.push(\n            documentTargetStore.get(docSentinelKey).next(maybeSentinel => {\n              if (!maybeSentinel) {\n                return writeSentinelKey(path);\n              } else {\n                return PersistencePromise.resolve();\n              }\n            })\n          );\n        })\n        .next(() => PersistencePromise.waitFor(promises));\n    });\n  }\n\n  private createCollectionParentIndex(\n    db: IDBDatabase,\n    txn: SimpleDbTransaction\n  ): PersistencePromise<void> {\n    // Create the index.\n    db.createObjectStore(DbCollectionParent.store, {\n      keyPath: DbCollectionParent.keyPath\n    });\n\n    const collectionParentsStore = txn.store<\n      DbCollectionParentKey,\n      DbCollectionParent\n    >(DbCollectionParent.store);\n\n    // Helper to add an index entry iff we haven't already written it.\n    const cache = new MemoryCollectionParentIndex();\n    const addEntry = (\n      collectionPath: ResourcePath\n    ): PersistencePromise<void> | undefined => {\n      if (cache.add(collectionPath)) {\n        const collectionId = collectionPath.lastSegment();\n        const parentPath = collectionPath.popLast();\n        return collectionParentsStore.put({\n          collectionId,\n          parent: encodeResourcePath(parentPath)\n        });\n      }\n    };\n\n    // Index existing remote documents.\n    return txn\n      .store<DbRemoteDocumentKey, DbRemoteDocument>(DbRemoteDocument.store)\n      .iterate({ keysOnly: true }, (pathSegments, _) => {\n        const path = new ResourcePath(pathSegments);\n        return addEntry(path.popLast());\n      })\n      .next(() => {\n        // Index existing mutations.\n        return txn\n          .store<DbDocumentMutationKey, DbDocumentMutation>(\n            DbDocumentMutation.store\n          )\n          .iterate({ keysOnly: true }, ([userID, encodedPath, batchId], _) => {\n            const path = decodeResourcePath(encodedPath);\n            return addEntry(path.popLast());\n          });\n      });\n  }\n\n  private rewriteCanonicalIds(\n    txn: SimpleDbTransaction\n  ): PersistencePromise<void> {\n    const targetStore = txn.store<DbTargetKey, DbTarget>(DbTarget.store);\n    return targetStore.iterate((key, originalDbTarget) => {\n      const originalTargetData = fromDbTarget(originalDbTarget);\n      const updatedDbTarget = toDbTarget(this.serializer, originalTargetData);\n      return targetStore.put(updatedDbTarget);\n    });\n  }\n}\n\nfunction sentinelKey(path: ResourcePath): DbTargetDocumentKey {\n  return [0, encodeResourcePath(path)];\n}\n\n/**\n * Wrapper class to store timestamps (seconds and nanos) in IndexedDb objects.\n */\nexport class DbTimestamp {\n  constructor(public seconds: number, public nanoseconds: number) {}\n}\n\n/** A timestamp type that can be used in IndexedDb keys. */\nexport type DbTimestampKey = [/* seconds */ number, /* nanos */ number];\n\n// The key for the singleton object in the DbPrimaryClient is a single string.\nexport type DbPrimaryClientKey = typeof DbPrimaryClient.key;\n\n/**\n * A singleton object to be stored in the 'owner' store in IndexedDb.\n *\n * A given database can have a single primary tab assigned at a given time. That\n * tab must validate that it is still holding the primary lease before every\n * operation that requires locked access. The primary tab should regularly\n * write an updated timestamp to this lease to prevent other tabs from\n * \"stealing\" the primary lease\n */\nexport class DbPrimaryClient {\n  /**\n   * Name of the IndexedDb object store.\n   *\n   * Note that the name 'owner' is chosen to ensure backwards compatibility with\n   * older clients that only supported single locked access to the persistence\n   * layer.\n   */\n  static store = 'owner';\n\n  /**\n   * The key string used for the single object that exists in the\n   * DbPrimaryClient store.\n   */\n  static key = 'owner';\n\n  constructor(\n    public ownerId: string,\n    /** Whether to allow shared access from multiple tabs. */\n    public allowTabSynchronization: boolean,\n    public leaseTimestampMs: number\n  ) {}\n}\n\nfunction createPrimaryClientStore(db: IDBDatabase): void {\n  db.createObjectStore(DbPrimaryClient.store);\n}\n\n/** Object keys in the 'mutationQueues' store are userId strings. */\nexport type DbMutationQueueKey = string;\n\n/**\n * An object to be stored in the 'mutationQueues' store in IndexedDb.\n *\n * Each user gets a single queue of MutationBatches to apply to the server.\n * DbMutationQueue tracks the metadata about the queue.\n */\nexport class DbMutationQueue {\n  /** Name of the IndexedDb object store.  */\n  static store = 'mutationQueues';\n\n  /** Keys are automatically assigned via the userId property. */\n  static keyPath = 'userId';\n\n  constructor(\n    /**\n     * The normalized user ID to which this queue belongs.\n     */\n    public userId: string,\n    /**\n     * An identifier for the highest numbered batch that has been acknowledged\n     * by the server. All MutationBatches in this queue with batchIds less\n     * than or equal to this value are considered to have been acknowledged by\n     * the server.\n     *\n     * NOTE: this is deprecated and no longer used by the code.\n     */\n    public lastAcknowledgedBatchId: number,\n    /**\n     * A stream token that was previously sent by the server.\n     *\n     * See StreamingWriteRequest in datastore.proto for more details about\n     * usage.\n     *\n     * After sending this token, earlier tokens may not be used anymore so\n     * only a single stream token is retained.\n     *\n     * NOTE: this is deprecated and no longer used by the code.\n     */\n    public lastStreamToken: string\n  ) {}\n}\n\n/** The 'mutations' store  is keyed by batch ID. */\nexport type DbMutationBatchKey = BatchId;\n\n/**\n * An object to be stored in the 'mutations' store in IndexedDb.\n *\n * Represents a batch of user-level mutations intended to be sent to the server\n * in a single write. Each user-level batch gets a separate DbMutationBatch\n * with a new batchId.\n */\nexport class DbMutationBatch {\n  /** Name of the IndexedDb object store.  */\n  static store = 'mutations';\n\n  /** Keys are automatically assigned via the userId, batchId properties. */\n  static keyPath = 'batchId';\n\n  /** The index name for lookup of mutations by user. */\n  static userMutationsIndex = 'userMutationsIndex';\n\n  /** The user mutations index is keyed by [userId, batchId] pairs. */\n  static userMutationsKeyPath = ['userId', 'batchId'];\n\n  constructor(\n    /**\n     * The normalized user ID to which this batch belongs.\n     */\n    public userId: string,\n    /**\n     * An identifier for this batch, allocated using an auto-generated key.\n     */\n    public batchId: BatchId,\n    /**\n     * The local write time of the batch, stored as milliseconds since the\n     * epoch.\n     */\n    public localWriteTimeMs: number,\n    /**\n     * A list of \"mutations\" that represent a partial base state from when this\n     * write batch was initially created. During local application of the write\n     * batch, these baseMutations are applied prior to the real writes in order\n     * to override certain document fields from the remote document cache. This\n     * is necessary in the case of non-idempotent writes (e.g. `increment()`\n     * transforms) to make sure that the local view of the modified documents\n     * doesn't flicker if the remote document cache receives the result of the\n     * non-idempotent write before the write is removed from the queue.\n     *\n     * These mutations are never sent to the backend.\n     */\n    public baseMutations: api.Write[] | undefined,\n    /**\n     * A list of mutations to apply. All mutations will be applied atomically.\n     *\n     * Mutations are serialized via toMutation().\n     */\n    public mutations: api.Write[]\n  ) {}\n}\n\n/**\n * The key for a db document mutation, which is made up of a userID, path, and\n * batchId. Note that the path must be serialized into a form that indexedDB can\n * sort.\n */\nexport type DbDocumentMutationKey = [string, EncodedResourcePath, BatchId];\n\nfunction createMutationQueue(db: IDBDatabase): void {\n  db.createObjectStore(DbMutationQueue.store, {\n    keyPath: DbMutationQueue.keyPath\n  });\n\n  const mutationBatchesStore = db.createObjectStore(DbMutationBatch.store, {\n    keyPath: DbMutationBatch.keyPath,\n    autoIncrement: true\n  });\n  mutationBatchesStore.createIndex(\n    DbMutationBatch.userMutationsIndex,\n    DbMutationBatch.userMutationsKeyPath,\n    { unique: true }\n  );\n\n  db.createObjectStore(DbDocumentMutation.store);\n}\n\n/**\n * Upgrade function to migrate the 'mutations' store from V1 to V3. Loads\n * and rewrites all data.\n */\nfunction upgradeMutationBatchSchemaAndMigrateData(\n  db: IDBDatabase,\n  txn: SimpleDbTransaction\n): PersistencePromise<void> {\n  const v1MutationsStore = txn.store<[string, number], DbMutationBatch>(\n    DbMutationBatch.store\n  );\n  return v1MutationsStore.loadAll().next(existingMutations => {\n    db.deleteObjectStore(DbMutationBatch.store);\n\n    const mutationsStore = db.createObjectStore(DbMutationBatch.store, {\n      keyPath: DbMutationBatch.keyPath,\n      autoIncrement: true\n    });\n    mutationsStore.createIndex(\n      DbMutationBatch.userMutationsIndex,\n      DbMutationBatch.userMutationsKeyPath,\n      { unique: true }\n    );\n\n    const v3MutationsStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n      DbMutationBatch.store\n    );\n    const writeAll = existingMutations.map(mutation =>\n      v3MutationsStore.put(mutation)\n    );\n\n    return PersistencePromise.waitFor(writeAll);\n  });\n}\n\n/**\n * An object to be stored in the 'documentMutations' store in IndexedDb.\n *\n * A manually maintained index of all the mutation batches that affect a given\n * document key. The rows in this table are references based on the contents of\n * DbMutationBatch.mutations.\n */\nexport class DbDocumentMutation {\n  static store = 'documentMutations';\n\n  /**\n   * Creates a [userId] key for use in the DbDocumentMutations index to iterate\n   * over all of a user's document mutations.\n   */\n  static prefixForUser(userId: string): [string] {\n    return [userId];\n  }\n\n  /**\n   * Creates a [userId, encodedPath] key for use in the DbDocumentMutations\n   * index to iterate over all at document mutations for a given path or lower.\n   */\n  static prefixForPath(\n    userId: string,\n    path: ResourcePath\n  ): [string, EncodedResourcePath] {\n    return [userId, encodeResourcePath(path)];\n  }\n\n  /**\n   * Creates a full index key of [userId, encodedPath, batchId] for inserting\n   * and deleting into the DbDocumentMutations index.\n   */\n  static key(\n    userId: string,\n    path: ResourcePath,\n    batchId: BatchId\n  ): DbDocumentMutationKey {\n    return [userId, encodeResourcePath(path), batchId];\n  }\n\n  /**\n   * Because we store all the useful information for this store in the key,\n   * there is no useful information to store as the value. The raw (unencoded)\n   * path cannot be stored because IndexedDb doesn't store prototype\n   * information.\n   */\n  static PLACEHOLDER = new DbDocumentMutation();\n\n  private constructor() {}\n}\n\n/**\n * A key in the 'remoteDocuments' object store is a string array containing the\n * segments that make up the path.\n */\nexport type DbRemoteDocumentKey = string[];\n\nfunction createRemoteDocumentCache(db: IDBDatabase): void {\n  db.createObjectStore(DbRemoteDocument.store);\n}\n\n/**\n * Represents the known absence of a document at a particular version.\n * Stored in IndexedDb as part of a DbRemoteDocument object.\n */\nexport class DbNoDocument {\n  constructor(public path: string[], public readTime: DbTimestamp) {}\n}\n\n/**\n * Represents a document that is known to exist but whose data is unknown.\n * Stored in IndexedDb as part of a DbRemoteDocument object.\n */\nexport class DbUnknownDocument {\n  constructor(public path: string[], public version: DbTimestamp) {}\n}\n\n/**\n * An object to be stored in the 'remoteDocuments' store in IndexedDb.\n * It represents either:\n *\n * - A complete document.\n * - A \"no document\" representing a document that is known not to exist (at\n * some version).\n * - An \"unknown document\" representing a document that is known to exist (at\n * some version) but whose contents are unknown.\n *\n * Note: This is the persisted equivalent of a MaybeDocument and could perhaps\n * be made more general if necessary.\n */\nexport class DbRemoteDocument {\n  static store = 'remoteDocuments';\n\n  /**\n   * An index that provides access to all entries sorted by read time (which\n   * corresponds to the last modification time of each row).\n   *\n   * This index is used to provide a changelog for Multi-Tab.\n   */\n  static readTimeIndex = 'readTimeIndex';\n\n  static readTimeIndexPath = 'readTime';\n\n  /**\n   * An index that provides access to documents in a collection sorted by read\n   * time.\n   *\n   * This index is used to allow the RemoteDocumentCache to fetch newly changed\n   * documents in a collection.\n   */\n  static collectionReadTimeIndex = 'collectionReadTimeIndex';\n\n  static collectionReadTimeIndexPath = ['parentPath', 'readTime'];\n\n  // TODO: We are currently storing full document keys almost three times\n  // (once as part of the primary key, once - partly - as `parentPath` and once\n  // inside the encoded documents). During our next migration, we should\n  // rewrite the primary key as parentPath + document ID which would allow us\n  // to drop one value.\n\n  constructor(\n    /**\n     * Set to an instance of DbUnknownDocument if the data for a document is\n     * not known, but it is known that a document exists at the specified\n     * version (e.g. it had a successful update applied to it)\n     */\n    public unknownDocument: DbUnknownDocument | null | undefined,\n    /**\n     * Set to an instance of a DbNoDocument if it is known that no document\n     * exists.\n     */\n    public noDocument: DbNoDocument | null,\n    /**\n     * Set to an instance of a Document if there's a cached version of the\n     * document.\n     */\n    public document: api.Document | null,\n    /**\n     * Documents that were written to the remote document store based on\n     * a write acknowledgment are marked with `hasCommittedMutations`. These\n     * documents are potentially inconsistent with the backend's copy and use\n     * the write's commit version as their document version.\n     */\n    public hasCommittedMutations: boolean | undefined,\n\n    /**\n     * When the document was read from the backend. Undefined for data written\n     * prior to schema version 9.\n     */\n    public readTime: DbTimestampKey | undefined,\n\n    /**\n     * The path of the collection this document is part of. Undefined for data\n     * written prior to schema version 9.\n     */\n    public parentPath: string[] | undefined\n  ) {}\n}\n\n/**\n * Contains a single entry that has metadata about the remote document cache.\n */\nexport class DbRemoteDocumentGlobal {\n  static store = 'remoteDocumentGlobal';\n\n  static key = 'remoteDocumentGlobalKey';\n\n  /**\n   * @param byteSize Approximately the total size in bytes of all the documents in the document\n   * cache.\n   */\n  constructor(public byteSize: number) {}\n}\n\nexport type DbRemoteDocumentGlobalKey = typeof DbRemoteDocumentGlobal.key;\n\nfunction createDocumentGlobalStore(db: IDBDatabase): void {\n  db.createObjectStore(DbRemoteDocumentGlobal.store);\n}\n\n/**\n * A key in the 'targets' object store is a targetId of the query.\n */\nexport type DbTargetKey = TargetId;\n\n/**\n * The persisted type for a query nested with in the 'targets' store in\n * IndexedDb. We use the proto definitions for these two kinds of queries in\n * order to avoid writing extra serialization logic.\n */\nexport type DbQuery = api.QueryTarget | api.DocumentsTarget;\n\n/**\n * An object to be stored in the 'targets' store in IndexedDb.\n *\n * This is based on and should be kept in sync with the proto used in the iOS\n * client.\n *\n * Each query the client listens to against the server is tracked on disk so\n * that the query can be efficiently resumed on restart.\n */\nexport class DbTarget {\n  static store = 'targets';\n\n  /** Keys are automatically assigned via the targetId property. */\n  static keyPath = 'targetId';\n\n  /** The name of the queryTargets index. */\n  static queryTargetsIndexName = 'queryTargetsIndex';\n\n  /**\n   * The index of all canonicalIds to the targets that they match. This is not\n   * a unique mapping because canonicalId does not promise a unique name for all\n   * possible queries, so we append the targetId to make the mapping unique.\n   */\n  static queryTargetsKeyPath = ['canonicalId', 'targetId'];\n\n  constructor(\n    /**\n     * An auto-generated sequential numeric identifier for the query.\n     *\n     * Queries are stored using their canonicalId as the key, but these\n     * canonicalIds can be quite long so we additionally assign a unique\n     * queryId which can be used by referenced data structures (e.g.\n     * indexes) to minimize the on-disk cost.\n     */\n    public targetId: TargetId,\n    /**\n     * The canonical string representing this query. This is not unique.\n     */\n    public canonicalId: string,\n    /**\n     * The last readTime received from the Watch Service for this query.\n     *\n     * This is the same value as TargetChange.read_time in the protos.\n     */\n    public readTime: DbTimestamp,\n    /**\n     * An opaque, server-assigned token that allows watching a query to be\n     * resumed after disconnecting without retransmitting all the data\n     * that matches the query. The resume token essentially identifies a\n     * point in time from which the server should resume sending results.\n     *\n     * This is related to the snapshotVersion in that the resumeToken\n     * effectively also encodes that value, but the resumeToken is opaque\n     * and sometimes encodes additional information.\n     *\n     * A consequence of this is that the resumeToken should be used when\n     * asking the server to reason about where this client is in the watch\n     * stream, but the client should use the snapshotVersion for its own\n     * purposes.\n     *\n     * This is the same value as TargetChange.resume_token in the protos.\n     */\n    public resumeToken: string,\n    /**\n     * A sequence number representing the last time this query was\n     * listened to, used for garbage collection purposes.\n     *\n     * Conventionally this would be a timestamp value, but device-local\n     * clocks are unreliable and they must be able to create new listens\n     * even while disconnected. Instead this should be a monotonically\n     * increasing number that's incremented on each listen call.\n     *\n     * This is different from the queryId since the queryId is an\n     * immutable identifier assigned to the Query on first use while\n     * lastListenSequenceNumber is updated every time the query is\n     * listened to.\n     */\n    public lastListenSequenceNumber: number,\n    /**\n     * Denotes the maximum snapshot version at which the associated query view\n     * contained no limbo documents.  Undefined for data written prior to\n     * schema version 9.\n     */\n    public lastLimboFreeSnapshotVersion: DbTimestamp | undefined,\n    /**\n     * The query for this target.\n     *\n     * Because canonical ids are not unique we must store the actual query. We\n     * use the proto to have an object we can persist without having to\n     * duplicate translation logic to and from a `Query` object.\n     */\n    public query: DbQuery\n  ) {}\n}\n\n/**\n * The key for a DbTargetDocument, containing a targetId and an encoded resource\n * path.\n */\nexport type DbTargetDocumentKey = [TargetId, EncodedResourcePath];\n\n/**\n * An object representing an association between a target and a document, or a\n * sentinel row marking the last sequence number at which a document was used.\n * Each document cached must have a corresponding sentinel row before lru\n * garbage collection is enabled.\n *\n * The target associations and sentinel rows are co-located so that orphaned\n * documents and their sequence numbers can be identified efficiently via a scan\n * of this store.\n */\nexport class DbTargetDocument {\n  /** Name of the IndexedDb object store.  */\n  static store = 'targetDocuments';\n\n  /** Keys are automatically assigned via the targetId, path properties. */\n  static keyPath = ['targetId', 'path'];\n\n  /** The index name for the reverse index. */\n  static documentTargetsIndex = 'documentTargetsIndex';\n\n  /** We also need to create the reverse index for these properties. */\n  static documentTargetsKeyPath = ['path', 'targetId'];\n\n  constructor(\n    /**\n     * The targetId identifying a target or 0 for a sentinel row.\n     */\n    public targetId: TargetId,\n    /**\n     * The path to the document, as encoded in the key.\n     */\n    public path: EncodedResourcePath,\n    /**\n     * If this is a sentinel row, this should be the sequence number of the last\n     * time the document specified by `path` was used. Otherwise, it should be\n     * `undefined`.\n     */\n    public sequenceNumber?: ListenSequenceNumber\n  ) {\n    debugAssert(\n      (targetId === 0) === (sequenceNumber !== undefined),\n      'A target-document row must either have targetId == 0 and a defined sequence number, or a non-zero targetId and no sequence number'\n    );\n  }\n}\n\n/**\n * The type to represent the single allowed key for the DbTargetGlobal store.\n */\nexport type DbTargetGlobalKey = typeof DbTargetGlobal.key;\n\n/**\n * A record of global state tracked across all Targets, tracked separately\n * to avoid the need for extra indexes.\n *\n * This should be kept in-sync with the proto used in the iOS client.\n */\nexport class DbTargetGlobal {\n  /**\n   * The key string used for the single object that exists in the\n   * DbTargetGlobal store.\n   */\n  static key = 'targetGlobalKey';\n  static store = 'targetGlobal';\n\n  constructor(\n    /**\n     * The highest numbered target id across all targets.\n     *\n     * See DbTarget.targetId.\n     */\n    public highestTargetId: TargetId,\n    /**\n     * The highest numbered lastListenSequenceNumber across all targets.\n     *\n     * See DbTarget.lastListenSequenceNumber.\n     */\n    public highestListenSequenceNumber: number,\n    /**\n     * A global snapshot version representing the last consistent snapshot we\n     * received from the backend. This is monotonically increasing and any\n     * snapshots received from the backend prior to this version (e.g. for\n     * targets resumed with a resumeToken) should be suppressed (buffered)\n     * until the backend has caught up to this snapshot version again. This\n     * prevents our cache from ever going backwards in time.\n     */\n    public lastRemoteSnapshotVersion: DbTimestamp,\n    /**\n     * The number of targets persisted.\n     */\n    public targetCount: number\n  ) {}\n}\n\n/**\n * The key for a DbCollectionParent entry, containing the collection ID\n * and the parent path that contains it. Note that the parent path will be an\n * empty path in the case of root-level collections.\n */\nexport type DbCollectionParentKey = [string, EncodedResourcePath];\n\n/**\n * An object representing an association between a Collection id (e.g. 'messages')\n * to a parent path (e.g. '/chats/123') that contains it as a (sub)collection.\n * This is used to efficiently find all collections to query when performing\n * a Collection Group query.\n */\nexport class DbCollectionParent {\n  /** Name of the IndexedDb object store. */\n  static store = 'collectionParents';\n\n  /** Keys are automatically assigned via the collectionId, parent properties. */\n  static keyPath = ['collectionId', 'parent'];\n\n  constructor(\n    /**\n     * The collectionId (e.g. 'messages')\n     */\n    public collectionId: string,\n    /**\n     * The path to the parent (either a document location or an empty path for\n     * a root-level collection).\n     */\n    public parent: EncodedResourcePath\n  ) {}\n}\n\nfunction createQueryCache(db: IDBDatabase): void {\n  const targetDocumentsStore = db.createObjectStore(DbTargetDocument.store, {\n    keyPath: DbTargetDocument.keyPath\n  });\n  targetDocumentsStore.createIndex(\n    DbTargetDocument.documentTargetsIndex,\n    DbTargetDocument.documentTargetsKeyPath,\n    { unique: true }\n  );\n\n  const targetStore = db.createObjectStore(DbTarget.store, {\n    keyPath: DbTarget.keyPath\n  });\n\n  // NOTE: This is unique only because the TargetId is the suffix.\n  targetStore.createIndex(\n    DbTarget.queryTargetsIndexName,\n    DbTarget.queryTargetsKeyPath,\n    { unique: true }\n  );\n  db.createObjectStore(DbTargetGlobal.store);\n}\n\nfunction dropQueryCache(db: IDBDatabase): void {\n  db.deleteObjectStore(DbTargetDocument.store);\n  db.deleteObjectStore(DbTarget.store);\n  db.deleteObjectStore(DbTargetGlobal.store);\n}\n\nfunction dropRemoteDocumentChangesStore(db: IDBDatabase): void {\n  if (db.objectStoreNames.contains('remoteDocumentChanges')) {\n    db.deleteObjectStore('remoteDocumentChanges');\n  }\n}\n\n/**\n * Creates the target global singleton row.\n *\n * @param {IDBTransaction} txn The version upgrade transaction for indexeddb\n */\nfunction writeEmptyTargetGlobalEntry(\n  txn: SimpleDbTransaction\n): PersistencePromise<void> {\n  const globalStore = txn.store<DbTargetGlobalKey, DbTargetGlobal>(\n    DbTargetGlobal.store\n  );\n  const metadata = new DbTargetGlobal(\n    /*highestTargetId=*/ 0,\n    /*lastListenSequenceNumber=*/ 0,\n    SnapshotVersion.min().toTimestamp(),\n    /*targetCount=*/ 0\n  );\n  return globalStore.put(DbTargetGlobal.key, metadata);\n}\n\n/**\n * Creates indices on the RemoteDocuments store used for both multi-tab\n * and Index-Free queries.\n */\nfunction createRemoteDocumentReadTimeIndex(txn: IDBTransaction): void {\n  const remoteDocumentStore = txn.objectStore(DbRemoteDocument.store);\n  remoteDocumentStore.createIndex(\n    DbRemoteDocument.readTimeIndex,\n    DbRemoteDocument.readTimeIndexPath,\n    { unique: false }\n  );\n  remoteDocumentStore.createIndex(\n    DbRemoteDocument.collectionReadTimeIndex,\n    DbRemoteDocument.collectionReadTimeIndexPath,\n    { unique: false }\n  );\n}\n\n/**\n * A record of the metadata state of each client.\n *\n * PORTING NOTE: This is used to synchronize multi-tab state and does not need\n * to be ported to iOS or Android.\n */\nexport class DbClientMetadata {\n  /** Name of the IndexedDb object store. */\n  static store = 'clientMetadata';\n\n  /** Keys are automatically assigned via the clientId properties. */\n  static keyPath = 'clientId';\n\n  constructor(\n    // Note: Previous schema versions included a field\n    // \"lastProcessedDocumentChangeId\". Don't use anymore.\n\n    /** The auto-generated client id assigned at client startup. */\n    public clientId: string,\n    /** The last time this state was updated. */\n    public updateTimeMs: number,\n    /** Whether the client's network connection is enabled. */\n    public networkEnabled: boolean,\n    /** Whether this client is running in a foreground tab. */\n    public inForeground: boolean\n  ) {}\n}\n\n/** Object keys in the 'clientMetadata' store are clientId strings. */\nexport type DbClientMetadataKey = string;\n\nfunction createClientMetadataStore(db: IDBDatabase): void {\n  db.createObjectStore(DbClientMetadata.store, {\n    keyPath: DbClientMetadata.keyPath\n  });\n}\n\n// Visible for testing\nexport const V1_STORES = [\n  DbMutationQueue.store,\n  DbMutationBatch.store,\n  DbDocumentMutation.store,\n  DbRemoteDocument.store,\n  DbTarget.store,\n  DbPrimaryClient.store,\n  DbTargetGlobal.store,\n  DbTargetDocument.store\n];\n\n// V2 is no longer usable (see comment at top of file)\n\n// Visible for testing\nexport const V3_STORES = V1_STORES;\n\n// Visible for testing\n// Note: DbRemoteDocumentChanges is no longer used and dropped with v9.\nexport const V4_STORES = [...V3_STORES, DbClientMetadata.store];\n\n// V5 does not change the set of stores.\n\nexport const V6_STORES = [...V4_STORES, DbRemoteDocumentGlobal.store];\n\n// V7 does not change the set of stores.\n\nexport const V8_STORES = [...V6_STORES, DbCollectionParent.store];\n\n// V9 does not change the set of stores.\n\n// V10 does not change the set of stores.\n\n/**\n * The list of all default IndexedDB stores used throughout the SDK. This is\n * used when creating transactions so that access across all stores is done\n * atomically.\n */\nexport const ALL_STORES = V8_STORES;\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 { ResourcePath } from '../model/path';\nimport { debugAssert } from '../util/assert';\nimport { immediateSuccessor } from '../util/misc';\nimport {\n  decodeResourcePath,\n  encodeResourcePath\n} from './encoded_resource_path';\nimport { IndexManager } from './index_manager';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport { DbCollectionParent, DbCollectionParentKey } from './indexeddb_schema';\nimport { MemoryCollectionParentIndex } from './memory_index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbStore } from './simple_db';\n\n/**\n * A persisted implementation of IndexManager.\n */\nexport class IndexedDbIndexManager implements IndexManager {\n  /**\n   * An in-memory copy of the index entries we've already written since the SDK\n   * launched. Used to avoid re-writing the same entry repeatedly.\n   *\n   * This is *NOT* a complete cache of what's in persistence and so can never be used to\n   * satisfy reads.\n   */\n  private collectionParentsCache = new MemoryCollectionParentIndex();\n\n  /**\n   * Adds a new entry to the collection parent index.\n   *\n   * Repeated calls for the same collectionPath should be avoided within a\n   * transaction as IndexedDbIndexManager only caches writes once a transaction\n   * has been committed.\n   */\n  addToCollectionParentIndex(\n    transaction: PersistenceTransaction,\n    collectionPath: ResourcePath\n  ): PersistencePromise<void> {\n    debugAssert(collectionPath.length % 2 === 1, 'Expected a collection path.');\n    if (!this.collectionParentsCache.has(collectionPath)) {\n      const collectionId = collectionPath.lastSegment();\n      const parentPath = collectionPath.popLast();\n\n      transaction.addOnCommittedListener(() => {\n        // Add the collection to the in memory cache only if the transaction was\n        // successfully committed.\n        this.collectionParentsCache.add(collectionPath);\n      });\n\n      const collectionParent: DbCollectionParent = {\n        collectionId,\n        parent: encodeResourcePath(parentPath)\n      };\n      return collectionParentsStore(transaction).put(collectionParent);\n    }\n    return PersistencePromise.resolve();\n  }\n\n  getCollectionParents(\n    transaction: PersistenceTransaction,\n    collectionId: string\n  ): PersistencePromise<ResourcePath[]> {\n    const parentPaths = [] as ResourcePath[];\n    const range = IDBKeyRange.bound(\n      [collectionId, ''],\n      [immediateSuccessor(collectionId), ''],\n      /*lowerOpen=*/ false,\n      /*upperOpen=*/ true\n    );\n    return collectionParentsStore(transaction)\n      .loadAll(range)\n      .next(entries => {\n        for (const entry of entries) {\n          // This collectionId guard shouldn't be necessary (and isn't as long\n          // as we're running in a real browser), but there's a bug in\n          // indexeddbshim that breaks our range in our tests running in node:\n          // https://github.com/axemclion/IndexedDBShim/issues/334\n          if (entry.collectionId !== collectionId) {\n            break;\n          }\n          parentPaths.push(decodeResourcePath(entry.parent));\n        }\n        return parentPaths;\n      });\n  }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the collectionParents\n * document store.\n */\nfunction collectionParentsStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbCollectionParentKey, DbCollectionParent> {\n  return IndexedDbPersistence.getStore<\n    DbCollectionParentKey,\n    DbCollectionParent\n  >(txn, DbCollectionParent.store);\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 { TargetId } from './types';\n\n/** Offset to ensure non-overlapping target ids. */\nconst OFFSET = 2;\n\n/**\n * Generates monotonically increasing target IDs for sending targets to the\n * watch stream.\n *\n * The client constructs two generators, one for the target cache, and one for\n * for the sync engine (to generate limbo documents targets). These\n * generators produce non-overlapping IDs (by using even and odd IDs\n * respectively).\n *\n * By separating the target ID space, the query cache can generate target IDs\n * that persist across client restarts, while sync engine can independently\n * generate in-memory target IDs that are transient and can be reused after a\n * restart.\n */\nexport class TargetIdGenerator {\n  constructor(private lastId: number) {}\n\n  next(): TargetId {\n    this.lastId += OFFSET;\n    return this.lastId;\n  }\n\n  static forTargetCache(): TargetIdGenerator {\n    // The target cache generator must return '2' in its first call to `next()`\n    // as there is no differentiation in the protocol layer between an unset\n    // number and the number '0'. If we were to sent a target with target ID\n    // '0', the backend would consider it unset and replace it with its own ID.\n    return new TargetIdGenerator(2 - OFFSET);\n  }\n\n  static forSyncEngine(): TargetIdGenerator {\n    // Sync engine assigns target IDs for limbo document detection.\n    return new TargetIdGenerator(1 - OFFSET);\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKeySet, documentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { hardAssert } from '../util/assert';\nimport { immediateSuccessor } from '../util/misc';\nimport { TargetIdGenerator } from '../core/target_id_generator';\nimport {\n  decodeResourcePath,\n  encodeResourcePath\n} from './encoded_resource_path';\nimport {\n  IndexedDbLruDelegate,\n  IndexedDbPersistence\n} from './indexeddb_persistence';\nimport {\n  DbTarget,\n  DbTargetDocument,\n  DbTargetDocumentKey,\n  DbTargetGlobal,\n  DbTargetGlobalKey,\n  DbTargetKey\n} from './indexeddb_schema';\nimport { fromDbTarget, LocalSerializer, toDbTarget } from './local_serializer';\nimport { ActiveTargets } from './lru_garbage_collector';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { TargetData } from './target_data';\nimport { SimpleDbStore } from './simple_db';\nimport { canonifyTarget, Target, targetEquals } from '../core/target';\n\nexport class IndexedDbTargetCache implements TargetCache {\n  constructor(\n    private readonly referenceDelegate: IndexedDbLruDelegate,\n    private serializer: LocalSerializer\n  ) {}\n\n  // PORTING NOTE: We don't cache global metadata for the target cache, since\n  // some of it (in particular `highestTargetId`) can be modified by secondary\n  // tabs. We could perhaps be more granular (and e.g. still cache\n  // `lastRemoteSnapshotVersion` in memory) but for simplicity we currently go\n  // to IndexedDb whenever we need to read metadata. We can revisit if it turns\n  // out to have a meaningful performance impact.\n\n  allocateTargetId(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<TargetId> {\n    return this.retrieveMetadata(transaction).next(metadata => {\n      const targetIdGenerator = new TargetIdGenerator(metadata.highestTargetId);\n      metadata.highestTargetId = targetIdGenerator.next();\n      return this.saveMetadata(transaction, metadata).next(\n        () => metadata.highestTargetId\n      );\n    });\n  }\n\n  getLastRemoteSnapshotVersion(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<SnapshotVersion> {\n    return this.retrieveMetadata(transaction).next(metadata => {\n      return SnapshotVersion.fromTimestamp(\n        new Timestamp(\n          metadata.lastRemoteSnapshotVersion.seconds,\n          metadata.lastRemoteSnapshotVersion.nanoseconds\n        )\n      );\n    });\n  }\n\n  getHighestSequenceNumber(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<ListenSequenceNumber> {\n    return this.retrieveMetadata(transaction).next(\n      targetGlobal => targetGlobal.highestListenSequenceNumber\n    );\n  }\n\n  setTargetsMetadata(\n    transaction: PersistenceTransaction,\n    highestListenSequenceNumber: number,\n    lastRemoteSnapshotVersion?: SnapshotVersion\n  ): PersistencePromise<void> {\n    return this.retrieveMetadata(transaction).next(metadata => {\n      metadata.highestListenSequenceNumber = highestListenSequenceNumber;\n      if (lastRemoteSnapshotVersion) {\n        metadata.lastRemoteSnapshotVersion = lastRemoteSnapshotVersion.toTimestamp();\n      }\n      if (highestListenSequenceNumber > metadata.highestListenSequenceNumber) {\n        metadata.highestListenSequenceNumber = highestListenSequenceNumber;\n      }\n      return this.saveMetadata(transaction, metadata);\n    });\n  }\n\n  addTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    return this.saveTargetData(transaction, targetData).next(() => {\n      return this.retrieveMetadata(transaction).next(metadata => {\n        metadata.targetCount += 1;\n        this.updateMetadataFromTargetData(targetData, metadata);\n        return this.saveMetadata(transaction, metadata);\n      });\n    });\n  }\n\n  updateTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    return this.saveTargetData(transaction, targetData);\n  }\n\n  removeTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    return this.removeMatchingKeysForTargetId(transaction, targetData.targetId)\n      .next(() => targetsStore(transaction).delete(targetData.targetId))\n      .next(() => this.retrieveMetadata(transaction))\n      .next(metadata => {\n        hardAssert(\n          metadata.targetCount > 0,\n          'Removing from an empty target cache'\n        );\n        metadata.targetCount -= 1;\n        return this.saveMetadata(transaction, metadata);\n      });\n  }\n\n  /**\n   * Drops any targets with sequence number less than or equal to the upper bound, excepting those\n   * present in `activeTargetIds`. Document associations for the removed targets are also removed.\n   * Returns the number of targets removed.\n   */\n  removeTargets(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number> {\n    let count = 0;\n    const promises: Array<PersistencePromise<void>> = [];\n    return targetsStore(txn)\n      .iterate((key, value) => {\n        const targetData = fromDbTarget(value);\n        if (\n          targetData.sequenceNumber <= upperBound &&\n          activeTargetIds.get(targetData.targetId) === null\n        ) {\n          count++;\n          promises.push(this.removeTargetData(txn, targetData));\n        }\n      })\n      .next(() => PersistencePromise.waitFor(promises))\n      .next(() => count);\n  }\n\n  /**\n   * Call provided function with each `TargetData` that we have cached.\n   */\n  forEachTarget(\n    txn: PersistenceTransaction,\n    f: (q: TargetData) => void\n  ): PersistencePromise<void> {\n    return targetsStore(txn).iterate((key, value) => {\n      const targetData = fromDbTarget(value);\n      f(targetData);\n    });\n  }\n\n  private retrieveMetadata(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<DbTargetGlobal> {\n    return globalTargetStore(transaction)\n      .get(DbTargetGlobal.key)\n      .next(metadata => {\n        hardAssert(metadata !== null, 'Missing metadata row.');\n        return metadata;\n      });\n  }\n\n  private saveMetadata(\n    transaction: PersistenceTransaction,\n    metadata: DbTargetGlobal\n  ): PersistencePromise<void> {\n    return globalTargetStore(transaction).put(DbTargetGlobal.key, metadata);\n  }\n\n  private saveTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    return targetsStore(transaction).put(\n      toDbTarget(this.serializer, targetData)\n    );\n  }\n\n  /**\n   * In-place updates the provided metadata to account for values in the given\n   * TargetData. Saving is done separately. Returns true if there were any\n   * changes to the metadata.\n   */\n  private updateMetadataFromTargetData(\n    targetData: TargetData,\n    metadata: DbTargetGlobal\n  ): boolean {\n    let updated = false;\n    if (targetData.targetId > metadata.highestTargetId) {\n      metadata.highestTargetId = targetData.targetId;\n      updated = true;\n    }\n\n    if (targetData.sequenceNumber > metadata.highestListenSequenceNumber) {\n      metadata.highestListenSequenceNumber = targetData.sequenceNumber;\n      updated = true;\n    }\n    return updated;\n  }\n\n  getTargetCount(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<number> {\n    return this.retrieveMetadata(transaction).next(\n      metadata => metadata.targetCount\n    );\n  }\n\n  getTargetData(\n    transaction: PersistenceTransaction,\n    target: Target\n  ): PersistencePromise<TargetData | null> {\n    // Iterating by the canonicalId may yield more than one result because\n    // canonicalId values are not required to be unique per target. This query\n    // depends on the queryTargets index to be efficient.\n    const canonicalId = canonifyTarget(target);\n    const range = IDBKeyRange.bound(\n      [canonicalId, Number.NEGATIVE_INFINITY],\n      [canonicalId, Number.POSITIVE_INFINITY]\n    );\n    let result: TargetData | null = null;\n    return targetsStore(transaction)\n      .iterate(\n        { range, index: DbTarget.queryTargetsIndexName },\n        (key, value, control) => {\n          const found = fromDbTarget(value);\n          // After finding a potential match, check that the target is\n          // actually equal to the requested target.\n          if (targetEquals(target, found.target)) {\n            result = found;\n            control.done();\n          }\n        }\n      )\n      .next(() => result);\n  }\n\n  addMatchingKeys(\n    txn: PersistenceTransaction,\n    keys: DocumentKeySet,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    // PORTING NOTE: The reverse index (documentsTargets) is maintained by\n    // IndexedDb.\n    const promises: Array<PersistencePromise<void>> = [];\n    const store = documentTargetStore(txn);\n    keys.forEach(key => {\n      const path = encodeResourcePath(key.path);\n      promises.push(store.put(new DbTargetDocument(targetId, path)));\n      promises.push(this.referenceDelegate.addReference(txn, targetId, key));\n    });\n    return PersistencePromise.waitFor(promises);\n  }\n\n  removeMatchingKeys(\n    txn: PersistenceTransaction,\n    keys: DocumentKeySet,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    // PORTING NOTE: The reverse index (documentsTargets) is maintained by\n    // IndexedDb.\n    const store = documentTargetStore(txn);\n    return PersistencePromise.forEach(keys, (key: DocumentKey) => {\n      const path = encodeResourcePath(key.path);\n      return PersistencePromise.waitFor([\n        store.delete([targetId, path]),\n        this.referenceDelegate.removeReference(txn, targetId, key)\n      ]);\n    });\n  }\n\n  removeMatchingKeysForTargetId(\n    txn: PersistenceTransaction,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    const store = documentTargetStore(txn);\n    const range = IDBKeyRange.bound(\n      [targetId],\n      [targetId + 1],\n      /*lowerOpen=*/ false,\n      /*upperOpen=*/ true\n    );\n    return store.delete(range);\n  }\n\n  getMatchingKeysForTargetId(\n    txn: PersistenceTransaction,\n    targetId: TargetId\n  ): PersistencePromise<DocumentKeySet> {\n    const range = IDBKeyRange.bound(\n      [targetId],\n      [targetId + 1],\n      /*lowerOpen=*/ false,\n      /*upperOpen=*/ true\n    );\n    const store = documentTargetStore(txn);\n    let result = documentKeySet();\n\n    return store\n      .iterate({ range, keysOnly: true }, (key, _, control) => {\n        const path = decodeResourcePath(key[1]);\n        const docKey = new DocumentKey(path);\n        result = result.add(docKey);\n      })\n      .next(() => result);\n  }\n\n  containsKey(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    const path = encodeResourcePath(key.path);\n    const range = IDBKeyRange.bound(\n      [path],\n      [immediateSuccessor(path)],\n      /*lowerOpen=*/ false,\n      /*upperOpen=*/ true\n    );\n    let count = 0;\n    return documentTargetStore(txn!)\n      .iterate(\n        {\n          index: DbTargetDocument.documentTargetsIndex,\n          keysOnly: true,\n          range\n        },\n        ([targetId, path], _, control) => {\n          // Having a sentinel row for a document does not count as containing that document;\n          // For the target cache, containing the document means the document is part of some\n          // target.\n          if (targetId !== 0) {\n            count++;\n            control.done();\n          }\n        }\n      )\n      .next(() => count > 0);\n  }\n\n  /**\n   * Looks up a TargetData entry by target ID.\n   *\n   * @param targetId The target ID of the TargetData entry to look up.\n   * @return The cached TargetData entry, or null if the cache has no entry for\n   * the target.\n   */\n  // PORTING NOTE: Multi-tab only.\n  getTargetDataForTarget(\n    transaction: PersistenceTransaction,\n    targetId: TargetId\n  ): PersistencePromise<TargetData | null> {\n    return targetsStore(transaction)\n      .get(targetId)\n      .next(found => {\n        if (found) {\n          return fromDbTarget(found);\n        } else {\n          return null;\n        }\n      });\n  }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the queries object store.\n */\nfunction targetsStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbTargetKey, DbTarget> {\n  return IndexedDbPersistence.getStore<DbTargetKey, DbTarget>(\n    txn,\n    DbTarget.store\n  );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the target globals object store.\n */\nfunction globalTargetStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbTargetGlobalKey, DbTargetGlobal> {\n  return IndexedDbPersistence.getStore<DbTargetGlobalKey, DbTargetGlobal>(\n    txn,\n    DbTargetGlobal.store\n  );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the document target object store.\n */\nexport function documentTargetStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbTargetDocumentKey, DbTargetDocument> {\n  return IndexedDbPersistence.getStore<DbTargetDocumentKey, DbTargetDocument>(\n    txn,\n    DbTargetDocument.store\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 { User } from '../auth/user';\nimport { DatabaseId } from '../core/database_info';\nimport { ListenSequence, SequenceNumberSyncer } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { debugAssert, fail } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\nimport {\n  decodeResourcePath,\n  EncodedResourcePath,\n  encodeResourcePath\n} from './encoded_resource_path';\nimport { IndexedDbIndexManager } from './indexeddb_index_manager';\nimport {\n  IndexedDbMutationQueue,\n  mutationQueuesContainKey\n} from './indexeddb_mutation_queue';\nimport { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';\nimport {\n  ALL_STORES,\n  DbClientMetadata,\n  DbClientMetadataKey,\n  DbPrimaryClient,\n  DbPrimaryClientKey,\n  DbTargetDocument,\n  SCHEMA_VERSION,\n  SchemaConverter\n} from './indexeddb_schema';\nimport {\n  documentTargetStore,\n  IndexedDbTargetCache\n} from './indexeddb_target_cache';\nimport { LocalSerializer } from './local_serializer';\nimport {\n  ActiveTargets,\n  LruDelegate,\n  LruGarbageCollector,\n  LruParams\n} from './lru_garbage_collector';\nimport {\n  Persistence,\n  PersistenceTransaction,\n  PersistenceTransactionMode,\n  PRIMARY_LEASE_LOST_ERROR_MSG,\n  PrimaryStateListener,\n  ReferenceDelegate\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ClientId } from './shared_client_state';\nimport { TargetData } from './target_data';\nimport {\n  isIndexedDbTransactionError,\n  SimpleDb,\n  SimpleDbStore,\n  SimpleDbTransaction\n} from './simple_db';\nimport { DocumentLike, WindowLike } from '../util/types';\n\nconst LOG_TAG = 'IndexedDbPersistence';\n\n/**\n * Oldest acceptable age in milliseconds for client metadata before the client\n * is considered inactive and its associated data is garbage collected.\n */\nconst MAX_CLIENT_AGE_MS = 30 * 60 * 1000; // 30 minutes\n\n/**\n * Oldest acceptable metadata age for clients that may participate in the\n * primary lease election. Clients that have not updated their client metadata\n * within 5 seconds are not eligible to receive a primary lease.\n */\nconst MAX_PRIMARY_ELIGIBLE_AGE_MS = 5000;\n\n/**\n * The interval at which clients will update their metadata, including\n * refreshing their primary lease if held or potentially trying to acquire it if\n * not held.\n *\n * Primary clients may opportunistically refresh their metadata earlier\n * if they're already performing an IndexedDB operation.\n */\nconst CLIENT_METADATA_REFRESH_INTERVAL_MS = 4000;\n/** User-facing error when the primary lease is required but not available. */\nconst PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG =\n  'Failed to obtain exclusive access to the persistence layer. ' +\n  'To allow shared access, make sure to invoke ' +\n  '`enablePersistence()` with `synchronizeTabs:true` in all tabs. ' +\n  'If you are using `experimentalForceOwningTab:true`, make sure that only ' +\n  'one tab has persistence enabled at any given time.';\nconst UNSUPPORTED_PLATFORM_ERROR_MSG =\n  'This platform is either missing' +\n  ' IndexedDB or is known to have an incomplete implementation. Offline' +\n  ' persistence has been disabled.';\n\n// The format of the LocalStorage key that stores zombied client is:\n//     firestore_zombie_<persistence_prefix>_<instance_key>\nconst ZOMBIED_CLIENTS_KEY_PREFIX = 'firestore_zombie';\n\n/**\n * The name of the main (and currently only) IndexedDB database. This name is\n * appended to the prefix provided to the IndexedDbPersistence constructor.\n */\nexport const MAIN_DATABASE = 'main';\n\nexport class IndexedDbTransaction extends PersistenceTransaction {\n  constructor(\n    readonly simpleDbTransaction: SimpleDbTransaction,\n    readonly currentSequenceNumber: ListenSequenceNumber\n  ) {\n    super();\n  }\n}\n\n/**\n * An IndexedDB-backed instance of Persistence. Data is stored persistently\n * across sessions.\n *\n * On Web only, the Firestore SDKs support shared access to its persistence\n * layer. This allows multiple browser tabs to read and write to IndexedDb and\n * to synchronize state even without network connectivity. Shared access is\n * currently optional and not enabled unless all clients invoke\n * `enablePersistence()` with `{synchronizeTabs:true}`.\n *\n * In multi-tab mode, if multiple clients are active at the same time, the SDK\n * will designate one client as the “primary client”. An effort is made to pick\n * a visible, network-connected and active client, and this client is\n * responsible for letting other clients know about its presence. The primary\n * client writes a unique client-generated identifier (the client ID) to\n * IndexedDb’s “owner” store every 4 seconds. If the primary client fails to\n * update this entry, another client can acquire the lease and take over as\n * primary.\n *\n * Some persistence operations in the SDK are designated as primary-client only\n * operations. This includes the acknowledgment of mutations and all updates of\n * remote documents. The effects of these operations are written to persistence\n * and then broadcast to other tabs via LocalStorage (see\n * `WebStorageSharedClientState`), which then refresh their state from\n * persistence.\n *\n * Similarly, the primary client listens to notifications sent by secondary\n * clients to discover persistence changes written by secondary clients, such as\n * the addition of new mutations and query targets.\n *\n * If multi-tab is not enabled and another tab already obtained the primary\n * lease, IndexedDbPersistence enters a failed state and all subsequent\n * operations will automatically fail.\n *\n * Additionally, there is an optimization so that when a tab is closed, the\n * primary lease is released immediately (this is especially important to make\n * sure that a refreshed tab is able to immediately re-acquire the primary\n * lease). Unfortunately, IndexedDB cannot be reliably used in window.unload\n * since it is an asynchronous API. So in addition to attempting to give up the\n * lease, the leaseholder writes its client ID to a \"zombiedClient\" entry in\n * LocalStorage which acts as an indicator that another tab should go ahead and\n * take the primary lease immediately regardless of the current lease timestamp.\n *\n * TODO(b/114226234): Remove `synchronizeTabs` section when multi-tab is no\n * longer optional.\n */\nexport class IndexedDbPersistence implements Persistence {\n  static getStore<Key extends IDBValidKey, Value>(\n    txn: PersistenceTransaction,\n    store: string\n  ): SimpleDbStore<Key, Value> {\n    if (txn instanceof IndexedDbTransaction) {\n      return SimpleDb.getStore<Key, Value>(txn.simpleDbTransaction, store);\n    } else {\n      throw fail(\n        'IndexedDbPersistence must use instances of IndexedDbTransaction'\n      );\n    }\n  }\n\n  private simpleDb: SimpleDb;\n\n  private listenSequence: ListenSequence | null = null;\n\n  private _started = false;\n  private isPrimary = false;\n  private networkEnabled = true;\n  private dbName: string;\n\n  /** Our window.unload handler, if registered. */\n  private windowUnloadHandler: (() => void) | null = null;\n  private inForeground = false;\n\n  private serializer: LocalSerializer;\n\n  /** Our 'visibilitychange' listener if registered. */\n  private documentVisibilityHandler: ((e?: Event) => void) | null = null;\n\n  /** The client metadata refresh task. */\n  private clientMetadataRefresher: DelayedOperation<void> | null = null;\n\n  /** The last time we garbage collected the client metadata object store. */\n  private lastGarbageCollectionTime = Number.NEGATIVE_INFINITY;\n\n  /** A listener to notify on primary state changes. */\n  private primaryStateListener: PrimaryStateListener = _ => Promise.resolve();\n\n  private readonly targetCache: IndexedDbTargetCache;\n  private readonly indexManager: IndexedDbIndexManager;\n  private readonly remoteDocumentCache: IndexedDbRemoteDocumentCache;\n  private readonly webStorage: Storage | null;\n  readonly referenceDelegate: IndexedDbLruDelegate;\n\n  constructor(\n    /**\n     * Whether to synchronize the in-memory state of multiple tabs and share\n     * access to local persistence.\n     */\n    private readonly allowTabSynchronization: boolean,\n\n    private readonly persistenceKey: string,\n    private readonly clientId: ClientId,\n    lruParams: LruParams,\n    private readonly queue: AsyncQueue,\n    private readonly window: WindowLike | null,\n    private readonly document: DocumentLike | null,\n    serializer: JsonProtoSerializer,\n    private readonly sequenceNumberSyncer: SequenceNumberSyncer,\n\n    /**\n     * If set to true, forcefully obtains database access. Existing tabs will\n     * no longer be able to access IndexedDB.\n     */\n    private readonly forceOwningTab: boolean\n  ) {\n    if (!IndexedDbPersistence.isAvailable()) {\n      throw new FirestoreError(\n        Code.UNIMPLEMENTED,\n        UNSUPPORTED_PLATFORM_ERROR_MSG\n      );\n    }\n\n    this.referenceDelegate = new IndexedDbLruDelegate(this, lruParams);\n    this.dbName = persistenceKey + MAIN_DATABASE;\n    this.serializer = new LocalSerializer(serializer);\n    this.simpleDb = new SimpleDb(\n      this.dbName,\n      SCHEMA_VERSION,\n      new SchemaConverter(this.serializer)\n    );\n    this.targetCache = new IndexedDbTargetCache(\n      this.referenceDelegate,\n      this.serializer\n    );\n    this.indexManager = new IndexedDbIndexManager();\n    this.remoteDocumentCache = new IndexedDbRemoteDocumentCache(\n      this.serializer,\n      this.indexManager\n    );\n    if (this.window && this.window.localStorage) {\n      this.webStorage = this.window.localStorage;\n    } else {\n      this.webStorage = null;\n      if (forceOwningTab === false) {\n        logError(\n          LOG_TAG,\n          'LocalStorage is unavailable. As a result, persistence may not work ' +\n            'reliably. In particular enablePersistence() could fail immediately ' +\n            'after refreshing the page.'\n        );\n      }\n    }\n  }\n\n  /**\n   * Attempt to start IndexedDb persistence.\n   *\n   * @return {Promise<void>} Whether persistence was enabled.\n   */\n  start(): Promise<void> {\n    debugAssert(!this.started, 'IndexedDbPersistence double-started!');\n    debugAssert(this.window !== null, \"Expected 'window' to be defined\");\n\n    // NOTE: This is expected to fail sometimes (in the case of another tab\n    // already having the persistence lock), so it's the first thing we should\n    // do.\n    return this.updateClientMetadataAndTryBecomePrimary()\n      .then(() => {\n        if (!this.isPrimary && !this.allowTabSynchronization) {\n          // Fail `start()` if `synchronizeTabs` is disabled and we cannot\n          // obtain the primary lease.\n          throw new FirestoreError(\n            Code.FAILED_PRECONDITION,\n            PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n          );\n        }\n        this.attachVisibilityHandler();\n        this.attachWindowUnloadHook();\n\n        this.scheduleClientMetadataAndPrimaryLeaseRefreshes();\n\n        return this.runTransaction(\n          'getHighestListenSequenceNumber',\n          'readonly',\n          txn => this.targetCache.getHighestSequenceNumber(txn)\n        );\n      })\n      .then(highestListenSequenceNumber => {\n        this.listenSequence = new ListenSequence(\n          highestListenSequenceNumber,\n          this.sequenceNumberSyncer\n        );\n      })\n      .then(() => {\n        this._started = true;\n      })\n      .catch(reason => {\n        this.simpleDb && this.simpleDb.close();\n        return Promise.reject(reason);\n      });\n  }\n\n  /**\n   * Registers a listener that gets called when the primary state of the\n   * instance changes. Upon registering, this listener is invoked immediately\n   * with the current primary state.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  setPrimaryStateListener(\n    primaryStateListener: PrimaryStateListener\n  ): Promise<void> {\n    this.primaryStateListener = async primaryState => {\n      if (this.started) {\n        return primaryStateListener(primaryState);\n      }\n    };\n    return primaryStateListener(this.isPrimary);\n  }\n\n  /**\n   * Registers a listener that gets called when the database receives a\n   * version change event indicating that it has deleted.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  setDatabaseDeletedListener(\n    databaseDeletedListener: () => Promise<void>\n  ): void {\n    this.simpleDb.setVersionChangeListener(async event => {\n      // Check if an attempt is made to delete IndexedDB.\n      if (event.newVersion === null) {\n        await databaseDeletedListener();\n      }\n    });\n  }\n\n  /**\n   * Adjusts the current network state in the client's metadata, potentially\n   * affecting the primary lease.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  setNetworkEnabled(networkEnabled: boolean): void {\n    if (this.networkEnabled !== networkEnabled) {\n      this.networkEnabled = networkEnabled;\n      // Schedule a primary lease refresh for immediate execution. The eventual\n      // lease update will be propagated via `primaryStateListener`.\n      this.queue.enqueueAndForget(async () => {\n        if (this.started) {\n          await this.updateClientMetadataAndTryBecomePrimary();\n        }\n      });\n    }\n  }\n\n  /**\n   * Updates the client metadata in IndexedDb and attempts to either obtain or\n   * extend the primary lease for the local client. Asynchronously notifies the\n   * primary state listener if the client either newly obtained or released its\n   * primary lease.\n   */\n  private updateClientMetadataAndTryBecomePrimary(): Promise<void> {\n    return this.runTransaction(\n      'updateClientMetadataAndTryBecomePrimary',\n      'readwrite',\n      txn => {\n        const metadataStore = clientMetadataStore(txn);\n        return metadataStore\n          .put(\n            new DbClientMetadata(\n              this.clientId,\n              Date.now(),\n              this.networkEnabled,\n              this.inForeground\n            )\n          )\n          .next(() => {\n            if (this.isPrimary) {\n              return this.verifyPrimaryLease(txn).next(success => {\n                if (!success) {\n                  this.isPrimary = false;\n                  this.queue.enqueueRetryable(() =>\n                    this.primaryStateListener(false)\n                  );\n                }\n              });\n            }\n          })\n          .next(() => this.canActAsPrimary(txn))\n          .next(canActAsPrimary => {\n            if (this.isPrimary && !canActAsPrimary) {\n              return this.releasePrimaryLeaseIfHeld(txn).next(() => false);\n            } else if (canActAsPrimary) {\n              return this.acquireOrExtendPrimaryLease(txn).next(() => true);\n            } else {\n              return /* canActAsPrimary= */ false;\n            }\n          });\n      }\n    )\n      .catch(e => {\n        if (isIndexedDbTransactionError(e)) {\n          logDebug(LOG_TAG, 'Failed to extend owner lease: ', e);\n          // Proceed with the existing state. Any subsequent access to\n          // IndexedDB will verify the lease.\n          return this.isPrimary;\n        }\n\n        if (!this.allowTabSynchronization) {\n          throw e;\n        }\n\n        logDebug(\n          LOG_TAG,\n          'Releasing owner lease after error during lease refresh',\n          e\n        );\n        return /* isPrimary= */ false;\n      })\n      .then(isPrimary => {\n        if (this.isPrimary !== isPrimary) {\n          this.queue.enqueueRetryable(() =>\n            this.primaryStateListener(isPrimary)\n          );\n        }\n        this.isPrimary = isPrimary;\n      });\n  }\n\n  private verifyPrimaryLease(\n    txn: PersistenceTransaction\n  ): PersistencePromise<boolean> {\n    const store = primaryClientStore(txn);\n    return store.get(DbPrimaryClient.key).next(primaryClient => {\n      return PersistencePromise.resolve(this.isLocalClient(primaryClient));\n    });\n  }\n\n  private removeClientMetadata(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    const metadataStore = clientMetadataStore(txn);\n    return metadataStore.delete(this.clientId);\n  }\n\n  /**\n   * If the garbage collection threshold has passed, prunes the\n   * RemoteDocumentChanges and the ClientMetadata store based on the last update\n   * time of all clients.\n   */\n  private async maybeGarbageCollectMultiClientState(): Promise<void> {\n    if (\n      this.isPrimary &&\n      !this.isWithinAge(this.lastGarbageCollectionTime, MAX_CLIENT_AGE_MS)\n    ) {\n      this.lastGarbageCollectionTime = Date.now();\n\n      const inactiveClients = await this.runTransaction(\n        'maybeGarbageCollectMultiClientState',\n        'readwrite-primary',\n        txn => {\n          const metadataStore = IndexedDbPersistence.getStore<\n            DbClientMetadataKey,\n            DbClientMetadata\n          >(txn, DbClientMetadata.store);\n\n          return metadataStore.loadAll().next(existingClients => {\n            const active = this.filterActiveClients(\n              existingClients,\n              MAX_CLIENT_AGE_MS\n            );\n            const inactive = existingClients.filter(\n              client => active.indexOf(client) === -1\n            );\n\n            // Delete metadata for clients that are no longer considered active.\n            return PersistencePromise.forEach(\n              inactive,\n              (inactiveClient: DbClientMetadata) =>\n                metadataStore.delete(inactiveClient.clientId)\n            ).next(() => inactive);\n          });\n        }\n      ).catch(() => {\n        // Ignore primary lease violations or any other type of error. The next\n        // primary will run `maybeGarbageCollectMultiClientState()` again.\n        // We don't use `ignoreIfPrimaryLeaseLoss()` since we don't want to depend\n        // on LocalStore.\n        return [];\n      });\n\n      // Delete potential leftover entries that may continue to mark the\n      // inactive clients as zombied in LocalStorage.\n      // Ideally we'd delete the IndexedDb and LocalStorage zombie entries for\n      // the client atomically, but we can't. So we opt to delete the IndexedDb\n      // entries first to avoid potentially reviving a zombied client.\n      if (this.webStorage) {\n        for (const inactiveClient of inactiveClients) {\n          this.webStorage.removeItem(\n            this.zombiedClientLocalStorageKey(inactiveClient.clientId)\n          );\n        }\n      }\n    }\n  }\n\n  /**\n   * Schedules a recurring timer to update the client metadata and to either\n   * extend or acquire the primary lease if the client is eligible.\n   */\n  private scheduleClientMetadataAndPrimaryLeaseRefreshes(): void {\n    this.clientMetadataRefresher = this.queue.enqueueAfterDelay(\n      TimerId.ClientMetadataRefresh,\n      CLIENT_METADATA_REFRESH_INTERVAL_MS,\n      () => {\n        return this.updateClientMetadataAndTryBecomePrimary()\n          .then(() => this.maybeGarbageCollectMultiClientState())\n          .then(() => this.scheduleClientMetadataAndPrimaryLeaseRefreshes());\n      }\n    );\n  }\n\n  /** Checks whether `client` is the local client. */\n  private isLocalClient(client: DbPrimaryClient | null): boolean {\n    return client ? client.ownerId === this.clientId : false;\n  }\n\n  /**\n   * Evaluate the state of all active clients and determine whether the local\n   * client is or can act as the holder of the primary lease. Returns whether\n   * the client is eligible for the lease, but does not actually acquire it.\n   * May return 'false' even if there is no active leaseholder and another\n   * (foreground) client should become leaseholder instead.\n   */\n  private canActAsPrimary(\n    txn: PersistenceTransaction\n  ): PersistencePromise<boolean> {\n    if (this.forceOwningTab) {\n      return PersistencePromise.resolve<boolean>(true);\n    }\n    const store = primaryClientStore(txn);\n    return store\n      .get(DbPrimaryClient.key)\n      .next(currentPrimary => {\n        const currentLeaseIsValid =\n          currentPrimary !== null &&\n          this.isWithinAge(\n            currentPrimary.leaseTimestampMs,\n            MAX_PRIMARY_ELIGIBLE_AGE_MS\n          ) &&\n          !this.isClientZombied(currentPrimary.ownerId);\n\n        // A client is eligible for the primary lease if:\n        // - its network is enabled and the client's tab is in the foreground.\n        // - its network is enabled and no other client's tab is in the\n        //   foreground.\n        // - every clients network is disabled and the client's tab is in the\n        //   foreground.\n        // - every clients network is disabled and no other client's tab is in\n        //   the foreground.\n        // - the `forceOwningTab` setting was passed in.\n        if (currentLeaseIsValid) {\n          if (this.isLocalClient(currentPrimary) && this.networkEnabled) {\n            return true;\n          }\n\n          if (!this.isLocalClient(currentPrimary)) {\n            if (!currentPrimary!.allowTabSynchronization) {\n              // Fail the `canActAsPrimary` check if the current leaseholder has\n              // not opted into multi-tab synchronization. If this happens at\n              // client startup, we reject the Promise returned by\n              // `enablePersistence()` and the user can continue to use Firestore\n              // with in-memory persistence.\n              // If this fails during a lease refresh, we will instead block the\n              // AsyncQueue from executing further operations. Note that this is\n              // acceptable since mixing & matching different `synchronizeTabs`\n              // settings is not supported.\n              //\n              // TODO(b/114226234): Remove this check when `synchronizeTabs` can\n              // no longer be turned off.\n              throw new FirestoreError(\n                Code.FAILED_PRECONDITION,\n                PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n              );\n            }\n\n            return false;\n          }\n        }\n\n        if (this.networkEnabled && this.inForeground) {\n          return true;\n        }\n\n        return clientMetadataStore(txn)\n          .loadAll()\n          .next(existingClients => {\n            // Process all existing clients and determine whether at least one of\n            // them is better suited to obtain the primary lease.\n            const preferredCandidate = this.filterActiveClients(\n              existingClients,\n              MAX_PRIMARY_ELIGIBLE_AGE_MS\n            ).find(otherClient => {\n              if (this.clientId !== otherClient.clientId) {\n                const otherClientHasBetterNetworkState =\n                  !this.networkEnabled && otherClient.networkEnabled;\n                const otherClientHasBetterVisibility =\n                  !this.inForeground && otherClient.inForeground;\n                const otherClientHasSameNetworkState =\n                  this.networkEnabled === otherClient.networkEnabled;\n                if (\n                  otherClientHasBetterNetworkState ||\n                  (otherClientHasBetterVisibility &&\n                    otherClientHasSameNetworkState)\n                ) {\n                  return true;\n                }\n              }\n              return false;\n            });\n            return preferredCandidate === undefined;\n          });\n      })\n      .next(canActAsPrimary => {\n        if (this.isPrimary !== canActAsPrimary) {\n          logDebug(\n            LOG_TAG,\n            `Client ${\n              canActAsPrimary ? 'is' : 'is not'\n            } eligible for a primary lease.`\n          );\n        }\n        return canActAsPrimary;\n      });\n  }\n\n  async shutdown(): Promise<void> {\n    // The shutdown() operations are idempotent and can be called even when\n    // start() aborted (e.g. because it couldn't acquire the persistence lease).\n    this._started = false;\n\n    this.markClientZombied();\n    if (this.clientMetadataRefresher) {\n      this.clientMetadataRefresher.cancel();\n      this.clientMetadataRefresher = null;\n    }\n    this.detachVisibilityHandler();\n    this.detachWindowUnloadHook();\n    await this.runTransaction('shutdown', 'readwrite', txn => {\n      return this.releasePrimaryLeaseIfHeld(txn).next(() =>\n        this.removeClientMetadata(txn)\n      );\n    }).catch(e => {\n      logDebug(LOG_TAG, 'Proceeding with shutdown despite failure: ', e);\n    });\n    this.simpleDb.close();\n\n    // Remove the entry marking the client as zombied from LocalStorage since\n    // we successfully deleted its metadata from IndexedDb.\n    this.removeClientZombiedEntry();\n  }\n\n  /**\n   * Returns clients that are not zombied and have an updateTime within the\n   * provided threshold.\n   */\n  private filterActiveClients(\n    clients: DbClientMetadata[],\n    activityThresholdMs: number\n  ): DbClientMetadata[] {\n    return clients.filter(\n      client =>\n        this.isWithinAge(client.updateTimeMs, activityThresholdMs) &&\n        !this.isClientZombied(client.clientId)\n    );\n  }\n\n  /**\n   * Returns the IDs of the clients that are currently active. If multi-tab\n   * is not supported, returns an array that only contains the local client's\n   * ID.\n   *\n   * PORTING NOTE: This is only used for Web multi-tab.\n   */\n  getActiveClients(): Promise<ClientId[]> {\n    return this.runTransaction('getActiveClients', 'readonly', txn => {\n      return clientMetadataStore(txn)\n        .loadAll()\n        .next(clients =>\n          this.filterActiveClients(clients, MAX_CLIENT_AGE_MS).map(\n            clientMetadata => clientMetadata.clientId\n          )\n        );\n    });\n  }\n\n  get started(): boolean {\n    return this._started;\n  }\n\n  getMutationQueue(user: User): IndexedDbMutationQueue {\n    debugAssert(\n      this.started,\n      'Cannot initialize MutationQueue before persistence is started.'\n    );\n    return IndexedDbMutationQueue.forUser(\n      user,\n      this.serializer,\n      this.indexManager,\n      this.referenceDelegate\n    );\n  }\n\n  getTargetCache(): IndexedDbTargetCache {\n    debugAssert(\n      this.started,\n      'Cannot initialize TargetCache before persistence is started.'\n    );\n    return this.targetCache;\n  }\n\n  getRemoteDocumentCache(): IndexedDbRemoteDocumentCache {\n    debugAssert(\n      this.started,\n      'Cannot initialize RemoteDocumentCache before persistence is started.'\n    );\n    return this.remoteDocumentCache;\n  }\n\n  getIndexManager(): IndexedDbIndexManager {\n    debugAssert(\n      this.started,\n      'Cannot initialize IndexManager before persistence is started.'\n    );\n    return this.indexManager;\n  }\n\n  runTransaction<T>(\n    action: string,\n    mode: PersistenceTransactionMode,\n    transactionOperation: (\n      transaction: PersistenceTransaction\n    ) => PersistencePromise<T>\n  ): Promise<T> {\n    logDebug(LOG_TAG, 'Starting transaction:', action);\n\n    const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';\n\n    let persistenceTransaction: PersistenceTransaction;\n\n    // Do all transactions as readwrite against all object stores, since we\n    // are the only reader/writer.\n    return this.simpleDb\n      .runTransaction(simpleDbMode, ALL_STORES, simpleDbTxn => {\n        persistenceTransaction = new IndexedDbTransaction(\n          simpleDbTxn,\n          this.listenSequence\n            ? this.listenSequence.next()\n            : ListenSequence.INVALID\n        );\n\n        if (mode === 'readwrite-primary') {\n          // While we merely verify that we have (or can acquire) the lease\n          // immediately, we wait to extend the primary lease until after\n          // executing transactionOperation(). This ensures that even if the\n          // transactionOperation takes a long time, we'll use a recent\n          // leaseTimestampMs in the extended (or newly acquired) lease.\n          return this.verifyPrimaryLease(persistenceTransaction)\n            .next(holdsPrimaryLease => {\n              if (holdsPrimaryLease) {\n                return /* holdsPrimaryLease= */ true;\n              }\n              return this.canActAsPrimary(persistenceTransaction);\n            })\n            .next(holdsPrimaryLease => {\n              if (!holdsPrimaryLease) {\n                logError(\n                  `Failed to obtain primary lease for action '${action}'.`\n                );\n                this.isPrimary = false;\n                this.queue.enqueueRetryable(() =>\n                  this.primaryStateListener(false)\n                );\n                throw new FirestoreError(\n                  Code.FAILED_PRECONDITION,\n                  PRIMARY_LEASE_LOST_ERROR_MSG\n                );\n              }\n              return transactionOperation(persistenceTransaction);\n            })\n            .next(result => {\n              return this.acquireOrExtendPrimaryLease(\n                persistenceTransaction\n              ).next(() => result);\n            });\n        } else {\n          return this.verifyAllowTabSynchronization(\n            persistenceTransaction\n          ).next(() => transactionOperation(persistenceTransaction));\n        }\n      })\n      .then(result => {\n        persistenceTransaction.raiseOnCommittedEvent();\n        return result;\n      });\n  }\n\n  /**\n   * Verifies that the current tab is the primary leaseholder or alternatively\n   * that the leaseholder has opted into multi-tab synchronization.\n   */\n  // TODO(b/114226234): Remove this check when `synchronizeTabs` can no longer\n  // be turned off.\n  private verifyAllowTabSynchronization(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    const store = primaryClientStore(txn);\n    return store.get(DbPrimaryClient.key).next(currentPrimary => {\n      const currentLeaseIsValid =\n        currentPrimary !== null &&\n        this.isWithinAge(\n          currentPrimary.leaseTimestampMs,\n          MAX_PRIMARY_ELIGIBLE_AGE_MS\n        ) &&\n        !this.isClientZombied(currentPrimary.ownerId);\n\n      if (currentLeaseIsValid && !this.isLocalClient(currentPrimary)) {\n        if (\n          !this.forceOwningTab &&\n          (!this.allowTabSynchronization ||\n            !currentPrimary!.allowTabSynchronization)\n        ) {\n          throw new FirestoreError(\n            Code.FAILED_PRECONDITION,\n            PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n          );\n        }\n      }\n    });\n  }\n\n  /**\n   * Obtains or extends the new primary lease for the local client. This\n   * method does not verify that the client is eligible for this lease.\n   */\n  private acquireOrExtendPrimaryLease(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    const newPrimary = new DbPrimaryClient(\n      this.clientId,\n      this.allowTabSynchronization,\n      Date.now()\n    );\n    return primaryClientStore(txn).put(DbPrimaryClient.key, newPrimary);\n  }\n\n  static isAvailable(): boolean {\n    return SimpleDb.isAvailable();\n  }\n\n  /** Checks the primary lease and removes it if we are the current primary. */\n  private releasePrimaryLeaseIfHeld(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    const store = primaryClientStore(txn);\n    return store.get(DbPrimaryClient.key).next(primaryClient => {\n      if (this.isLocalClient(primaryClient)) {\n        logDebug(LOG_TAG, 'Releasing primary lease.');\n        return store.delete(DbPrimaryClient.key);\n      } else {\n        return PersistencePromise.resolve();\n      }\n    });\n  }\n\n  /** Verifies that `updateTimeMs` is within `maxAgeMs`. */\n  private isWithinAge(updateTimeMs: number, maxAgeMs: number): boolean {\n    const now = Date.now();\n    const minAcceptable = now - maxAgeMs;\n    const maxAcceptable = now;\n    if (updateTimeMs < minAcceptable) {\n      return false;\n    } else if (updateTimeMs > maxAcceptable) {\n      logError(\n        `Detected an update time that is in the future: ${updateTimeMs} > ${maxAcceptable}`\n      );\n      return false;\n    }\n\n    return true;\n  }\n\n  private attachVisibilityHandler(): void {\n    if (\n      this.document !== null &&\n      typeof this.document.addEventListener === 'function'\n    ) {\n      this.documentVisibilityHandler = () => {\n        this.queue.enqueueAndForget(() => {\n          this.inForeground = this.document!.visibilityState === 'visible';\n          return this.updateClientMetadataAndTryBecomePrimary();\n        });\n      };\n\n      this.document.addEventListener(\n        'visibilitychange',\n        this.documentVisibilityHandler\n      );\n\n      this.inForeground = this.document.visibilityState === 'visible';\n    }\n  }\n\n  private detachVisibilityHandler(): void {\n    if (this.documentVisibilityHandler) {\n      debugAssert(\n        this.document !== null &&\n          typeof this.document.addEventListener === 'function',\n        \"Expected 'document.addEventListener' to be a function\"\n      );\n      this.document.removeEventListener(\n        'visibilitychange',\n        this.documentVisibilityHandler\n      );\n      this.documentVisibilityHandler = null;\n    }\n  }\n\n  /**\n   * Attaches a window.unload handler that will synchronously write our\n   * clientId to a \"zombie client id\" location in LocalStorage. This can be used\n   * by tabs trying to acquire the primary lease to determine that the lease\n   * is no longer valid even if the timestamp is recent. This is particularly\n   * important for the refresh case (so the tab correctly re-acquires the\n   * primary lease). LocalStorage is used for this rather than IndexedDb because\n   * it is a synchronous API and so can be used reliably from  an unload\n   * handler.\n   */\n  private attachWindowUnloadHook(): void {\n    if (typeof this.window?.addEventListener === 'function') {\n      this.windowUnloadHandler = () => {\n        // Note: In theory, this should be scheduled on the AsyncQueue since it\n        // accesses internal state. We execute this code directly during shutdown\n        // to make sure it gets a chance to run.\n        this.markClientZombied();\n\n        this.queue.enqueueAndForget(() => {\n          // Attempt graceful shutdown (including releasing our primary lease),\n          // but there's no guarantee it will complete.\n          return this.shutdown();\n        });\n      };\n      this.window.addEventListener('unload', this.windowUnloadHandler);\n    }\n  }\n\n  private detachWindowUnloadHook(): void {\n    if (this.windowUnloadHandler) {\n      debugAssert(\n        typeof this.window?.removeEventListener === 'function',\n        \"Expected 'window.removeEventListener' to be a function\"\n      );\n      this.window!.removeEventListener('unload', this.windowUnloadHandler);\n      this.windowUnloadHandler = null;\n    }\n  }\n\n  /**\n   * Returns whether a client is \"zombied\" based on its LocalStorage entry.\n   * Clients become zombied when their tab closes without running all of the\n   * cleanup logic in `shutdown()`.\n   */\n  private isClientZombied(clientId: ClientId): boolean {\n    try {\n      const isZombied =\n        this.webStorage?.getItem(\n          this.zombiedClientLocalStorageKey(clientId)\n        ) !== null;\n      logDebug(\n        LOG_TAG,\n        `Client '${clientId}' ${\n          isZombied ? 'is' : 'is not'\n        } zombied in LocalStorage`\n      );\n      return isZombied;\n    } catch (e) {\n      // Gracefully handle if LocalStorage isn't working.\n      logError(LOG_TAG, 'Failed to get zombied client id.', e);\n      return false;\n    }\n  }\n\n  /**\n   * Record client as zombied (a client that had its tab closed). Zombied\n   * clients are ignored during primary tab selection.\n   */\n  private markClientZombied(): void {\n    if (!this.webStorage) {\n      return;\n    }\n    try {\n      this.webStorage.setItem(\n        this.zombiedClientLocalStorageKey(this.clientId),\n        String(Date.now())\n      );\n    } catch (e) {\n      // Gracefully handle if LocalStorage isn't available / working.\n      logError('Failed to set zombie client id.', e);\n    }\n  }\n\n  /** Removes the zombied client entry if it exists. */\n  private removeClientZombiedEntry(): void {\n    if (!this.webStorage) {\n      return;\n    }\n    try {\n      this.webStorage.removeItem(\n        this.zombiedClientLocalStorageKey(this.clientId)\n      );\n    } catch (e) {\n      // Ignore\n    }\n  }\n\n  private zombiedClientLocalStorageKey(clientId: ClientId): string {\n    return `${ZOMBIED_CLIENTS_KEY_PREFIX}_${this.persistenceKey}_${clientId}`;\n  }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the primary client object store.\n */\nfunction primaryClientStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbPrimaryClientKey, DbPrimaryClient> {\n  return IndexedDbPersistence.getStore<DbPrimaryClientKey, DbPrimaryClient>(\n    txn,\n    DbPrimaryClient.store\n  );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the client metadata object store.\n */\nfunction clientMetadataStore(\n  txn: PersistenceTransaction\n): SimpleDbStore<DbClientMetadataKey, DbClientMetadata> {\n  return IndexedDbPersistence.getStore<DbClientMetadataKey, DbClientMetadata>(\n    txn,\n    DbClientMetadata.store\n  );\n}\n\n/** Provides LRU functionality for IndexedDB persistence. */\nexport class IndexedDbLruDelegate implements ReferenceDelegate, LruDelegate {\n  readonly garbageCollector: LruGarbageCollector;\n\n  constructor(private readonly db: IndexedDbPersistence, params: LruParams) {\n    this.garbageCollector = new LruGarbageCollector(this, params);\n  }\n\n  getSequenceNumberCount(\n    txn: PersistenceTransaction\n  ): PersistencePromise<number> {\n    const docCountPromise = this.orphanedDocumentCount(txn);\n    const targetCountPromise = this.db.getTargetCache().getTargetCount(txn);\n    return targetCountPromise.next(targetCount =>\n      docCountPromise.next(docCount => targetCount + docCount)\n    );\n  }\n\n  private orphanedDocumentCount(\n    txn: PersistenceTransaction\n  ): PersistencePromise<number> {\n    let orphanedCount = 0;\n    return this.forEachOrphanedDocumentSequenceNumber(txn, _ => {\n      orphanedCount++;\n    }).next(() => orphanedCount);\n  }\n\n  forEachTarget(\n    txn: PersistenceTransaction,\n    f: (q: TargetData) => void\n  ): PersistencePromise<void> {\n    return this.db.getTargetCache().forEachTarget(txn, f);\n  }\n\n  forEachOrphanedDocumentSequenceNumber(\n    txn: PersistenceTransaction,\n    f: (sequenceNumber: ListenSequenceNumber) => void\n  ): PersistencePromise<void> {\n    return this.forEachOrphanedDocument(txn, (docKey, sequenceNumber) =>\n      f(sequenceNumber)\n    );\n  }\n\n  addReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    return writeSentinelKey(txn, key);\n  }\n\n  removeReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    return writeSentinelKey(txn, key);\n  }\n\n  removeTargets(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number> {\n    return this.db\n      .getTargetCache()\n      .removeTargets(txn, upperBound, activeTargetIds);\n  }\n\n  markPotentiallyOrphaned(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    return writeSentinelKey(txn, key);\n  }\n\n  /**\n   * Returns true if anything would prevent this document from being garbage\n   * collected, given that the document in question is not present in any\n   * targets and has a sequence number less than or equal to the upper bound for\n   * the collection run.\n   */\n  private isPinned(\n    txn: PersistenceTransaction,\n    docKey: DocumentKey\n  ): PersistencePromise<boolean> {\n    return mutationQueuesContainKey(txn, docKey);\n  }\n\n  removeOrphanedDocuments(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber\n  ): PersistencePromise<number> {\n    const documentCache = this.db.getRemoteDocumentCache();\n    const changeBuffer = documentCache.newChangeBuffer();\n\n    const promises: Array<PersistencePromise<void>> = [];\n    let documentCount = 0;\n\n    const iteration = this.forEachOrphanedDocument(\n      txn,\n      (docKey, sequenceNumber) => {\n        if (sequenceNumber <= upperBound) {\n          const p = this.isPinned(txn, docKey).next(isPinned => {\n            if (!isPinned) {\n              documentCount++;\n              // Our size accounting requires us to read all documents before\n              // removing them.\n              return changeBuffer.getEntry(txn, docKey).next(() => {\n                changeBuffer.removeEntry(docKey);\n                return documentTargetStore(txn).delete(sentinelKey(docKey));\n              });\n            }\n          });\n          promises.push(p);\n        }\n      }\n    );\n\n    return iteration\n      .next(() => PersistencePromise.waitFor(promises))\n      .next(() => changeBuffer.apply(txn))\n      .next(() => documentCount);\n  }\n\n  removeTarget(\n    txn: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    const updated = targetData.withSequenceNumber(txn.currentSequenceNumber);\n    return this.db.getTargetCache().updateTargetData(txn, updated);\n  }\n\n  updateLimboDocument(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    return writeSentinelKey(txn, key);\n  }\n\n  /**\n   * Call provided function for each document in the cache that is 'orphaned'. Orphaned\n   * means not a part of any target, so the only entry in the target-document index for\n   * that document will be the sentinel row (targetId 0), which will also have the sequence\n   * number for the last time the document was accessed.\n   */\n  private forEachOrphanedDocument(\n    txn: PersistenceTransaction,\n    f: (docKey: DocumentKey, sequenceNumber: ListenSequenceNumber) => void\n  ): PersistencePromise<void> {\n    const store = documentTargetStore(txn);\n    let nextToReport: ListenSequenceNumber = ListenSequence.INVALID;\n    let nextPath: EncodedResourcePath;\n    return store\n      .iterate(\n        {\n          index: DbTargetDocument.documentTargetsIndex\n        },\n        ([targetId, docKey], { path, sequenceNumber }) => {\n          if (targetId === 0) {\n            // if nextToReport is valid, report it, this is a new key so the\n            // last one must not be a member of any targets.\n            if (nextToReport !== ListenSequence.INVALID) {\n              f(new DocumentKey(decodeResourcePath(nextPath)), nextToReport);\n            }\n            // set nextToReport to be this sequence number. It's the next one we\n            // might report, if we don't find any targets for this document.\n            // Note that the sequence number must be defined when the targetId\n            // is 0.\n            nextToReport = sequenceNumber!;\n            nextPath = path;\n          } else {\n            // set nextToReport to be invalid, we know we don't need to report\n            // this one since we found a target for it.\n            nextToReport = ListenSequence.INVALID;\n          }\n        }\n      )\n      .next(() => {\n        // Since we report sequence numbers after getting to the next key, we\n        // need to check if the last key we iterated over was an orphaned\n        // document and report it.\n        if (nextToReport !== ListenSequence.INVALID) {\n          f(new DocumentKey(decodeResourcePath(nextPath)), nextToReport);\n        }\n      });\n  }\n\n  getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n    return this.db.getRemoteDocumentCache().getSize(txn);\n  }\n}\n\nfunction sentinelKey(key: DocumentKey): [TargetId, EncodedResourcePath] {\n  return [0, encodeResourcePath(key.path)];\n}\n\n/**\n * @return A value suitable for writing a sentinel row in the target-document\n * store.\n */\nfunction sentinelRow(\n  key: DocumentKey,\n  sequenceNumber: ListenSequenceNumber\n): DbTargetDocument {\n  return new DbTargetDocument(0, encodeResourcePath(key.path), sequenceNumber);\n}\n\nfunction writeSentinelKey(\n  txn: PersistenceTransaction,\n  key: DocumentKey\n): PersistencePromise<void> {\n  return documentTargetStore(txn).put(\n    sentinelRow(key, txn.currentSequenceNumber)\n  );\n}\n\n/**\n * Generates a string used as a prefix when storing data in IndexedDB and\n * LocalStorage.\n */\nexport function indexedDbStoragePrefix(\n  databaseId: DatabaseId,\n  persistenceKey: string\n): string {\n  // Use two different prefix formats:\n  //\n  //   * firestore / persistenceKey / projectID . databaseID / ...\n  //   * firestore / persistenceKey / projectID / ...\n  //\n  // projectIDs are DNS-compatible names and cannot contain dots\n  // so there's no danger of collisions.\n  let database = databaseId.projectId;\n  if (!databaseId.isDefaultDatabase) {\n    database += '.' + databaseId.database;\n  }\n\n  return 'firestore/' + persistenceKey + '/' + database + '/';\n}\n\nexport async function indexedDbClearPersistence(\n  persistenceKey: string\n): Promise<void> {\n  if (!SimpleDb.isAvailable()) {\n    return Promise.resolve();\n  }\n  const dbName = persistenceKey + MAIN_DATABASE;\n  await SimpleDb.delete(dbName);\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 { Timestamp } from '../api/timestamp';\nimport { User } from '../auth/user';\nimport { Query, queryToTarget } from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { canonifyTarget, Target, targetEquals } from '../core/target';\nimport { BatchId, TargetId } from '../core/types';\nimport {\n  DocumentKeySet,\n  documentKeySet,\n  DocumentMap,\n  maybeDocumentMap,\n  MaybeDocumentMap\n} from '../model/collections';\nimport { MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport {\n  Mutation,\n  PatchMutation,\n  Precondition,\n  extractMutationBaseValue\n} from '../model/mutation';\nimport {\n  BATCHID_UNKNOWN,\n  MutationBatch,\n  MutationBatchResult\n} from '../model/mutation_batch';\nimport { RemoteEvent, TargetChange } from '../remote/remote_event';\nimport { debugAssert, debugCast, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { LocalDocumentsView } from './local_documents_view';\nimport { LocalViewChanges } from './local_view_changes';\nimport { LruGarbageCollector, LruResults } from './lru_garbage_collector';\nimport { MutationQueue } from './mutation_queue';\nimport {\n  Persistence,\n  PersistenceTransaction,\n  PRIMARY_LEASE_LOST_ERROR_MSG\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { QueryEngine } from './query_engine';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\nimport { ClientId } from './shared_client_state';\nimport { TargetData, TargetPurpose } from './target_data';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport { IndexedDbMutationQueue } from './indexeddb_mutation_queue';\nimport { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';\nimport { IndexedDbTargetCache } from './indexeddb_target_cache';\nimport { extractFieldMask } from '../model/object_value';\nimport { isIndexedDbTransactionError } from './simple_db';\n\nconst LOG_TAG = 'LocalStore';\n\n/** The result of a write to the local store. */\nexport interface LocalWriteResult {\n  batchId: BatchId;\n  changes: MaybeDocumentMap;\n}\n\n/** The result of a user-change operation in the local store. */\nexport interface UserChangeResult {\n  readonly affectedDocuments: MaybeDocumentMap;\n  readonly removedBatchIds: BatchId[];\n  readonly addedBatchIds: BatchId[];\n}\n\n/** The result of executing a query against the local store. */\nexport interface QueryResult {\n  readonly documents: DocumentMap;\n  readonly remoteKeys: DocumentKeySet;\n}\n\n/**\n * Local storage in the Firestore client. Coordinates persistence components\n * like the mutation queue and remote document cache to present a\n * latency-compensated view of stored data.\n *\n * The LocalStore is responsible for accepting mutations from the Sync Engine.\n * Writes from the client are put into a queue as provisional Mutations until\n * they are processed by the RemoteStore and confirmed as having been written\n * to the server.\n *\n * The local store provides the local version of documents that have been\n * modified locally. It maintains the constraint:\n *\n *   LocalDocument = RemoteDocument + Active(LocalMutations)\n *\n * (Active mutations are those that are enqueued and have not been previously\n * acknowledged or rejected).\n *\n * The RemoteDocument (\"ground truth\") state is provided via the\n * applyChangeBatch method. It will be some version of a server-provided\n * document OR will be a server-provided document PLUS acknowledged mutations:\n *\n *   RemoteDocument' = RemoteDocument + Acknowledged(LocalMutations)\n *\n * Note that this \"dirty\" version of a RemoteDocument will not be identical to a\n * server base version, since it has LocalMutations added to it pending getting\n * an authoritative copy from the server.\n *\n * Since LocalMutations can be rejected by the server, we have to be able to\n * revert a LocalMutation that has already been applied to the LocalDocument\n * (typically done by replaying all remaining LocalMutations to the\n * RemoteDocument to re-apply).\n *\n * The LocalStore is responsible for the garbage collection of the documents it\n * contains. For now, it every doc referenced by a view, the mutation queue, or\n * the RemoteStore.\n *\n * It also maintains the persistence of mapping queries to resume tokens and\n * target ids. It needs to know this data about queries to properly know what\n * docs it would be allowed to garbage collect.\n *\n * The LocalStore must be able to efficiently execute queries against its local\n * cache of the documents, to provide the initial set of results before any\n * remote changes have been received.\n *\n * Note: In TypeScript, most methods return Promises since the implementation\n * may rely on fetching data from IndexedDB which is async.\n * These Promises will only be rejected on an I/O error or other internal\n * (unexpected) failure (e.g. failed assert) and always represent an\n * unrecoverable error (should be caught / reported by the async_queue).\n */\nexport interface LocalStore {\n  /**\n   * Tells the LocalStore that the currently authenticated user has changed.\n   *\n   * In response the local store switches the mutation queue to the new user and\n   * returns any resulting document changes.\n   */\n  // PORTING NOTE: Android and iOS only return the documents affected by the\n  // change.\n  handleUserChange(user: User): Promise<UserChangeResult>;\n\n  /* Accept locally generated Mutations and commit them to storage. */\n  localWrite(mutations: Mutation[]): Promise<LocalWriteResult>;\n\n  /**\n   * Acknowledge the given batch.\n   *\n   * On the happy path when a batch is acknowledged, the local store will\n   *\n   *  + remove the batch from the mutation queue;\n   *  + apply the changes to the remote document cache;\n   *  + recalculate the latency compensated view implied by those changes (there\n   *    may be mutations in the queue that affect the documents but haven't been\n   *    acknowledged yet); and\n   *  + give the changed documents back the sync engine\n   *\n   * @returns The resulting (modified) documents.\n   */\n  acknowledgeBatch(batchResult: MutationBatchResult): Promise<MaybeDocumentMap>;\n\n  /**\n   * Remove mutations from the MutationQueue for the specified batch;\n   * LocalDocuments will be recalculated.\n   *\n   * @returns The resulting modified documents.\n   */\n  rejectBatch(batchId: BatchId): Promise<MaybeDocumentMap>;\n\n  /**\n   * Returns the largest (latest) batch id in mutation queue that is pending\n   * server response.\n   *\n   * Returns `BATCHID_UNKNOWN` if the queue is empty.\n   */\n  getHighestUnacknowledgedBatchId(): Promise<BatchId>;\n\n  /**\n   * Returns the last consistent snapshot processed (used by the RemoteStore to\n   * determine whether to buffer incoming snapshots from the backend).\n   */\n  getLastRemoteSnapshotVersion(): Promise<SnapshotVersion>;\n\n  /**\n   * Update the \"ground-state\" (remote) documents. We assume that the remote\n   * event reflects any write batches that have been acknowledged or rejected\n   * (i.e. we do not re-apply local mutations to updates from this event).\n   *\n   * LocalDocuments are re-calculated if there are remaining mutations in the\n   * queue.\n   */\n  applyRemoteEvent(remoteEvent: RemoteEvent): Promise<MaybeDocumentMap>;\n\n  /**\n   * Notify local store of the changed views to locally pin documents.\n   */\n  notifyLocalViewChanges(viewChanges: LocalViewChanges[]): Promise<void>;\n\n  /**\n   * Gets the mutation batch after the passed in batchId in the mutation queue\n   * or null if empty.\n   * @param afterBatchId If provided, the batch to search after.\n   * @returns The next mutation or null if there wasn't one.\n   */\n  nextMutationBatch(afterBatchId?: BatchId): Promise<MutationBatch | null>;\n\n  /**\n   * Read the current value of a Document with a given key or null if not\n   * found - used for testing.\n   */\n  readDocument(key: DocumentKey): Promise<MaybeDocument | null>;\n\n  /**\n   * Assigns the given target an internal ID so that its results can be pinned so\n   * they don't get GC'd. A target must be allocated in the local store before\n   * the store can be used to manage its view.\n   *\n   * Allocating an already allocated `Target` will return the existing `TargetData`\n   * for that `Target`.\n   */\n  allocateTarget(target: Target): Promise<TargetData>;\n\n  /**\n   * Returns the TargetData as seen by the LocalStore, including updates that may\n   * have not yet been persisted to the TargetCache.\n   */\n  // Visible for testing.\n  getTargetData(\n    transaction: PersistenceTransaction,\n    target: Target\n  ): PersistencePromise<TargetData | null>;\n\n  /**\n   * Unpin all the documents associated with the given target. If\n   * `keepPersistedTargetData` is set to false and Eager GC enabled, the method\n   * directly removes the associated target data from the target cache.\n   *\n   * Releasing a non-existing `Target` is a no-op.\n   */\n  // PORTING NOTE: `keepPersistedTargetData` is multi-tab only.\n  releaseTarget(\n    targetId: number,\n    keepPersistedTargetData: boolean\n  ): Promise<void>;\n\n  /**\n   * Runs the specified query against the local store and returns the results,\n   * potentially taking advantage of query data from previous executions (such\n   * as the set of remote keys).\n   *\n   * @param usePreviousResults Whether results from previous executions can\n   * be used to optimize this query execution.\n   */\n  executeQuery(query: Query, usePreviousResults: boolean): Promise<QueryResult>;\n\n  collectGarbage(garbageCollector: LruGarbageCollector): Promise<LruResults>;\n}\n\n/**\n * Implements `LocalStore` interface.\n *\n * Note: some field defined in this class might have public access level, but\n * the class is not exported so they are only accessible from this module.\n * This is useful to implement optional features (like bundles) in free\n * functions, such that they are tree-shakeable.\n */\nclass LocalStoreImpl implements LocalStore {\n  /**\n   * The maximum time to leave a resume token buffered without writing it out.\n   * This value is arbitrary: it's long enough to avoid several writes\n   * (possibly indefinitely if updates come more frequently than this) but\n   * short enough that restarting after crashing will still have a pretty\n   * recent resume token.\n   */\n  private static readonly RESUME_TOKEN_MAX_AGE_MICROS = 5 * 60 * 1e6;\n\n  /**\n   * The set of all mutations that have been sent but not yet been applied to\n   * the backend.\n   */\n  mutationQueue: MutationQueue;\n\n  /** The set of all cached remote documents. */\n  remoteDocuments: RemoteDocumentCache;\n\n  /**\n   * The \"local\" view of all documents (layering mutationQueue on top of\n   * remoteDocumentCache).\n   */\n  localDocuments: LocalDocumentsView;\n\n  /** Maps a target to its `TargetData`. */\n  targetCache: TargetCache;\n\n  /**\n   * Maps a targetID to data about its target.\n   *\n   * PORTING NOTE: We are using an immutable data structure on Web to make re-runs\n   * of `applyRemoteEvent()` idempotent.\n   */\n  targetDataByTarget = new SortedMap<TargetId, TargetData>(primitiveComparator);\n\n  /** Maps a target to its targetID. */\n  // TODO(wuandy): Evaluate if TargetId can be part of Target.\n  private targetIdByTarget = new ObjectMap<Target, TargetId>(\n    t => canonifyTarget(t),\n    targetEquals\n  );\n\n  /**\n   * The read time of the last entry processed by `getNewDocumentChanges()`.\n   *\n   * PORTING NOTE: This is only used for multi-tab synchronization.\n   */\n  lastDocumentChangeReadTime = SnapshotVersion.min();\n\n  constructor(\n    /** Manages our in-memory or durable persistence. */\n    readonly persistence: Persistence,\n    private queryEngine: QueryEngine,\n    initialUser: User\n  ) {\n    debugAssert(\n      persistence.started,\n      'LocalStore was passed an unstarted persistence implementation'\n    );\n    this.mutationQueue = persistence.getMutationQueue(initialUser);\n    this.remoteDocuments = persistence.getRemoteDocumentCache();\n    this.targetCache = persistence.getTargetCache();\n    this.localDocuments = new LocalDocumentsView(\n      this.remoteDocuments,\n      this.mutationQueue,\n      this.persistence.getIndexManager()\n    );\n    this.queryEngine.setLocalDocumentsView(this.localDocuments);\n  }\n\n  async handleUserChange(user: User): Promise<UserChangeResult> {\n    let newMutationQueue = this.mutationQueue;\n    let newLocalDocuments = this.localDocuments;\n\n    const result = await this.persistence.runTransaction(\n      'Handle user change',\n      'readonly',\n      txn => {\n        // Swap out the mutation queue, grabbing the pending mutation batches\n        // before and after.\n        let oldBatches: MutationBatch[];\n        return this.mutationQueue\n          .getAllMutationBatches(txn)\n          .next(promisedOldBatches => {\n            oldBatches = promisedOldBatches;\n\n            newMutationQueue = this.persistence.getMutationQueue(user);\n\n            // Recreate our LocalDocumentsView using the new\n            // MutationQueue.\n            newLocalDocuments = new LocalDocumentsView(\n              this.remoteDocuments,\n              newMutationQueue,\n              this.persistence.getIndexManager()\n            );\n            return newMutationQueue.getAllMutationBatches(txn);\n          })\n          .next(newBatches => {\n            const removedBatchIds: BatchId[] = [];\n            const addedBatchIds: BatchId[] = [];\n\n            // Union the old/new changed keys.\n            let changedKeys = documentKeySet();\n\n            for (const batch of oldBatches) {\n              removedBatchIds.push(batch.batchId);\n              for (const mutation of batch.mutations) {\n                changedKeys = changedKeys.add(mutation.key);\n              }\n            }\n\n            for (const batch of newBatches) {\n              addedBatchIds.push(batch.batchId);\n              for (const mutation of batch.mutations) {\n                changedKeys = changedKeys.add(mutation.key);\n              }\n            }\n\n            // Return the set of all (potentially) changed documents and the list\n            // of mutation batch IDs that were affected by change.\n            return newLocalDocuments\n              .getDocuments(txn, changedKeys)\n              .next(affectedDocuments => {\n                return {\n                  affectedDocuments,\n                  removedBatchIds,\n                  addedBatchIds\n                };\n              });\n          });\n      }\n    );\n\n    this.mutationQueue = newMutationQueue;\n    this.localDocuments = newLocalDocuments;\n    this.queryEngine.setLocalDocumentsView(this.localDocuments);\n\n    return result;\n  }\n\n  localWrite(mutations: Mutation[]): Promise<LocalWriteResult> {\n    const localWriteTime = Timestamp.now();\n    const keys = mutations.reduce(\n      (keys, m) => keys.add(m.key),\n      documentKeySet()\n    );\n\n    let existingDocs: MaybeDocumentMap;\n\n    return this.persistence\n      .runTransaction('Locally write mutations', 'readwrite', txn => {\n        // Load and apply all existing mutations. This lets us compute the\n        // current base state for all non-idempotent transforms before applying\n        // any additional user-provided writes.\n        return this.localDocuments.getDocuments(txn, keys).next(docs => {\n          existingDocs = docs;\n\n          // For non-idempotent mutations (such as `FieldValue.increment()`),\n          // we record the base state in a separate patch mutation. This is\n          // later used to guarantee consistent values and prevents flicker\n          // even if the backend sends us an update that already includes our\n          // transform.\n          const baseMutations: Mutation[] = [];\n\n          for (const mutation of mutations) {\n            const baseValue = extractMutationBaseValue(\n              mutation,\n              existingDocs.get(mutation.key)\n            );\n            if (baseValue != null) {\n              // NOTE: The base state should only be applied if there's some\n              // existing document to override, so use a Precondition of\n              // exists=true\n              baseMutations.push(\n                new PatchMutation(\n                  mutation.key,\n                  baseValue,\n                  extractFieldMask(baseValue.proto.mapValue!),\n                  Precondition.exists(true)\n                )\n              );\n            }\n          }\n\n          return this.mutationQueue.addMutationBatch(\n            txn,\n            localWriteTime,\n            baseMutations,\n            mutations\n          );\n        });\n      })\n      .then(batch => {\n        const changes = batch.applyToLocalDocumentSet(existingDocs);\n        return { batchId: batch.batchId, changes };\n      });\n  }\n\n  acknowledgeBatch(\n    batchResult: MutationBatchResult\n  ): Promise<MaybeDocumentMap> {\n    return this.persistence.runTransaction(\n      'Acknowledge batch',\n      'readwrite-primary',\n      txn => {\n        const affected = batchResult.batch.keys();\n        const documentBuffer = this.remoteDocuments.newChangeBuffer({\n          trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`\n        });\n        return this.applyWriteToRemoteDocuments(\n          txn,\n          batchResult,\n          documentBuffer\n        )\n          .next(() => documentBuffer.apply(txn))\n          .next(() => this.mutationQueue.performConsistencyCheck(txn))\n          .next(() => this.localDocuments.getDocuments(txn, affected));\n      }\n    );\n  }\n\n  rejectBatch(batchId: BatchId): Promise<MaybeDocumentMap> {\n    return this.persistence.runTransaction(\n      'Reject batch',\n      'readwrite-primary',\n      txn => {\n        let affectedKeys: DocumentKeySet;\n        return this.mutationQueue\n          .lookupMutationBatch(txn, batchId)\n          .next((batch: MutationBatch | null) => {\n            hardAssert(batch !== null, 'Attempt to reject nonexistent batch!');\n            affectedKeys = batch.keys();\n            return this.mutationQueue.removeMutationBatch(txn, batch);\n          })\n          .next(() => {\n            return this.mutationQueue.performConsistencyCheck(txn);\n          })\n          .next(() => {\n            return this.localDocuments.getDocuments(txn, affectedKeys);\n          });\n      }\n    );\n  }\n\n  getHighestUnacknowledgedBatchId(): Promise<BatchId> {\n    return this.persistence.runTransaction(\n      'Get highest unacknowledged batch id',\n      'readonly',\n      txn => {\n        return this.mutationQueue.getHighestUnacknowledgedBatchId(txn);\n      }\n    );\n  }\n\n  getLastRemoteSnapshotVersion(): Promise<SnapshotVersion> {\n    return this.persistence.runTransaction(\n      'Get last remote snapshot version',\n      'readonly',\n      txn => this.targetCache.getLastRemoteSnapshotVersion(txn)\n    );\n  }\n\n  applyRemoteEvent(remoteEvent: RemoteEvent): Promise<MaybeDocumentMap> {\n    const remoteVersion = remoteEvent.snapshotVersion;\n    let newTargetDataByTargetMap = this.targetDataByTarget;\n\n    return this.persistence\n      .runTransaction('Apply remote event', 'readwrite-primary', txn => {\n        const documentBuffer = this.remoteDocuments.newChangeBuffer({\n          trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`\n        });\n\n        // Reset newTargetDataByTargetMap in case this transaction gets re-run.\n        newTargetDataByTargetMap = this.targetDataByTarget;\n\n        const promises = [] as Array<PersistencePromise<void>>;\n        remoteEvent.targetChanges.forEach((change, targetId) => {\n          const oldTargetData = newTargetDataByTargetMap.get(targetId);\n          if (!oldTargetData) {\n            return;\n          }\n\n          // Only update the remote keys if the target is still active. This\n          // ensures that we can persist the updated target data along with\n          // the updated assignment.\n          promises.push(\n            this.targetCache\n              .removeMatchingKeys(txn, change.removedDocuments, targetId)\n              .next(() => {\n                return this.targetCache.addMatchingKeys(\n                  txn,\n                  change.addedDocuments,\n                  targetId\n                );\n              })\n          );\n\n          const resumeToken = change.resumeToken;\n          // Update the resume token if the change includes one.\n          if (resumeToken.approximateByteSize() > 0) {\n            const newTargetData = oldTargetData\n              .withResumeToken(resumeToken, remoteVersion)\n              .withSequenceNumber(txn.currentSequenceNumber);\n            newTargetDataByTargetMap = newTargetDataByTargetMap.insert(\n              targetId,\n              newTargetData\n            );\n\n            // Update the target data if there are target changes (or if\n            // sufficient time has passed since the last update).\n            if (\n              LocalStoreImpl.shouldPersistTargetData(\n                oldTargetData,\n                newTargetData,\n                change\n              )\n            ) {\n              promises.push(\n                this.targetCache.updateTargetData(txn, newTargetData)\n              );\n            }\n          }\n        });\n\n        let changedDocs = maybeDocumentMap();\n        let updatedKeys = documentKeySet();\n        remoteEvent.documentUpdates.forEach((key, doc) => {\n          updatedKeys = updatedKeys.add(key);\n        });\n\n        // Each loop iteration only affects its \"own\" doc, so it's safe to get all the remote\n        // documents in advance in a single call.\n        promises.push(\n          documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {\n            remoteEvent.documentUpdates.forEach((key, doc) => {\n              const existingDoc = existingDocs.get(key);\n\n              // Note: The order of the steps below is important, since we want\n              // to ensure that rejected limbo resolutions (which fabricate\n              // NoDocuments with SnapshotVersion.min()) never add documents to\n              // cache.\n              if (\n                doc instanceof NoDocument &&\n                doc.version.isEqual(SnapshotVersion.min())\n              ) {\n                // NoDocuments with SnapshotVersion.min() are used in manufactured\n                // events. We remove these documents from cache since we lost\n                // access.\n                documentBuffer.removeEntry(key, remoteVersion);\n                changedDocs = changedDocs.insert(key, doc);\n              } else if (\n                existingDoc == null ||\n                doc.version.compareTo(existingDoc.version) > 0 ||\n                (doc.version.compareTo(existingDoc.version) === 0 &&\n                  existingDoc.hasPendingWrites)\n              ) {\n                debugAssert(\n                  !SnapshotVersion.min().isEqual(remoteVersion),\n                  'Cannot add a document when the remote version is zero'\n                );\n                documentBuffer.addEntry(doc, remoteVersion);\n                changedDocs = changedDocs.insert(key, doc);\n              } else {\n                logDebug(\n                  LOG_TAG,\n                  'Ignoring outdated watch update for ',\n                  key,\n                  '. Current version:',\n                  existingDoc.version,\n                  ' Watch version:',\n                  doc.version\n                );\n              }\n\n              if (remoteEvent.resolvedLimboDocuments.has(key)) {\n                promises.push(\n                  this.persistence.referenceDelegate.updateLimboDocument(\n                    txn,\n                    key\n                  )\n                );\n              }\n            });\n          })\n        );\n\n        // HACK: The only reason we allow a null snapshot version is so that we\n        // can synthesize remote events when we get permission denied errors while\n        // trying to resolve the state of a locally cached document that is in\n        // limbo.\n        if (!remoteVersion.isEqual(SnapshotVersion.min())) {\n          const updateRemoteVersion = this.targetCache\n            .getLastRemoteSnapshotVersion(txn)\n            .next(lastRemoteSnapshotVersion => {\n              debugAssert(\n                remoteVersion.compareTo(lastRemoteSnapshotVersion) >= 0,\n                'Watch stream reverted to previous snapshot?? ' +\n                  remoteVersion +\n                  ' < ' +\n                  lastRemoteSnapshotVersion\n              );\n              return this.targetCache.setTargetsMetadata(\n                txn,\n                txn.currentSequenceNumber,\n                remoteVersion\n              );\n            });\n          promises.push(updateRemoteVersion);\n        }\n\n        return PersistencePromise.waitFor(promises)\n          .next(() => documentBuffer.apply(txn))\n          .next(() => {\n            return this.localDocuments.getLocalViewOfDocuments(\n              txn,\n              changedDocs\n            );\n          });\n      })\n      .then(changedDocs => {\n        this.targetDataByTarget = newTargetDataByTargetMap;\n        return changedDocs;\n      });\n  }\n\n  /**\n   * Returns true if the newTargetData should be persisted during an update of\n   * an active target. TargetData should always be persisted when a target is\n   * being released and should not call this function.\n   *\n   * While the target is active, TargetData updates can be omitted when nothing\n   * about the target has changed except metadata like the resume token or\n   * snapshot version. Occasionally it's worth the extra write to prevent these\n   * values from getting too stale after a crash, but this doesn't have to be\n   * too frequent.\n   */\n  private static shouldPersistTargetData(\n    oldTargetData: TargetData,\n    newTargetData: TargetData,\n    change: TargetChange\n  ): boolean {\n    hardAssert(\n      newTargetData.resumeToken.approximateByteSize() > 0,\n      'Attempted to persist target data with no resume token'\n    );\n\n    // Always persist target data if we don't already have a resume token.\n    if (oldTargetData.resumeToken.approximateByteSize() === 0) {\n      return true;\n    }\n\n    // Don't allow resume token changes to be buffered indefinitely. This\n    // allows us to be reasonably up-to-date after a crash and avoids needing\n    // to loop over all active queries on shutdown. Especially in the browser\n    // we may not get time to do anything interesting while the current tab is\n    // closing.\n    const timeDelta =\n      newTargetData.snapshotVersion.toMicroseconds() -\n      oldTargetData.snapshotVersion.toMicroseconds();\n    if (timeDelta >= this.RESUME_TOKEN_MAX_AGE_MICROS) {\n      return true;\n    }\n\n    // Otherwise if the only thing that has changed about a target is its resume\n    // token it's not worth persisting. Note that the RemoteStore keeps an\n    // in-memory view of the currently active targets which includes the current\n    // resume token, so stream failure or user changes will still use an\n    // up-to-date resume token regardless of what we do here.\n    const changes =\n      change.addedDocuments.size +\n      change.modifiedDocuments.size +\n      change.removedDocuments.size;\n    return changes > 0;\n  }\n\n  async notifyLocalViewChanges(viewChanges: LocalViewChanges[]): Promise<void> {\n    try {\n      await this.persistence.runTransaction(\n        'notifyLocalViewChanges',\n        'readwrite',\n        txn => {\n          return PersistencePromise.forEach(\n            viewChanges,\n            (viewChange: LocalViewChanges) => {\n              return PersistencePromise.forEach(\n                viewChange.addedKeys,\n                (key: DocumentKey) =>\n                  this.persistence.referenceDelegate.addReference(\n                    txn,\n                    viewChange.targetId,\n                    key\n                  )\n              ).next(() =>\n                PersistencePromise.forEach(\n                  viewChange.removedKeys,\n                  (key: DocumentKey) =>\n                    this.persistence.referenceDelegate.removeReference(\n                      txn,\n                      viewChange.targetId,\n                      key\n                    )\n                )\n              );\n            }\n          );\n        }\n      );\n    } catch (e) {\n      if (isIndexedDbTransactionError(e)) {\n        // If `notifyLocalViewChanges` fails, we did not advance the sequence\n        // number for the documents that were included in this transaction.\n        // This might trigger them to be deleted earlier than they otherwise\n        // would have, but it should not invalidate the integrity of the data.\n        logDebug(LOG_TAG, 'Failed to update sequence numbers: ' + e);\n      } else {\n        throw e;\n      }\n    }\n\n    for (const viewChange of viewChanges) {\n      const targetId = viewChange.targetId;\n\n      if (!viewChange.fromCache) {\n        const targetData = this.targetDataByTarget.get(targetId);\n        debugAssert(\n          targetData !== null,\n          `Can't set limbo-free snapshot version for unknown target: ${targetId}`\n        );\n\n        // Advance the last limbo free snapshot version\n        const lastLimboFreeSnapshotVersion = targetData.snapshotVersion;\n        const updatedTargetData = targetData.withLastLimboFreeSnapshotVersion(\n          lastLimboFreeSnapshotVersion\n        );\n        this.targetDataByTarget = this.targetDataByTarget.insert(\n          targetId,\n          updatedTargetData\n        );\n      }\n    }\n  }\n\n  nextMutationBatch(afterBatchId?: BatchId): Promise<MutationBatch | null> {\n    return this.persistence.runTransaction(\n      'Get next mutation batch',\n      'readonly',\n      txn => {\n        if (afterBatchId === undefined) {\n          afterBatchId = BATCHID_UNKNOWN;\n        }\n        return this.mutationQueue.getNextMutationBatchAfterBatchId(\n          txn,\n          afterBatchId\n        );\n      }\n    );\n  }\n\n  readDocument(key: DocumentKey): Promise<MaybeDocument | null> {\n    return this.persistence.runTransaction('read document', 'readonly', txn => {\n      return this.localDocuments.getDocument(txn, key);\n    });\n  }\n\n  allocateTarget(target: Target): Promise<TargetData> {\n    return this.persistence\n      .runTransaction('Allocate target', 'readwrite', txn => {\n        let targetData: TargetData;\n        return this.targetCache\n          .getTargetData(txn, target)\n          .next((cached: TargetData | null) => {\n            if (cached) {\n              // This target has been listened to previously, so reuse the\n              // previous targetID.\n              // TODO(mcg): freshen last accessed date?\n              targetData = cached;\n              return PersistencePromise.resolve(targetData);\n            } else {\n              return this.targetCache.allocateTargetId(txn).next(targetId => {\n                targetData = new TargetData(\n                  target,\n                  targetId,\n                  TargetPurpose.Listen,\n                  txn.currentSequenceNumber\n                );\n                return this.targetCache\n                  .addTargetData(txn, targetData)\n                  .next(() => targetData);\n              });\n            }\n          });\n      })\n      .then(targetData => {\n        // If Multi-Tab is enabled, the existing target data may be newer than\n        // the in-memory data\n        const cachedTargetData = this.targetDataByTarget.get(\n          targetData.targetId\n        );\n        if (\n          cachedTargetData === null ||\n          targetData.snapshotVersion.compareTo(\n            cachedTargetData.snapshotVersion\n          ) > 0\n        ) {\n          this.targetDataByTarget = this.targetDataByTarget.insert(\n            targetData.targetId,\n            targetData\n          );\n          this.targetIdByTarget.set(target, targetData.targetId);\n        }\n        return targetData;\n      });\n  }\n\n  getTargetData(\n    transaction: PersistenceTransaction,\n    target: Target\n  ): PersistencePromise<TargetData | null> {\n    const targetId = this.targetIdByTarget.get(target);\n    if (targetId !== undefined) {\n      return PersistencePromise.resolve<TargetData | null>(\n        this.targetDataByTarget.get(targetId)\n      );\n    } else {\n      return this.targetCache.getTargetData(transaction, target);\n    }\n  }\n\n  async releaseTarget(\n    targetId: number,\n    keepPersistedTargetData: boolean\n  ): Promise<void> {\n    const targetData = this.targetDataByTarget.get(targetId);\n    debugAssert(\n      targetData !== null,\n      `Tried to release nonexistent target: ${targetId}`\n    );\n\n    const mode = keepPersistedTargetData ? 'readwrite' : 'readwrite-primary';\n\n    try {\n      if (!keepPersistedTargetData) {\n        await this.persistence.runTransaction('Release target', mode, txn => {\n          return this.persistence.referenceDelegate.removeTarget(\n            txn,\n            targetData!\n          );\n        });\n      }\n    } catch (e) {\n      if (isIndexedDbTransactionError(e)) {\n        // All `releaseTarget` does is record the final metadata state for the\n        // target, but we've been recording this periodically during target\n        // activity. If we lose this write this could cause a very slight\n        // difference in the order of target deletion during GC, but we\n        // don't define exact LRU semantics so this is acceptable.\n        logDebug(\n          LOG_TAG,\n          `Failed to update sequence numbers for target ${targetId}: ${e}`\n        );\n      } else {\n        throw e;\n      }\n    }\n\n    this.targetDataByTarget = this.targetDataByTarget.remove(targetId);\n    this.targetIdByTarget.delete(targetData!.target);\n  }\n\n  executeQuery(\n    query: Query,\n    usePreviousResults: boolean\n  ): Promise<QueryResult> {\n    let lastLimboFreeSnapshotVersion = SnapshotVersion.min();\n    let remoteKeys = documentKeySet();\n\n    return this.persistence.runTransaction('Execute query', 'readonly', txn => {\n      return this.getTargetData(txn, queryToTarget(query))\n        .next(targetData => {\n          if (targetData) {\n            lastLimboFreeSnapshotVersion =\n              targetData.lastLimboFreeSnapshotVersion;\n            return this.targetCache\n              .getMatchingKeysForTargetId(txn, targetData.targetId)\n              .next(result => {\n                remoteKeys = result;\n              });\n          }\n        })\n        .next(() =>\n          this.queryEngine.getDocumentsMatchingQuery(\n            txn,\n            query,\n            usePreviousResults\n              ? lastLimboFreeSnapshotVersion\n              : SnapshotVersion.min(),\n            usePreviousResults ? remoteKeys : documentKeySet()\n          )\n        )\n        .next(documents => {\n          return { documents, remoteKeys };\n        });\n    });\n  }\n\n  private applyWriteToRemoteDocuments(\n    txn: PersistenceTransaction,\n    batchResult: MutationBatchResult,\n    documentBuffer: RemoteDocumentChangeBuffer\n  ): PersistencePromise<void> {\n    const batch = batchResult.batch;\n    const docKeys = batch.keys();\n    let promiseChain = PersistencePromise.resolve();\n    docKeys.forEach(docKey => {\n      promiseChain = promiseChain\n        .next(() => {\n          return documentBuffer.getEntry(txn, docKey);\n        })\n        .next((remoteDoc: MaybeDocument | null) => {\n          let doc = remoteDoc;\n          const ackVersion = batchResult.docVersions.get(docKey);\n          hardAssert(\n            ackVersion !== null,\n            'ackVersions should contain every doc in the write.'\n          );\n          if (!doc || doc.version.compareTo(ackVersion!) < 0) {\n            doc = batch.applyToRemoteDocument(docKey, doc, batchResult);\n            if (!doc) {\n              debugAssert(\n                !remoteDoc,\n                'Mutation batch ' +\n                  batch +\n                  ' applied to document ' +\n                  remoteDoc +\n                  ' resulted in null'\n              );\n            } else {\n              // We use the commitVersion as the readTime rather than the\n              // document's updateTime since the updateTime is not advanced\n              // for updates that do not modify the underlying document.\n              documentBuffer.addEntry(doc, batchResult.commitVersion);\n            }\n          }\n        });\n    });\n    return promiseChain.next(() =>\n      this.mutationQueue.removeMutationBatch(txn, batch)\n    );\n  }\n\n  collectGarbage(garbageCollector: LruGarbageCollector): Promise<LruResults> {\n    return this.persistence.runTransaction(\n      'Collect garbage',\n      'readwrite-primary',\n      txn => garbageCollector.collect(txn, this.targetDataByTarget)\n    );\n  }\n}\n\nexport function newLocalStore(\n  /** Manages our in-memory or durable persistence. */\n  persistence: Persistence,\n  queryEngine: QueryEngine,\n  initialUser: User\n): LocalStore {\n  return new LocalStoreImpl(persistence, queryEngine, initialUser);\n}\n\n/** Returns the local view of the documents affected by a mutation batch. */\n// PORTING NOTE: Multi-Tab only.\nexport function lookupMutationDocuments(\n  localStore: LocalStore,\n  batchId: BatchId\n): Promise<MaybeDocumentMap | null> {\n  const localStoreImpl = debugCast(localStore, LocalStoreImpl);\n  const mutationQueueImpl = debugCast(\n    localStoreImpl.mutationQueue,\n    IndexedDbMutationQueue // We only support IndexedDb in multi-tab mode.\n  );\n  return localStoreImpl.persistence.runTransaction(\n    'Lookup mutation documents',\n    'readonly',\n    txn => {\n      return mutationQueueImpl.lookupMutationKeys(txn, batchId).next(keys => {\n        if (keys) {\n          return localStoreImpl.localDocuments.getDocuments(\n            txn,\n            keys\n          ) as PersistencePromise<MaybeDocumentMap | null>;\n        } else {\n          return PersistencePromise.resolve<MaybeDocumentMap | null>(null);\n        }\n      });\n    }\n  );\n}\n\n// PORTING NOTE: Multi-Tab only.\nexport function removeCachedMutationBatchMetadata(\n  localStore: LocalStore,\n  batchId: BatchId\n): void {\n  const mutationQueueImpl = debugCast(\n    debugCast(localStore, LocalStoreImpl).mutationQueue,\n    IndexedDbMutationQueue // We only support IndexedDb in multi-tab mode.\n  );\n  mutationQueueImpl.removeCachedMutationKeys(batchId);\n}\n\n// PORTING NOTE: Multi-Tab only.\nexport function getActiveClientsFromPersistence(\n  localStore: LocalStore\n): Promise<ClientId[]> {\n  const persistenceImpl = debugCast(\n    debugCast(localStore, LocalStoreImpl).persistence,\n    IndexedDbPersistence // We only support IndexedDb in multi-tab mode.\n  );\n  return persistenceImpl.getActiveClients();\n}\n\n// PORTING NOTE: Multi-Tab only.\nexport function getCachedTarget(\n  localStore: LocalStore,\n  targetId: TargetId\n): Promise<Target | null> {\n  const localStoreImpl = debugCast(localStore, LocalStoreImpl);\n  const targetCacheImpl = debugCast(\n    localStoreImpl.targetCache,\n    IndexedDbTargetCache // We only support IndexedDb in multi-tab mode.\n  );\n  const cachedTargetData = localStoreImpl.targetDataByTarget.get(targetId);\n  if (cachedTargetData) {\n    return Promise.resolve(cachedTargetData.target);\n  } else {\n    return localStoreImpl.persistence.runTransaction(\n      'Get target data',\n      'readonly',\n      txn => {\n        return targetCacheImpl\n          .getTargetDataForTarget(txn, targetId)\n          .next(targetData => (targetData ? targetData.target : null));\n      }\n    );\n  }\n}\n\n/**\n * Returns the set of documents that have been updated since the last call.\n * If this is the first call, returns the set of changes since client\n * initialization. Further invocations will return document that have changed\n * since the prior call.\n */\n// PORTING NOTE: Multi-Tab only.\nexport function getNewDocumentChanges(\n  localStore: LocalStore\n): Promise<MaybeDocumentMap> {\n  const localStoreImpl = debugCast(localStore, LocalStoreImpl);\n  const remoteDocumentCacheImpl = debugCast(\n    localStoreImpl.remoteDocuments,\n    IndexedDbRemoteDocumentCache // We only support IndexedDb in multi-tab mode.\n  );\n  return localStoreImpl.persistence\n    .runTransaction('Get new document changes', 'readonly', txn =>\n      remoteDocumentCacheImpl.getNewDocumentChanges(\n        txn,\n        localStoreImpl.lastDocumentChangeReadTime\n      )\n    )\n    .then(({ changedDocs, readTime }) => {\n      localStoreImpl.lastDocumentChangeReadTime = readTime;\n      return changedDocs;\n    });\n}\n\n/**\n * Reads the newest document change from persistence and moves the internal\n * synchronization marker forward so that calls to `getNewDocumentChanges()`\n * only return changes that happened after client initialization.\n */\n// PORTING NOTE: Multi-Tab only.\nexport async function synchronizeLastDocumentChangeReadTime(\n  localStore: LocalStore\n): Promise<void> {\n  const localStoreImpl = debugCast(localStore, LocalStoreImpl);\n  const remoteDocumentCacheImpl = debugCast(\n    localStoreImpl.remoteDocuments,\n    IndexedDbRemoteDocumentCache // We only support IndexedDb in multi-tab mode.\n  );\n  return localStoreImpl.persistence\n    .runTransaction(\n      'Synchronize last document change read time',\n      'readonly',\n      txn => remoteDocumentCacheImpl.getLastReadTime(txn)\n    )\n    .then(readTime => {\n      localStoreImpl.lastDocumentChangeReadTime = readTime;\n    });\n}\n\n/**\n * Verifies the error thrown by a LocalStore operation. If a LocalStore\n * operation fails because the primary lease has been taken by another client,\n * we ignore the error (the persistence layer will immediately call\n * `applyPrimaryLease` to propagate the primary state change). All other errors\n * are re-thrown.\n *\n * @param err An error returned by a LocalStore operation.\n * @return A Promise that resolves after we recovered, or the original error.\n */\nexport async function ignoreIfPrimaryLeaseLoss(\n  err: FirestoreError\n): Promise<void> {\n  if (\n    err.code === Code.FAILED_PRECONDITION &&\n    err.message === PRIMARY_LEASE_LOST_ERROR_MSG\n  ) {\n    logDebug(LOG_TAG, 'Unexpectedly lost primary lease');\n  } else {\n    throw err;\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 { BatchId, TargetId } from '../core/types';\nimport { documentKeySet, DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedSet } from '../util/sorted_set';\nimport { ResourcePath } from '../model/path';\n\n/**\n * A collection of references to a document from some kind of numbered entity\n * (either a target ID or batch ID). As references are added to or removed from\n * the set corresponding events are emitted to a registered garbage collector.\n *\n * Each reference is represented by a DocumentReference object. Each of them\n * contains enough information to uniquely identify the reference. They are all\n * stored primarily in a set sorted by key. A document is considered garbage if\n * there's no references in that set (this can be efficiently checked thanks to\n * sorting by key).\n *\n * ReferenceSet also keeps a secondary set that contains references sorted by\n * IDs. This one is used to efficiently implement removal of all references by\n * some target ID.\n */\nexport class ReferenceSet {\n  // A set of outstanding references to a document sorted by key.\n  private refsByKey = new SortedSet(DocReference.compareByKey);\n\n  // A set of outstanding references to a document sorted by target id.\n  private refsByTarget = new SortedSet(DocReference.compareByTargetId);\n\n  /** Returns true if the reference set contains no references. */\n  isEmpty(): boolean {\n    return this.refsByKey.isEmpty();\n  }\n\n  /** Adds a reference to the given document key for the given ID. */\n  addReference(key: DocumentKey, id: TargetId | BatchId): void {\n    const ref = new DocReference(key, id);\n    this.refsByKey = this.refsByKey.add(ref);\n    this.refsByTarget = this.refsByTarget.add(ref);\n  }\n\n  /** Add references to the given document keys for the given ID. */\n  addReferences(keys: DocumentKeySet, id: TargetId | BatchId): void {\n    keys.forEach(key => this.addReference(key, id));\n  }\n\n  /**\n   * Removes a reference to the given document key for the given\n   * ID.\n   */\n  removeReference(key: DocumentKey, id: TargetId | BatchId): void {\n    this.removeRef(new DocReference(key, id));\n  }\n\n  removeReferences(keys: DocumentKeySet, id: TargetId | BatchId): void {\n    keys.forEach(key => this.removeReference(key, id));\n  }\n\n  /**\n   * Clears all references with a given ID. Calls removeRef() for each key\n   * removed.\n   */\n  removeReferencesForId(id: TargetId | BatchId): DocumentKey[] {\n    const emptyKey = new DocumentKey(new ResourcePath([]));\n    const startRef = new DocReference(emptyKey, id);\n    const endRef = new DocReference(emptyKey, id + 1);\n    const keys: DocumentKey[] = [];\n    this.refsByTarget.forEachInRange([startRef, endRef], ref => {\n      this.removeRef(ref);\n      keys.push(ref.key);\n    });\n    return keys;\n  }\n\n  removeAllReferences(): void {\n    this.refsByKey.forEach(ref => this.removeRef(ref));\n  }\n\n  private removeRef(ref: DocReference): void {\n    this.refsByKey = this.refsByKey.delete(ref);\n    this.refsByTarget = this.refsByTarget.delete(ref);\n  }\n\n  referencesForId(id: TargetId | BatchId): DocumentKeySet {\n    const emptyKey = new DocumentKey(new ResourcePath([]));\n    const startRef = new DocReference(emptyKey, id);\n    const endRef = new DocReference(emptyKey, id + 1);\n    let keys = documentKeySet();\n    this.refsByTarget.forEachInRange([startRef, endRef], ref => {\n      keys = keys.add(ref.key);\n    });\n    return keys;\n  }\n\n  containsKey(key: DocumentKey): boolean {\n    const ref = new DocReference(key, 0);\n    const firstRef = this.refsByKey.firstAfterOrEqual(ref);\n    return firstRef !== null && key.isEqual(firstRef.key);\n  }\n}\n\nexport class DocReference {\n  constructor(\n    public key: DocumentKey,\n    public targetOrBatchId: TargetId | BatchId\n  ) {}\n\n  /** Compare by key then by ID */\n  static compareByKey(left: DocReference, right: DocReference): number {\n    return (\n      DocumentKey.comparator(left.key, right.key) ||\n      primitiveComparator(left.targetOrBatchId, right.targetOrBatchId)\n    );\n  }\n\n  /** Compare by ID then by key */\n  static compareByTargetId(left: DocReference, right: DocReference): number {\n    return (\n      primitiveComparator(left.targetOrBatchId, right.targetOrBatchId) ||\n      DocumentKey.comparator(left.key, right.key)\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\n/**\n * Simple wrapper around a nullable UID. Mostly exists to make code more\n * readable.\n */\nexport class User {\n  /** A user with a null UID. */\n  static readonly UNAUTHENTICATED = new User(null);\n\n  // TODO(mikelehen): Look into getting a proper uid-equivalent for\n  // non-FirebaseAuth providers.\n  static readonly GOOGLE_CREDENTIALS = new User('google-credentials-uid');\n  static readonly FIRST_PARTY = new User('first-party-uid');\n\n  constructor(readonly uid: string | null) {}\n\n  isAuthenticated(): boolean {\n    return this.uid != null;\n  }\n\n  /**\n   * Returns a key representing this user, suitable for inclusion in a\n   * dictionary.\n   */\n  toKey(): string {\n    if (this.isAuthenticated()) {\n      return 'uid:' + this.uid;\n    } else {\n      return 'anonymous-user';\n    }\n  }\n\n  isEqual(otherUser: User): boolean {\n    return otherUser.uid === this.uid;\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 { User } from '../auth/user';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n  FirebaseAuthInternal,\n  FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\nimport { logDebug } from '../util/log';\n\n// TODO(mikelehen): This should be split into multiple files and probably\n// moved to an auth/ folder to match other platforms.\n\nexport interface FirstPartyCredentialsSettings {\n  type: 'gapi';\n  client: unknown;\n  sessionIndex: string;\n}\n\nexport interface ProviderCredentialsSettings {\n  type: 'provider';\n  client: CredentialsProvider;\n}\n\n/** Settings for private credentials */\nexport type CredentialsSettings =\n  | FirstPartyCredentialsSettings\n  | ProviderCredentialsSettings;\n\nexport type TokenType = 'OAuth' | 'FirstParty';\nexport interface Token {\n  /** Type of token. */\n  type: TokenType;\n\n  /**\n   * The user with which the token is associated (used for persisting user\n   * state on disk, etc.).\n   */\n  user: User;\n\n  /** Extra header values to be passed along with a request */\n  authHeaders: { [header: string]: string };\n}\n\nexport class OAuthToken implements Token {\n  type = 'OAuth' as TokenType;\n  authHeaders: { [header: string]: string };\n  constructor(value: string, public user: User) {\n    this.authHeaders = {};\n    // Set the headers using Object Literal notation to avoid minification\n    this.authHeaders['Authorization'] = `Bearer ${value}`;\n  }\n}\n\n/**\n * A Listener for credential change events. The listener should fetch a new\n * token and may need to invalidate other state if the current user has also\n * changed.\n */\nexport type CredentialChangeListener = (user: User) => void;\n\n/**\n * Provides methods for getting the uid and token for the current user and\n * listening for changes.\n */\nexport interface CredentialsProvider {\n  /** Requests a token for the current user. */\n  getToken(): Promise<Token | null>;\n\n  /**\n   * Marks the last retrieved token as invalid, making the next GetToken request\n   * force-refresh the token.\n   */\n  invalidateToken(): void;\n\n  /**\n   * Specifies a listener to be notified of credential changes\n   * (sign-in / sign-out, token changes). It is immediately called once with the\n   * initial user.\n   */\n  setChangeListener(changeListener: CredentialChangeListener): void;\n\n  /** Removes the previously-set change listener. */\n  removeChangeListener(): void;\n}\n\n/** A CredentialsProvider that always yields an empty token. */\nexport class EmptyCredentialsProvider implements CredentialsProvider {\n  /**\n   * Stores the listener registered with setChangeListener()\n   * This isn't actually necessary since the UID never changes, but we use this\n   * to verify the listen contract is adhered to in tests.\n   */\n  private changeListener: CredentialChangeListener | null = null;\n\n  getToken(): Promise<Token | null> {\n    return Promise.resolve<Token | null>(null);\n  }\n\n  invalidateToken(): void {}\n\n  setChangeListener(changeListener: CredentialChangeListener): void {\n    debugAssert(\n      !this.changeListener,\n      'Can only call setChangeListener() once.'\n    );\n    this.changeListener = changeListener;\n    // Fire with initial user.\n    changeListener(User.UNAUTHENTICATED);\n  }\n\n  removeChangeListener(): void {\n    debugAssert(\n      this.changeListener !== null,\n      'removeChangeListener() when no listener registered'\n    );\n    this.changeListener = null;\n  }\n}\n\nexport class FirebaseCredentialsProvider implements CredentialsProvider {\n  /**\n   * The auth token listener registered with FirebaseApp, retained here so we\n   * can unregister it.\n   */\n  private tokenListener: ((token: string | null) => void) | null = null;\n\n  /** Tracks the current User. */\n  private currentUser: User = User.UNAUTHENTICATED;\n  private receivedInitialUser: boolean = false;\n\n  /**\n   * Counter used to detect if the token changed while a getToken request was\n   * outstanding.\n   */\n  private tokenCounter = 0;\n\n  /** The listener registered with setChangeListener(). */\n  private changeListener: CredentialChangeListener | null = null;\n\n  private forceRefresh = false;\n\n  private auth: FirebaseAuthInternal | null;\n\n  constructor(authProvider: Provider<FirebaseAuthInternalName>) {\n    this.tokenListener = () => {\n      this.tokenCounter++;\n      this.currentUser = this.getUser();\n      this.receivedInitialUser = true;\n      if (this.changeListener) {\n        this.changeListener(this.currentUser);\n      }\n    };\n\n    this.tokenCounter = 0;\n\n    this.auth = authProvider.getImmediate({ optional: true });\n\n    if (this.auth) {\n      this.auth.addAuthTokenListener(this.tokenListener!);\n    } else {\n      // if auth is not available, invoke tokenListener once with null token\n      this.tokenListener(null);\n      authProvider.get().then(\n        auth => {\n          this.auth = auth;\n          if (this.tokenListener) {\n            // tokenListener can be removed by removeChangeListener()\n            this.auth.addAuthTokenListener(this.tokenListener);\n          }\n        },\n        () => {\n          /* this.authProvider.get() never rejects */\n        }\n      );\n    }\n  }\n\n  getToken(): Promise<Token | null> {\n    debugAssert(\n      this.tokenListener != null,\n      'getToken cannot be called after listener removed.'\n    );\n\n    // Take note of the current value of the tokenCounter so that this method\n    // can fail (with an ABORTED error) if there is a token change while the\n    // request is outstanding.\n    const initialTokenCounter = this.tokenCounter;\n    const forceRefresh = this.forceRefresh;\n    this.forceRefresh = false;\n\n    if (!this.auth) {\n      return Promise.resolve(null);\n    }\n\n    return this.auth.getToken(forceRefresh).then(tokenData => {\n      // Cancel the request since the token changed while the request was\n      // outstanding so the response is potentially for a previous user (which\n      // user, we can't be sure).\n      if (this.tokenCounter !== initialTokenCounter) {\n        logDebug(\n          'FirebaseCredentialsProvider',\n          'getToken aborted due to token change.'\n        );\n        return this.getToken();\n      } else {\n        if (tokenData) {\n          hardAssert(\n            typeof tokenData.accessToken === 'string',\n            'Invalid tokenData returned from getToken():' + tokenData\n          );\n          return new OAuthToken(tokenData.accessToken, this.currentUser);\n        } else {\n          return null;\n        }\n      }\n    });\n  }\n\n  invalidateToken(): void {\n    this.forceRefresh = true;\n  }\n\n  setChangeListener(changeListener: CredentialChangeListener): void {\n    debugAssert(\n      !this.changeListener,\n      'Can only call setChangeListener() once.'\n    );\n    this.changeListener = changeListener;\n\n    // Fire the initial event\n    if (this.receivedInitialUser) {\n      changeListener(this.currentUser);\n    }\n  }\n\n  removeChangeListener(): void {\n    debugAssert(\n      this.tokenListener != null,\n      'removeChangeListener() called twice'\n    );\n    debugAssert(\n      this.changeListener !== null,\n      'removeChangeListener() called when no listener registered'\n    );\n\n    if (this.auth) {\n      this.auth.removeAuthTokenListener(this.tokenListener!);\n    }\n    this.tokenListener = null;\n    this.changeListener = null;\n  }\n\n  // Auth.getUid() can return null even with a user logged in. It is because\n  // getUid() is synchronous, but the auth code populating Uid is asynchronous.\n  // This method should only be called in the AuthTokenListener callback\n  // to guarantee to get the actual user.\n  private getUser(): User {\n    const currentUid = this.auth && this.auth.getUid();\n    hardAssert(\n      currentUid === null || typeof currentUid === 'string',\n      'Received invalid UID: ' + currentUid\n    );\n    return new User(currentUid);\n  }\n}\n\n// Manual type definition for the subset of Gapi we use.\ninterface Gapi {\n  auth: {\n    getAuthHeaderValueForFirstParty: (\n      userIdentifiers: Array<{ [key: string]: string }>\n    ) => string | null;\n  };\n}\n\n/*\n * FirstPartyToken provides a fresh token each time its value\n * is requested, because if the token is too old, requests will be rejected.\n * Technically this may no longer be necessary since the SDK should gracefully\n * recover from unauthenticated errors (see b/33147818 for context), but it's\n * safer to keep the implementation as-is.\n */\nexport class FirstPartyToken implements Token {\n  type = 'FirstParty' as TokenType;\n  user = User.FIRST_PARTY;\n\n  constructor(private gapi: Gapi, private sessionIndex: string) {}\n\n  get authHeaders(): { [header: string]: string } {\n    const headers: { [header: string]: string } = {\n      'X-Goog-AuthUser': this.sessionIndex\n    };\n    const authHeader = this.gapi.auth.getAuthHeaderValueForFirstParty([]);\n    if (authHeader) {\n      headers['Authorization'] = authHeader;\n    }\n    return headers;\n  }\n}\n\n/*\n * Provides user credentials required for the Firestore JavaScript SDK\n * to authenticate the user, using technique that is only available\n * to applications hosted by Google.\n */\nexport class FirstPartyCredentialsProvider implements CredentialsProvider {\n  constructor(private gapi: Gapi, private sessionIndex: string) {}\n\n  getToken(): Promise<Token | null> {\n    return Promise.resolve(new FirstPartyToken(this.gapi, this.sessionIndex));\n  }\n\n  setChangeListener(changeListener: CredentialChangeListener): void {\n    // Fire with initial uid.\n    changeListener(User.FIRST_PARTY);\n  }\n\n  removeChangeListener(): void {}\n\n  invalidateToken(): void {}\n}\n\n/**\n * Builds a CredentialsProvider depending on the type of\n * the credentials passed in.\n */\nexport function makeCredentialsProvider(\n  credentials?: CredentialsSettings\n): CredentialsProvider {\n  if (!credentials) {\n    return new EmptyCredentialsProvider();\n  }\n\n  switch (credentials.type) {\n    case 'gapi':\n      const client = credentials.client as Gapi;\n      // Make sure this really is a Gapi client.\n      hardAssert(\n        !!(\n          typeof client === 'object' &&\n          client !== null &&\n          client['auth'] &&\n          client['auth']['getAuthHeaderValueForFirstParty']\n        ),\n        'unexpected gapi interface'\n      );\n      return new FirstPartyCredentialsProvider(\n        client,\n        credentials.sessionIndex || '0'\n      );\n\n    case 'provider':\n      return credentials.client;\n\n    default:\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'makeCredentialsProvider failed due to invalid credential type'\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 { CredentialsProvider, Token } from '../api/credentials';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport { TargetData } from '../local/target_data';\nimport { Mutation, MutationResult } from '../model/mutation';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugAssert, hardAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\n\nimport { isNullOrUndefined } from '../util/types';\nimport { ExponentialBackoff } from './backoff';\nimport { Connection, Stream } from './connection';\nimport {\n  fromVersion,\n  fromWatchChange,\n  fromWriteResults,\n  getEncodedDatabaseId,\n  JsonProtoSerializer,\n  toListenRequestLabels,\n  toMutation,\n  toTarget,\n  versionFromListenResponse\n} from './serializer';\nimport { WatchChange } from './watch_change';\n\nconst LOG_TAG = 'PersistentStream';\n\n// The generated proto interfaces for these class are missing the database\n// field. So we add it here.\n// TODO(b/36015800): Remove this once the api generator is fixed.\ninterface ListenRequest extends api.ListenRequest {\n  database?: string;\n}\nexport interface WriteRequest extends api.WriteRequest {\n  database?: string;\n}\n/**\n * PersistentStream can be in one of 5 states (each described in detail below)\n * based on the following state transition diagram:\n *\n *          start() called             auth & connection succeeded\n * INITIAL ----------------> STARTING -----------------------------> OPEN\n *                             ^  |                                   |\n *                             |  |                    error occurred |\n *                             |  \\-----------------------------v-----/\n *                             |                                |\n *                    backoff  |                                |\n *                    elapsed  |              start() called    |\n *                             \\--- BACKOFF <---------------- ERROR\n *\n * [any state] --------------------------> INITIAL\n *               stop() called or\n *               idle timer expired\n */\nconst enum PersistentStreamState {\n  /**\n   * The streaming RPC is not yet running and there's no error condition.\n   * Calling start() will start the stream immediately without backoff.\n   * While in this state isStarted() will return false.\n   */\n  Initial,\n\n  /**\n   * The stream is starting, either waiting for an auth token or for the stream\n   * to successfully open. While in this state, isStarted() will return true but\n   * isOpen() will return false.\n   */\n  Starting,\n\n  /**\n   * The streaming RPC is up and running. Requests and responses can flow\n   * freely. Both isStarted() and isOpen() will return true.\n   */\n  Open,\n\n  /**\n   * The stream encountered an error. The next start attempt will back off.\n   * While in this state isStarted() will return false.\n   */\n  Error,\n\n  /**\n   * An in-between state after an error where the stream is waiting before\n   * re-starting. After waiting is complete, the stream will try to open.\n   * While in this state isStarted() will return true but isOpen() will return\n   * false.\n   */\n  Backoff\n}\n\n/**\n * Provides a common interface that is shared by the listeners for stream\n * events by the concrete implementation classes.\n */\nexport interface PersistentStreamListener {\n  /**\n   * Called after the stream was established and can accept outgoing\n   * messages\n   */\n  onOpen: () => Promise<void>;\n  /**\n   * Called after the stream has closed. If there was an error, the\n   * FirestoreError will be set.\n   */\n  onClose: (err?: FirestoreError) => Promise<void>;\n}\n\n/** The time a stream stays open after it is marked idle. */\nconst IDLE_TIMEOUT_MS = 60 * 1000;\n\n/**\n * A PersistentStream is an abstract base class that represents a streaming RPC\n * to the Firestore backend. It's built on top of the connections own support\n * for streaming RPCs, and adds several critical features for our clients:\n *\n *   - Exponential backoff on failure\n *   - Authentication via CredentialsProvider\n *   - Dispatching all callbacks into the shared worker queue\n *   - Closing idle streams after 60 seconds of inactivity\n *\n * Subclasses of PersistentStream implement serialization of models to and\n * from the JSON representation of the protocol buffers for a specific\n * streaming RPC.\n *\n * ## Starting and Stopping\n *\n * Streaming RPCs are stateful and need to be start()ed before messages can\n * be sent and received. The PersistentStream will call the onOpen() function\n * of the listener once the stream is ready to accept requests.\n *\n * Should a start() fail, PersistentStream will call the registered onClose()\n * listener with a FirestoreError indicating what went wrong.\n *\n * A PersistentStream can be started and stopped repeatedly.\n *\n * Generic types:\n *  SendType: The type of the outgoing message of the underlying\n *    connection stream\n *  ReceiveType: The type of the incoming message of the underlying\n *    connection stream\n *  ListenerType: The type of the listener that will be used for callbacks\n */\nexport abstract class PersistentStream<\n  SendType,\n  ReceiveType,\n  ListenerType extends PersistentStreamListener\n> {\n  private state = PersistentStreamState.Initial;\n  /**\n   * A close count that's incremented every time the stream is closed; used by\n   * getCloseGuardedDispatcher() to invalidate callbacks that happen after\n   * close.\n   */\n  private closeCount = 0;\n\n  private idleTimer: DelayedOperation<void> | null = null;\n  private stream: Stream<SendType, ReceiveType> | null = null;\n\n  protected backoff: ExponentialBackoff;\n\n  constructor(\n    private queue: AsyncQueue,\n    connectionTimerId: TimerId,\n    private idleTimerId: TimerId,\n    protected connection: Connection,\n    private credentialsProvider: CredentialsProvider,\n    protected listener: ListenerType\n  ) {\n    this.backoff = new ExponentialBackoff(queue, connectionTimerId);\n  }\n\n  /**\n   * Returns true if start() has been called and no error has occurred. True\n   * indicates the stream is open or in the process of opening (which\n   * encompasses respecting backoff, getting auth tokens, and starting the\n   * actual RPC). Use isOpen() to determine if the stream is open and ready for\n   * outbound requests.\n   */\n  isStarted(): boolean {\n    return (\n      this.state === PersistentStreamState.Starting ||\n      this.state === PersistentStreamState.Open ||\n      this.state === PersistentStreamState.Backoff\n    );\n  }\n\n  /**\n   * Returns true if the underlying RPC is open (the onOpen() listener has been\n   * called) and the stream is ready for outbound requests.\n   */\n  isOpen(): boolean {\n    return this.state === PersistentStreamState.Open;\n  }\n\n  /**\n   * Starts the RPC. Only allowed if isStarted() returns false. The stream is\n   * not immediately ready for use: onOpen() will be invoked when the RPC is\n   * ready for outbound requests, at which point isOpen() will return true.\n   *\n   * When start returns, isStarted() will return true.\n   */\n  start(): void {\n    if (this.state === PersistentStreamState.Error) {\n      this.performBackoff();\n      return;\n    }\n\n    debugAssert(\n      this.state === PersistentStreamState.Initial,\n      'Already started'\n    );\n    this.auth();\n  }\n\n  /**\n   * Stops the RPC. This call is idempotent and allowed regardless of the\n   * current isStarted() state.\n   *\n   * When stop returns, isStarted() and isOpen() will both return false.\n   */\n  async stop(): Promise<void> {\n    if (this.isStarted()) {\n      await this.close(PersistentStreamState.Initial);\n    }\n  }\n\n  /**\n   * After an error the stream will usually back off on the next attempt to\n   * start it. If the error warrants an immediate restart of the stream, the\n   * sender can use this to indicate that the receiver should not back off.\n   *\n   * Each error will call the onClose() listener. That function can decide to\n   * inhibit backoff if required.\n   */\n  inhibitBackoff(): void {\n    debugAssert(\n      !this.isStarted(),\n      'Can only inhibit backoff in a stopped state'\n    );\n\n    this.state = PersistentStreamState.Initial;\n    this.backoff.reset();\n  }\n\n  /**\n   * Marks this stream as idle. If no further actions are performed on the\n   * stream for one minute, the stream will automatically close itself and\n   * notify the stream's onClose() handler with Status.OK. The stream will then\n   * be in a !isStarted() state, requiring the caller to start the stream again\n   * before further use.\n   *\n   * Only streams that are in state 'Open' can be marked idle, as all other\n   * states imply pending network operations.\n   */\n  markIdle(): void {\n    // Starts the idle time if we are in state 'Open' and are not yet already\n    // running a timer (in which case the previous idle timeout still applies).\n    if (this.isOpen() && this.idleTimer === null) {\n      this.idleTimer = this.queue.enqueueAfterDelay(\n        this.idleTimerId,\n        IDLE_TIMEOUT_MS,\n        () => this.handleIdleCloseTimer()\n      );\n    }\n  }\n\n  /** Sends a message to the underlying stream. */\n  protected sendRequest(msg: SendType): void {\n    this.cancelIdleCheck();\n    this.stream!.send(msg);\n  }\n\n  /** Called by the idle timer when the stream should close due to inactivity. */\n  private async handleIdleCloseTimer(): Promise<void> {\n    if (this.isOpen()) {\n      // When timing out an idle stream there's no reason to force the stream into backoff when\n      // it restarts so set the stream state to Initial instead of Error.\n      return this.close(PersistentStreamState.Initial);\n    }\n  }\n\n  /** Marks the stream as active again. */\n  private cancelIdleCheck(): void {\n    if (this.idleTimer) {\n      this.idleTimer.cancel();\n      this.idleTimer = null;\n    }\n  }\n\n  /**\n   * Closes the stream and cleans up as necessary:\n   *\n   * * closes the underlying GRPC stream;\n   * * calls the onClose handler with the given 'error';\n   * * sets internal stream state to 'finalState';\n   * * adjusts the backoff timer based on the error\n   *\n   * A new stream can be opened by calling start().\n   *\n   * @param finalState the intended state of the stream after closing.\n   * @param error the error the connection was closed with.\n   */\n  private async close(\n    finalState: PersistentStreamState,\n    error?: FirestoreError\n  ): Promise<void> {\n    debugAssert(this.isStarted(), 'Only started streams should be closed.');\n    debugAssert(\n      finalState === PersistentStreamState.Error || isNullOrUndefined(error),\n      \"Can't provide an error when not in an error state.\"\n    );\n\n    // Cancel any outstanding timers (they're guaranteed not to execute).\n    this.cancelIdleCheck();\n    this.backoff.cancel();\n\n    // Invalidates any stream-related callbacks (e.g. from auth or the\n    // underlying stream), guaranteeing they won't execute.\n    this.closeCount++;\n\n    if (finalState !== PersistentStreamState.Error) {\n      // If this is an intentional close ensure we don't delay our next connection attempt.\n      this.backoff.reset();\n    } else if (error && error.code === Code.RESOURCE_EXHAUSTED) {\n      // Log the error. (Probably either 'quota exceeded' or 'max queue length reached'.)\n      logError(error.toString());\n      logError(\n        'Using maximum backoff delay to prevent overloading the backend.'\n      );\n      this.backoff.resetToMax();\n    } else if (error && error.code === Code.UNAUTHENTICATED) {\n      // \"unauthenticated\" error means the token was rejected. Try force refreshing it in case it\n      // just expired.\n      this.credentialsProvider.invalidateToken();\n    }\n\n    // Clean up the underlying stream because we are no longer interested in events.\n    if (this.stream !== null) {\n      this.tearDown();\n      this.stream.close();\n      this.stream = null;\n    }\n\n    // This state must be assigned before calling onClose() to allow the callback to\n    // inhibit backoff or otherwise manipulate the state in its non-started state.\n    this.state = finalState;\n\n    // Notify the listener that the stream closed.\n    await this.listener.onClose(error);\n  }\n\n  /**\n   * Can be overridden to perform additional cleanup before the stream is closed.\n   * Calling super.tearDown() is not required.\n   */\n  protected tearDown(): void {}\n\n  /**\n   * Used by subclasses to start the concrete RPC and return the underlying\n   * connection stream.\n   */\n  protected abstract startRpc(\n    token: Token | null\n  ): Stream<SendType, ReceiveType>;\n\n  /**\n   * Called after the stream has received a message. The function will be\n   * called on the right queue and must return a Promise.\n   * @param message The message received from the stream.\n   */\n  protected abstract onMessage(message: ReceiveType): Promise<void>;\n\n  private auth(): void {\n    debugAssert(\n      this.state === PersistentStreamState.Initial,\n      'Must be in initial state to auth'\n    );\n\n    this.state = PersistentStreamState.Starting;\n\n    const dispatchIfNotClosed = this.getCloseGuardedDispatcher(this.closeCount);\n\n    // TODO(mikelehen): Just use dispatchIfNotClosed, but see TODO below.\n    const closeCount = this.closeCount;\n\n    this.credentialsProvider.getToken().then(\n      token => {\n        // Stream can be stopped while waiting for authentication.\n        // TODO(mikelehen): We really should just use dispatchIfNotClosed\n        // and let this dispatch onto the queue, but that opened a spec test can\n        // of worms that I don't want to deal with in this PR.\n        if (this.closeCount === closeCount) {\n          // Normally we'd have to schedule the callback on the AsyncQueue.\n          // However, the following calls are safe to be called outside the\n          // AsyncQueue since they don't chain asynchronous calls\n          this.startStream(token);\n        }\n      },\n      (error: Error) => {\n        dispatchIfNotClosed(() => {\n          const rpcError = new FirestoreError(\n            Code.UNKNOWN,\n            'Fetching auth token failed: ' + error.message\n          );\n          return this.handleStreamClose(rpcError);\n        });\n      }\n    );\n  }\n\n  private startStream(token: Token | null): void {\n    debugAssert(\n      this.state === PersistentStreamState.Starting,\n      'Trying to start stream in a non-starting state'\n    );\n\n    const dispatchIfNotClosed = this.getCloseGuardedDispatcher(this.closeCount);\n\n    this.stream = this.startRpc(token);\n    this.stream.onOpen(() => {\n      dispatchIfNotClosed(() => {\n        debugAssert(\n          this.state === PersistentStreamState.Starting,\n          'Expected stream to be in state Starting, but was ' + this.state\n        );\n        this.state = PersistentStreamState.Open;\n        return this.listener!.onOpen();\n      });\n    });\n    this.stream.onClose((error?: FirestoreError) => {\n      dispatchIfNotClosed(() => {\n        return this.handleStreamClose(error);\n      });\n    });\n    this.stream.onMessage((msg: ReceiveType) => {\n      dispatchIfNotClosed(() => {\n        return this.onMessage(msg);\n      });\n    });\n  }\n\n  private performBackoff(): void {\n    debugAssert(\n      this.state === PersistentStreamState.Error,\n      'Should only perform backoff when in Error state'\n    );\n    this.state = PersistentStreamState.Backoff;\n\n    this.backoff.backoffAndRun(async () => {\n      debugAssert(\n        this.state === PersistentStreamState.Backoff,\n        'Backoff elapsed but state is now: ' + this.state\n      );\n\n      this.state = PersistentStreamState.Initial;\n      this.start();\n      debugAssert(this.isStarted(), 'PersistentStream should have started');\n    });\n  }\n\n  // Visible for tests\n  handleStreamClose(error?: FirestoreError): Promise<void> {\n    debugAssert(\n      this.isStarted(),\n      \"Can't handle server close on non-started stream\"\n    );\n    logDebug(LOG_TAG, `close with error: ${error}`);\n\n    this.stream = null;\n\n    // In theory the stream could close cleanly, however, in our current model\n    // we never expect this to happen because if we stop a stream ourselves,\n    // this callback will never be called. To prevent cases where we retry\n    // without a backoff accidentally, we set the stream to error in all cases.\n    return this.close(PersistentStreamState.Error, error);\n  }\n\n  /**\n   * Returns a \"dispatcher\" function that dispatches operations onto the\n   * AsyncQueue but only runs them if closeCount remains unchanged. This allows\n   * us to turn auth / stream callbacks into no-ops if the stream is closed /\n   * re-opened, etc.\n   */\n  private getCloseGuardedDispatcher(\n    startCloseCount: number\n  ): (fn: () => Promise<void>) => void {\n    return (fn: () => Promise<void>): void => {\n      this.queue.enqueueAndForget(() => {\n        if (this.closeCount === startCloseCount) {\n          return fn();\n        } else {\n          logDebug(\n            LOG_TAG,\n            'stream callback skipped by getCloseGuardedDispatcher.'\n          );\n          return Promise.resolve();\n        }\n      });\n    };\n  }\n}\n\n/** Listener for the PersistentWatchStream */\nexport interface WatchStreamListener extends PersistentStreamListener {\n  /**\n   * Called on a watchChange. The snapshot parameter will be MIN if the watch\n   * change did not have a snapshot associated with it.\n   */\n  onWatchChange: (\n    watchChange: WatchChange,\n    snapshot: SnapshotVersion\n  ) => Promise<void>;\n}\n\n/**\n * A PersistentStream that implements the Listen RPC.\n *\n * Once the Listen stream has called the onOpen() listener, any number of\n * listen() and unlisten() calls can be made to control what changes will be\n * sent from the server for ListenResponses.\n */\nexport class PersistentListenStream extends PersistentStream<\n  api.ListenRequest,\n  api.ListenResponse,\n  WatchStreamListener\n> {\n  constructor(\n    queue: AsyncQueue,\n    connection: Connection,\n    credentials: CredentialsProvider,\n    private serializer: JsonProtoSerializer,\n    listener: WatchStreamListener\n  ) {\n    super(\n      queue,\n      TimerId.ListenStreamConnectionBackoff,\n      TimerId.ListenStreamIdle,\n      connection,\n      credentials,\n      listener\n    );\n  }\n\n  protected startRpc(\n    token: Token | null\n  ): Stream<api.ListenRequest, api.ListenResponse> {\n    return this.connection.openStream<api.ListenRequest, api.ListenResponse>(\n      'Listen',\n      token\n    );\n  }\n\n  protected onMessage(watchChangeProto: api.ListenResponse): Promise<void> {\n    // A successful response means the stream is healthy\n    this.backoff.reset();\n\n    const watchChange = fromWatchChange(this.serializer, watchChangeProto);\n    const snapshot = versionFromListenResponse(watchChangeProto);\n    return this.listener!.onWatchChange(watchChange, snapshot);\n  }\n\n  /**\n   * Registers interest in the results of the given target. If the target\n   * includes a resumeToken it will be included in the request. Results that\n   * affect the target will be streamed back as WatchChange messages that\n   * reference the targetId.\n   */\n  watch(targetData: TargetData): void {\n    const request: ListenRequest = {};\n    request.database = getEncodedDatabaseId(this.serializer);\n    request.addTarget = toTarget(this.serializer, targetData);\n\n    const labels = toListenRequestLabels(this.serializer, targetData);\n    if (labels) {\n      request.labels = labels;\n    }\n\n    this.sendRequest(request);\n  }\n\n  /**\n   * Unregisters interest in the results of the target associated with the\n   * given targetId.\n   */\n  unwatch(targetId: TargetId): void {\n    const request: ListenRequest = {};\n    request.database = getEncodedDatabaseId(this.serializer);\n    request.removeTarget = targetId;\n    this.sendRequest(request);\n  }\n}\n\n/** Listener for the PersistentWriteStream */\nexport interface WriteStreamListener extends PersistentStreamListener {\n  /**\n   * Called by the PersistentWriteStream upon a successful handshake response\n   * from the server, which is the receiver's cue to send any pending writes.\n   */\n  onHandshakeComplete: () => Promise<void>;\n\n  /**\n   * Called by the PersistentWriteStream upon receiving a StreamingWriteResponse\n   * from the server that contains a mutation result.\n   */\n  onMutationResult: (\n    commitVersion: SnapshotVersion,\n    results: MutationResult[]\n  ) => Promise<void>;\n}\n\n/**\n * A Stream that implements the Write RPC.\n *\n * The Write RPC requires the caller to maintain special streamToken\n * state in between calls, to help the server understand which responses the\n * client has processed by the time the next request is made. Every response\n * will contain a streamToken; this value must be passed to the next\n * request.\n *\n * After calling start() on this stream, the next request must be a handshake,\n * containing whatever streamToken is on hand. Once a response to this\n * request is received, all pending mutations may be submitted. When\n * submitting multiple batches of mutations at the same time, it's\n * okay to use the same streamToken for the calls to writeMutations.\n *\n * TODO(b/33271235): Use proto types\n */\nexport class PersistentWriteStream extends PersistentStream<\n  api.WriteRequest,\n  api.WriteResponse,\n  WriteStreamListener\n> {\n  private handshakeComplete_ = false;\n\n  constructor(\n    queue: AsyncQueue,\n    connection: Connection,\n    credentials: CredentialsProvider,\n    private serializer: JsonProtoSerializer,\n    listener: WriteStreamListener\n  ) {\n    super(\n      queue,\n      TimerId.WriteStreamConnectionBackoff,\n      TimerId.WriteStreamIdle,\n      connection,\n      credentials,\n      listener\n    );\n  }\n\n  /**\n   * The last received stream token from the server, used to acknowledge which\n   * responses the client has processed. Stream tokens are opaque checkpoint\n   * markers whose only real value is their inclusion in the next request.\n   *\n   * PersistentWriteStream manages propagating this value from responses to the\n   * next request.\n   */\n  private lastStreamToken: string | Uint8Array | undefined;\n\n  /**\n   * Tracks whether or not a handshake has been successfully exchanged and\n   * the stream is ready to accept mutations.\n   */\n  get handshakeComplete(): boolean {\n    return this.handshakeComplete_;\n  }\n\n  // Override of PersistentStream.start\n  start(): void {\n    this.handshakeComplete_ = false;\n    this.lastStreamToken = undefined;\n    super.start();\n  }\n\n  protected tearDown(): void {\n    if (this.handshakeComplete_) {\n      this.writeMutations([]);\n    }\n  }\n\n  protected startRpc(\n    token: Token | null\n  ): Stream<api.WriteRequest, api.WriteResponse> {\n    return this.connection.openStream<api.WriteRequest, api.WriteResponse>(\n      'Write',\n      token\n    );\n  }\n\n  protected onMessage(responseProto: api.WriteResponse): Promise<void> {\n    // Always capture the last stream token.\n    hardAssert(\n      !!responseProto.streamToken,\n      'Got a write response without a stream token'\n    );\n    this.lastStreamToken = responseProto.streamToken;\n\n    if (!this.handshakeComplete_) {\n      // The first response is always the handshake response\n      hardAssert(\n        !responseProto.writeResults || responseProto.writeResults.length === 0,\n        'Got mutation results for handshake'\n      );\n      this.handshakeComplete_ = true;\n      return this.listener!.onHandshakeComplete();\n    } else {\n      // A successful first write response means the stream is healthy,\n      // Note, that we could consider a successful handshake healthy, however,\n      // the write itself might be causing an error we want to back off from.\n      this.backoff.reset();\n\n      const results = fromWriteResults(\n        responseProto.writeResults,\n        responseProto.commitTime\n      );\n      const commitVersion = fromVersion(responseProto.commitTime!);\n      return this.listener!.onMutationResult(commitVersion, results);\n    }\n  }\n\n  /**\n   * Sends an initial streamToken to the server, performing the handshake\n   * required to make the StreamingWrite RPC work. Subsequent\n   * calls should wait until onHandshakeComplete was called.\n   */\n  writeHandshake(): void {\n    debugAssert(this.isOpen(), 'Writing handshake requires an opened stream');\n    debugAssert(!this.handshakeComplete_, 'Handshake already completed');\n    debugAssert(\n      !this.lastStreamToken,\n      'Stream token should be empty during handshake'\n    );\n    // TODO(dimond): Support stream resumption. We intentionally do not set the\n    // stream token on the handshake, ignoring any stream token we might have.\n    const request: WriteRequest = {};\n    request.database = getEncodedDatabaseId(this.serializer);\n    this.sendRequest(request);\n  }\n\n  /** Sends a group of mutations to the Firestore backend to apply. */\n  writeMutations(mutations: Mutation[]): void {\n    debugAssert(this.isOpen(), 'Writing mutations requires an opened stream');\n    debugAssert(\n      this.handshakeComplete_,\n      'Handshake must be complete before writing mutations'\n    );\n    debugAssert(\n      !!this.lastStreamToken,\n      'Trying to write mutation without a token'\n    );\n\n    const request: WriteRequest = {\n      streamToken: this.lastStreamToken,\n      writes: mutations.map(mutation => toMutation(this.serializer, mutation))\n    };\n\n    this.sendRequest(request);\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 { CredentialsProvider } from '../api/credentials';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugAssert, debugCast, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { Connection } from './connection';\nimport {\n  fromDocument,\n  fromMaybeDocument,\n  getEncodedDatabaseId,\n  JsonProtoSerializer,\n  toMutation,\n  toName,\n  toQueryTarget\n} from './serializer';\nimport {\n  PersistentListenStream,\n  PersistentWriteStream,\n  WatchStreamListener,\n  WriteStreamListener\n} from './persistent_stream';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Query, queryToTarget } from '../core/query';\n\n/**\n * Datastore and its related methods are a wrapper around the external Google\n * Cloud Datastore grpc API, which provides an interface that is more convenient\n * for the rest of the client SDK architecture to consume.\n */\nexport abstract class Datastore {\n  abstract terminate(): void;\n}\n\n/**\n * An implementation of Datastore that exposes additional state for internal\n * consumption.\n */\nclass DatastoreImpl extends Datastore {\n  terminated = false;\n\n  constructor(\n    readonly credentials: CredentialsProvider,\n    readonly connection: Connection,\n    readonly serializer: JsonProtoSerializer\n  ) {\n    super();\n  }\n\n  verifyInitialized(): void {\n    debugAssert(!!this.connection, 'Datastore.start() not called');\n    if (this.terminated) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'The client has already been terminated.'\n      );\n    }\n  }\n\n  /** Gets an auth token and invokes the provided RPC. */\n  invokeRPC<Req, Resp>(\n    rpcName: string,\n    path: string,\n    request: Req\n  ): Promise<Resp> {\n    this.verifyInitialized();\n    return this.credentials\n      .getToken()\n      .then(token => {\n        return this.connection.invokeRPC<Req, Resp>(\n          rpcName,\n          path,\n          request,\n          token\n        );\n      })\n      .catch((error: FirestoreError) => {\n        if (error.code === Code.UNAUTHENTICATED) {\n          this.credentials.invalidateToken();\n        }\n        throw error;\n      });\n  }\n\n  /** Gets an auth token and invokes the provided RPC with streamed results. */\n  invokeStreamingRPC<Req, Resp>(\n    rpcName: string,\n    path: string,\n    request: Req\n  ): Promise<Resp[]> {\n    this.verifyInitialized();\n    return this.credentials\n      .getToken()\n      .then(token => {\n        return this.connection.invokeStreamingRPC<Req, Resp>(\n          rpcName,\n          path,\n          request,\n          token\n        );\n      })\n      .catch((error: FirestoreError) => {\n        if (error.code === Code.UNAUTHENTICATED) {\n          this.credentials.invalidateToken();\n        }\n        throw error;\n      });\n  }\n\n  terminate(): void {\n    this.terminated = false;\n  }\n}\n\n// TODO(firestorexp): Make sure there is only one Datastore instance per\n// firestore-exp client.\nexport function newDatastore(\n  credentials: CredentialsProvider,\n  connection: Connection,\n  serializer: JsonProtoSerializer\n): Datastore {\n  return new DatastoreImpl(credentials, connection, serializer);\n}\n\nexport async function invokeCommitRpc(\n  datastore: Datastore,\n  mutations: Mutation[]\n): Promise<void> {\n  const datastoreImpl = debugCast(datastore, DatastoreImpl);\n  const path = getEncodedDatabaseId(datastoreImpl.serializer) + '/documents';\n  const request = {\n    writes: mutations.map(m => toMutation(datastoreImpl.serializer, m))\n  };\n  await datastoreImpl.invokeRPC('Commit', path, request);\n}\n\nexport async function invokeBatchGetDocumentsRpc(\n  datastore: Datastore,\n  keys: DocumentKey[]\n): Promise<MaybeDocument[]> {\n  const datastoreImpl = debugCast(datastore, DatastoreImpl);\n  const path = getEncodedDatabaseId(datastoreImpl.serializer) + '/documents';\n  const request = {\n    documents: keys.map(k => toName(datastoreImpl.serializer, k))\n  };\n  const response = await datastoreImpl.invokeStreamingRPC<\n    api.BatchGetDocumentsRequest,\n    api.BatchGetDocumentsResponse\n  >('BatchGetDocuments', path, request);\n\n  const docs = new Map<string, MaybeDocument>();\n  response.forEach(proto => {\n    const doc = fromMaybeDocument(datastoreImpl.serializer, proto);\n    docs.set(doc.key.toString(), doc);\n  });\n  const result: MaybeDocument[] = [];\n  keys.forEach(key => {\n    const doc = docs.get(key.toString());\n    hardAssert(!!doc, 'Missing entity in write response for ' + key);\n    result.push(doc);\n  });\n  return result;\n}\n\nexport async function invokeRunQueryRpc(\n  datastore: Datastore,\n  query: Query\n): Promise<Document[]> {\n  const datastoreImpl = debugCast(datastore, DatastoreImpl);\n  const request = toQueryTarget(datastoreImpl.serializer, queryToTarget(query));\n  const response = await datastoreImpl.invokeStreamingRPC<\n    api.RunQueryRequest,\n    api.RunQueryResponse\n  >('RunQuery', request.parent!, { structuredQuery: request.structuredQuery });\n  return (\n    response\n      // Omit RunQueryResponses that only contain readTimes.\n      .filter(proto => !!proto.document)\n      .map(proto =>\n        fromDocument(datastoreImpl.serializer, proto.document!, undefined)\n      )\n  );\n}\n\nexport function newPersistentWriteStream(\n  datastore: Datastore,\n  queue: AsyncQueue,\n  listener: WriteStreamListener\n): PersistentWriteStream {\n  const datastoreImpl = debugCast(datastore, DatastoreImpl);\n  datastoreImpl.verifyInitialized();\n  return new PersistentWriteStream(\n    queue,\n    datastoreImpl.connection,\n    datastoreImpl.credentials,\n    datastoreImpl.serializer,\n    listener\n  );\n}\n\nexport function newPersistentWatchStream(\n  datastore: Datastore,\n  queue: AsyncQueue,\n  listener: WatchStreamListener\n): PersistentListenStream {\n  const datastoreImpl = debugCast(datastore, DatastoreImpl);\n  datastoreImpl.verifyInitialized();\n  return new PersistentListenStream(\n    queue,\n    datastoreImpl.connection,\n    datastoreImpl.credentials,\n    datastoreImpl.serializer,\n    listener\n  );\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 { OnlineState } from '../core/types';\nimport { debugAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\n\nconst LOG_TAG = 'OnlineStateTracker';\n\n// To deal with transient failures, we allow multiple stream attempts before\n// giving up and transitioning from OnlineState.Unknown to Offline.\n// TODO(mikelehen): This used to be set to 2 as a mitigation for b/66228394.\n// @jdimond thinks that bug is sufficiently fixed so that we can set this back\n// to 1. If that works okay, we could potentially remove this logic entirely.\nconst MAX_WATCH_STREAM_FAILURES = 1;\n\n// To deal with stream attempts that don't succeed or fail in a timely manner,\n// we have a timeout for OnlineState to reach Online or Offline.\n// If the timeout is reached, we transition to Offline rather than waiting\n// indefinitely.\nconst ONLINE_STATE_TIMEOUT_MS = 10 * 1000;\n\n/**\n * A component used by the RemoteStore to track the OnlineState (that is,\n * whether or not the client as a whole should be considered to be online or\n * offline), implementing the appropriate heuristics.\n *\n * In particular, when the client is trying to connect to the backend, we\n * allow up to MAX_WATCH_STREAM_FAILURES within ONLINE_STATE_TIMEOUT_MS for\n * a connection to succeed. If we have too many failures or the timeout elapses,\n * then we set the OnlineState to Offline, and the client will behave as if\n * it is offline (get()s will return cached data, etc.).\n */\nexport class OnlineStateTracker {\n  /** The current OnlineState. */\n  private state = OnlineState.Unknown;\n\n  /**\n   * A count of consecutive failures to open the stream. If it reaches the\n   * maximum defined by MAX_WATCH_STREAM_FAILURES, we'll set the OnlineState to\n   * Offline.\n   */\n  private watchStreamFailures = 0;\n\n  /**\n   * A timer that elapses after ONLINE_STATE_TIMEOUT_MS, at which point we\n   * transition from OnlineState.Unknown to OnlineState.Offline without waiting\n   * for the stream to actually fail (MAX_WATCH_STREAM_FAILURES times).\n   */\n  private onlineStateTimer: DelayedOperation<void> | null = null;\n\n  /**\n   * Whether the client should log a warning message if it fails to connect to\n   * the backend (initially true, cleared after a successful stream, or if we've\n   * logged the message already).\n   */\n  private shouldWarnClientIsOffline = true;\n\n  constructor(\n    private asyncQueue: AsyncQueue,\n    private onlineStateHandler: (onlineState: OnlineState) => void\n  ) {}\n\n  /**\n   * Called by RemoteStore when a watch stream is started (including on each\n   * backoff attempt).\n   *\n   * If this is the first attempt, it sets the OnlineState to Unknown and starts\n   * the onlineStateTimer.\n   */\n  handleWatchStreamStart(): void {\n    if (this.watchStreamFailures === 0) {\n      this.setAndBroadcast(OnlineState.Unknown);\n\n      debugAssert(\n        this.onlineStateTimer === null,\n        `onlineStateTimer shouldn't be started yet`\n      );\n      this.onlineStateTimer = this.asyncQueue.enqueueAfterDelay(\n        TimerId.OnlineStateTimeout,\n        ONLINE_STATE_TIMEOUT_MS,\n        () => {\n          this.onlineStateTimer = null;\n          debugAssert(\n            this.state === OnlineState.Unknown,\n            'Timer should be canceled if we transitioned to a different state.'\n          );\n          this.logClientOfflineWarningIfNecessary(\n            `Backend didn't respond within ${ONLINE_STATE_TIMEOUT_MS / 1000} ` +\n              `seconds.`\n          );\n          this.setAndBroadcast(OnlineState.Offline);\n\n          // NOTE: handleWatchStreamFailure() will continue to increment\n          // watchStreamFailures even though we are already marked Offline,\n          // but this is non-harmful.\n\n          return Promise.resolve();\n        }\n      );\n    }\n  }\n\n  /**\n   * Updates our OnlineState as appropriate after the watch stream reports a\n   * failure. The first failure moves us to the 'Unknown' state. We then may\n   * allow multiple failures (based on MAX_WATCH_STREAM_FAILURES) before we\n   * actually transition to the 'Offline' state.\n   */\n  handleWatchStreamFailure(error: FirestoreError): void {\n    if (this.state === OnlineState.Online) {\n      this.setAndBroadcast(OnlineState.Unknown);\n\n      // To get to OnlineState.Online, set() must have been called which would\n      // have reset our heuristics.\n      debugAssert(\n        this.watchStreamFailures === 0,\n        'watchStreamFailures must be 0'\n      );\n      debugAssert(\n        this.onlineStateTimer === null,\n        'onlineStateTimer must be null'\n      );\n    } else {\n      this.watchStreamFailures++;\n      if (this.watchStreamFailures >= MAX_WATCH_STREAM_FAILURES) {\n        this.clearOnlineStateTimer();\n\n        this.logClientOfflineWarningIfNecessary(\n          `Connection failed ${MAX_WATCH_STREAM_FAILURES} ` +\n            `times. Most recent error: ${error.toString()}`\n        );\n\n        this.setAndBroadcast(OnlineState.Offline);\n      }\n    }\n  }\n\n  /**\n   * Explicitly sets the OnlineState to the specified state.\n   *\n   * Note that this resets our timers / failure counters, etc. used by our\n   * Offline heuristics, so must not be used in place of\n   * handleWatchStreamStart() and handleWatchStreamFailure().\n   */\n  set(newState: OnlineState): void {\n    this.clearOnlineStateTimer();\n    this.watchStreamFailures = 0;\n\n    if (newState === OnlineState.Online) {\n      // We've connected to watch at least once. Don't warn the developer\n      // about being offline going forward.\n      this.shouldWarnClientIsOffline = false;\n    }\n\n    this.setAndBroadcast(newState);\n  }\n\n  private setAndBroadcast(newState: OnlineState): void {\n    if (newState !== this.state) {\n      this.state = newState;\n      this.onlineStateHandler(newState);\n    }\n  }\n\n  private logClientOfflineWarningIfNecessary(details: string): void {\n    const message =\n      `Could not reach Cloud Firestore backend. ${details}\\n` +\n      `This typically indicates that your device does not have a healthy ` +\n      `Internet connection at the moment. The client will operate in offline ` +\n      `mode until it is able to successfully connect to the backend.`;\n    if (this.shouldWarnClientIsOffline) {\n      logError(message);\n      this.shouldWarnClientIsOffline = false;\n    } else {\n      logDebug(LOG_TAG, message);\n    }\n  }\n\n  private clearOnlineStateTimer(): void {\n    if (this.onlineStateTimer !== null) {\n      this.onlineStateTimer.cancel();\n      this.onlineStateTimer = null;\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { OnlineState, TargetId } from '../core/types';\nimport { LocalStore } from '../local/local_store';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport { MutationResult } from '../model/mutation';\nimport {\n  BATCHID_UNKNOWN,\n  MutationBatch,\n  MutationBatchResult\n} from '../model/mutation_batch';\nimport { debugAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { DocumentKeySet } from '../model/collections';\nimport { AsyncQueue } from '../util/async_queue';\nimport { ConnectivityMonitor, NetworkStatus } from './connectivity_monitor';\nimport {\n  Datastore,\n  newPersistentWatchStream,\n  newPersistentWriteStream\n} from './datastore';\nimport { OnlineStateTracker } from './online_state_tracker';\nimport {\n  PersistentListenStream,\n  PersistentWriteStream\n} from './persistent_stream';\nimport { RemoteSyncer } from './remote_syncer';\nimport { isPermanentWriteError } from './rpc_error';\nimport {\n  DocumentWatchChange,\n  ExistenceFilterChange,\n  TargetMetadataProvider,\n  WatchChange,\n  WatchChangeAggregator,\n  WatchTargetChange,\n  WatchTargetChangeState\n} from './watch_change';\nimport { ByteString } from '../util/byte_string';\nimport { isIndexedDbTransactionError } from '../local/simple_db';\nimport { User } from '../auth/user';\n\nconst LOG_TAG = 'RemoteStore';\n\n// TODO(b/35853402): Negotiate this with the stream.\nconst MAX_PENDING_WRITES = 10;\n\n/** Reasons for why the RemoteStore may be offline. */\nconst enum OfflineCause {\n  /** The user has explicitly disabled the network (via `disableNetwork()`). */\n  UserDisabled,\n  /** An IndexedDb failure occurred while persisting a stream update. */\n  IndexedDbFailed,\n  /** The tab is not the primary tab (only relevant with multi-tab). */\n  IsSecondary,\n  /** We are restarting the streams due to an Auth credential change. */\n  CredentialChange,\n  /** The connectivity state of the environment has changed. */\n  ConnectivityChange,\n  /** The RemoteStore has been shut down. */\n  Shutdown\n}\n\n/**\n * RemoteStore - An interface to remotely stored data, basically providing a\n * wrapper around the Datastore that is more reliable for the rest of the\n * system.\n *\n * RemoteStore is responsible for maintaining the connection to the server.\n * - maintaining a list of active listens.\n * - reconnecting when the connection is dropped.\n * - resuming all the active listens on reconnect.\n *\n * RemoteStore handles all incoming events from the Datastore.\n * - listening to the watch stream and repackaging the events as RemoteEvents\n * - notifying SyncEngine of any changes to the active listens.\n *\n * RemoteStore takes writes from other components and handles them reliably.\n * - pulling pending mutations from LocalStore and sending them to Datastore.\n * - retrying mutations that failed because of network problems.\n * - acking mutations to the SyncEngine once they are accepted or rejected.\n */\nexport class RemoteStore implements TargetMetadataProvider {\n  /**\n   * A list of up to MAX_PENDING_WRITES writes that we have fetched from the\n   * LocalStore via fillWritePipeline() and have or will send to the write\n   * stream.\n   *\n   * Whenever writePipeline.length > 0 the RemoteStore will attempt to start or\n   * restart the write stream. When the stream is established the writes in the\n   * pipeline will be sent in order.\n   *\n   * Writes remain in writePipeline until they are acknowledged by the backend\n   * and thus will automatically be re-sent if the stream is interrupted /\n   * restarted before they're acknowledged.\n   *\n   * Write responses from the backend are linked to their originating request\n   * purely based on order, and so we can just shift() writes from the front of\n   * the writePipeline as we receive responses.\n   */\n  private writePipeline: MutationBatch[] = [];\n\n  /**\n   * A mapping of watched targets that the client cares about tracking and the\n   * user has explicitly called a 'listen' for this target.\n   *\n   * These targets may or may not have been sent to or acknowledged by the\n   * server. On re-establishing the listen stream, these targets should be sent\n   * to the server. The targets removed with unlistens are removed eagerly\n   * without waiting for confirmation from the listen stream.\n   */\n  private listenTargets = new Map<TargetId, TargetData>();\n\n  private connectivityMonitor: ConnectivityMonitor;\n  private watchStream: PersistentListenStream;\n  private writeStream: PersistentWriteStream;\n  private watchChangeAggregator: WatchChangeAggregator | null = null;\n\n  /**\n   * A set of reasons for why the RemoteStore may be offline. If empty, the\n   * RemoteStore may start its network connections.\n   */\n  private offlineCauses = new Set<OfflineCause>();\n\n  private onlineStateTracker: OnlineStateTracker;\n\n  constructor(\n    /**\n     * The local store, used to fill the write pipeline with outbound mutations.\n     */\n    private localStore: LocalStore,\n    /** The client-side proxy for interacting with the backend. */\n    private datastore: Datastore,\n    private asyncQueue: AsyncQueue,\n    onlineStateHandler: (onlineState: OnlineState) => void,\n    connectivityMonitor: ConnectivityMonitor\n  ) {\n    this.connectivityMonitor = connectivityMonitor;\n    this.connectivityMonitor.addCallback((_: NetworkStatus) => {\n      asyncQueue.enqueueAndForget(async () => {\n        // Porting Note: Unlike iOS, `restartNetwork()` is called even when the\n        // network becomes unreachable as we don't have any other way to tear\n        // down our streams.\n        if (this.canUseNetwork()) {\n          logDebug(\n            LOG_TAG,\n            'Restarting streams for network reachability change.'\n          );\n          await this.restartNetwork();\n        }\n      });\n    });\n\n    this.onlineStateTracker = new OnlineStateTracker(\n      asyncQueue,\n      onlineStateHandler\n    );\n\n    // Create streams (but note they're not started yet).\n    this.watchStream = newPersistentWatchStream(this.datastore, asyncQueue, {\n      onOpen: this.onWatchStreamOpen.bind(this),\n      onClose: this.onWatchStreamClose.bind(this),\n      onWatchChange: this.onWatchStreamChange.bind(this)\n    });\n\n    this.writeStream = newPersistentWriteStream(this.datastore, asyncQueue, {\n      onOpen: this.onWriteStreamOpen.bind(this),\n      onClose: this.onWriteStreamClose.bind(this),\n      onHandshakeComplete: this.onWriteHandshakeComplete.bind(this),\n      onMutationResult: this.onMutationResult.bind(this)\n    });\n  }\n\n  /**\n   * SyncEngine to notify of watch and write events. This must be set\n   * immediately after construction.\n   */\n  syncEngine!: RemoteSyncer;\n\n  /**\n   * Starts up the remote store, creating streams, restoring state from\n   * LocalStore, etc.\n   */\n  start(): Promise<void> {\n    return this.enableNetwork();\n  }\n\n  /** Re-enables the network. Idempotent. */\n  enableNetwork(): Promise<void> {\n    this.offlineCauses.delete(OfflineCause.UserDisabled);\n    return this.enableNetworkInternal();\n  }\n\n  private async enableNetworkInternal(): Promise<void> {\n    if (this.canUseNetwork()) {\n      if (this.shouldStartWatchStream()) {\n        this.startWatchStream();\n      } else {\n        this.onlineStateTracker.set(OnlineState.Unknown);\n      }\n\n      // This will start the write stream if necessary.\n      await this.fillWritePipeline();\n    }\n  }\n\n  /**\n   * Temporarily disables the network. The network can be re-enabled using\n   * enableNetwork().\n   */\n  async disableNetwork(): Promise<void> {\n    this.offlineCauses.add(OfflineCause.UserDisabled);\n    await this.disableNetworkInternal();\n\n    // Set the OnlineState to Offline so get()s return from cache, etc.\n    this.onlineStateTracker.set(OnlineState.Offline);\n  }\n\n  private async disableNetworkInternal(): Promise<void> {\n    await this.writeStream.stop();\n    await this.watchStream.stop();\n\n    if (this.writePipeline.length > 0) {\n      logDebug(\n        LOG_TAG,\n        `Stopping write stream with ${this.writePipeline.length} pending writes`\n      );\n      this.writePipeline = [];\n    }\n\n    this.cleanUpWatchStreamState();\n  }\n\n  async shutdown(): Promise<void> {\n    logDebug(LOG_TAG, 'RemoteStore shutting down.');\n    this.offlineCauses.add(OfflineCause.Shutdown);\n    await this.disableNetworkInternal();\n    this.connectivityMonitor.shutdown();\n\n    // Set the OnlineState to Unknown (rather than Offline) to avoid potentially\n    // triggering spurious listener events with cached data, etc.\n    this.onlineStateTracker.set(OnlineState.Unknown);\n  }\n\n  /**\n   * Starts new listen for the given target. Uses resume token if provided. It\n   * is a no-op if the target of given `TargetData` is already being listened to.\n   */\n  listen(targetData: TargetData): void {\n    if (this.listenTargets.has(targetData.targetId)) {\n      return;\n    }\n\n    // Mark this as something the client is currently listening for.\n    this.listenTargets.set(targetData.targetId, targetData);\n\n    if (this.shouldStartWatchStream()) {\n      // The listen will be sent in onWatchStreamOpen\n      this.startWatchStream();\n    } else if (this.watchStream.isOpen()) {\n      this.sendWatchRequest(targetData);\n    }\n  }\n\n  /**\n   * Removes the listen from server. It is a no-op if the given target id is\n   * not being listened to.\n   */\n  unlisten(targetId: TargetId): void {\n    debugAssert(\n      this.listenTargets.has(targetId),\n      `unlisten called on target no currently watched: ${targetId}`\n    );\n\n    this.listenTargets.delete(targetId);\n    if (this.watchStream.isOpen()) {\n      this.sendUnwatchRequest(targetId);\n    }\n\n    if (this.listenTargets.size === 0) {\n      if (this.watchStream.isOpen()) {\n        this.watchStream.markIdle();\n      } else if (this.canUseNetwork()) {\n        // Revert to OnlineState.Unknown if the watch stream is not open and we\n        // have no listeners, since without any listens to send we cannot\n        // confirm if the stream is healthy and upgrade to OnlineState.Online.\n        this.onlineStateTracker.set(OnlineState.Unknown);\n      }\n    }\n  }\n\n  /** {@link TargetMetadataProvider.getTargetDataForTarget} */\n  getTargetDataForTarget(targetId: TargetId): TargetData | null {\n    return this.listenTargets.get(targetId) || null;\n  }\n\n  /** {@link TargetMetadataProvider.getRemoteKeysForTarget} */\n  getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet {\n    return this.syncEngine.getRemoteKeysForTarget(targetId);\n  }\n\n  /**\n   * We need to increment the the expected number of pending responses we're due\n   * from watch so we wait for the ack to process any messages from this target.\n   */\n  private sendWatchRequest(targetData: TargetData): void {\n    this.watchChangeAggregator!.recordPendingTargetRequest(targetData.targetId);\n    this.watchStream.watch(targetData);\n  }\n\n  /**\n   * We need to increment the expected number of pending responses we're due\n   * from watch so we wait for the removal on the server before we process any\n   * messages from this target.\n   */\n  private sendUnwatchRequest(targetId: TargetId): void {\n    this.watchChangeAggregator!.recordPendingTargetRequest(targetId);\n    this.watchStream.unwatch(targetId);\n  }\n\n  private startWatchStream(): void {\n    debugAssert(\n      this.shouldStartWatchStream(),\n      'startWatchStream() called when shouldStartWatchStream() is false.'\n    );\n\n    this.watchChangeAggregator = new WatchChangeAggregator(this);\n    this.watchStream.start();\n    this.onlineStateTracker.handleWatchStreamStart();\n  }\n\n  /**\n   * Returns whether the watch stream should be started because it's necessary\n   * and has not yet been started.\n   */\n  private shouldStartWatchStream(): boolean {\n    return (\n      this.canUseNetwork() &&\n      !this.watchStream.isStarted() &&\n      this.listenTargets.size > 0\n    );\n  }\n\n  canUseNetwork(): boolean {\n    return this.offlineCauses.size === 0;\n  }\n\n  private cleanUpWatchStreamState(): void {\n    this.watchChangeAggregator = null;\n  }\n\n  private async onWatchStreamOpen(): Promise<void> {\n    this.listenTargets.forEach((targetData, targetId) => {\n      this.sendWatchRequest(targetData);\n    });\n  }\n\n  private async onWatchStreamClose(error?: FirestoreError): Promise<void> {\n    if (error === undefined) {\n      // Graceful stop (due to stop() or idle timeout). Make sure that's\n      // desirable.\n      debugAssert(\n        !this.shouldStartWatchStream(),\n        'Watch stream was stopped gracefully while still needed.'\n      );\n    }\n\n    this.cleanUpWatchStreamState();\n\n    // If we still need the watch stream, retry the connection.\n    if (this.shouldStartWatchStream()) {\n      this.onlineStateTracker.handleWatchStreamFailure(error!);\n\n      this.startWatchStream();\n    } else {\n      // No need to restart watch stream because there are no active targets.\n      // The online state is set to unknown because there is no active attempt\n      // at establishing a connection\n      this.onlineStateTracker.set(OnlineState.Unknown);\n    }\n  }\n\n  private async onWatchStreamChange(\n    watchChange: WatchChange,\n    snapshotVersion: SnapshotVersion\n  ): Promise<void> {\n    // Mark the client as online since we got a message from the server\n    this.onlineStateTracker.set(OnlineState.Online);\n\n    if (\n      watchChange instanceof WatchTargetChange &&\n      watchChange.state === WatchTargetChangeState.Removed &&\n      watchChange.cause\n    ) {\n      // There was an error on a target, don't wait for a consistent snapshot\n      // to raise events\n      try {\n        await this.handleTargetError(watchChange);\n      } catch (e) {\n        logDebug(\n          LOG_TAG,\n          'Failed to remove targets %s: %s ',\n          watchChange.targetIds.join(','),\n          e\n        );\n        await this.disableNetworkUntilRecovery(e);\n      }\n      return;\n    }\n\n    if (watchChange instanceof DocumentWatchChange) {\n      this.watchChangeAggregator!.handleDocumentChange(watchChange);\n    } else if (watchChange instanceof ExistenceFilterChange) {\n      this.watchChangeAggregator!.handleExistenceFilter(watchChange);\n    } else {\n      debugAssert(\n        watchChange instanceof WatchTargetChange,\n        'Expected watchChange to be an instance of WatchTargetChange'\n      );\n      this.watchChangeAggregator!.handleTargetChange(watchChange);\n    }\n\n    if (!snapshotVersion.isEqual(SnapshotVersion.min())) {\n      try {\n        const lastRemoteSnapshotVersion = await this.localStore.getLastRemoteSnapshotVersion();\n        if (snapshotVersion.compareTo(lastRemoteSnapshotVersion) >= 0) {\n          // We have received a target change with a global snapshot if the snapshot\n          // version is not equal to SnapshotVersion.min().\n          await this.raiseWatchSnapshot(snapshotVersion);\n        }\n      } catch (e) {\n        logDebug(LOG_TAG, 'Failed to raise snapshot:', e);\n        await this.disableNetworkUntilRecovery(e);\n      }\n    }\n  }\n\n  /**\n   * Recovery logic for IndexedDB errors that takes the network offline until\n   * `op` succeeds. Retries are scheduled with backoff using\n   * `enqueueRetryable()`. If `op()` is not provided, IndexedDB access is\n   * validated via a generic operation.\n   *\n   * The returned Promise is resolved once the network is disabled and before\n   * any retry attempt.\n   */\n  private async disableNetworkUntilRecovery(\n    e: FirestoreError,\n    op?: () => Promise<unknown>\n  ): Promise<void> {\n    if (isIndexedDbTransactionError(e)) {\n      debugAssert(\n        !this.offlineCauses.has(OfflineCause.IndexedDbFailed),\n        'Unexpected network event when IndexedDB was marked failed.'\n      );\n      this.offlineCauses.add(OfflineCause.IndexedDbFailed);\n\n      // Disable network and raise offline snapshots\n      await this.disableNetworkInternal();\n      this.onlineStateTracker.set(OnlineState.Offline);\n\n      if (!op) {\n        // Use a simple read operation to determine if IndexedDB recovered.\n        // Ideally, we would expose a health check directly on SimpleDb, but\n        // RemoteStore only has access to persistence through LocalStore.\n        op = () => this.localStore.getLastRemoteSnapshotVersion();\n      }\n\n      // Probe IndexedDB periodically and re-enable network\n      this.asyncQueue.enqueueRetryable(async () => {\n        logDebug(LOG_TAG, 'Retrying IndexedDB access');\n        await op!();\n        this.offlineCauses.delete(OfflineCause.IndexedDbFailed);\n        await this.enableNetworkInternal();\n      });\n    } else {\n      throw e;\n    }\n  }\n\n  /**\n   * Executes `op`. If `op` fails, takes the network offline until `op`\n   * succeeds. Returns after the first attempt.\n   */\n  private executeWithRecovery(op: () => Promise<void>): Promise<void> {\n    return op().catch(e => this.disableNetworkUntilRecovery(e, op));\n  }\n\n  /**\n   * Takes a batch of changes from the Datastore, repackages them as a\n   * RemoteEvent, and passes that on to the listener, which is typically the\n   * SyncEngine.\n   */\n  private raiseWatchSnapshot(snapshotVersion: SnapshotVersion): Promise<void> {\n    debugAssert(\n      !snapshotVersion.isEqual(SnapshotVersion.min()),\n      \"Can't raise event for unknown SnapshotVersion\"\n    );\n    const remoteEvent = this.watchChangeAggregator!.createRemoteEvent(\n      snapshotVersion\n    );\n\n    // Update in-memory resume tokens. LocalStore will update the\n    // persistent view of these when applying the completed RemoteEvent.\n    remoteEvent.targetChanges.forEach((change, targetId) => {\n      if (change.resumeToken.approximateByteSize() > 0) {\n        const targetData = this.listenTargets.get(targetId);\n        // A watched target might have been removed already.\n        if (targetData) {\n          this.listenTargets.set(\n            targetId,\n            targetData.withResumeToken(change.resumeToken, snapshotVersion)\n          );\n        }\n      }\n    });\n\n    // Re-establish listens for the targets that have been invalidated by\n    // existence filter mismatches.\n    remoteEvent.targetMismatches.forEach(targetId => {\n      const targetData = this.listenTargets.get(targetId);\n      if (!targetData) {\n        // A watched target might have been removed already.\n        return;\n      }\n\n      // Clear the resume token for the target, since we're in a known mismatch\n      // state.\n      this.listenTargets.set(\n        targetId,\n        targetData.withResumeToken(\n          ByteString.EMPTY_BYTE_STRING,\n          targetData.snapshotVersion\n        )\n      );\n\n      // Cause a hard reset by unwatching and rewatching immediately, but\n      // deliberately don't send a resume token so that we get a full update.\n      this.sendUnwatchRequest(targetId);\n\n      // Mark the target we send as being on behalf of an existence filter\n      // mismatch, but don't actually retain that in listenTargets. This ensures\n      // that we flag the first re-listen this way without impacting future\n      // listens of this target (that might happen e.g. on reconnect).\n      const requestTargetData = new TargetData(\n        targetData.target,\n        targetId,\n        TargetPurpose.ExistenceFilterMismatch,\n        targetData.sequenceNumber\n      );\n      this.sendWatchRequest(requestTargetData);\n    });\n\n    // Finally raise remote event\n    return this.syncEngine.applyRemoteEvent(remoteEvent);\n  }\n\n  /** Handles an error on a target */\n  private async handleTargetError(\n    watchChange: WatchTargetChange\n  ): Promise<void> {\n    debugAssert(!!watchChange.cause, 'Handling target error without a cause');\n    const error = watchChange.cause!;\n    for (const targetId of watchChange.targetIds) {\n      // A watched target might have been removed already.\n      if (this.listenTargets.has(targetId)) {\n        await this.syncEngine.rejectListen(targetId, error);\n        this.listenTargets.delete(targetId);\n        this.watchChangeAggregator!.removeTarget(targetId);\n      }\n    }\n  }\n\n  /**\n   * Attempts to fill our write pipeline with writes from the LocalStore.\n   *\n   * Called internally to bootstrap or refill the write pipeline and by\n   * SyncEngine whenever there are new mutations to process.\n   *\n   * Starts the write stream if necessary.\n   */\n  async fillWritePipeline(): Promise<void> {\n    let lastBatchIdRetrieved =\n      this.writePipeline.length > 0\n        ? this.writePipeline[this.writePipeline.length - 1].batchId\n        : BATCHID_UNKNOWN;\n\n    while (this.canAddToWritePipeline()) {\n      try {\n        const batch = await this.localStore.nextMutationBatch(\n          lastBatchIdRetrieved\n        );\n\n        if (batch === null) {\n          if (this.writePipeline.length === 0) {\n            this.writeStream.markIdle();\n          }\n          break;\n        } else {\n          lastBatchIdRetrieved = batch.batchId;\n          this.addToWritePipeline(batch);\n        }\n      } catch (e) {\n        await this.disableNetworkUntilRecovery(e);\n      }\n    }\n\n    if (this.shouldStartWriteStream()) {\n      this.startWriteStream();\n    }\n  }\n\n  /**\n   * Returns true if we can add to the write pipeline (i.e. the network is\n   * enabled and the write pipeline is not full).\n   */\n  private canAddToWritePipeline(): boolean {\n    return (\n      this.canUseNetwork() && this.writePipeline.length < MAX_PENDING_WRITES\n    );\n  }\n\n  // For testing\n  outstandingWrites(): number {\n    return this.writePipeline.length;\n  }\n\n  /**\n   * Queues additional writes to be sent to the write stream, sending them\n   * immediately if the write stream is established.\n   */\n  private addToWritePipeline(batch: MutationBatch): void {\n    debugAssert(\n      this.canAddToWritePipeline(),\n      'addToWritePipeline called when pipeline is full'\n    );\n    this.writePipeline.push(batch);\n\n    if (this.writeStream.isOpen() && this.writeStream.handshakeComplete) {\n      this.writeStream.writeMutations(batch.mutations);\n    }\n  }\n\n  private shouldStartWriteStream(): boolean {\n    return (\n      this.canUseNetwork() &&\n      !this.writeStream.isStarted() &&\n      this.writePipeline.length > 0\n    );\n  }\n\n  private startWriteStream(): void {\n    debugAssert(\n      this.shouldStartWriteStream(),\n      'startWriteStream() called when shouldStartWriteStream() is false.'\n    );\n    this.writeStream.start();\n  }\n\n  private async onWriteStreamOpen(): Promise<void> {\n    this.writeStream.writeHandshake();\n  }\n\n  private async onWriteHandshakeComplete(): Promise<void> {\n    // Send the write pipeline now that the stream is established.\n    for (const batch of this.writePipeline) {\n      this.writeStream.writeMutations(batch.mutations);\n    }\n  }\n\n  private async onMutationResult(\n    commitVersion: SnapshotVersion,\n    results: MutationResult[]\n  ): Promise<void> {\n    // This is a response to a write containing mutations and should be\n    // correlated to the first write in our write pipeline.\n    debugAssert(\n      this.writePipeline.length > 0,\n      'Got result for empty write pipeline'\n    );\n    const batch = this.writePipeline.shift()!;\n    const success = MutationBatchResult.from(batch, commitVersion, results);\n\n    await this.executeWithRecovery(() =>\n      this.syncEngine.applySuccessfulWrite(success)\n    );\n\n    // It's possible that with the completion of this mutation another\n    // slot has freed up.\n    await this.fillWritePipeline();\n  }\n\n  private async onWriteStreamClose(error?: FirestoreError): Promise<void> {\n    if (error === undefined) {\n      // Graceful stop (due to stop() or idle timeout). Make sure that's\n      // desirable.\n      debugAssert(\n        !this.shouldStartWriteStream(),\n        'Write stream was stopped gracefully while still needed.'\n      );\n    }\n\n    // If the write stream closed after the write handshake completes, a write\n    // operation failed and we fail the pending operation.\n    if (error && this.writeStream.handshakeComplete) {\n      // This error affects the actual write.\n      await this.handleWriteError(error!);\n    }\n\n    // The write stream might have been started by refilling the write\n    // pipeline for failed writes\n    if (this.shouldStartWriteStream()) {\n      this.startWriteStream();\n    }\n  }\n\n  private async handleWriteError(error: FirestoreError): Promise<void> {\n    // Only handle permanent errors here. If it's transient, just let the retry\n    // logic kick in.\n    if (isPermanentWriteError(error.code)) {\n      // This was a permanent error, the request itself was the problem\n      // so it's not going to succeed if we resend it.\n      const batch = this.writePipeline.shift()!;\n\n      // In this case it's also unlikely that the server itself is melting\n      // down -- this was just a bad request so inhibit backoff on the next\n      // restart.\n      this.writeStream.inhibitBackoff();\n\n      await this.executeWithRecovery(() =>\n        this.syncEngine.rejectFailedWrite(batch.batchId, error)\n      );\n\n      // It's possible that with the completion of this mutation\n      // another slot has freed up.\n      await this.fillWritePipeline();\n    } else {\n      // Transient error, just let the retry logic kick in.\n    }\n  }\n\n  private async restartNetwork(): Promise<void> {\n    this.offlineCauses.add(OfflineCause.ConnectivityChange);\n    await this.disableNetworkInternal();\n    this.onlineStateTracker.set(OnlineState.Unknown);\n    this.writeStream.inhibitBackoff();\n    this.watchStream.inhibitBackoff();\n    this.offlineCauses.delete(OfflineCause.ConnectivityChange);\n    await this.enableNetworkInternal();\n  }\n\n  async handleCredentialChange(user: User): Promise<void> {\n    this.asyncQueue.verifyOperationInProgress();\n\n    // Tear down and re-create our network streams. This will ensure we get a\n    // fresh auth token for the new user and re-fill the write pipeline with\n    // new mutations from the LocalStore (since mutations are per-user).\n    logDebug(LOG_TAG, 'RemoteStore received new credentials');\n    this.offlineCauses.add(OfflineCause.CredentialChange);\n\n    await this.disableNetworkInternal();\n    this.onlineStateTracker.set(OnlineState.Unknown);\n    await this.syncEngine.handleCredentialChange(user);\n\n    this.offlineCauses.delete(OfflineCause.CredentialChange);\n    await this.enableNetworkInternal();\n  }\n\n  /**\n   * Toggles the network state when the client gains or loses its primary lease.\n   */\n  async applyPrimaryState(isPrimary: boolean): Promise<void> {\n    if (isPrimary) {\n      this.offlineCauses.delete(OfflineCause.IsSecondary);\n      await this.enableNetworkInternal();\n    } else if (!isPrimary) {\n      this.offlineCauses.add(OfflineCause.IsSecondary);\n      await this.disableNetworkInternal();\n      this.onlineStateTracker.set(OnlineState.Unknown);\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 { BatchId, MutationBatchState, TargetId } from '../core/types';\nimport { QueryTargetState } from './shared_client_state_syncer';\nimport { debugAssert } from '../util/assert';\nimport { ClientId } from './shared_client_state';\nimport { User } from '../auth/user';\n\n// The format of the LocalStorage key that stores the client state is:\n//     firestore_clients_<persistence_prefix>_<instance_key>\nexport const CLIENT_STATE_KEY_PREFIX = 'firestore_clients';\n\n/** Assembles the key for a client state in WebStorage */\nexport function createWebStorageClientStateKey(\n  persistenceKey: string,\n  clientId: ClientId\n): string {\n  debugAssert(\n    clientId.indexOf('_') === -1,\n    `Client key cannot contain '_', but was '${clientId}'`\n  );\n\n  return `${CLIENT_STATE_KEY_PREFIX}_${persistenceKey}_${clientId}`;\n}\n\n/**\n * The JSON representation of a clients's metadata as used during WebStorage\n * serialization. The ClientId is omitted here as it is encoded as part of the\n * key.\n */\nexport interface ClientStateSchema {\n  activeTargetIds: number[];\n  updateTimeMs: number;\n}\n\n// The format of the WebStorage key that stores the mutation state is:\n//     firestore_mutations_<persistence_prefix>_<batch_id>\n//     (for unauthenticated users)\n// or: firestore_mutations_<persistence_prefix>_<batch_id>_<user_uid>\n//\n// 'user_uid' is last to avoid needing to escape '_' characters that it might\n// contain.\nexport const MUTATION_BATCH_KEY_PREFIX = 'firestore_mutations';\n\n/** Assembles the key for a mutation batch in WebStorage */\nexport function createWebStorageMutationBatchKey(\n  persistenceKey: string,\n  user: User,\n  batchId: BatchId\n): string {\n  let mutationKey = `${MUTATION_BATCH_KEY_PREFIX}_${persistenceKey}_${batchId}`;\n\n  if (user.isAuthenticated()) {\n    mutationKey += `_${user.uid}`;\n  }\n\n  return mutationKey;\n}\n\n/**\n * The JSON representation of a mutation batch's metadata as used during\n * WebStorage serialization. The UserId and BatchId is omitted as it is\n * encoded as part of the key.\n */\nexport interface MutationMetadataSchema {\n  state: MutationBatchState;\n  error?: { code: string; message: string }; // Only set when state === 'rejected'\n  updateTimeMs: number;\n}\n\n// The format of the WebStorage key that stores a query target's metadata is:\n//     firestore_targets_<persistence_prefix>_<target_id>\nexport const QUERY_TARGET_KEY_PREFIX = 'firestore_targets';\n\n/** Assembles the key for a query state in WebStorage */\nexport function createWebStorageQueryTargetMetadataKey(\n  persistenceKey: string,\n  targetId: TargetId\n): string {\n  return `${QUERY_TARGET_KEY_PREFIX}_${persistenceKey}_${targetId}`;\n}\n\n/**\n * The JSON representation of a query target's state as used during WebStorage\n * serialization. The TargetId is omitted as it is encoded as part of the key.\n */\nexport interface QueryTargetStateSchema {\n  state: QueryTargetState;\n  error?: { code: string; message: string }; // Only set when state === 'rejected'\n  updateTimeMs: number;\n}\n\n// The WebStorage prefix that stores the primary tab's online state. The\n// format of the key is:\n//     firestore_online_state_<persistence_prefix>\nexport const ONLINE_STATE_KEY_PREFIX = 'firestore_online_state';\n\n/** Assembles the key for the online state of the primary tab. */\nexport function createWebStorageOnlineStateKey(persistenceKey: string): string {\n  return `${ONLINE_STATE_KEY_PREFIX}_${persistenceKey}`;\n}\n\n/**\n * The JSON representation of the system's online state, as written by the\n * primary client.\n */\nexport interface SharedOnlineStateSchema {\n  /**\n   * The clientId of the client that wrote this onlineState value. Tracked so\n   * that on startup, clients can check if this client is still active when\n   * determining whether to apply this value or not.\n   */\n  readonly clientId: string;\n  readonly onlineState: string;\n}\n\n// The WebStorage key prefix for the key that stores the last sequence number allocated. The key\n// looks like 'firestore_sequence_number_<persistence_prefix>'.\nexport const SEQUENCE_NUMBER_KEY_PREFIX = 'firestore_sequence_number';\n\n/** Assembles the key for the current sequence number. */\nexport function createWebStorageSequenceNumberKey(\n  persistenceKey: string\n): string {\n  return `${SEQUENCE_NUMBER_KEY_PREFIX}_${persistenceKey}`;\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 { User } from '../auth/user';\nimport { ListenSequence } from '../core/listen_sequence';\nimport {\n  BatchId,\n  ListenSequenceNumber,\n  MutationBatchState,\n  OnlineState,\n  TargetId\n} from '../core/types';\nimport { TargetIdSet, targetIdSet } from '../model/collections';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\nimport { SortedSet } from '../util/sorted_set';\nimport { SortedMap } from '../util/sorted_map';\nimport { primitiveComparator } from '../util/misc';\nimport { isSafeInteger, WindowLike } from '../util/types';\nimport {\n  QueryTargetState,\n  SharedClientStateSyncer\n} from './shared_client_state_syncer';\nimport {\n  CLIENT_STATE_KEY_PREFIX,\n  ClientStateSchema,\n  createWebStorageClientStateKey,\n  createWebStorageMutationBatchKey,\n  createWebStorageOnlineStateKey,\n  createWebStorageQueryTargetMetadataKey,\n  createWebStorageSequenceNumberKey,\n  MUTATION_BATCH_KEY_PREFIX,\n  MutationMetadataSchema,\n  QUERY_TARGET_KEY_PREFIX,\n  QueryTargetStateSchema,\n  SharedOnlineStateSchema\n} from './shared_client_state_schema';\n\nconst LOG_TAG = 'SharedClientState';\n\n/**\n * A randomly-generated key assigned to each Firestore instance at startup.\n */\nexport type ClientId = string;\n\n/**\n * A `SharedClientState` keeps track of the global state of the mutations\n * and query targets for all active clients with the same persistence key (i.e.\n * project ID and FirebaseApp name). It relays local changes to other clients\n * and updates its local state as new state is observed.\n *\n * `SharedClientState` is primarily used for synchronization in Multi-Tab\n * environments. Each tab is responsible for registering its active query\n * targets and mutations. `SharedClientState` will then notify the listener\n * assigned to `.syncEngine` for updates to mutations and queries that\n * originated in other clients.\n *\n * To receive notifications, `.syncEngine` and `.onlineStateHandler` has to be\n * assigned before calling `start()`.\n */\nexport interface SharedClientState {\n  onlineStateHandler: ((onlineState: OnlineState) => void) | null;\n  sequenceNumberHandler:\n    | ((sequenceNumber: ListenSequenceNumber) => void)\n    | null;\n\n  /** Registers the Mutation Batch ID of a newly pending mutation. */\n  addPendingMutation(batchId: BatchId): void;\n\n  /**\n   * Records that a pending mutation has been acknowledged or rejected.\n   * Called by the primary client to notify secondary clients of mutation\n   * results as they come back from the backend.\n   */\n  updateMutationState(\n    batchId: BatchId,\n    state: 'acknowledged' | 'rejected',\n    error?: FirestoreError\n  ): void;\n\n  /**\n   * Associates a new Query Target ID with the local Firestore client. Returns\n   * the new query state for the query (which can be 'current' if the query is\n   * already associated with another tab).\n   *\n   * If the target id is already associated with local client, the method simply\n   * returns its `QueryTargetState`.\n   */\n  addLocalQueryTarget(targetId: TargetId): QueryTargetState;\n\n  /** Removes the Query Target ID association from the local client. */\n  removeLocalQueryTarget(targetId: TargetId): void;\n\n  /** Checks whether the target is associated with the local client. */\n  isLocalQueryTarget(targetId: TargetId): boolean;\n\n  /**\n   * Processes an update to a query target.\n   *\n   * Called by the primary client to notify secondary clients of document\n   * changes or state transitions that affect the provided query target.\n   */\n  updateQueryState(\n    targetId: TargetId,\n    state: QueryTargetState,\n    error?: FirestoreError\n  ): void;\n\n  /**\n   * Removes the target's metadata entry.\n   *\n   * Called by the primary client when all clients stopped listening to a query\n   * target.\n   */\n  clearQueryState(targetId: TargetId): void;\n\n  /**\n   * Gets the active Query Targets IDs for all active clients.\n   *\n   * The implementation for this may require O(n) runtime, where 'n' is the size\n   * of the result set.\n   */\n  // Visible for testing\n  getAllActiveQueryTargets(): SortedSet<TargetId>;\n\n  /**\n   * Checks whether the provided target ID is currently being listened to by\n   * any of the active clients.\n   *\n   * The implementation may require O(n*log m) runtime, where 'n' is the number\n   * of clients and 'm' the number of targets.\n   */\n  isActiveQueryTarget(targetId: TargetId): boolean;\n\n  /**\n   * Starts the SharedClientState, reads existing client data and registers\n   * listeners for updates to new and existing clients.\n   */\n  start(): Promise<void>;\n\n  /** Shuts down the `SharedClientState` and its listeners. */\n  shutdown(): void;\n\n  /**\n   * Changes the active user and removes all existing user-specific data. The\n   * user change does not call back into SyncEngine (for example, no mutations\n   * will be marked as removed).\n   */\n  handleUserChange(\n    user: User,\n    removedBatchIds: BatchId[],\n    addedBatchIds: BatchId[]\n  ): void;\n\n  /** Changes the shared online state of all clients. */\n  setOnlineState(onlineState: OnlineState): void;\n\n  writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void;\n}\n\n/**\n * Holds the state of a mutation batch, including its user ID, batch ID and\n * whether the batch is 'pending', 'acknowledged' or 'rejected'.\n */\n// Visible for testing\nexport class MutationMetadata {\n  constructor(\n    readonly user: User,\n    readonly batchId: BatchId,\n    readonly state: MutationBatchState,\n    readonly error?: FirestoreError\n  ) {\n    debugAssert(\n      (error !== undefined) === (state === 'rejected'),\n      `MutationMetadata must contain an error iff state is 'rejected'`\n    );\n  }\n\n  /**\n   * Parses a MutationMetadata from its JSON representation in WebStorage.\n   * Logs a warning and returns null if the format of the data is not valid.\n   */\n  static fromWebStorageEntry(\n    user: User,\n    batchId: BatchId,\n    value: string\n  ): MutationMetadata | null {\n    const mutationBatch = JSON.parse(value) as MutationMetadataSchema;\n\n    let validData =\n      typeof mutationBatch === 'object' &&\n      ['pending', 'acknowledged', 'rejected'].indexOf(mutationBatch.state) !==\n        -1 &&\n      (mutationBatch.error === undefined ||\n        typeof mutationBatch.error === 'object');\n\n    let firestoreError: FirestoreError | undefined = undefined;\n\n    if (validData && mutationBatch.error) {\n      validData =\n        typeof mutationBatch.error.message === 'string' &&\n        typeof mutationBatch.error.code === 'string';\n      if (validData) {\n        firestoreError = new FirestoreError(\n          mutationBatch.error.code as Code,\n          mutationBatch.error.message\n        );\n      }\n    }\n\n    if (validData) {\n      return new MutationMetadata(\n        user,\n        batchId,\n        mutationBatch.state,\n        firestoreError\n      );\n    } else {\n      logError(\n        LOG_TAG,\n        `Failed to parse mutation state for ID '${batchId}': ${value}`\n      );\n      return null;\n    }\n  }\n\n  toWebStorageJSON(): string {\n    const batchMetadata: MutationMetadataSchema = {\n      state: this.state,\n      updateTimeMs: Date.now() // Modify the existing value to trigger update.\n    };\n\n    if (this.error) {\n      batchMetadata.error = {\n        code: this.error.code,\n        message: this.error.message\n      };\n    }\n\n    return JSON.stringify(batchMetadata);\n  }\n}\n\n/**\n * Holds the state of a query target, including its target ID and whether the\n * target is 'not-current', 'current' or 'rejected'.\n */\n// Visible for testing\nexport class QueryTargetMetadata {\n  constructor(\n    readonly targetId: TargetId,\n    readonly state: QueryTargetState,\n    readonly error?: FirestoreError\n  ) {\n    debugAssert(\n      (error !== undefined) === (state === 'rejected'),\n      `QueryTargetMetadata must contain an error iff state is 'rejected'`\n    );\n  }\n\n  /**\n   * Parses a QueryTargetMetadata from its JSON representation in WebStorage.\n   * Logs a warning and returns null if the format of the data is not valid.\n   */\n  static fromWebStorageEntry(\n    targetId: TargetId,\n    value: string\n  ): QueryTargetMetadata | null {\n    const targetState = JSON.parse(value) as QueryTargetStateSchema;\n\n    let validData =\n      typeof targetState === 'object' &&\n      ['not-current', 'current', 'rejected'].indexOf(targetState.state) !==\n        -1 &&\n      (targetState.error === undefined ||\n        typeof targetState.error === 'object');\n\n    let firestoreError: FirestoreError | undefined = undefined;\n\n    if (validData && targetState.error) {\n      validData =\n        typeof targetState.error.message === 'string' &&\n        typeof targetState.error.code === 'string';\n      if (validData) {\n        firestoreError = new FirestoreError(\n          targetState.error.code as Code,\n          targetState.error.message\n        );\n      }\n    }\n\n    if (validData) {\n      return new QueryTargetMetadata(\n        targetId,\n        targetState.state,\n        firestoreError\n      );\n    } else {\n      logError(\n        LOG_TAG,\n        `Failed to parse target state for ID '${targetId}': ${value}`\n      );\n      return null;\n    }\n  }\n\n  toWebStorageJSON(): string {\n    const targetState: QueryTargetStateSchema = {\n      state: this.state,\n      updateTimeMs: Date.now() // Modify the existing value to trigger update.\n    };\n\n    if (this.error) {\n      targetState.error = {\n        code: this.error.code,\n        message: this.error.message\n      };\n    }\n\n    return JSON.stringify(targetState);\n  }\n}\n\n/**\n * Metadata state of a single client denoting the query targets it is actively\n * listening to.\n */\n// Visible for testing.\nexport interface ClientState {\n  readonly activeTargetIds: TargetIdSet;\n}\n\n/**\n * This class represents the immutable ClientState for a client read from\n * WebStorage, containing the list of active query targets.\n */\nclass RemoteClientState implements ClientState {\n  private constructor(\n    readonly clientId: ClientId,\n    readonly activeTargetIds: TargetIdSet\n  ) {}\n\n  /**\n   * Parses a RemoteClientState from the JSON representation in WebStorage.\n   * Logs a warning and returns null if the format of the data is not valid.\n   */\n  static fromWebStorageEntry(\n    clientId: ClientId,\n    value: string\n  ): RemoteClientState | null {\n    const clientState = JSON.parse(value) as ClientStateSchema;\n\n    let validData =\n      typeof clientState === 'object' &&\n      clientState.activeTargetIds instanceof Array;\n\n    let activeTargetIdsSet = targetIdSet();\n\n    for (let i = 0; validData && i < clientState.activeTargetIds.length; ++i) {\n      validData = isSafeInteger(clientState.activeTargetIds[i]);\n      activeTargetIdsSet = activeTargetIdsSet.add(\n        clientState.activeTargetIds[i]\n      );\n    }\n\n    if (validData) {\n      return new RemoteClientState(clientId, activeTargetIdsSet);\n    } else {\n      logError(\n        LOG_TAG,\n        `Failed to parse client data for instance '${clientId}': ${value}`\n      );\n      return null;\n    }\n  }\n}\n\n/**\n * This class represents the online state for all clients participating in\n * multi-tab. The online state is only written to by the primary client, and\n * used in secondary clients to update their query views.\n */\nexport class SharedOnlineState {\n  constructor(readonly clientId: string, readonly onlineState: OnlineState) {}\n\n  /**\n   * Parses a SharedOnlineState from its JSON representation in WebStorage.\n   * Logs a warning and returns null if the format of the data is not valid.\n   */\n  static fromWebStorageEntry(value: string): SharedOnlineState | null {\n    const onlineState = JSON.parse(value) as SharedOnlineStateSchema;\n\n    const validData =\n      typeof onlineState === 'object' &&\n      ['Unknown', 'Online', 'Offline'].indexOf(onlineState.onlineState) !==\n        -1 &&\n      typeof onlineState.clientId === 'string';\n\n    if (validData) {\n      return new SharedOnlineState(\n        onlineState.clientId,\n        onlineState.onlineState as OnlineState\n      );\n    } else {\n      logError(LOG_TAG, `Failed to parse online state: ${value}`);\n      return null;\n    }\n  }\n}\n\n/**\n * Metadata state of the local client. Unlike `RemoteClientState`, this class is\n * mutable and keeps track of all pending mutations, which allows us to\n * update the range of pending mutation batch IDs as new mutations are added or\n * removed.\n *\n * The data in `LocalClientState` is not read from WebStorage and instead\n * updated via its instance methods. The updated state can be serialized via\n * `toWebStorageJSON()`.\n */\n// Visible for testing.\nexport class LocalClientState implements ClientState {\n  activeTargetIds = targetIdSet();\n\n  addQueryTarget(targetId: TargetId): void {\n    this.activeTargetIds = this.activeTargetIds.add(targetId);\n  }\n\n  removeQueryTarget(targetId: TargetId): void {\n    this.activeTargetIds = this.activeTargetIds.delete(targetId);\n  }\n\n  /**\n   * Converts this entry into a JSON-encoded format we can use for WebStorage.\n   * Does not encode `clientId` as it is part of the key in WebStorage.\n   */\n  toWebStorageJSON(): string {\n    const data: ClientStateSchema = {\n      activeTargetIds: this.activeTargetIds.toArray(),\n      updateTimeMs: Date.now() // Modify the existing value to trigger update.\n    };\n    return JSON.stringify(data);\n  }\n}\n\n/**\n * `WebStorageSharedClientState` uses WebStorage (window.localStorage) as the\n * backing store for the SharedClientState. It keeps track of all active\n * clients and supports modifications of the local client's data.\n */\nexport class WebStorageSharedClientState implements SharedClientState {\n  syncEngine: SharedClientStateSyncer | null = null;\n  onlineStateHandler: ((onlineState: OnlineState) => void) | null = null;\n  sequenceNumberHandler:\n    | ((sequenceNumber: ListenSequenceNumber) => void)\n    | null = null;\n\n  private readonly storage: Storage;\n  private readonly localClientStorageKey: string;\n  private readonly sequenceNumberKey: string;\n  private readonly storageListener = this.handleWebStorageEvent.bind(this);\n  private readonly onlineStateKey: string;\n  private readonly clientStateKeyRe: RegExp;\n  private readonly mutationBatchKeyRe: RegExp;\n  private readonly queryTargetKeyRe: RegExp;\n  private activeClients = new SortedMap<string, ClientState>(\n    primitiveComparator\n  );\n  private started = false;\n  private currentUser: User;\n\n  /**\n   * Captures WebStorage events that occur before `start()` is called. These\n   * events are replayed once `WebStorageSharedClientState` is started.\n   */\n  private earlyEvents: StorageEvent[] = [];\n\n  constructor(\n    private readonly window: WindowLike,\n    private readonly queue: AsyncQueue,\n    private readonly persistenceKey: string,\n    private readonly localClientId: ClientId,\n    initialUser: User\n  ) {\n    // Escape the special characters mentioned here:\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n    const escapedPersistenceKey = persistenceKey.replace(\n      /[.*+?^${}()|[\\]\\\\]/g,\n      '\\\\$&'\n    );\n\n    this.storage = this.window.localStorage;\n    this.currentUser = initialUser;\n    this.localClientStorageKey = createWebStorageClientStateKey(\n      this.persistenceKey,\n      this.localClientId\n    );\n    this.sequenceNumberKey = createWebStorageSequenceNumberKey(\n      this.persistenceKey\n    );\n    this.activeClients = this.activeClients.insert(\n      this.localClientId,\n      new LocalClientState()\n    );\n\n    this.clientStateKeyRe = new RegExp(\n      `^${CLIENT_STATE_KEY_PREFIX}_${escapedPersistenceKey}_([^_]*)$`\n    );\n    this.mutationBatchKeyRe = new RegExp(\n      `^${MUTATION_BATCH_KEY_PREFIX}_${escapedPersistenceKey}_(\\\\d+)(?:_(.*))?$`\n    );\n    this.queryTargetKeyRe = new RegExp(\n      `^${QUERY_TARGET_KEY_PREFIX}_${escapedPersistenceKey}_(\\\\d+)$`\n    );\n\n    this.onlineStateKey = createWebStorageOnlineStateKey(this.persistenceKey);\n\n    // Rather than adding the storage observer during start(), we add the\n    // storage observer during initialization. This ensures that we collect\n    // events before other components populate their initial state (during their\n    // respective start() calls). Otherwise, we might for example miss a\n    // mutation that is added after LocalStore's start() processed the existing\n    // mutations but before we observe WebStorage events.\n    this.window.addEventListener('storage', this.storageListener);\n  }\n\n  /** Returns 'true' if WebStorage is available in the current environment. */\n  static isAvailable(window: WindowLike | null): window is WindowLike {\n    return !!(window && window.localStorage);\n  }\n\n  async start(): Promise<void> {\n    debugAssert(!this.started, 'WebStorageSharedClientState already started');\n    debugAssert(\n      this.syncEngine !== null,\n      'syncEngine property must be set before calling start()'\n    );\n    debugAssert(\n      this.onlineStateHandler !== null,\n      'onlineStateHandler property must be set before calling start()'\n    );\n\n    // Retrieve the list of existing clients to backfill the data in\n    // SharedClientState.\n    const existingClients = await this.syncEngine!.getActiveClients();\n\n    for (const clientId of existingClients) {\n      if (clientId === this.localClientId) {\n        continue;\n      }\n\n      const storageItem = this.getItem(\n        createWebStorageClientStateKey(this.persistenceKey, clientId)\n      );\n      if (storageItem) {\n        const clientState = RemoteClientState.fromWebStorageEntry(\n          clientId,\n          storageItem\n        );\n        if (clientState) {\n          this.activeClients = this.activeClients.insert(\n            clientState.clientId,\n            clientState\n          );\n        }\n      }\n    }\n\n    this.persistClientState();\n\n    // Check if there is an existing online state and call the callback handler\n    // if applicable.\n    const onlineStateJSON = this.storage.getItem(this.onlineStateKey);\n    if (onlineStateJSON) {\n      const onlineState = this.fromWebStorageOnlineState(onlineStateJSON);\n      if (onlineState) {\n        this.handleOnlineStateEvent(onlineState);\n      }\n    }\n\n    for (const event of this.earlyEvents) {\n      this.handleWebStorageEvent(event);\n    }\n\n    this.earlyEvents = [];\n\n    // Register a window unload hook to remove the client metadata entry from\n    // WebStorage even if `shutdown()` was not called.\n    this.window.addEventListener('unload', () => this.shutdown());\n\n    this.started = true;\n  }\n\n  writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void {\n    this.setItem(this.sequenceNumberKey, JSON.stringify(sequenceNumber));\n  }\n\n  getAllActiveQueryTargets(): TargetIdSet {\n    return this.extractActiveQueryTargets(this.activeClients);\n  }\n\n  isActiveQueryTarget(targetId: TargetId): boolean {\n    let found = false;\n    this.activeClients.forEach((key, value) => {\n      if (value.activeTargetIds.has(targetId)) {\n        found = true;\n      }\n    });\n    return found;\n  }\n\n  addPendingMutation(batchId: BatchId): void {\n    this.persistMutationState(batchId, 'pending');\n  }\n\n  updateMutationState(\n    batchId: BatchId,\n    state: 'acknowledged' | 'rejected',\n    error?: FirestoreError\n  ): void {\n    this.persistMutationState(batchId, state, error);\n\n    // Once a final mutation result is observed by other clients, they no longer\n    // access the mutation's metadata entry. Since WebStorage replays events\n    // in order, it is safe to delete the entry right after updating it.\n    this.removeMutationState(batchId);\n  }\n\n  addLocalQueryTarget(targetId: TargetId): QueryTargetState {\n    let queryState: QueryTargetState = 'not-current';\n\n    // Lookup an existing query state if the target ID was already registered\n    // by another tab\n    if (this.isActiveQueryTarget(targetId)) {\n      const storageItem = this.storage.getItem(\n        createWebStorageQueryTargetMetadataKey(this.persistenceKey, targetId)\n      );\n\n      if (storageItem) {\n        const metadata = QueryTargetMetadata.fromWebStorageEntry(\n          targetId,\n          storageItem\n        );\n        if (metadata) {\n          queryState = metadata.state;\n        }\n      }\n    }\n\n    this.localClientState.addQueryTarget(targetId);\n    this.persistClientState();\n\n    return queryState;\n  }\n\n  removeLocalQueryTarget(targetId: TargetId): void {\n    this.localClientState.removeQueryTarget(targetId);\n    this.persistClientState();\n  }\n\n  isLocalQueryTarget(targetId: TargetId): boolean {\n    return this.localClientState.activeTargetIds.has(targetId);\n  }\n\n  clearQueryState(targetId: TargetId): void {\n    this.removeItem(\n      createWebStorageQueryTargetMetadataKey(this.persistenceKey, targetId)\n    );\n  }\n\n  updateQueryState(\n    targetId: TargetId,\n    state: QueryTargetState,\n    error?: FirestoreError\n  ): void {\n    this.persistQueryTargetState(targetId, state, error);\n  }\n\n  handleUserChange(\n    user: User,\n    removedBatchIds: BatchId[],\n    addedBatchIds: BatchId[]\n  ): void {\n    removedBatchIds.forEach(batchId => {\n      this.removeMutationState(batchId);\n    });\n    this.currentUser = user;\n    addedBatchIds.forEach(batchId => {\n      this.addPendingMutation(batchId);\n    });\n  }\n\n  setOnlineState(onlineState: OnlineState): void {\n    this.persistOnlineState(onlineState);\n  }\n\n  shutdown(): void {\n    if (this.started) {\n      this.window.removeEventListener('storage', this.storageListener);\n      this.removeItem(this.localClientStorageKey);\n      this.started = false;\n    }\n  }\n\n  private getItem(key: string): string | null {\n    const value = this.storage.getItem(key);\n    logDebug(LOG_TAG, 'READ', key, value);\n    return value;\n  }\n\n  private setItem(key: string, value: string): void {\n    logDebug(LOG_TAG, 'SET', key, value);\n    this.storage.setItem(key, value);\n  }\n\n  private removeItem(key: string): void {\n    logDebug(LOG_TAG, 'REMOVE', key);\n    this.storage.removeItem(key);\n  }\n\n  private handleWebStorageEvent(event: Event): void {\n    // Note: The function is typed to take Event to be interface-compatible with\n    // `Window.addEventListener`.\n    const storageEvent = event as StorageEvent;\n    if (storageEvent.storageArea === this.storage) {\n      logDebug(LOG_TAG, 'EVENT', storageEvent.key, storageEvent.newValue);\n\n      if (storageEvent.key === this.localClientStorageKey) {\n        logError(\n          'Received WebStorage notification for local change. Another client might have ' +\n            'garbage-collected our state'\n        );\n        return;\n      }\n\n      this.queue.enqueueRetryable(async () => {\n        if (!this.started) {\n          this.earlyEvents.push(storageEvent);\n          return;\n        }\n\n        if (storageEvent.key === null) {\n          return;\n        }\n\n        if (this.clientStateKeyRe.test(storageEvent.key)) {\n          if (storageEvent.newValue != null) {\n            const clientState = this.fromWebStorageClientState(\n              storageEvent.key,\n              storageEvent.newValue\n            );\n            if (clientState) {\n              return this.handleClientStateEvent(\n                clientState.clientId,\n                clientState\n              );\n            }\n          } else {\n            const clientId = this.fromWebStorageClientStateKey(\n              storageEvent.key\n            )!;\n            return this.handleClientStateEvent(clientId, null);\n          }\n        } else if (this.mutationBatchKeyRe.test(storageEvent.key)) {\n          if (storageEvent.newValue !== null) {\n            const mutationMetadata = this.fromWebStorageMutationMetadata(\n              storageEvent.key,\n              storageEvent.newValue\n            );\n            if (mutationMetadata) {\n              return this.handleMutationBatchEvent(mutationMetadata);\n            }\n          }\n        } else if (this.queryTargetKeyRe.test(storageEvent.key)) {\n          if (storageEvent.newValue !== null) {\n            const queryTargetMetadata = this.fromWebStorageQueryTargetMetadata(\n              storageEvent.key,\n              storageEvent.newValue\n            );\n            if (queryTargetMetadata) {\n              return this.handleQueryTargetEvent(queryTargetMetadata);\n            }\n          }\n        } else if (storageEvent.key === this.onlineStateKey) {\n          if (storageEvent.newValue !== null) {\n            const onlineState = this.fromWebStorageOnlineState(\n              storageEvent.newValue\n            );\n            if (onlineState) {\n              return this.handleOnlineStateEvent(onlineState);\n            }\n          }\n        } else if (storageEvent.key === this.sequenceNumberKey) {\n          debugAssert(\n            !!this.sequenceNumberHandler,\n            'Missing sequenceNumberHandler'\n          );\n          const sequenceNumber = fromWebStorageSequenceNumber(\n            storageEvent.newValue\n          );\n          if (sequenceNumber !== ListenSequence.INVALID) {\n            this.sequenceNumberHandler!(sequenceNumber);\n          }\n        }\n      });\n    }\n  }\n\n  private get localClientState(): LocalClientState {\n    return this.activeClients.get(this.localClientId) as LocalClientState;\n  }\n\n  private persistClientState(): void {\n    this.setItem(\n      this.localClientStorageKey,\n      this.localClientState.toWebStorageJSON()\n    );\n  }\n\n  private persistMutationState(\n    batchId: BatchId,\n    state: MutationBatchState,\n    error?: FirestoreError\n  ): void {\n    const mutationState = new MutationMetadata(\n      this.currentUser,\n      batchId,\n      state,\n      error\n    );\n    const mutationKey = createWebStorageMutationBatchKey(\n      this.persistenceKey,\n      this.currentUser,\n      batchId\n    );\n    this.setItem(mutationKey, mutationState.toWebStorageJSON());\n  }\n\n  private removeMutationState(batchId: BatchId): void {\n    const mutationKey = createWebStorageMutationBatchKey(\n      this.persistenceKey,\n      this.currentUser,\n      batchId\n    );\n    this.removeItem(mutationKey);\n  }\n\n  private persistOnlineState(onlineState: OnlineState): void {\n    const entry: SharedOnlineStateSchema = {\n      clientId: this.localClientId,\n      onlineState\n    };\n    this.storage.setItem(this.onlineStateKey, JSON.stringify(entry));\n  }\n\n  private persistQueryTargetState(\n    targetId: TargetId,\n    state: QueryTargetState,\n    error?: FirestoreError\n  ): void {\n    const targetKey = createWebStorageQueryTargetMetadataKey(\n      this.persistenceKey,\n      targetId\n    );\n    const targetMetadata = new QueryTargetMetadata(targetId, state, error);\n    this.setItem(targetKey, targetMetadata.toWebStorageJSON());\n  }\n\n  /**\n   * Parses a client state key in WebStorage. Returns null if the key does not\n   * match the expected key format.\n   */\n  private fromWebStorageClientStateKey(key: string): ClientId | null {\n    const match = this.clientStateKeyRe.exec(key);\n    return match ? match[1] : null;\n  }\n\n  /**\n   * Parses a client state in WebStorage. Returns 'null' if the value could not\n   * be parsed.\n   */\n  private fromWebStorageClientState(\n    key: string,\n    value: string\n  ): RemoteClientState | null {\n    const clientId = this.fromWebStorageClientStateKey(key);\n    debugAssert(clientId !== null, `Cannot parse client state key '${key}'`);\n    return RemoteClientState.fromWebStorageEntry(clientId, value);\n  }\n\n  /**\n   * Parses a mutation batch state in WebStorage. Returns 'null' if the value\n   * could not be parsed.\n   */\n  private fromWebStorageMutationMetadata(\n    key: string,\n    value: string\n  ): MutationMetadata | null {\n    const match = this.mutationBatchKeyRe.exec(key);\n    debugAssert(match !== null, `Cannot parse mutation batch key '${key}'`);\n\n    const batchId = Number(match[1]);\n    const userId = match[2] !== undefined ? match[2] : null;\n    return MutationMetadata.fromWebStorageEntry(\n      new User(userId),\n      batchId,\n      value\n    );\n  }\n\n  /**\n   * Parses a query target state from WebStorage. Returns 'null' if the value\n   * could not be parsed.\n   */\n  private fromWebStorageQueryTargetMetadata(\n    key: string,\n    value: string\n  ): QueryTargetMetadata | null {\n    const match = this.queryTargetKeyRe.exec(key);\n    debugAssert(match !== null, `Cannot parse query target key '${key}'`);\n\n    const targetId = Number(match[1]);\n    return QueryTargetMetadata.fromWebStorageEntry(targetId, value);\n  }\n\n  /**\n   * Parses an online state from WebStorage. Returns 'null' if the value\n   * could not be parsed.\n   */\n  private fromWebStorageOnlineState(value: string): SharedOnlineState | null {\n    return SharedOnlineState.fromWebStorageEntry(value);\n  }\n\n  private async handleMutationBatchEvent(\n    mutationBatch: MutationMetadata\n  ): Promise<void> {\n    if (mutationBatch.user.uid !== this.currentUser.uid) {\n      logDebug(\n        LOG_TAG,\n        `Ignoring mutation for non-active user ${mutationBatch.user.uid}`\n      );\n      return;\n    }\n\n    return this.syncEngine!.applyBatchState(\n      mutationBatch.batchId,\n      mutationBatch.state,\n      mutationBatch.error\n    );\n  }\n\n  private handleQueryTargetEvent(\n    targetMetadata: QueryTargetMetadata\n  ): Promise<void> {\n    return this.syncEngine!.applyTargetState(\n      targetMetadata.targetId,\n      targetMetadata.state,\n      targetMetadata.error\n    );\n  }\n\n  private handleClientStateEvent(\n    clientId: ClientId,\n    clientState: RemoteClientState | null\n  ): Promise<void> {\n    const updatedClients = clientState\n      ? this.activeClients.insert(clientId, clientState)\n      : this.activeClients.remove(clientId);\n\n    const existingTargets = this.extractActiveQueryTargets(this.activeClients);\n    const newTargets = this.extractActiveQueryTargets(updatedClients);\n\n    const addedTargets: TargetId[] = [];\n    const removedTargets: TargetId[] = [];\n\n    newTargets.forEach(targetId => {\n      if (!existingTargets.has(targetId)) {\n        addedTargets.push(targetId);\n      }\n    });\n\n    existingTargets.forEach(targetId => {\n      if (!newTargets.has(targetId)) {\n        removedTargets.push(targetId);\n      }\n    });\n\n    return this.syncEngine!.applyActiveTargetsChange(\n      addedTargets,\n      removedTargets\n    ).then(() => {\n      this.activeClients = updatedClients;\n    });\n  }\n\n  private handleOnlineStateEvent(onlineState: SharedOnlineState): void {\n    // We check whether the client that wrote this online state is still active\n    // by comparing its client ID to the list of clients kept active in\n    // IndexedDb. If a client does not update their IndexedDb client state\n    // within 5 seconds, it is considered inactive and we don't emit an online\n    // state event.\n    if (this.activeClients.get(onlineState.clientId)) {\n      this.onlineStateHandler!(onlineState.onlineState);\n    }\n  }\n\n  private extractActiveQueryTargets(\n    clients: SortedMap<string, ClientState>\n  ): SortedSet<TargetId> {\n    let activeTargets = targetIdSet();\n    clients.forEach((kev, value) => {\n      activeTargets = activeTargets.unionWith(value.activeTargetIds);\n    });\n    return activeTargets;\n  }\n}\n\nfunction fromWebStorageSequenceNumber(\n  seqString: string | null\n): ListenSequenceNumber {\n  let sequenceNumber = ListenSequence.INVALID;\n  if (seqString != null) {\n    try {\n      const parsed = JSON.parse(seqString);\n      hardAssert(\n        typeof parsed === 'number',\n        'Found non-numeric sequence number'\n      );\n      sequenceNumber = parsed;\n    } catch (e) {\n      logError(LOG_TAG, 'Failed to read sequence number from WebStorage', e);\n    }\n  }\n  return sequenceNumber;\n}\n\n/**\n * `MemorySharedClientState` is a simple implementation of SharedClientState for\n * clients using memory persistence. The state in this class remains fully\n * isolated and no synchronization is performed.\n */\nexport class MemorySharedClientState implements SharedClientState {\n  private localState = new LocalClientState();\n  private queryState: { [targetId: number]: QueryTargetState } = {};\n  onlineStateHandler: ((onlineState: OnlineState) => void) | null = null;\n  sequenceNumberHandler:\n    | ((sequenceNumber: ListenSequenceNumber) => void)\n    | null = null;\n\n  addPendingMutation(batchId: BatchId): void {\n    // No op.\n  }\n\n  updateMutationState(\n    batchId: BatchId,\n    state: 'acknowledged' | 'rejected',\n    error?: FirestoreError\n  ): void {\n    // No op.\n  }\n\n  addLocalQueryTarget(targetId: TargetId): QueryTargetState {\n    this.localState.addQueryTarget(targetId);\n    return this.queryState[targetId] || 'not-current';\n  }\n\n  updateQueryState(\n    targetId: TargetId,\n    state: QueryTargetState,\n    error?: FirestoreError\n  ): void {\n    this.queryState[targetId] = state;\n  }\n\n  removeLocalQueryTarget(targetId: TargetId): void {\n    this.localState.removeQueryTarget(targetId);\n  }\n\n  isLocalQueryTarget(targetId: TargetId): boolean {\n    return this.localState.activeTargetIds.has(targetId);\n  }\n\n  clearQueryState(targetId: TargetId): void {\n    delete this.queryState[targetId];\n  }\n\n  getAllActiveQueryTargets(): TargetIdSet {\n    return this.localState.activeTargetIds;\n  }\n\n  isActiveQueryTarget(targetId: TargetId): boolean {\n    return this.localState.activeTargetIds.has(targetId);\n  }\n\n  start(): Promise<void> {\n    this.localState = new LocalClientState();\n    return Promise.resolve();\n  }\n\n  handleUserChange(\n    user: User,\n    removedBatchIds: BatchId[],\n    addedBatchIds: BatchId[]\n  ): void {\n    // No op.\n  }\n\n  setOnlineState(onlineState: OnlineState): void {\n    // No op.\n  }\n\n  shutdown(): void {}\n\n  writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void {}\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 { QueryResult } from '../local/local_store';\nimport {\n  documentKeySet,\n  DocumentKeySet,\n  MaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DocumentSet } from '../model/document_set';\nimport { TargetChange } from '../remote/remote_event';\nimport { debugAssert, fail } from '../util/assert';\n\nimport { newQueryComparator, Query, queryMatches } from './query';\nimport { OnlineState } from './types';\nimport {\n  ChangeType,\n  DocumentChangeSet,\n  SyncState,\n  ViewSnapshot\n} from './view_snapshot';\n\nexport type LimboDocumentChange = AddedLimboDocument | RemovedLimboDocument;\nexport class AddedLimboDocument {\n  constructor(public key: DocumentKey) {}\n}\nexport class RemovedLimboDocument {\n  constructor(public key: DocumentKey) {}\n}\n\n/** The result of applying a set of doc changes to a view. */\nexport interface ViewDocumentChanges {\n  /** The new set of docs that should be in the view. */\n  documentSet: DocumentSet;\n  /** The diff of these docs with the previous set of docs. */\n  changeSet: DocumentChangeSet;\n  /**\n   * Whether the set of documents passed in was not sufficient to calculate the\n   * new state of the view and there needs to be another pass based on the\n   * local cache.\n   */\n  needsRefill: boolean;\n\n  mutatedKeys: DocumentKeySet;\n}\n\nexport interface ViewChange {\n  snapshot?: ViewSnapshot;\n  limboChanges: LimboDocumentChange[];\n}\n\n/**\n * View is responsible for computing the final merged truth of what docs are in\n * a query. It gets notified of local and remote changes to docs, and applies\n * the query filters and limits to determine the most correct possible results.\n */\nexport class View {\n  private syncState: SyncState | null = null;\n  /**\n   * A flag whether the view is current with the backend. A view is considered\n   * current after it has seen the current flag from the backend and did not\n   * lose consistency within the watch stream (e.g. because of an existence\n   * filter mismatch).\n   */\n  private current = false;\n  private documentSet: DocumentSet;\n  /** Documents in the view but not in the remote target */\n  private limboDocuments = documentKeySet();\n  /** Document Keys that have local changes */\n  private mutatedKeys = documentKeySet();\n  /** Query comparator that defines the document order in this view. */\n  private docComparator: (d1: Document, d2: Document) => number;\n\n  constructor(\n    private query: Query,\n    /** Documents included in the remote target */\n    private _syncedDocuments: DocumentKeySet\n  ) {\n    this.docComparator = newQueryComparator(query);\n    this.documentSet = new DocumentSet(this.docComparator);\n  }\n\n  /**\n   * The set of remote documents that the server has told us belongs to the target associated with\n   * this view.\n   */\n  get syncedDocuments(): DocumentKeySet {\n    return this._syncedDocuments;\n  }\n\n  /**\n   * Iterates over a set of doc changes, applies the query limit, and computes\n   * what the new results should be, what the changes were, and whether we may\n   * need to go back to the local cache for more results. Does not make any\n   * changes to the view.\n   * @param docChanges The doc changes to apply to this view.\n   * @param previousChanges If this is being called with a refill, then start\n   *        with this set of docs and changes instead of the current view.\n   * @return a new set of docs, changes, and refill flag.\n   */\n  computeDocChanges(\n    docChanges: MaybeDocumentMap,\n    previousChanges?: ViewDocumentChanges\n  ): ViewDocumentChanges {\n    const changeSet = previousChanges\n      ? previousChanges.changeSet\n      : new DocumentChangeSet();\n    const oldDocumentSet = previousChanges\n      ? previousChanges.documentSet\n      : this.documentSet;\n    let newMutatedKeys = previousChanges\n      ? previousChanges.mutatedKeys\n      : this.mutatedKeys;\n    let newDocumentSet = oldDocumentSet;\n    let needsRefill = false;\n\n    // Track the last doc in a (full) limit. This is necessary, because some\n    // update (a delete, or an update moving a doc past the old limit) might\n    // mean there is some other document in the local cache that either should\n    // come (1) between the old last limit doc and the new last document, in the\n    // case of updates, or (2) after the new last document, in the case of\n    // deletes. So we keep this doc at the old limit to compare the updates to.\n    //\n    // Note that this should never get used in a refill (when previousChanges is\n    // set), because there will only be adds -- no deletes or updates.\n    const lastDocInLimit =\n      this.query.hasLimitToFirst() && oldDocumentSet.size === this.query.limit\n        ? oldDocumentSet.last()\n        : null;\n    const firstDocInLimit =\n      this.query.hasLimitToLast() && oldDocumentSet.size === this.query.limit\n        ? oldDocumentSet.first()\n        : null;\n\n    docChanges.inorderTraversal(\n      (key: DocumentKey, newMaybeDoc: MaybeDocument) => {\n        const oldDoc = oldDocumentSet.get(key);\n        let newDoc = newMaybeDoc instanceof Document ? newMaybeDoc : null;\n        if (newDoc) {\n          debugAssert(\n            key.isEqual(newDoc.key),\n            'Mismatching keys found in document changes: ' +\n              key +\n              ' != ' +\n              newDoc.key\n          );\n          newDoc = queryMatches(this.query, newDoc) ? newDoc : null;\n        }\n\n        const oldDocHadPendingMutations = oldDoc\n          ? this.mutatedKeys.has(oldDoc.key)\n          : false;\n        const newDocHasPendingMutations = newDoc\n          ? newDoc.hasLocalMutations ||\n            // We only consider committed mutations for documents that were\n            // mutated during the lifetime of the view.\n            (this.mutatedKeys.has(newDoc.key) && newDoc.hasCommittedMutations)\n          : false;\n\n        let changeApplied = false;\n\n        // Calculate change\n        if (oldDoc && newDoc) {\n          const docsEqual = oldDoc.data().isEqual(newDoc.data());\n          if (!docsEqual) {\n            if (!this.shouldWaitForSyncedDocument(oldDoc, newDoc)) {\n              changeSet.track({\n                type: ChangeType.Modified,\n                doc: newDoc\n              });\n              changeApplied = true;\n\n              if (\n                (lastDocInLimit &&\n                  this.docComparator(newDoc, lastDocInLimit) > 0) ||\n                (firstDocInLimit &&\n                  this.docComparator(newDoc, firstDocInLimit) < 0)\n              ) {\n                // This doc moved from inside the limit to outside the limit.\n                // That means there may be some other doc in the local cache\n                // that should be included instead.\n                needsRefill = true;\n              }\n            }\n          } else if (oldDocHadPendingMutations !== newDocHasPendingMutations) {\n            changeSet.track({ type: ChangeType.Metadata, doc: newDoc });\n            changeApplied = true;\n          }\n        } else if (!oldDoc && newDoc) {\n          changeSet.track({ type: ChangeType.Added, doc: newDoc });\n          changeApplied = true;\n        } else if (oldDoc && !newDoc) {\n          changeSet.track({ type: ChangeType.Removed, doc: oldDoc });\n          changeApplied = true;\n\n          if (lastDocInLimit || firstDocInLimit) {\n            // A doc was removed from a full limit query. We'll need to\n            // requery from the local cache to see if we know about some other\n            // doc that should be in the results.\n            needsRefill = true;\n          }\n        }\n\n        if (changeApplied) {\n          if (newDoc) {\n            newDocumentSet = newDocumentSet.add(newDoc);\n            if (newDocHasPendingMutations) {\n              newMutatedKeys = newMutatedKeys.add(key);\n            } else {\n              newMutatedKeys = newMutatedKeys.delete(key);\n            }\n          } else {\n            newDocumentSet = newDocumentSet.delete(key);\n            newMutatedKeys = newMutatedKeys.delete(key);\n          }\n        }\n      }\n    );\n\n    // Drop documents out to meet limit/limitToLast requirement.\n    if (this.query.hasLimitToFirst() || this.query.hasLimitToLast()) {\n      while (newDocumentSet.size > this.query.limit!) {\n        const oldDoc = this.query.hasLimitToFirst()\n          ? newDocumentSet.last()\n          : newDocumentSet.first();\n        newDocumentSet = newDocumentSet.delete(oldDoc!.key);\n        newMutatedKeys = newMutatedKeys.delete(oldDoc!.key);\n        changeSet.track({ type: ChangeType.Removed, doc: oldDoc! });\n      }\n    }\n\n    debugAssert(\n      !needsRefill || !previousChanges,\n      'View was refilled using docs that themselves needed refilling.'\n    );\n    return {\n      documentSet: newDocumentSet,\n      changeSet,\n      needsRefill,\n      mutatedKeys: newMutatedKeys\n    };\n  }\n\n  private shouldWaitForSyncedDocument(\n    oldDoc: Document,\n    newDoc: Document\n  ): boolean {\n    // We suppress the initial change event for documents that were modified as\n    // part of a write acknowledgment (e.g. when the value of a server transform\n    // is applied) as Watch will send us the same document again.\n    // By suppressing the event, we only raise two user visible events (one with\n    // `hasPendingWrites` and the final state of the document) instead of three\n    // (one with `hasPendingWrites`, the modified document with\n    // `hasPendingWrites` and the final state of the document).\n    return (\n      oldDoc.hasLocalMutations &&\n      newDoc.hasCommittedMutations &&\n      !newDoc.hasLocalMutations\n    );\n  }\n\n  /**\n   * Updates the view with the given ViewDocumentChanges and optionally updates\n   * limbo docs and sync state from the provided target change.\n   * @param docChanges The set of changes to make to the view's docs.\n   * @param updateLimboDocuments Whether to update limbo documents based on this\n   *        change.\n   * @param targetChange A target change to apply for computing limbo docs and\n   *        sync state.\n   * @return A new ViewChange with the given docs, changes, and sync state.\n   */\n  // PORTING NOTE: The iOS/Android clients always compute limbo document changes.\n  applyChanges(\n    docChanges: ViewDocumentChanges,\n    updateLimboDocuments: boolean,\n    targetChange?: TargetChange\n  ): ViewChange {\n    debugAssert(\n      !docChanges.needsRefill,\n      'Cannot apply changes that need a refill'\n    );\n    const oldDocs = this.documentSet;\n    this.documentSet = docChanges.documentSet;\n    this.mutatedKeys = docChanges.mutatedKeys;\n    // Sort changes based on type and query comparator\n    const changes = docChanges.changeSet.getChanges();\n    changes.sort((c1, c2) => {\n      return (\n        compareChangeType(c1.type, c2.type) ||\n        this.docComparator(c1.doc, c2.doc)\n      );\n    });\n\n    this.applyTargetChange(targetChange);\n    const limboChanges = updateLimboDocuments\n      ? this.updateLimboDocuments()\n      : [];\n    const synced = this.limboDocuments.size === 0 && this.current;\n    const newSyncState = synced ? SyncState.Synced : SyncState.Local;\n    const syncStateChanged = newSyncState !== this.syncState;\n    this.syncState = newSyncState;\n\n    if (changes.length === 0 && !syncStateChanged) {\n      // no changes\n      return { limboChanges };\n    } else {\n      const snap: ViewSnapshot = new ViewSnapshot(\n        this.query,\n        docChanges.documentSet,\n        oldDocs,\n        changes,\n        docChanges.mutatedKeys,\n        newSyncState === SyncState.Local,\n        syncStateChanged,\n        /* excludesMetadataChanges= */ false\n      );\n      return {\n        snapshot: snap,\n        limboChanges\n      };\n    }\n  }\n\n  /**\n   * Applies an OnlineState change to the view, potentially generating a\n   * ViewChange if the view's syncState changes as a result.\n   */\n  applyOnlineStateChange(onlineState: OnlineState): ViewChange {\n    if (this.current && onlineState === OnlineState.Offline) {\n      // If we're offline, set `current` to false and then call applyChanges()\n      // to refresh our syncState and generate a ViewChange as appropriate. We\n      // are guaranteed to get a new TargetChange that sets `current` back to\n      // true once the client is back online.\n      this.current = false;\n      return this.applyChanges(\n        {\n          documentSet: this.documentSet,\n          changeSet: new DocumentChangeSet(),\n          mutatedKeys: this.mutatedKeys,\n          needsRefill: false\n        },\n        /* updateLimboDocuments= */ false\n      );\n    } else {\n      // No effect, just return a no-op ViewChange.\n      return { limboChanges: [] };\n    }\n  }\n\n  /**\n   * Returns whether the doc for the given key should be in limbo.\n   */\n  private shouldBeInLimbo(key: DocumentKey): boolean {\n    // If the remote end says it's part of this query, it's not in limbo.\n    if (this._syncedDocuments.has(key)) {\n      return false;\n    }\n    // The local store doesn't think it's a result, so it shouldn't be in limbo.\n    if (!this.documentSet.has(key)) {\n      return false;\n    }\n    // If there are local changes to the doc, they might explain why the server\n    // doesn't know that it's part of the query. So don't put it in limbo.\n    // TODO(klimt): Ideally, we would only consider changes that might actually\n    // affect this specific query.\n    if (this.documentSet.get(key)!.hasLocalMutations) {\n      return false;\n    }\n    // Everything else is in limbo.\n    return true;\n  }\n\n  /**\n   * Updates syncedDocuments, current, and limbo docs based on the given change.\n   * Returns the list of changes to which docs are in limbo.\n   */\n  private applyTargetChange(targetChange?: TargetChange): void {\n    if (targetChange) {\n      targetChange.addedDocuments.forEach(\n        key => (this._syncedDocuments = this._syncedDocuments.add(key))\n      );\n      targetChange.modifiedDocuments.forEach(key => {\n        debugAssert(\n          this._syncedDocuments.has(key),\n          `Modified document ${key} not found in view.`\n        );\n      });\n      targetChange.removedDocuments.forEach(\n        key => (this._syncedDocuments = this._syncedDocuments.delete(key))\n      );\n      this.current = targetChange.current;\n    }\n  }\n\n  private updateLimboDocuments(): LimboDocumentChange[] {\n    // We can only determine limbo documents when we're in-sync with the server.\n    if (!this.current) {\n      return [];\n    }\n\n    // TODO(klimt): Do this incrementally so that it's not quadratic when\n    // updating many documents.\n    const oldLimboDocuments = this.limboDocuments;\n    this.limboDocuments = documentKeySet();\n    this.documentSet.forEach(doc => {\n      if (this.shouldBeInLimbo(doc.key)) {\n        this.limboDocuments = this.limboDocuments.add(doc.key);\n      }\n    });\n\n    // Diff the new limbo docs with the old limbo docs.\n    const changes: LimboDocumentChange[] = [];\n    oldLimboDocuments.forEach(key => {\n      if (!this.limboDocuments.has(key)) {\n        changes.push(new RemovedLimboDocument(key));\n      }\n    });\n    this.limboDocuments.forEach(key => {\n      if (!oldLimboDocuments.has(key)) {\n        changes.push(new AddedLimboDocument(key));\n      }\n    });\n    return changes;\n  }\n\n  /**\n   * Update the in-memory state of the current view with the state read from\n   * persistence.\n   *\n   * We update the query view whenever a client's primary status changes:\n   * - When a client transitions from primary to secondary, it can miss\n   *   LocalStorage updates and its query views may temporarily not be\n   *   synchronized with the state on disk.\n   * - For secondary to primary transitions, the client needs to update the list\n   *   of `syncedDocuments` since secondary clients update their query views\n   *   based purely on synthesized RemoteEvents.\n   *\n   * @param queryResult.documents - The documents that match the query according\n   * to the LocalStore.\n   * @param queryResult.remoteKeys - The keys of the documents that match the\n   * query according to the backend.\n   *\n   * @return The ViewChange that resulted from this synchronization.\n   */\n  // PORTING NOTE: Multi-tab only.\n  synchronizeWithPersistedState(queryResult: QueryResult): ViewChange {\n    this._syncedDocuments = queryResult.remoteKeys;\n    this.limboDocuments = documentKeySet();\n    const docChanges = this.computeDocChanges(queryResult.documents);\n    return this.applyChanges(docChanges, /*updateLimboDocuments=*/ true);\n  }\n\n  /**\n   * Returns a view snapshot as if this query was just listened to. Contains\n   * a document add for every existing document and the `fromCache` and\n   * `hasPendingWrites` status of the already established view.\n   */\n  // PORTING NOTE: Multi-tab only.\n  computeInitialSnapshot(): ViewSnapshot {\n    return ViewSnapshot.fromInitialDocuments(\n      this.query,\n      this.documentSet,\n      this.mutatedKeys,\n      this.syncState === SyncState.Local\n    );\n  }\n}\n\nfunction compareChangeType(c1: ChangeType, c2: ChangeType): number {\n  const order = (change: ChangeType): 0 | 1 | 2 => {\n    switch (change) {\n      case ChangeType.Added:\n        return 1;\n      case ChangeType.Modified:\n        return 2;\n      case ChangeType.Metadata:\n        // A metadata change is converted to a modified change at the public\n        // api layer.  Since we sort by document key and then change type,\n        // metadata and modified changes must be sorted equivalently.\n        return 2;\n      case ChangeType.Removed:\n        return 0;\n      default:\n        return fail('Unknown ChangeType: ' + change);\n    }\n  };\n\n  return order(c1) - order(c2);\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 { User } from '../auth/user';\nimport {\n  getNewDocumentChanges,\n  getCachedTarget,\n  ignoreIfPrimaryLeaseLoss,\n  LocalStore,\n  getActiveClientsFromPersistence,\n  lookupMutationDocuments,\n  removeCachedMutationBatchMetadata\n} from '../local/local_store';\nimport { LocalViewChanges } from '../local/local_view_changes';\nimport { ReferenceSet } from '../local/reference_set';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport {\n  documentKeySet,\n  DocumentKeySet,\n  MaybeDocumentMap\n} from '../model/collections';\nimport { MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { BATCHID_UNKNOWN, MutationBatchResult } from '../model/mutation_batch';\nimport { RemoteEvent, TargetChange } from '../remote/remote_event';\nimport { RemoteStore } from '../remote/remote_store';\nimport { RemoteSyncer } from '../remote/remote_syncer';\nimport { debugAssert, debugCast, fail, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { Deferred } from '../util/promise';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { ClientId, SharedClientState } from '../local/shared_client_state';\nimport { QueryTargetState } from '../local/shared_client_state_syncer';\nimport { SortedSet } from '../util/sorted_set';\nimport { ListenSequence } from './listen_sequence';\nimport {\n  canonifyQuery,\n  LimitType,\n  newQuery,\n  newQueryForPath,\n  Query,\n  queryEquals,\n  queryToTarget,\n  stringifyQuery\n} from './query';\nimport { SnapshotVersion } from './snapshot_version';\nimport { Target } from './target';\nimport { TargetIdGenerator } from './target_id_generator';\nimport {\n  BatchId,\n  MutationBatchState,\n  OnlineState,\n  OnlineStateSource,\n  TargetId\n} from './types';\nimport {\n  AddedLimboDocument,\n  LimboDocumentChange,\n  RemovedLimboDocument,\n  View,\n  ViewChange,\n  ViewDocumentChanges\n} from './view';\nimport { ViewSnapshot } from './view_snapshot';\nimport { wrapInUserErrorIfRecoverable } from '../util/async_queue';\nimport { Datastore } from '../remote/datastore';\n\nconst LOG_TAG = 'SyncEngine';\n\n/**\n * QueryView contains all of the data that SyncEngine needs to keep track of for\n * a particular query.\n */\nclass QueryView {\n  constructor(\n    /**\n     * The query itself.\n     */\n    public query: Query,\n    /**\n     * The target number created by the client that is used in the watch\n     * stream to identify this query.\n     */\n    public targetId: TargetId,\n    /**\n     * The view is responsible for computing the final merged truth of what\n     * docs are in the query. It gets notified of local and remote changes,\n     * and applies the query filters and limits to determine the most correct\n     * possible results.\n     */\n    public view: View\n  ) {}\n}\n\n/** Tracks a limbo resolution. */\nclass LimboResolution {\n  constructor(public key: DocumentKey) {}\n\n  /**\n   * Set to true once we've received a document. This is used in\n   * getRemoteKeysForTarget() and ultimately used by WatchChangeAggregator to\n   * decide whether it needs to manufacture a delete event for the target once\n   * the target is CURRENT.\n   */\n  receivedDocument: boolean = false;\n}\n\n/**\n * Interface implemented by EventManager to handle notifications from\n * SyncEngine.\n */\nexport interface SyncEngineListener {\n  /** Handles new view snapshots. */\n  onWatchChange(snapshots: ViewSnapshot[]): void;\n\n  /** Handles the failure of a query. */\n  onWatchError(query: Query, error: Error): void;\n\n  /** Handles a change in online state. */\n  onOnlineStateChange(onlineState: OnlineState): void;\n}\n\n/**\n * SyncEngine is the central controller in the client SDK architecture. It is\n * the glue code between the EventManager, LocalStore, and RemoteStore. Some of\n * SyncEngine's responsibilities include:\n * 1. Coordinating client requests and remote events between the EventManager\n *    and the local and remote data stores.\n * 2. Managing a View object for each query, providing the unified view between\n *    the local and remote data stores.\n * 3. Notifying the RemoteStore when the LocalStore has new mutations in its\n *    queue that need sending to the backend.\n *\n * The SyncEngine’s methods should only ever be called by methods running in the\n * global async queue.\n */\nexport interface SyncEngine extends RemoteSyncer {\n  isPrimaryClient: boolean;\n\n  /** Subscribes to SyncEngine notifications. Has to be called exactly once. */\n  subscribe(syncEngineListener: SyncEngineListener): void;\n\n  /**\n   * Initiates the new listen, resolves promise when listen enqueued to the\n   * server. All the subsequent view snapshots or errors are sent to the\n   * subscribed handlers. Returns the initial snapshot.\n   */\n  listen(query: Query): Promise<ViewSnapshot>;\n\n  /** Stops listening to the query. */\n  unlisten(query: Query): Promise<void>;\n\n  /**\n   * Initiates the write of local mutation batch which involves adding the\n   * writes to the mutation queue, notifying the remote store about new\n   * mutations and raising events for any changes this write caused.\n   *\n   * The promise returned by this call is resolved when the above steps\n   * have completed, *not* when the write was acked by the backend. The\n   * userCallback is resolved once the write was acked/rejected by the\n   * backend (or failed locally for any other reason).\n   */\n  write(batch: Mutation[], userCallback: Deferred<void>): Promise<void>;\n\n  /**\n   * Applies an OnlineState change to the sync engine and notifies any views of\n   * the change.\n   */\n  applyOnlineStateChange(\n    onlineState: OnlineState,\n    source: OnlineStateSource\n  ): void;\n\n  /**\n   * Registers a user callback that resolves when all pending mutations at the moment of calling\n   * are acknowledged .\n   */\n  registerPendingWritesCallback(callback: Deferred<void>): Promise<void>;\n\n  // Visible for testing\n  activeLimboDocumentResolutions(): SortedMap<DocumentKey, TargetId>;\n\n  // Visible for testing\n  enqueuedLimboDocumentResolutions(): DocumentKey[];\n\n  handleCredentialChange(user: User): Promise<void>;\n\n  getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet;\n}\n\n/**\n * An implementation of `SyncEngine` coordinating with other parts of SDK.\n *\n * Note: some field defined in this class might have public access level, but\n * the class is not exported so they are only accessible from this module.\n * This is useful to implement optional features (like bundles) in free\n * functions, such that they are tree-shakeable.\n */\nclass SyncEngineImpl implements SyncEngine {\n  syncEngineListener: SyncEngineListener | null = null;\n\n  queryViewsByQuery = new ObjectMap<Query, QueryView>(\n    q => canonifyQuery(q),\n    queryEquals\n  );\n  queriesByTarget = new Map<TargetId, Query[]>();\n  /**\n   * The keys of documents that are in limbo for which we haven't yet started a\n   * limbo resolution query.\n   */\n  private enqueuedLimboResolutions: DocumentKey[] = [];\n  /**\n   * Keeps track of the target ID for each document that is in limbo with an\n   * active target.\n   */\n  activeLimboTargetsByKey = new SortedMap<DocumentKey, TargetId>(\n    DocumentKey.comparator\n  );\n  /**\n   * Keeps track of the information about an active limbo resolution for each\n   * active target ID that was started for the purpose of limbo resolution.\n   */\n  activeLimboResolutionsByTarget = new Map<TargetId, LimboResolution>();\n  limboDocumentRefs = new ReferenceSet();\n  /** Stores user completion handlers, indexed by User and BatchId. */\n  private mutationUserCallbacks = {} as {\n    [uidKey: string]: SortedMap<BatchId, Deferred<void>>;\n  };\n  /** Stores user callbacks waiting for all pending writes to be acknowledged. */\n  private pendingWritesCallbacks = new Map<BatchId, Array<Deferred<void>>>();\n  private limboTargetIdGenerator = TargetIdGenerator.forSyncEngine();\n\n  private onlineState = OnlineState.Unknown;\n\n  // The primary state is set to `true` or `false` immediately after Firestore\n  // startup. In the interim, a client should only be considered primary if\n  // `isPrimary` is true.\n  _isPrimaryClient: undefined | boolean = undefined;\n\n  constructor(\n    public localStore: LocalStore,\n    public remoteStore: RemoteStore,\n    protected datastore: Datastore,\n    // PORTING NOTE: Manages state synchronization in multi-tab environments.\n    public sharedClientState: SharedClientState,\n    private currentUser: User,\n    private maxConcurrentLimboResolutions: number\n  ) {}\n\n  get isPrimaryClient(): boolean {\n    return this._isPrimaryClient === true;\n  }\n\n  subscribe(syncEngineListener: SyncEngineListener): void {\n    debugAssert(\n      syncEngineListener !== null,\n      'SyncEngine listener cannot be null'\n    );\n    debugAssert(\n      this.syncEngineListener === null,\n      'SyncEngine already has a subscriber.'\n    );\n\n    this.syncEngineListener = syncEngineListener;\n  }\n\n  async listen(query: Query): Promise<ViewSnapshot> {\n    this.assertSubscribed('listen()');\n\n    let targetId;\n    let viewSnapshot;\n\n    const queryView = this.queryViewsByQuery.get(query);\n    if (queryView) {\n      // PORTING NOTE: With Multi-Tab Web, it is possible that a query view\n      // already exists when EventManager calls us for the first time. This\n      // happens when the primary tab is already listening to this query on\n      // behalf of another tab and the user of the primary also starts listening\n      // to the query. EventManager will not have an assigned target ID in this\n      // case and calls `listen` to obtain this ID.\n      targetId = queryView.targetId;\n      this.sharedClientState.addLocalQueryTarget(targetId);\n      viewSnapshot = queryView.view.computeInitialSnapshot();\n    } else {\n      const targetData = await this.localStore.allocateTarget(\n        queryToTarget(query)\n      );\n\n      const status = this.sharedClientState.addLocalQueryTarget(\n        targetData.targetId\n      );\n      targetId = targetData.targetId;\n      viewSnapshot = await this.initializeViewAndComputeSnapshot(\n        query,\n        targetId,\n        status === 'current'\n      );\n      if (this.isPrimaryClient) {\n        this.remoteStore.listen(targetData);\n      }\n    }\n\n    return viewSnapshot;\n  }\n\n  /**\n   * Registers a view for a previously unknown query and computes its initial\n   * snapshot.\n   */\n  async initializeViewAndComputeSnapshot(\n    query: Query,\n    targetId: TargetId,\n    current: boolean\n  ): Promise<ViewSnapshot> {\n    const queryResult = await this.localStore.executeQuery(\n      query,\n      /* usePreviousResults= */ true\n    );\n    const view = new View(query, queryResult.remoteKeys);\n    const viewDocChanges = view.computeDocChanges(queryResult.documents);\n    const synthesizedTargetChange = TargetChange.createSynthesizedTargetChangeForCurrentChange(\n      targetId,\n      current && this.onlineState !== OnlineState.Offline\n    );\n    const viewChange = view.applyChanges(\n      viewDocChanges,\n      /* updateLimboDocuments= */ this.isPrimaryClient,\n      synthesizedTargetChange\n    );\n    this.updateTrackedLimbos(targetId, viewChange.limboChanges);\n\n    debugAssert(\n      !!viewChange.snapshot,\n      'applyChanges for new view should always return a snapshot'\n    );\n\n    const data = new QueryView(query, targetId, view);\n    this.queryViewsByQuery.set(query, data);\n    if (this.queriesByTarget.has(targetId)) {\n      this.queriesByTarget.get(targetId)!.push(query);\n    } else {\n      this.queriesByTarget.set(targetId, [query]);\n    }\n    return viewChange.snapshot!;\n  }\n\n  async unlisten(query: Query): Promise<void> {\n    this.assertSubscribed('unlisten()');\n\n    const queryView = this.queryViewsByQuery.get(query)!;\n    debugAssert(\n      !!queryView,\n      'Trying to unlisten on query not found:' + stringifyQuery(query)\n    );\n\n    // Only clean up the query view and target if this is the only query mapped\n    // to the target.\n    const queries = this.queriesByTarget.get(queryView.targetId)!;\n    if (queries.length > 1) {\n      this.queriesByTarget.set(\n        queryView.targetId,\n        queries.filter(q => !queryEquals(q, query))\n      );\n      this.queryViewsByQuery.delete(query);\n      return;\n    }\n\n    // No other queries are mapped to the target, clean up the query and the target.\n    if (this.isPrimaryClient) {\n      // We need to remove the local query target first to allow us to verify\n      // whether any other client is still interested in this target.\n      this.sharedClientState.removeLocalQueryTarget(queryView.targetId);\n      const targetRemainsActive = this.sharedClientState.isActiveQueryTarget(\n        queryView.targetId\n      );\n\n      if (!targetRemainsActive) {\n        await this.localStore\n          .releaseTarget(queryView.targetId, /*keepPersistedTargetData=*/ false)\n          .then(() => {\n            this.sharedClientState.clearQueryState(queryView.targetId);\n            this.remoteStore.unlisten(queryView.targetId);\n            this.removeAndCleanupTarget(queryView.targetId);\n          })\n          .catch(ignoreIfPrimaryLeaseLoss);\n      }\n    } else {\n      this.removeAndCleanupTarget(queryView.targetId);\n      await this.localStore.releaseTarget(\n        queryView.targetId,\n        /*keepPersistedTargetData=*/ true\n      );\n    }\n  }\n\n  async write(batch: Mutation[], userCallback: Deferred<void>): Promise<void> {\n    this.assertSubscribed('write()');\n\n    try {\n      const result = await this.localStore.localWrite(batch);\n      this.sharedClientState.addPendingMutation(result.batchId);\n      this.addMutationCallback(result.batchId, userCallback);\n      await this.emitNewSnapsAndNotifyLocalStore(result.changes);\n      await this.remoteStore.fillWritePipeline();\n    } catch (e) {\n      // If we can't persist the mutation, we reject the user callback and\n      // don't send the mutation. The user can then retry the write.\n      const error = wrapInUserErrorIfRecoverable(e, `Failed to persist write`);\n      userCallback.reject(error);\n    }\n  }\n\n  async applyRemoteEvent(remoteEvent: RemoteEvent): Promise<void> {\n    this.assertSubscribed('applyRemoteEvent()');\n    try {\n      const changes = await this.localStore.applyRemoteEvent(remoteEvent);\n      // Update `receivedDocument` as appropriate for any limbo targets.\n      remoteEvent.targetChanges.forEach((targetChange, targetId) => {\n        const limboResolution = this.activeLimboResolutionsByTarget.get(\n          targetId\n        );\n        if (limboResolution) {\n          // Since this is a limbo resolution lookup, it's for a single document\n          // and it could be added, modified, or removed, but not a combination.\n          hardAssert(\n            targetChange.addedDocuments.size +\n              targetChange.modifiedDocuments.size +\n              targetChange.removedDocuments.size <=\n              1,\n            'Limbo resolution for single document contains multiple changes.'\n          );\n          if (targetChange.addedDocuments.size > 0) {\n            limboResolution.receivedDocument = true;\n          } else if (targetChange.modifiedDocuments.size > 0) {\n            hardAssert(\n              limboResolution.receivedDocument,\n              'Received change for limbo target document without add.'\n            );\n          } else if (targetChange.removedDocuments.size > 0) {\n            hardAssert(\n              limboResolution.receivedDocument,\n              'Received remove for limbo target document without add.'\n            );\n            limboResolution.receivedDocument = false;\n          } else {\n            // This was probably just a CURRENT targetChange or similar.\n          }\n        }\n      });\n      await this.emitNewSnapsAndNotifyLocalStore(changes, remoteEvent);\n    } catch (error) {\n      await ignoreIfPrimaryLeaseLoss(error);\n    }\n  }\n\n  applyOnlineStateChange(\n    onlineState: OnlineState,\n    source: OnlineStateSource\n  ): void {\n    // If we are the secondary client, we explicitly ignore the remote store's\n    // online state (the local client may go offline, even though the primary\n    // tab remains online) and only apply the primary tab's online state from\n    // SharedClientState.\n    if (\n      (this.isPrimaryClient && source === OnlineStateSource.RemoteStore) ||\n      (!this.isPrimaryClient && source === OnlineStateSource.SharedClientState)\n    ) {\n      this.assertSubscribed('applyOnlineStateChange()');\n      const newViewSnapshots = [] as ViewSnapshot[];\n      this.queryViewsByQuery.forEach((query, queryView) => {\n        const viewChange = queryView.view.applyOnlineStateChange(onlineState);\n        debugAssert(\n          viewChange.limboChanges.length === 0,\n          'OnlineState should not affect limbo documents.'\n        );\n        if (viewChange.snapshot) {\n          newViewSnapshots.push(viewChange.snapshot);\n        }\n      });\n      this.syncEngineListener!.onOnlineStateChange(onlineState);\n      this.syncEngineListener!.onWatchChange(newViewSnapshots);\n      this.onlineState = onlineState;\n      if (this.isPrimaryClient) {\n        this.sharedClientState.setOnlineState(onlineState);\n      }\n    }\n  }\n\n  async rejectListen(targetId: TargetId, err: FirestoreError): Promise<void> {\n    this.assertSubscribed('rejectListens()');\n\n    // PORTING NOTE: Multi-tab only.\n    this.sharedClientState.updateQueryState(targetId, 'rejected', err);\n\n    const limboResolution = this.activeLimboResolutionsByTarget.get(targetId);\n    const limboKey = limboResolution && limboResolution.key;\n    if (limboKey) {\n      // TODO(klimt): We really only should do the following on permission\n      // denied errors, but we don't have the cause code here.\n\n      // It's a limbo doc. Create a synthetic event saying it was deleted.\n      // This is kind of a hack. Ideally, we would have a method in the local\n      // store to purge a document. However, it would be tricky to keep all of\n      // the local store's invariants with another method.\n      let documentUpdates = new SortedMap<DocumentKey, MaybeDocument>(\n        DocumentKey.comparator\n      );\n      documentUpdates = documentUpdates.insert(\n        limboKey,\n        new NoDocument(limboKey, SnapshotVersion.min())\n      );\n      const resolvedLimboDocuments = documentKeySet().add(limboKey);\n      const event = new RemoteEvent(\n        SnapshotVersion.min(),\n        /* targetChanges= */ new Map<TargetId, TargetChange>(),\n        /* targetMismatches= */ new SortedSet<TargetId>(primitiveComparator),\n        documentUpdates,\n        resolvedLimboDocuments\n      );\n\n      await this.applyRemoteEvent(event);\n\n      // Since this query failed, we won't want to manually unlisten to it.\n      // We only remove it from bookkeeping after we successfully applied the\n      // RemoteEvent. If `applyRemoteEvent()` throws, we want to re-listen to\n      // this query when the RemoteStore restarts the Watch stream, which should\n      // re-trigger the target failure.\n      this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.remove(\n        limboKey\n      );\n      this.activeLimboResolutionsByTarget.delete(targetId);\n      this.pumpEnqueuedLimboResolutions();\n    } else {\n      await this.localStore\n        .releaseTarget(targetId, /* keepPersistedTargetData */ false)\n        .then(() => this.removeAndCleanupTarget(targetId, err))\n        .catch(ignoreIfPrimaryLeaseLoss);\n    }\n  }\n\n  async applySuccessfulWrite(\n    mutationBatchResult: MutationBatchResult\n  ): Promise<void> {\n    this.assertSubscribed('applySuccessfulWrite()');\n\n    const batchId = mutationBatchResult.batch.batchId;\n\n    try {\n      const changes = await this.localStore.acknowledgeBatch(\n        mutationBatchResult\n      );\n\n      // The local store may or may not be able to apply the write result and\n      // raise events immediately (depending on whether the watcher is caught\n      // up), so we raise user callbacks first so that they consistently happen\n      // before listen events.\n      this.processUserCallback(batchId, /*error=*/ null);\n      this.triggerPendingWritesCallbacks(batchId);\n\n      this.sharedClientState.updateMutationState(batchId, 'acknowledged');\n      await this.emitNewSnapsAndNotifyLocalStore(changes);\n    } catch (error) {\n      await ignoreIfPrimaryLeaseLoss(error);\n    }\n  }\n\n  async rejectFailedWrite(\n    batchId: BatchId,\n    error: FirestoreError\n  ): Promise<void> {\n    this.assertSubscribed('rejectFailedWrite()');\n\n    try {\n      const changes = await this.localStore.rejectBatch(batchId);\n\n      // The local store may or may not be able to apply the write result and\n      // raise events immediately (depending on whether the watcher is caught up),\n      // so we raise user callbacks first so that they consistently happen before\n      // listen events.\n      this.processUserCallback(batchId, error);\n      this.triggerPendingWritesCallbacks(batchId);\n\n      this.sharedClientState.updateMutationState(batchId, 'rejected', error);\n      await this.emitNewSnapsAndNotifyLocalStore(changes);\n    } catch (error) {\n      await ignoreIfPrimaryLeaseLoss(error);\n    }\n  }\n\n  async registerPendingWritesCallback(callback: Deferred<void>): Promise<void> {\n    if (!this.remoteStore.canUseNetwork()) {\n      logDebug(\n        LOG_TAG,\n        'The network is disabled. The task returned by ' +\n          \"'awaitPendingWrites()' will not complete until the network is enabled.\"\n      );\n    }\n\n    try {\n      const highestBatchId = await this.localStore.getHighestUnacknowledgedBatchId();\n      if (highestBatchId === BATCHID_UNKNOWN) {\n        // Trigger the callback right away if there is no pending writes at the moment.\n        callback.resolve();\n        return;\n      }\n\n      const callbacks = this.pendingWritesCallbacks.get(highestBatchId) || [];\n      callbacks.push(callback);\n      this.pendingWritesCallbacks.set(highestBatchId, callbacks);\n    } catch (e) {\n      const firestoreError = wrapInUserErrorIfRecoverable(\n        e,\n        'Initialization of waitForPendingWrites() operation failed'\n      );\n      callback.reject(firestoreError);\n    }\n  }\n\n  /**\n   * Triggers the callbacks that are waiting for this batch id to get acknowledged by server,\n   * if there are any.\n   */\n  private triggerPendingWritesCallbacks(batchId: BatchId): void {\n    (this.pendingWritesCallbacks.get(batchId) || []).forEach(callback => {\n      callback.resolve();\n    });\n\n    this.pendingWritesCallbacks.delete(batchId);\n  }\n\n  /** Reject all outstanding callbacks waiting for pending writes to complete. */\n  private rejectOutstandingPendingWritesCallbacks(errorMessage: string): void {\n    this.pendingWritesCallbacks.forEach(callbacks => {\n      callbacks.forEach(callback => {\n        callback.reject(new FirestoreError(Code.CANCELLED, errorMessage));\n      });\n    });\n\n    this.pendingWritesCallbacks.clear();\n  }\n\n  private addMutationCallback(\n    batchId: BatchId,\n    callback: Deferred<void>\n  ): void {\n    let newCallbacks = this.mutationUserCallbacks[this.currentUser.toKey()];\n    if (!newCallbacks) {\n      newCallbacks = new SortedMap<BatchId, Deferred<void>>(\n        primitiveComparator\n      );\n    }\n    newCallbacks = newCallbacks.insert(batchId, callback);\n    this.mutationUserCallbacks[this.currentUser.toKey()] = newCallbacks;\n  }\n\n  /**\n   * Resolves or rejects the user callback for the given batch and then discards\n   * it.\n   */\n  processUserCallback(batchId: BatchId, error: Error | null): void {\n    let newCallbacks = this.mutationUserCallbacks[this.currentUser.toKey()];\n\n    // NOTE: Mutations restored from persistence won't have callbacks, so it's\n    // okay for there to be no callback for this ID.\n    if (newCallbacks) {\n      const callback = newCallbacks.get(batchId);\n      if (callback) {\n        debugAssert(\n          batchId === newCallbacks.minKey(),\n          'Mutation callbacks processed out-of-order?'\n        );\n        if (error) {\n          callback.reject(error);\n        } else {\n          callback.resolve();\n        }\n        newCallbacks = newCallbacks.remove(batchId);\n      }\n      this.mutationUserCallbacks[this.currentUser.toKey()] = newCallbacks;\n    }\n  }\n\n  removeAndCleanupTarget(targetId: number, error: Error | null = null): void {\n    this.sharedClientState.removeLocalQueryTarget(targetId);\n\n    debugAssert(\n      this.queriesByTarget.has(targetId) &&\n        this.queriesByTarget.get(targetId)!.length !== 0,\n      `There are no queries mapped to target id ${targetId}`\n    );\n\n    for (const query of this.queriesByTarget.get(targetId)!) {\n      this.queryViewsByQuery.delete(query);\n      if (error) {\n        this.syncEngineListener!.onWatchError(query, error);\n      }\n    }\n\n    this.queriesByTarget.delete(targetId);\n\n    if (this.isPrimaryClient) {\n      const limboKeys = this.limboDocumentRefs.removeReferencesForId(targetId);\n      limboKeys.forEach(limboKey => {\n        const isReferenced = this.limboDocumentRefs.containsKey(limboKey);\n        if (!isReferenced) {\n          // We removed the last reference for this key\n          this.removeLimboTarget(limboKey);\n        }\n      });\n    }\n  }\n\n  private removeLimboTarget(key: DocumentKey): void {\n    // It's possible that the target already got removed because the query failed. In that case,\n    // the key won't exist in `limboTargetsByKey`. Only do the cleanup if we still have the target.\n    const limboTargetId = this.activeLimboTargetsByKey.get(key);\n    if (limboTargetId === null) {\n      // This target already got removed, because the query failed.\n      return;\n    }\n\n    this.remoteStore.unlisten(limboTargetId);\n    this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.remove(key);\n    this.activeLimboResolutionsByTarget.delete(limboTargetId);\n    this.pumpEnqueuedLimboResolutions();\n  }\n\n  updateTrackedLimbos(\n    targetId: TargetId,\n    limboChanges: LimboDocumentChange[]\n  ): void {\n    for (const limboChange of limboChanges) {\n      if (limboChange instanceof AddedLimboDocument) {\n        this.limboDocumentRefs.addReference(limboChange.key, targetId);\n        this.trackLimboChange(limboChange);\n      } else if (limboChange instanceof RemovedLimboDocument) {\n        logDebug(LOG_TAG, 'Document no longer in limbo: ' + limboChange.key);\n        this.limboDocumentRefs.removeReference(limboChange.key, targetId);\n        const isReferenced = this.limboDocumentRefs.containsKey(\n          limboChange.key\n        );\n        if (!isReferenced) {\n          // We removed the last reference for this key\n          this.removeLimboTarget(limboChange.key);\n        }\n      } else {\n        fail('Unknown limbo change: ' + JSON.stringify(limboChange));\n      }\n    }\n  }\n\n  private trackLimboChange(limboChange: AddedLimboDocument): void {\n    const key = limboChange.key;\n    if (!this.activeLimboTargetsByKey.get(key)) {\n      logDebug(LOG_TAG, 'New document in limbo: ' + key);\n      this.enqueuedLimboResolutions.push(key);\n      this.pumpEnqueuedLimboResolutions();\n    }\n  }\n\n  /**\n   * Starts listens for documents in limbo that are enqueued for resolution,\n   * subject to a maximum number of concurrent resolutions.\n   *\n   * Without bounding the number of concurrent resolutions, the server can fail\n   * with \"resource exhausted\" errors which can lead to pathological client\n   * behavior as seen in https://github.com/firebase/firebase-js-sdk/issues/2683.\n   */\n  private pumpEnqueuedLimboResolutions(): void {\n    while (\n      this.enqueuedLimboResolutions.length > 0 &&\n      this.activeLimboTargetsByKey.size < this.maxConcurrentLimboResolutions\n    ) {\n      const key = this.enqueuedLimboResolutions.shift()!;\n      const limboTargetId = this.limboTargetIdGenerator.next();\n      this.activeLimboResolutionsByTarget.set(\n        limboTargetId,\n        new LimboResolution(key)\n      );\n      this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.insert(\n        key,\n        limboTargetId\n      );\n      this.remoteStore.listen(\n        new TargetData(\n          queryToTarget(newQueryForPath(key.path)),\n          limboTargetId,\n          TargetPurpose.LimboResolution,\n          ListenSequence.INVALID\n        )\n      );\n    }\n  }\n\n  // Visible for testing\n  activeLimboDocumentResolutions(): SortedMap<DocumentKey, TargetId> {\n    return this.activeLimboTargetsByKey;\n  }\n\n  // Visible for testing\n  enqueuedLimboDocumentResolutions(): DocumentKey[] {\n    return this.enqueuedLimboResolutions;\n  }\n\n  async emitNewSnapsAndNotifyLocalStore(\n    changes: MaybeDocumentMap,\n    remoteEvent?: RemoteEvent\n  ): Promise<void> {\n    const newSnaps: ViewSnapshot[] = [];\n    const docChangesInAllViews: LocalViewChanges[] = [];\n    const queriesProcessed: Array<Promise<void>> = [];\n\n    this.queryViewsByQuery.forEach((_, queryView) => {\n      queriesProcessed.push(\n        Promise.resolve()\n          .then(() => {\n            const viewDocChanges = queryView.view.computeDocChanges(changes);\n            if (!viewDocChanges.needsRefill) {\n              return viewDocChanges;\n            }\n            // The query has a limit and some docs were removed, so we need\n            // to re-run the query against the local store to make sure we\n            // didn't lose any good docs that had been past the limit.\n            return this.localStore\n              .executeQuery(queryView.query, /* usePreviousResults= */ false)\n              .then(({ documents }) => {\n                return queryView.view.computeDocChanges(\n                  documents,\n                  viewDocChanges\n                );\n              });\n          })\n          .then((viewDocChanges: ViewDocumentChanges) => {\n            const targetChange =\n              remoteEvent && remoteEvent.targetChanges.get(queryView.targetId);\n            const viewChange = queryView.view.applyChanges(\n              viewDocChanges,\n              /* updateLimboDocuments= */ this.isPrimaryClient,\n              targetChange\n            );\n            this.updateTrackedLimbos(\n              queryView.targetId,\n              viewChange.limboChanges\n            );\n            if (viewChange.snapshot) {\n              if (this.isPrimaryClient) {\n                this.sharedClientState.updateQueryState(\n                  queryView.targetId,\n                  viewChange.snapshot.fromCache ? 'not-current' : 'current'\n                );\n              }\n\n              newSnaps.push(viewChange.snapshot);\n              const docChanges = LocalViewChanges.fromSnapshot(\n                queryView.targetId,\n                viewChange.snapshot\n              );\n              docChangesInAllViews.push(docChanges);\n            }\n          })\n      );\n    });\n\n    await Promise.all(queriesProcessed);\n    this.syncEngineListener!.onWatchChange(newSnaps);\n    await this.localStore.notifyLocalViewChanges(docChangesInAllViews);\n  }\n\n  assertSubscribed(fnName: string): void {\n    debugAssert(\n      this.syncEngineListener !== null,\n      'Trying to call ' + fnName + ' before calling subscribe().'\n    );\n  }\n\n  async handleCredentialChange(user: User): Promise<void> {\n    const userChanged = !this.currentUser.isEqual(user);\n\n    if (userChanged) {\n      logDebug(LOG_TAG, 'User change. New user:', user.toKey());\n\n      const result = await this.localStore.handleUserChange(user);\n      this.currentUser = user;\n\n      // Fails tasks waiting for pending writes requested by previous user.\n      this.rejectOutstandingPendingWritesCallbacks(\n        \"'waitForPendingWrites' promise is rejected due to a user change.\"\n      );\n      // TODO(b/114226417): Consider calling this only in the primary tab.\n      this.sharedClientState.handleUserChange(\n        user,\n        result.removedBatchIds,\n        result.addedBatchIds\n      );\n      await this.emitNewSnapsAndNotifyLocalStore(result.affectedDocuments);\n    }\n  }\n\n  getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet {\n    const limboResolution = this.activeLimboResolutionsByTarget.get(targetId);\n    if (limboResolution && limboResolution.receivedDocument) {\n      return documentKeySet().add(limboResolution.key);\n    } else {\n      let keySet = documentKeySet();\n      const queries = this.queriesByTarget.get(targetId);\n      if (!queries) {\n        return keySet;\n      }\n      for (const query of queries) {\n        const queryView = this.queryViewsByQuery.get(query);\n        debugAssert(\n          !!queryView,\n          `No query view found for ${stringifyQuery(query)}`\n        );\n        keySet = keySet.unionWith(queryView.view.syncedDocuments);\n      }\n      return keySet;\n    }\n  }\n}\n\nexport function newSyncEngine(\n  localStore: LocalStore,\n  remoteStore: RemoteStore,\n  datastore: Datastore,\n  // PORTING NOTE: Manages state synchronization in multi-tab environments.\n  sharedClientState: SharedClientState,\n  currentUser: User,\n  maxConcurrentLimboResolutions: number,\n  isPrimary: boolean\n): SyncEngine {\n  const syncEngine = new SyncEngineImpl(\n    localStore,\n    remoteStore,\n    datastore,\n    sharedClientState,\n    currentUser,\n    maxConcurrentLimboResolutions\n  );\n  if (isPrimary) {\n    syncEngine._isPrimaryClient = true;\n  }\n  return syncEngine;\n}\n\n/**\n * Reconcile the list of synced documents in an existing view with those\n * from persistence.\n */\nasync function synchronizeViewAndComputeSnapshot(\n  syncEngine: SyncEngine,\n  queryView: QueryView\n): Promise<ViewChange> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  const queryResult = await syncEngineImpl.localStore.executeQuery(\n    queryView.query,\n    /* usePreviousResults= */ true\n  );\n  const viewSnapshot = queryView.view.synchronizeWithPersistedState(\n    queryResult\n  );\n  if (syncEngineImpl.isPrimaryClient) {\n    syncEngineImpl.updateTrackedLimbos(\n      queryView.targetId,\n      viewSnapshot.limboChanges\n    );\n  }\n  return viewSnapshot;\n}\n\n/** Applies a mutation state to an existing batch.  */\n// PORTING NOTE: Multi-Tab only.\nexport async function applyBatchState(\n  syncEngine: SyncEngine,\n  batchId: BatchId,\n  batchState: MutationBatchState,\n  error?: FirestoreError\n): Promise<void> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  syncEngineImpl.assertSubscribed('applyBatchState()');\n  const documents = await lookupMutationDocuments(\n    syncEngineImpl.localStore,\n    batchId\n  );\n\n  if (documents === null) {\n    // A throttled tab may not have seen the mutation before it was completed\n    // and removed from the mutation queue, in which case we won't have cached\n    // the affected documents. In this case we can safely ignore the update\n    // since that means we didn't apply the mutation locally at all (if we\n    // had, we would have cached the affected documents), and so we will just\n    // see any resulting document changes via normal remote document updates\n    // as applicable.\n    logDebug(LOG_TAG, 'Cannot apply mutation batch with id: ' + batchId);\n    return;\n  }\n\n  if (batchState === 'pending') {\n    // If we are the primary client, we need to send this write to the\n    // backend. Secondary clients will ignore these writes since their remote\n    // connection is disabled.\n    await syncEngineImpl.remoteStore.fillWritePipeline();\n  } else if (batchState === 'acknowledged' || batchState === 'rejected') {\n    // NOTE: Both these methods are no-ops for batches that originated from\n    // other clients.\n    syncEngineImpl.processUserCallback(batchId, error ? error : null);\n    removeCachedMutationBatchMetadata(syncEngineImpl.localStore, batchId);\n  } else {\n    fail(`Unknown batchState: ${batchState}`);\n  }\n\n  await syncEngineImpl.emitNewSnapsAndNotifyLocalStore(documents);\n}\n\n/** Applies a query target change from a different tab. */\n// PORTING NOTE: Multi-Tab only.\nexport async function applyPrimaryState(\n  syncEngine: SyncEngine,\n  isPrimary: boolean\n): Promise<void> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  if (isPrimary === true && syncEngineImpl._isPrimaryClient !== true) {\n    // Secondary tabs only maintain Views for their local listeners and the\n    // Views internal state may not be 100% populated (in particular\n    // secondary tabs don't track syncedDocuments, the set of documents the\n    // server considers to be in the target). So when a secondary becomes\n    // primary, we need to need to make sure that all views for all targets\n    // match the state on disk.\n    const activeTargets = syncEngineImpl.sharedClientState.getAllActiveQueryTargets();\n    const activeQueries = await synchronizeQueryViewsAndRaiseSnapshots(\n      syncEngineImpl,\n      activeTargets.toArray(),\n      /*transitionToPrimary=*/ true\n    );\n    syncEngineImpl._isPrimaryClient = true;\n    await syncEngineImpl.remoteStore.applyPrimaryState(true);\n    for (const targetData of activeQueries) {\n      syncEngineImpl.remoteStore.listen(targetData);\n    }\n  } else if (isPrimary === false && syncEngineImpl._isPrimaryClient !== false) {\n    const activeTargets: TargetId[] = [];\n\n    let p = Promise.resolve();\n    syncEngineImpl.queriesByTarget.forEach((_, targetId) => {\n      if (syncEngineImpl.sharedClientState.isLocalQueryTarget(targetId)) {\n        activeTargets.push(targetId);\n      } else {\n        p = p.then(() => {\n          syncEngineImpl.removeAndCleanupTarget(targetId);\n          return syncEngineImpl.localStore.releaseTarget(\n            targetId,\n            /*keepPersistedTargetData=*/ true\n          );\n        });\n      }\n      syncEngineImpl.remoteStore.unlisten(targetId);\n    });\n    await p;\n\n    await synchronizeQueryViewsAndRaiseSnapshots(\n      syncEngineImpl,\n      activeTargets,\n      /*transitionToPrimary=*/ false\n    );\n    resetLimboDocuments(syncEngineImpl);\n    syncEngineImpl._isPrimaryClient = false;\n    await syncEngineImpl.remoteStore.applyPrimaryState(false);\n  }\n}\n\n// PORTING NOTE: Multi-Tab only.\nfunction resetLimboDocuments(syncEngine: SyncEngine): void {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  syncEngineImpl.activeLimboResolutionsByTarget.forEach((_, targetId) => {\n    syncEngineImpl.remoteStore.unlisten(targetId);\n  });\n  syncEngineImpl.limboDocumentRefs.removeAllReferences();\n  syncEngineImpl.activeLimboResolutionsByTarget = new Map<\n    TargetId,\n    LimboResolution\n  >();\n  syncEngineImpl.activeLimboTargetsByKey = new SortedMap<DocumentKey, TargetId>(\n    DocumentKey.comparator\n  );\n}\n\n/**\n * Reconcile the query views of the provided query targets with the state from\n * persistence. Raises snapshots for any changes that affect the local\n * client and returns the updated state of all target's query data.\n *\n * @param targets the list of targets with views that need to be recomputed\n * @param transitionToPrimary `true` iff the tab transitions from a secondary\n * tab to a primary tab\n */\n// PORTING NOTE: Multi-Tab only.\nasync function synchronizeQueryViewsAndRaiseSnapshots(\n  syncEngine: SyncEngine,\n  targets: TargetId[],\n  transitionToPrimary: boolean\n): Promise<TargetData[]> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  const activeQueries: TargetData[] = [];\n  const newViewSnapshots: ViewSnapshot[] = [];\n  for (const targetId of targets) {\n    let targetData: TargetData;\n    const queries = syncEngineImpl.queriesByTarget.get(targetId);\n\n    if (queries && queries.length !== 0) {\n      // For queries that have a local View, we fetch their current state\n      // from LocalStore (as the resume token and the snapshot version\n      // might have changed) and reconcile their views with the persisted\n      // state (the list of syncedDocuments may have gotten out of sync).\n      targetData = await syncEngineImpl.localStore.allocateTarget(\n        queryToTarget(queries[0])\n      );\n\n      for (const query of queries) {\n        const queryView = syncEngineImpl.queryViewsByQuery.get(query);\n        debugAssert(\n          !!queryView,\n          `No query view found for ${stringifyQuery(query)}`\n        );\n\n        const viewChange = await synchronizeViewAndComputeSnapshot(\n          syncEngineImpl,\n          queryView\n        );\n        if (viewChange.snapshot) {\n          newViewSnapshots.push(viewChange.snapshot);\n        }\n      }\n    } else {\n      debugAssert(\n        transitionToPrimary,\n        'A secondary tab should never have an active view without an active target.'\n      );\n      // For queries that never executed on this client, we need to\n      // allocate the target in LocalStore and initialize a new View.\n      const target = await getCachedTarget(syncEngineImpl.localStore, targetId);\n      debugAssert(!!target, `Target for id ${targetId} not found`);\n      targetData = await syncEngineImpl.localStore.allocateTarget(target);\n      await syncEngineImpl.initializeViewAndComputeSnapshot(\n        synthesizeTargetToQuery(target!),\n        targetId,\n        /*current=*/ false\n      );\n    }\n\n    activeQueries.push(targetData!);\n  }\n\n  syncEngineImpl.syncEngineListener!.onWatchChange(newViewSnapshots);\n  return activeQueries;\n}\n\n/**\n * Creates a `Query` object from the specified `Target`. There is no way to\n * obtain the original `Query`, so we synthesize a `Query` from the `Target`\n * object.\n *\n * The synthesized result might be different from the original `Query`, but\n * since the synthesized `Query` should return the same results as the\n * original one (only the presentation of results might differ), the potential\n * difference will not cause issues.\n */\n// PORTING NOTE: Multi-Tab only.\nfunction synthesizeTargetToQuery(target: Target): Query {\n  return newQuery(\n    target.path,\n    target.collectionGroup,\n    target.orderBy,\n    target.filters,\n    target.limit,\n    LimitType.First,\n    target.startAt,\n    target.endAt\n  );\n}\n\n/** Returns the IDs of the clients that are currently active. */\n// PORTING NOTE: Multi-Tab only.\nexport function getActiveClients(syncEngine: SyncEngine): Promise<ClientId[]> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  return getActiveClientsFromPersistence(syncEngineImpl.localStore);\n}\n\n/** Applies a query target change from a different tab. */\n// PORTING NOTE: Multi-Tab only.\nexport async function applyTargetState(\n  syncEngine: SyncEngine,\n  targetId: TargetId,\n  state: QueryTargetState,\n  error?: FirestoreError\n): Promise<void> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  if (syncEngineImpl._isPrimaryClient) {\n    // If we receive a target state notification via WebStorage, we are\n    // either already secondary or another tab has taken the primary lease.\n    logDebug(LOG_TAG, 'Ignoring unexpected query state notification.');\n    return;\n  }\n\n  if (syncEngineImpl.queriesByTarget.has(targetId)) {\n    switch (state) {\n      case 'current':\n      case 'not-current': {\n        const changes = await getNewDocumentChanges(syncEngineImpl.localStore);\n        const synthesizedRemoteEvent = RemoteEvent.createSynthesizedRemoteEventForCurrentChange(\n          targetId,\n          state === 'current'\n        );\n        await syncEngineImpl.emitNewSnapsAndNotifyLocalStore(\n          changes,\n          synthesizedRemoteEvent\n        );\n        break;\n      }\n      case 'rejected': {\n        await syncEngineImpl.localStore.releaseTarget(\n          targetId,\n          /* keepPersistedTargetData */ true\n        );\n        syncEngineImpl.removeAndCleanupTarget(targetId, error);\n        break;\n      }\n      default:\n        fail('Unexpected target state: ' + state);\n    }\n  }\n}\n\n/** Adds or removes Watch targets for queries from different tabs. */\nexport async function applyActiveTargetsChange(\n  syncEngine: SyncEngine,\n  added: TargetId[],\n  removed: TargetId[]\n): Promise<void> {\n  const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);\n  if (!syncEngineImpl._isPrimaryClient) {\n    return;\n  }\n\n  for (const targetId of added) {\n    if (syncEngineImpl.queriesByTarget.has(targetId)) {\n      // A target might have been added in a previous attempt\n      logDebug(LOG_TAG, 'Adding an already active target ' + targetId);\n      continue;\n    }\n\n    const target = await getCachedTarget(syncEngineImpl.localStore, targetId);\n    debugAssert(!!target, `Query data for active target ${targetId} not found`);\n    const targetData = await syncEngineImpl.localStore.allocateTarget(target);\n    await syncEngineImpl.initializeViewAndComputeSnapshot(\n      synthesizeTargetToQuery(target),\n      targetData.targetId,\n      /*current=*/ false\n    );\n    syncEngineImpl.remoteStore.listen(targetData);\n  }\n\n  for (const targetId of removed) {\n    // Check that the target is still active since the target might have been\n    // removed if it has been rejected by the backend.\n    if (!syncEngineImpl.queriesByTarget.has(targetId)) {\n      continue;\n    }\n\n    // Release queries that are still active.\n    await syncEngineImpl.localStore\n      .releaseTarget(targetId, /* keepPersistedTargetData */ false)\n      .then(() => {\n        syncEngineImpl.remoteStore.unlisten(targetId);\n        syncEngineImpl.removeAndCleanupTarget(targetId);\n      })\n      .catch(ignoreIfPrimaryLeaseLoss);\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 { debugAssert } from '../util/assert';\nimport { EventHandler } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { canonifyQuery, Query, queryEquals, stringifyQuery } from './query';\nimport { SyncEngine, SyncEngineListener } from './sync_engine';\nimport { OnlineState } from './types';\nimport { ChangeType, DocumentViewChange, ViewSnapshot } from './view_snapshot';\nimport { wrapInUserErrorIfRecoverable } from '../util/async_queue';\n\n/**\n * Holds the listeners and the last received ViewSnapshot for a query being\n * tracked by EventManager.\n */\nclass QueryListenersInfo {\n  viewSnap: ViewSnapshot | undefined = undefined;\n  listeners: QueryListener[] = [];\n}\n\n/**\n * Interface for handling events from the EventManager.\n */\nexport interface Observer<T> {\n  next: EventHandler<T>;\n  error: EventHandler<Error>;\n}\n\n/**\n * EventManager is responsible for mapping queries to query event emitters.\n * It handles \"fan-out\". -- Identical queries will re-use the same watch on the\n * backend.\n */\nexport class EventManager implements SyncEngineListener {\n  private queries = new ObjectMap<Query, QueryListenersInfo>(\n    q => canonifyQuery(q),\n    queryEquals\n  );\n\n  private onlineState = OnlineState.Unknown;\n\n  private snapshotsInSyncListeners: Set<Observer<void>> = new Set();\n\n  constructor(private syncEngine: SyncEngine) {\n    this.syncEngine.subscribe(this);\n  }\n\n  async listen(listener: QueryListener): Promise<void> {\n    const query = listener.query;\n    let firstListen = false;\n\n    let queryInfo = this.queries.get(query);\n    if (!queryInfo) {\n      firstListen = true;\n      queryInfo = new QueryListenersInfo();\n    }\n\n    if (firstListen) {\n      try {\n        queryInfo.viewSnap = await this.syncEngine.listen(query);\n      } catch (e) {\n        const firestoreError = wrapInUserErrorIfRecoverable(\n          e,\n          `Initialization of query '${stringifyQuery(listener.query)}' failed`\n        );\n        listener.onError(firestoreError);\n        return;\n      }\n    }\n\n    this.queries.set(query, queryInfo);\n    queryInfo.listeners.push(listener);\n\n    // Run global snapshot listeners if a consistent snapshot has been emitted.\n    const raisedEvent = listener.applyOnlineStateChange(this.onlineState);\n    debugAssert(\n      !raisedEvent,\n      \"applyOnlineStateChange() shouldn't raise an event for brand-new listeners.\"\n    );\n\n    if (queryInfo.viewSnap) {\n      const raisedEvent = listener.onViewSnapshot(queryInfo.viewSnap);\n      if (raisedEvent) {\n        this.raiseSnapshotsInSyncEvent();\n      }\n    }\n  }\n\n  async unlisten(listener: QueryListener): Promise<void> {\n    const query = listener.query;\n    let lastListen = false;\n\n    const queryInfo = this.queries.get(query);\n    if (queryInfo) {\n      const i = queryInfo.listeners.indexOf(listener);\n      if (i >= 0) {\n        queryInfo.listeners.splice(i, 1);\n        lastListen = queryInfo.listeners.length === 0;\n      }\n    }\n\n    if (lastListen) {\n      this.queries.delete(query);\n      return this.syncEngine.unlisten(query);\n    }\n  }\n\n  onWatchChange(viewSnaps: ViewSnapshot[]): void {\n    let raisedEvent = false;\n    for (const viewSnap of viewSnaps) {\n      const query = viewSnap.query;\n      const queryInfo = this.queries.get(query);\n      if (queryInfo) {\n        for (const listener of queryInfo.listeners) {\n          if (listener.onViewSnapshot(viewSnap)) {\n            raisedEvent = true;\n          }\n        }\n        queryInfo.viewSnap = viewSnap;\n      }\n    }\n    if (raisedEvent) {\n      this.raiseSnapshotsInSyncEvent();\n    }\n  }\n\n  onWatchError(query: Query, error: Error): void {\n    const queryInfo = this.queries.get(query);\n    if (queryInfo) {\n      for (const listener of queryInfo.listeners) {\n        listener.onError(error);\n      }\n    }\n\n    // Remove all listeners. NOTE: We don't need to call syncEngine.unlisten()\n    // after an error.\n    this.queries.delete(query);\n  }\n\n  onOnlineStateChange(onlineState: OnlineState): void {\n    this.onlineState = onlineState;\n    let raisedEvent = false;\n    this.queries.forEach((_, queryInfo) => {\n      for (const listener of queryInfo.listeners) {\n        // Run global snapshot listeners if a consistent snapshot has been emitted.\n        if (listener.applyOnlineStateChange(onlineState)) {\n          raisedEvent = true;\n        }\n      }\n    });\n    if (raisedEvent) {\n      this.raiseSnapshotsInSyncEvent();\n    }\n  }\n\n  addSnapshotsInSyncListener(observer: Observer<void>): void {\n    this.snapshotsInSyncListeners.add(observer);\n    // Immediately fire an initial event, indicating all existing listeners\n    // are in-sync.\n    observer.next();\n  }\n\n  removeSnapshotsInSyncListener(observer: Observer<void>): void {\n    this.snapshotsInSyncListeners.delete(observer);\n  }\n\n  // Call all global snapshot listeners that have been set.\n  private raiseSnapshotsInSyncEvent(): void {\n    this.snapshotsInSyncListeners.forEach(observer => {\n      observer.next();\n    });\n  }\n}\n\nexport interface ListenOptions {\n  /** Raise events even when only the metadata changes */\n  readonly includeMetadataChanges?: boolean;\n\n  /**\n   * Wait for a sync with the server when online, but still raise events while\n   * offline.\n   */\n  readonly waitForSyncWhenOnline?: boolean;\n}\n\n/**\n * QueryListener takes a series of internal view snapshots and determines\n * when to raise the event.\n *\n * It uses an Observer to dispatch events.\n */\nexport class QueryListener {\n  /**\n   * Initial snapshots (e.g. from cache) may not be propagated to the wrapped\n   * observer. This flag is set to true once we've actually raised an event.\n   */\n  private raisedInitialEvent = false;\n\n  private options: ListenOptions;\n\n  private snap: ViewSnapshot | null = null;\n\n  private onlineState = OnlineState.Unknown;\n\n  constructor(\n    readonly query: Query,\n    private queryObserver: Observer<ViewSnapshot>,\n    options?: ListenOptions\n  ) {\n    this.options = options || {};\n  }\n\n  /**\n   * Applies the new ViewSnapshot to this listener, raising a user-facing event\n   * if applicable (depending on what changed, whether the user has opted into\n   * metadata-only changes, etc.). Returns true if a user-facing event was\n   * indeed raised.\n   */\n  onViewSnapshot(snap: ViewSnapshot): boolean {\n    debugAssert(\n      snap.docChanges.length > 0 || snap.syncStateChanged,\n      'We got a new snapshot with no changes?'\n    );\n\n    if (!this.options.includeMetadataChanges) {\n      // Remove the metadata only changes.\n      const docChanges: DocumentViewChange[] = [];\n      for (const docChange of snap.docChanges) {\n        if (docChange.type !== ChangeType.Metadata) {\n          docChanges.push(docChange);\n        }\n      }\n      snap = new ViewSnapshot(\n        snap.query,\n        snap.docs,\n        snap.oldDocs,\n        docChanges,\n        snap.mutatedKeys,\n        snap.fromCache,\n        snap.syncStateChanged,\n        /* excludesMetadataChanges= */ true\n      );\n    }\n    let raisedEvent = false;\n    if (!this.raisedInitialEvent) {\n      if (this.shouldRaiseInitialEvent(snap, this.onlineState)) {\n        this.raiseInitialEvent(snap);\n        raisedEvent = true;\n      }\n    } else if (this.shouldRaiseEvent(snap)) {\n      this.queryObserver.next(snap);\n      raisedEvent = true;\n    }\n\n    this.snap = snap;\n    return raisedEvent;\n  }\n\n  onError(error: Error): void {\n    this.queryObserver.error(error);\n  }\n\n  /** Returns whether a snapshot was raised. */\n  applyOnlineStateChange(onlineState: OnlineState): boolean {\n    this.onlineState = onlineState;\n    let raisedEvent = false;\n    if (\n      this.snap &&\n      !this.raisedInitialEvent &&\n      this.shouldRaiseInitialEvent(this.snap, onlineState)\n    ) {\n      this.raiseInitialEvent(this.snap);\n      raisedEvent = true;\n    }\n    return raisedEvent;\n  }\n\n  private shouldRaiseInitialEvent(\n    snap: ViewSnapshot,\n    onlineState: OnlineState\n  ): boolean {\n    debugAssert(\n      !this.raisedInitialEvent,\n      'Determining whether to raise first event but already had first event'\n    );\n\n    // Always raise the first event when we're synced\n    if (!snap.fromCache) {\n      return true;\n    }\n\n    // NOTE: We consider OnlineState.Unknown as online (it should become Offline\n    // or Online if we wait long enough).\n    const maybeOnline = onlineState !== OnlineState.Offline;\n    // Don't raise the event if we're online, aren't synced yet (checked\n    // above) and are waiting for a sync.\n    if (this.options.waitForSyncWhenOnline && maybeOnline) {\n      debugAssert(\n        snap.fromCache,\n        'Waiting for sync, but snapshot is not from cache'\n      );\n      return false;\n    }\n\n    // Raise data from cache if we have any documents or we are offline\n    return !snap.docs.isEmpty() || onlineState === OnlineState.Offline;\n  }\n\n  private shouldRaiseEvent(snap: ViewSnapshot): boolean {\n    // We don't need to handle includeDocumentMetadataChanges here because\n    // the Metadata only changes have already been stripped out if needed.\n    // At this point the only changes we will see are the ones we should\n    // propagate.\n    if (snap.docChanges.length > 0) {\n      return true;\n    }\n\n    const hasPendingWritesChanged =\n      this.snap && this.snap.hasPendingWrites !== snap.hasPendingWrites;\n    if (snap.syncStateChanged || hasPendingWritesChanged) {\n      return this.options.includeMetadataChanges === true;\n    }\n\n    // Generally we should have hit one of the cases above, but it's possible\n    // to get here if there were only metadata docChanges and they got\n    // stripped out.\n    return false;\n  }\n\n  private raiseInitialEvent(snap: ViewSnapshot): void {\n    debugAssert(\n      !this.raisedInitialEvent,\n      'Trying to raise initial events for second time'\n    );\n    snap = ViewSnapshot.fromInitialDocuments(\n      snap.query,\n      snap.docs,\n      snap.mutatedKeys,\n      snap.fromCache\n    );\n    this.raisedInitialEvent = true;\n    this.queryObserver.next(snap);\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 { QueryEngine } from './query_engine';\nimport { LocalDocumentsView } from './local_documents_view';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport {\n  LimitType,\n  newQueryComparator,\n  Query,\n  queryMatches,\n  stringifyQuery\n} from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n  DocumentKeySet,\n  DocumentMap,\n  MaybeDocumentMap\n} from '../model/collections';\nimport { Document } from '../model/document';\nimport { debugAssert } from '../util/assert';\nimport { getLogLevel, LogLevel, logDebug } from '../util/log';\nimport { SortedSet } from '../util/sorted_set';\n\n// TOOD(b/140938512): Drop SimpleQueryEngine and rename IndexFreeQueryEngine.\n\n/**\n * A query engine that takes advantage of the target document mapping in the\n * QueryCache. The IndexFreeQueryEngine optimizes query execution by only\n * reading the documents that previously matched a query plus any documents that were\n * edited after the query was last listened to.\n *\n * There are some cases where Index-Free queries are not guaranteed to produce\n * the same results as full collection scans. In these cases, the\n * IndexFreeQueryEngine falls back to full query processing. These cases are:\n *\n * - Limit queries where a document that matched the query previously no longer\n *   matches the query.\n *\n * - Limit queries where a document edit may cause the document to sort below\n *   another document that is in the local cache.\n *\n * - Queries that have never been CURRENT or free of Limbo documents.\n */\nexport class IndexFreeQueryEngine implements QueryEngine {\n  private localDocumentsView: LocalDocumentsView | undefined;\n\n  setLocalDocumentsView(localDocuments: LocalDocumentsView): void {\n    this.localDocumentsView = localDocuments;\n  }\n\n  getDocumentsMatchingQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    lastLimboFreeSnapshotVersion: SnapshotVersion,\n    remoteKeys: DocumentKeySet\n  ): PersistencePromise<DocumentMap> {\n    debugAssert(\n      this.localDocumentsView !== undefined,\n      'setLocalDocumentsView() not called'\n    );\n\n    // Queries that match all documents don't benefit from using\n    // IndexFreeQueries. It is more efficient to scan all documents in a\n    // collection, rather than to perform individual lookups.\n    if (query.matchesAllDocuments()) {\n      return this.executeFullCollectionScan(transaction, query);\n    }\n\n    // Queries that have never seen a snapshot without limbo free documents\n    // should also be run as a full collection scan.\n    if (lastLimboFreeSnapshotVersion.isEqual(SnapshotVersion.min())) {\n      return this.executeFullCollectionScan(transaction, query);\n    }\n\n    return this.localDocumentsView!.getDocuments(transaction, remoteKeys).next(\n      documents => {\n        const previousResults = this.applyQuery(query, documents);\n\n        if (\n          (query.hasLimitToFirst() || query.hasLimitToLast()) &&\n          this.needsRefill(\n            query.limitType,\n            previousResults,\n            remoteKeys,\n            lastLimboFreeSnapshotVersion\n          )\n        ) {\n          return this.executeFullCollectionScan(transaction, query);\n        }\n\n        if (getLogLevel() <= LogLevel.DEBUG) {\n          logDebug(\n            'IndexFreeQueryEngine',\n            'Re-using previous result from %s to execute query: %s',\n            lastLimboFreeSnapshotVersion.toString(),\n            stringifyQuery(query)\n          );\n        }\n\n        // Retrieve all results for documents that were updated since the last\n        // limbo-document free remote snapshot.\n        return this.localDocumentsView!.getDocumentsMatchingQuery(\n          transaction,\n          query,\n          lastLimboFreeSnapshotVersion\n        ).next(updatedResults => {\n          // We merge `previousResults` into `updateResults`, since\n          // `updateResults` is already a DocumentMap. If a document is\n          // contained in both lists, then its contents are the same.\n          previousResults.forEach(doc => {\n            updatedResults = updatedResults.insert(doc.key, doc);\n          });\n          return updatedResults;\n        });\n      }\n    );\n  }\n\n  /** Applies the query filter and sorting to the provided documents.  */\n  private applyQuery(\n    query: Query,\n    documents: MaybeDocumentMap\n  ): SortedSet<Document> {\n    // Sort the documents and re-apply the query filter since previously\n    // matching documents do not necessarily still match the query.\n    let queryResults = new SortedSet<Document>(newQueryComparator(query));\n    documents.forEach((_, maybeDoc) => {\n      if (maybeDoc instanceof Document && queryMatches(query, maybeDoc)) {\n        queryResults = queryResults.add(maybeDoc);\n      }\n    });\n    return queryResults;\n  }\n\n  /**\n   * Determines if a limit query needs to be refilled from cache, making it\n   * ineligible for index-free execution.\n   *\n   * @param sortedPreviousResults The documents that matched the query when it\n   * was last synchronized, sorted by the query's comparator.\n   * @param remoteKeys The document keys that matched the query at the last\n   * snapshot.\n   * @param limboFreeSnapshotVersion The version of the snapshot when the query\n   * was last synchronized.\n   */\n  private needsRefill(\n    limitType: LimitType,\n    sortedPreviousResults: SortedSet<Document>,\n    remoteKeys: DocumentKeySet,\n    limboFreeSnapshotVersion: SnapshotVersion\n  ): boolean {\n    // The query needs to be refilled if a previously matching document no\n    // longer matches.\n    if (remoteKeys.size !== sortedPreviousResults.size) {\n      return true;\n    }\n\n    // Limit queries are not eligible for index-free query execution if there is\n    // a potential that an older document from cache now sorts before a document\n    // that was previously part of the limit. This, however, can only happen if\n    // the document at the edge of the limit goes out of limit.\n    // If a document that is not the limit boundary sorts differently,\n    // the boundary of the limit itself did not change and documents from cache\n    // will continue to be \"rejected\" by this boundary. Therefore, we can ignore\n    // any modifications that don't affect the last document.\n    const docAtLimitEdge =\n      limitType === LimitType.First\n        ? sortedPreviousResults.last()\n        : sortedPreviousResults.first();\n    if (!docAtLimitEdge) {\n      // We don't need to refill the query if there were already no documents.\n      return false;\n    }\n    return (\n      docAtLimitEdge.hasPendingWrites ||\n      docAtLimitEdge.version.compareTo(limboFreeSnapshotVersion) > 0\n    );\n  }\n\n  private executeFullCollectionScan(\n    transaction: PersistenceTransaction,\n    query: Query\n  ): PersistencePromise<DocumentMap> {\n    if (getLogLevel() <= LogLevel.DEBUG) {\n      logDebug(\n        'IndexFreeQueryEngine',\n        'Using full collection scan to execute query:',\n        stringifyQuery(query)\n      );\n    }\n\n    return this.localDocumentsView!.getDocumentsMatchingQuery(\n      transaction,\n      query,\n      SnapshotVersion.min()\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 { Timestamp } from '../api/timestamp';\nimport { isCollectionGroupQuery, Query } from '../core/query';\nimport { BatchId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { MutationBatch, BATCHID_UNKNOWN } from '../model/mutation_batch';\nimport { debugAssert, hardAssert } from '../util/assert';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { IndexManager } from './index_manager';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistenceTransaction, ReferenceDelegate } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { DocReference } from './reference_set';\n\nexport class MemoryMutationQueue implements MutationQueue {\n  /**\n   * The set of all mutations that have been sent but not yet been applied to\n   * the backend.\n   */\n  private mutationQueue: MutationBatch[] = [];\n\n  /** Next value to use when assigning sequential IDs to each mutation batch. */\n  private nextBatchId: BatchId = 1;\n\n  /** An ordered mapping between documents and the mutations batch IDs. */\n  private batchesByDocumentKey = new SortedSet(DocReference.compareByKey);\n\n  constructor(\n    private readonly indexManager: IndexManager,\n    private readonly referenceDelegate: ReferenceDelegate\n  ) {}\n\n  checkEmpty(transaction: PersistenceTransaction): PersistencePromise<boolean> {\n    return PersistencePromise.resolve(this.mutationQueue.length === 0);\n  }\n\n  addMutationBatch(\n    transaction: PersistenceTransaction,\n    localWriteTime: Timestamp,\n    baseMutations: Mutation[],\n    mutations: Mutation[]\n  ): PersistencePromise<MutationBatch> {\n    debugAssert(mutations.length !== 0, 'Mutation batches should not be empty');\n\n    const batchId = this.nextBatchId;\n    this.nextBatchId++;\n\n    if (this.mutationQueue.length > 0) {\n      const prior = this.mutationQueue[this.mutationQueue.length - 1];\n      debugAssert(\n        prior.batchId < batchId,\n        'Mutation batchIDs must be monotonically increasing order'\n      );\n    }\n\n    const batch = new MutationBatch(\n      batchId,\n      localWriteTime,\n      baseMutations,\n      mutations\n    );\n    this.mutationQueue.push(batch);\n\n    // Track references by document key and index collection parents.\n    for (const mutation of mutations) {\n      this.batchesByDocumentKey = this.batchesByDocumentKey.add(\n        new DocReference(mutation.key, batchId)\n      );\n\n      this.indexManager.addToCollectionParentIndex(\n        transaction,\n        mutation.key.path.popLast()\n      );\n    }\n\n    return PersistencePromise.resolve(batch);\n  }\n\n  lookupMutationBatch(\n    transaction: PersistenceTransaction,\n    batchId: BatchId\n  ): PersistencePromise<MutationBatch | null> {\n    return PersistencePromise.resolve(this.findMutationBatch(batchId));\n  }\n\n  getNextMutationBatchAfterBatchId(\n    transaction: PersistenceTransaction,\n    batchId: BatchId\n  ): PersistencePromise<MutationBatch | null> {\n    const nextBatchId = batchId + 1;\n\n    // The requested batchId may still be out of range so normalize it to the\n    // start of the queue.\n    const rawIndex = this.indexOfBatchId(nextBatchId);\n    const index = rawIndex < 0 ? 0 : rawIndex;\n    return PersistencePromise.resolve(\n      this.mutationQueue.length > index ? this.mutationQueue[index] : null\n    );\n  }\n\n  getHighestUnacknowledgedBatchId(): PersistencePromise<BatchId> {\n    return PersistencePromise.resolve(\n      this.mutationQueue.length === 0 ? BATCHID_UNKNOWN : this.nextBatchId - 1\n    );\n  }\n\n  getAllMutationBatches(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<MutationBatch[]> {\n    return PersistencePromise.resolve(this.mutationQueue.slice());\n  }\n\n  getAllMutationBatchesAffectingDocumentKey(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MutationBatch[]> {\n    const start = new DocReference(documentKey, 0);\n    const end = new DocReference(documentKey, Number.POSITIVE_INFINITY);\n    const result: MutationBatch[] = [];\n    this.batchesByDocumentKey.forEachInRange([start, end], ref => {\n      debugAssert(\n        documentKey.isEqual(ref.key),\n        \"Should only iterate over a single key's batches\"\n      );\n      const batch = this.findMutationBatch(ref.targetOrBatchId);\n      debugAssert(\n        batch !== null,\n        'Batches in the index must exist in the main table'\n      );\n      result.push(batch!);\n    });\n\n    return PersistencePromise.resolve(result);\n  }\n\n  getAllMutationBatchesAffectingDocumentKeys(\n    transaction: PersistenceTransaction,\n    documentKeys: SortedMap<DocumentKey, unknown>\n  ): PersistencePromise<MutationBatch[]> {\n    let uniqueBatchIDs = new SortedSet<number>(primitiveComparator);\n\n    documentKeys.forEach(documentKey => {\n      const start = new DocReference(documentKey, 0);\n      const end = new DocReference(documentKey, Number.POSITIVE_INFINITY);\n      this.batchesByDocumentKey.forEachInRange([start, end], ref => {\n        debugAssert(\n          documentKey.isEqual(ref.key),\n          \"For each key, should only iterate over a single key's batches\"\n        );\n\n        uniqueBatchIDs = uniqueBatchIDs.add(ref.targetOrBatchId);\n      });\n    });\n\n    return PersistencePromise.resolve(this.findMutationBatches(uniqueBatchIDs));\n  }\n\n  getAllMutationBatchesAffectingQuery(\n    transaction: PersistenceTransaction,\n    query: Query\n  ): PersistencePromise<MutationBatch[]> {\n    debugAssert(\n      !isCollectionGroupQuery(query),\n      'CollectionGroup queries should be handled in LocalDocumentsView'\n    );\n    // Use the query path as a prefix for testing if a document matches the\n    // query.\n    const prefix = query.path;\n    const immediateChildrenPathLength = prefix.length + 1;\n\n    // Construct a document reference for actually scanning the index. Unlike\n    // the prefix the document key in this reference must have an even number of\n    // segments. The empty segment can be used a suffix of the query path\n    // because it precedes all other segments in an ordered traversal.\n    let startPath = prefix;\n    if (!DocumentKey.isDocumentKey(startPath)) {\n      startPath = startPath.child('');\n    }\n\n    const start = new DocReference(new DocumentKey(startPath), 0);\n\n    // Find unique batchIDs referenced by all documents potentially matching the\n    // query.\n    let uniqueBatchIDs = new SortedSet<number>(primitiveComparator);\n\n    this.batchesByDocumentKey.forEachWhile(ref => {\n      const rowKeyPath = ref.key.path;\n      if (!prefix.isPrefixOf(rowKeyPath)) {\n        return false;\n      } else {\n        // Rows with document keys more than one segment longer than the query\n        // path can't be matches. For example, a query on 'rooms' can't match\n        // the document /rooms/abc/messages/xyx.\n        // TODO(mcg): we'll need a different scanner when we implement\n        // ancestor queries.\n        if (rowKeyPath.length === immediateChildrenPathLength) {\n          uniqueBatchIDs = uniqueBatchIDs.add(ref.targetOrBatchId);\n        }\n        return true;\n      }\n    }, start);\n\n    return PersistencePromise.resolve(this.findMutationBatches(uniqueBatchIDs));\n  }\n\n  private findMutationBatches(batchIDs: SortedSet<number>): MutationBatch[] {\n    // Construct an array of matching batches, sorted by batchID to ensure that\n    // multiple mutations affecting the same document key are applied in order.\n    const result: MutationBatch[] = [];\n    batchIDs.forEach(batchId => {\n      const batch = this.findMutationBatch(batchId);\n      if (batch !== null) {\n        result.push(batch);\n      }\n    });\n    return result;\n  }\n\n  removeMutationBatch(\n    transaction: PersistenceTransaction,\n    batch: MutationBatch\n  ): PersistencePromise<void> {\n    // Find the position of the first batch for removal.\n    const batchIndex = this.indexOfExistingBatchId(batch.batchId, 'removed');\n    hardAssert(\n      batchIndex === 0,\n      'Can only remove the first entry of the mutation queue'\n    );\n    this.mutationQueue.shift();\n\n    let references = this.batchesByDocumentKey;\n    return PersistencePromise.forEach(batch.mutations, (mutation: Mutation) => {\n      const ref = new DocReference(mutation.key, batch.batchId);\n      references = references.delete(ref);\n      return this.referenceDelegate.markPotentiallyOrphaned(\n        transaction,\n        mutation.key\n      );\n    }).next(() => {\n      this.batchesByDocumentKey = references;\n    });\n  }\n\n  removeCachedMutationKeys(batchId: BatchId): void {\n    // No-op since the memory mutation queue does not maintain a separate cache.\n  }\n\n  containsKey(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    const ref = new DocReference(key, 0);\n    const firstRef = this.batchesByDocumentKey.firstAfterOrEqual(ref);\n    return PersistencePromise.resolve(key.isEqual(firstRef && firstRef.key));\n  }\n\n  performConsistencyCheck(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    if (this.mutationQueue.length === 0) {\n      debugAssert(\n        this.batchesByDocumentKey.isEmpty(),\n        'Document leak -- detected dangling mutation references when queue is empty.'\n      );\n    }\n    return PersistencePromise.resolve();\n  }\n\n  /**\n   * Finds the index of the given batchId in the mutation queue and asserts that\n   * the resulting index is within the bounds of the queue.\n   *\n   * @param batchId The batchId to search for\n   * @param action A description of what the caller is doing, phrased in passive\n   * form (e.g. \"acknowledged\" in a routine that acknowledges batches).\n   */\n  private indexOfExistingBatchId(batchId: BatchId, action: string): number {\n    const index = this.indexOfBatchId(batchId);\n    debugAssert(\n      index >= 0 && index < this.mutationQueue.length,\n      'Batches must exist to be ' + action\n    );\n    return index;\n  }\n\n  /**\n   * Finds the index of the given batchId in the mutation queue. This operation\n   * is O(1).\n   *\n   * @return The computed index of the batch with the given batchId, based on\n   * the state of the queue. Note this index can be negative if the requested\n   * batchId has already been remvoed from the queue or past the end of the\n   * queue if the batchId is larger than the last added batch.\n   */\n  private indexOfBatchId(batchId: BatchId): number {\n    if (this.mutationQueue.length === 0) {\n      // As an index this is past the end of the queue\n      return 0;\n    }\n\n    // Examine the front of the queue to figure out the difference between the\n    // batchId and indexes in the array. Note that since the queue is ordered\n    // by batchId, if the first batch has a larger batchId then the requested\n    // batchId doesn't exist in the queue.\n    const firstBatchId = this.mutationQueue[0].batchId;\n    return batchId - firstBatchId;\n  }\n\n  /**\n   * A version of lookupMutationBatch that doesn't return a promise, this makes\n   * other functions that uses this code easier to read and more efficent.\n   */\n  private findMutationBatch(batchId: BatchId): MutationBatch | null {\n    const index = this.indexOfBatchId(batchId);\n    if (index < 0 || index >= this.mutationQueue.length) {\n      return null;\n    }\n\n    const batch = this.mutationQueue[index];\n    debugAssert(batch.batchId === batchId, 'If found batch must match');\n    return batch;\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 { isCollectionGroupQuery, Query, queryMatches } from '../core/query';\nimport {\n  DocumentKeySet,\n  DocumentMap,\n  documentMap,\n  DocumentSizeEntry,\n  NullableMaybeDocumentMap,\n  nullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert } from '../util/assert';\nimport { SortedMap } from '../util/sorted_map';\nimport { IndexManager } from './index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\n\nexport type DocumentSizer = (doc: MaybeDocument) => number;\n\n/** Miscellaneous collection types / constants. */\ninterface MemoryRemoteDocumentCacheEntry extends DocumentSizeEntry {\n  readTime: SnapshotVersion;\n}\n\ntype DocumentEntryMap = SortedMap<DocumentKey, MemoryRemoteDocumentCacheEntry>;\nfunction documentEntryMap(): DocumentEntryMap {\n  return new SortedMap<DocumentKey, MemoryRemoteDocumentCacheEntry>(\n    DocumentKey.comparator\n  );\n}\n\nexport class MemoryRemoteDocumentCache implements RemoteDocumentCache {\n  /** Underlying cache of documents and their read times. */\n  private docs = documentEntryMap();\n\n  /** Size of all cached documents. */\n  private size = 0;\n\n  /**\n   * @param sizer Used to assess the size of a document. For eager GC, this is expected to just\n   * return 0 to avoid unnecessarily doing the work of calculating the size.\n   */\n  constructor(\n    private readonly indexManager: IndexManager,\n    private readonly sizer: DocumentSizer\n  ) {}\n\n  /**\n   * Adds the supplied entry to the cache and updates the cache size as appropriate.\n   *\n   * All calls of `addEntry`  are required to go through the RemoteDocumentChangeBuffer\n   * returned by `newChangeBuffer()`.\n   */\n  private addEntry(\n    transaction: PersistenceTransaction,\n    doc: MaybeDocument,\n    readTime: SnapshotVersion\n  ): PersistencePromise<void> {\n    debugAssert(\n      !readTime.isEqual(SnapshotVersion.min()),\n      'Cannot add a document with a read time of zero'\n    );\n\n    const key = doc.key;\n    const entry = this.docs.get(key);\n    const previousSize = entry ? entry.size : 0;\n    const currentSize = this.sizer(doc);\n\n    this.docs = this.docs.insert(key, {\n      maybeDocument: doc,\n      size: currentSize,\n      readTime\n    });\n\n    this.size += currentSize - previousSize;\n\n    return this.indexManager.addToCollectionParentIndex(\n      transaction,\n      key.path.popLast()\n    );\n  }\n\n  /**\n   * Removes the specified entry from the cache and updates the cache size as appropriate.\n   *\n   * All calls of `removeEntry` are required to go through the RemoteDocumentChangeBuffer\n   * returned by `newChangeBuffer()`.\n   */\n  private removeEntry(documentKey: DocumentKey): void {\n    const entry = this.docs.get(documentKey);\n    if (entry) {\n      this.docs = this.docs.remove(documentKey);\n      this.size -= entry.size;\n    }\n  }\n\n  getEntry(\n    transaction: PersistenceTransaction,\n    documentKey: DocumentKey\n  ): PersistencePromise<MaybeDocument | null> {\n    const entry = this.docs.get(documentKey);\n    return PersistencePromise.resolve(entry ? entry.maybeDocument : null);\n  }\n\n  getEntries(\n    transaction: PersistenceTransaction,\n    documentKeys: DocumentKeySet\n  ): PersistencePromise<NullableMaybeDocumentMap> {\n    let results = nullableMaybeDocumentMap();\n    documentKeys.forEach(documentKey => {\n      const entry = this.docs.get(documentKey);\n      results = results.insert(documentKey, entry ? entry.maybeDocument : null);\n    });\n    return PersistencePromise.resolve(results);\n  }\n\n  getDocumentsMatchingQuery(\n    transaction: PersistenceTransaction,\n    query: Query,\n    sinceReadTime: SnapshotVersion\n  ): PersistencePromise<DocumentMap> {\n    debugAssert(\n      !isCollectionGroupQuery(query),\n      'CollectionGroup queries should be handled in LocalDocumentsView'\n    );\n    let results = documentMap();\n\n    // Documents are ordered by key, so we can use a prefix scan to narrow down\n    // the documents we need to match the query against.\n    const prefix = new DocumentKey(query.path.child(''));\n    const iterator = this.docs.getIteratorFrom(prefix);\n    while (iterator.hasNext()) {\n      const {\n        key,\n        value: { maybeDocument, readTime }\n      } = iterator.getNext();\n      if (!query.path.isPrefixOf(key.path)) {\n        break;\n      }\n      if (readTime.compareTo(sinceReadTime) <= 0) {\n        continue;\n      }\n      if (\n        maybeDocument instanceof Document &&\n        queryMatches(query, maybeDocument)\n      ) {\n        results = results.insert(maybeDocument.key, maybeDocument);\n      }\n    }\n    return PersistencePromise.resolve(results);\n  }\n\n  forEachDocumentKey(\n    transaction: PersistenceTransaction,\n    f: (key: DocumentKey) => PersistencePromise<void>\n  ): PersistencePromise<void> {\n    return PersistencePromise.forEach(this.docs, (key: DocumentKey) => f(key));\n  }\n\n  newChangeBuffer(options?: {\n    trackRemovals: boolean;\n  }): RemoteDocumentChangeBuffer {\n    // `trackRemovals` is ignores since the MemoryRemoteDocumentCache keeps\n    // a separate changelog and does not need special handling for removals.\n    return new MemoryRemoteDocumentCache.RemoteDocumentChangeBuffer(this);\n  }\n\n  getSize(txn: PersistenceTransaction): PersistencePromise<number> {\n    return PersistencePromise.resolve(this.size);\n  }\n\n  /**\n   * Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.\n   */\n  private static RemoteDocumentChangeBuffer = class extends RemoteDocumentChangeBuffer {\n    constructor(private readonly documentCache: MemoryRemoteDocumentCache) {\n      super();\n    }\n\n    protected applyChanges(\n      transaction: PersistenceTransaction\n    ): PersistencePromise<void> {\n      const promises: Array<PersistencePromise<void>> = [];\n      this.changes.forEach((key, doc) => {\n        if (doc) {\n          promises.push(\n            this.documentCache.addEntry(transaction, doc, this.readTime)\n          );\n        } else {\n          this.documentCache.removeEntry(key);\n        }\n      });\n      return PersistencePromise.waitFor(promises);\n    }\n\n    protected getFromCache(\n      transaction: PersistenceTransaction,\n      documentKey: DocumentKey\n    ): PersistencePromise<MaybeDocument | null> {\n      return this.documentCache.getEntry(transaction, documentKey);\n    }\n\n    protected getAllFromCache(\n      transaction: PersistenceTransaction,\n      documentKeys: DocumentKeySet\n    ): PersistencePromise<NullableMaybeDocumentMap> {\n      return this.documentCache.getEntries(transaction, documentKeys);\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetIdGenerator } from '../core/target_id_generator';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert } from '../util/assert';\nimport { ObjectMap } from '../util/obj_map';\n\nimport { ActiveTargets } from './lru_garbage_collector';\nimport { MemoryPersistence } from './memory_persistence';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ReferenceSet } from './reference_set';\nimport { TargetCache } from './target_cache';\nimport { TargetData } from './target_data';\nimport { canonifyTarget, Target, targetEquals } from '../core/target';\n\nexport class MemoryTargetCache implements TargetCache {\n  /**\n   * Maps a target to the data about that target\n   */\n  private targets = new ObjectMap<Target, TargetData>(\n    t => canonifyTarget(t),\n    targetEquals\n  );\n\n  /** The last received snapshot version. */\n  private lastRemoteSnapshotVersion = SnapshotVersion.min();\n  /** The highest numbered target ID encountered. */\n  private highestTargetId: TargetId = 0;\n  /** The highest sequence number encountered. */\n  private highestSequenceNumber: ListenSequenceNumber = 0;\n  /**\n   * A ordered bidirectional mapping between documents and the remote target\n   * IDs.\n   */\n  private references = new ReferenceSet();\n\n  private targetCount = 0;\n\n  private targetIdGenerator = TargetIdGenerator.forTargetCache();\n\n  constructor(private readonly persistence: MemoryPersistence) {}\n\n  forEachTarget(\n    txn: PersistenceTransaction,\n    f: (q: TargetData) => void\n  ): PersistencePromise<void> {\n    this.targets.forEach((_, targetData) => f(targetData));\n    return PersistencePromise.resolve();\n  }\n\n  getLastRemoteSnapshotVersion(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<SnapshotVersion> {\n    return PersistencePromise.resolve(this.lastRemoteSnapshotVersion);\n  }\n\n  getHighestSequenceNumber(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<ListenSequenceNumber> {\n    return PersistencePromise.resolve(this.highestSequenceNumber);\n  }\n\n  allocateTargetId(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<TargetId> {\n    this.highestTargetId = this.targetIdGenerator.next();\n    return PersistencePromise.resolve(this.highestTargetId);\n  }\n\n  setTargetsMetadata(\n    transaction: PersistenceTransaction,\n    highestListenSequenceNumber: number,\n    lastRemoteSnapshotVersion?: SnapshotVersion\n  ): PersistencePromise<void> {\n    if (lastRemoteSnapshotVersion) {\n      this.lastRemoteSnapshotVersion = lastRemoteSnapshotVersion;\n    }\n    if (highestListenSequenceNumber > this.highestSequenceNumber) {\n      this.highestSequenceNumber = highestListenSequenceNumber;\n    }\n    return PersistencePromise.resolve();\n  }\n\n  private saveTargetData(targetData: TargetData): void {\n    this.targets.set(targetData.target, targetData);\n    const targetId = targetData.targetId;\n    if (targetId > this.highestTargetId) {\n      this.targetIdGenerator = new TargetIdGenerator(targetId);\n      this.highestTargetId = targetId;\n    }\n    if (targetData.sequenceNumber > this.highestSequenceNumber) {\n      this.highestSequenceNumber = targetData.sequenceNumber;\n    }\n  }\n\n  addTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    debugAssert(\n      !this.targets.has(targetData.target),\n      'Adding a target that already exists'\n    );\n    this.saveTargetData(targetData);\n    this.targetCount += 1;\n    return PersistencePromise.resolve();\n  }\n\n  updateTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    debugAssert(\n      this.targets.has(targetData.target),\n      'Updating a non-existent target'\n    );\n    this.saveTargetData(targetData);\n    return PersistencePromise.resolve();\n  }\n\n  removeTargetData(\n    transaction: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    debugAssert(this.targetCount > 0, 'Removing a target from an empty cache');\n    debugAssert(\n      this.targets.has(targetData.target),\n      'Removing a non-existent target from the cache'\n    );\n    this.targets.delete(targetData.target);\n    this.references.removeReferencesForId(targetData.targetId);\n    this.targetCount -= 1;\n    return PersistencePromise.resolve();\n  }\n\n  removeTargets(\n    transaction: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number> {\n    let count = 0;\n    const removals: Array<PersistencePromise<void>> = [];\n    this.targets.forEach((key, targetData) => {\n      if (\n        targetData.sequenceNumber <= upperBound &&\n        activeTargetIds.get(targetData.targetId) === null\n      ) {\n        this.targets.delete(key);\n        removals.push(\n          this.removeMatchingKeysForTargetId(transaction, targetData.targetId)\n        );\n        count++;\n      }\n    });\n    return PersistencePromise.waitFor(removals).next(() => count);\n  }\n\n  getTargetCount(\n    transaction: PersistenceTransaction\n  ): PersistencePromise<number> {\n    return PersistencePromise.resolve(this.targetCount);\n  }\n\n  getTargetData(\n    transaction: PersistenceTransaction,\n    target: Target\n  ): PersistencePromise<TargetData | null> {\n    const targetData = this.targets.get(target) || null;\n    return PersistencePromise.resolve(targetData);\n  }\n\n  addMatchingKeys(\n    txn: PersistenceTransaction,\n    keys: DocumentKeySet,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    this.references.addReferences(keys, targetId);\n    return PersistencePromise.resolve();\n  }\n\n  removeMatchingKeys(\n    txn: PersistenceTransaction,\n    keys: DocumentKeySet,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    this.references.removeReferences(keys, targetId);\n    const referenceDelegate = this.persistence.referenceDelegate;\n    const promises: Array<PersistencePromise<void>> = [];\n    if (referenceDelegate) {\n      keys.forEach(key => {\n        promises.push(referenceDelegate.markPotentiallyOrphaned(txn, key));\n      });\n    }\n    return PersistencePromise.waitFor(promises);\n  }\n\n  removeMatchingKeysForTargetId(\n    txn: PersistenceTransaction,\n    targetId: TargetId\n  ): PersistencePromise<void> {\n    this.references.removeReferencesForId(targetId);\n    return PersistencePromise.resolve();\n  }\n\n  getMatchingKeysForTargetId(\n    txn: PersistenceTransaction,\n    targetId: TargetId\n  ): PersistencePromise<DocumentKeySet> {\n    const matchingKeys = this.references.referencesForId(targetId);\n    return PersistencePromise.resolve(matchingKeys);\n  }\n\n  containsKey(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    return PersistencePromise.resolve(this.references.containsKey(key));\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 { User } from '../auth/user';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { fail } from '../util/assert';\nimport { logDebug } from '../util/log';\nimport { ObjectMap } from '../util/obj_map';\nimport { encodeResourcePath } from './encoded_resource_path';\nimport {\n  ActiveTargets,\n  LruDelegate,\n  LruGarbageCollector,\n  LruParams\n} from './lru_garbage_collector';\nimport { ListenSequence } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { estimateByteSize } from '../model/values';\nimport { MemoryIndexManager } from './memory_index_manager';\nimport { MemoryMutationQueue } from './memory_mutation_queue';\nimport { MemoryRemoteDocumentCache } from './memory_remote_document_cache';\nimport { MemoryTargetCache } from './memory_target_cache';\nimport { MutationQueue } from './mutation_queue';\nimport {\n  Persistence,\n  PersistenceTransaction,\n  PersistenceTransactionMode,\n  ReferenceDelegate\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ReferenceSet } from './reference_set';\nimport { TargetData } from './target_data';\n\nconst LOG_TAG = 'MemoryPersistence';\n/**\n * A memory-backed instance of Persistence. Data is stored only in RAM and\n * not persisted across sessions.\n */\nexport class MemoryPersistence implements Persistence {\n  /**\n   * Note that these are retained here to make it easier to write tests\n   * affecting both the in-memory and IndexedDB-backed persistence layers. Tests\n   * can create a new LocalStore wrapping this Persistence instance and this\n   * will make the in-memory persistence layer behave as if it were actually\n   * persisting values.\n   */\n  private readonly indexManager: MemoryIndexManager;\n  private mutationQueues: { [user: string]: MemoryMutationQueue } = {};\n  private readonly remoteDocumentCache: MemoryRemoteDocumentCache;\n  private readonly targetCache: MemoryTargetCache;\n  private readonly listenSequence = new ListenSequence(0);\n\n  private _started = false;\n\n  readonly referenceDelegate: MemoryReferenceDelegate;\n\n  /**\n   * The constructor accepts a factory for creating a reference delegate. This\n   * allows both the delegate and this instance to have strong references to\n   * each other without having nullable fields that would then need to be\n   * checked or asserted on every access.\n   */\n  constructor(\n    referenceDelegateFactory: (p: MemoryPersistence) => MemoryReferenceDelegate\n  ) {\n    this._started = true;\n    this.referenceDelegate = referenceDelegateFactory(this);\n    this.targetCache = new MemoryTargetCache(this);\n    const sizer = (doc: MaybeDocument): number =>\n      this.referenceDelegate.documentSize(doc);\n    this.indexManager = new MemoryIndexManager();\n    this.remoteDocumentCache = new MemoryRemoteDocumentCache(\n      this.indexManager,\n      sizer\n    );\n  }\n\n  start(): Promise<void> {\n    return Promise.resolve();\n  }\n\n  shutdown(): Promise<void> {\n    // No durable state to ensure is closed on shutdown.\n    this._started = false;\n    return Promise.resolve();\n  }\n\n  get started(): boolean {\n    return this._started;\n  }\n\n  setDatabaseDeletedListener(): void {\n    // No op.\n  }\n\n  setNetworkEnabled(): void {\n    // No op.\n  }\n\n  getIndexManager(): MemoryIndexManager {\n    return this.indexManager;\n  }\n\n  getMutationQueue(user: User): MutationQueue {\n    let queue = this.mutationQueues[user.toKey()];\n    if (!queue) {\n      queue = new MemoryMutationQueue(\n        this.indexManager,\n        this.referenceDelegate\n      );\n      this.mutationQueues[user.toKey()] = queue;\n    }\n    return queue;\n  }\n\n  getTargetCache(): MemoryTargetCache {\n    return this.targetCache;\n  }\n\n  getRemoteDocumentCache(): MemoryRemoteDocumentCache {\n    return this.remoteDocumentCache;\n  }\n\n  runTransaction<T>(\n    action: string,\n    mode: PersistenceTransactionMode,\n    transactionOperation: (\n      transaction: PersistenceTransaction\n    ) => PersistencePromise<T>\n  ): Promise<T> {\n    logDebug(LOG_TAG, 'Starting transaction:', action);\n    const txn = new MemoryTransaction(this.listenSequence.next());\n    this.referenceDelegate.onTransactionStarted();\n    return transactionOperation(txn)\n      .next(result => {\n        return this.referenceDelegate\n          .onTransactionCommitted(txn)\n          .next(() => result);\n      })\n      .toPromise()\n      .then(result => {\n        txn.raiseOnCommittedEvent();\n        return result;\n      });\n  }\n\n  mutationQueuesContainKey(\n    transaction: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    return PersistencePromise.or(\n      Object.values(this.mutationQueues).map(queue => () =>\n        queue.containsKey(transaction, key)\n      )\n    );\n  }\n}\n\n/**\n * Memory persistence is not actually transactional, but future implementations\n * may have transaction-scoped state.\n */\nexport class MemoryTransaction extends PersistenceTransaction {\n  constructor(readonly currentSequenceNumber: ListenSequenceNumber) {\n    super();\n  }\n}\n\nexport interface MemoryReferenceDelegate extends ReferenceDelegate {\n  documentSize(doc: MaybeDocument): number;\n  onTransactionStarted(): void;\n  onTransactionCommitted(txn: PersistenceTransaction): PersistencePromise<void>;\n}\n\nexport class MemoryEagerDelegate implements MemoryReferenceDelegate {\n  /** Tracks all documents that are active in Query views. */\n  private localViewReferences: ReferenceSet = new ReferenceSet();\n  /** The list of documents that are potentially GCed after each transaction. */\n  private _orphanedDocuments: Set<DocumentKey> | null = null;\n\n  private constructor(private readonly persistence: MemoryPersistence) {}\n\n  static factory(persistence: MemoryPersistence): MemoryEagerDelegate {\n    return new MemoryEagerDelegate(persistence);\n  }\n\n  private get orphanedDocuments(): Set<DocumentKey> {\n    if (!this._orphanedDocuments) {\n      throw fail('orphanedDocuments is only valid during a transaction.');\n    } else {\n      return this._orphanedDocuments;\n    }\n  }\n\n  addReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.localViewReferences.addReference(key, targetId);\n    this.orphanedDocuments.delete(key);\n    return PersistencePromise.resolve();\n  }\n\n  removeReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.localViewReferences.removeReference(key, targetId);\n    this.orphanedDocuments.add(key);\n    return PersistencePromise.resolve();\n  }\n\n  markPotentiallyOrphaned(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.orphanedDocuments.add(key);\n    return PersistencePromise.resolve();\n  }\n\n  removeTarget(\n    txn: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    const orphaned = this.localViewReferences.removeReferencesForId(\n      targetData.targetId\n    );\n    orphaned.forEach(key => this.orphanedDocuments.add(key));\n    const cache = this.persistence.getTargetCache();\n    return cache\n      .getMatchingKeysForTargetId(txn, targetData.targetId)\n      .next(keys => {\n        keys.forEach(key => this.orphanedDocuments.add(key));\n      })\n      .next(() => cache.removeTargetData(txn, targetData));\n  }\n\n  onTransactionStarted(): void {\n    this._orphanedDocuments = new Set<DocumentKey>();\n  }\n\n  onTransactionCommitted(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    // Remove newly orphaned documents.\n    const cache = this.persistence.getRemoteDocumentCache();\n    const changeBuffer = cache.newChangeBuffer();\n    return PersistencePromise.forEach(\n      this.orphanedDocuments,\n      (key: DocumentKey) => {\n        return this.isReferenced(txn, key).next(isReferenced => {\n          if (!isReferenced) {\n            changeBuffer.removeEntry(key);\n          }\n        });\n      }\n    ).next(() => {\n      this._orphanedDocuments = null;\n      return changeBuffer.apply(txn);\n    });\n  }\n\n  updateLimboDocument(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    return this.isReferenced(txn, key).next(isReferenced => {\n      if (isReferenced) {\n        this.orphanedDocuments.delete(key);\n      } else {\n        this.orphanedDocuments.add(key);\n      }\n    });\n  }\n\n  documentSize(doc: MaybeDocument): number {\n    // For eager GC, we don't care about the document size, there are no size thresholds.\n    return 0;\n  }\n\n  private isReferenced(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<boolean> {\n    return PersistencePromise.or([\n      () =>\n        PersistencePromise.resolve(this.localViewReferences.containsKey(key)),\n      () => this.persistence.getTargetCache().containsKey(txn, key),\n      () => this.persistence.mutationQueuesContainKey(txn, key)\n    ]);\n  }\n}\n\nexport class MemoryLruDelegate implements ReferenceDelegate, LruDelegate {\n  private orphanedSequenceNumbers: ObjectMap<\n    DocumentKey,\n    ListenSequenceNumber\n  > = new ObjectMap(\n    k => encodeResourcePath(k.path),\n    (l, r) => l.isEqual(r)\n  );\n\n  readonly garbageCollector: LruGarbageCollector;\n\n  constructor(\n    private readonly persistence: MemoryPersistence,\n    lruParams: LruParams\n  ) {\n    this.garbageCollector = new LruGarbageCollector(this, lruParams);\n  }\n\n  // No-ops, present so memory persistence doesn't have to care which delegate\n  // it has.\n  onTransactionStarted(): void {}\n\n  onTransactionCommitted(\n    txn: PersistenceTransaction\n  ): PersistencePromise<void> {\n    return PersistencePromise.resolve();\n  }\n\n  forEachTarget(\n    txn: PersistenceTransaction,\n    f: (q: TargetData) => void\n  ): PersistencePromise<void> {\n    return this.persistence.getTargetCache().forEachTarget(txn, f);\n  }\n\n  getSequenceNumberCount(\n    txn: PersistenceTransaction\n  ): PersistencePromise<number> {\n    const docCountPromise = this.orphanedDocumentCount(txn);\n    const targetCountPromise = this.persistence\n      .getTargetCache()\n      .getTargetCount(txn);\n    return targetCountPromise.next(targetCount =>\n      docCountPromise.next(docCount => targetCount + docCount)\n    );\n  }\n\n  private orphanedDocumentCount(\n    txn: PersistenceTransaction\n  ): PersistencePromise<number> {\n    let orphanedCount = 0;\n    return this.forEachOrphanedDocumentSequenceNumber(txn, _ => {\n      orphanedCount++;\n    }).next(() => orphanedCount);\n  }\n\n  forEachOrphanedDocumentSequenceNumber(\n    txn: PersistenceTransaction,\n    f: (sequenceNumber: ListenSequenceNumber) => void\n  ): PersistencePromise<void> {\n    return PersistencePromise.forEach(\n      this.orphanedSequenceNumbers,\n      (key, sequenceNumber) => {\n        // Pass in the exact sequence number as the upper bound so we know it won't be pinned by\n        // being too recent.\n        return this.isPinned(txn, key, sequenceNumber).next(isPinned => {\n          if (!isPinned) {\n            return f(sequenceNumber);\n          } else {\n            return PersistencePromise.resolve();\n          }\n        });\n      }\n    );\n  }\n\n  removeTargets(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber,\n    activeTargetIds: ActiveTargets\n  ): PersistencePromise<number> {\n    return this.persistence\n      .getTargetCache()\n      .removeTargets(txn, upperBound, activeTargetIds);\n  }\n\n  removeOrphanedDocuments(\n    txn: PersistenceTransaction,\n    upperBound: ListenSequenceNumber\n  ): PersistencePromise<number> {\n    let count = 0;\n    const cache = this.persistence.getRemoteDocumentCache();\n    const changeBuffer = cache.newChangeBuffer();\n    const p = cache.forEachDocumentKey(txn, key => {\n      return this.isPinned(txn, key, upperBound).next(isPinned => {\n        if (!isPinned) {\n          count++;\n          changeBuffer.removeEntry(key);\n        }\n      });\n    });\n    return p.next(() => changeBuffer.apply(txn)).next(() => count);\n  }\n\n  markPotentiallyOrphaned(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n    return PersistencePromise.resolve();\n  }\n\n  removeTarget(\n    txn: PersistenceTransaction,\n    targetData: TargetData\n  ): PersistencePromise<void> {\n    const updated = targetData.withSequenceNumber(txn.currentSequenceNumber);\n    return this.persistence.getTargetCache().updateTargetData(txn, updated);\n  }\n\n  addReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n    return PersistencePromise.resolve();\n  }\n\n  removeReference(\n    txn: PersistenceTransaction,\n    targetId: TargetId,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n    return PersistencePromise.resolve();\n  }\n\n  updateLimboDocument(\n    txn: PersistenceTransaction,\n    key: DocumentKey\n  ): PersistencePromise<void> {\n    this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n    return PersistencePromise.resolve();\n  }\n\n  documentSize(maybeDoc: MaybeDocument): number {\n    let documentSize = maybeDoc.key.toString().length;\n    if (maybeDoc instanceof Document) {\n      documentSize += estimateByteSize(maybeDoc.toProto());\n    }\n    return documentSize;\n  }\n\n  private isPinned(\n    txn: PersistenceTransaction,\n    key: DocumentKey,\n    upperBound: ListenSequenceNumber\n  ): PersistencePromise<boolean> {\n    return PersistencePromise.or([\n      () => this.persistence.mutationQueuesContainKey(txn, key),\n      () => this.persistence.getTargetCache().containsKey(txn, key),\n      () => {\n        const orphanedAt = this.orphanedSequenceNumbers.get(key);\n        return PersistencePromise.resolve(\n          orphanedAt !== undefined && orphanedAt > upperBound\n        );\n      }\n    ]);\n  }\n\n  getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n    return this.persistence.getRemoteDocumentCache().getSize(txn);\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 { debugAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\n\nimport { Stream } from './connection';\n\n/**\n * Provides a simple helper class that implements the Stream interface to\n * bridge to other implementations that are streams but do not implement the\n * interface. The stream callbacks are invoked with the callOn... methods.\n */\nexport class StreamBridge<I, O> implements Stream<I, O> {\n  private wrappedOnOpen: (() => void) | undefined;\n  private wrappedOnClose: ((err?: FirestoreError) => void) | undefined;\n  private wrappedOnMessage: ((msg: O) => void) | undefined;\n\n  private sendFn: (msg: I) => void;\n  private closeFn: () => void;\n\n  constructor(args: { sendFn: (msg: I) => void; closeFn: () => void }) {\n    this.sendFn = args.sendFn;\n    this.closeFn = args.closeFn;\n  }\n\n  onOpen(callback: () => void): void {\n    debugAssert(!this.wrappedOnOpen, 'Called onOpen on stream twice!');\n    this.wrappedOnOpen = callback;\n  }\n\n  onClose(callback: (err?: FirestoreError) => void): void {\n    debugAssert(!this.wrappedOnClose, 'Called onClose on stream twice!');\n    this.wrappedOnClose = callback;\n  }\n\n  onMessage(callback: (msg: O) => void): void {\n    debugAssert(!this.wrappedOnMessage, 'Called onMessage on stream twice!');\n    this.wrappedOnMessage = callback;\n  }\n\n  close(): void {\n    this.closeFn();\n  }\n\n  send(msg: I): void {\n    this.sendFn(msg);\n  }\n\n  callOnOpen(): void {\n    debugAssert(\n      this.wrappedOnOpen !== undefined,\n      'Cannot call onOpen because no callback was set'\n    );\n    this.wrappedOnOpen();\n  }\n\n  callOnClose(err?: FirestoreError): void {\n    debugAssert(\n      this.wrappedOnClose !== undefined,\n      'Cannot call onClose because no callback was set'\n    );\n    this.wrappedOnClose(err);\n  }\n\n  callOnMessage(msg: O): void {\n    debugAssert(\n      this.wrappedOnMessage !== undefined,\n      'Cannot call onMessage because no callback was set'\n    );\n    this.wrappedOnMessage(msg);\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 { Token } from '../api/credentials';\nimport { DatabaseId, DatabaseInfo } from '../core/database_info';\nimport { SDK_VERSION } from '../../src/core/version';\nimport { Connection, Stream } from './connection';\nimport { logDebug, logWarn } from '../util/log';\nimport { FirestoreError } from '../util/error';\nimport { StringMap } from '../util/types';\nimport { debugAssert } from '../util/assert';\n\nconst LOG_TAG = 'RestConnection';\n\n/**\n * Maps RPC names to the corresponding REST endpoint name.\n *\n * We use array notation to avoid mangling.\n */\nconst RPC_NAME_URL_MAPPING: StringMap = {};\n\nRPC_NAME_URL_MAPPING['BatchGetDocuments'] = 'batchGet';\nRPC_NAME_URL_MAPPING['Commit'] = 'commit';\nRPC_NAME_URL_MAPPING['RunQuery'] = 'runQuery';\n\nconst RPC_URL_VERSION = 'v1';\nconst X_GOOG_API_CLIENT_VALUE = 'gl-js/ fire/' + SDK_VERSION;\n\n/**\n * Base class for all Rest-based connections to the backend (WebChannel and\n * HTTP).\n */\nexport abstract class RestConnection implements Connection {\n  protected readonly databaseId: DatabaseId;\n  protected readonly baseUrl: string;\n  private readonly databaseRoot: string;\n\n  constructor(private readonly databaseInfo: DatabaseInfo) {\n    this.databaseId = databaseInfo.databaseId;\n    const proto = databaseInfo.ssl ? 'https' : 'http';\n    this.baseUrl = proto + '://' + databaseInfo.host;\n    this.databaseRoot =\n      'projects/' +\n      this.databaseId.projectId +\n      '/databases/' +\n      this.databaseId.database +\n      '/documents';\n  }\n\n  invokeRPC<Req, Resp>(\n    rpcName: string,\n    path: string,\n    req: Req,\n    token: Token | null\n  ): Promise<Resp> {\n    const url = this.makeUrl(rpcName, path);\n    logDebug(LOG_TAG, 'Sending: ', url, req);\n\n    const headers = {};\n    this.modifyHeadersForRequest(headers, token);\n\n    return this.performRPCRequest<Req, Resp>(rpcName, url, headers, req).then(\n      response => {\n        logDebug(LOG_TAG, 'Received: ', response);\n        return response;\n      },\n      (err: FirestoreError) => {\n        logWarn(\n          LOG_TAG,\n          `${rpcName} failed with error: `,\n          err,\n          'url: ',\n          url,\n          'request:',\n          req\n        );\n        throw err;\n      }\n    );\n  }\n\n  invokeStreamingRPC<Req, Resp>(\n    rpcName: string,\n    path: string,\n    request: Req,\n    token: Token | null\n  ): Promise<Resp[]> {\n    // The REST API automatically aggregates all of the streamed results, so we\n    // can just use the normal invoke() method.\n    return this.invokeRPC<Req, Resp[]>(rpcName, path, request, token);\n  }\n\n  abstract openStream<Req, Resp>(\n    rpcName: string,\n    token: Token | null\n  ): Stream<Req, Resp>;\n\n  /**\n   * Modifies the headers for a request, adding any authorization token if\n   * present and any additional headers for the request.\n   */\n  protected modifyHeadersForRequest(\n    headers: StringMap,\n    token: Token | null\n  ): void {\n    headers['X-Goog-Api-Client'] = X_GOOG_API_CLIENT_VALUE;\n\n    // Content-Type: text/plain will avoid preflight requests which might\n    // mess with CORS and redirects by proxies. If we add custom headers\n    // we will need to change this code to potentially use the $httpOverwrite\n    // parameter supported by ESF to avoid\ttriggering preflight requests.\n    headers['Content-Type'] = 'text/plain';\n\n    if (token) {\n      for (const header in token.authHeaders) {\n        if (token.authHeaders.hasOwnProperty(header)) {\n          headers[header] = token.authHeaders[header];\n        }\n      }\n    }\n  }\n\n  /**\n   * Performs an RPC request using an implementation specific networking layer.\n   */\n  protected abstract performRPCRequest<Req, Resp>(\n    rpcName: string,\n    url: string,\n    headers: StringMap,\n    body: Req\n  ): Promise<Resp>;\n\n  private makeUrl<Req>(rpcName: string, path: string): string {\n    const urlRpcName = RPC_NAME_URL_MAPPING[rpcName];\n    debugAssert(\n      urlRpcName !== undefined,\n      'Unknown REST mapping for: ' + rpcName\n    );\n    return `${this.baseUrl}/${RPC_URL_VERSION}/${path}:${urlRpcName}`;\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 {\n  createWebChannelTransport,\n  ErrorCode,\n  EventType,\n  WebChannel,\n  WebChannelError,\n  WebChannelOptions,\n  XhrIo\n} from '@firebase/webchannel-wrapper';\n\nimport {\n  isBrowserExtension,\n  isElectron,\n  isIE,\n  isMobileCordova,\n  isReactNative,\n  isUWP\n} from '@firebase/util';\n\nimport { Token } from '../../api/credentials';\nimport { DatabaseInfo } from '../../core/database_info';\nimport { Stream } from '../../remote/connection';\nimport {\n  mapCodeFromRpcStatus,\n  mapCodeFromHttpResponseErrorStatus\n} from '../../remote/rpc_error';\nimport { StreamBridge } from '../../remote/stream_bridge';\nimport { fail, hardAssert } from '../../util/assert';\nimport { Code, FirestoreError } from '../../util/error';\nimport { logDebug, logWarn } from '../../util/log';\nimport { Rejecter, Resolver } from '../../util/promise';\nimport { StringMap } from '../../util/types';\nimport { RestConnection } from '../../remote/rest_connection';\n\nconst LOG_TAG = 'Connection';\n\nconst RPC_STREAM_SERVICE = 'google.firestore.v1.Firestore';\n\nconst XHR_TIMEOUT_SECS = 15;\n\nexport class WebChannelConnection extends RestConnection {\n  private readonly forceLongPolling: boolean;\n\n  constructor(info: DatabaseInfo) {\n    super(info);\n    this.forceLongPolling = info.forceLongPolling;\n  }\n\n  protected performRPCRequest<Req, Resp>(\n    rpcName: string,\n    url: string,\n    headers: StringMap,\n    body: Req\n  ): Promise<Resp> {\n    return new Promise((resolve: Resolver<Resp>, reject: Rejecter) => {\n      const xhr = new XhrIo();\n      xhr.listenOnce(EventType.COMPLETE, () => {\n        try {\n          switch (xhr.getLastErrorCode()) {\n            case ErrorCode.NO_ERROR:\n              const json = xhr.getResponseJson() as Resp;\n              logDebug(LOG_TAG, 'XHR received:', JSON.stringify(json));\n              resolve(json);\n              break;\n            case ErrorCode.TIMEOUT:\n              logDebug(LOG_TAG, 'RPC \"' + rpcName + '\" timed out');\n              reject(\n                new FirestoreError(Code.DEADLINE_EXCEEDED, 'Request time out')\n              );\n              break;\n            case ErrorCode.HTTP_ERROR:\n              const status = xhr.getStatus();\n              logDebug(\n                LOG_TAG,\n                'RPC \"' + rpcName + '\" failed with status:',\n                status,\n                'response text:',\n                xhr.getResponseText()\n              );\n              if (status > 0) {\n                const responseError = (xhr.getResponseJson() as WebChannelError)\n                  .error;\n                if (\n                  !!responseError &&\n                  !!responseError.status &&\n                  !!responseError.message\n                ) {\n                  const firestoreErrorCode = mapCodeFromHttpResponseErrorStatus(\n                    responseError.status\n                  );\n                  reject(\n                    new FirestoreError(\n                      firestoreErrorCode,\n                      responseError.message\n                    )\n                  );\n                } else {\n                  reject(\n                    new FirestoreError(\n                      Code.UNKNOWN,\n                      'Server responded with status ' + xhr.getStatus()\n                    )\n                  );\n                }\n              } else {\n                // If we received an HTTP_ERROR but there's no status code,\n                // it's most probably a connection issue\n                reject(\n                  new FirestoreError(Code.UNAVAILABLE, 'Connection failed.')\n                );\n              }\n              break;\n            default:\n              fail(\n                'RPC \"' +\n                  rpcName +\n                  '\" failed with unanticipated ' +\n                  'webchannel error ' +\n                  xhr.getLastErrorCode() +\n                  ': ' +\n                  xhr.getLastError() +\n                  ', giving up.'\n              );\n          }\n        } finally {\n          logDebug(LOG_TAG, 'RPC \"' + rpcName + '\" completed.');\n        }\n      });\n\n      const requestString = JSON.stringify(body);\n      xhr.send(url, 'POST', requestString, headers, XHR_TIMEOUT_SECS);\n    });\n  }\n\n  openStream<Req, Resp>(\n    rpcName: string,\n    token: Token | null\n  ): Stream<Req, Resp> {\n    const urlParts = [\n      this.baseUrl,\n      '/',\n      RPC_STREAM_SERVICE,\n      '/',\n      rpcName,\n      '/channel'\n    ];\n    const webchannelTransport = createWebChannelTransport();\n    const request: WebChannelOptions = {\n      // Required for backend stickiness, routing behavior is based on this\n      // parameter.\n      httpSessionIdParam: 'gsessionid',\n      initMessageHeaders: {},\n      messageUrlParams: {\n        // This param is used to improve routing and project isolation by the\n        // backend and must be included in every request.\n        database: `projects/${this.databaseId.projectId}/databases/${this.databaseId.database}`\n      },\n      sendRawJson: true,\n      supportsCrossDomainXhr: true,\n      internalChannelParams: {\n        // Override the default timeout (randomized between 10-20 seconds) since\n        // a large write batch on a slow internet connection may take a long\n        // time to send to the backend. Rather than have WebChannel impose a\n        // tight timeout which could lead to infinite timeouts and retries, we\n        // set it very large (5-10 minutes) and rely on the browser's builtin\n        // timeouts to kick in if the request isn't working.\n        forwardChannelRequestTimeoutMs: 10 * 60 * 1000\n      },\n      forceLongPolling: this.forceLongPolling\n    };\n\n    this.modifyHeadersForRequest(request.initMessageHeaders!, token);\n\n    // Sending the custom headers we just added to request.initMessageHeaders\n    // (Authorization, etc.) will trigger the browser to make a CORS preflight\n    // request because the XHR will no longer meet the criteria for a \"simple\"\n    // CORS request:\n    // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests\n    //\n    // Therefore to avoid the CORS preflight request (an extra network\n    // roundtrip), we use the httpHeadersOverwriteParam option to specify that\n    // the headers should instead be encoded into a special \"$httpHeaders\" query\n    // parameter, which is recognized by the webchannel backend. This is\n    // formally defined here:\n    // https://github.com/google/closure-library/blob/b0e1815b13fb92a46d7c9b3c30de5d6a396a3245/closure/goog/net/rpc/httpcors.js#L32\n    //\n    // TODO(b/145624756): There is a backend bug where $httpHeaders isn't respected if the request\n    // doesn't have an Origin header. So we have to exclude a few browser environments that are\n    // known to (sometimes) not include an Origin. See\n    // https://github.com/firebase/firebase-js-sdk/issues/1491.\n    if (\n      !isMobileCordova() &&\n      !isReactNative() &&\n      !isElectron() &&\n      !isIE() &&\n      !isUWP() &&\n      !isBrowserExtension()\n    ) {\n      request.httpHeadersOverwriteParam = '$httpHeaders';\n    }\n\n    const url = urlParts.join('');\n    logDebug(LOG_TAG, 'Creating WebChannel: ' + url, request);\n    const channel = webchannelTransport.createWebChannel(url, request);\n\n    // WebChannel supports sending the first message with the handshake - saving\n    // a network round trip. However, it will have to call send in the same\n    // JS event loop as open. In order to enforce this, we delay actually\n    // opening the WebChannel until send is called. Whether we have called\n    // open is tracked with this variable.\n    let opened = false;\n\n    // A flag to determine whether the stream was closed (by us or through an\n    // error/close event) to avoid delivering multiple close events or sending\n    // on a closed stream\n    let closed = false;\n\n    const streamBridge = new StreamBridge<Req, Resp>({\n      sendFn: (msg: Req) => {\n        if (!closed) {\n          if (!opened) {\n            logDebug(LOG_TAG, 'Opening WebChannel transport.');\n            channel.open();\n            opened = true;\n          }\n          logDebug(LOG_TAG, 'WebChannel sending:', msg);\n          channel.send(msg);\n        } else {\n          logDebug(LOG_TAG, 'Not sending because WebChannel is closed:', msg);\n        }\n      },\n      closeFn: () => channel.close()\n    });\n\n    // Closure events are guarded and exceptions are swallowed, so catch any\n    // exception and rethrow using a setTimeout so they become visible again.\n    // Note that eventually this function could go away if we are confident\n    // enough the code is exception free.\n    const unguardedEventListen = <T>(\n      type: string,\n      fn: (param?: T) => void\n    ): void => {\n      // TODO(dimond): closure typing seems broken because WebChannel does\n      // not implement goog.events.Listenable\n      channel.listen(type, (param: unknown) => {\n        try {\n          fn(param as T);\n        } catch (e) {\n          setTimeout(() => {\n            throw e;\n          }, 0);\n        }\n      });\n    };\n\n    unguardedEventListen(WebChannel.EventType.OPEN, () => {\n      if (!closed) {\n        logDebug(LOG_TAG, 'WebChannel transport opened.');\n      }\n    });\n\n    unguardedEventListen(WebChannel.EventType.CLOSE, () => {\n      if (!closed) {\n        closed = true;\n        logDebug(LOG_TAG, 'WebChannel transport closed');\n        streamBridge.callOnClose();\n      }\n    });\n\n    unguardedEventListen<Error>(WebChannel.EventType.ERROR, err => {\n      if (!closed) {\n        closed = true;\n        logWarn(LOG_TAG, 'WebChannel transport errored:', err);\n        streamBridge.callOnClose(\n          new FirestoreError(\n            Code.UNAVAILABLE,\n            'The operation could not be completed'\n          )\n        );\n      }\n    });\n\n    // WebChannel delivers message events as array. If batching is not enabled\n    // (it's off by default) each message will be delivered alone, resulting in\n    // a single element array.\n    interface WebChannelResponse {\n      data: Resp[];\n    }\n\n    unguardedEventListen<WebChannelResponse>(\n      WebChannel.EventType.MESSAGE,\n      msg => {\n        if (!closed) {\n          const msgData = msg!.data[0];\n          hardAssert(!!msgData, 'Got a webchannel message without data.');\n          // TODO(b/35143891): There is a bug in One Platform that caused errors\n          // (and only errors) to be wrapped in an extra array. To be forward\n          // compatible with the bug we need to check either condition. The latter\n          // can be removed once the fix has been rolled out.\n          // Use any because msgData.error is not typed.\n          const msgDataOrError: WebChannelError | object = msgData;\n          const error =\n            msgDataOrError.error ||\n            (msgDataOrError as WebChannelError[])[0]?.error;\n          if (error) {\n            logDebug(LOG_TAG, 'WebChannel received error:', error);\n            // error.status will be a string like 'OK' or 'NOT_FOUND'.\n            const status: string = error.status;\n            let code = mapCodeFromRpcStatus(status);\n            let message = error.message;\n            if (code === undefined) {\n              code = Code.INTERNAL;\n              message =\n                'Unknown error status: ' +\n                status +\n                ' with message ' +\n                error.message;\n            }\n            // Mark closed so no further events are propagated\n            closed = true;\n            streamBridge.callOnClose(new FirestoreError(code, message));\n            channel.close();\n          } else {\n            logDebug(LOG_TAG, 'WebChannel received:', msgData);\n            streamBridge.callOnMessage(msgData);\n          }\n        }\n      }\n    );\n\n    setTimeout(() => {\n      // Technically we could/should wait for the WebChannel opened event,\n      // but because we want to send the first message with the WebChannel\n      // handshake we pretend the channel opened here (asynchronously), and\n      // then delay the actual open until the first message is sent.\n      streamBridge.callOnOpen();\n    }, 0);\n    return streamBridge;\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 { logDebug } from '../../util/log';\nimport {\n  ConnectivityMonitor,\n  ConnectivityMonitorCallback,\n  NetworkStatus\n} from '../../remote/connectivity_monitor';\n\n// References to `window` are guarded by BrowserConnectivityMonitor.isAvailable()\n/* eslint-disable no-restricted-globals */\n\nconst LOG_TAG = 'ConnectivityMonitor';\n\n/**\n * Browser implementation of ConnectivityMonitor.\n */\nexport class BrowserConnectivityMonitor implements ConnectivityMonitor {\n  private readonly networkAvailableListener = (): void =>\n    this.onNetworkAvailable();\n  private readonly networkUnavailableListener = (): void =>\n    this.onNetworkUnavailable();\n  private callbacks: ConnectivityMonitorCallback[] = [];\n\n  constructor() {\n    this.configureNetworkMonitoring();\n  }\n\n  addCallback(callback: (status: NetworkStatus) => void): void {\n    this.callbacks.push(callback);\n  }\n\n  shutdown(): void {\n    window.removeEventListener('online', this.networkAvailableListener);\n    window.removeEventListener('offline', this.networkUnavailableListener);\n  }\n\n  private configureNetworkMonitoring(): void {\n    window.addEventListener('online', this.networkAvailableListener);\n    window.addEventListener('offline', this.networkUnavailableListener);\n  }\n\n  private onNetworkAvailable(): void {\n    logDebug(LOG_TAG, 'Network connectivity changed: AVAILABLE');\n    for (const callback of this.callbacks) {\n      callback(NetworkStatus.AVAILABLE);\n    }\n  }\n\n  private onNetworkUnavailable(): void {\n    logDebug(LOG_TAG, 'Network connectivity changed: UNAVAILABLE');\n    for (const callback of this.callbacks) {\n      callback(NetworkStatus.UNAVAILABLE);\n    }\n  }\n\n  // TODO(chenbrian): Consider passing in window either into this component or\n  // here for testing via FakeWindow.\n  /** Checks that all used attributes of window are available. */\n  static isAvailable(): boolean {\n    return (\n      typeof window !== 'undefined' &&\n      window.addEventListener !== undefined &&\n      window.removeEventListener !== undefined\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 { ConnectivityMonitor, NetworkStatus } from './connectivity_monitor';\n\nexport class NoopConnectivityMonitor implements ConnectivityMonitor {\n  addCallback(callback: (status: NetworkStatus) => void): void {\n    // No-op.\n  }\n\n  shutdown(): void {\n    // No-op.\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\n/** Return the Platform-specific serializer monitor. */\nimport { DatabaseId } from '../../core/database_info';\nimport { JsonProtoSerializer } from '../../remote/serializer';\n\nexport function newSerializer(databaseId: DatabaseId): JsonProtoSerializer {\n  return new JsonProtoSerializer(databaseId, /* useProto3Json= */ true);\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  ClientId,\n  MemorySharedClientState,\n  SharedClientState,\n  WebStorageSharedClientState\n} from '../local/shared_client_state';\nimport {\n  LocalStore,\n  newLocalStore,\n  synchronizeLastDocumentChangeReadTime\n} from '../local/local_store';\nimport {\n  applyActiveTargetsChange,\n  applyBatchState,\n  applyPrimaryState,\n  applyTargetState,\n  getActiveClients,\n  newSyncEngine,\n  SyncEngine\n} from './sync_engine';\nimport { RemoteStore } from '../remote/remote_store';\nimport { EventManager } from './event_manager';\nimport { AsyncQueue } from '../util/async_queue';\nimport { DatabaseId, DatabaseInfo } from './database_info';\nimport { Datastore, newDatastore } from '../remote/datastore';\nimport { User } from '../auth/user';\nimport { PersistenceSettings } from './firestore_client';\nimport { debugAssert } from '../util/assert';\nimport { GarbageCollectionScheduler, Persistence } from '../local/persistence';\nimport { Code, FirestoreError } from '../util/error';\nimport { OnlineStateSource } from './types';\nimport { LruParams, LruScheduler } from '../local/lru_garbage_collector';\nimport { IndexFreeQueryEngine } from '../local/index_free_query_engine';\nimport {\n  indexedDbStoragePrefix,\n  IndexedDbPersistence,\n  indexedDbClearPersistence\n} from '../local/indexeddb_persistence';\nimport {\n  MemoryEagerDelegate,\n  MemoryPersistence\n} from '../local/memory_persistence';\nimport { newConnection, newConnectivityMonitor } from '../platform/connection';\nimport { newSerializer } from '../platform/serializer';\nimport { getDocument, getWindow } from '../platform/dom';\nimport { CredentialsProvider } from '../api/credentials';\n\nconst MEMORY_ONLY_PERSISTENCE_ERROR_MESSAGE =\n  'You are using the memory-only build of Firestore. Persistence support is ' +\n  'only available via the @firebase/firestore bundle or the ' +\n  'firebase-firestore.js build.';\n\nexport interface ComponentConfiguration {\n  asyncQueue: AsyncQueue;\n  databaseInfo: DatabaseInfo;\n  credentials: CredentialsProvider;\n  clientId: ClientId;\n  initialUser: User;\n  maxConcurrentLimboResolutions: number;\n  persistenceSettings: PersistenceSettings;\n}\n\n/**\n * Initializes and wires components that are needed to interface with the local\n * cache. Implementations override `initialize()` to provide all components.\n */\nexport interface OfflineComponentProvider {\n  persistence: Persistence;\n  sharedClientState: SharedClientState;\n  localStore: LocalStore;\n  gcScheduler: GarbageCollectionScheduler | null;\n\n  initialize(cfg: ComponentConfiguration): Promise<void>;\n\n  terminate(): Promise<void>;\n\n  clearPersistence(\n    databaseId: DatabaseId,\n    persistenceKey: string\n  ): Promise<void>;\n}\n\n/**\n * Provides all components needed for Firestore with in-memory persistence.\n * Uses EagerGC garbage collection.\n */\nexport class MemoryOfflineComponentProvider\n  implements OfflineComponentProvider {\n  persistence!: Persistence;\n  sharedClientState!: SharedClientState;\n  localStore!: LocalStore;\n  gcScheduler!: GarbageCollectionScheduler | null;\n\n  async initialize(cfg: ComponentConfiguration): Promise<void> {\n    this.sharedClientState = this.createSharedClientState(cfg);\n    this.persistence = this.createPersistence(cfg);\n    await this.persistence.start();\n    this.gcScheduler = this.createGarbageCollectionScheduler(cfg);\n    this.localStore = this.createLocalStore(cfg);\n  }\n\n  createGarbageCollectionScheduler(\n    cfg: ComponentConfiguration\n  ): GarbageCollectionScheduler | null {\n    return null;\n  }\n\n  createLocalStore(cfg: ComponentConfiguration): LocalStore {\n    return newLocalStore(\n      this.persistence,\n      new IndexFreeQueryEngine(),\n      cfg.initialUser\n    );\n  }\n\n  createPersistence(cfg: ComponentConfiguration): Persistence {\n    if (cfg.persistenceSettings.durable) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        MEMORY_ONLY_PERSISTENCE_ERROR_MESSAGE\n      );\n    }\n    return new MemoryPersistence(MemoryEagerDelegate.factory);\n  }\n\n  createSharedClientState(cfg: ComponentConfiguration): SharedClientState {\n    return new MemorySharedClientState();\n  }\n\n  async terminate(): Promise<void> {\n    if (this.gcScheduler) {\n      this.gcScheduler.stop();\n    }\n    await this.sharedClientState.shutdown();\n    await this.persistence.shutdown();\n  }\n\n  clearPersistence(\n    databaseId: DatabaseId,\n    persistenceKey: string\n  ): Promise<void> {\n    throw new FirestoreError(\n      Code.FAILED_PRECONDITION,\n      MEMORY_ONLY_PERSISTENCE_ERROR_MESSAGE\n    );\n  }\n}\n\n/**\n * Provides all components needed for Firestore with IndexedDB persistence.\n */\nexport class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentProvider {\n  persistence!: IndexedDbPersistence;\n  sharedClientState!: SharedClientState;\n  localStore!: LocalStore;\n  gcScheduler!: GarbageCollectionScheduler | null;\n\n  async initialize(cfg: ComponentConfiguration): Promise<void> {\n    await super.initialize(cfg);\n    await synchronizeLastDocumentChangeReadTime(this.localStore);\n  }\n\n  createGarbageCollectionScheduler(\n    cfg: ComponentConfiguration\n  ): GarbageCollectionScheduler | null {\n    const garbageCollector = this.persistence.referenceDelegate\n      .garbageCollector;\n    return new LruScheduler(garbageCollector, cfg.asyncQueue);\n  }\n\n  createPersistence(cfg: ComponentConfiguration): IndexedDbPersistence {\n    debugAssert(\n      cfg.persistenceSettings.durable,\n      'Can only start durable persistence'\n    );\n\n    const persistenceKey = indexedDbStoragePrefix(\n      cfg.databaseInfo.databaseId,\n      cfg.databaseInfo.persistenceKey\n    );\n    const serializer = newSerializer(cfg.databaseInfo.databaseId);\n    return new IndexedDbPersistence(\n      cfg.persistenceSettings.synchronizeTabs,\n      persistenceKey,\n      cfg.clientId,\n      LruParams.withCacheSize(cfg.persistenceSettings.cacheSizeBytes),\n      cfg.asyncQueue,\n      getWindow(),\n      getDocument(),\n      serializer,\n      this.sharedClientState,\n      cfg.persistenceSettings.forceOwningTab\n    );\n  }\n\n  createSharedClientState(cfg: ComponentConfiguration): SharedClientState {\n    return new MemorySharedClientState();\n  }\n\n  clearPersistence(\n    databaseId: DatabaseId,\n    persistenceKey: string\n  ): Promise<void> {\n    return indexedDbClearPersistence(\n      indexedDbStoragePrefix(databaseId, persistenceKey)\n    );\n  }\n}\n\n/**\n * Provides all components needed for Firestore with multi-tab IndexedDB\n * persistence.\n *\n * In the legacy client, this provider is used to provide both multi-tab and\n * non-multi-tab persistence since we cannot tell at build time whether\n * `synchronizeTabs` will be enabled.\n */\nexport class MultiTabOfflineComponentProvider extends IndexedDbOfflineComponentProvider {\n  constructor(\n    private readonly onlineComponentProvider: OnlineComponentProvider\n  ) {\n    super();\n  }\n\n  async initialize(cfg: ComponentConfiguration): Promise<void> {\n    await super.initialize(cfg);\n\n    await this.onlineComponentProvider.initialize(this, cfg);\n    const syncEngine = this.onlineComponentProvider.syncEngine;\n\n    if (this.sharedClientState instanceof WebStorageSharedClientState) {\n      this.sharedClientState.syncEngine = {\n        applyBatchState: applyBatchState.bind(null, syncEngine),\n        applyTargetState: applyTargetState.bind(null, syncEngine),\n        applyActiveTargetsChange: applyActiveTargetsChange.bind(\n          null,\n          syncEngine\n        ),\n        getActiveClients: getActiveClients.bind(null, syncEngine)\n      };\n      await this.sharedClientState.start();\n    }\n\n    // NOTE: This will immediately call the listener, so we make sure to\n    // set it after localStore / remoteStore are started.\n    await this.persistence.setPrimaryStateListener(async isPrimary => {\n      await applyPrimaryState(\n        this.onlineComponentProvider.syncEngine,\n        isPrimary\n      );\n      if (this.gcScheduler) {\n        if (isPrimary && !this.gcScheduler.started) {\n          this.gcScheduler.start(this.localStore);\n        } else if (!isPrimary) {\n          this.gcScheduler.stop();\n        }\n      }\n    });\n  }\n\n  createSharedClientState(cfg: ComponentConfiguration): SharedClientState {\n    if (\n      cfg.persistenceSettings.durable &&\n      cfg.persistenceSettings.synchronizeTabs\n    ) {\n      const window = getWindow();\n      if (!WebStorageSharedClientState.isAvailable(window)) {\n        throw new FirestoreError(\n          Code.UNIMPLEMENTED,\n          'IndexedDB persistence is only available on platforms that support LocalStorage.'\n        );\n      }\n      const persistenceKey = indexedDbStoragePrefix(\n        cfg.databaseInfo.databaseId,\n        cfg.databaseInfo.persistenceKey\n      );\n      return new WebStorageSharedClientState(\n        window,\n        cfg.asyncQueue,\n        persistenceKey,\n        cfg.clientId,\n        cfg.initialUser\n      );\n    }\n    return new MemorySharedClientState();\n  }\n}\n\n/**\n * Initializes and wires the components that are needed to interface with the\n * network.\n */\nexport class OnlineComponentProvider {\n  protected localStore!: LocalStore;\n  protected sharedClientState!: SharedClientState;\n  datastore!: Datastore;\n  eventManager!: EventManager;\n  remoteStore!: RemoteStore;\n  syncEngine!: SyncEngine;\n\n  async initialize(\n    offlineComponentProvider: OfflineComponentProvider,\n    cfg: ComponentConfiguration\n  ): Promise<void> {\n    if (this.localStore) {\n      // OnlineComponentProvider may get initialized multiple times if\n      // multi-tab persistence is used.\n      return;\n    }\n\n    this.localStore = offlineComponentProvider.localStore;\n    this.sharedClientState = offlineComponentProvider.sharedClientState;\n    this.datastore = this.createDatastore(cfg);\n    this.remoteStore = this.createRemoteStore(cfg);\n    this.syncEngine = this.createSyncEngine(cfg);\n    this.eventManager = this.createEventManager(cfg);\n\n    this.sharedClientState.onlineStateHandler = onlineState =>\n      this.syncEngine.applyOnlineStateChange(\n        onlineState,\n        OnlineStateSource.SharedClientState\n      );\n\n    this.remoteStore.syncEngine = this.syncEngine;\n\n    await this.remoteStore.start();\n    await this.remoteStore.applyPrimaryState(this.syncEngine.isPrimaryClient);\n  }\n\n  createEventManager(cfg: ComponentConfiguration): EventManager {\n    return new EventManager(this.syncEngine);\n  }\n\n  createDatastore(cfg: ComponentConfiguration): Datastore {\n    const serializer = newSerializer(cfg.databaseInfo.databaseId);\n    const connection = newConnection(cfg.databaseInfo);\n    return newDatastore(cfg.credentials, connection, serializer);\n  }\n\n  createRemoteStore(cfg: ComponentConfiguration): RemoteStore {\n    return new RemoteStore(\n      this.localStore,\n      this.datastore,\n      cfg.asyncQueue,\n      onlineState =>\n        this.syncEngine.applyOnlineStateChange(\n          onlineState,\n          OnlineStateSource.RemoteStore\n        ),\n      newConnectivityMonitor()\n    );\n  }\n\n  createSyncEngine(cfg: ComponentConfiguration): SyncEngine {\n    return newSyncEngine(\n      this.localStore,\n      this.remoteStore,\n      this.datastore,\n      this.sharedClientState,\n      cfg.initialUser,\n      cfg.maxConcurrentLimboResolutions,\n      !cfg.persistenceSettings.durable ||\n        !cfg.persistenceSettings.synchronizeTabs\n    );\n  }\n\n  terminate(): Promise<void> {\n    return this.remoteStore.shutdown();\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 { WebChannelConnection } from './webchannel_connection';\nimport { DatabaseInfo } from '../../core/database_info';\nimport { Connection } from '../../remote/connection';\nimport { ConnectivityMonitor } from '../../remote/connectivity_monitor';\nimport { BrowserConnectivityMonitor } from './connectivity_monitor';\nimport { NoopConnectivityMonitor } from '../../remote/connectivity_monitor_noop';\n\n/** Initializes the WebChannelConnection for the browser. */\nexport function newConnection(databaseInfo: DatabaseInfo): Connection {\n  return new WebChannelConnection(databaseInfo);\n}\n\n/** Return the Platform-specific connectivity monitor. */\nexport function newConnectivityMonitor(): ConnectivityMonitor {\n  if (BrowserConnectivityMonitor.isAvailable()) {\n    return new BrowserConnectivityMonitor();\n  } else {\n    return new NoopConnectivityMonitor();\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 { JsonObject } from '../model/object_value';\n\n/**\n * Observer/Subscribe interfaces.\n */\nexport type NextFn<T> = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\n// Allow for any of the Observer methods to be undefined.\nexport interface PartialObserver<T> {\n  next?: NextFn<T>;\n  error?: ErrorFn;\n  complete?: CompleteFn;\n}\n\nexport interface Unsubscribe {\n  (): void;\n}\n\nexport function isPartialObserver(obj: unknown): boolean {\n  return implementsAnyMethods(obj, ['next', 'error', 'complete']);\n}\n\n/**\n * Returns true if obj is an object and contains at least one of the specified\n * methods.\n */\nfunction implementsAnyMethods(obj: unknown, methods: string[]): boolean {\n  if (typeof obj !== 'object' || obj === null) {\n    return false;\n  }\n\n  const object = obj as JsonObject<unknown>;\n  for (const method of methods) {\n    if (method in object && typeof object[method] === 'function') {\n      return true;\n    }\n  }\n  return false;\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 { Observer } from '../core/event_manager';\nimport { EventHandler } from './misc';\n\n/*\n * A wrapper implementation of Observer<T> that will dispatch events\n * asynchronously. To allow immediate silencing, a mute call is added which\n * causes events scheduled to no longer be raised.\n */\nexport class AsyncObserver<T> implements Observer<T> {\n  /**\n   * When set to true, will not raise future events. Necessary to deal with\n   * async detachment of listener.\n   */\n  private muted = false;\n\n  constructor(private observer: Partial<Observer<T>>) {}\n\n  next(value: T): void {\n    if (this.observer.next) {\n      this.scheduleEvent(this.observer.next, value);\n    }\n  }\n\n  error(error: Error): void {\n    if (this.observer.error) {\n      this.scheduleEvent(this.observer.error, error);\n    } else {\n      console.error('Uncaught Error in snapshot listener:', error);\n    }\n  }\n\n  mute(): void {\n    this.muted = true;\n  }\n\n  private scheduleEvent<E>(eventHandler: EventHandler<E>, event: E): void {\n    if (!this.muted) {\n      setTimeout(() => {\n        if (!this.muted) {\n          eventHandler(event);\n        }\n      }, 0);\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 */\nimport { fail } from './assert';\nimport { Code, FirestoreError } from './error';\nimport { Dict, forEach } from './obj';\nimport { DocumentKey } from '../model/document_key';\nimport { ResourcePath } from '../model/path';\n\n/** Types accepted by validateType() and related methods for validation. */\nexport type ValidationType =\n  | 'undefined'\n  | 'object'\n  | 'function'\n  | 'boolean'\n  | 'number'\n  | 'string'\n  | 'non-empty string';\n\n/**\n * Validates that no arguments were passed in the invocation of functionName.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateNoArgs('myFunction', arguments);\n */\nexport function validateNoArgs(functionName: string, args: IArguments): void {\n  if (args.length !== 0) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() does not support arguments, ` +\n        'but was called with ' +\n        formatPlural(args.length, 'argument') +\n        '.'\n    );\n  }\n}\n\n/**\n * Validates the invocation of functionName has the exact number of arguments.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateExactNumberOfArgs('myFunction', arguments, 2);\n */\nexport function validateExactNumberOfArgs(\n  functionName: string,\n  args: ArrayLike<unknown>,\n  numberOfArgs: number\n): void {\n  if (args.length !== numberOfArgs) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires ` +\n        formatPlural(numberOfArgs, 'argument') +\n        ', but was called with ' +\n        formatPlural(args.length, 'argument') +\n        '.'\n    );\n  }\n}\n\n/**\n * Validates the invocation of functionName has at least the provided number of\n * arguments (but can have many more).\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateAtLeastNumberOfArgs('myFunction', arguments, 2);\n */\nexport function validateAtLeastNumberOfArgs(\n  functionName: string,\n  args: IArguments,\n  minNumberOfArgs: number\n): void {\n  if (args.length < minNumberOfArgs) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires at least ` +\n        formatPlural(minNumberOfArgs, 'argument') +\n        ', but was called with ' +\n        formatPlural(args.length, 'argument') +\n        '.'\n    );\n  }\n}\n\n/**\n * Validates the invocation of functionName has number of arguments between\n * the values provided.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateBetweenNumberOfArgs('myFunction', arguments, 2, 3);\n */\nexport function validateBetweenNumberOfArgs(\n  functionName: string,\n  args: IArguments,\n  minNumberOfArgs: number,\n  maxNumberOfArgs: number\n): void {\n  if (args.length < minNumberOfArgs || args.length > maxNumberOfArgs) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires between ${minNumberOfArgs} and ` +\n        `${maxNumberOfArgs} arguments, but was called with ` +\n        formatPlural(args.length, 'argument') +\n        '.'\n    );\n  }\n}\n\n/**\n * Validates the provided argument is an array and has as least the expected\n * number of elements.\n */\nexport function validateNamedArrayAtLeastNumberOfElements<T>(\n  functionName: string,\n  value: T[],\n  name: string,\n  minNumberOfElements: number\n): void {\n  if (!(value instanceof Array) || value.length < minNumberOfElements) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires its ${name} argument to be an ` +\n        'array with at least ' +\n        `${formatPlural(minNumberOfElements, 'element')}.`\n    );\n  }\n}\n\n/**\n * Validates the provided positional argument has the native JavaScript type\n * using typeof checks.\n */\nexport function validateArgType(\n  functionName: string,\n  type: ValidationType,\n  position: number,\n  argument: unknown\n): void {\n  validateType(functionName, type, `${ordinal(position)} argument`, argument);\n}\n\n/**\n * Validates the provided argument has the native JavaScript type using\n * typeof checks or is undefined.\n */\nexport function validateOptionalArgType(\n  functionName: string,\n  type: ValidationType,\n  position: number,\n  argument: unknown\n): void {\n  if (argument !== undefined) {\n    validateArgType(functionName, type, position, argument);\n  }\n}\n\n/**\n * Validates the provided named option has the native JavaScript type using\n * typeof checks.\n */\nexport function validateNamedType(\n  functionName: string,\n  type: ValidationType,\n  optionName: string,\n  argument: unknown\n): void {\n  validateType(functionName, type, `${optionName} option`, argument);\n}\n\n/**\n * Validates the provided named option has the native JavaScript type using\n * typeof checks or is undefined.\n */\nexport function validateNamedOptionalType(\n  functionName: string,\n  type: ValidationType,\n  optionName: string,\n  argument: unknown\n): void {\n  if (argument !== undefined) {\n    validateNamedType(functionName, type, optionName, argument);\n  }\n}\n\nexport function validateArrayElements<T>(\n  functionName: string,\n  optionName: string,\n  typeDescription: string,\n  argument: T[],\n  validator: (arg0: T) => boolean\n): void {\n  if (!(argument instanceof Array)) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires its ${optionName} ` +\n        `option to be an array, but it was: ${valueDescription(argument)}`\n    );\n  }\n\n  for (let i = 0; i < argument.length; ++i) {\n    if (!validator(argument[i])) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Function ${functionName}() requires all ${optionName} ` +\n          `elements to be ${typeDescription}, but the value at index ${i} ` +\n          `was: ${valueDescription(argument[i])}`\n      );\n    }\n  }\n}\n\nexport function validateOptionalArrayElements<T>(\n  functionName: string,\n  optionName: string,\n  typeDescription: string,\n  argument: T[] | undefined,\n  validator: (arg0: T) => boolean\n): void {\n  if (argument !== undefined) {\n    validateArrayElements(\n      functionName,\n      optionName,\n      typeDescription,\n      argument,\n      validator\n    );\n  }\n}\n\n/**\n * Validates that the provided named option equals one of the expected values.\n */\nexport function validateNamedPropertyEquals<T>(\n  functionName: string,\n  inputName: string,\n  optionName: string,\n  input: T,\n  expected: T[]\n): void {\n  const expectedDescription: string[] = [];\n\n  for (const val of expected) {\n    if (val === input) {\n      return;\n    }\n    expectedDescription.push(valueDescription(val));\n  }\n\n  const actualDescription = valueDescription(input);\n  throw new FirestoreError(\n    Code.INVALID_ARGUMENT,\n    `Invalid value ${actualDescription} provided to function ${functionName}() for option ` +\n      `\"${optionName}\". Acceptable values: ${expectedDescription.join(', ')}`\n  );\n}\n\n/**\n * Validates that the provided named option equals one of the expected values or\n * is undefined.\n */\nexport function validateNamedOptionalPropertyEquals<T>(\n  functionName: string,\n  inputName: string,\n  optionName: string,\n  input: T,\n  expected: T[]\n): void {\n  if (input !== undefined) {\n    validateNamedPropertyEquals(\n      functionName,\n      inputName,\n      optionName,\n      input,\n      expected\n    );\n  }\n}\n\n/**\n * Validates that the provided argument is a valid enum.\n *\n * @param functionName Function making the validation call.\n * @param enums Array containing all possible values for the enum.\n * @param position Position of the argument in `functionName`.\n * @param argument Argument to validate.\n * @return The value as T if the argument can be converted.\n */\nexport function validateStringEnum<T>(\n  functionName: string,\n  enums: T[],\n  position: number,\n  argument: unknown\n): T {\n  if (!enums.some(element => element === argument)) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid value ${valueDescription(argument)} provided to function ` +\n        `${functionName}() for its ${ordinal(position)} argument. Acceptable ` +\n        `values: ${enums.join(', ')}`\n    );\n  }\n  return argument as T;\n}\n\n/**\n * Validates that `path` refers to a document (indicated by the fact it contains\n * an even numbers of segments).\n */\nexport function validateDocumentPath(path: ResourcePath): void {\n  if (!DocumentKey.isDocumentKey(path)) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid document reference. Document references must have an even number of segments, but ${path} has ${path.length}.`\n    );\n  }\n}\n\n/**\n * Validates that `path` refers to a collection (indicated by the fact it\n * contains an odd numbers of segments).\n */\nexport function validateCollectionPath(path: ResourcePath): void {\n  if (DocumentKey.isDocumentKey(path)) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid collection reference. Collection references must have an odd number of segments, but ${path} has ${path.length}.`\n    );\n  }\n}\n\n/** Helper to validate the type of a provided input. */\nfunction validateType(\n  functionName: string,\n  type: ValidationType,\n  inputName: string,\n  input: unknown\n): void {\n  let valid = false;\n  if (type === 'object') {\n    valid = isPlainObject(input);\n  } else if (type === 'non-empty string') {\n    valid = typeof input === 'string' && input !== '';\n  } else {\n    valid = typeof input === type;\n  }\n\n  if (!valid) {\n    const description = valueDescription(input);\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires its ${inputName} ` +\n        `to be of type ${type}, but it was: ${description}`\n    );\n  }\n}\n\n/**\n * Returns true if it's a non-null object without a custom prototype\n * (i.e. excludes Array, Date, etc.).\n */\nexport function isPlainObject(input: unknown): boolean {\n  return (\n    typeof input === 'object' &&\n    input !== null &&\n    (Object.getPrototypeOf(input) === Object.prototype ||\n      Object.getPrototypeOf(input) === null)\n  );\n}\n\n/** Returns a string describing the type / value of the provided input. */\nexport function valueDescription(input: unknown): string {\n  if (input === undefined) {\n    return 'undefined';\n  } else if (input === null) {\n    return 'null';\n  } else if (typeof input === 'string') {\n    if (input.length > 20) {\n      input = `${input.substring(0, 20)}...`;\n    }\n    return JSON.stringify(input);\n  } else if (typeof input === 'number' || typeof input === 'boolean') {\n    return '' + input;\n  } else if (typeof input === 'object') {\n    if (input instanceof Array) {\n      return 'an array';\n    } else {\n      const customObjectName = tryGetCustomObjectType(input!);\n      if (customObjectName) {\n        return `a custom ${customObjectName} object`;\n      } else {\n        return 'an object';\n      }\n    }\n  } else if (typeof input === 'function') {\n    return 'a function';\n  } else {\n    return fail('Unknown wrong type: ' + typeof input);\n  }\n}\n\n/** Hacky method to try to get the constructor name for an object. */\nexport function tryGetCustomObjectType(input: object): string | null {\n  if (input.constructor) {\n    const funcNameRegex = /function\\s+([^\\s(]+)\\s*\\(/;\n    const results = funcNameRegex.exec(input.constructor.toString());\n    if (results && results.length > 1) {\n      return results[1];\n    }\n  }\n  return null;\n}\n\n/** Validates the provided argument is defined. */\nexport function validateDefined(\n  functionName: string,\n  position: number,\n  argument: unknown\n): void {\n  if (argument === undefined) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires a valid ${ordinal(position)} ` +\n        `argument, but it was undefined.`\n    );\n  }\n}\n\n/**\n * Validates the provided positional argument is an object, and its keys and\n * values match the expected keys and types provided in optionTypes.\n */\nexport function validateOptionNames(\n  functionName: string,\n  options: object,\n  optionNames: string[]\n): void {\n  forEach(options as Dict<unknown>, (key, _) => {\n    if (optionNames.indexOf(key) < 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Unknown option '${key}' passed to function ${functionName}(). ` +\n          'Available options: ' +\n          optionNames.join(', ')\n      );\n    }\n  });\n}\n\n/**\n * Helper method to throw an error that the provided argument did not pass\n * an instanceof check.\n */\nexport function invalidClassError(\n  functionName: string,\n  type: string,\n  position: number,\n  argument: unknown\n): Error {\n  const description = valueDescription(argument);\n  return new FirestoreError(\n    Code.INVALID_ARGUMENT,\n    `Function ${functionName}() requires its ${ordinal(position)} ` +\n      `argument to be a ${type}, but it was: ${description}`\n  );\n}\n\nexport function validatePositiveNumber(\n  functionName: string,\n  position: number,\n  n: number\n): void {\n  if (n <= 0) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${functionName}() requires its ${ordinal(\n        position\n      )} argument to be a positive number, but it was: ${n}.`\n    );\n  }\n}\n\n/** Converts a number to its english word representation */\nfunction ordinal(num: number): string {\n  switch (num) {\n    case 1:\n      return 'first';\n    case 2:\n      return 'second';\n    case 3:\n      return 'third';\n    default:\n      return num + 'th';\n  }\n}\n\n/**\n * Formats the given word as plural conditionally given the preceding number.\n */\nfunction formatPlural(num: number, str: string): string {\n  return `${num} ${str}` + (num === 1 ? '' : 's');\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 { isBase64Available } from '../platform/base64';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n  invalidClassError,\n  validateArgType,\n  validateExactNumberOfArgs\n} from '../util/input_validation';\nimport { ByteString } from '../util/byte_string';\n\n/** Helper function to assert Uint8Array is available at runtime. */\nfunction assertUint8ArrayAvailable(): void {\n  if (typeof Uint8Array === 'undefined') {\n    throw new FirestoreError(\n      Code.UNIMPLEMENTED,\n      'Uint8Arrays are not available in this environment.'\n    );\n  }\n}\n\n/** Helper function to assert Base64 functions are available at runtime. */\nfunction assertBase64Available(): void {\n  if (!isBase64Available()) {\n    throw new FirestoreError(\n      Code.UNIMPLEMENTED,\n      'Blobs are unavailable in Firestore in this environment.'\n    );\n  }\n}\n\n/**\n * Immutable class holding a blob (binary data).\n * This class is directly exposed in the public API.\n *\n * Note that while you can't hide the constructor in JavaScript code, we are\n * using the hack above to make sure no-one outside this module can call it.\n */\nexport class Blob {\n  // Prefix with underscore to signal that we consider this not part of the\n  // public API and to prevent it from showing up for autocompletion.\n  _byteString: ByteString;\n\n  constructor(byteString: ByteString) {\n    assertBase64Available();\n    this._byteString = byteString;\n  }\n\n  static fromBase64String(base64: string): Blob {\n    validateExactNumberOfArgs('Blob.fromBase64String', arguments, 1);\n    validateArgType('Blob.fromBase64String', 'string', 1, base64);\n    assertBase64Available();\n    try {\n      return new Blob(ByteString.fromBase64String(base64));\n    } catch (e) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Failed to construct Blob from Base64 string: ' + e\n      );\n    }\n  }\n\n  static fromUint8Array(array: Uint8Array): Blob {\n    validateExactNumberOfArgs('Blob.fromUint8Array', arguments, 1);\n    assertUint8ArrayAvailable();\n    if (!(array instanceof Uint8Array)) {\n      throw invalidClassError('Blob.fromUint8Array', 'Uint8Array', 1, array);\n    }\n    return new Blob(ByteString.fromUint8Array(array));\n  }\n\n  toBase64(): string {\n    validateExactNumberOfArgs('Blob.toBase64', arguments, 0);\n    assertBase64Available();\n    return this._byteString.toBase64();\n  }\n\n  toUint8Array(): Uint8Array {\n    validateExactNumberOfArgs('Blob.toUint8Array', arguments, 0);\n    assertUint8ArrayAvailable();\n    return this._byteString.toUint8Array();\n  }\n\n  toString(): string {\n    return 'Blob(base64: ' + this.toBase64() + ')';\n  }\n\n  isEqual(other: Blob): boolean {\n    return this._byteString.isEqual(other._byteString);\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 * as firestore from '@firebase/firestore-types';\n\nimport { FieldPath as InternalFieldPath } from '../model/path';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n  invalidClassError,\n  validateArgType,\n  validateNamedArrayAtLeastNumberOfElements\n} from '../util/input_validation';\n\n// The objects that are a part of this API are exposed to third-parties as\n// compiled javascript so we want to flag our private members with a leading\n// underscore to discourage their use.\n\n/**\n * A field class base class that is shared by the lite, full and legacy SDK,\n * which supports shared code that deals with FieldPaths.\n */\nexport abstract class BaseFieldPath {\n  /** Internal representation of a Firestore field path. */\n  readonly _internalPath: InternalFieldPath;\n\n  constructor(fieldNames: string[]) {\n    validateNamedArrayAtLeastNumberOfElements(\n      'FieldPath',\n      fieldNames,\n      'fieldNames',\n      1\n    );\n\n    for (let i = 0; i < fieldNames.length; ++i) {\n      validateArgType('FieldPath', 'string', i, fieldNames[i]);\n      if (fieldNames[i].length === 0) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid field name at argument $(i + 1). ` +\n            'Field names must not be empty.'\n        );\n      }\n    }\n\n    this._internalPath = new InternalFieldPath(fieldNames);\n  }\n}\n\n/**\n * A FieldPath refers to a field in a document. The path may consist of a single\n * field name (referring to a top-level field in the document), or a list of\n * field names (referring to a nested field in the document).\n */\nexport class FieldPath extends BaseFieldPath implements firestore.FieldPath {\n  /**\n   * Creates a FieldPath from the provided field names. If more than one field\n   * name is provided, the path will point to a nested field in a document.\n   *\n   * @param fieldNames A list of field names.\n   */\n  constructor(...fieldNames: string[]) {\n    super(fieldNames);\n  }\n\n  static documentId(): FieldPath {\n    /**\n     * Internal Note: The backend doesn't technically support querying by\n     * document ID. Instead it queries by the entire document name (full path\n     * included), but in the cases we currently support documentId(), the net\n     * effect is the same.\n     */\n    return new FieldPath(InternalFieldPath.keyField().canonicalString());\n  }\n\n  isEqual(other: firestore.FieldPath): boolean {\n    if (!(other instanceof FieldPath)) {\n      throw invalidClassError('isEqual', 'FieldPath', 1, other);\n    }\n    return this._internalPath.isEqual(other._internalPath);\n  }\n}\n\n/**\n * Matches any characters in a field path string that are reserved.\n */\nconst RESERVED = new RegExp('[~\\\\*/\\\\[\\\\]]');\n\n/**\n * Parses a field path string into a FieldPath, treating dots as separators.\n */\nexport function fromDotSeparatedString(path: string): FieldPath {\n  const found = path.search(RESERVED);\n  if (found >= 0) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid field path (${path}). Paths must not contain ` +\n        `'~', '*', '/', '[', or ']'`\n    );\n  }\n  try {\n    return new FieldPath(...path.split('.'));\n  } catch (e) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid field path (${path}). Paths must not be empty, ` +\n        `begin with '.', end with '.', or contain '..'`\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 * as firestore from '@firebase/firestore-types';\nimport {\n  validateArgType,\n  validateAtLeastNumberOfArgs,\n  validateExactNumberOfArgs,\n  validateNoArgs\n} from '../util/input_validation';\nimport { FieldTransform } from '../model/mutation';\nimport {\n  ArrayRemoveTransformOperation,\n  ArrayUnionTransformOperation,\n  NumericIncrementTransformOperation,\n  ServerTimestampTransform\n} from '../model/transform_operation';\nimport { ParseContext, parseData, UserDataSource } from './user_data_reader';\nimport { debugAssert } from '../util/assert';\nimport { toNumber } from '../remote/serializer';\n\n/**\n * An opaque base class for FieldValue sentinel objects in our public API that\n * is shared between the full, lite and legacy SDK.\n */\nexport abstract class SerializableFieldValue {\n  /** The public API endpoint that returns this class. */\n  abstract readonly _methodName: string;\n\n  /** A pointer to the implementing class. */\n  readonly _delegate: SerializableFieldValue = this;\n\n  abstract _toFieldTransform(context: ParseContext): FieldTransform | null;\n\n  abstract isEqual(other: SerializableFieldValue): boolean;\n}\n\nexport class DeleteFieldValueImpl extends SerializableFieldValue {\n  constructor(readonly _methodName: string) {\n    super();\n  }\n\n  _toFieldTransform(context: ParseContext): null {\n    if (context.dataSource === UserDataSource.MergeSet) {\n      // No transform to add for a delete, but we need to add it to our\n      // fieldMask so it gets deleted.\n      context.fieldMask.push(context.path!);\n    } else if (context.dataSource === UserDataSource.Update) {\n      debugAssert(\n        context.path!.length > 0,\n        `${this._methodName}() at the top level should have already ` +\n          'been handled.'\n      );\n      throw context.createError(\n        `${this._methodName}() can only appear at the top level ` +\n          'of your update data'\n      );\n    } else {\n      // We shouldn't encounter delete sentinels for queries or non-merge set() calls.\n      throw context.createError(\n        `${this._methodName}() cannot be used with set() unless you pass ` +\n          '{merge:true}'\n      );\n    }\n    return null;\n  }\n\n  isEqual(other: FieldValue): boolean {\n    return other instanceof DeleteFieldValueImpl;\n  }\n}\n\n/**\n * Creates a child context for parsing SerializableFieldValues.\n *\n * This is different than calling `ParseContext.contextWith` because it keeps\n * the fieldTransforms and fieldMask separate.\n *\n * The created context has its `dataSource` set to `UserDataSource.Argument`.\n * Although these values are used with writes, any elements in these FieldValues\n * are not considered writes since they cannot contain any FieldValue sentinels,\n * etc.\n *\n * @param fieldValue The sentinel FieldValue for which to create a child\n *     context.\n * @param context The parent context.\n * @param arrayElement Whether or not the FieldValue has an array.\n */\nfunction createSentinelChildContext(\n  fieldValue: SerializableFieldValue,\n  context: ParseContext,\n  arrayElement: boolean\n): ParseContext {\n  return new ParseContext(\n    {\n      dataSource: UserDataSource.Argument,\n      targetDoc: context.settings.targetDoc,\n      methodName: fieldValue._methodName,\n      arrayElement\n    },\n    context.databaseId,\n    context.serializer,\n    context.ignoreUndefinedProperties\n  );\n}\n\nexport class ServerTimestampFieldValueImpl extends SerializableFieldValue {\n  constructor(readonly _methodName: string) {\n    super();\n  }\n\n  _toFieldTransform(context: ParseContext): FieldTransform {\n    return new FieldTransform(context.path!, new ServerTimestampTransform());\n  }\n\n  isEqual(other: FieldValue): boolean {\n    return other instanceof ServerTimestampFieldValueImpl;\n  }\n}\n\nexport class ArrayUnionFieldValueImpl extends SerializableFieldValue {\n  constructor(\n    readonly _methodName: string,\n    private readonly _elements: unknown[]\n  ) {\n    super();\n  }\n\n  _toFieldTransform(context: ParseContext): FieldTransform {\n    const parseContext = createSentinelChildContext(\n      this,\n      context,\n      /*array=*/ true\n    );\n    const parsedElements = this._elements.map(\n      element => parseData(element, parseContext)!\n    );\n    const arrayUnion = new ArrayUnionTransformOperation(parsedElements);\n    return new FieldTransform(context.path!, arrayUnion);\n  }\n\n  isEqual(other: FieldValue): boolean {\n    // TODO(mrschmidt): Implement isEquals\n    return this === other;\n  }\n}\n\nexport class ArrayRemoveFieldValueImpl extends SerializableFieldValue {\n  constructor(readonly _methodName: string, readonly _elements: unknown[]) {\n    super();\n  }\n\n  _toFieldTransform(context: ParseContext): FieldTransform {\n    const parseContext = createSentinelChildContext(\n      this,\n      context,\n      /*array=*/ true\n    );\n    const parsedElements = this._elements.map(\n      element => parseData(element, parseContext)!\n    );\n    const arrayUnion = new ArrayRemoveTransformOperation(parsedElements);\n    return new FieldTransform(context.path!, arrayUnion);\n  }\n\n  isEqual(other: FieldValue): boolean {\n    // TODO(mrschmidt): Implement isEquals\n    return this === other;\n  }\n}\n\nexport class NumericIncrementFieldValueImpl extends SerializableFieldValue {\n  constructor(readonly _methodName: string, private readonly _operand: number) {\n    super();\n  }\n\n  _toFieldTransform(context: ParseContext): FieldTransform {\n    const numericIncrement = new NumericIncrementTransformOperation(\n      context.serializer,\n      toNumber(context.serializer, this._operand)\n    );\n    return new FieldTransform(context.path!, numericIncrement);\n  }\n\n  isEqual(other: FieldValue): boolean {\n    // TODO(mrschmidt): Implement isEquals\n    return this === other;\n  }\n}\n\n/** The public FieldValue class of the lite API. */\nexport abstract class FieldValue extends SerializableFieldValue\n  implements firestore.FieldValue {\n  protected constructor() {\n    super();\n  }\n\n  static delete(): firestore.FieldValue {\n    validateNoArgs('FieldValue.delete', arguments);\n    return new FieldValueDelegate(\n      new DeleteFieldValueImpl('FieldValue.delete')\n    );\n  }\n\n  static serverTimestamp(): firestore.FieldValue {\n    validateNoArgs('FieldValue.serverTimestamp', arguments);\n    return new FieldValueDelegate(\n      new ServerTimestampFieldValueImpl('FieldValue.serverTimestamp')\n    );\n  }\n\n  static arrayUnion(...elements: unknown[]): firestore.FieldValue {\n    validateAtLeastNumberOfArgs('FieldValue.arrayUnion', arguments, 1);\n    // NOTE: We don't actually parse the data until it's used in set() or\n    // update() since we'd need the Firestore instance to do this.\n    return new FieldValueDelegate(\n      new ArrayUnionFieldValueImpl('FieldValue.arrayUnion', elements)\n    );\n  }\n\n  static arrayRemove(...elements: unknown[]): firestore.FieldValue {\n    validateAtLeastNumberOfArgs('FieldValue.arrayRemove', arguments, 1);\n    // NOTE: We don't actually parse the data until it's used in set() or\n    // update() since we'd need the Firestore instance to do this.\n    return new FieldValueDelegate(\n      new ArrayRemoveFieldValueImpl('FieldValue.arrayRemove', elements)\n    );\n  }\n\n  static increment(n: number): firestore.FieldValue {\n    validateArgType('FieldValue.increment', 'number', 1, n);\n    validateExactNumberOfArgs('FieldValue.increment', arguments, 1);\n    return new FieldValueDelegate(\n      new NumericIncrementFieldValueImpl('FieldValue.increment', n)\n    );\n  }\n}\n\n/**\n * A delegate class that allows the FieldValue implementations returned by\n * deleteField(), serverTimestamp(), arrayUnion(), arrayRemove() and\n * increment() to be an instance of the legacy FieldValue class declared above.\n *\n * We don't directly subclass `FieldValue` in the various field value\n * implementations as the base FieldValue class differs between the lite, full\n * and legacy SDK.\n */\nclass FieldValueDelegate extends FieldValue implements firestore.FieldValue {\n  readonly _methodName: string;\n\n  constructor(readonly _delegate: SerializableFieldValue) {\n    super();\n    this._methodName = _delegate._methodName;\n  }\n\n  _toFieldTransform(context: ParseContext): FieldTransform | null {\n    return this._delegate._toFieldTransform(context);\n  }\n\n  isEqual(other: firestore.FieldValue): boolean {\n    if (!(other instanceof FieldValueDelegate)) {\n      return false;\n    }\n    return this._delegate.isEqual(other._delegate);\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 { Code, FirestoreError } from '../util/error';\nimport {\n  validateArgType,\n  validateExactNumberOfArgs\n} from '../util/input_validation';\nimport { primitiveComparator } from '../util/misc';\n\n/**\n * Immutable class representing a geo point as latitude-longitude pair.\n * This class is directly exposed in the public API, including its constructor.\n */\nexport class GeoPoint {\n  // Prefix with underscore to signal this is a private variable in JS and\n  // prevent it showing up for autocompletion when typing latitude or longitude.\n  private _lat: number;\n  private _long: number;\n\n  constructor(latitude: number, longitude: number) {\n    validateExactNumberOfArgs('GeoPoint', arguments, 2);\n    validateArgType('GeoPoint', 'number', 1, latitude);\n    validateArgType('GeoPoint', 'number', 2, longitude);\n    if (!isFinite(latitude) || latitude < -90 || latitude > 90) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Latitude must be a number between -90 and 90, but was: ' + latitude\n      );\n    }\n    if (!isFinite(longitude) || longitude < -180 || longitude > 180) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Longitude must be a number between -180 and 180, but was: ' + longitude\n      );\n    }\n\n    this._lat = latitude;\n    this._long = longitude;\n  }\n\n  /**\n   * Returns the latitude of this geo point, a number between -90 and 90.\n   */\n  get latitude(): number {\n    return this._lat;\n  }\n\n  /**\n   * Returns the longitude of this geo point, a number between -180 and 180.\n   */\n  get longitude(): number {\n    return this._long;\n  }\n\n  isEqual(other: GeoPoint): boolean {\n    return this._lat === other._lat && this._long === other._long;\n  }\n\n  /**\n   * Actually private to JS consumers of our API, so this function is prefixed\n   * with an underscore.\n   */\n  _compareTo(other: GeoPoint): number {\n    return (\n      primitiveComparator(this._lat, other._lat) ||\n      primitiveComparator(this._long, other._long)\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from './timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport { DocumentKey } from '../model/document_key';\nimport {\n  FieldMask,\n  FieldTransform,\n  Mutation,\n  PatchMutation,\n  Precondition,\n  SetMutation,\n  TransformMutation\n} from '../model/mutation';\nimport { FieldPath } from '../model/path';\nimport { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { isPlainObject, valueDescription } from '../util/input_validation';\nimport { Dict, forEach, isEmpty } from '../util/obj';\nimport { ObjectValue, ObjectValueBuilder } from '../model/object_value';\nimport {\n  JsonProtoSerializer,\n  toBytes,\n  toNumber,\n  toResourceName,\n  toTimestamp\n} from '../remote/serializer';\nimport { Blob } from './blob';\nimport { BaseFieldPath, fromDotSeparatedString } from './field_path';\nimport { DeleteFieldValueImpl, SerializableFieldValue } from './field_value';\nimport { GeoPoint } from './geo_point';\nimport { newSerializer } from '../platform/serializer';\n\nconst RESERVED_FIELD_REGEX = /^__.*__$/;\n\n/**\n * An untyped Firestore Data Converter interface that is shared between the\n * lite, full and legacy SDK.\n */\nexport interface UntypedFirestoreDataConverter<T> {\n  toFirestore(modelObject: T): firestore.DocumentData;\n  toFirestore(\n    modelObject: Partial<T>,\n    options: firestore.SetOptions\n  ): firestore.DocumentData;\n  fromFirestore(snapshot: unknown, options?: unknown): T;\n}\n\n/**\n * A reference to a document in a Firebase project.\n *\n * This class serves as a common base class for the public DocumentReferences\n * exposed in the lite, full and legacy SDK.\n */\nexport class DocumentKeyReference<T> {\n  constructor(\n    readonly _databaseId: DatabaseId,\n    readonly _key: DocumentKey,\n    readonly _converter: UntypedFirestoreDataConverter<T> | null\n  ) {}\n}\n\n/** The result of parsing document data (e.g. for a setData call). */\nexport class ParsedSetData {\n  constructor(\n    readonly data: ObjectValue,\n    readonly fieldMask: FieldMask | null,\n    readonly fieldTransforms: FieldTransform[]\n  ) {}\n\n  toMutations(key: DocumentKey, precondition: Precondition): Mutation[] {\n    const mutations = [] as Mutation[];\n    if (this.fieldMask !== null) {\n      mutations.push(\n        new PatchMutation(key, this.data, this.fieldMask, precondition)\n      );\n    } else {\n      mutations.push(new SetMutation(key, this.data, precondition));\n    }\n    if (this.fieldTransforms.length > 0) {\n      mutations.push(new TransformMutation(key, this.fieldTransforms));\n    }\n    return mutations;\n  }\n}\n\n/** The result of parsing \"update\" data (i.e. for an updateData call). */\nexport class ParsedUpdateData {\n  constructor(\n    readonly data: ObjectValue,\n    readonly fieldMask: FieldMask,\n    readonly fieldTransforms: FieldTransform[]\n  ) {}\n\n  toMutations(key: DocumentKey, precondition: Precondition): Mutation[] {\n    const mutations = [\n      new PatchMutation(key, this.data, this.fieldMask, precondition)\n    ] as Mutation[];\n    if (this.fieldTransforms.length > 0) {\n      mutations.push(new TransformMutation(key, this.fieldTransforms));\n    }\n    return mutations;\n  }\n}\n\n/*\n * Represents what type of API method provided the data being parsed; useful\n * for determining which error conditions apply during parsing and providing\n * better error messages.\n */\nexport const enum UserDataSource {\n  Set,\n  Update,\n  MergeSet,\n  /**\n   * Indicates the source is a where clause, cursor bound, arrayUnion()\n   * element, etc. Of note, isWrite(source) will return false.\n   */\n  Argument,\n  /**\n   * Indicates that the source is an Argument that may directly contain nested\n   * arrays (e.g. the operand of an `in` query).\n   */\n  ArrayArgument\n}\n\nfunction isWrite(dataSource: UserDataSource): boolean {\n  switch (dataSource) {\n    case UserDataSource.Set: // fall through\n    case UserDataSource.MergeSet: // fall through\n    case UserDataSource.Update:\n      return true;\n    case UserDataSource.Argument:\n    case UserDataSource.ArrayArgument:\n      return false;\n    default:\n      throw fail(`Unexpected case for UserDataSource: ${dataSource}`);\n  }\n}\n\n/** Contains the settings that are mutated as we parse user data. */\ninterface ContextSettings {\n  /** Indicates what kind of API method this data came from. */\n  readonly dataSource: UserDataSource;\n  /** The name of the method the user called to create the ParseContext. */\n  readonly methodName: string;\n  /** The document the user is attempting to modify, if that applies. */\n  readonly targetDoc?: DocumentKey;\n  /**\n   * A path within the object being parsed. This could be an empty path (in\n   * which case the context represents the root of the data being parsed), or a\n   * nonempty path (indicating the context represents a nested location within\n   * the data).\n   */\n  readonly path?: FieldPath;\n  /**\n   * Whether or not this context corresponds to an element of an array.\n   * If not set, elements are treated as if they were outside of arrays.\n   */\n  readonly arrayElement?: boolean;\n  /**\n   * Whether or not a converter was specified in this context. If true, error\n   * messages will reference the converter when invalid data is provided.\n   */\n  readonly hasConverter?: boolean;\n}\n\n/** A \"context\" object passed around while parsing user data. */\nexport class ParseContext {\n  readonly fieldTransforms: FieldTransform[];\n  readonly fieldMask: FieldPath[];\n  /**\n   * Initializes a ParseContext with the given source and path.\n   *\n   * @param settings The settings for the parser.\n   * @param databaseId The database ID of the Firestore instance.\n   * @param serializer The serializer to use to generate the Value proto.\n   * @param ignoreUndefinedProperties Whether to ignore undefined properties\n   * rather than throw.\n   * @param fieldTransforms A mutable list of field transforms encountered while\n   *     parsing the data.\n   * @param fieldMask A mutable list of field paths encountered while parsing\n   *     the data.\n   *\n   * TODO(b/34871131): We don't support array paths right now, so path can be\n   * null to indicate the context represents any location within an array (in\n   * which case certain features will not work and errors will be somewhat\n   * compromised).\n   */\n  constructor(\n    readonly settings: ContextSettings,\n    readonly databaseId: DatabaseId,\n    readonly serializer: JsonProtoSerializer,\n    readonly ignoreUndefinedProperties: boolean,\n    fieldTransforms?: FieldTransform[],\n    fieldMask?: FieldPath[]\n  ) {\n    // Minor hack: If fieldTransforms is undefined, we assume this is an\n    // external call and we need to validate the entire path.\n    if (fieldTransforms === undefined) {\n      this.validatePath();\n    }\n    this.fieldTransforms = fieldTransforms || [];\n    this.fieldMask = fieldMask || [];\n  }\n\n  get path(): FieldPath | undefined {\n    return this.settings.path;\n  }\n\n  get dataSource(): UserDataSource {\n    return this.settings.dataSource;\n  }\n\n  /** Returns a new context with the specified settings overwritten. */\n  contextWith(configuration: Partial<ContextSettings>): ParseContext {\n    return new ParseContext(\n      { ...this.settings, ...configuration },\n      this.databaseId,\n      this.serializer,\n      this.ignoreUndefinedProperties,\n      this.fieldTransforms,\n      this.fieldMask\n    );\n  }\n\n  childContextForField(field: string): ParseContext {\n    const childPath = this.path?.child(field);\n    const context = this.contextWith({ path: childPath, arrayElement: false });\n    context.validatePathSegment(field);\n    return context;\n  }\n\n  childContextForFieldPath(field: FieldPath): ParseContext {\n    const childPath = this.path?.child(field);\n    const context = this.contextWith({ path: childPath, arrayElement: false });\n    context.validatePath();\n    return context;\n  }\n\n  childContextForArray(index: number): ParseContext {\n    // TODO(b/34871131): We don't support array paths right now; so make path\n    // undefined.\n    return this.contextWith({ path: undefined, arrayElement: true });\n  }\n\n  createError(reason: string): Error {\n    return createError(\n      reason,\n      this.settings.methodName,\n      this.settings.hasConverter || false,\n      this.path,\n      this.settings.targetDoc\n    );\n  }\n\n  /** Returns 'true' if 'fieldPath' was traversed when creating this context. */\n  contains(fieldPath: FieldPath): boolean {\n    return (\n      this.fieldMask.find(field => fieldPath.isPrefixOf(field)) !== undefined ||\n      this.fieldTransforms.find(transform =>\n        fieldPath.isPrefixOf(transform.field)\n      ) !== undefined\n    );\n  }\n\n  private validatePath(): void {\n    // TODO(b/34871131): Remove null check once we have proper paths for fields\n    // within arrays.\n    if (!this.path) {\n      return;\n    }\n    for (let i = 0; i < this.path.length; i++) {\n      this.validatePathSegment(this.path.get(i));\n    }\n  }\n\n  private validatePathSegment(segment: string): void {\n    if (segment.length === 0) {\n      throw this.createError('Document fields must not be empty');\n    }\n    if (isWrite(this.dataSource) && RESERVED_FIELD_REGEX.test(segment)) {\n      throw this.createError('Document fields cannot begin and end with \"__\"');\n    }\n  }\n}\n\n/**\n * Helper for parsing raw user input (provided via the API) into internal model\n * classes.\n */\nexport class UserDataReader {\n  private readonly serializer: JsonProtoSerializer;\n\n  constructor(\n    private readonly databaseId: DatabaseId,\n    private readonly ignoreUndefinedProperties: boolean,\n    serializer?: JsonProtoSerializer\n  ) {\n    this.serializer = serializer || newSerializer(databaseId);\n  }\n\n  /** Creates a new top-level parse context. */\n  createContext(\n    dataSource: UserDataSource,\n    methodName: string,\n    targetDoc?: DocumentKey,\n    hasConverter = false\n  ): ParseContext {\n    return new ParseContext(\n      {\n        dataSource,\n        methodName,\n        targetDoc,\n        path: FieldPath.emptyPath(),\n        arrayElement: false,\n        hasConverter\n      },\n      this.databaseId,\n      this.serializer,\n      this.ignoreUndefinedProperties\n    );\n  }\n}\n\n/** Parse document data from a set() call. */\nexport function parseSetData(\n  userDataReader: UserDataReader,\n  methodName: string,\n  targetDoc: DocumentKey,\n  input: unknown,\n  hasConverter: boolean,\n  options: firestore.SetOptions = {}\n): ParsedSetData {\n  const context = userDataReader.createContext(\n    options.merge || options.mergeFields\n      ? UserDataSource.MergeSet\n      : UserDataSource.Set,\n    methodName,\n    targetDoc,\n    hasConverter\n  );\n  validatePlainObject('Data must be an object, but it was:', context, input);\n  const updateData = parseObject(input, context)!;\n\n  let fieldMask: FieldMask | null;\n  let fieldTransforms: FieldTransform[];\n\n  if (options.merge) {\n    fieldMask = new FieldMask(context.fieldMask);\n    fieldTransforms = context.fieldTransforms;\n  } else if (options.mergeFields) {\n    const validatedFieldPaths: FieldPath[] = [];\n\n    for (const stringOrFieldPath of options.mergeFields) {\n      let fieldPath: FieldPath;\n\n      if (stringOrFieldPath instanceof BaseFieldPath) {\n        fieldPath = stringOrFieldPath._internalPath;\n      } else if (typeof stringOrFieldPath === 'string') {\n        fieldPath = fieldPathFromDotSeparatedString(\n          methodName,\n          stringOrFieldPath,\n          targetDoc\n        );\n      } else {\n        throw fail('Expected stringOrFieldPath to be a string or a FieldPath');\n      }\n\n      if (!context.contains(fieldPath)) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Field '${fieldPath}' is specified in your field mask but missing from your input data.`\n        );\n      }\n\n      if (!fieldMaskContains(validatedFieldPaths, fieldPath)) {\n        validatedFieldPaths.push(fieldPath);\n      }\n    }\n\n    fieldMask = new FieldMask(validatedFieldPaths);\n    fieldTransforms = context.fieldTransforms.filter(transform =>\n      fieldMask!.covers(transform.field)\n    );\n  } else {\n    fieldMask = null;\n    fieldTransforms = context.fieldTransforms;\n  }\n\n  return new ParsedSetData(\n    new ObjectValue(updateData),\n    fieldMask,\n    fieldTransforms\n  );\n}\n\n/** Parse update data from an update() call. */\nexport function parseUpdateData(\n  userDataReader: UserDataReader,\n  methodName: string,\n  targetDoc: DocumentKey,\n  input: unknown\n): ParsedUpdateData {\n  const context = userDataReader.createContext(\n    UserDataSource.Update,\n    methodName,\n    targetDoc\n  );\n  validatePlainObject('Data must be an object, but it was:', context, input);\n\n  const fieldMaskPaths: FieldPath[] = [];\n  const updateData = new ObjectValueBuilder();\n  forEach(input as Dict<unknown>, (key, value) => {\n    const path = fieldPathFromDotSeparatedString(methodName, key, targetDoc);\n\n    const childContext = context.childContextForFieldPath(path);\n    if (\n      value instanceof SerializableFieldValue &&\n      value._delegate instanceof DeleteFieldValueImpl\n    ) {\n      // Add it to the field mask, but don't add anything to updateData.\n      fieldMaskPaths.push(path);\n    } else {\n      const parsedValue = parseData(value, childContext);\n      if (parsedValue != null) {\n        fieldMaskPaths.push(path);\n        updateData.set(path, parsedValue);\n      }\n    }\n  });\n\n  const mask = new FieldMask(fieldMaskPaths);\n  return new ParsedUpdateData(\n    updateData.build(),\n    mask,\n    context.fieldTransforms\n  );\n}\n\n/** Parse update data from a list of field/value arguments. */\nexport function parseUpdateVarargs(\n  userDataReader: UserDataReader,\n  methodName: string,\n  targetDoc: DocumentKey,\n  field: string | BaseFieldPath,\n  value: unknown,\n  moreFieldsAndValues: unknown[]\n): ParsedUpdateData {\n  const context = userDataReader.createContext(\n    UserDataSource.Update,\n    methodName,\n    targetDoc\n  );\n  const keys = [fieldPathFromArgument(methodName, field, targetDoc)];\n  const values = [value];\n\n  if (moreFieldsAndValues.length % 2 !== 0) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Function ${methodName}() needs to be called with an even number ` +\n        'of arguments that alternate between field names and values.'\n    );\n  }\n\n  for (let i = 0; i < moreFieldsAndValues.length; i += 2) {\n    keys.push(\n      fieldPathFromArgument(\n        methodName,\n        moreFieldsAndValues[i] as string | BaseFieldPath\n      )\n    );\n    values.push(moreFieldsAndValues[i + 1]);\n  }\n\n  const fieldMaskPaths: FieldPath[] = [];\n  const updateData = new ObjectValueBuilder();\n\n  // We iterate in reverse order to pick the last value for a field if the\n  // user specified the field multiple times.\n  for (let i = keys.length - 1; i >= 0; --i) {\n    if (!fieldMaskContains(fieldMaskPaths, keys[i])) {\n      const path = keys[i];\n      const value = values[i];\n      const childContext = context.childContextForFieldPath(path);\n      if (\n        value instanceof SerializableFieldValue &&\n        value._delegate instanceof DeleteFieldValueImpl\n      ) {\n        // Add it to the field mask, but don't add anything to updateData.\n        fieldMaskPaths.push(path);\n      } else {\n        const parsedValue = parseData(value, childContext);\n        if (parsedValue != null) {\n          fieldMaskPaths.push(path);\n          updateData.set(path, parsedValue);\n        }\n      }\n    }\n  }\n\n  const mask = new FieldMask(fieldMaskPaths);\n  return new ParsedUpdateData(\n    updateData.build(),\n    mask,\n    context.fieldTransforms\n  );\n}\n\n/**\n * Parse a \"query value\" (e.g. value in a where filter or a value in a cursor\n * bound).\n *\n * @param allowArrays Whether the query value is an array that may directly\n * contain additional arrays (e.g. the operand of an `in` query).\n */\nexport function parseQueryValue(\n  userDataReader: UserDataReader,\n  methodName: string,\n  input: unknown,\n  allowArrays = false\n): api.Value {\n  const context = userDataReader.createContext(\n    allowArrays ? UserDataSource.ArrayArgument : UserDataSource.Argument,\n    methodName\n  );\n  const parsed = parseData(input, context);\n  debugAssert(parsed != null, 'Parsed data should not be null.');\n  debugAssert(\n    context.fieldTransforms.length === 0,\n    'Field transforms should have been disallowed.'\n  );\n  return parsed;\n}\n\n/**\n * Parses user data to Protobuf Values.\n *\n * @param input Data to be parsed.\n * @param context A context object representing the current path being parsed,\n * the source of the data being parsed, etc.\n * @return The parsed value, or null if the value was a FieldValue sentinel\n * that should not be included in the resulting parsed data.\n */\nexport function parseData(\n  input: unknown,\n  context: ParseContext\n): api.Value | null {\n  if (looksLikeJsonObject(input)) {\n    validatePlainObject('Unsupported field value:', context, input);\n    return parseObject(input, context);\n  } else if (input instanceof SerializableFieldValue) {\n    // FieldValues usually parse into transforms (except FieldValue.delete())\n    // in which case we do not want to include this field in our parsed data\n    // (as doing so will overwrite the field directly prior to the transform\n    // trying to transform it). So we don't add this location to\n    // context.fieldMask and we return null as our parsing result.\n    parseSentinelFieldValue(input, context);\n    return null;\n  } else {\n    // If context.path is null we are inside an array and we don't support\n    // field mask paths more granular than the top-level array.\n    if (context.path) {\n      context.fieldMask.push(context.path);\n    }\n\n    if (input instanceof Array) {\n      // TODO(b/34871131): Include the path containing the array in the error\n      // message.\n      // In the case of IN queries, the parsed data is an array (representing\n      // the set of values to be included for the IN query) that may directly\n      // contain additional arrays (each representing an individual field\n      // value), so we disable this validation.\n      if (\n        context.settings.arrayElement &&\n        context.dataSource !== UserDataSource.ArrayArgument\n      ) {\n        throw context.createError('Nested arrays are not supported');\n      }\n      return parseArray(input as unknown[], context);\n    } else {\n      return parseScalarValue(input, context);\n    }\n  }\n}\n\nfunction parseObject(\n  obj: Dict<unknown>,\n  context: ParseContext\n): { mapValue: api.MapValue } {\n  const fields: Dict<api.Value> = {};\n\n  if (isEmpty(obj)) {\n    // If we encounter an empty object, we explicitly add it to the update\n    // mask to ensure that the server creates a map entry.\n    if (context.path && context.path.length > 0) {\n      context.fieldMask.push(context.path);\n    }\n  } else {\n    forEach(obj, (key: string, val: unknown) => {\n      const parsedValue = parseData(val, context.childContextForField(key));\n      if (parsedValue != null) {\n        fields[key] = parsedValue;\n      }\n    });\n  }\n\n  return { mapValue: { fields } };\n}\n\nfunction parseArray(array: unknown[], context: ParseContext): api.Value {\n  const values: api.Value[] = [];\n  let entryIndex = 0;\n  for (const entry of array) {\n    let parsedEntry = parseData(\n      entry,\n      context.childContextForArray(entryIndex)\n    );\n    if (parsedEntry == null) {\n      // Just include nulls in the array for fields being replaced with a\n      // sentinel.\n      parsedEntry = { nullValue: 'NULL_VALUE' };\n    }\n    values.push(parsedEntry);\n    entryIndex++;\n  }\n  return { arrayValue: { values } };\n}\n\n/**\n * \"Parses\" the provided FieldValueImpl, adding any necessary transforms to\n * context.fieldTransforms.\n */\nfunction parseSentinelFieldValue(\n  value: SerializableFieldValue,\n  context: ParseContext\n): void {\n  // Sentinels are only supported with writes, and not within arrays.\n  if (!isWrite(context.dataSource)) {\n    throw context.createError(\n      `${value._methodName}() can only be used with update() and set()`\n    );\n  }\n  if (!context.path) {\n    throw context.createError(\n      `${value._methodName}() is not currently supported inside arrays`\n    );\n  }\n\n  const fieldTransform = value._toFieldTransform(context);\n  if (fieldTransform) {\n    context.fieldTransforms.push(fieldTransform);\n  }\n}\n\n/**\n * Helper to parse a scalar value (i.e. not an Object, Array, or FieldValue)\n *\n * @return The parsed value\n */\nfunction parseScalarValue(\n  value: unknown,\n  context: ParseContext\n): api.Value | null {\n  if (value === null) {\n    return { nullValue: 'NULL_VALUE' };\n  } else if (typeof value === 'number') {\n    return toNumber(context.serializer, value);\n  } else if (typeof value === 'boolean') {\n    return { booleanValue: value };\n  } else if (typeof value === 'string') {\n    return { stringValue: value };\n  } else if (value instanceof Date) {\n    const timestamp = Timestamp.fromDate(value);\n    return {\n      timestampValue: toTimestamp(context.serializer, timestamp)\n    };\n  } else if (value instanceof Timestamp) {\n    // Firestore backend truncates precision down to microseconds. To ensure\n    // offline mode works the same with regards to truncation, perform the\n    // truncation immediately without waiting for the backend to do that.\n    const timestamp = new Timestamp(\n      value.seconds,\n      Math.floor(value.nanoseconds / 1000) * 1000\n    );\n    return {\n      timestampValue: toTimestamp(context.serializer, timestamp)\n    };\n  } else if (value instanceof GeoPoint) {\n    return {\n      geoPointValue: {\n        latitude: value.latitude,\n        longitude: value.longitude\n      }\n    };\n  } else if (value instanceof Blob) {\n    return { bytesValue: toBytes(context.serializer, value) };\n  } else if (value instanceof DocumentKeyReference) {\n    const thisDb = context.databaseId;\n    const otherDb = value._databaseId;\n    if (!otherDb.isEqual(thisDb)) {\n      throw context.createError(\n        'Document reference is for database ' +\n          `${otherDb.projectId}/${otherDb.database} but should be ` +\n          `for database ${thisDb.projectId}/${thisDb.database}`\n      );\n    }\n    return {\n      referenceValue: toResourceName(\n        value._databaseId || context.databaseId,\n        value._key.path\n      )\n    };\n  } else if (value === undefined && context.ignoreUndefinedProperties) {\n    return null;\n  } else {\n    throw context.createError(\n      `Unsupported field value: ${valueDescription(value)}`\n    );\n  }\n}\n\n/**\n * Checks whether an object looks like a JSON object that should be converted\n * into a struct. Normal class/prototype instances are considered to look like\n * JSON objects since they should be converted to a struct value. Arrays, Dates,\n * GeoPoints, etc. are not considered to look like JSON objects since they map\n * to specific FieldValue types other than ObjectValue.\n */\nfunction looksLikeJsonObject(input: unknown): boolean {\n  return (\n    typeof input === 'object' &&\n    input !== null &&\n    !(input instanceof Array) &&\n    !(input instanceof Date) &&\n    !(input instanceof Timestamp) &&\n    !(input instanceof GeoPoint) &&\n    !(input instanceof Blob) &&\n    !(input instanceof DocumentKeyReference) &&\n    !(input instanceof SerializableFieldValue)\n  );\n}\n\nfunction validatePlainObject(\n  message: string,\n  context: ParseContext,\n  input: unknown\n): asserts input is Dict<unknown> {\n  if (!looksLikeJsonObject(input) || !isPlainObject(input)) {\n    const description = valueDescription(input);\n    if (description === 'an object') {\n      // Massage the error if it was an object.\n      throw context.createError(message + ' a custom object');\n    } else {\n      throw context.createError(message + ' ' + description);\n    }\n  }\n}\n\n/**\n * Helper that calls fromDotSeparatedString() but wraps any error thrown.\n */\nexport function fieldPathFromArgument(\n  methodName: string,\n  path: string | BaseFieldPath,\n  targetDoc?: DocumentKey\n): FieldPath {\n  if (path instanceof BaseFieldPath) {\n    return path._internalPath;\n  } else if (typeof path === 'string') {\n    return fieldPathFromDotSeparatedString(methodName, path);\n  } else {\n    const message = 'Field path arguments must be of type string or FieldPath.';\n    throw createError(\n      message,\n      methodName,\n      /* hasConverter= */ false,\n      /* path= */ undefined,\n      targetDoc\n    );\n  }\n}\n\n/**\n * Wraps fromDotSeparatedString with an error message about the method that\n * was thrown.\n * @param methodName The publicly visible method name\n * @param path The dot-separated string form of a field path which will be split\n * on dots.\n * @param targetDoc The document against which the field path will be evaluated.\n */\nexport function fieldPathFromDotSeparatedString(\n  methodName: string,\n  path: string,\n  targetDoc?: DocumentKey\n): FieldPath {\n  try {\n    return fromDotSeparatedString(path)._internalPath;\n  } catch (e) {\n    const message = errorMessage(e);\n    throw createError(\n      message,\n      methodName,\n      /* hasConverter= */ false,\n      /* path= */ undefined,\n      targetDoc\n    );\n  }\n}\n\nfunction createError(\n  reason: string,\n  methodName: string,\n  hasConverter: boolean,\n  path?: FieldPath,\n  targetDoc?: DocumentKey\n): Error {\n  const hasPath = path && !path.isEmpty();\n  const hasDocument = targetDoc !== undefined;\n  let message = `Function ${methodName}() called with invalid data`;\n  if (hasConverter) {\n    message += ' (via `toFirestore()`)';\n  }\n  message += '. ';\n\n  let description = '';\n  if (hasPath || hasDocument) {\n    description += ' (found';\n\n    if (hasPath) {\n      description += ` in field ${path}`;\n    }\n    if (hasDocument) {\n      description += ` in document ${targetDoc}`;\n    }\n    description += ')';\n  }\n\n  return new FirestoreError(\n    Code.INVALID_ARGUMENT,\n    message + reason + description\n  );\n}\n\n/**\n * Extracts the message from a caught exception, which should be an Error object\n * though JS doesn't guarantee that.\n */\nfunction errorMessage(error: Error | object): string {\n  return error instanceof Error ? error.message : error.toString();\n}\n\n/** Checks `haystack` if FieldPath `needle` is present. Runs in O(n). */\nfunction fieldMaskContains(haystack: FieldPath[], needle: FieldPath): boolean {\n  return haystack.some(v => v.isEqual(needle));\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 { ParsedSetData, ParsedUpdateData } from '../api/user_data_reader';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\n\nimport { DocumentKey } from '../model/document_key';\nimport {\n  DeleteMutation,\n  Mutation,\n  Precondition,\n  VerifyMutation\n} from '../model/mutation';\nimport {\n  Datastore,\n  invokeBatchGetDocumentsRpc,\n  invokeCommitRpc\n} from '../remote/datastore';\nimport { fail, debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { SnapshotVersion } from './snapshot_version';\nimport { ResourcePath } from '../model/path';\n\n/**\n * Internal transaction object responsible for accumulating the mutations to\n * perform and the base versions for any documents read.\n */\nexport class Transaction {\n  // The version of each document that was read during this transaction.\n  private readVersions = new Map</* path */ string, SnapshotVersion>();\n  private mutations: Mutation[] = [];\n  private committed = false;\n\n  /**\n   * A deferred usage error that occurred previously in this transaction that\n   * will cause the transaction to fail once it actually commits.\n   */\n  private lastWriteError: FirestoreError | null = null;\n\n  /**\n   * Set of documents that have been written in the transaction.\n   *\n   * When there's more than one write to the same key in a transaction, any\n   * writes after the first are handled differently.\n   */\n  private writtenDocs: Set<DocumentKey> = new Set();\n\n  constructor(private datastore: Datastore) {}\n\n  async lookup(keys: DocumentKey[]): Promise<MaybeDocument[]> {\n    this.ensureCommitNotCalled();\n\n    if (this.mutations.length > 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Firestore transactions require all reads to be executed before all writes.'\n      );\n    }\n    const docs = await invokeBatchGetDocumentsRpc(this.datastore, keys);\n    docs.forEach(doc => {\n      if (doc instanceof NoDocument || doc instanceof Document) {\n        this.recordVersion(doc);\n      } else {\n        fail('Document in a transaction was a ' + doc.constructor.name);\n      }\n    });\n    return docs;\n  }\n\n  set(key: DocumentKey, data: ParsedSetData): void {\n    this.write(data.toMutations(key, this.precondition(key)));\n    this.writtenDocs.add(key);\n  }\n\n  update(key: DocumentKey, data: ParsedUpdateData): void {\n    try {\n      this.write(data.toMutations(key, this.preconditionForUpdate(key)));\n    } catch (e) {\n      this.lastWriteError = e;\n    }\n    this.writtenDocs.add(key);\n  }\n\n  delete(key: DocumentKey): void {\n    this.write([new DeleteMutation(key, this.precondition(key))]);\n    this.writtenDocs.add(key);\n  }\n\n  async commit(): Promise<void> {\n    this.ensureCommitNotCalled();\n\n    if (this.lastWriteError) {\n      throw this.lastWriteError;\n    }\n    const unwritten = this.readVersions;\n    // For each mutation, note that the doc was written.\n    this.mutations.forEach(mutation => {\n      unwritten.delete(mutation.key.toString());\n    });\n    // For each document that was read but not written to, we want to perform\n    // a `verify` operation.\n    unwritten.forEach((_, path) => {\n      const key = new DocumentKey(ResourcePath.fromString(path));\n      this.mutations.push(new VerifyMutation(key, this.precondition(key)));\n    });\n    await invokeCommitRpc(this.datastore, this.mutations);\n    this.committed = true;\n  }\n\n  private recordVersion(doc: MaybeDocument): void {\n    let docVersion: SnapshotVersion;\n\n    if (doc instanceof Document) {\n      docVersion = doc.version;\n    } else if (doc instanceof NoDocument) {\n      // For deleted docs, we must use baseVersion 0 when we overwrite them.\n      docVersion = SnapshotVersion.min();\n    } else {\n      throw fail('Document in a transaction was a ' + doc.constructor.name);\n    }\n\n    const existingVersion = this.readVersions.get(doc.key.toString());\n    if (existingVersion) {\n      if (!docVersion.isEqual(existingVersion)) {\n        // This transaction will fail no matter what.\n        throw new FirestoreError(\n          Code.ABORTED,\n          'Document version changed between two reads.'\n        );\n      }\n    } else {\n      this.readVersions.set(doc.key.toString(), docVersion);\n    }\n  }\n\n  /**\n   * Returns the version of this document when it was read in this transaction,\n   * as a precondition, or no precondition if it was not read.\n   */\n  private precondition(key: DocumentKey): Precondition {\n    const version = this.readVersions.get(key.toString());\n    if (!this.writtenDocs.has(key) && version) {\n      return Precondition.updateTime(version);\n    } else {\n      return Precondition.none();\n    }\n  }\n\n  /**\n   * Returns the precondition for a document if the operation is an update.\n   */\n  private preconditionForUpdate(key: DocumentKey): Precondition {\n    const version = this.readVersions.get(key.toString());\n    // The first time a document is written, we want to take into account the\n    // read time and existence\n    if (!this.writtenDocs.has(key) && version) {\n      if (version.isEqual(SnapshotVersion.min())) {\n        // The document doesn't exist, so fail the transaction.\n\n        // This has to be validated locally because you can't send a\n        // precondition that a document does not exist without changing the\n        // semantics of the backend write to be an insert. This is the reverse\n        // of what we want, since we want to assert that the document doesn't\n        // exist but then send the update and have it fail. Since we can't\n        // express that to the backend, we have to validate locally.\n\n        // Note: this can change once we can send separate verify writes in the\n        // transaction.\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          \"Can't update a document that doesn't exist.\"\n        );\n      }\n      // Document exists, base precondition on document update time.\n      return Precondition.updateTime(version);\n    } else {\n      // Document was not read, so we just use the preconditions for a blind\n      // update.\n      return Precondition.exists(true);\n    }\n  }\n\n  private write(mutations: Mutation[]): void {\n    this.ensureCommitNotCalled();\n    this.mutations = this.mutations.concat(mutations);\n  }\n\n  private ensureCommitNotCalled(): void {\n    debugAssert(\n      !this.committed,\n      'A transaction object cannot be used after its update callback has been invoked.'\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 { Deferred } from '../util/promise';\nimport { TimerId, AsyncQueue } from '../util/async_queue';\nimport { ExponentialBackoff } from '../remote/backoff';\nimport { Transaction } from './transaction';\nimport { Datastore } from '../remote/datastore';\nimport { isNullOrUndefined } from '../util/types';\nimport { isPermanentError } from '../remote/rpc_error';\nimport { FirestoreError } from '../util/error';\n\nconst RETRY_COUNT = 5;\n\n/**\n * TransactionRunner encapsulates the logic needed to run and retry transactions\n * with backoff.\n */\nexport class TransactionRunner<T> {\n  private retries = RETRY_COUNT;\n  private backoff: ExponentialBackoff;\n\n  constructor(\n    private readonly asyncQueue: AsyncQueue,\n    private readonly datastore: Datastore,\n    private readonly updateFunction: (transaction: Transaction) => Promise<T>,\n    private readonly deferred: Deferred<T>\n  ) {\n    this.backoff = new ExponentialBackoff(\n      this.asyncQueue,\n      TimerId.TransactionRetry\n    );\n  }\n\n  /** Runs the transaction and sets the result on deferred. */\n  run(): void {\n    this.runWithBackOff();\n  }\n\n  private runWithBackOff(): void {\n    this.backoff.backoffAndRun(async () => {\n      const transaction = new Transaction(this.datastore);\n      const userPromise = this.tryRunUpdateFunction(transaction);\n      if (userPromise) {\n        userPromise\n          .then(result => {\n            this.asyncQueue.enqueueAndForget(() => {\n              return transaction\n                .commit()\n                .then(() => {\n                  this.deferred.resolve(result);\n                })\n                .catch(commitError => {\n                  this.handleTransactionError(commitError);\n                });\n            });\n          })\n          .catch(userPromiseError => {\n            this.handleTransactionError(userPromiseError);\n          });\n      }\n    });\n  }\n\n  private tryRunUpdateFunction(transaction: Transaction): Promise<T> | null {\n    try {\n      const userPromise = this.updateFunction(transaction);\n      if (\n        isNullOrUndefined(userPromise) ||\n        !userPromise.catch ||\n        !userPromise.then\n      ) {\n        this.deferred.reject(\n          Error('Transaction callback must return a Promise')\n        );\n        return null;\n      }\n      return userPromise;\n    } catch (error) {\n      // Do not retry errors thrown by user provided updateFunction.\n      this.deferred.reject(error);\n      return null;\n    }\n  }\n\n  private handleTransactionError(error: Error): void {\n    if (this.retries > 0 && this.isRetryableTransactionError(error)) {\n      this.retries -= 1;\n      this.asyncQueue.enqueueAndForget(() => {\n        this.runWithBackOff();\n        return Promise.resolve();\n      });\n    } else {\n      this.deferred.reject(error);\n    }\n  }\n\n  private isRetryableTransactionError(error: Error): boolean {\n    if (error.name === 'FirebaseError') {\n      // In transactions, the backend will fail outdated reads with FAILED_PRECONDITION and\n      // non-matching document versions with ABORTED. These errors should be retried.\n      const code = (error as FirestoreError).code;\n      return (\n        code === 'aborted' ||\n        code === 'failed-precondition' ||\n        !isPermanentError(code)\n      );\n    }\n    return false;\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 { GetOptions } from '@firebase/firestore-types';\n\nimport { CredentialsProvider } from '../api/credentials';\nimport { User } from '../auth/user';\nimport { LocalStore } from '../local/local_store';\nimport { GarbageCollectionScheduler, Persistence } from '../local/persistence';\nimport { Document, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { RemoteStore } from '../remote/remote_store';\nimport { AsyncQueue, wrapInUserErrorIfRecoverable } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { Deferred } from '../util/promise';\nimport {\n  EventManager,\n  ListenOptions,\n  Observer,\n  QueryListener\n} from './event_manager';\nimport { SyncEngine } from './sync_engine';\nimport { View } from './view';\nimport { SharedClientState } from '../local/shared_client_state';\nimport { AutoId } from '../util/misc';\nimport { DatabaseId, DatabaseInfo } from './database_info';\nimport { newQueryForPath, Query } from './query';\nimport { Transaction } from './transaction';\nimport { ViewSnapshot } from './view_snapshot';\nimport {\n  MemoryOfflineComponentProvider,\n  OfflineComponentProvider,\n  OnlineComponentProvider\n} from './component_provider';\nimport { PartialObserver, Unsubscribe } from '../api/observer';\nimport { AsyncObserver } from '../util/async_observer';\nimport { debugAssert } from '../util/assert';\nimport { TransactionRunner } from './transaction_runner';\nimport { Datastore } from '../remote/datastore';\n\nconst LOG_TAG = 'FirestoreClient';\nexport const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;\n\n/** DOMException error code constants. */\nconst DOM_EXCEPTION_INVALID_STATE = 11;\nconst DOM_EXCEPTION_ABORTED = 20;\nconst DOM_EXCEPTION_QUOTA_EXCEEDED = 22;\n\nexport type PersistenceSettings =\n  | {\n      readonly durable: false;\n    }\n  | {\n      readonly durable: true;\n      readonly cacheSizeBytes: number;\n      readonly synchronizeTabs: boolean;\n      readonly forceOwningTab: boolean;\n    };\n\n/**\n * FirestoreClient is a top-level class that constructs and owns all of the\n * pieces of the client SDK architecture. It is responsible for creating the\n * async queue that is shared by all of the other components in the system.\n */\nexport class FirestoreClient {\n  // NOTE: These should technically have '|undefined' in the types, since\n  // they're initialized asynchronously rather than in the constructor, but\n  // given that all work is done on the async queue and we assert that\n  // initialization completes before any other work is queued, we're cheating\n  // with the types rather than littering the code with '!' or unnecessary\n  // undefined checks.\n  private databaseInfo!: DatabaseInfo;\n  private eventMgr!: EventManager;\n  private persistence!: Persistence;\n  private localStore!: LocalStore;\n  private datastore!: Datastore;\n  private remoteStore!: RemoteStore;\n  private syncEngine!: SyncEngine;\n  private gcScheduler!: GarbageCollectionScheduler | null;\n\n  // PORTING NOTE: SharedClientState is only used for multi-tab web.\n  private sharedClientState!: SharedClientState;\n\n  private readonly clientId = AutoId.newId();\n\n  // We defer our initialization until we get the current user from\n  // setChangeListener(). We block the async queue until we got the initial\n  // user and the initialization is completed. This will prevent any scheduled\n  // work from happening before initialization is completed.\n  //\n  // If initializationDone resolved then the FirestoreClient is in a usable\n  // state.\n  private readonly initializationDone = new Deferred<void>();\n\n  constructor(\n    private credentials: CredentialsProvider,\n    /**\n     * Asynchronous queue responsible for all of our internal processing. When\n     * we get incoming work from the user (via public API) or the network\n     * (incoming GRPC messages), we should always schedule onto this queue.\n     * This ensures all of our work is properly serialized (e.g. we don't\n     * start processing a new operation while the previous one is waiting for\n     * an async I/O to complete).\n     */\n    private asyncQueue: AsyncQueue\n  ) {}\n\n  /**\n   * Starts up the FirestoreClient, returning only whether or not enabling\n   * persistence succeeded.\n   *\n   * The intent here is to \"do the right thing\" as far as users are concerned.\n   * Namely, in cases where offline persistence is requested and possible,\n   * enable it, but otherwise fall back to persistence disabled. For the most\n   * part we expect this to succeed one way or the other so we don't expect our\n   * users to actually wait on the firestore.enablePersistence Promise since\n   * they generally won't care.\n   *\n   * Of course some users actually do care about whether or not persistence\n   * was successfully enabled, so the Promise returned from this method\n   * indicates this outcome.\n   *\n   * This presents a problem though: even before enablePersistence resolves or\n   * rejects, users may have made calls to e.g. firestore.collection() which\n   * means that the FirestoreClient in there will be available and will be\n   * enqueuing actions on the async queue.\n   *\n   * Meanwhile any failure of an operation on the async queue causes it to\n   * panic and reject any further work, on the premise that unhandled errors\n   * are fatal.\n   *\n   * Consequently the fallback is handled internally here in start, and if the\n   * fallback succeeds we signal success to the async queue even though the\n   * start() itself signals failure.\n   *\n   * @param databaseInfo The connection information for the current instance.\n   * @param offlineComponentProvider Provider that returns all components\n   * required for memory-only or IndexedDB persistence.\n   * @param onlineComponentProvider Provider that returns all components\n   * required for online support.\n   * @param persistenceSettings Settings object to configure offline\n   *     persistence.\n   * @returns A deferred result indicating the user-visible result of enabling\n   *     offline persistence. This method will reject this if IndexedDB fails to\n   *     start for any reason. If usePersistence is false this is\n   *     unconditionally resolved.\n   */\n  start(\n    databaseInfo: DatabaseInfo,\n    offlineComponentProvider: OfflineComponentProvider,\n    onlineComponentProvider: OnlineComponentProvider,\n    persistenceSettings: PersistenceSettings\n  ): Promise<void> {\n    this.verifyNotTerminated();\n\n    this.databaseInfo = databaseInfo;\n\n    // If usePersistence is true, certain classes of errors while starting are\n    // recoverable but only by falling back to persistence disabled.\n    //\n    // If there's an error in the first case but not in recovery we cannot\n    // reject the promise blocking the async queue because this will cause the\n    // async queue to panic.\n    const persistenceResult = new Deferred<void>();\n\n    let initialized = false;\n    this.credentials.setChangeListener(user => {\n      if (!initialized) {\n        initialized = true;\n\n        logDebug(LOG_TAG, 'Initializing. user=', user.uid);\n\n        return this.initializeComponents(\n          offlineComponentProvider,\n          onlineComponentProvider,\n          persistenceSettings,\n          user,\n          persistenceResult\n        ).then(this.initializationDone.resolve, this.initializationDone.reject);\n      } else {\n        this.asyncQueue.enqueueRetryable(() =>\n          this.remoteStore.handleCredentialChange(user)\n        );\n      }\n    });\n\n    // Block the async queue until initialization is done\n    this.asyncQueue.enqueueAndForget(() => this.initializationDone.promise);\n\n    // Return only the result of enabling persistence. Note that this does not\n    // need to await the completion of initializationDone because the result of\n    // this method should not reflect any other kind of failure to start.\n    return persistenceResult.promise;\n  }\n\n  /** Enables the network connection and requeues all pending operations. */\n  enableNetwork(): Promise<void> {\n    this.verifyNotTerminated();\n    return this.asyncQueue.enqueue(() => {\n      this.persistence.setNetworkEnabled(true);\n      return this.remoteStore.enableNetwork();\n    });\n  }\n\n  /**\n   * Initializes persistent storage, attempting to use IndexedDB if\n   * usePersistence is true or memory-only if false.\n   *\n   * If IndexedDB fails because it's already open in another tab or because the\n   * platform can't possibly support our implementation then this method rejects\n   * the persistenceResult and falls back on memory-only persistence.\n   *\n   * @param offlineComponentProvider Provider that returns all components\n   * required for memory-only or IndexedDB persistence.\n   * @param onlineComponentProvider Provider that returns all components\n   * required for online support.\n   * @param persistenceSettings Settings object to configure offline persistence\n   * @param user The initial user\n   * @param persistenceResult A deferred result indicating the user-visible\n   *     result of enabling offline persistence. This method will reject this if\n   *     IndexedDB fails to start for any reason. If usePersistence is false\n   *     this is unconditionally resolved.\n   * @returns a Promise indicating whether or not initialization should\n   *     continue, i.e. that one of the persistence implementations actually\n   *     succeeded.\n   */\n  private async initializeComponents(\n    offlineComponentProvider: OfflineComponentProvider,\n    onlineComponentProvider: OnlineComponentProvider,\n    persistenceSettings: PersistenceSettings,\n    user: User,\n    persistenceResult: Deferred<void>\n  ): Promise<void> {\n    try {\n      const componentConfiguration = {\n        asyncQueue: this.asyncQueue,\n        databaseInfo: this.databaseInfo,\n        clientId: this.clientId,\n        credentials: this.credentials,\n        initialUser: user,\n        maxConcurrentLimboResolutions: MAX_CONCURRENT_LIMBO_RESOLUTIONS,\n        persistenceSettings\n      };\n\n      await offlineComponentProvider.initialize(componentConfiguration);\n      await onlineComponentProvider.initialize(\n        offlineComponentProvider,\n        componentConfiguration\n      );\n\n      this.persistence = offlineComponentProvider.persistence;\n      this.sharedClientState = offlineComponentProvider.sharedClientState;\n      this.localStore = offlineComponentProvider.localStore;\n      this.gcScheduler = offlineComponentProvider.gcScheduler;\n      this.datastore = onlineComponentProvider.datastore;\n      this.remoteStore = onlineComponentProvider.remoteStore;\n      this.syncEngine = onlineComponentProvider.syncEngine;\n      this.eventMgr = onlineComponentProvider.eventManager;\n\n      // When a user calls clearPersistence() in one client, all other clients\n      // need to be terminated to allow the delete to succeed.\n      this.persistence.setDatabaseDeletedListener(async () => {\n        await this.terminate();\n      });\n\n      persistenceResult.resolve();\n    } catch (error) {\n      // Regardless of whether or not the retry succeeds, from an user\n      // perspective, offline persistence has failed.\n      persistenceResult.reject(error);\n\n      // An unknown failure on the first stage shuts everything down.\n      if (!this.canFallback(error)) {\n        throw error;\n      }\n      console.warn(\n        'Error enabling offline persistence. Falling back to' +\n          ' persistence disabled: ' +\n          error\n      );\n      return this.initializeComponents(\n        new MemoryOfflineComponentProvider(),\n        new OnlineComponentProvider(),\n        { durable: false },\n        user,\n        persistenceResult\n      );\n    }\n  }\n\n  /**\n   * Decides whether the provided error allows us to gracefully disable\n   * persistence (as opposed to crashing the client).\n   */\n  private canFallback(error: FirestoreError | DOMException): boolean {\n    if (error.name === 'FirebaseError') {\n      return (\n        error.code === Code.FAILED_PRECONDITION ||\n        error.code === Code.UNIMPLEMENTED\n      );\n    } else if (\n      typeof DOMException !== 'undefined' &&\n      error instanceof DOMException\n    ) {\n      // There are a few known circumstances where we can open IndexedDb but\n      // trying to read/write will fail (e.g. quota exceeded). For\n      // well-understood cases, we attempt to detect these and then gracefully\n      // fall back to memory persistence.\n      // NOTE: Rather than continue to add to this list, we could decide to\n      // always fall back, with the risk that we might accidentally hide errors\n      // representing actual SDK bugs.\n      return (\n        // When the browser is out of quota we could get either quota exceeded\n        // or an aborted error depending on whether the error happened during\n        // schema migration.\n        error.code === DOM_EXCEPTION_QUOTA_EXCEEDED ||\n        error.code === DOM_EXCEPTION_ABORTED ||\n        // Firefox Private Browsing mode disables IndexedDb and returns\n        // INVALID_STATE for any usage.\n        error.code === DOM_EXCEPTION_INVALID_STATE\n      );\n    }\n\n    return true;\n  }\n\n  /**\n   * Checks that the client has not been terminated. Ensures that other methods on\n   * this class cannot be called after the client is terminated.\n   */\n  private verifyNotTerminated(): void {\n    if (this.asyncQueue.isShuttingDown) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'The client has already been terminated.'\n      );\n    }\n  }\n\n  /** Disables the network connection. Pending operations will not complete. */\n  disableNetwork(): Promise<void> {\n    this.verifyNotTerminated();\n    return this.asyncQueue.enqueue(() => {\n      this.persistence.setNetworkEnabled(false);\n      return this.remoteStore.disableNetwork();\n    });\n  }\n\n  terminate(): Promise<void> {\n    return this.asyncQueue.enqueueAndInitiateShutdown(async () => {\n      // PORTING NOTE: LocalStore does not need an explicit shutdown on web.\n      if (this.gcScheduler) {\n        this.gcScheduler.stop();\n      }\n\n      await this.remoteStore.shutdown();\n      await this.sharedClientState.shutdown();\n      await this.persistence.shutdown();\n\n      // `removeChangeListener` must be called after shutting down the\n      // RemoteStore as it will prevent the RemoteStore from retrieving\n      // auth tokens.\n      this.credentials.removeChangeListener();\n    });\n  }\n\n  /**\n   * Returns a Promise that resolves when all writes that were pending at the time this\n   * method was called received server acknowledgement. An acknowledgement can be either acceptance\n   * or rejection.\n   */\n  waitForPendingWrites(): Promise<void> {\n    this.verifyNotTerminated();\n\n    const deferred = new Deferred<void>();\n    this.asyncQueue.enqueueAndForget(() => {\n      return this.syncEngine.registerPendingWritesCallback(deferred);\n    });\n    return deferred.promise;\n  }\n\n  listen(\n    query: Query,\n    options: ListenOptions,\n    observer: Partial<Observer<ViewSnapshot>>\n  ): () => void {\n    this.verifyNotTerminated();\n    const wrappedObserver = new AsyncObserver(observer);\n    const listener = new QueryListener(query, wrappedObserver, options);\n    this.asyncQueue.enqueueAndForget(() => this.eventMgr.listen(listener));\n    return () => {\n      wrappedObserver.mute();\n      this.asyncQueue.enqueueAndForget(() => this.eventMgr.unlisten(listener));\n    };\n  }\n\n  async getDocumentFromLocalCache(\n    docKey: DocumentKey\n  ): Promise<Document | null> {\n    this.verifyNotTerminated();\n    await this.initializationDone.promise;\n    return enqueueReadDocumentFromCache(\n      this.asyncQueue,\n      this.localStore,\n      docKey\n    );\n  }\n\n  async getDocumentViaSnapshotListener(\n    key: DocumentKey,\n    options?: GetOptions\n  ): Promise<ViewSnapshot> {\n    this.verifyNotTerminated();\n    await this.initializationDone.promise;\n    return enqueueReadDocumentViaSnapshotListener(\n      this.asyncQueue,\n      this.eventMgr,\n      key,\n      options\n    );\n  }\n\n  async getDocumentsFromLocalCache(query: Query): Promise<ViewSnapshot> {\n    this.verifyNotTerminated();\n    await this.initializationDone.promise;\n    return enqueueExecuteQueryFromCache(\n      this.asyncQueue,\n      this.localStore,\n      query\n    );\n  }\n\n  async getDocumentsViaSnapshotListener(\n    query: Query,\n    options?: GetOptions\n  ): Promise<ViewSnapshot> {\n    this.verifyNotTerminated();\n    await this.initializationDone.promise;\n    return enqueueExecuteQueryViaSnapshotListener(\n      this.asyncQueue,\n      this.eventMgr,\n      query,\n      options\n    );\n  }\n\n  write(mutations: Mutation[]): Promise<void> {\n    this.verifyNotTerminated();\n    const deferred = new Deferred<void>();\n    this.asyncQueue.enqueueAndForget(() =>\n      this.syncEngine.write(mutations, deferred)\n    );\n    return deferred.promise;\n  }\n\n  databaseId(): DatabaseId {\n    return this.databaseInfo.databaseId;\n  }\n\n  addSnapshotsInSyncListener(observer: Partial<Observer<void>>): () => void {\n    this.verifyNotTerminated();\n    const wrappedObserver = new AsyncObserver(observer);\n    this.asyncQueue.enqueueAndForget(async () =>\n      this.eventMgr.addSnapshotsInSyncListener(wrappedObserver)\n    );\n    return () => {\n      wrappedObserver.mute();\n      this.asyncQueue.enqueueAndForget(async () =>\n        this.eventMgr.removeSnapshotsInSyncListener(wrappedObserver)\n      );\n    };\n  }\n\n  get clientTerminated(): boolean {\n    // Technically, the asyncQueue is still running, but only accepting operations\n    // related to termination or supposed to be run after termination. It is effectively\n    // terminated to the eyes of users.\n    return this.asyncQueue.isShuttingDown;\n  }\n\n  /**\n   * Takes an updateFunction in which a set of reads and writes can be performed\n   * atomically. In the updateFunction, the client can read and write values\n   * using the supplied transaction object. After the updateFunction, all\n   * changes will be committed. If a retryable error occurs (ex: some other\n   * client has changed any of the data referenced), then the updateFunction\n   * will be called again after a backoff. If the updateFunction still fails\n   * after all retries, then the transaction will be rejected.\n   *\n   * The transaction object passed to the updateFunction contains methods for\n   * accessing documents and collections. Unlike other datastore access, data\n   * accessed with the transaction will not reflect local changes that have not\n   * been committed. For this reason, it is required that all reads are\n   * performed before any writes. Transactions must be performed while online.\n   */\n  transaction<T>(\n    updateFunction: (transaction: Transaction) => Promise<T>\n  ): Promise<T> {\n    this.verifyNotTerminated();\n    const deferred = new Deferred<T>();\n    this.asyncQueue.enqueueAndForget(() => {\n      new TransactionRunner<T>(\n        this.asyncQueue,\n        this.datastore,\n        updateFunction,\n        deferred\n      ).run();\n      return Promise.resolve();\n    });\n    return deferred.promise;\n  }\n}\n\nexport function enqueueWrite(\n  asyncQueue: AsyncQueue,\n  syncEngine: SyncEngine,\n  mutations: Mutation[]\n): Promise<void> {\n  const deferred = new Deferred<void>();\n  asyncQueue.enqueueAndForget(() => syncEngine.write(mutations, deferred));\n  return deferred.promise;\n}\n\nexport function enqueueNetworkEnabled(\n  asyncQueue: AsyncQueue,\n  remoteStore: RemoteStore,\n  persistence: Persistence,\n  enabled: boolean\n): Promise<void> {\n  return asyncQueue.enqueue(() => {\n    persistence.setNetworkEnabled(enabled);\n    return enabled ? remoteStore.enableNetwork() : remoteStore.disableNetwork();\n  });\n}\n\nexport function enqueueWaitForPendingWrites(\n  asyncQueue: AsyncQueue,\n  syncEngine: SyncEngine\n): Promise<void> {\n  const deferred = new Deferred<void>();\n  asyncQueue.enqueueAndForget(() => {\n    return syncEngine.registerPendingWritesCallback(deferred);\n  });\n  return deferred.promise;\n}\n\nexport function enqueueListen(\n  asyncQueue: AsyncQueue,\n  eventManger: EventManager,\n  query: Query,\n  options: ListenOptions,\n  observer: PartialObserver<ViewSnapshot>\n): Unsubscribe {\n  const wrappedObserver = new AsyncObserver(observer);\n  const listener = new QueryListener(query, wrappedObserver, options);\n  asyncQueue.enqueueAndForget(() => eventManger.listen(listener));\n  return () => {\n    wrappedObserver.mute();\n    asyncQueue.enqueueAndForget(() => eventManger.unlisten(listener));\n  };\n}\n\nexport function enqueueSnapshotsInSyncListen(\n  asyncQueue: AsyncQueue,\n  eventManager: EventManager,\n  observer: PartialObserver<void>\n): Unsubscribe {\n  const wrappedObserver = new AsyncObserver(observer);\n  asyncQueue.enqueueAndForget(async () =>\n    eventManager.addSnapshotsInSyncListener(wrappedObserver)\n  );\n  return () => {\n    wrappedObserver.mute();\n    asyncQueue.enqueueAndForget(async () =>\n      eventManager.removeSnapshotsInSyncListener(wrappedObserver)\n    );\n  };\n}\n\nexport async function enqueueReadDocumentFromCache(\n  asyncQueue: AsyncQueue,\n  localStore: LocalStore,\n  docKey: DocumentKey\n): Promise<Document | null> {\n  const deferred = new Deferred<Document | null>();\n  await asyncQueue.enqueue(async () => {\n    try {\n      const maybeDoc = await localStore.readDocument(docKey);\n      if (maybeDoc instanceof Document) {\n        deferred.resolve(maybeDoc);\n      } else if (maybeDoc instanceof NoDocument) {\n        deferred.resolve(null);\n      } else {\n        deferred.reject(\n          new FirestoreError(\n            Code.UNAVAILABLE,\n            'Failed to get document from cache. (However, this document may ' +\n              \"exist on the server. Run again without setting 'source' in \" +\n              'the GetOptions to attempt to retrieve the document from the ' +\n              'server.)'\n          )\n        );\n      }\n    } catch (e) {\n      const firestoreError = wrapInUserErrorIfRecoverable(\n        e,\n        `Failed to get document '${docKey} from cache`\n      );\n      deferred.reject(firestoreError);\n    }\n  });\n  return deferred.promise;\n}\n\n/**\n * Retrieves a latency-compensated document from the backend via a\n * SnapshotListener.\n */\nexport function enqueueReadDocumentViaSnapshotListener(\n  asyncQueue: AsyncQueue,\n  eventManager: EventManager,\n  key: DocumentKey,\n  options?: GetOptions\n): Promise<ViewSnapshot> {\n  const result = new Deferred<ViewSnapshot>();\n  const unlisten = enqueueListen(\n    asyncQueue,\n    eventManager,\n    newQueryForPath(key.path),\n    {\n      includeMetadataChanges: true,\n      waitForSyncWhenOnline: true\n    },\n    {\n      next: (snap: ViewSnapshot) => {\n        // Remove query first before passing event to user to avoid\n        // user actions affecting the now stale query.\n        unlisten();\n\n        const exists = snap.docs.has(key);\n        if (!exists && snap.fromCache) {\n          // TODO(dimond): If we're online and the document doesn't\n          // exist then we resolve with a doc.exists set to false. If\n          // we're offline however, we reject the Promise in this\n          // case. Two options: 1) Cache the negative response from\n          // the server so we can deliver that even when you're\n          // offline 2) Actually reject the Promise in the online case\n          // if the document doesn't exist.\n          result.reject(\n            new FirestoreError(\n              Code.UNAVAILABLE,\n              'Failed to get document because the client is ' + 'offline.'\n            )\n          );\n        } else if (\n          exists &&\n          snap.fromCache &&\n          options &&\n          options.source === 'server'\n        ) {\n          result.reject(\n            new FirestoreError(\n              Code.UNAVAILABLE,\n              'Failed to get document from server. (However, this ' +\n                'document does exist in the local cache. Run again ' +\n                'without setting source to \"server\" to ' +\n                'retrieve the cached document.)'\n            )\n          );\n        } else {\n          debugAssert(\n            snap.docs.size <= 1,\n            'Expected zero or a single result on a document-only query'\n          );\n          result.resolve(snap);\n        }\n      },\n      error: e => result.reject(e)\n    }\n  );\n  return result.promise;\n}\n\nexport async function enqueueExecuteQueryFromCache(\n  asyncQueue: AsyncQueue,\n  localStore: LocalStore,\n  query: Query\n): Promise<ViewSnapshot> {\n  const deferred = new Deferred<ViewSnapshot>();\n  await asyncQueue.enqueue(async () => {\n    try {\n      const queryResult = await localStore.executeQuery(\n        query,\n        /* usePreviousResults= */ true\n      );\n      const view = new View(query, queryResult.remoteKeys);\n      const viewDocChanges = view.computeDocChanges(queryResult.documents);\n      const viewChange = view.applyChanges(\n        viewDocChanges,\n        /* updateLimboDocuments= */ false\n      );\n      deferred.resolve(viewChange.snapshot!);\n    } catch (e) {\n      const firestoreError = wrapInUserErrorIfRecoverable(\n        e,\n        `Failed to execute query '${query} against cache`\n      );\n      deferred.reject(firestoreError);\n    }\n  });\n  return deferred.promise;\n}\n\n/**\n * Retrieves a latency-compensated query snapshot from the backend via a\n * SnapshotListener.\n */\nexport function enqueueExecuteQueryViaSnapshotListener(\n  asyncQueue: AsyncQueue,\n  eventManager: EventManager,\n  query: Query,\n  options?: GetOptions\n): Promise<ViewSnapshot> {\n  const result = new Deferred<ViewSnapshot>();\n  const unlisten = enqueueListen(\n    asyncQueue,\n    eventManager,\n    query,\n    {\n      includeMetadataChanges: true,\n      waitForSyncWhenOnline: true\n    },\n    {\n      next: snapshot => {\n        // Remove query first before passing event to user to avoid\n        // user actions affecting the now stale query.\n        unlisten();\n\n        if (snapshot.fromCache && options && options.source === 'server') {\n          result.reject(\n            new FirestoreError(\n              Code.UNAVAILABLE,\n              'Failed to get documents from server. (However, these ' +\n                'documents may exist in the local cache. Run again ' +\n                'without setting source to \"server\" to ' +\n                'retrieve the cached documents.)'\n            )\n          );\n        } else {\n          result.resolve(snapshot);\n        }\n      },\n      error: e => result.reject(e)\n    }\n  );\n  return result.promise;\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { DocumentKeyReference } from './user_data_reader';\nimport { Blob } from './blob';\nimport { GeoPoint } from './geo_point';\nimport { Timestamp } from './timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport { DocumentKey } from '../model/document_key';\nimport {\n  normalizeByteString,\n  normalizeNumber,\n  normalizeTimestamp,\n  typeOrder\n} from '../model/values';\nimport {\n  getLocalWriteTime,\n  getPreviousValue\n} from '../model/server_timestamps';\nimport { fail, hardAssert } from '../util/assert';\nimport { forEach } from '../util/obj';\nimport { TypeOrder } from '../model/object_value';\nimport { ResourcePath } from '../model/path';\nimport { isValidResourceName } from '../remote/serializer';\nimport { logError } from '../util/log';\n\nexport type ServerTimestampBehavior = 'estimate' | 'previous' | 'none';\n\n/**\n * Converts Firestore's internal types to the JavaScript types that we expose\n * to the user.\n */\nexport class UserDataWriter {\n  constructor(\n    private readonly databaseId: DatabaseId,\n    private readonly timestampsInSnapshots: boolean,\n    private readonly serverTimestampBehavior: ServerTimestampBehavior,\n    private readonly referenceFactory: (\n      key: DocumentKey\n    ) => DocumentKeyReference<firestore.DocumentData>\n  ) {}\n\n  convertValue(value: api.Value): unknown {\n    switch (typeOrder(value)) {\n      case TypeOrder.NullValue:\n        return null;\n      case TypeOrder.BooleanValue:\n        return value.booleanValue!;\n      case TypeOrder.NumberValue:\n        return normalizeNumber(value.integerValue || value.doubleValue);\n      case TypeOrder.TimestampValue:\n        return this.convertTimestamp(value.timestampValue!);\n      case TypeOrder.ServerTimestampValue:\n        return this.convertServerTimestamp(value);\n      case TypeOrder.StringValue:\n        return value.stringValue!;\n      case TypeOrder.BlobValue:\n        return new Blob(normalizeByteString(value.bytesValue!));\n      case TypeOrder.RefValue:\n        return this.convertReference(value.referenceValue!);\n      case TypeOrder.GeoPointValue:\n        return this.convertGeoPoint(value.geoPointValue!);\n      case TypeOrder.ArrayValue:\n        return this.convertArray(value.arrayValue!);\n      case TypeOrder.ObjectValue:\n        return this.convertObject(value.mapValue!);\n      default:\n        throw fail('Invalid value type: ' + JSON.stringify(value));\n    }\n  }\n\n  private convertObject(mapValue: api.MapValue): firestore.DocumentData {\n    const result: firestore.DocumentData = {};\n    forEach(mapValue.fields || {}, (key, value) => {\n      result[key] = this.convertValue(value);\n    });\n    return result;\n  }\n\n  private convertGeoPoint(value: api.LatLng): GeoPoint {\n    return new GeoPoint(\n      normalizeNumber(value.latitude),\n      normalizeNumber(value.longitude)\n    );\n  }\n\n  private convertArray(arrayValue: api.ArrayValue): unknown[] {\n    return (arrayValue.values || []).map(value => this.convertValue(value));\n  }\n\n  private convertServerTimestamp(value: api.Value): unknown {\n    switch (this.serverTimestampBehavior) {\n      case 'previous':\n        const previousValue = getPreviousValue(value);\n        if (previousValue == null) {\n          return null;\n        }\n        return this.convertValue(previousValue);\n      case 'estimate':\n        return this.convertTimestamp(getLocalWriteTime(value));\n      default:\n        return null;\n    }\n  }\n\n  private convertTimestamp(value: api.Timestamp): Timestamp | Date {\n    const normalizedValue = normalizeTimestamp(value);\n    const timestamp = new Timestamp(\n      normalizedValue.seconds,\n      normalizedValue.nanos\n    );\n    if (this.timestampsInSnapshots) {\n      return timestamp;\n    } else {\n      return timestamp.toDate();\n    }\n  }\n\n  private convertReference(\n    name: string\n  ): DocumentKeyReference<firestore.DocumentData> {\n    const resourcePath = ResourcePath.fromString(name);\n    hardAssert(\n      isValidResourceName(resourcePath),\n      'ReferenceValue is not valid ' + name\n    );\n    const databaseId = new DatabaseId(resourcePath.get(1), resourcePath.get(3));\n    const key = new DocumentKey(resourcePath.popFirst(5));\n\n    if (!databaseId.isEqual(this.databaseId)) {\n      // TODO(b/64130202): Somehow support foreign references.\n      logError(\n        `Document ${key} contains a document ` +\n          `reference within a different database (` +\n          `${databaseId.projectId}/${databaseId.database}) which is not ` +\n          `supported. It will be treated as a reference in the current ` +\n          `database (${this.databaseId.projectId}/${this.databaseId.database}) ` +\n          `instead.`\n      );\n    }\n\n    return this.referenceFactory(key);\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { _FirebaseApp, FirebaseService } from '@firebase/app-types/private';\nimport { DatabaseId, DatabaseInfo } from '../core/database_info';\nimport { ListenOptions } from '../core/event_manager';\nimport {\n  MemoryOfflineComponentProvider,\n  OfflineComponentProvider,\n  OnlineComponentProvider\n} from '../core/component_provider';\nimport { FirestoreClient, PersistenceSettings } from '../core/firestore_client';\nimport {\n  Bound,\n  Direction,\n  FieldFilter,\n  Filter,\n  isCollectionGroupQuery,\n  LimitType,\n  newQueryComparator,\n  newQueryForCollectionGroup,\n  newQueryForPath,\n  Operator,\n  OrderBy,\n  Query as InternalQuery,\n  queryEquals,\n  queryOrderBy,\n  queryWithAddedFilter,\n  queryWithAddedOrderBy,\n  queryWithEndAt,\n  queryWithLimit,\n  queryWithStartAt\n} from '../core/query';\nimport { Transaction as InternalTransaction } from '../core/transaction';\nimport { ChangeType, ViewSnapshot } from '../core/view_snapshot';\nimport { LruParams } from '../local/lru_garbage_collector';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DeleteMutation, Mutation, Precondition } from '../model/mutation';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport { isServerTimestamp } from '../model/server_timestamps';\nimport { refValue } from '../model/values';\nimport { debugAssert, fail } from '../util/assert';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n  invalidClassError,\n  validateArgType,\n  validateAtLeastNumberOfArgs,\n  validateBetweenNumberOfArgs,\n  validateDefined,\n  validateExactNumberOfArgs,\n  validateNamedOptionalPropertyEquals,\n  validateNamedOptionalType,\n  validateNamedType,\n  validateOptionalArgType,\n  validateOptionalArrayElements,\n  validateOptionNames,\n  validatePositiveNumber,\n  validateStringEnum,\n  valueDescription\n} from '../util/input_validation';\nimport { getLogLevel, logError, LogLevel, setLogLevel } from '../util/log';\nimport { AutoId } from '../util/misc';\nimport { Deferred } from '../util/promise';\nimport { FieldPath as ExternalFieldPath } from './field_path';\nimport {\n  CredentialsProvider,\n  CredentialsSettings,\n  EmptyCredentialsProvider,\n  FirebaseCredentialsProvider,\n  makeCredentialsProvider\n} from './credentials';\nimport {\n  CompleteFn,\n  ErrorFn,\n  isPartialObserver,\n  NextFn,\n  PartialObserver,\n  Unsubscribe\n} from './observer';\nimport {\n  DocumentKeyReference,\n  fieldPathFromArgument,\n  parseQueryValue,\n  parseSetData,\n  parseUpdateData,\n  parseUpdateVarargs,\n  UntypedFirestoreDataConverter,\n  UserDataReader\n} from './user_data_reader';\nimport { UserDataWriter } from './user_data_writer';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\n\n// settings() defaults:\nconst DEFAULT_HOST = 'firestore.googleapis.com';\nconst DEFAULT_SSL = true;\nconst DEFAULT_TIMESTAMPS_IN_SNAPSHOTS = true;\nconst DEFAULT_FORCE_LONG_POLLING = false;\nconst DEFAULT_IGNORE_UNDEFINED_PROPERTIES = false;\n\n/**\n * Constant used to indicate the LRU garbage collection should be disabled.\n * Set this value as the `cacheSizeBytes` on the settings passed to the\n * `Firestore` instance.\n */\nexport const CACHE_SIZE_UNLIMITED = LruParams.COLLECTION_DISABLED;\n\n// enablePersistence() defaults:\nconst DEFAULT_SYNCHRONIZE_TABS = false;\n\n/** Undocumented, private additional settings not exposed in our public API. */\ninterface PrivateSettings extends firestore.Settings {\n  // Can be a google-auth-library or gapi client.\n  credentials?: CredentialsSettings;\n}\n\n/**\n * Options that can be provided in the Firestore constructor when not using\n * Firebase (aka standalone mode).\n */\nexport interface FirestoreDatabase {\n  projectId: string;\n  database?: string;\n}\n\n/**\n * A concrete type describing all the values that can be applied via a\n * user-supplied firestore.Settings object. This is a separate type so that\n * defaults can be supplied and the value can be checked for equality.\n */\nclass FirestoreSettings {\n  /** The hostname to connect to. */\n  readonly host: string;\n\n  /** Whether to use SSL when connecting. */\n  readonly ssl: boolean;\n\n  readonly timestampsInSnapshots: boolean;\n\n  readonly cacheSizeBytes: number;\n\n  readonly forceLongPolling: boolean;\n\n  readonly ignoreUndefinedProperties: boolean;\n\n  // Can be a google-auth-library or gapi client.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  credentials?: any;\n\n  constructor(settings: PrivateSettings) {\n    if (settings.host === undefined) {\n      if (settings.ssl !== undefined) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          \"Can't provide ssl option if host option is not set\"\n        );\n      }\n      this.host = DEFAULT_HOST;\n      this.ssl = DEFAULT_SSL;\n    } else {\n      validateNamedType('settings', 'non-empty string', 'host', settings.host);\n      this.host = settings.host;\n\n      validateNamedOptionalType('settings', 'boolean', 'ssl', settings.ssl);\n      this.ssl = settings.ssl ?? DEFAULT_SSL;\n    }\n    validateOptionNames('settings', settings, [\n      'host',\n      'ssl',\n      'credentials',\n      'timestampsInSnapshots',\n      'cacheSizeBytes',\n      'experimentalForceLongPolling',\n      'ignoreUndefinedProperties'\n    ]);\n\n    validateNamedOptionalType(\n      'settings',\n      'object',\n      'credentials',\n      settings.credentials\n    );\n    this.credentials = settings.credentials;\n\n    validateNamedOptionalType(\n      'settings',\n      'boolean',\n      'timestampsInSnapshots',\n      settings.timestampsInSnapshots\n    );\n\n    validateNamedOptionalType(\n      'settings',\n      'boolean',\n      'ignoreUndefinedProperties',\n      settings.ignoreUndefinedProperties\n    );\n\n    // Nobody should set timestampsInSnapshots anymore, but the error depends on\n    // whether they set it to true or false...\n    if (settings.timestampsInSnapshots === true) {\n      logError(\n        \"The setting 'timestampsInSnapshots: true' is no longer required \" +\n          'and should be removed.'\n      );\n    } else if (settings.timestampsInSnapshots === false) {\n      logError(\n        \"Support for 'timestampsInSnapshots: false' will be removed soon. \" +\n          'You must update your code to handle Timestamp objects.'\n      );\n    }\n    this.timestampsInSnapshots =\n      settings.timestampsInSnapshots ?? DEFAULT_TIMESTAMPS_IN_SNAPSHOTS;\n    this.ignoreUndefinedProperties =\n      settings.ignoreUndefinedProperties ?? DEFAULT_IGNORE_UNDEFINED_PROPERTIES;\n\n    validateNamedOptionalType(\n      'settings',\n      'number',\n      'cacheSizeBytes',\n      settings.cacheSizeBytes\n    );\n    if (settings.cacheSizeBytes === undefined) {\n      this.cacheSizeBytes = LruParams.DEFAULT_CACHE_SIZE_BYTES;\n    } else {\n      if (\n        settings.cacheSizeBytes !== CACHE_SIZE_UNLIMITED &&\n        settings.cacheSizeBytes < LruParams.MINIMUM_CACHE_SIZE_BYTES\n      ) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `cacheSizeBytes must be at least ${LruParams.MINIMUM_CACHE_SIZE_BYTES}`\n        );\n      } else {\n        this.cacheSizeBytes = settings.cacheSizeBytes;\n      }\n    }\n\n    validateNamedOptionalType(\n      'settings',\n      'boolean',\n      'experimentalForceLongPolling',\n      settings.experimentalForceLongPolling\n    );\n    this.forceLongPolling =\n      settings.experimentalForceLongPolling ?? DEFAULT_FORCE_LONG_POLLING;\n  }\n\n  isEqual(other: FirestoreSettings): boolean {\n    return (\n      this.host === other.host &&\n      this.ssl === other.ssl &&\n      this.timestampsInSnapshots === other.timestampsInSnapshots &&\n      this.credentials === other.credentials &&\n      this.cacheSizeBytes === other.cacheSizeBytes &&\n      this.forceLongPolling === other.forceLongPolling &&\n      this.ignoreUndefinedProperties === other.ignoreUndefinedProperties\n    );\n  }\n}\n\n/**\n * The root reference to the database.\n */\nexport class Firestore implements firestore.FirebaseFirestore, FirebaseService {\n  // The objects that are a part of this API are exposed to third-parties as\n  // compiled javascript so we want to flag our private members with a leading\n  // underscore to discourage their use.\n  readonly _databaseId: DatabaseId;\n  private readonly _persistenceKey: string;\n  private _credentials: CredentialsProvider;\n  private readonly _firebaseApp: FirebaseApp | null = null;\n  private _settings: FirestoreSettings;\n\n  // The firestore client instance. This will be available as soon as\n  // configureClient is called, but any calls against it will block until\n  // setup has completed.\n  //\n  // Operations on the _firestoreClient don't block on _firestoreReady. Those\n  // are already set to synchronize on the async queue.\n  private _firestoreClient: FirestoreClient | undefined;\n\n  // Public for use in tests.\n  // TODO(mikelehen): Use modularized initialization instead.\n  readonly _queue = new AsyncQueue();\n\n  _userDataReader: UserDataReader | undefined;\n\n  // Note: We are using `MemoryComponentProvider` as a default\n  // ComponentProvider to ensure backwards compatibility with the format\n  // expected by the console build.\n  constructor(\n    databaseIdOrApp: FirestoreDatabase | FirebaseApp,\n    authProvider: Provider<FirebaseAuthInternalName>,\n    private _offlineComponentProvider: OfflineComponentProvider = new MemoryOfflineComponentProvider(),\n    private _onlineComponentProvider = new OnlineComponentProvider()\n  ) {\n    if (typeof (databaseIdOrApp as FirebaseApp).options === 'object') {\n      // This is very likely a Firebase app object\n      // TODO(b/34177605): Can we somehow use instanceof?\n      const app = databaseIdOrApp as FirebaseApp;\n      this._firebaseApp = app;\n      this._databaseId = Firestore.databaseIdFromApp(app);\n      this._persistenceKey = app.name;\n      this._credentials = new FirebaseCredentialsProvider(authProvider);\n    } else {\n      const external = databaseIdOrApp as FirestoreDatabase;\n      if (!external.projectId) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          'Must provide projectId'\n        );\n      }\n\n      this._databaseId = new DatabaseId(external.projectId, external.database);\n      // Use a default persistenceKey that lines up with FirebaseApp.\n      this._persistenceKey = '[DEFAULT]';\n      this._credentials = new EmptyCredentialsProvider();\n    }\n\n    this._settings = new FirestoreSettings({});\n  }\n\n  get _dataReader(): UserDataReader {\n    debugAssert(\n      !!this._firestoreClient,\n      'Cannot obtain UserDataReader before instance is intitialized'\n    );\n    if (!this._userDataReader) {\n      // Lazy initialize UserDataReader once the settings are frozen\n      this._userDataReader = new UserDataReader(\n        this._databaseId,\n        this._settings.ignoreUndefinedProperties\n      );\n    }\n    return this._userDataReader;\n  }\n\n  settings(settingsLiteral: firestore.Settings): void {\n    validateExactNumberOfArgs('Firestore.settings', arguments, 1);\n    validateArgType('Firestore.settings', 'object', 1, settingsLiteral);\n\n    const newSettings = new FirestoreSettings(settingsLiteral);\n    if (this._firestoreClient && !this._settings.isEqual(newSettings)) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'Firestore has already been started and its settings can no longer ' +\n          'be changed. You can only call settings() before calling any other ' +\n          'methods on a Firestore object.'\n      );\n    }\n\n    this._settings = newSettings;\n    if (newSettings.credentials !== undefined) {\n      this._credentials = makeCredentialsProvider(newSettings.credentials);\n    }\n  }\n\n  enableNetwork(): Promise<void> {\n    this.ensureClientConfigured();\n    return this._firestoreClient!.enableNetwork();\n  }\n\n  disableNetwork(): Promise<void> {\n    this.ensureClientConfigured();\n    return this._firestoreClient!.disableNetwork();\n  }\n\n  enablePersistence(settings?: firestore.PersistenceSettings): Promise<void> {\n    if (this._firestoreClient) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'Firestore has already been started and persistence can no longer ' +\n          'be enabled. You can only call enablePersistence() before calling ' +\n          'any other methods on a Firestore object.'\n      );\n    }\n\n    let synchronizeTabs = false;\n    let experimentalForceOwningTab = false;\n\n    if (settings) {\n      if (settings.experimentalTabSynchronization !== undefined) {\n        logError(\n          \"The 'experimentalTabSynchronization' setting will be removed. Use 'synchronizeTabs' instead.\"\n        );\n      }\n      synchronizeTabs =\n        settings.synchronizeTabs ??\n        settings.experimentalTabSynchronization ??\n        DEFAULT_SYNCHRONIZE_TABS;\n\n      experimentalForceOwningTab = settings.experimentalForceOwningTab\n        ? settings.experimentalForceOwningTab\n        : false;\n\n      if (synchronizeTabs && experimentalForceOwningTab) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          \"The 'experimentalForceOwningTab' setting cannot be used with 'synchronizeTabs'.\"\n        );\n      }\n    }\n\n    return this.configureClient(\n      this._offlineComponentProvider,\n      this._onlineComponentProvider,\n      {\n        durable: true,\n        cacheSizeBytes: this._settings.cacheSizeBytes,\n        synchronizeTabs,\n        forceOwningTab: experimentalForceOwningTab\n      }\n    );\n  }\n\n  async clearPersistence(): Promise<void> {\n    if (\n      this._firestoreClient !== undefined &&\n      !this._firestoreClient.clientTerminated\n    ) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'Persistence can only be cleared before a Firestore instance is ' +\n          'initialized or after it is terminated.'\n      );\n    }\n\n    const deferred = new Deferred<void>();\n    this._queue.enqueueAndForgetEvenAfterShutdown(async () => {\n      try {\n        await this._offlineComponentProvider.clearPersistence(\n          this._databaseId,\n          this._persistenceKey\n        );\n        deferred.resolve();\n      } catch (e) {\n        deferred.reject(e);\n      }\n    });\n    return deferred.promise;\n  }\n\n  terminate(): Promise<void> {\n    (this.app as _FirebaseApp)._removeServiceInstance('firestore');\n    return this.INTERNAL.delete();\n  }\n\n  get _isTerminated(): boolean {\n    this.ensureClientConfigured();\n    return this._firestoreClient!.clientTerminated;\n  }\n\n  waitForPendingWrites(): Promise<void> {\n    this.ensureClientConfigured();\n    return this._firestoreClient!.waitForPendingWrites();\n  }\n\n  onSnapshotsInSync(observer: PartialObserver<void>): Unsubscribe;\n  onSnapshotsInSync(onSync: () => void): Unsubscribe;\n  onSnapshotsInSync(arg: unknown): Unsubscribe {\n    this.ensureClientConfigured();\n\n    if (isPartialObserver(arg)) {\n      return this._firestoreClient!.addSnapshotsInSyncListener(\n        arg as PartialObserver<void>\n      );\n    } else {\n      validateArgType('Firestore.onSnapshotsInSync', 'function', 1, arg);\n      const observer: PartialObserver<void> = {\n        next: arg as () => void\n      };\n      return this._firestoreClient!.addSnapshotsInSyncListener(observer);\n    }\n  }\n\n  ensureClientConfigured(): FirestoreClient {\n    if (!this._firestoreClient) {\n      // Kick off starting the client but don't actually wait for it.\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.configureClient(\n        new MemoryOfflineComponentProvider(),\n        new OnlineComponentProvider(),\n        {\n          durable: false\n        }\n      );\n    }\n    return this._firestoreClient as FirestoreClient;\n  }\n\n  private makeDatabaseInfo(): DatabaseInfo {\n    return new DatabaseInfo(\n      this._databaseId,\n      this._persistenceKey,\n      this._settings.host,\n      this._settings.ssl,\n      this._settings.forceLongPolling\n    );\n  }\n\n  private configureClient(\n    offlineComponentProvider: OfflineComponentProvider,\n    onlineComponentProvider: OnlineComponentProvider,\n    persistenceSettings: PersistenceSettings\n  ): Promise<void> {\n    debugAssert(!!this._settings.host, 'FirestoreSettings.host is not set');\n\n    debugAssert(\n      !this._firestoreClient,\n      'configureClient() called multiple times'\n    );\n\n    const databaseInfo = this.makeDatabaseInfo();\n\n    this._firestoreClient = new FirestoreClient(this._credentials, this._queue);\n\n    return this._firestoreClient.start(\n      databaseInfo,\n      offlineComponentProvider,\n      onlineComponentProvider,\n      persistenceSettings\n    );\n  }\n\n  private static databaseIdFromApp(app: FirebaseApp): DatabaseId {\n    if (!contains(app.options, 'projectId')) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        '\"projectId\" not provided in firebase.initializeApp.'\n      );\n    }\n\n    const projectId = app.options.projectId;\n    if (!projectId || typeof projectId !== 'string') {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'projectId must be a string in FirebaseApp.options'\n      );\n    }\n    return new DatabaseId(projectId);\n  }\n\n  get app(): FirebaseApp {\n    if (!this._firebaseApp) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        \"Firestore was not initialized using the Firebase SDK. 'app' is \" +\n          'not available'\n      );\n    }\n    return this._firebaseApp;\n  }\n\n  INTERNAL = {\n    delete: async (): Promise<void> => {\n      // The client must be initalized to ensure that all subsequent API usage\n      // throws an exception.\n      this.ensureClientConfigured();\n      await this._firestoreClient!.terminate();\n    }\n  };\n\n  collection(pathString: string): firestore.CollectionReference {\n    validateExactNumberOfArgs('Firestore.collection', arguments, 1);\n    validateArgType('Firestore.collection', 'non-empty string', 1, pathString);\n    this.ensureClientConfigured();\n    return new CollectionReference(\n      ResourcePath.fromString(pathString),\n      this,\n      /* converter= */ null\n    );\n  }\n\n  doc(pathString: string): firestore.DocumentReference {\n    validateExactNumberOfArgs('Firestore.doc', arguments, 1);\n    validateArgType('Firestore.doc', 'non-empty string', 1, pathString);\n    this.ensureClientConfigured();\n    return DocumentReference.forPath(\n      ResourcePath.fromString(pathString),\n      this,\n      /* converter= */ null\n    );\n  }\n\n  collectionGroup(collectionId: string): firestore.Query {\n    validateExactNumberOfArgs('Firestore.collectionGroup', arguments, 1);\n    validateArgType(\n      'Firestore.collectionGroup',\n      'non-empty string',\n      1,\n      collectionId\n    );\n    if (collectionId.indexOf('/') >= 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid collection ID '${collectionId}' passed to function ` +\n          `Firestore.collectionGroup(). Collection IDs must not contain '/'.`\n      );\n    }\n    this.ensureClientConfigured();\n    return new Query(\n      newQueryForCollectionGroup(collectionId),\n      this,\n      /* converter= */ null\n    );\n  }\n\n  runTransaction<T>(\n    updateFunction: (transaction: firestore.Transaction) => Promise<T>\n  ): Promise<T> {\n    validateExactNumberOfArgs('Firestore.runTransaction', arguments, 1);\n    validateArgType('Firestore.runTransaction', 'function', 1, updateFunction);\n    return this.ensureClientConfigured().transaction(\n      (transaction: InternalTransaction) => {\n        return updateFunction(new Transaction(this, transaction));\n      }\n    );\n  }\n\n  batch(): firestore.WriteBatch {\n    this.ensureClientConfigured();\n\n    return new WriteBatch(this);\n  }\n\n  static get logLevel(): firestore.LogLevel {\n    switch (getLogLevel()) {\n      case LogLevel.DEBUG:\n        return 'debug';\n      case LogLevel.ERROR:\n        return 'error';\n      case LogLevel.SILENT:\n        return 'silent';\n      case LogLevel.WARN:\n        return 'warn';\n      case LogLevel.INFO:\n        return 'info';\n      case LogLevel.VERBOSE:\n        return 'verbose';\n      default:\n        // The default log level is error\n        return 'error';\n    }\n  }\n\n  static setLogLevel(level: firestore.LogLevel): void {\n    validateExactNumberOfArgs('Firestore.setLogLevel', arguments, 1);\n    validateStringEnum(\n      'setLogLevel',\n      ['debug', 'error', 'silent', 'warn', 'info', 'verbose'],\n      1,\n      level\n    );\n    setLogLevel(level);\n  }\n\n  // Note: this is not a property because the minifier can't work correctly with\n  // the way TypeScript compiler outputs properties.\n  _areTimestampsInSnapshotsEnabled(): boolean {\n    return this._settings.timestampsInSnapshots;\n  }\n}\n\n/**\n * A reference to a transaction.\n */\nexport class Transaction implements firestore.Transaction {\n  constructor(\n    private _firestore: Firestore,\n    private _transaction: InternalTransaction\n  ) {}\n\n  get<T>(\n    documentRef: firestore.DocumentReference<T>\n  ): Promise<firestore.DocumentSnapshot<T>> {\n    validateExactNumberOfArgs('Transaction.get', arguments, 1);\n    const ref = validateReference(\n      'Transaction.get',\n      documentRef,\n      this._firestore\n    );\n    return this._transaction\n      .lookup([ref._key])\n      .then((docs: MaybeDocument[]) => {\n        if (!docs || docs.length !== 1) {\n          return fail('Mismatch in docs returned from document lookup.');\n        }\n        const doc = docs[0];\n        if (doc instanceof NoDocument) {\n          return new DocumentSnapshot<T>(\n            this._firestore,\n            ref._key,\n            null,\n            /* fromCache= */ false,\n            /* hasPendingWrites= */ false,\n            ref._converter\n          );\n        } else if (doc instanceof Document) {\n          return new DocumentSnapshot<T>(\n            this._firestore,\n            ref._key,\n            doc,\n            /* fromCache= */ false,\n            /* hasPendingWrites= */ false,\n            ref._converter\n          );\n        } else {\n          throw fail(\n            `BatchGetDocumentsRequest returned unexpected document type: ${doc.constructor.name}`\n          );\n        }\n      });\n  }\n\n  set<T>(\n    documentRef: DocumentReference<T>,\n    data: Partial<T>,\n    options: firestore.SetOptions\n  ): Transaction;\n  set<T>(documentRef: DocumentReference<T>, data: T): Transaction;\n  set<T>(\n    documentRef: firestore.DocumentReference<T>,\n    value: T | Partial<T>,\n    options?: firestore.SetOptions\n  ): Transaction {\n    validateBetweenNumberOfArgs('Transaction.set', arguments, 2, 3);\n    const ref = validateReference(\n      'Transaction.set',\n      documentRef,\n      this._firestore\n    );\n    options = validateSetOptions('Transaction.set', options);\n    const convertedValue = applyFirestoreDataConverter(\n      ref._converter,\n      value,\n      options\n    );\n    const parsed = parseSetData(\n      this._firestore._dataReader,\n      'Transaction.set',\n      ref._key,\n      convertedValue,\n      ref._converter !== null,\n      options\n    );\n    this._transaction.set(ref._key, parsed);\n    return this;\n  }\n\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    value: firestore.UpdateData\n  ): Transaction;\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    field: string | ExternalFieldPath,\n    value: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): Transaction;\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n    value?: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): Transaction {\n    let ref;\n    let parsed;\n\n    if (\n      typeof fieldOrUpdateData === 'string' ||\n      fieldOrUpdateData instanceof ExternalFieldPath\n    ) {\n      validateAtLeastNumberOfArgs('Transaction.update', arguments, 3);\n      ref = validateReference(\n        'Transaction.update',\n        documentRef,\n        this._firestore\n      );\n      parsed = parseUpdateVarargs(\n        this._firestore._dataReader,\n        'Transaction.update',\n        ref._key,\n        fieldOrUpdateData,\n        value,\n        moreFieldsAndValues\n      );\n    } else {\n      validateExactNumberOfArgs('Transaction.update', arguments, 2);\n      ref = validateReference(\n        'Transaction.update',\n        documentRef,\n        this._firestore\n      );\n      parsed = parseUpdateData(\n        this._firestore._dataReader,\n        'Transaction.update',\n        ref._key,\n        fieldOrUpdateData\n      );\n    }\n\n    this._transaction.update(ref._key, parsed);\n    return this;\n  }\n\n  delete(documentRef: firestore.DocumentReference<unknown>): Transaction {\n    validateExactNumberOfArgs('Transaction.delete', arguments, 1);\n    const ref = validateReference(\n      'Transaction.delete',\n      documentRef,\n      this._firestore\n    );\n    this._transaction.delete(ref._key);\n    return this;\n  }\n}\n\nexport class WriteBatch implements firestore.WriteBatch {\n  private _mutations = [] as Mutation[];\n  private _committed = false;\n\n  constructor(private _firestore: Firestore) {}\n\n  set<T>(\n    documentRef: DocumentReference<T>,\n    data: Partial<T>,\n    options: firestore.SetOptions\n  ): WriteBatch;\n  set<T>(documentRef: DocumentReference<T>, data: T): WriteBatch;\n  set<T>(\n    documentRef: firestore.DocumentReference<T>,\n    value: T | Partial<T>,\n    options?: firestore.SetOptions\n  ): WriteBatch {\n    validateBetweenNumberOfArgs('WriteBatch.set', arguments, 2, 3);\n    this.verifyNotCommitted();\n    const ref = validateReference(\n      'WriteBatch.set',\n      documentRef,\n      this._firestore\n    );\n    options = validateSetOptions('WriteBatch.set', options);\n    const convertedValue = applyFirestoreDataConverter(\n      ref._converter,\n      value,\n      options\n    );\n    const parsed = parseSetData(\n      this._firestore._dataReader,\n      'WriteBatch.set',\n      ref._key,\n      convertedValue,\n      ref._converter !== null,\n      options\n    );\n    this._mutations = this._mutations.concat(\n      parsed.toMutations(ref._key, Precondition.none())\n    );\n    return this;\n  }\n\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    value: firestore.UpdateData\n  ): WriteBatch;\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    field: string | ExternalFieldPath,\n    value: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): WriteBatch;\n  update(\n    documentRef: firestore.DocumentReference<unknown>,\n    fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n    value?: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): WriteBatch {\n    this.verifyNotCommitted();\n\n    let ref;\n    let parsed;\n\n    if (\n      typeof fieldOrUpdateData === 'string' ||\n      fieldOrUpdateData instanceof ExternalFieldPath\n    ) {\n      validateAtLeastNumberOfArgs('WriteBatch.update', arguments, 3);\n      ref = validateReference(\n        'WriteBatch.update',\n        documentRef,\n        this._firestore\n      );\n      parsed = parseUpdateVarargs(\n        this._firestore._dataReader,\n        'WriteBatch.update',\n        ref._key,\n        fieldOrUpdateData,\n        value,\n        moreFieldsAndValues\n      );\n    } else {\n      validateExactNumberOfArgs('WriteBatch.update', arguments, 2);\n      ref = validateReference(\n        'WriteBatch.update',\n        documentRef,\n        this._firestore\n      );\n      parsed = parseUpdateData(\n        this._firestore._dataReader,\n        'WriteBatch.update',\n        ref._key,\n        fieldOrUpdateData\n      );\n    }\n\n    this._mutations = this._mutations.concat(\n      parsed.toMutations(ref._key, Precondition.exists(true))\n    );\n    return this;\n  }\n\n  delete(documentRef: firestore.DocumentReference<unknown>): WriteBatch {\n    validateExactNumberOfArgs('WriteBatch.delete', arguments, 1);\n    this.verifyNotCommitted();\n    const ref = validateReference(\n      'WriteBatch.delete',\n      documentRef,\n      this._firestore\n    );\n    this._mutations = this._mutations.concat(\n      new DeleteMutation(ref._key, Precondition.none())\n    );\n    return this;\n  }\n\n  commit(): Promise<void> {\n    this.verifyNotCommitted();\n    this._committed = true;\n    if (this._mutations.length > 0) {\n      return this._firestore.ensureClientConfigured().write(this._mutations);\n    }\n\n    return Promise.resolve();\n  }\n\n  private verifyNotCommitted(): void {\n    if (this._committed) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'A write batch can no longer be used after commit() ' +\n          'has been called.'\n      );\n    }\n  }\n}\n\n/**\n * A reference to a particular document in a collection in the database.\n */\nexport class DocumentReference<T = firestore.DocumentData>\n  extends DocumentKeyReference<T>\n  implements firestore.DocumentReference<T> {\n  private _firestoreClient: FirestoreClient;\n\n  constructor(\n    public _key: DocumentKey,\n    readonly firestore: Firestore,\n    readonly _converter: firestore.FirestoreDataConverter<T> | null\n  ) {\n    super(firestore._databaseId, _key, _converter);\n    this._firestoreClient = this.firestore.ensureClientConfigured();\n  }\n\n  static forPath<U>(\n    path: ResourcePath,\n    firestore: Firestore,\n    converter: firestore.FirestoreDataConverter<U> | null\n  ): DocumentReference<U> {\n    if (path.length % 2 !== 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Invalid document reference. Document ' +\n          'references must have an even number of segments, but ' +\n          `${path.canonicalString()} has ${path.length}`\n      );\n    }\n    return new DocumentReference(new DocumentKey(path), firestore, converter);\n  }\n\n  get id(): string {\n    return this._key.path.lastSegment();\n  }\n\n  get parent(): firestore.CollectionReference<T> {\n    return new CollectionReference(\n      this._key.path.popLast(),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  get path(): string {\n    return this._key.path.canonicalString();\n  }\n\n  collection(\n    pathString: string\n  ): firestore.CollectionReference<firestore.DocumentData> {\n    validateExactNumberOfArgs('DocumentReference.collection', arguments, 1);\n    validateArgType(\n      'DocumentReference.collection',\n      'non-empty string',\n      1,\n      pathString\n    );\n    if (!pathString) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Must provide a non-empty collection name to collection()'\n      );\n    }\n    const path = ResourcePath.fromString(pathString);\n    return new CollectionReference(\n      this._key.path.child(path),\n      this.firestore,\n      /* converter= */ null\n    );\n  }\n\n  isEqual(other: firestore.DocumentReference<T>): boolean {\n    if (!(other instanceof DocumentReference)) {\n      throw invalidClassError('isEqual', 'DocumentReference', 1, other);\n    }\n    return (\n      this.firestore === other.firestore &&\n      this._key.isEqual(other._key) &&\n      this._converter === other._converter\n    );\n  }\n\n  set(value: Partial<T>, options: firestore.SetOptions): Promise<void>;\n  set(value: T): Promise<void>;\n  set(value: T | Partial<T>, options?: firestore.SetOptions): Promise<void> {\n    validateBetweenNumberOfArgs('DocumentReference.set', arguments, 1, 2);\n    options = validateSetOptions('DocumentReference.set', options);\n    const convertedValue = applyFirestoreDataConverter(\n      this._converter,\n      value,\n      options\n    );\n    const parsed = parseSetData(\n      this.firestore._dataReader,\n      'DocumentReference.set',\n      this._key,\n      convertedValue,\n      this._converter !== null,\n      options\n    );\n    return this._firestoreClient.write(\n      parsed.toMutations(this._key, Precondition.none())\n    );\n  }\n\n  update(value: firestore.UpdateData): Promise<void>;\n  update(\n    field: string | ExternalFieldPath,\n    value: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): Promise<void>;\n  update(\n    fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n    value?: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): Promise<void> {\n    let parsed;\n\n    if (\n      typeof fieldOrUpdateData === 'string' ||\n      fieldOrUpdateData instanceof ExternalFieldPath\n    ) {\n      validateAtLeastNumberOfArgs('DocumentReference.update', arguments, 2);\n      parsed = parseUpdateVarargs(\n        this.firestore._dataReader,\n        'DocumentReference.update',\n        this._key,\n        fieldOrUpdateData,\n        value,\n        moreFieldsAndValues\n      );\n    } else {\n      validateExactNumberOfArgs('DocumentReference.update', arguments, 1);\n      parsed = parseUpdateData(\n        this.firestore._dataReader,\n        'DocumentReference.update',\n        this._key,\n        fieldOrUpdateData\n      );\n    }\n\n    return this._firestoreClient.write(\n      parsed.toMutations(this._key, Precondition.exists(true))\n    );\n  }\n\n  delete(): Promise<void> {\n    validateExactNumberOfArgs('DocumentReference.delete', arguments, 0);\n    return this._firestoreClient.write([\n      new DeleteMutation(this._key, Precondition.none())\n    ]);\n  }\n\n  onSnapshot(\n    observer: PartialObserver<firestore.DocumentSnapshot<T>>\n  ): Unsubscribe;\n  onSnapshot(\n    options: firestore.SnapshotListenOptions,\n    observer: PartialObserver<firestore.DocumentSnapshot<T>>\n  ): Unsubscribe;\n  onSnapshot(\n    onNext: NextFn<firestore.DocumentSnapshot<T>>,\n    onError?: ErrorFn,\n    onCompletion?: CompleteFn\n  ): Unsubscribe;\n  onSnapshot(\n    options: firestore.SnapshotListenOptions,\n    onNext: NextFn<firestore.DocumentSnapshot<T>>,\n    onError?: ErrorFn,\n    onCompletion?: CompleteFn\n  ): Unsubscribe;\n\n  onSnapshot(...args: unknown[]): Unsubscribe {\n    validateBetweenNumberOfArgs(\n      'DocumentReference.onSnapshot',\n      arguments,\n      1,\n      4\n    );\n    let options: ListenOptions = {\n      includeMetadataChanges: false\n    };\n    let currArg = 0;\n    if (\n      typeof args[currArg] === 'object' &&\n      !isPartialObserver(args[currArg])\n    ) {\n      options = args[currArg] as firestore.SnapshotListenOptions;\n      validateOptionNames('DocumentReference.onSnapshot', options, [\n        'includeMetadataChanges'\n      ]);\n      validateNamedOptionalType(\n        'DocumentReference.onSnapshot',\n        'boolean',\n        'includeMetadataChanges',\n        options.includeMetadataChanges\n      );\n      currArg++;\n    }\n\n    const internalOptions = {\n      includeMetadataChanges: options.includeMetadataChanges\n    };\n\n    if (isPartialObserver(args[currArg])) {\n      const userObserver = args[currArg] as PartialObserver<\n        firestore.DocumentSnapshot<T>\n      >;\n      args[currArg] = userObserver.next?.bind(userObserver);\n      args[currArg + 1] = userObserver.error?.bind(userObserver);\n      args[currArg + 2] = userObserver.complete?.bind(userObserver);\n    } else {\n      validateArgType(\n        'DocumentReference.onSnapshot',\n        'function',\n        currArg,\n        args[currArg]\n      );\n      validateOptionalArgType(\n        'DocumentReference.onSnapshot',\n        'function',\n        currArg + 1,\n        args[currArg + 1]\n      );\n      validateOptionalArgType(\n        'DocumentReference.onSnapshot',\n        'function',\n        currArg + 2,\n        args[currArg + 2]\n      );\n    }\n\n    const observer: PartialObserver<ViewSnapshot> = {\n      next: snapshot => {\n        if (args[currArg]) {\n          (args[currArg] as NextFn<firestore.DocumentSnapshot<T>>)(\n            this._convertToDocSnapshot(snapshot)\n          );\n        }\n      },\n      error: args[currArg + 1] as ErrorFn,\n      complete: args[currArg + 2] as CompleteFn\n    };\n\n    return this._firestoreClient.listen(\n      newQueryForPath(this._key.path),\n      internalOptions,\n      observer\n    );\n  }\n\n  get(options?: firestore.GetOptions): Promise<firestore.DocumentSnapshot<T>> {\n    validateBetweenNumberOfArgs('DocumentReference.get', arguments, 0, 1);\n    validateGetOptions('DocumentReference.get', options);\n\n    const firestoreClient = this.firestore.ensureClientConfigured();\n    if (options && options.source === 'cache') {\n      return firestoreClient\n        .getDocumentFromLocalCache(this._key)\n        .then(\n          doc =>\n            new DocumentSnapshot(\n              this.firestore,\n              this._key,\n              doc,\n              /*fromCache=*/ true,\n              doc instanceof Document ? doc.hasLocalMutations : false,\n              this._converter\n            )\n        );\n    } else {\n      return firestoreClient\n        .getDocumentViaSnapshotListener(this._key, options)\n        .then(snapshot => this._convertToDocSnapshot(snapshot));\n    }\n  }\n\n  withConverter<U>(\n    converter: firestore.FirestoreDataConverter<U>\n  ): firestore.DocumentReference<U> {\n    return new DocumentReference<U>(this._key, this.firestore, converter);\n  }\n\n  /**\n   * Converts a ViewSnapshot that contains the current document to a\n   * DocumentSnapshot.\n   */\n  private _convertToDocSnapshot(snapshot: ViewSnapshot): DocumentSnapshot<T> {\n    debugAssert(\n      snapshot.docs.size <= 1,\n      'Too many documents returned on a document query'\n    );\n    const doc = snapshot.docs.get(this._key);\n\n    return new DocumentSnapshot(\n      this.firestore,\n      this._key,\n      doc,\n      snapshot.fromCache,\n      snapshot.hasPendingWrites,\n      this._converter\n    );\n  }\n}\n\nexport class SnapshotMetadata implements firestore.SnapshotMetadata {\n  constructor(\n    readonly hasPendingWrites: boolean,\n    readonly fromCache: boolean\n  ) {}\n\n  isEqual(other: firestore.SnapshotMetadata): boolean {\n    return (\n      this.hasPendingWrites === other.hasPendingWrites &&\n      this.fromCache === other.fromCache\n    );\n  }\n}\n\n/**\n * Options interface that can be provided to configure the deserialization of\n * DocumentSnapshots.\n */\nexport interface SnapshotOptions extends firestore.SnapshotOptions {}\n\nexport class DocumentSnapshot<T = firestore.DocumentData>\n  implements firestore.DocumentSnapshot<T> {\n  constructor(\n    private _firestore: Firestore,\n    private _key: DocumentKey,\n    public _document: Document | null,\n    private _fromCache: boolean,\n    private _hasPendingWrites: boolean,\n    private readonly _converter: firestore.FirestoreDataConverter<T> | null\n  ) {}\n\n  data(options?: firestore.SnapshotOptions): T | undefined {\n    validateBetweenNumberOfArgs('DocumentSnapshot.data', arguments, 0, 1);\n    options = validateSnapshotOptions('DocumentSnapshot.data', options);\n    if (!this._document) {\n      return undefined;\n    } else {\n      // We only want to use the converter and create a new DocumentSnapshot\n      // if a converter has been provided.\n      if (this._converter) {\n        const snapshot = new QueryDocumentSnapshot(\n          this._firestore,\n          this._key,\n          this._document,\n          this._fromCache,\n          this._hasPendingWrites,\n          /* converter= */ null\n        );\n        return this._converter.fromFirestore(snapshot, options);\n      } else {\n        const userDataWriter = new UserDataWriter(\n          this._firestore._databaseId,\n          this._firestore._areTimestampsInSnapshotsEnabled(),\n          options.serverTimestamps || 'none',\n          key =>\n            new DocumentReference(key, this._firestore, /* converter= */ null)\n        );\n        return userDataWriter.convertValue(this._document.toProto()) as T;\n      }\n    }\n  }\n\n  get(\n    fieldPath: string | ExternalFieldPath,\n    options?: firestore.SnapshotOptions\n  ): unknown {\n    validateBetweenNumberOfArgs('DocumentSnapshot.get', arguments, 1, 2);\n    options = validateSnapshotOptions('DocumentSnapshot.get', options);\n    if (this._document) {\n      const value = this._document\n        .data()\n        .field(\n          fieldPathFromArgument('DocumentSnapshot.get', fieldPath, this._key)\n        );\n      if (value !== null) {\n        const userDataWriter = new UserDataWriter(\n          this._firestore._databaseId,\n          this._firestore._areTimestampsInSnapshotsEnabled(),\n          options.serverTimestamps || 'none',\n          key => new DocumentReference(key, this._firestore, this._converter)\n        );\n        return userDataWriter.convertValue(value);\n      }\n    }\n    return undefined;\n  }\n\n  get id(): string {\n    return this._key.path.lastSegment();\n  }\n\n  get ref(): firestore.DocumentReference<T> {\n    return new DocumentReference<T>(\n      this._key,\n      this._firestore,\n      this._converter\n    );\n  }\n\n  get exists(): boolean {\n    return this._document !== null;\n  }\n\n  get metadata(): firestore.SnapshotMetadata {\n    return new SnapshotMetadata(this._hasPendingWrites, this._fromCache);\n  }\n\n  isEqual(other: firestore.DocumentSnapshot<T>): boolean {\n    if (!(other instanceof DocumentSnapshot)) {\n      throw invalidClassError('isEqual', 'DocumentSnapshot', 1, other);\n    }\n    return (\n      this._firestore === other._firestore &&\n      this._fromCache === other._fromCache &&\n      this._key.isEqual(other._key) &&\n      (this._document === null\n        ? other._document === null\n        : this._document.isEqual(other._document)) &&\n      this._converter === other._converter\n    );\n  }\n}\n\nexport class QueryDocumentSnapshot<T = firestore.DocumentData>\n  extends DocumentSnapshot<T>\n  implements firestore.QueryDocumentSnapshot<T> {\n  data(options?: SnapshotOptions): T {\n    const data = super.data(options);\n    debugAssert(\n      data !== undefined,\n      'Document in a QueryDocumentSnapshot should exist'\n    );\n    return data;\n  }\n}\n\nexport function newQueryFilter(\n  query: InternalQuery,\n  methodName: string,\n  dataReader: UserDataReader,\n  databaseId: DatabaseId,\n  fieldPath: FieldPath,\n  op: Operator,\n  value: unknown\n): FieldFilter {\n  let fieldValue: api.Value;\n  if (fieldPath.isKeyField()) {\n    if (op === Operator.ARRAY_CONTAINS || op === Operator.ARRAY_CONTAINS_ANY) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid Query. You can't perform '${op}' ` +\n          'queries on FieldPath.documentId().'\n      );\n    } else if (op === Operator.IN || op === Operator.NOT_IN) {\n      validateDisjunctiveFilterElements(value, op);\n      const referenceList: api.Value[] = [];\n      for (const arrayValue of value as api.Value[]) {\n        referenceList.push(parseDocumentIdValue(databaseId, query, arrayValue));\n      }\n      fieldValue = { arrayValue: { values: referenceList } };\n    } else {\n      fieldValue = parseDocumentIdValue(databaseId, query, value);\n    }\n  } else {\n    if (\n      op === Operator.IN ||\n      op === Operator.NOT_IN ||\n      op === Operator.ARRAY_CONTAINS_ANY\n    ) {\n      validateDisjunctiveFilterElements(value, op);\n    }\n    fieldValue = parseQueryValue(\n      dataReader,\n      methodName,\n      value,\n      /* allowArrays= */ op === Operator.IN || op === Operator.NOT_IN\n    );\n  }\n  const filter = FieldFilter.create(fieldPath, op, fieldValue);\n  validateNewFilter(query, filter);\n  return filter;\n}\n\nexport function newQueryOrderBy(\n  query: InternalQuery,\n  fieldPath: FieldPath,\n  direction: Direction\n): OrderBy {\n  if (query.startAt !== null) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Invalid query. You must not call startAt() or startAfter() before ' +\n        'calling orderBy().'\n    );\n  }\n  if (query.endAt !== null) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Invalid query. You must not call endAt() or endBefore() before ' +\n        'calling orderBy().'\n    );\n  }\n  const orderBy = new OrderBy(fieldPath, direction);\n  validateNewOrderBy(query, orderBy);\n  return orderBy;\n}\n\n/**\n * Create a Bound from a query and a document.\n *\n * Note that the Bound will always include the key of the document\n * and so only the provided document will compare equal to the returned\n * position.\n *\n * Will throw if the document does not contain all fields of the order by\n * of the query or if any of the fields in the order by are an uncommitted\n * server timestamp.\n */\nexport function newQueryBoundFromDocument(\n  query: InternalQuery,\n  databaseId: DatabaseId,\n  methodName: string,\n  doc: Document | null,\n  before: boolean\n): Bound {\n  if (!doc) {\n    throw new FirestoreError(\n      Code.NOT_FOUND,\n      `Can't use a DocumentSnapshot that doesn't exist for ` +\n        `${methodName}().`\n    );\n  }\n\n  const components: api.Value[] = [];\n\n  // Because people expect to continue/end a query at the exact document\n  // provided, we need to use the implicit sort order rather than the explicit\n  // sort order, because it's guaranteed to contain the document key. That way\n  // the position becomes unambiguous and the query continues/ends exactly at\n  // the provided document. Without the key (by using the explicit sort\n  // orders), multiple documents could match the position, yielding duplicate\n  // results.\n  for (const orderBy of queryOrderBy(query)) {\n    if (orderBy.field.isKeyField()) {\n      components.push(refValue(databaseId, doc.key));\n    } else {\n      const value = doc.field(orderBy.field);\n      if (isServerTimestamp(value)) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          'Invalid query. You are trying to start or end a query using a ' +\n            'document for which the field \"' +\n            orderBy.field +\n            '\" is an uncommitted server timestamp. (Since the value of ' +\n            'this field is unknown, you cannot start/end a query with it.)'\n        );\n      } else if (value !== null) {\n        components.push(value);\n      } else {\n        const field = orderBy.field.canonicalString();\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid query. You are trying to start or end a query using a ` +\n            `document for which the field '${field}' (used as the ` +\n            `orderBy) does not exist.`\n        );\n      }\n    }\n  }\n  return new Bound(components, before);\n}\n\n/**\n * Converts a list of field values to a Bound for the given query.\n */\nexport function newQueryBoundFromFields(\n  query: InternalQuery,\n  databaseId: DatabaseId,\n  dataReader: UserDataReader,\n  methodName: string,\n  values: unknown[],\n  before: boolean\n): Bound {\n  // Use explicit order by's because it has to match the query the user made\n  const orderBy = query.explicitOrderBy;\n  if (values.length > orderBy.length) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Too many arguments provided to ${methodName}(). ` +\n        `The number of arguments must be less than or equal to the ` +\n        `number of orderBy() clauses`\n    );\n  }\n\n  const components: api.Value[] = [];\n  for (let i = 0; i < values.length; i++) {\n    const rawValue = values[i];\n    const orderByComponent = orderBy[i];\n    if (orderByComponent.field.isKeyField()) {\n      if (typeof rawValue !== 'string') {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid query. Expected a string for document ID in ` +\n            `${methodName}(), but got a ${typeof rawValue}`\n        );\n      }\n      if (!isCollectionGroupQuery(query) && rawValue.indexOf('/') !== -1) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid query. When querying a collection and ordering by FieldPath.documentId(), ` +\n            `the value passed to ${methodName}() must be a plain document ID, but ` +\n            `'${rawValue}' contains a slash.`\n        );\n      }\n      const path = query.path.child(ResourcePath.fromString(rawValue));\n      if (!DocumentKey.isDocumentKey(path)) {\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          `Invalid query. When querying a collection group and ordering by ` +\n            `FieldPath.documentId(), the value passed to ${methodName}() must result in a ` +\n            `valid document path, but '${path}' is not because it contains an odd number ` +\n            `of segments.`\n        );\n      }\n      const key = new DocumentKey(path);\n      components.push(refValue(databaseId, key));\n    } else {\n      const wrapped = parseQueryValue(dataReader, methodName, rawValue);\n      components.push(wrapped);\n    }\n  }\n\n  return new Bound(components, before);\n}\n\n/**\n * Parses the given documentIdValue into a ReferenceValue, throwing\n * appropriate errors if the value is anything other than a DocumentReference\n * or String, or if the string is malformed.\n */\nfunction parseDocumentIdValue(\n  databaseId: DatabaseId,\n  query: InternalQuery,\n  documentIdValue: unknown\n): api.Value {\n  if (typeof documentIdValue === 'string') {\n    if (documentIdValue === '') {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Invalid query. When querying with FieldPath.documentId(), you ' +\n          'must provide a valid document ID, but it was an empty string.'\n      );\n    }\n    if (!isCollectionGroupQuery(query) && documentIdValue.indexOf('/') !== -1) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid query. When querying a collection by ` +\n          `FieldPath.documentId(), you must provide a plain document ID, but ` +\n          `'${documentIdValue}' contains a '/' character.`\n      );\n    }\n    const path = query.path.child(ResourcePath.fromString(documentIdValue));\n    if (!DocumentKey.isDocumentKey(path)) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid query. When querying a collection group by ` +\n          `FieldPath.documentId(), the value provided must result in a valid document path, ` +\n          `but '${path}' is not because it has an odd number of segments (${path.length}).`\n      );\n    }\n    return refValue(databaseId, new DocumentKey(path));\n  } else if (documentIdValue instanceof DocumentKeyReference) {\n    return refValue(databaseId, documentIdValue._key);\n  } else {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid query. When querying with FieldPath.documentId(), you must provide a valid ` +\n        `string or a DocumentReference, but it was: ` +\n        `${valueDescription(documentIdValue)}.`\n    );\n  }\n}\n\n/**\n * Validates that the value passed into a disjunctive filter satisfies all\n * array requirements.\n */\nfunction validateDisjunctiveFilterElements(\n  value: unknown,\n  operator: Operator\n): void {\n  if (!Array.isArray(value) || value.length === 0) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Invalid Query. A non-empty array is required for ' +\n        `'${operator.toString()}' filters.`\n    );\n  }\n  if (value.length > 10) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid Query. '${operator.toString()}' filters support a ` +\n        'maximum of 10 elements in the value array.'\n    );\n  }\n  if (operator === Operator.IN || operator === Operator.ARRAY_CONTAINS_ANY) {\n    if (value.indexOf(null) >= 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid Query. '${operator.toString()}' filters cannot contain 'null' ` +\n          'in the value array.'\n      );\n    }\n    if (value.filter(element => Number.isNaN(element)).length > 0) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid Query. '${operator.toString()}' filters cannot contain 'NaN' ` +\n          'in the value array.'\n      );\n    }\n  }\n}\n\n/**\n * Given an operator, returns the set of operators that cannot be used with it.\n *\n * Operators in a query must adhere to the following set of rules:\n * 1. Only one array operator is allowed.\n * 2. Only one disjunctive operator is allowed.\n * 3. NOT_EQUAL cannot be used with another NOT_EQUAL operator.\n * 4. NOT_IN cannot be used with array, disjunctive, or NOT_EQUAL operators.\n *\n * Array operators: ARRAY_CONTAINS, ARRAY_CONTAINS_ANY\n * Disjunctive operators: IN, ARRAY_CONTAINS_ANY, NOT_IN\n */\nfunction conflictingOps(op: Operator): Operator[] {\n  switch (op) {\n    case Operator.NOT_EQUAL:\n      return [Operator.NOT_EQUAL, Operator.NOT_IN];\n    case Operator.ARRAY_CONTAINS:\n      return [\n        Operator.ARRAY_CONTAINS,\n        Operator.ARRAY_CONTAINS_ANY,\n        Operator.NOT_IN\n      ];\n    case Operator.IN:\n      return [Operator.ARRAY_CONTAINS_ANY, Operator.IN, Operator.NOT_IN];\n    case Operator.ARRAY_CONTAINS_ANY:\n      return [\n        Operator.ARRAY_CONTAINS,\n        Operator.ARRAY_CONTAINS_ANY,\n        Operator.IN,\n        Operator.NOT_IN\n      ];\n    case Operator.NOT_IN:\n      return [\n        Operator.ARRAY_CONTAINS,\n        Operator.ARRAY_CONTAINS_ANY,\n        Operator.IN,\n        Operator.NOT_IN,\n        Operator.NOT_EQUAL\n      ];\n    default:\n      return [];\n  }\n}\n\nfunction validateNewFilter(query: InternalQuery, filter: Filter): void {\n  debugAssert(filter instanceof FieldFilter, 'Only FieldFilters are supported');\n\n  if (filter.isInequality()) {\n    const existingField = query.getInequalityFilterField();\n    if (existingField !== null && !existingField.isEqual(filter.field)) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Invalid query. All where filters with an inequality' +\n          ' (<, <=, >, or >=) must be on the same field. But you have' +\n          ` inequality filters on '${existingField.toString()}'` +\n          ` and '${filter.field.toString()}'`\n      );\n    }\n\n    const firstOrderByField = query.getFirstOrderByField();\n    if (firstOrderByField !== null) {\n      validateOrderByAndInequalityMatch(query, filter.field, firstOrderByField);\n    }\n  }\n\n  const conflictingOp = query.findFilterOperator(conflictingOps(filter.op));\n  if (conflictingOp !== null) {\n    // Special case when it's a duplicate op to give a slightly clearer error message.\n    if (conflictingOp === filter.op) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Invalid query. You cannot use more than one ' +\n          `'${filter.op.toString()}' filter.`\n      );\n    } else {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Invalid query. You cannot use '${filter.op.toString()}' filters ` +\n          `with '${conflictingOp.toString()}' filters.`\n      );\n    }\n  }\n}\n\nfunction validateNewOrderBy(query: InternalQuery, orderBy: OrderBy): void {\n  if (query.getFirstOrderByField() === null) {\n    // This is the first order by. It must match any inequality.\n    const inequalityField = query.getInequalityFilterField();\n    if (inequalityField !== null) {\n      validateOrderByAndInequalityMatch(query, inequalityField, orderBy.field);\n    }\n  }\n}\n\nfunction validateOrderByAndInequalityMatch(\n  baseQuery: InternalQuery,\n  inequality: FieldPath,\n  orderBy: FieldPath\n): void {\n  if (!orderBy.isEqual(inequality)) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid query. You have a where filter with an inequality ` +\n        `(<, <=, >, or >=) on field '${inequality.toString()}' ` +\n        `and so you must also use '${inequality.toString()}' ` +\n        `as your first orderBy(), but your first orderBy() ` +\n        `is on field '${orderBy.toString()}' instead.`\n    );\n  }\n}\n\nexport function validateHasExplicitOrderByForLimitToLast(\n  query: InternalQuery\n): void {\n  if (query.hasLimitToLast() && query.explicitOrderBy.length === 0) {\n    throw new FirestoreError(\n      Code.UNIMPLEMENTED,\n      'limitToLast() queries require specifying at least one orderBy() clause'\n    );\n  }\n}\n\nexport class Query<T = firestore.DocumentData> implements firestore.Query<T> {\n  constructor(\n    public _query: InternalQuery,\n    readonly firestore: Firestore,\n    protected readonly _converter: firestore.FirestoreDataConverter<T> | null\n  ) {}\n\n  where(\n    field: string | ExternalFieldPath,\n    opStr: firestore.WhereFilterOp,\n    value: unknown\n  ): firestore.Query<T> {\n    validateExactNumberOfArgs('Query.where', arguments, 3);\n    validateDefined('Query.where', 3, value);\n\n    // TODO(ne-queries): Add 'not-in' and '!=' to validation.\n    let op: Operator;\n    if ((opStr as unknown) === 'not-in' || (opStr as unknown) === '!=') {\n      op = opStr as Operator;\n    } else {\n      // Enumerated from the WhereFilterOp type in index.d.ts.\n      const whereFilterOpEnums = [\n        Operator.LESS_THAN,\n        Operator.LESS_THAN_OR_EQUAL,\n        Operator.EQUAL,\n        Operator.GREATER_THAN_OR_EQUAL,\n        Operator.GREATER_THAN,\n        Operator.ARRAY_CONTAINS,\n        Operator.IN,\n        Operator.ARRAY_CONTAINS_ANY\n      ];\n      op = validateStringEnum('Query.where', whereFilterOpEnums, 2, opStr);\n    }\n\n    const fieldPath = fieldPathFromArgument('Query.where', field);\n    const filter = newQueryFilter(\n      this._query,\n      'Query.where',\n      this.firestore._dataReader,\n      this.firestore._databaseId,\n      fieldPath,\n      op,\n      value\n    );\n    return new Query(\n      queryWithAddedFilter(this._query, filter),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  orderBy(\n    field: string | ExternalFieldPath,\n    directionStr?: firestore.OrderByDirection\n  ): firestore.Query<T> {\n    validateBetweenNumberOfArgs('Query.orderBy', arguments, 1, 2);\n    validateOptionalArgType(\n      'Query.orderBy',\n      'non-empty string',\n      2,\n      directionStr\n    );\n    let direction: Direction;\n    if (directionStr === undefined || directionStr === 'asc') {\n      direction = Direction.ASCENDING;\n    } else if (directionStr === 'desc') {\n      direction = Direction.DESCENDING;\n    } else {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        `Function Query.orderBy() has unknown direction '${directionStr}', ` +\n          `expected 'asc' or 'desc'.`\n      );\n    }\n    const fieldPath = fieldPathFromArgument('Query.orderBy', field);\n    const orderBy = newQueryOrderBy(this._query, fieldPath, direction);\n    return new Query(\n      queryWithAddedOrderBy(this._query, orderBy),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  limit(n: number): firestore.Query<T> {\n    validateExactNumberOfArgs('Query.limit', arguments, 1);\n    validateArgType('Query.limit', 'number', 1, n);\n    validatePositiveNumber('Query.limit', 1, n);\n    return new Query(\n      queryWithLimit(this._query, n, LimitType.First),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  limitToLast(n: number): firestore.Query<T> {\n    validateExactNumberOfArgs('Query.limitToLast', arguments, 1);\n    validateArgType('Query.limitToLast', 'number', 1, n);\n    validatePositiveNumber('Query.limitToLast', 1, n);\n    return new Query(\n      queryWithLimit(this._query, n, LimitType.Last),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  startAt(\n    docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n    ...fields: unknown[]\n  ): firestore.Query<T> {\n    validateAtLeastNumberOfArgs('Query.startAt', arguments, 1);\n    const bound = this.boundFromDocOrFields(\n      'Query.startAt',\n      docOrField,\n      fields,\n      /*before=*/ true\n    );\n    return new Query(\n      queryWithStartAt(this._query, bound),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  startAfter(\n    docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n    ...fields: unknown[]\n  ): firestore.Query<T> {\n    validateAtLeastNumberOfArgs('Query.startAfter', arguments, 1);\n    const bound = this.boundFromDocOrFields(\n      'Query.startAfter',\n      docOrField,\n      fields,\n      /*before=*/ false\n    );\n    return new Query(\n      queryWithStartAt(this._query, bound),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  endBefore(\n    docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n    ...fields: unknown[]\n  ): firestore.Query<T> {\n    validateAtLeastNumberOfArgs('Query.endBefore', arguments, 1);\n    const bound = this.boundFromDocOrFields(\n      'Query.endBefore',\n      docOrField,\n      fields,\n      /*before=*/ true\n    );\n    return new Query(\n      queryWithEndAt(this._query, bound),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  endAt(\n    docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n    ...fields: unknown[]\n  ): firestore.Query<T> {\n    validateAtLeastNumberOfArgs('Query.endAt', arguments, 1);\n    const bound = this.boundFromDocOrFields(\n      'Query.endAt',\n      docOrField,\n      fields,\n      /*before=*/ false\n    );\n    return new Query(\n      queryWithEndAt(this._query, bound),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  isEqual(other: firestore.Query<T>): boolean {\n    if (!(other instanceof Query)) {\n      throw invalidClassError('isEqual', 'Query', 1, other);\n    }\n    return (\n      this.firestore === other.firestore &&\n      queryEquals(this._query, other._query) &&\n      this._converter === other._converter\n    );\n  }\n\n  withConverter<U>(\n    converter: firestore.FirestoreDataConverter<U>\n  ): firestore.Query<U> {\n    return new Query<U>(this._query, this.firestore, converter);\n  }\n\n  /** Helper function to create a bound from a document or fields */\n  private boundFromDocOrFields(\n    methodName: string,\n    docOrField: unknown | firestore.DocumentSnapshot<T>,\n    fields: unknown[],\n    before: boolean\n  ): Bound {\n    validateDefined(methodName, 1, docOrField);\n    if (docOrField instanceof DocumentSnapshot) {\n      validateExactNumberOfArgs(methodName, [docOrField, ...fields], 1);\n      return newQueryBoundFromDocument(\n        this._query,\n        this.firestore._databaseId,\n        methodName,\n        docOrField._document,\n        before\n      );\n    } else {\n      const allFields = [docOrField].concat(fields);\n      return newQueryBoundFromFields(\n        this._query,\n        this.firestore._databaseId,\n        this.firestore._dataReader,\n        methodName,\n        allFields,\n        before\n      );\n    }\n  }\n\n  onSnapshot(\n    observer: PartialObserver<firestore.QuerySnapshot<T>>\n  ): Unsubscribe;\n  onSnapshot(\n    options: firestore.SnapshotListenOptions,\n    observer: PartialObserver<firestore.QuerySnapshot<T>>\n  ): Unsubscribe;\n  onSnapshot(\n    onNext: NextFn<firestore.QuerySnapshot<T>>,\n    onError?: ErrorFn,\n    onCompletion?: CompleteFn\n  ): Unsubscribe;\n  onSnapshot(\n    options: firestore.SnapshotListenOptions,\n    onNext: NextFn<firestore.QuerySnapshot<T>>,\n    onError?: ErrorFn,\n    onCompletion?: CompleteFn\n  ): Unsubscribe;\n\n  onSnapshot(...args: unknown[]): Unsubscribe {\n    validateBetweenNumberOfArgs('Query.onSnapshot', arguments, 1, 4);\n    let options: ListenOptions = {};\n    let currArg = 0;\n    if (\n      typeof args[currArg] === 'object' &&\n      !isPartialObserver(args[currArg])\n    ) {\n      options = args[currArg] as firestore.SnapshotListenOptions;\n      validateOptionNames('Query.onSnapshot', options, [\n        'includeMetadataChanges'\n      ]);\n      validateNamedOptionalType(\n        'Query.onSnapshot',\n        'boolean',\n        'includeMetadataChanges',\n        options.includeMetadataChanges\n      );\n      currArg++;\n    }\n\n    if (isPartialObserver(args[currArg])) {\n      const userObserver = args[currArg] as PartialObserver<\n        firestore.QuerySnapshot<T>\n      >;\n      args[currArg] = userObserver.next?.bind(userObserver);\n      args[currArg + 1] = userObserver.error?.bind(userObserver);\n      args[currArg + 2] = userObserver.complete?.bind(userObserver);\n    } else {\n      validateArgType('Query.onSnapshot', 'function', currArg, args[currArg]);\n      validateOptionalArgType(\n        'Query.onSnapshot',\n        'function',\n        currArg + 1,\n        args[currArg + 1]\n      );\n      validateOptionalArgType(\n        'Query.onSnapshot',\n        'function',\n        currArg + 2,\n        args[currArg + 2]\n      );\n    }\n\n    const observer: PartialObserver<ViewSnapshot> = {\n      next: snapshot => {\n        if (args[currArg]) {\n          (args[currArg] as NextFn<firestore.QuerySnapshot<T>>)(\n            new QuerySnapshot(\n              this.firestore,\n              this._query,\n              snapshot,\n              this._converter\n            )\n          );\n        }\n      },\n      error: args[currArg + 1] as ErrorFn,\n      complete: args[currArg + 2] as CompleteFn\n    };\n\n    validateHasExplicitOrderByForLimitToLast(this._query);\n    const firestoreClient = this.firestore.ensureClientConfigured();\n    return firestoreClient.listen(this._query, options, observer);\n  }\n\n  get(options?: firestore.GetOptions): Promise<firestore.QuerySnapshot<T>> {\n    validateBetweenNumberOfArgs('Query.get', arguments, 0, 1);\n    validateGetOptions('Query.get', options);\n    validateHasExplicitOrderByForLimitToLast(this._query);\n\n    const firestoreClient = this.firestore.ensureClientConfigured();\n    return (options && options.source === 'cache'\n      ? firestoreClient.getDocumentsFromLocalCache(this._query)\n      : firestoreClient.getDocumentsViaSnapshotListener(this._query, options)\n    ).then(\n      snap =>\n        new QuerySnapshot(this.firestore, this._query, snap, this._converter)\n    );\n  }\n}\n\nexport class QuerySnapshot<T = firestore.DocumentData>\n  implements firestore.QuerySnapshot<T> {\n  private _cachedChanges: Array<firestore.DocumentChange<T>> | null = null;\n  private _cachedChangesIncludeMetadataChanges: boolean | null = null;\n\n  readonly metadata: firestore.SnapshotMetadata;\n\n  constructor(\n    private readonly _firestore: Firestore,\n    private readonly _originalQuery: InternalQuery,\n    private readonly _snapshot: ViewSnapshot,\n    private readonly _converter: firestore.FirestoreDataConverter<T> | null\n  ) {\n    this.metadata = new SnapshotMetadata(\n      _snapshot.hasPendingWrites,\n      _snapshot.fromCache\n    );\n  }\n\n  get docs(): Array<firestore.QueryDocumentSnapshot<T>> {\n    const result: Array<firestore.QueryDocumentSnapshot<T>> = [];\n    this.forEach(doc => result.push(doc));\n    return result;\n  }\n\n  get empty(): boolean {\n    return this._snapshot.docs.isEmpty();\n  }\n\n  get size(): number {\n    return this._snapshot.docs.size;\n  }\n\n  forEach(\n    callback: (result: firestore.QueryDocumentSnapshot<T>) => void,\n    thisArg?: unknown\n  ): void {\n    validateBetweenNumberOfArgs('QuerySnapshot.forEach', arguments, 1, 2);\n    validateArgType('QuerySnapshot.forEach', 'function', 1, callback);\n    this._snapshot.docs.forEach(doc => {\n      callback.call(\n        thisArg,\n        this.convertToDocumentImpl(\n          doc,\n          this.metadata.fromCache,\n          this._snapshot.mutatedKeys.has(doc.key)\n        )\n      );\n    });\n  }\n\n  get query(): firestore.Query<T> {\n    return new Query(this._originalQuery, this._firestore, this._converter);\n  }\n\n  docChanges(\n    options?: firestore.SnapshotListenOptions\n  ): Array<firestore.DocumentChange<T>> {\n    if (options) {\n      validateOptionNames('QuerySnapshot.docChanges', options, [\n        'includeMetadataChanges'\n      ]);\n      validateNamedOptionalType(\n        'QuerySnapshot.docChanges',\n        'boolean',\n        'includeMetadataChanges',\n        options.includeMetadataChanges\n      );\n    }\n\n    const includeMetadataChanges = !!(\n      options && options.includeMetadataChanges\n    );\n\n    if (includeMetadataChanges && this._snapshot.excludesMetadataChanges) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'To include metadata changes with your document changes, you must ' +\n          'also pass { includeMetadataChanges:true } to onSnapshot().'\n      );\n    }\n\n    if (\n      !this._cachedChanges ||\n      this._cachedChangesIncludeMetadataChanges !== includeMetadataChanges\n    ) {\n      this._cachedChanges = changesFromSnapshot<QueryDocumentSnapshot<T>>(\n        this._snapshot,\n        includeMetadataChanges,\n        this.convertToDocumentImpl.bind(this)\n      );\n      this._cachedChangesIncludeMetadataChanges = includeMetadataChanges;\n    }\n\n    return this._cachedChanges;\n  }\n\n  /** Check the equality. The call can be very expensive. */\n  isEqual(other: firestore.QuerySnapshot<T>): boolean {\n    if (!(other instanceof QuerySnapshot)) {\n      throw invalidClassError('isEqual', 'QuerySnapshot', 1, other);\n    }\n\n    return (\n      this._firestore === other._firestore &&\n      queryEquals(this._originalQuery, other._originalQuery) &&\n      this._snapshot.isEqual(other._snapshot) &&\n      this._converter === other._converter\n    );\n  }\n\n  private convertToDocumentImpl(\n    doc: Document,\n    fromCache: boolean,\n    hasPendingWrites: boolean\n  ): QueryDocumentSnapshot<T> {\n    return new QueryDocumentSnapshot(\n      this._firestore,\n      doc.key,\n      doc,\n      fromCache,\n      hasPendingWrites,\n      this._converter\n    );\n  }\n}\n\nexport class CollectionReference<T = firestore.DocumentData> extends Query<T>\n  implements firestore.CollectionReference<T> {\n  constructor(\n    readonly _path: ResourcePath,\n    firestore: Firestore,\n    _converter: firestore.FirestoreDataConverter<T> | null\n  ) {\n    super(newQueryForPath(_path), firestore, _converter);\n    if (_path.length % 2 !== 1) {\n      throw new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Invalid collection reference. Collection ' +\n          'references must have an odd number of segments, but ' +\n          `${_path.canonicalString()} has ${_path.length}`\n      );\n    }\n  }\n\n  get id(): string {\n    return this._query.path.lastSegment();\n  }\n\n  get parent(): firestore.DocumentReference<firestore.DocumentData> | null {\n    const parentPath = this._query.path.popLast();\n    if (parentPath.isEmpty()) {\n      return null;\n    } else {\n      return new DocumentReference<firestore.DocumentData>(\n        new DocumentKey(parentPath),\n        this.firestore,\n        /* converter= */ null\n      );\n    }\n  }\n\n  get path(): string {\n    return this._query.path.canonicalString();\n  }\n\n  doc(pathString?: string): firestore.DocumentReference<T> {\n    validateBetweenNumberOfArgs('CollectionReference.doc', arguments, 0, 1);\n    // We allow omission of 'pathString' but explicitly prohibit passing in both\n    // 'undefined' and 'null'.\n    if (arguments.length === 0) {\n      pathString = AutoId.newId();\n    }\n    validateArgType(\n      'CollectionReference.doc',\n      'non-empty string',\n      1,\n      pathString\n    );\n    const path = ResourcePath.fromString(pathString!);\n    return DocumentReference.forPath<T>(\n      this._query.path.child(path),\n      this.firestore,\n      this._converter\n    );\n  }\n\n  add(value: T): Promise<firestore.DocumentReference<T>> {\n    validateExactNumberOfArgs('CollectionReference.add', arguments, 1);\n    const convertedValue = this._converter\n      ? this._converter.toFirestore(value)\n      : value;\n    validateArgType('CollectionReference.add', 'object', 1, convertedValue);\n    const docRef = this.doc();\n    return docRef.set(value).then(() => docRef);\n  }\n\n  withConverter<U>(\n    converter: firestore.FirestoreDataConverter<U>\n  ): firestore.CollectionReference<U> {\n    return new CollectionReference<U>(this._path, this.firestore, converter);\n  }\n}\n\nfunction validateSetOptions(\n  methodName: string,\n  options: firestore.SetOptions | undefined\n): firestore.SetOptions {\n  if (options === undefined) {\n    return {\n      merge: false\n    };\n  }\n\n  validateOptionNames(methodName, options, ['merge', 'mergeFields']);\n  validateNamedOptionalType(methodName, 'boolean', 'merge', options.merge);\n  validateOptionalArrayElements(\n    methodName,\n    'mergeFields',\n    'a string or a FieldPath',\n    options.mergeFields,\n    element =>\n      typeof element === 'string' || element instanceof ExternalFieldPath\n  );\n\n  if (options.mergeFields !== undefined && options.merge !== undefined) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      `Invalid options passed to function ${methodName}(): You cannot specify both \"merge\" ` +\n        `and \"mergeFields\".`\n    );\n  }\n\n  return options;\n}\n\nfunction validateSnapshotOptions(\n  methodName: string,\n  options: firestore.SnapshotOptions | undefined\n): firestore.SnapshotOptions {\n  if (options === undefined) {\n    return {};\n  }\n\n  validateOptionNames(methodName, options, ['serverTimestamps']);\n  validateNamedOptionalPropertyEquals(\n    methodName,\n    'options',\n    'serverTimestamps',\n    options.serverTimestamps,\n    ['estimate', 'previous', 'none']\n  );\n  return options;\n}\n\nfunction validateGetOptions(\n  methodName: string,\n  options: firestore.GetOptions | undefined\n): void {\n  validateOptionalArgType(methodName, 'object', 1, options);\n  if (options) {\n    validateOptionNames(methodName, options, ['source']);\n    validateNamedOptionalPropertyEquals(\n      methodName,\n      'options',\n      'source',\n      options.source,\n      ['default', 'server', 'cache']\n    );\n  }\n}\n\nfunction validateReference<T>(\n  methodName: string,\n  documentRef: firestore.DocumentReference<T>,\n  firestore: Firestore\n): DocumentKeyReference<T> {\n  if (!(documentRef instanceof DocumentKeyReference)) {\n    throw invalidClassError(methodName, 'DocumentReference', 1, documentRef);\n  } else if (documentRef.firestore !== firestore) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Provided document reference is from a different Firestore instance.'\n    );\n  } else {\n    return documentRef;\n  }\n}\n\n/**\n * Calculates the array of firestore.DocumentChange's for a given ViewSnapshot.\n *\n * Exported for testing.\n *\n * @param snapshot The ViewSnapshot that represents the expected state.\n * @param includeMetadataChanges Whether to include metadata changes.\n * @param converter A factory function that returns a QueryDocumentSnapshot.\n * @return An objecyt that matches the firestore.DocumentChange API.\n */\nexport function changesFromSnapshot<DocSnap>(\n  snapshot: ViewSnapshot,\n  includeMetadataChanges: boolean,\n  converter: (\n    doc: Document,\n    fromCache: boolean,\n    hasPendingWrite: boolean\n  ) => DocSnap\n): Array<{\n  type: firestore.DocumentChangeType;\n  doc: DocSnap;\n  oldIndex: number;\n  newIndex: number;\n}> {\n  if (snapshot.oldDocs.isEmpty()) {\n    // Special case the first snapshot because index calculation is easy and\n    // fast\n    let lastDoc: Document;\n    let index = 0;\n    return snapshot.docChanges.map(change => {\n      const doc = converter(\n        change.doc,\n        snapshot.fromCache,\n        snapshot.mutatedKeys.has(change.doc.key)\n      );\n      debugAssert(\n        change.type === ChangeType.Added,\n        'Invalid event type for first snapshot'\n      );\n      debugAssert(\n        !lastDoc || newQueryComparator(snapshot.query)(lastDoc, change.doc) < 0,\n        'Got added events in wrong order'\n      );\n      lastDoc = change.doc;\n      return {\n        type: 'added' as firestore.DocumentChangeType,\n        doc,\n        oldIndex: -1,\n        newIndex: index++\n      };\n    });\n  } else {\n    // A DocumentSet that is updated incrementally as changes are applied to use\n    // to lookup the index of a document.\n    let indexTracker = snapshot.oldDocs;\n    return snapshot.docChanges\n      .filter(\n        change => includeMetadataChanges || change.type !== ChangeType.Metadata\n      )\n      .map(change => {\n        const doc = converter(\n          change.doc,\n          snapshot.fromCache,\n          snapshot.mutatedKeys.has(change.doc.key)\n        );\n        let oldIndex = -1;\n        let newIndex = -1;\n        if (change.type !== ChangeType.Added) {\n          oldIndex = indexTracker.indexOf(change.doc.key);\n          debugAssert(oldIndex >= 0, 'Index for document not found');\n          indexTracker = indexTracker.delete(change.doc.key);\n        }\n        if (change.type !== ChangeType.Removed) {\n          indexTracker = indexTracker.add(change.doc);\n          newIndex = indexTracker.indexOf(change.doc.key);\n        }\n        return { type: resultChangeType(change.type), doc, oldIndex, newIndex };\n      });\n  }\n}\n\nfunction resultChangeType(type: ChangeType): firestore.DocumentChangeType {\n  switch (type) {\n    case ChangeType.Added:\n      return 'added';\n    case ChangeType.Modified:\n    case ChangeType.Metadata:\n      return 'modified';\n    case ChangeType.Removed:\n      return 'removed';\n    default:\n      return fail('Unknown change type: ' + type);\n  }\n}\n\n/**\n * Converts custom model object of type T into DocumentData by applying the\n * converter if it exists.\n *\n * This function is used when converting user objects to DocumentData\n * because we want to provide the user with a more specific error message if\n * their set() or fails due to invalid data originating from a toFirestore()\n * call.\n */\nexport function applyFirestoreDataConverter<T>(\n  converter: UntypedFirestoreDataConverter<T> | null,\n  value: T,\n  options?: firestore.SetOptions\n): firestore.DocumentData {\n  let convertedValue;\n  if (converter) {\n    if (options && (options.merge || options.mergeFields)) {\n      // Cast to `any` in order to satisfy the union type constraint on\n      // toFirestore().\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      convertedValue = (converter as any).toFirestore(value, options);\n    } else {\n      convertedValue = converter.toFirestore(value);\n    }\n  } else {\n    convertedValue = value as firestore.DocumentData;\n  }\n  return convertedValue;\n}\n\nfunction contains(obj: object, key: string): obj is { key: unknown } {\n  return Object.prototype.hasOwnProperty.call(obj, key);\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 { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { _FirebaseNamespace } from '@firebase/app-types/private';\nimport { Component, ComponentType, Provider } from '@firebase/component';\nimport {\n  CACHE_SIZE_UNLIMITED,\n  CollectionReference,\n  DocumentReference,\n  DocumentSnapshot,\n  Firestore,\n  Query,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  Transaction,\n  WriteBatch\n} from './api/database';\nimport { Blob } from './api/blob';\nimport { FieldPath } from './api/field_path';\nimport { GeoPoint } from './api/geo_point';\nimport { Timestamp } from './api/timestamp';\nimport { FieldValue } from './api/field_value';\n\nconst firestoreNamespace = {\n  Firestore,\n  GeoPoint,\n  Timestamp,\n  Blob,\n  Transaction,\n  WriteBatch,\n  DocumentReference,\n  DocumentSnapshot,\n  Query,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  CollectionReference,\n  FieldPath,\n  FieldValue,\n  setLogLevel: Firestore.setLogLevel,\n  CACHE_SIZE_UNLIMITED\n};\n\n/**\n * Configures Firestore as part of the Firebase SDK by calling registerService.\n *\n * @param firebase The FirebaseNamespace to register Firestore with\n * @param firestoreFactory A factory function that returns a new Firestore\n *    instance.\n */\nexport function configureForFirebase(\n  firebase: FirebaseNamespace,\n  firestoreFactory: (\n    app: FirebaseApp,\n    auth: Provider<FirebaseAuthInternalName>\n  ) => Firestore\n): void {\n  (firebase as _FirebaseNamespace).INTERNAL.registerComponent(\n    new Component(\n      'firestore',\n      container => {\n        const app = container.getProvider('app').getImmediate()!;\n        return firestoreFactory(app, container.getProvider('auth-internal'));\n      },\n      ComponentType.PUBLIC\n    ).setServiceProps({ ...firestoreNamespace })\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 { HttpsError, FunctionsErrorCode } from '@firebase/functions-types';\nimport { Serializer } from '../serializer';\nimport { HttpResponseBody } from './service';\n\n/**\n * Standard error codes for different ways a request can fail, as defined by:\n * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto\n *\n * This map is used primarily to convert from a backend error code string to\n * a client SDK error code string, and make sure it's in the supported set.\n */\nconst errorCodeMap: { [name: string]: FunctionsErrorCode } = {\n  OK: 'ok',\n  CANCELLED: 'cancelled',\n  UNKNOWN: 'unknown',\n  INVALID_ARGUMENT: 'invalid-argument',\n  DEADLINE_EXCEEDED: 'deadline-exceeded',\n  NOT_FOUND: 'not-found',\n  ALREADY_EXISTS: 'already-exists',\n  PERMISSION_DENIED: 'permission-denied',\n  UNAUTHENTICATED: 'unauthenticated',\n  RESOURCE_EXHAUSTED: 'resource-exhausted',\n  FAILED_PRECONDITION: 'failed-precondition',\n  ABORTED: 'aborted',\n  OUT_OF_RANGE: 'out-of-range',\n  UNIMPLEMENTED: 'unimplemented',\n  INTERNAL: 'internal',\n  UNAVAILABLE: 'unavailable',\n  DATA_LOSS: 'data-loss'\n};\n\n/**\n * An explicit error that can be thrown from a handler to send an error to the\n * client that called the function.\n */\nexport class HttpsErrorImpl extends Error implements HttpsError {\n  /**\n   * A standard error code that will be returned to the client. This also\n   * determines the HTTP status code of the response, as defined in code.proto.\n   */\n  readonly code: FunctionsErrorCode;\n\n  /**\n   * Extra data to be converted to JSON and included in the error response.\n   */\n  readonly details?: unknown;\n\n  constructor(code: FunctionsErrorCode, message?: string, details?: unknown) {\n    super(message);\n\n    // This is a workaround for a bug in TypeScript when extending Error:\n    // tslint:disable-next-line\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, HttpsErrorImpl.prototype);\n\n    this.code = code;\n    this.details = details;\n  }\n}\n\n/**\n * Takes an HTTP status code and returns the corresponding ErrorCode.\n * This is the standard HTTP status code -> error mapping defined in:\n * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto\n *\n * @param status An HTTP status code.\n * @return The corresponding ErrorCode, or ErrorCode.UNKNOWN if none.\n */\nfunction codeForHTTPStatus(status: number): FunctionsErrorCode {\n  // Make sure any successful status is OK.\n  if (status >= 200 && status < 300) {\n    return 'ok';\n  }\n  switch (status) {\n    case 0:\n      // This can happen if the server returns 500.\n      return 'internal';\n    case 400:\n      return 'invalid-argument';\n    case 401:\n      return 'unauthenticated';\n    case 403:\n      return 'permission-denied';\n    case 404:\n      return 'not-found';\n    case 409:\n      return 'aborted';\n    case 429:\n      return 'resource-exhausted';\n    case 499:\n      return 'cancelled';\n    case 500:\n      return 'internal';\n    case 501:\n      return 'unimplemented';\n    case 503:\n      return 'unavailable';\n    case 504:\n      return 'deadline-exceeded';\n    default: // ignore\n  }\n  return 'unknown';\n}\n\n/**\n * Takes an HTTP response and returns the corresponding Error, if any.\n */\nexport function _errorForResponse(\n  status: number,\n  bodyJSON: HttpResponseBody | null,\n  serializer: Serializer\n): Error | null {\n  let code = codeForHTTPStatus(status);\n\n  // Start with reasonable defaults from the status code.\n  let description: string = code;\n\n  let details: unknown = undefined;\n\n  // Then look through the body for explicit details.\n  try {\n    const errorJSON = bodyJSON && bodyJSON.error;\n    if (errorJSON) {\n      const status = errorJSON.status;\n      if (typeof status === 'string') {\n        if (!errorCodeMap[status]) {\n          // They must've included an unknown error code in the body.\n          return new HttpsErrorImpl('internal', 'internal');\n        }\n        code = errorCodeMap[status];\n\n        // TODO(klimt): Add better default descriptions for error enums.\n        // The default description needs to be updated for the new code.\n        description = status;\n      }\n\n      const message = errorJSON.message;\n      if (typeof message === 'string') {\n        description = message;\n      }\n\n      details = errorJSON.details;\n      if (details !== undefined) {\n        details = serializer.decode(details as {} | null);\n      }\n    }\n  } catch (e) {\n    // If we couldn't parse explicit error data, that's fine.\n  }\n\n  if (code === 'ok') {\n    // Technically, there's an edge case where a developer could explicitly\n    // return an error code of OK, and we will treat it as success, but that\n    // seems reasonable.\n    return null;\n  }\n\n  return new HttpsErrorImpl(code, description, details);\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 */\nimport { _FirebaseApp } from '@firebase/app-types/private';\nimport {\n  FirebaseMessaging,\n  FirebaseMessagingName\n} from '@firebase/messaging-types';\nimport {\n  FirebaseAuthInternal,\n  FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\n\n/**\n * The metadata that should be supplied with function calls.\n */\nexport interface Context {\n  authToken?: string;\n  instanceIdToken?: string;\n}\n\n/**\n * Helper class to get metadata that should be included with a function call.\n */\nexport class ContextProvider {\n  private auth: FirebaseAuthInternal | null = null;\n  private messaging: FirebaseMessaging | null = null;\n  constructor(\n    authProvider: Provider<FirebaseAuthInternalName>,\n    messagingProvider: Provider<FirebaseMessagingName>\n  ) {\n    this.auth = authProvider.getImmediate({ optional: true });\n    this.messaging = messagingProvider.getImmediate({\n      optional: true\n    });\n\n    if (!this.auth) {\n      authProvider.get().then(\n        auth => (this.auth = auth),\n        () => {\n          /* get() never rejects */\n        }\n      );\n    }\n\n    if (!this.messaging) {\n      messagingProvider.get().then(\n        messaging => (this.messaging = messaging),\n        () => {\n          /* get() never rejects */\n        }\n      );\n    }\n  }\n\n  async getAuthToken(): Promise<string | undefined> {\n    if (!this.auth) {\n      return undefined;\n    }\n\n    try {\n      const token = await this.auth.getToken();\n      if (!token) {\n        return undefined;\n      }\n      return token.accessToken;\n    } catch (e) {\n      // If there's any error when trying to get the auth token, leave it off.\n      return undefined;\n    }\n  }\n\n  async getInstanceIdToken(): Promise<string | undefined> {\n    if (\n      !this.messaging ||\n      !('Notification' in self) ||\n      Notification.permission !== 'granted'\n    ) {\n      return undefined;\n    }\n\n    try {\n      return this.messaging.getToken();\n    } catch (e) {\n      // We don't warn on this, because it usually means messaging isn't set up.\n      // console.warn('Failed to retrieve instance id token.', e);\n\n      // If there's any error when trying to get the token, leave it off.\n      return undefined;\n    }\n  }\n\n  async getContext(): Promise<Context> {\n    const authToken = await this.getAuthToken();\n    const instanceIdToken = await this.getInstanceIdToken();\n    return { authToken, instanceIdToken };\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 LONG_TYPE = 'type.googleapis.com/google.protobuf.Int64Value';\nconst UNSIGNED_LONG_TYPE = 'type.googleapis.com/google.protobuf.UInt64Value';\n\nfunction mapValues(\n  // { [k: string]: unknown } is no longer a wildcard assignment target after typescript 3.5\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  o: { [key: string]: any },\n  f: (arg0: unknown) => unknown\n): object {\n  const result: { [key: string]: unknown } = {};\n  for (const key in o) {\n    if (o.hasOwnProperty(key)) {\n      result[key] = f(o[key]);\n    }\n  }\n  return result;\n}\n\nexport class Serializer {\n  // Takes data and encodes it in a JSON-friendly way, such that types such as\n  // Date are preserved.\n  encode(data: unknown): unknown {\n    if (data == null) {\n      return null;\n    }\n    if (data instanceof Number) {\n      data = data.valueOf();\n    }\n    if (typeof data === 'number' && isFinite(data)) {\n      // Any number in JS is safe to put directly in JSON and parse as a double\n      // without any loss of precision.\n      return data;\n    }\n    if (data === true || data === false) {\n      return data;\n    }\n    if (Object.prototype.toString.call(data) === '[object String]') {\n      return data;\n    }\n    if (Array.isArray(data)) {\n      return data.map(x => this.encode(x));\n    }\n    if (typeof data === 'function' || typeof data === 'object') {\n      return mapValues(data as object, x => this.encode(x));\n    }\n    // If we got this far, the data is not encodable.\n    throw new Error('Data cannot be encoded in JSON: ' + data);\n  }\n\n  // Takes data that's been encoded in a JSON-friendly form and returns a form\n  // with richer datatypes, such as Dates, etc.\n  decode(json: unknown): unknown {\n    if (json == null) {\n      return json;\n    }\n    if ((json as { [key: string]: unknown })['@type']) {\n      switch ((json as { [key: string]: unknown })['@type']) {\n        case LONG_TYPE:\n        // Fall through and handle this the same as unsigned.\n        case UNSIGNED_LONG_TYPE: {\n          // Technically, this could work return a valid number for malformed\n          // data if there was a number followed by garbage. But it's just not\n          // worth all the extra code to detect that case.\n          const value = Number((json as { [key: string]: unknown })['value']);\n          if (isNaN(value)) {\n            throw new Error('Data cannot be decoded from JSON: ' + json);\n          }\n          return value;\n        }\n        default: {\n          throw new Error('Data cannot be decoded from JSON: ' + json);\n        }\n      }\n    }\n    if (Array.isArray(json)) {\n      return json.map(x => this.decode(x));\n    }\n    if (typeof json === 'function' || typeof json === 'object') {\n      return mapValues(json as object, x => this.decode(x as {} | null));\n    }\n    // Anything else is safe to return.\n    return json;\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 { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport {\n  FirebaseFunctions,\n  HttpsCallable,\n  HttpsCallableResult,\n  HttpsCallableOptions\n} from '@firebase/functions-types';\nimport { _errorForResponse, HttpsErrorImpl } from './error';\nimport { ContextProvider } from '../context';\nimport { Serializer } from '../serializer';\nimport { Provider } from '@firebase/component';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { FirebaseMessagingName } from '@firebase/messaging-types';\n\n/**\n * The response to an http request.\n */\ninterface HttpResponse {\n  status: number;\n  json: HttpResponseBody | null;\n}\n/**\n * Describes the shape of the HttpResponse body.\n * It makes functions that would otherwise take {} able to access the\n * possible elements in the body more easily\n */\nexport interface HttpResponseBody {\n  data?: unknown;\n  result?: unknown;\n  error?: {\n    message?: unknown;\n    status?: unknown;\n    details?: unknown;\n  };\n}\n\n/**\n * Returns a Promise that will be rejected after the given duration.\n * The error will be of type HttpsErrorImpl.\n *\n * @param millis Number of milliseconds to wait before rejecting.\n */\nfunction failAfter(\n  millis: number\n): {\n  timer: number | NodeJS.Timeout;\n  promise: Promise<never>;\n} {\n  let timer!: number | NodeJS.Timeout;\n  const promise = new Promise<never>((_, reject) => {\n    timer = setTimeout(() => {\n      reject(new HttpsErrorImpl('deadline-exceeded', 'deadline-exceeded'));\n    }, millis);\n  });\n\n  return {\n    timer,\n    promise\n  };\n}\n\n/**\n * The main class for the Firebase Functions SDK.\n */\nexport class Service implements FirebaseFunctions, FirebaseService {\n  private readonly contextProvider: ContextProvider;\n  private readonly serializer = new Serializer();\n  private emulatorOrigin: string | null = null;\n  private cancelAllRequests: Promise<void>;\n  private deleteService!: Function;\n\n  /**\n   * Creates a new Functions service for the given app and (optional) region.\n   * @param app_ The FirebaseApp to use.\n   * @param region_ The region to call functions in.\n   */\n  constructor(\n    private app_: FirebaseApp,\n    authProvider: Provider<FirebaseAuthInternalName>,\n    messagingProvider: Provider<FirebaseMessagingName>,\n    private region_: string = 'us-central1'\n  ) {\n    this.contextProvider = new ContextProvider(authProvider, messagingProvider);\n    // Cancels all ongoing requests when resolved.\n    this.cancelAllRequests = new Promise(resolve => {\n      this.deleteService = () => {\n        return resolve();\n      };\n    });\n  }\n\n  get app(): FirebaseApp {\n    return this.app_;\n  }\n\n  INTERNAL = {\n    delete: (): Promise<void> => {\n      return this.deleteService();\n    }\n  };\n\n  /**\n   * Returns the URL for a callable with the given name.\n   * @param name The name of the callable.\n   */\n  _url(name: string): string {\n    const projectId = this.app_.options.projectId;\n    const region = this.region_;\n    if (this.emulatorOrigin !== null) {\n      const origin = this.emulatorOrigin;\n      return `${origin}/${projectId}/${region}/${name}`;\n    }\n    return `https://${region}-${projectId}.cloudfunctions.net/${name}`;\n  }\n\n  /**\n   * Changes this instance to point to a Cloud Functions emulator running\n   * locally. See https://firebase.google.com/docs/functions/local-emulator\n   *\n   * @param origin The origin of the local emulator, such as\n   * \"http://localhost:5005\".\n   */\n  useFunctionsEmulator(origin: string): void {\n    this.emulatorOrigin = origin;\n  }\n\n  /**\n   * Returns a reference to the callable https trigger with the given name.\n   * @param name The name of the trigger.\n   */\n  httpsCallable(name: string, options?: HttpsCallableOptions): HttpsCallable {\n    return data => {\n      return this.call(name, data, options || {});\n    };\n  }\n\n  /**\n   * Does an HTTP POST and returns the completed response.\n   * @param url The url to post to.\n   * @param body The JSON body of the post.\n   * @param headers The HTTP headers to include in the request.\n   * @return A Promise that will succeed when the request finishes.\n   */\n  private async postJSON(\n    url: string,\n    body: {},\n    headers: Headers\n  ): Promise<HttpResponse> {\n    headers.append('Content-Type', 'application/json');\n\n    let response: Response;\n    try {\n      response = await fetch(url, {\n        method: 'POST',\n        body: JSON.stringify(body),\n        headers\n      });\n    } catch (e) {\n      // This could be an unhandled error on the backend, or it could be a\n      // network error. There's no way to know, since an unhandled error on the\n      // backend will fail to set the proper CORS header, and thus will be\n      // treated as a network error by fetch.\n      return {\n        status: 0,\n        json: null\n      };\n    }\n    let json: {} | null = null;\n    try {\n      json = await response.json();\n    } catch (e) {\n      // If we fail to parse JSON, it will fail the same as an empty body.\n    }\n    return {\n      status: response.status,\n      json\n    };\n  }\n\n  /**\n   * Calls a callable function asynchronously and returns the result.\n   * @param name The name of the callable trigger.\n   * @param data The data to pass as params to the function.s\n   */\n  private async call(\n    name: string,\n    data: unknown,\n    options: HttpsCallableOptions\n  ): Promise<HttpsCallableResult> {\n    const url = this._url(name);\n\n    // Encode any special types, such as dates, in the input data.\n    data = this.serializer.encode(data);\n    const body = { data };\n\n    // Add a header for the authToken.\n    const headers = new Headers();\n    const context = await this.contextProvider.getContext();\n    if (context.authToken) {\n      headers.append('Authorization', 'Bearer ' + context.authToken);\n    }\n    if (context.instanceIdToken) {\n      headers.append('Firebase-Instance-ID-Token', context.instanceIdToken);\n    }\n\n    // Default timeout to 70s, but let the options override it.\n    const timeout = options.timeout || 70000;\n\n    const { timer, promise: failAfterPromise } = failAfter(timeout);\n\n    const response = await Promise.race([\n      clearTimeoutWrapper(timer, this.postJSON(url, body, headers)),\n      failAfterPromise,\n      clearTimeoutWrapper(timer, this.cancelAllRequests)\n    ]);\n\n    // If service was deleted, interrupted response throws an error.\n    if (!response) {\n      throw new HttpsErrorImpl(\n        'cancelled',\n        'Firebase Functions instance was deleted.'\n      );\n    }\n\n    // Check for an error status, regardless of http status.\n    const error = _errorForResponse(\n      response.status,\n      response.json,\n      this.serializer\n    );\n    if (error) {\n      throw error;\n    }\n\n    if (!response.json) {\n      throw new HttpsErrorImpl(\n        'internal',\n        'Response is not valid JSON object.'\n      );\n    }\n\n    let responseData = response.json.data;\n    // TODO(klimt): For right now, allow \"result\" instead of \"data\", for\n    // backwards compatibility.\n    if (typeof responseData === 'undefined') {\n      responseData = response.json.result;\n    }\n    if (typeof responseData === 'undefined') {\n      // Consider the response malformed.\n      throw new HttpsErrorImpl('internal', 'Response is missing data field.');\n    }\n\n    // Decode any special types, such as dates, in the returned data.\n    const decodedData = this.serializer.decode(responseData as {} | null);\n\n    return { data: decodedData };\n  }\n}\n\nasync function clearTimeoutWrapper<T>(\n  timer: number | NodeJS.Timeout,\n  promise: Promise<T>\n): Promise<T> {\n  const result = await promise;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  clearTimeout(timer as any);\n  return result;\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 { 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<ErrorCode, ErrorParams>(\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 & 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 { AppConfig } from '../interfaces/app-config';\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';\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<FirebaseError> {\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<Response>\n): Promise<Response> {\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 { AppConfig } from '../interfaces/app-config';\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';\n\nexport async function createInstallationRequest(\n  appConfig: AppConfig,\n  { fid }: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n  const endpoint = getInstallationsEndpoint(appConfig);\n\n  const headers = getHeaders(appConfig);\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<void> {\n  return new Promise<void>(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/app-config';\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/app-config';\nimport { IdChangeCallbackFn } from '../functions';\n\nconst fidChangeCallbacks: Map<string, Set<IdChangeCallbackFn>> = 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 { DB, openDb } from 'idb';\nimport { AppConfig } from '../interfaces/app-config';\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\nlet dbPromise: Promise<DB> | null = null;\nfunction getDbPromise(): Promise<DB> {\n  if (!dbPromise) {\n    dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDB => {\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 (upgradeDB.oldVersion) {\n        case 0:\n          upgradeDB.createObjectStore(OBJECT_STORE_NAME);\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<InstallationEntry | undefined> {\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);\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set<ValueType extends InstallationEntry>(\n  appConfig: AppConfig,\n  value: ValueType\n): Promise<ValueType> {\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);\n  await objectStore.put(value, key);\n  await tx.complete;\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<void> {\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.complete;\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<ValueType extends InstallationEntry | undefined>(\n  appConfig: AppConfig,\n  updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise<ValueType> {\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(key);\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.complete;\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<void> {\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.complete;\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 '../api/create-installation-request';\nimport { AppConfig } from '../interfaces/app-config';\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<RegisteredInstallationEntry>;\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  appConfig: AppConfig\n): Promise<InstallationEntryWithRegistrationPromise> {\n  let registrationPromise: Promise<RegisteredInstallationEntry> | undefined;\n\n  const installationEntry = await update(appConfig, oldEntry => {\n    const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n    const entryWithPromise = triggerRegistrationIfNecessary(\n      appConfig,\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  appConfig: AppConfig,\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      appConfig,\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(appConfig)\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  appConfig: AppConfig,\n  installationEntry: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n  try {\n    const registeredInstallationEntry = await createInstallationRequest(\n      appConfig,\n      installationEntry\n    );\n    return set(appConfig, registeredInstallationEntry);\n  } catch (e) {\n    if (isServerError(e) && e.serverCode === 409) {\n      // Server returned a \"FID can not be used\" error.\n      // Generate a new ID next time.\n      await remove(appConfig);\n    } else {\n      // Registration failed. Set FID as not registered.\n      await set(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  appConfig: AppConfig\n): Promise<RegisteredInstallationEntry> {\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(appConfig);\n  while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n    // createInstallation request still in progress.\n    await sleep(100);\n\n    entry = await updateInstallationRequest(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 {\n      installationEntry,\n      registrationPromise\n    } = await getInstallationEntry(appConfig);\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<InstallationEntry> {\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 { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\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';\n\nexport async function generateAuthTokenRequest(\n  { appConfig, platformLoggerProvider }: FirebaseDependencies,\n  installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n  const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n  const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n  // If platform logger exists, add the platform info string to the header.\n  const platformLogger = platformLoggerProvider.getImmediate({\n    optional: true\n  });\n  if (platformLogger) {\n    headers.append('x-firebase-client', platformLogger.getPlatformInfoString());\n  }\n\n  const body = {\n    installation: {\n      sdkVersion: PACKAGE_VERSION\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 = extractAuthTokenInfoFromResponse(\n      responseValue\n    );\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 '../api/generate-auth-token-request';\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\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  dependencies: FirebaseDependencies,\n  forceRefresh = false\n): Promise<CompletedAuthToken> {\n  let tokenPromise: Promise<CompletedAuthToken> | undefined;\n  const entry = await update(dependencies.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(dependencies, 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(dependencies, 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  dependencies: FirebaseDependencies,\n  forceRefresh: boolean\n): Promise<CompletedAuthToken> {\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(dependencies.appConfig);\n  while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n    // generateAuthToken still in progress.\n    await sleep(100);\n\n    entry = await updateAuthTokenRequest(dependencies.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(dependencies, 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<RegisteredInstallationEntry> {\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  dependencies: FirebaseDependencies,\n  installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n  try {\n    const authToken = await generateAuthTokenRequest(\n      dependencies,\n      installationEntry\n    );\n    const updatedInstallationEntry: RegisteredInstallationEntry = {\n      ...installationEntry,\n      authToken\n    };\n    await set(dependencies.appConfig, updatedInstallationEntry);\n    return authToken;\n  } catch (e) {\n    if (isServerError(e) && (e.serverCode === 401 || e.serverCode === 404)) {\n      // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n      // Generate a new ID next time.\n      await remove(dependencies.appConfig);\n    } else {\n      const updatedInstallationEntry: RegisteredInstallationEntry = {\n        ...installationEntry,\n        authToken: { requestStatus: RequestStatus.NOT_STARTED }\n      };\n      await set(dependencies.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 { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getId(\n  dependencies: FirebaseDependencies\n): Promise<string> {\n  const { installationEntry, registrationPromise } = await getInstallationEntry(\n    dependencies.appConfig\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(dependencies).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 { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getToken(\n  dependencies: FirebaseDependencies,\n  forceRefresh = false\n): Promise<string> {\n  await completeInstallationRegistration(dependencies.appConfig);\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(dependencies, forceRefresh);\n  return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n  appConfig: AppConfig\n): Promise<void> {\n  const { registrationPromise } = await getInstallationEntry(appConfig);\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/app-config';\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<void> {\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 '../api/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport async function deleteInstallation(\n  dependencies: FirebaseDependencies\n): Promise<void> {\n  const { appConfig } = dependencies;\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 { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport type IdChangeCallbackFn = (installationId: string) => void;\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 */\nexport function onIdChange(\n  { appConfig }: FirebaseDependencies,\n  callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n  addCallback(appConfig, callback);\n\n  return () => {\n    removeCallback(appConfig, callback);\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 { FirebaseApp, FirebaseOptions } from '@firebase/app-types';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/app-config';\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<keyof FirebaseOptions> = [\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 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 firebase from '@firebase/app';\nimport {\n  _FirebaseNamespace,\n  FirebaseService\n} from '@firebase/app-types/private';\nimport { Component, ComponentType } from '@firebase/component';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport {\n  deleteInstallation,\n  getId,\n  getToken,\n  IdChangeCallbackFn,\n  IdChangeUnsubscribeFn,\n  onIdChange\n} from './functions';\nimport { extractAppConfig } from './helpers/extract-app-config';\nimport { FirebaseDependencies } from './interfaces/firebase-dependencies';\n\nimport { name, version } from '../package.json';\n\nexport function registerInstallations(instance: _FirebaseNamespace): void {\n  const installationsName = 'installations';\n\n  instance.INTERNAL.registerComponent(\n    new Component(\n      installationsName,\n      container => {\n        const app = container.getProvider('app').getImmediate();\n\n        // Throws if app isn't configured properly.\n        const appConfig = extractAppConfig(app);\n        const platformLoggerProvider = container.getProvider('platform-logger');\n        const dependencies: FirebaseDependencies = {\n          appConfig,\n          platformLoggerProvider\n        };\n\n        const installations: FirebaseInstallations & FirebaseService = {\n          app,\n          getId: () => getId(dependencies),\n          getToken: (forceRefresh?: boolean) =>\n            getToken(dependencies, forceRefresh),\n          delete: () => deleteInstallation(dependencies),\n          onIdChange: (callback: IdChangeCallbackFn): IdChangeUnsubscribeFn =>\n            onIdChange(dependencies, callback)\n        };\n        return installations;\n      },\n      ComponentType.PUBLIC\n    )\n  );\n\n  instance.registerVersion(name, version);\n}\n\nregisterInstallations(firebase as _FirebaseNamespace);\n\n/**\n * Define extension behavior of `registerInstallations`\n */\ndeclare module '@firebase/app-types' {\n  interface FirebaseNamespace {\n    installations(app?: FirebaseApp): FirebaseInstallations;\n  }\n  interface FirebaseApp {\n    installations(): FirebaseInstallations;\n  }\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  // 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<TokenDetails | null> {\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 (indexedDB as {\n      databases(): Promise<Array<{ name: string; version: number }>>;\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, async db => {\n    if (db.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 = db.transaction.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 (db.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 (db.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 (db.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  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 { 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<string> {\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\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<string> {\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\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<void> {\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\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<Headers> {\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 { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n  arrayToBase64,\n  base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from '../helpers/idb-manager';\nimport { requestDeleteToken, requestGetToken, requestUpdateToken } from './api';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\n/** UpdateRegistration will be called once every week. */\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getToken(\n  firebaseDependencies: FirebaseInternalDependencies,\n  swRegistration: ServiceWorkerRegistration,\n  vapidKey: string\n): Promise<string> {\n  if (Notification.permission !== 'granted') {\n    throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n  }\n\n  // If a PushSubscription exists it's returned, otherwise a new subscription is generated and\n  // returned.\n  const pushSubscription = await getPushSubscription(swRegistration, vapidKey);\n  const tokenDetails = await dbGet(firebaseDependencies);\n\n  const subscriptionOptions: SubscriptionOptions = {\n    vapidKey,\n    swScope: swRegistration.scope,\n    endpoint: pushSubscription.endpoint,\n    auth: arrayToBase64(pushSubscription.getKey('auth')!),\n    p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n  };\n\n  if (!tokenDetails) {\n    // No token, get a new one.\n    return getNewToken(firebaseDependencies, subscriptionOptions);\n  } else if (\n    !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n  ) {\n    // Invalid token, get a new one.\n    try {\n      await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n    } catch (e) {\n      // Suppress errors because of #2364\n      console.warn(e);\n    }\n\n    return getNewToken(firebaseDependencies, subscriptionOptions);\n  } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n    // Weekly token refresh\n    return updateToken(\n      {\n        token: tokenDetails.token,\n        createTime: Date.now(),\n        subscriptionOptions\n      },\n      firebaseDependencies,\n      swRegistration\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 deleteToken(\n  firebaseDependencies: FirebaseInternalDependencies,\n  swRegistration: ServiceWorkerRegistration\n): Promise<boolean> {\n  const tokenDetails = await dbGet(firebaseDependencies);\n  if (tokenDetails) {\n    await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n    await dbRemove(firebaseDependencies);\n  }\n\n  // Unsubscribe from the push subscription.\n  const pushSubscription = await 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  tokenDetails: TokenDetails,\n  firebaseDependencies: FirebaseInternalDependencies,\n  swRegistration: ServiceWorkerRegistration\n): Promise<string> {\n  try {\n    const updatedToken = await requestUpdateToken(\n      firebaseDependencies,\n      tokenDetails\n    );\n\n    const updatedTokenDetails: TokenDetails = {\n      ...tokenDetails,\n      token: updatedToken,\n      createTime: Date.now()\n    };\n\n    await dbSet(firebaseDependencies, updatedTokenDetails);\n    return updatedToken;\n  } catch (e) {\n    await deleteToken(firebaseDependencies, swRegistration);\n    throw e;\n  }\n}\n\nasync function getNewToken(\n  firebaseDependencies: FirebaseInternalDependencies,\n  subscriptionOptions: SubscriptionOptions\n): Promise<string> {\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<PushSubscription> {\n  const subscription = await swRegistration.pushManager.getSubscription();\n  if (subscription) {\n    return subscription;\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 '@firebase/messaging-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  } 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  if (!messagePayloadInternal.fcmOptions) {\n    return;\n  }\n\n  payload.fcmOptions = {};\n\n  const link = messagePayloadInternal.fcmOptions!.link;\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<void> {\n  return new Promise<void>(resolve => {\n    setTimeout(resolve, ms);\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 { DEFAULT_VAPID_KEY, FCM_MSG, TAG } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseMessaging, MessagePayload } from '@firebase/messaging-types';\nimport {\n  MessagePayloadInternal,\n  MessageType,\n  NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport { NextFn, Observer, Unsubscribe } from '@firebase/util';\nimport { deleteToken, getToken } from '../core/token-management';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { dbGet } from '../helpers/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport type BgMessageHandler = (payload: MessagePayload) => unknown;\n\nexport class SwController implements FirebaseMessaging, FirebaseService {\n  // A boolean flag to determine wether an app is using onBackgroundMessage or\n  // setBackgroundMessageHandler. onBackgroundMessage will receive a MessagePayload regardless of if\n  // a notification is displayed. Whereas, setBackgroundMessageHandler will swallow the\n  // MessagePayload if a NotificationPayload is included.\n  private isOnBackgroundMessageUsed: boolean | null = null;\n  private vapidKey: string | null = null;\n  private bgMessageHandler:\n    | BgMessageHandler\n    | null\n    | NextFn<MessagePayload>\n    | Observer<MessagePayload> = null;\n\n  constructor(\n    private readonly firebaseDependencies: FirebaseInternalDependencies\n  ) {\n    self.addEventListener('push', e => {\n      e.waitUntil(this.onPush(e));\n    });\n    self.addEventListener('pushsubscriptionchange', e => {\n      e.waitUntil(this.onSubChange(e));\n    });\n    self.addEventListener('notificationclick', e => {\n      e.waitUntil(this.onNotificationClick(e));\n    });\n  }\n\n  get app(): FirebaseApp {\n    return this.firebaseDependencies.app;\n  }\n\n  /**\n   * @deprecated. Use onBackgroundMessage(nextOrObserver: NextFn<object> | Observer<object>):\n   * Unsubscribe instead.\n   *\n   * Calling setBackgroundMessageHandler will opt in to some specific behaviors.\n   *\n   * 1.) If a notification doesn't need to be shown due to a window already being visible, then push\n   * messages will be sent to the page. 2.) If a notification needs to be shown, and the message\n   * contains no notification data this method will be called and the promise it returns will be\n   * passed to event.waitUntil. If you do not set this callback then all push messages will let and\n   * the developer can handle them in a their own 'push' event callback\n   *\n   * @param callback The callback to be called when a push message is received and a notification\n   * must be shown. The callback will be given the data from the push message.\n   */\n  setBackgroundMessageHandler(callback: BgMessageHandler): void {\n    this.isOnBackgroundMessageUsed = false;\n\n    if (!callback || typeof callback !== 'function') {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_BG_HANDLER);\n    }\n\n    this.bgMessageHandler = callback;\n  }\n\n  onBackgroundMessage(\n    nextOrObserver: NextFn<object> | Observer<object>\n  ): Unsubscribe {\n    this.isOnBackgroundMessageUsed = true;\n    this.bgMessageHandler = nextOrObserver;\n\n    return () => {\n      this.bgMessageHandler = null;\n    };\n  }\n\n  // TODO: Remove getToken from SW Controller. Calling this from an old SW can cause all kinds of\n  // trouble.\n  async getToken(): Promise<string> {\n    if (!this.vapidKey) {\n      // Call getToken using the current VAPID key if there already is a token. This is needed\n      // because usePublicVapidKey was not available in SW. It will be removed when vapidKey becomes\n      // a parameter of getToken, or when getToken is removed from SW.\n      const tokenDetails = await dbGet(this.firebaseDependencies);\n      this.vapidKey =\n        tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n    }\n\n    return getToken(\n      this.firebaseDependencies,\n      self.registration,\n      this.vapidKey\n    );\n  }\n\n  // TODO: Remove deleteToken from SW Controller. Calling this from an old SW can cause all kinds of\n  // trouble.\n  deleteToken(): Promise<boolean> {\n    return deleteToken(this.firebaseDependencies, self.registration);\n  }\n\n  requestPermission(): Promise<void> {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n  }\n\n  // TODO: Remove this together with getToken from SW Controller.\n  usePublicVapidKey(vapidKey: string): void {\n    if (this.vapidKey !== null) {\n      throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n    }\n\n    if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n    }\n\n    this.vapidKey = vapidKey;\n  }\n\n  useServiceWorker(): void {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n  }\n\n  onMessage(): Unsubscribe {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n  }\n\n  onTokenRefresh(): Unsubscribe {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n  }\n\n  /**\n   * A handler for push events that shows notifications based on the content of the payload.\n   *\n   * The payload must be a JSON-encoded Object with a `notification` key. The value of the\n   * `notification` property will be used as the NotificationOptions object passed to\n   * showNotification. Additionally, the `title` property of the notification object will be used as\n   * the title.\n   *\n   * If there is no notification data in the payload then no notification will be shown.\n   */\n  async onPush(event: PushEvent): Promise<void> {\n    const internalPayload = getMessagePayloadInternal(event);\n    if (!internalPayload) {\n      console.debug(\n        TAG +\n          'failed to get parsed MessagePayload from the PushEvent. Skip handling the push.'\n      );\n      return;\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 and pass to onBackgroundMessage hook\n    let isNotificationShown = false;\n    if (!!internalPayload.notification) {\n      await showNotification(wrapInternalPayload(internalPayload));\n      isNotificationShown = true;\n    }\n\n    // MessagePayload is only passed to `onBackgroundMessage`. Skip passing MessagePayload for\n    // the legacy `setBackgroundMessageHandler` to preserve the SDK behaviors.\n    if (\n      isNotificationShown === true &&\n      this.isOnBackgroundMessageUsed === false\n    ) {\n      return;\n    }\n\n    if (!!this.bgMessageHandler) {\n      const payload = externalizePayload(internalPayload);\n\n      if (typeof this.bgMessageHandler === 'function') {\n        this.bgMessageHandler(payload);\n      } else {\n        this.bgMessageHandler.next(payload);\n      }\n    }\n  }\n\n  async onSubChange(event: PushSubscriptionChangeEvent): Promise<void> {\n    const { newSubscription } = event;\n    if (!newSubscription) {\n      // Subscription revoked, delete token\n      await deleteToken(this.firebaseDependencies, self.registration);\n      return;\n    }\n\n    const tokenDetails = await dbGet(this.firebaseDependencies);\n    await deleteToken(this.firebaseDependencies, self.registration);\n    await getToken(\n      this.firebaseDependencies,\n      self.registration,\n      tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY\n    );\n  }\n\n  async onNotificationClick(event: NotificationEvent): Promise<void> {\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    const link = getLink(internalPayload);\n    if (!link) {\n      return;\n    }\n\n    let client = await getWindowClient(link);\n    if (!client) {\n      // Unable to find window client so need to open one. This also focuses the opened client.\n      client = await self.clients.openWindow(link);\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}\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: string): Promise<WindowClient | null> {\n  // Use URL to normalize the URL when comparing to windowClients. This at least handles whether to\n  // include trailing slashes or not\n  const parsedURL = new URL(url, self.location.href);\n\n  const clientList = await getClientList();\n\n  for (const client of clientList) {\n    const parsedClientUrl = new URL(client.url, self.location.href);\n    if (parsedClientUrl.host === parsedURL.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<WindowClient[]> {\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<WindowClient[]>;\n}\n\nfunction showNotification(\n  notificationPayloadInternal: NotificationPayloadInternal\n): Promise<void> {\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 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 {\n  CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n  CONSOLE_CAMPAIGN_ID,\n  CONSOLE_CAMPAIGN_NAME,\n  CONSOLE_CAMPAIGN_TIME,\n  DEFAULT_SW_PATH,\n  DEFAULT_SW_SCOPE,\n  DEFAULT_VAPID_KEY\n} from '../util/constants';\nimport {\n  ConsoleMessageData,\n  MessagePayloadInternal,\n  MessageType\n} from '../interfaces/internal-message-payload';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { NextFn, Observer, Unsubscribe } from '@firebase/util';\nimport { deleteToken, getToken } from '../core/token-management';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { isConsoleMessage } from '../helpers/is-console-message';\n\nexport class WindowController implements FirebaseMessaging, FirebaseService {\n  private vapidKey: string | null = null;\n  private swRegistration?: ServiceWorkerRegistration;\n  private onMessageCallback: NextFn<object> | Observer<object> | null = null;\n\n  constructor(\n    private readonly firebaseDependencies: FirebaseInternalDependencies\n  ) {\n    navigator.serviceWorker.addEventListener('message', e =>\n      this.messageEventListener(e)\n    );\n  }\n\n  get app(): FirebaseApp {\n    return this.firebaseDependencies.app;\n  }\n\n  private async messageEventListener(event: MessageEvent): Promise<void> {\n    const internalPayload = event.data as MessagePayloadInternal;\n\n    if (!internalPayload.isFirebaseMessaging) {\n      return;\n    }\n\n    // onMessageCallback is either a function or observer/subscriber.\n    // TODO: in the modularization release, have onMessage handle type MessagePayload as supposed to\n    // the legacy payload where some fields are in snake cases.\n    if (\n      this.onMessageCallback &&\n      internalPayload.messageType === MessageType.PUSH_RECEIVED\n    ) {\n      if (typeof this.onMessageCallback === 'function') {\n        this.onMessageCallback(\n          stripInternalFields(Object.assign({}, internalPayload))\n        );\n      } else {\n        this.onMessageCallback.next(Object.assign({}, internalPayload));\n      }\n    }\n\n    const dataPayload = internalPayload.data;\n\n    if (\n      isConsoleMessage(dataPayload) &&\n      dataPayload[CONSOLE_CAMPAIGN_ANALYTICS_ENABLED] === '1'\n    ) {\n      await this.logEvent(internalPayload.messageType!, dataPayload);\n    }\n  }\n\n  getVapidKey(): string | null {\n    return this.vapidKey;\n  }\n\n  getSwReg(): ServiceWorkerRegistration | undefined {\n    return this.swRegistration;\n  }\n\n  async getToken(options?: {\n    vapidKey?: string;\n    serviceWorkerRegistration?: ServiceWorkerRegistration;\n  }): Promise<string> {\n    if (Notification.permission === 'default') {\n      await Notification.requestPermission();\n    }\n\n    if (Notification.permission !== 'granted') {\n      throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n    }\n\n    await this.updateVapidKey(options?.vapidKey);\n    await this.updateSwReg(options?.serviceWorkerRegistration);\n\n    return getToken(\n      this.firebaseDependencies,\n      this.swRegistration!,\n      this.vapidKey!\n    );\n  }\n\n  async updateVapidKey(vapidKey?: string | undefined): Promise<void> {\n    if (!!vapidKey) {\n      this.vapidKey = vapidKey;\n    } else if (!this.vapidKey) {\n      this.vapidKey = DEFAULT_VAPID_KEY;\n    }\n  }\n\n  async updateSwReg(\n    swRegistration?: ServiceWorkerRegistration | undefined\n  ): Promise<void> {\n    if (!swRegistration && !this.swRegistration) {\n      await this.registerDefaultSw();\n    }\n\n    if (!swRegistration && !!this.swRegistration) {\n      return;\n    }\n\n    if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_SW_REGISTRATION);\n    }\n\n    this.swRegistration = swRegistration;\n  }\n\n  private async registerDefaultSw(): Promise<void> {\n    try {\n      this.swRegistration = await navigator.serviceWorker.register(\n        DEFAULT_SW_PATH,\n        {\n          scope: DEFAULT_SW_SCOPE\n        }\n      );\n\n      // The timing when browser updates sw when sw has an update is unreliable by my experiment. It\n      // leads to version conflict when the SDK upgrades to a newer version in the main page, but sw\n      // is stuck with the old version. For example,\n      // https://github.com/firebase/firebase-js-sdk/issues/2590 The following line reliably updates\n      // sw if there was an update.\n      this.swRegistration.update().catch(() => {\n        /* it is non blocking and we don't care if it failed */\n      });\n    } catch (e) {\n      throw ERROR_FACTORY.create(ErrorCode.FAILED_DEFAULT_REGISTRATION, {\n        browserErrorMessage: e.message\n      });\n    }\n  }\n\n  async deleteToken(): Promise<boolean> {\n    if (!this.swRegistration) {\n      await this.registerDefaultSw();\n    }\n\n    return deleteToken(this.firebaseDependencies, this.swRegistration!);\n  }\n\n  /**\n   * Request permission if it is not currently granted.\n   *\n   * @return Resolves if the permission was granted, rejects otherwise.\n   *\n   * @deprecated Use Notification.requestPermission() instead.\n   * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\n   */\n  async requestPermission(): Promise<void> {\n    if (Notification.permission === 'granted') {\n      return;\n    }\n\n    const permissionResult = await Notification.requestPermission();\n    if (permissionResult === 'granted') {\n      return;\n    } else if (permissionResult === 'denied') {\n      throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n    } else {\n      throw ERROR_FACTORY.create(ErrorCode.PERMISSION_DEFAULT);\n    }\n  }\n\n  /**\n   * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\n   * ServiceWorkerRegistration;}): Promise<string> instead.\n   */\n  usePublicVapidKey(vapidKey: string): void {\n    if (this.vapidKey !== null) {\n      throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n    }\n\n    if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n    }\n\n    this.vapidKey = vapidKey;\n  }\n\n  /**\n   * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\n   * ServiceWorkerRegistration;}): Promise<string> instead.\n   */\n  useServiceWorker(swRegistration: ServiceWorkerRegistration): void {\n    if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_SW_REGISTRATION);\n    }\n\n    if (this.swRegistration) {\n      throw ERROR_FACTORY.create(ErrorCode.USE_SW_AFTER_GET_TOKEN);\n    }\n\n    this.swRegistration = swRegistration;\n  }\n\n  /**\n   * @param nextOrObserver An observer object or a function triggered on message.\n   *\n   * @return The unsubscribe function for the observer.\n   */\n  onMessage(nextOrObserver: NextFn<object> | Observer<object>): Unsubscribe {\n    this.onMessageCallback = nextOrObserver;\n\n    return () => {\n      this.onMessageCallback = null;\n    };\n  }\n\n  setBackgroundMessageHandler(): void {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n  }\n\n  onBackgroundMessage(): Unsubscribe {\n    throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n  }\n\n  /**\n   * @deprecated No-op. It was initially designed with token rotation requests from server in mind.\n   * However, the plan to implement such feature was abandoned.\n   */\n  onTokenRefresh(): Unsubscribe {\n    return () => {};\n  }\n\n  private async logEvent(\n    messageType: MessageType,\n    data: ConsoleMessageData\n  ): Promise<void> {\n    const eventType = getEventType(messageType);\n    const analytics = await this.firebaseDependencies.analyticsProvider.get();\n    analytics.logEvent(eventType, {\n      /* eslint-disable camelcase */\n      message_id: data[CONSOLE_CAMPAIGN_ID],\n      message_name: data[CONSOLE_CAMPAIGN_NAME],\n      message_time: data[CONSOLE_CAMPAIGN_TIME],\n      message_device_time: Math.floor(Date.now() / 1000)\n      /* eslint-enable camelcase */\n    });\n  }\n}\n\nfunction getEventType(messageType: MessageType): string {\n  switch (messageType) {\n    case MessageType.NOTIFICATION_CLICKED:\n      return 'notification_open';\n    case MessageType.PUSH_RECEIVED:\n      return 'notification_foreground';\n    default:\n      throw new Error();\n  }\n}\n\nfunction stripInternalFields(\n  internalPayload: MessagePayloadInternal\n): MessagePayloadInternal {\n  delete internalPayload.messageType;\n  delete internalPayload.isFirebaseMessaging;\n  return internalPayload;\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 { ErrorFactory } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from '../constants';\n\nexport const enum ErrorCode {\n  TRACE_STARTED_BEFORE = 'trace started',\n  TRACE_STOPPED_BEFORE = 'trace stopped',\n  NO_WINDOW = 'no window',\n  NO_APP_ID = 'no app id',\n  NO_PROJECT_ID = 'no project id',\n  NO_API_KEY = 'no api key',\n  INVALID_CC_LOG = 'invalid cc log',\n  FB_NOT_DEFAULT = 'FB not default',\n  RC_NOT_OK = 'RC response not ok',\n  INVALID_ATTRIBUTE_NAME = 'invalid attribute name',\n  INVALID_ATTRIBUTE_VALUE = 'invalid attribute value',\n  INVALID_CUSTOM_METRIC_NAME = 'invalid custom metric name',\n  INVALID_STRING_MERGER_PARAMETER = 'invalid String merger input'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n  [ErrorCode.TRACE_STARTED_BEFORE]: 'Trace {$traceName} was started before.',\n  [ErrorCode.TRACE_STOPPED_BEFORE]: 'Trace {$traceName} is not running.',\n  [ErrorCode.NO_WINDOW]: 'Window is not available.',\n  [ErrorCode.NO_APP_ID]: 'App id is not available.',\n  [ErrorCode.NO_PROJECT_ID]: 'Project id is not available.',\n  [ErrorCode.NO_API_KEY]: 'Api key is not available.',\n  [ErrorCode.INVALID_CC_LOG]: 'Attempted to queue invalid cc event',\n  [ErrorCode.FB_NOT_DEFAULT]:\n    'Performance can only start when Firebase app instance is the default one.',\n  [ErrorCode.RC_NOT_OK]: 'RC response is not ok',\n  [ErrorCode.INVALID_ATTRIBUTE_NAME]:\n    'Attribute name {$attributeName} is invalid.',\n  [ErrorCode.INVALID_ATTRIBUTE_VALUE]:\n    'Attribute value {$attributeValue} is invalid.',\n  [ErrorCode.INVALID_CUSTOM_METRIC_NAME]:\n    'Custom metric name {$customMetricName} is invalid',\n  [ErrorCode.INVALID_STRING_MERGER_PARAMETER]:\n    'Input for String merger is invalid, contact support team to resolve.'\n};\n\ninterface ErrorParams {\n  [ErrorCode.TRACE_STARTED_BEFORE]: { traceName: string };\n  [ErrorCode.TRACE_STOPPED_BEFORE]: { traceName: string };\n  [ErrorCode.INVALID_ATTRIBUTE_NAME]: { attributeName: string };\n  [ErrorCode.INVALID_ATTRIBUTE_VALUE]: { attributeValue: string };\n  [ErrorCode.INVALID_CUSTOM_METRIC_NAME]: { customMetricName: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<ErrorCode, ErrorParams>(\n  SERVICE,\n  SERVICE_NAME,\n  ERROR_DESCRIPTION_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 { ERROR_FACTORY, ErrorCode } from '../utils/errors';\n\ndeclare global {\n  interface Window {\n    PerformanceObserver: typeof PerformanceObserver;\n    perfMetrics?: { onFirstInputDelay: Function };\n  }\n}\n\nlet apiInstance: Api | undefined;\nlet windowInstance: Window | undefined;\n\nexport type EntryType =\n  | 'mark'\n  | 'measure'\n  | 'paint'\n  | 'resource'\n  | 'frame'\n  | 'navigation';\n\n/**\n * This class holds a reference to various browser related objects injected by\n * set methods.\n */\nexport class Api {\n  private readonly performance: Performance;\n  /** PreformanceObserver constructor function. */\n  private readonly PerformanceObserver: typeof PerformanceObserver;\n  private readonly windowLocation: Location;\n  readonly onFirstInputDelay?: Function;\n  readonly localStorage?: Storage;\n  readonly document: Document;\n  readonly navigator: Navigator;\n\n  constructor(readonly window?: Window) {\n    if (!window) {\n      throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);\n    }\n    this.performance = window.performance;\n    this.PerformanceObserver = window.PerformanceObserver;\n    this.windowLocation = window.location;\n    this.navigator = window.navigator;\n    this.document = window.document;\n    if (this.navigator && this.navigator.cookieEnabled) {\n      // If user blocks cookies on the browser, accessing localStorage will\n      // throw an exception.\n      this.localStorage = window.localStorage;\n    }\n    if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {\n      this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;\n    }\n  }\n\n  getUrl(): string {\n    // Do not capture the string query part of url.\n    return this.windowLocation.href.split('?')[0];\n  }\n\n  mark(name: string): void {\n    if (!this.performance || !this.performance.mark) {\n      return;\n    }\n    this.performance.mark(name);\n  }\n\n  measure(measureName: string, mark1: string, mark2: string): void {\n    if (!this.performance || !this.performance.measure) {\n      return;\n    }\n    this.performance.measure(measureName, mark1, mark2);\n  }\n\n  getEntriesByType(type: EntryType): PerformanceEntry[] {\n    if (!this.performance || !this.performance.getEntriesByType) {\n      return [];\n    }\n    return this.performance.getEntriesByType(type);\n  }\n\n  getEntriesByName(name: string): PerformanceEntry[] {\n    if (!this.performance || !this.performance.getEntriesByName) {\n      return [];\n    }\n    return this.performance.getEntriesByName(name);\n  }\n\n  getTimeOrigin(): number {\n    // Polyfill the time origin with performance.timing.navigationStart.\n    return (\n      this.performance &&\n      (this.performance.timeOrigin || this.performance.timing.navigationStart)\n    );\n  }\n\n  requiredApisAvailable(): boolean {\n    if (fetch && Promise && this.navigator && this.navigator.cookieEnabled) {\n      return true;\n    }\n    return false;\n  }\n\n  setupObserver(\n    entryType: EntryType,\n    callback: (entry: PerformanceEntry) => void\n  ): void {\n    if (!this.PerformanceObserver) {\n      return;\n    }\n    const observer = new this.PerformanceObserver(list => {\n      for (const entry of list.getEntries()) {\n        // `entry` is a PerformanceEntry instance.\n        callback(entry);\n      }\n    });\n\n    // Start observing the entry types you care about.\n    observer.observe({ entryTypes: [entryType] });\n  }\n\n  static getInstance(): Api {\n    if (apiInstance === undefined) {\n      apiInstance = new Api(windowInstance);\n    }\n    return apiInstance;\n  }\n}\n\nexport function setupApi(window: Window): void {\n  windowInstance = window;\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 './errors';\n\nexport function mergeStrings(part1: string, part2: string): string {\n  const sizeDiff = part1.length - part2.length;\n  if (sizeDiff < 0 || sizeDiff > 1) {\n    throw ERROR_FACTORY.create(ErrorCode.INVALID_STRING_MERGER_PARAMETER);\n  }\n\n  const resultArray = [];\n  for (let i = 0; i < part1.length; i++) {\n    resultArray.push(part1.charAt(i));\n    if (part2.length > i) {\n      resultArray.push(part2.charAt(i));\n    }\n  }\n\n  return resultArray.join('');\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 } from '@firebase/app-types';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport { mergeStrings } from '../utils/string_merger';\n\nlet settingsServiceInstance: SettingsService | undefined;\n\nexport class SettingsService {\n  // The variable which controls logging of automatic traces and HTTP/S network monitoring.\n  instrumentationEnabled = true;\n\n  // The variable which controls logging of custom traces.\n  dataCollectionEnabled = true;\n\n  // Configuration flags set through remote config.\n  loggingEnabled = false;\n  // Sampling rate between 0 and 1.\n  tracesSamplingRate = 1;\n  networkRequestsSamplingRate = 1;\n\n  // Address of logging service.\n  logEndPointUrl =\n    'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';\n  // Performance event transport endpoint URL which should be compatible with proto3.\n  // New Address for transport service, not configurable via Remote Config.\n  flTransportEndpointUrl = mergeStrings(\n    'hts/frbslgigp.ogepscmv/ieo/eaylg',\n    'tp:/ieaeogn-agolai.o/1frlglgc/o'\n  );\n\n  transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');\n\n  // Source type for performance event logs.\n  logSource = 462;\n\n  // Flags which control per session logging of traces and network requests.\n  logTraceAfterSampling = false;\n  logNetworkAfterSampling = false;\n\n  // TTL of config retrieved from remote config in hours.\n  configTimeToLive = 12;\n\n  firebaseAppInstance!: FirebaseApp;\n\n  installationsService!: FirebaseInstallations;\n\n  getAppId(): string {\n    const appId =\n      this.firebaseAppInstance &&\n      this.firebaseAppInstance.options &&\n      this.firebaseAppInstance.options.appId;\n    if (!appId) {\n      throw ERROR_FACTORY.create(ErrorCode.NO_APP_ID);\n    }\n    return appId;\n  }\n\n  getProjectId(): string {\n    const projectId =\n      this.firebaseAppInstance &&\n      this.firebaseAppInstance.options &&\n      this.firebaseAppInstance.options.projectId;\n    if (!projectId) {\n      throw ERROR_FACTORY.create(ErrorCode.NO_PROJECT_ID);\n    }\n    return projectId;\n  }\n\n  getApiKey(): string {\n    const apiKey =\n      this.firebaseAppInstance &&\n      this.firebaseAppInstance.options &&\n      this.firebaseAppInstance.options.apiKey;\n    if (!apiKey) {\n      throw ERROR_FACTORY.create(ErrorCode.NO_API_KEY);\n    }\n    return apiKey;\n  }\n\n  getFlTransportFullUrl(): string {\n    return this.flTransportEndpointUrl.concat('?key=', this.transportKey);\n  }\n\n  static getInstance(): SettingsService {\n    if (settingsServiceInstance === undefined) {\n      settingsServiceInstance = new SettingsService();\n    }\n    return settingsServiceInstance;\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 { SettingsService } from './settings_service';\n\nlet iid: string | undefined;\nlet authToken: string | undefined;\n\nexport function getIidPromise(): Promise<string> {\n  const iidPromise = SettingsService.getInstance().installationsService.getId();\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  iidPromise.then((iidVal: string) => {\n    iid = iidVal;\n  });\n  return iidPromise;\n}\n\n// This method should be used after the iid is retrieved by getIidPromise method.\nexport function getIid(): string | undefined {\n  return iid;\n}\n\nexport function getAuthTokenPromise(): Promise<string> {\n  const authTokenPromise = SettingsService.getInstance().installationsService.getToken();\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  authTokenPromise.then((authTokenVal: string) => {\n    authToken = authTokenVal;\n  });\n  return authTokenPromise;\n}\n\nexport function getAuthenticationToken(): string | undefined {\n  return authToken;\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 { Api } from '../services/api_service';\n\n// The values and orders of the following enums should not be changed.\nconst enum ServiceWorkerStatus {\n  UNKNOWN = 0,\n  UNSUPPORTED = 1,\n  CONTROLLED = 2,\n  UNCONTROLLED = 3\n}\n\nexport enum VisibilityState {\n  UNKNOWN = 0,\n  VISIBLE = 1,\n  HIDDEN = 2\n}\n\nconst enum EffectiveConnectionType {\n  UNKNOWN = 0,\n  CONNECTION_SLOW_2G = 1,\n  CONNECTION_2G = 2,\n  CONNECTION_3G = 3,\n  CONNECTION_4G = 4\n}\n\n/**\n * NetworkInformation\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation\n */\ninterface NetworkInformation {\n  readonly effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';\n}\n\ninterface NavigatorWithConnection extends Navigator {\n  readonly connection: NetworkInformation;\n}\n\nconst RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];\nconst ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\\\w*$');\nconst MAX_ATTRIBUTE_NAME_LENGTH = 40;\nconst MAX_ATTRIBUTE_VALUE_LENGTH = 100;\n\nexport function getServiceWorkerStatus(): ServiceWorkerStatus {\n  const navigator = Api.getInstance().navigator;\n  if ('serviceWorker' in navigator) {\n    if (navigator.serviceWorker.controller) {\n      return ServiceWorkerStatus.CONTROLLED;\n    } else {\n      return ServiceWorkerStatus.UNCONTROLLED;\n    }\n  } else {\n    return ServiceWorkerStatus.UNSUPPORTED;\n  }\n}\n\nexport function getVisibilityState(): VisibilityState {\n  const document = Api.getInstance().document;\n  const visibilityState = document.visibilityState;\n  switch (visibilityState) {\n    case 'visible':\n      return VisibilityState.VISIBLE;\n    case 'hidden':\n      return VisibilityState.HIDDEN;\n    default:\n      return VisibilityState.UNKNOWN;\n  }\n}\n\nexport function getEffectiveConnectionType(): EffectiveConnectionType {\n  const navigator = Api.getInstance().navigator;\n  const navigatorConnection = (navigator as NavigatorWithConnection).connection;\n  const effectiveType =\n    navigatorConnection && navigatorConnection.effectiveType;\n  switch (effectiveType) {\n    case 'slow-2g':\n      return EffectiveConnectionType.CONNECTION_SLOW_2G;\n    case '2g':\n      return EffectiveConnectionType.CONNECTION_2G;\n    case '3g':\n      return EffectiveConnectionType.CONNECTION_3G;\n    case '4g':\n      return EffectiveConnectionType.CONNECTION_4G;\n    default:\n      return EffectiveConnectionType.UNKNOWN;\n  }\n}\n\nexport function isValidCustomAttributeName(name: string): boolean {\n  if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {\n    return false;\n  }\n  const matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(prefix =>\n    name.startsWith(prefix)\n  );\n  return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);\n}\n\nexport function isValidCustomAttributeValue(value: string): boolean {\n  return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_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 { Logger, LogLevel } from '@firebase/logger';\nimport { SERVICE_NAME } from '../constants';\n\nexport const consoleLogger = new Logger(SERVICE_NAME);\nconsoleLogger.logLevel = LogLevel.INFO;\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  CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n  CONFIG_LOCAL_STORAGE_KEY,\n  SDK_VERSION\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\n\nimport { Api } from './api_service';\nimport { getAuthTokenPromise } from './iid_service';\nimport { SettingsService } from './settings_service';\n\nconst REMOTE_CONFIG_SDK_VERSION = '0.0.1';\n\ninterface SecondaryConfig {\n  loggingEnabled?: boolean;\n  logSource?: number;\n  logEndPointUrl?: string;\n  transportKey?: string;\n  tracesSamplingRate?: number;\n  networkRequestsSamplingRate?: number;\n}\n\n// These values will be used if the remote config object is successfully\n// retrieved, but the template does not have these fields.\nconst DEFAULT_CONFIGS: SecondaryConfig = {\n  loggingEnabled: true\n};\n\n/* eslint-disable camelcase */\ninterface RemoteConfigTemplate {\n  fpr_enabled?: string;\n  fpr_log_source?: string;\n  fpr_log_endpoint_url?: string;\n  fpr_log_transport_key?: string;\n  fpr_log_transport_web_percent?: string;\n  fpr_vc_network_request_sampling_rate?: string;\n  fpr_vc_trace_sampling_rate?: string;\n  fpr_vc_session_sampling_rate?: string;\n}\n/* eslint-enable camelcase */\n\ninterface RemoteConfigResponse {\n  entries?: RemoteConfigTemplate;\n  state?: string;\n}\n\nconst FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';\n\nexport function getConfig(iid: string): Promise<void> {\n  const config = getStoredConfig();\n  if (config) {\n    processConfig(config);\n    return Promise.resolve();\n  }\n\n  return getRemoteConfig(iid)\n    .then(processConfig)\n    .then(\n      config => storeConfig(config),\n      /** Do nothing for error, use defaults set in settings service. */\n      () => {}\n    );\n}\n\nfunction getStoredConfig(): RemoteConfigResponse | undefined {\n  const localStorage = Api.getInstance().localStorage;\n  if (!localStorage) {\n    return;\n  }\n  const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);\n  if (!expiryString || !configValid(expiryString)) {\n    return;\n  }\n\n  const configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);\n  if (!configStringified) {\n    return;\n  }\n  try {\n    const configResponse: RemoteConfigResponse = JSON.parse(configStringified);\n    return configResponse;\n  } catch {\n    return;\n  }\n}\n\nfunction storeConfig(config: RemoteConfigResponse | undefined): void {\n  const localStorage = Api.getInstance().localStorage;\n  if (!config || !localStorage) {\n    return;\n  }\n\n  localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));\n  localStorage.setItem(\n    CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n    String(\n      Date.now() +\n        SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000\n    )\n  );\n}\n\nconst COULD_NOT_GET_CONFIG_MSG =\n  'Could not fetch config, will use default configs';\n\nfunction getRemoteConfig(\n  iid: string\n): Promise<RemoteConfigResponse | undefined> {\n  // Perf needs auth token only to retrieve remote config.\n  return getAuthTokenPromise()\n    .then(authToken => {\n      const projectId = SettingsService.getInstance().getProjectId();\n      const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${SettingsService.getInstance().getApiKey()}`;\n      const request = new Request(configEndPoint, {\n        method: 'POST',\n        headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` },\n        /* eslint-disable camelcase */\n        body: JSON.stringify({\n          app_instance_id: iid,\n          app_instance_id_token: authToken,\n          app_id: SettingsService.getInstance().getAppId(),\n          app_version: SDK_VERSION,\n          sdk_version: REMOTE_CONFIG_SDK_VERSION\n        })\n        /* eslint-enable camelcase */\n      });\n      return fetch(request).then(response => {\n        if (response.ok) {\n          return response.json() as RemoteConfigResponse;\n        }\n        // In case response is not ok. This will be caught by catch.\n        throw ERROR_FACTORY.create(ErrorCode.RC_NOT_OK);\n      });\n    })\n    .catch(() => {\n      consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);\n      return undefined;\n    });\n}\n\n/**\n * Processes config coming either from calling RC or from local storage.\n * This method only runs if call is successful or config in storage\n * is valid.\n */\nfunction processConfig(\n  config?: RemoteConfigResponse\n): RemoteConfigResponse | undefined {\n  if (!config) {\n    return config;\n  }\n  const settingsServiceInstance = SettingsService.getInstance();\n  const entries = config.entries || {};\n  if (entries.fpr_enabled !== undefined) {\n    // TODO: Change the assignment of loggingEnabled once the received type is\n    // known.\n    settingsServiceInstance.loggingEnabled =\n      String(entries.fpr_enabled) === 'true';\n  } else if (DEFAULT_CONFIGS.loggingEnabled !== undefined) {\n    // Config retrieved successfully, but there is no fpr_enabled in template.\n    // Use secondary configs value.\n    settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;\n  }\n  if (entries.fpr_log_source) {\n    settingsServiceInstance.logSource = Number(entries.fpr_log_source);\n  } else if (DEFAULT_CONFIGS.logSource) {\n    settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;\n  }\n\n  if (entries.fpr_log_endpoint_url) {\n    settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;\n  } else if (DEFAULT_CONFIGS.logEndPointUrl) {\n    settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;\n  }\n\n  // Key from Remote Config has to be non-empty string, otherwsie use local value.\n  if (entries.fpr_log_transport_key) {\n    settingsServiceInstance.transportKey = entries.fpr_log_transport_key;\n  } else if (DEFAULT_CONFIGS.transportKey) {\n    settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;\n  }\n\n  if (entries.fpr_vc_network_request_sampling_rate !== undefined) {\n    settingsServiceInstance.networkRequestsSamplingRate = Number(\n      entries.fpr_vc_network_request_sampling_rate\n    );\n  } else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {\n    settingsServiceInstance.networkRequestsSamplingRate =\n      DEFAULT_CONFIGS.networkRequestsSamplingRate;\n  }\n  if (entries.fpr_vc_trace_sampling_rate !== undefined) {\n    settingsServiceInstance.tracesSamplingRate = Number(\n      entries.fpr_vc_trace_sampling_rate\n    );\n  } else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {\n    settingsServiceInstance.tracesSamplingRate =\n      DEFAULT_CONFIGS.tracesSamplingRate;\n  }\n  // Set the per session trace and network logging flags.\n  settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(\n    settingsServiceInstance.tracesSamplingRate\n  );\n  settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(\n    settingsServiceInstance.networkRequestsSamplingRate\n  );\n  return config;\n}\n\nfunction configValid(expiry: string): boolean {\n  return Number(expiry) > Date.now();\n}\n\nfunction shouldLogAfterSampling(samplingRate: number): boolean {\n  return Math.random() <= samplingRate;\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 { getIidPromise } from './iid_service';\nimport { getConfig } from './remote_config_service';\nimport { Api } from './api_service';\n\nconst enum InitializationStatus {\n  notInitialized = 1,\n  initializationPending,\n  initialized\n}\n\nlet initializationStatus = InitializationStatus.notInitialized;\n\nlet initializationPromise: Promise<void> | undefined;\n\nexport function getInitializationPromise(): Promise<void> {\n  initializationStatus = InitializationStatus.initializationPending;\n\n  initializationPromise = initializationPromise || initializePerf();\n\n  return initializationPromise;\n}\n\nexport function isPerfInitialized(): boolean {\n  return initializationStatus === InitializationStatus.initialized;\n}\n\nfunction initializePerf(): Promise<void> {\n  return getDocumentReadyComplete()\n    .then(() => getIidPromise())\n    .then(iid => getConfig(iid))\n    .then(\n      () => changeInitializationStatus(),\n      () => changeInitializationStatus()\n    );\n}\n\n/**\n * Returns a promise which resolves whenever the document readystate is complete or\n * immediately if it is called after page load complete.\n */\nfunction getDocumentReadyComplete(): Promise<void> {\n  const document = Api.getInstance().document;\n  return new Promise(resolve => {\n    if (document && document.readyState !== 'complete') {\n      const handler = (): void => {\n        if (document.readyState === 'complete') {\n          document.removeEventListener('readystatechange', handler);\n          resolve();\n        }\n      };\n      document.addEventListener('readystatechange', handler);\n    } else {\n      resolve();\n    }\n  });\n}\n\nfunction changeInitializationStatus(): void {\n  initializationStatus = InitializationStatus.initialized;\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 { SettingsService } from './settings_service';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst DEFAULT_SEND_INTERVAL_MS = 10 * 1000;\nconst INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;\n// If end point does not work, the call will be tried for these many times.\nconst DEFAULT_REMAINING_TRIES = 3;\nlet remainingTries = DEFAULT_REMAINING_TRIES;\n\ninterface LogResponseDetails {\n  responseAction?: string;\n}\n\ninterface BatchEvent {\n  message: string;\n  eventTime: number;\n}\n\n/* eslint-disable camelcase */\n// CC/Fl accepted log format.\ninterface TransportBatchLogFormat {\n  request_time_ms: string;\n  client_info: ClientInfo;\n  log_source: number;\n  log_event: Log[];\n}\n\ninterface ClientInfo {\n  client_type: number;\n  js_client_info: {};\n}\n\ninterface Log {\n  source_extension_json_proto3: string;\n  event_time_ms: string;\n}\n/* eslint-enable camelcase */\n\nlet queue: BatchEvent[] = [];\n\nlet isTransportSetup: boolean = false;\n\nexport function setupTransportService(): void {\n  if (!isTransportSetup) {\n    processQueue(INITIAL_SEND_TIME_DELAY_MS);\n    isTransportSetup = true;\n  }\n}\n\n/**\n * Utilized by testing to clean up message queue and un-initialize transport service.\n */\nexport function resetTransportService(): void {\n  isTransportSetup = false;\n  queue = [];\n}\n\nfunction processQueue(timeOffset: number): void {\n  setTimeout(() => {\n    // If there is no remainingTries left, stop retrying.\n    if (remainingTries === 0) {\n      return;\n    }\n\n    // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.\n    if (!queue.length) {\n      return processQueue(DEFAULT_SEND_INTERVAL_MS);\n    }\n\n    dispatchQueueEvents();\n  }, timeOffset);\n}\n\nfunction dispatchQueueEvents(): void {\n  // Capture a snapshot of the queue and empty the \"official queue\".\n  const staged = [...queue];\n  queue = [];\n\n  /* eslint-disable camelcase */\n  // We will pass the JSON serialized event to the backend.\n  const log_event: Log[] = staged.map(evt => ({\n    source_extension_json_proto3: evt.message,\n    event_time_ms: String(evt.eventTime)\n  }));\n\n  const data: TransportBatchLogFormat = {\n    request_time_ms: String(Date.now()),\n    client_info: {\n      client_type: 1, // 1 is JS\n      js_client_info: {}\n    },\n    log_source: SettingsService.getInstance().logSource,\n    log_event\n  };\n  /* eslint-enable camelcase */\n\n  sendEventsToFl(data, staged).catch(() => {\n    // If the request fails for some reason, add the events that were attempted\n    // back to the primary queue to retry later.\n    queue = [...staged, ...queue];\n    remainingTries--;\n    consoleLogger.info(`Tries left: ${remainingTries}.`);\n    processQueue(DEFAULT_SEND_INTERVAL_MS);\n  });\n}\n\nfunction sendEventsToFl(\n  data: TransportBatchLogFormat,\n  staged: BatchEvent[]\n): Promise<void> {\n  return postToFlEndpoint(data)\n    .then(res => {\n      if (!res.ok) {\n        consoleLogger.info('Call to Firebase backend failed.');\n      }\n      return res.json();\n    })\n    .then(res => {\n      // Find the next call wait time from the response.\n      const transportWait = Number(res.nextRequestWaitMillis);\n      let requestOffset = DEFAULT_SEND_INTERVAL_MS;\n      if (!isNaN(transportWait)) {\n        requestOffset = Math.max(transportWait, requestOffset);\n      }\n\n      // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.\n      // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.\n      const logResponseDetails: LogResponseDetails[] = res.logResponseDetails;\n      if (\n        Array.isArray(logResponseDetails) &&\n        logResponseDetails.length > 0 &&\n        logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER'\n      ) {\n        queue = [...staged, ...queue];\n        consoleLogger.info(`Retry transport request later.`);\n      }\n\n      remainingTries = DEFAULT_REMAINING_TRIES;\n      // Schedule the next process.\n      processQueue(requestOffset);\n    });\n}\n\nfunction postToFlEndpoint(data: TransportBatchLogFormat): Promise<Response> {\n  const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();\n  return fetch(flTransportFullUrl, {\n    method: 'POST',\n    body: JSON.stringify(data)\n  });\n}\n\nfunction addToQueue(evt: BatchEvent): void {\n  if (!evt.eventTime || !evt.message) {\n    throw ERROR_FACTORY.create(ErrorCode.INVALID_CC_LOG);\n  }\n  // Add the new event to the queue.\n  queue = [...queue, evt];\n}\n\n/** Log handler for cc service to send the performance logs to the server. */\nexport function transportHandler(\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  serializer: (...args: any[]) => string\n): (...args: unknown[]) => void {\n  return (...args) => {\n    const message = serializer(...args);\n    addToQueue({\n      message,\n      eventTime: Date.now()\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 { getIid } from './iid_service';\nimport { NetworkRequest } from '../resources/network_request';\nimport { Trace } from '../resources/trace';\nimport { Api } from './api_service';\nimport { SettingsService } from './settings_service';\nimport {\n  getServiceWorkerStatus,\n  getVisibilityState,\n  VisibilityState,\n  getEffectiveConnectionType\n} from '../utils/attributes_utils';\nimport {\n  isPerfInitialized,\n  getInitializationPromise\n} from './initialization_service';\nimport { transportHandler } from './transport_service';\nimport { SDK_VERSION } from '../constants';\n\nconst enum ResourceType {\n  NetworkRequest,\n  Trace\n}\n\n/* eslint-disable camelcase */\ninterface ApplicationInfo {\n  google_app_id: string;\n  app_instance_id?: string;\n  web_app_info: WebAppInfo;\n  application_process_state: number;\n}\n\ninterface WebAppInfo {\n  sdk_version: string;\n  page_url: string;\n  service_worker_status: number;\n  visibility_state: number;\n  effective_connection_type: number;\n}\n\ninterface PerfNetworkLog {\n  application_info: ApplicationInfo;\n  network_request_metric: NetworkRequestMetric;\n}\n\ninterface PerfTraceLog {\n  application_info: ApplicationInfo;\n  trace_metric: TraceMetric;\n}\n\ninterface NetworkRequestMetric {\n  url: string;\n  http_method: number;\n  http_response_code: number;\n  response_payload_bytes?: number;\n  client_start_time_us?: number;\n  time_to_response_initiated_us?: number;\n  time_to_response_completed_us?: number;\n}\n\ninterface TraceMetric {\n  name: string;\n  is_auto: boolean;\n  client_start_time_us: number;\n  duration_us: number;\n  counters?: { [key: string]: number };\n  custom_attributes?: { [key: string]: string };\n}\n\n/* eslint-enble camelcase */\n\nlet logger: (\n  resource: NetworkRequest | Trace,\n  resourceType: ResourceType\n) => void | undefined;\n// This method is not called before initialization.\nfunction sendLog(\n  resource: NetworkRequest | Trace,\n  resourceType: ResourceType\n): void {\n  if (!logger) {\n    logger = transportHandler(serializer);\n  }\n  logger(resource, resourceType);\n}\n\nexport function logTrace(trace: Trace): void {\n  const settingsService = SettingsService.getInstance();\n  // Do not log if trace is auto generated and instrumentation is disabled.\n  if (!settingsService.instrumentationEnabled && trace.isAuto) {\n    return;\n  }\n  // Do not log if trace is custom and data collection is disabled.\n  if (!settingsService.dataCollectionEnabled && !trace.isAuto) {\n    return;\n  }\n  // Do not log if required apis are not available.\n  if (!Api.getInstance().requiredApisAvailable()) {\n    return;\n  }\n  // Only log the page load auto traces if page is visible.\n  if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {\n    return;\n  }\n\n  if (\n    !settingsService.loggingEnabled ||\n    !settingsService.logTraceAfterSampling\n  ) {\n    return;\n  }\n\n  if (isPerfInitialized()) {\n    sendTraceLog(trace);\n  } else {\n    // Custom traces can be used before the initialization but logging\n    // should wait until after.\n    getInitializationPromise().then(\n      () => sendTraceLog(trace),\n      () => sendTraceLog(trace)\n    );\n  }\n}\n\nfunction sendTraceLog(trace: Trace): void {\n  if (getIid()) {\n    setTimeout(() => sendLog(trace, ResourceType.Trace), 0);\n  }\n}\n\nexport function logNetworkRequest(networkRequest: NetworkRequest): void {\n  const settingsService = SettingsService.getInstance();\n  // Do not log network requests if instrumentation is disabled.\n  if (!settingsService.instrumentationEnabled) {\n    return;\n  }\n\n  // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.\n  // Need to blacklist both old and new endpoints to avoid migration gap.\n  const networkRequestUrl = networkRequest.url;\n\n  // Blacklist old log endpoint and new transport endpoint.\n  // Because Performance SDK doesn't instrument requests sent from SDK itself.\n  const logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];\n  const flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];\n  if (\n    networkRequestUrl === logEndpointUrl ||\n    networkRequestUrl === flEndpointUrl\n  ) {\n    return;\n  }\n\n  if (\n    !settingsService.loggingEnabled ||\n    !settingsService.logNetworkAfterSampling\n  ) {\n    return;\n  }\n\n  setTimeout(() => sendLog(networkRequest, ResourceType.NetworkRequest), 0);\n}\n\nfunction serializer(\n  resource: NetworkRequest | Trace,\n  resourceType: ResourceType\n): string {\n  if (resourceType === ResourceType.NetworkRequest) {\n    return serializeNetworkRequest(resource as NetworkRequest);\n  }\n  return serializeTrace(resource as Trace);\n}\n\nfunction serializeNetworkRequest(networkRequest: NetworkRequest): string {\n  const networkRequestMetric: NetworkRequestMetric = {\n    url: networkRequest.url,\n    http_method: networkRequest.httpMethod || 0,\n    http_response_code: 200,\n    response_payload_bytes: networkRequest.responsePayloadBytes,\n    client_start_time_us: networkRequest.startTimeUs,\n    time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,\n    time_to_response_completed_us: networkRequest.timeToResponseCompletedUs\n  };\n  const perfMetric: PerfNetworkLog = {\n    application_info: getApplicationInfo(),\n    network_request_metric: networkRequestMetric\n  };\n  return JSON.stringify(perfMetric);\n}\n\nfunction serializeTrace(trace: Trace): string {\n  const traceMetric: TraceMetric = {\n    name: trace.name,\n    is_auto: trace.isAuto,\n    client_start_time_us: trace.startTimeUs,\n    duration_us: trace.durationUs\n  };\n\n  if (Object.keys(trace.counters).length !== 0) {\n    traceMetric.counters = trace.counters;\n  }\n  const customAttributes = trace.getAttributes();\n  if (Object.keys(customAttributes).length !== 0) {\n    traceMetric.custom_attributes = customAttributes;\n  }\n\n  const perfMetric: PerfTraceLog = {\n    application_info: getApplicationInfo(),\n    trace_metric: traceMetric\n  };\n  return JSON.stringify(perfMetric);\n}\n\nfunction getApplicationInfo(): ApplicationInfo {\n  return {\n    google_app_id: SettingsService.getInstance().getAppId(),\n    app_instance_id: getIid(),\n    web_app_info: {\n      sdk_version: SDK_VERSION,\n      page_url: Api.getInstance().getUrl(),\n      service_worker_status: getServiceWorkerStatus(),\n      visibility_state: getVisibilityState(),\n      effective_connection_type: getEffectiveConnectionType()\n    },\n    application_process_state: 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 {\n  FIRST_PAINT_COUNTER_NAME,\n  FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n  FIRST_INPUT_DELAY_COUNTER_NAME,\n  OOB_TRACE_PAGE_LOAD_PREFIX\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst MAX_METRIC_NAME_LENGTH = 100;\nconst RESERVED_AUTO_PREFIX = '_';\nconst oobMetrics = [\n  FIRST_PAINT_COUNTER_NAME,\n  FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n  FIRST_INPUT_DELAY_COUNTER_NAME\n];\n\n/**\n * Returns true if the metric is custom and does not start with reserved prefix, or if\n * the metric is one of out of the box page load trace metrics.\n */\nexport function isValidMetricName(name: string, traceName?: string): boolean {\n  if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {\n    return false;\n  }\n  return (\n    (traceName &&\n      traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&\n      oobMetrics.indexOf(name) > -1) ||\n    !name.startsWith(RESERVED_AUTO_PREFIX)\n  );\n}\n\n/**\n * Converts the provided value to an integer value to be used in case of a metric.\n * @param providedValue Provided number value of the metric that needs to be converted to an integer.\n *\n * @returns Converted integer number to be set for the metric.\n */\nexport function convertMetricValueToInteger(providedValue: number): number {\n  const valueAsInteger: number = Math.floor(providedValue);\n  if (valueAsInteger < providedValue) {\n    consoleLogger.info(\n      `Metric value should be an Integer, setting the value as : ${valueAsInteger}.`\n    );\n  }\n  return valueAsInteger;\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  TRACE_START_MARK_PREFIX,\n  TRACE_STOP_MARK_PREFIX,\n  TRACE_MEASURE_PREFIX,\n  OOB_TRACE_PAGE_LOAD_PREFIX,\n  FIRST_PAINT_COUNTER_NAME,\n  FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n  FIRST_INPUT_DELAY_COUNTER_NAME\n} from '../constants';\nimport { Api } from '../services/api_service';\nimport { logTrace } from '../services/perf_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport {\n  isValidCustomAttributeName,\n  isValidCustomAttributeValue\n} from '../utils/attributes_utils';\nimport {\n  isValidMetricName,\n  convertMetricValueToInteger\n} from '../utils/metric_utils';\nimport { PerformanceTrace } from '@firebase/performance-types';\n\nconst enum TraceState {\n  UNINITIALIZED = 1,\n  RUNNING,\n  TERMINATED\n}\n\nexport class Trace implements PerformanceTrace {\n  private state: TraceState = TraceState.UNINITIALIZED;\n  startTimeUs!: number;\n  durationUs!: number;\n  private customAttributes: { [key: string]: string } = {};\n  counters: { [counterName: string]: number } = {};\n  private api = Api.getInstance();\n  private randomId = Math.floor(Math.random() * 1000000);\n  private traceStartMark!: string;\n  private traceStopMark!: string;\n  private traceMeasure!: string;\n\n  /**\n   * @param name The name of the trace.\n   * @param isAuto If the trace is auto-instrumented.\n   * @param traceMeasureName The name of the measure marker in user timing specification. This field\n   * is only set when the trace is built for logging when the user directly uses the user timing\n   * api (performance.mark and performance.measure).\n   */\n  constructor(\n    readonly name: string,\n    readonly isAuto = false,\n    traceMeasureName?: string\n  ) {\n    if (!this.isAuto) {\n      this.traceStartMark = `${TRACE_START_MARK_PREFIX}-${this.randomId}-${this.name}`;\n      this.traceStopMark = `${TRACE_STOP_MARK_PREFIX}-${this.randomId}-${this.name}`;\n      this.traceMeasure =\n        traceMeasureName ||\n        `${TRACE_MEASURE_PREFIX}-${this.randomId}-${this.name}`;\n\n      if (traceMeasureName) {\n        // For the case of direct user timing traces, no start stop will happen. The measure object\n        // is already available.\n        this.calculateTraceMetrics();\n      }\n    }\n  }\n\n  /**\n   * Starts a trace. The measurement of the duration starts at this point.\n   */\n  start(): void {\n    if (this.state !== TraceState.UNINITIALIZED) {\n      throw ERROR_FACTORY.create(ErrorCode.TRACE_STARTED_BEFORE, {\n        traceName: this.name\n      });\n    }\n    this.api.mark(this.traceStartMark);\n    this.state = TraceState.RUNNING;\n  }\n\n  /**\n   * Stops the trace. The measurement of the duration of the trace stops at this point and trace\n   * is logged.\n   */\n  stop(): void {\n    if (this.state !== TraceState.RUNNING) {\n      throw ERROR_FACTORY.create(ErrorCode.TRACE_STOPPED_BEFORE, {\n        traceName: this.name\n      });\n    }\n    this.state = TraceState.TERMINATED;\n    this.api.mark(this.traceStopMark);\n    this.api.measure(\n      this.traceMeasure,\n      this.traceStartMark,\n      this.traceStopMark\n    );\n    this.calculateTraceMetrics();\n    logTrace(this);\n  }\n\n  /**\n   * Records a trace with predetermined values. If this method is used a trace is created and logged\n   * directly. No need to use start and stop methods.\n   * @param startTime Trace start time since epoch in millisec\n   * @param duration The duraction of the trace in millisec\n   * @param options An object which can optionally hold maps of custom metrics and custom attributes\n   */\n  record(\n    startTime: number,\n    duration: number,\n    options?: {\n      metrics?: { [key: string]: number };\n      attributes?: { [key: string]: string };\n    }\n  ): void {\n    this.durationUs = Math.floor(duration * 1000);\n    this.startTimeUs = Math.floor(startTime * 1000);\n    if (options && options.attributes) {\n      this.customAttributes = { ...options.attributes };\n    }\n    if (options && options.metrics) {\n      for (const metric of Object.keys(options.metrics)) {\n        if (!isNaN(Number(options.metrics[metric]))) {\n          this.counters[metric] = Number(Math.floor(options.metrics[metric]));\n        }\n      }\n    }\n    logTrace(this);\n  }\n\n  /**\n   * Increments a custom metric by a certain number or 1 if number not specified. Will create a new\n   * custom metric if one with the given name does not exist. The value will be floored down to an\n   * integer.\n   * @param counter Name of the custom metric\n   * @param numAsInteger Increment by value\n   */\n  incrementMetric(counter: string, numAsInteger = 1): void {\n    if (this.counters[counter] === undefined) {\n      this.putMetric(counter, numAsInteger);\n    } else {\n      this.putMetric(counter, this.counters[counter] + numAsInteger);\n    }\n  }\n\n  /**\n   * Sets a custom metric to a specified value. Will create a new custom metric if one with the\n   * given name does not exist. The value will be floored down to an integer.\n   * @param counter Name of the custom metric\n   * @param numAsInteger Set custom metric to this value\n   */\n  putMetric(counter: string, numAsInteger: number): void {\n    if (isValidMetricName(counter, this.name)) {\n      this.counters[counter] = convertMetricValueToInteger(numAsInteger);\n    } else {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_CUSTOM_METRIC_NAME, {\n        customMetricName: counter\n      });\n    }\n  }\n\n  /**\n   * Returns the value of the custom metric by that name. If a custom metric with that name does\n   * not exist will return zero.\n   * @param counter\n   */\n  getMetric(counter: string): number {\n    return this.counters[counter] || 0;\n  }\n\n  /**\n   * Sets a custom attribute of a trace to a certain value.\n   * @param attr\n   * @param value\n   */\n  putAttribute(attr: string, value: string): void {\n    const isValidName = isValidCustomAttributeName(attr);\n    const isValidValue = isValidCustomAttributeValue(value);\n    if (isValidName && isValidValue) {\n      this.customAttributes[attr] = value;\n      return;\n    }\n    // Throw appropriate error when the attribute name or value is invalid.\n    if (!isValidName) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_NAME, {\n        attributeName: attr\n      });\n    }\n    if (!isValidValue) {\n      throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_VALUE, {\n        attributeValue: value\n      });\n    }\n  }\n\n  /**\n   * Retrieves the value a custom attribute of a trace is set to.\n   * @param attr\n   */\n  getAttribute(attr: string): string | undefined {\n    return this.customAttributes[attr];\n  }\n\n  removeAttribute(attr: string): void {\n    if (this.customAttributes[attr] === undefined) {\n      return;\n    }\n    delete this.customAttributes[attr];\n  }\n\n  getAttributes(): { [key: string]: string } {\n    return { ...this.customAttributes };\n  }\n\n  private setStartTime(startTime: number): void {\n    this.startTimeUs = startTime;\n  }\n\n  private setDuration(duration: number): void {\n    this.durationUs = duration;\n  }\n\n  /**\n   * Calculates and assigns the duration and start time of the trace using the measure performance\n   * entry.\n   */\n  private calculateTraceMetrics(): void {\n    const perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);\n    const perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];\n    if (perfMeasureEntry) {\n      this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);\n      this.startTimeUs = Math.floor(\n        (perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000\n      );\n    }\n  }\n\n  /**\n   * @param navigationTimings A single element array which contains the navigationTIming object of\n   * the page load\n   * @param paintTimings A array which contains paintTiming object of the page load\n   * @param firstInputDelay First input delay in millisec\n   */\n  static createOobTrace(\n    navigationTimings: PerformanceNavigationTiming[],\n    paintTimings: PerformanceEntry[],\n    firstInputDelay?: number\n  ): void {\n    const route = Api.getInstance().getUrl();\n    if (!route) {\n      return;\n    }\n    const trace = new Trace(OOB_TRACE_PAGE_LOAD_PREFIX + route, true);\n    const timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);\n    trace.setStartTime(timeOriginUs);\n\n    // navigationTimings includes only one element.\n    if (navigationTimings && navigationTimings[0]) {\n      trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));\n      trace.putMetric(\n        'domInteractive',\n        Math.floor(navigationTimings[0].domInteractive * 1000)\n      );\n      trace.putMetric(\n        'domContentLoadedEventEnd',\n        Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000)\n      );\n      trace.putMetric(\n        'loadEventEnd',\n        Math.floor(navigationTimings[0].loadEventEnd * 1000)\n      );\n    }\n\n    const FIRST_PAINT = 'first-paint';\n    const FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';\n    if (paintTimings) {\n      const firstPaint = paintTimings.find(\n        paintObject => paintObject.name === FIRST_PAINT\n      );\n      if (firstPaint && firstPaint.startTime) {\n        trace.putMetric(\n          FIRST_PAINT_COUNTER_NAME,\n          Math.floor(firstPaint.startTime * 1000)\n        );\n      }\n      const firstContentfulPaint = paintTimings.find(\n        paintObject => paintObject.name === FIRST_CONTENTFUL_PAINT\n      );\n      if (firstContentfulPaint && firstContentfulPaint.startTime) {\n        trace.putMetric(\n          FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n          Math.floor(firstContentfulPaint.startTime * 1000)\n        );\n      }\n\n      if (firstInputDelay) {\n        trace.putMetric(\n          FIRST_INPUT_DELAY_COUNTER_NAME,\n          Math.floor(firstInputDelay * 1000)\n        );\n      }\n    }\n\n    logTrace(trace);\n  }\n\n  static createUserTimingTrace(measureName: string): void {\n    const trace = new Trace(measureName, false, measureName);\n    logTrace(trace);\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 { Api } from '../services/api_service';\nimport { logNetworkRequest } from '../services/perf_logger';\n\n// The order of values of this enum should not be changed.\nexport const enum HttpMethod {\n  HTTP_METHOD_UNKNOWN = 0,\n  GET = 1,\n  PUT = 2,\n  POST = 3,\n  DELETE = 4,\n  HEAD = 5,\n  PATCH = 6,\n  OPTIONS = 7,\n  TRACE = 8,\n  CONNECT = 9\n}\n\n// Durations are in microseconds.\nexport interface NetworkRequest {\n  url: string;\n  httpMethod?: HttpMethod;\n  requestPayloadBytes?: number;\n  responsePayloadBytes?: number;\n  httpResponseCode?: number;\n  responseContentType?: string;\n  startTimeUs?: number;\n  timeToRequestCompletedUs?: number;\n  timeToResponseInitiatedUs?: number;\n  timeToResponseCompletedUs?: number;\n}\n\nexport function createNetworkRequestEntry(entry: PerformanceEntry): void {\n  const performanceEntry = entry as PerformanceResourceTiming;\n  if (!performanceEntry || performanceEntry.responseStart === undefined) {\n    return;\n  }\n  const timeOrigin = Api.getInstance().getTimeOrigin();\n  const startTimeUs = Math.floor(\n    (performanceEntry.startTime + timeOrigin) * 1000\n  );\n  const timeToResponseInitiatedUs = performanceEntry.responseStart\n    ? Math.floor(\n        (performanceEntry.responseStart - performanceEntry.startTime) * 1000\n      )\n    : undefined;\n  const timeToResponseCompletedUs = Math.floor(\n    (performanceEntry.responseEnd - performanceEntry.startTime) * 1000\n  );\n  // Remove the query params from logged network request url.\n  const url = performanceEntry.name && performanceEntry.name.split('?')[0];\n  const networkRequest: NetworkRequest = {\n    url,\n    responsePayloadBytes: performanceEntry.transferSize,\n    startTimeUs,\n    timeToResponseInitiatedUs,\n    timeToResponseCompletedUs\n  };\n\n  logNetworkRequest(networkRequest);\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 { Api } from './api_service';\nimport { Trace } from '../resources/trace';\nimport { createNetworkRequestEntry } from '../resources/network_request';\nimport { TRACE_MEASURE_PREFIX } from '../constants';\nimport { getIid } from './iid_service';\n\nconst FID_WAIT_TIME_MS = 5000;\n\nexport function setupOobResources(): void {\n  // Do not initialize unless iid is available.\n  if (!getIid()) {\n    return;\n  }\n  // The load event might not have fired yet, and that means performance navigation timing\n  // object has a duration of 0. The setup should run after all current tasks in js queue.\n  setTimeout(() => setupOobTraces(), 0);\n  setTimeout(() => setupNetworkRequests(), 0);\n  setTimeout(() => setupUserTimingTraces(), 0);\n}\n\nfunction setupNetworkRequests(): void {\n  const api = Api.getInstance();\n  const resources = api.getEntriesByType('resource');\n  for (const resource of resources) {\n    createNetworkRequestEntry(resource);\n  }\n  api.setupObserver('resource', createNetworkRequestEntry);\n}\n\nfunction setupOobTraces(): void {\n  const api = Api.getInstance();\n  const navigationTimings = api.getEntriesByType(\n    'navigation'\n  ) as PerformanceNavigationTiming[];\n  const paintTimings = api.getEntriesByType('paint');\n  // If First Input Desly polyfill is added to the page, report the fid value.\n  // https://github.com/GoogleChromeLabs/first-input-delay\n  if (api.onFirstInputDelay) {\n    // If the fid call back is not called for certain time, continue without it.\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    let timeoutId: any = setTimeout(() => {\n      Trace.createOobTrace(navigationTimings, paintTimings);\n      timeoutId = undefined;\n    }, FID_WAIT_TIME_MS);\n    api.onFirstInputDelay((fid: number) => {\n      if (timeoutId) {\n        clearTimeout(timeoutId);\n        Trace.createOobTrace(navigationTimings, paintTimings, fid);\n      }\n    });\n  } else {\n    Trace.createOobTrace(navigationTimings, paintTimings);\n  }\n}\n\nfunction setupUserTimingTraces(): void {\n  const api = Api.getInstance();\n  // Run through the measure performance entries collected up to this point.\n  const measures = api.getEntriesByType('measure');\n  for (const measure of measures) {\n    createUserTimingTrace(measure);\n  }\n  // Setup an observer to capture the measures from this point on.\n  api.setupObserver('measure', createUserTimingTrace);\n}\n\nfunction createUserTimingTrace(measure: PerformanceEntry): void {\n  const measureName = measure.name;\n  // Do not create a trace, if the user timing marks and measures are created by the sdk itself.\n  if (\n    measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===\n    TRACE_MEASURE_PREFIX\n  ) {\n    return;\n  }\n  Trace.createUserTimingTrace(measureName);\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 { Trace } from '../resources/trace';\nimport { setupOobResources } from '../services/oob_resources_service';\nimport { SettingsService } from '../services/settings_service';\nimport { getInitializationPromise } from '../services/initialization_service';\nimport { Api } from '../services/api_service';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebasePerformance } from '@firebase/performance-types';\nimport { consoleLogger } from '../utils/console_logger';\nimport { setupTransportService } from '../services/transport_service';\n\nexport class PerformanceController implements FirebasePerformance {\n  constructor(readonly app: FirebaseApp) {\n    if (Api.getInstance().requiredApisAvailable()) {\n      setupTransportService();\n      getInitializationPromise().then(setupOobResources, setupOobResources);\n    } else {\n      consoleLogger.info(\n        'Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.'\n      );\n    }\n  }\n\n  trace(name: string): Trace {\n    return new Trace(name);\n  }\n\n  set instrumentationEnabled(val: boolean) {\n    SettingsService.getInstance().instrumentationEnabled = val;\n  }\n  get instrumentationEnabled(): boolean {\n    return SettingsService.getInstance().instrumentationEnabled;\n  }\n\n  set dataCollectionEnabled(val: boolean) {\n    SettingsService.getInstance().dataCollectionEnabled = val;\n  }\n  get dataCollectionEnabled(): boolean {\n    return SettingsService.getInstance().dataCollectionEnabled;\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 { StorageCache } from '../storage/storage_cache';\nimport {\n  FetchResponse,\n  RemoteConfigFetchClient,\n  FetchRequest\n} from './remote_config_fetch_client';\nimport { Storage } from '../storage/storage';\nimport { Logger } from '@firebase/logger';\n\n/**\n * Implements the {@link RemoteConfigClient} abstraction with success response caching.\n *\n * <p>Comparable to the browser's Cache API for responses, but the Cache API requires a Service\n * Worker, which requires HTTPS, which would significantly complicate SDK installation. Also, the\n * Cache API doesn't support matching entries by time.\n */\nexport class CachingClient implements RemoteConfigFetchClient {\n  constructor(\n    private readonly client: RemoteConfigFetchClient,\n    private readonly storage: Storage,\n    private readonly storageCache: StorageCache,\n    private readonly logger: Logger\n  ) {}\n\n  /**\n   * Returns true if the age of the cached fetched configs is less than or equal to\n   * {@link Settings#minimumFetchIntervalInSeconds}.\n   *\n   * <p>This is comparable to passing `headers = { 'Cache-Control': max-age <maxAge> }` to the\n   * native Fetch API.\n   *\n   * <p>Visible for testing.\n   */\n  isCachedDataFresh(\n    cacheMaxAgeMillis: number,\n    lastSuccessfulFetchTimestampMillis: number | undefined\n  ): boolean {\n    // Cache can only be fresh if it's populated.\n    if (!lastSuccessfulFetchTimestampMillis) {\n      this.logger.debug('Config fetch cache check. Cache unpopulated.');\n      return false;\n    }\n\n    // Calculates age of cache entry.\n    const cacheAgeMillis = Date.now() - lastSuccessfulFetchTimestampMillis;\n\n    const isCachedDataFresh = cacheAgeMillis <= cacheMaxAgeMillis;\n\n    this.logger.debug(\n      'Config fetch cache check.' +\n        ` Cache age millis: ${cacheAgeMillis}.` +\n        ` Cache max age millis (minimumFetchIntervalMillis setting): ${cacheMaxAgeMillis}.` +\n        ` Is cache hit: ${isCachedDataFresh}.`\n    );\n\n    return isCachedDataFresh;\n  }\n\n  async fetch(request: FetchRequest): Promise<FetchResponse> {\n    // Reads from persisted storage to avoid cache miss if callers don't wait on initialization.\n    const [\n      lastSuccessfulFetchTimestampMillis,\n      lastSuccessfulFetchResponse\n    ] = await Promise.all([\n      this.storage.getLastSuccessfulFetchTimestampMillis(),\n      this.storage.getLastSuccessfulFetchResponse()\n    ]);\n\n    // Exits early on cache hit.\n    if (\n      lastSuccessfulFetchResponse &&\n      this.isCachedDataFresh(\n        request.cacheMaxAgeMillis,\n        lastSuccessfulFetchTimestampMillis\n      )\n    ) {\n      return lastSuccessfulFetchResponse;\n    }\n\n    // Deviates from pure decorator by not honoring a passed ETag since we don't have a public API\n    // that allows the caller to pass an ETag.\n    request.eTag =\n      lastSuccessfulFetchResponse && lastSuccessfulFetchResponse.eTag;\n\n    // Falls back to service on cache miss.\n    const response = await this.client.fetch(request);\n\n    // Fetch throws for non-success responses, so success is guaranteed here.\n\n    const storageOperations = [\n      // Uses write-through cache for consistency with synchronous public API.\n      this.storageCache.setLastSuccessfulFetchTimestampMillis(Date.now())\n    ];\n\n    if (response.status === 200) {\n      // Caches response only if it has changed, ie non-304 responses.\n      storageOperations.push(\n        this.storage.setLastSuccessfulFetchResponse(response)\n      );\n    }\n\n    await Promise.all(storageOperations);\n\n    return 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/**\n * Attempts to get the most accurate browser language setting.\n *\n * <p>Adapted from getUserLanguage in packages/auth/src/utils.js for TypeScript.\n *\n * <p>Defers default language specification to server logic for consistency.\n *\n * @param navigatorLanguage Enables tests to override read-only {@link NavigatorLanguage}.\n */\nexport function getUserLanguage(\n  navigatorLanguage: NavigatorLanguage = navigator\n): string {\n  return (\n    // Most reliable, but only supported in Chrome/Firefox.\n    (navigatorLanguage.languages && navigatorLanguage.languages[0]) ||\n    // Supported in most browsers, but returns the language of the browser\n    // UI, not the language set in browser settings.\n    navigatorLanguage.language\n    // Polyfill otherwise.\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 { FirebaseInstallations } from '@firebase/installations-types';\nimport {\n  FetchResponse,\n  RemoteConfigFetchClient,\n  FirebaseRemoteConfigObject,\n  FetchRequest\n} from './remote_config_fetch_client';\nimport { ERROR_FACTORY, ErrorCode } from '../errors';\nimport { getUserLanguage } from '../language';\n\n/**\n * Defines request body parameters required to call the fetch API:\n * https://firebase.google.com/docs/reference/remote-config/rest\n *\n * <p>Not exported because this file encapsulates REST API specifics.\n *\n * <p>Not passing User Properties because Analytics' source of truth on Web is server-side.\n */\ninterface FetchRequestBody {\n  // Disables camelcase linting for request body params.\n  /* eslint-disable camelcase*/\n  sdk_version: string;\n  app_instance_id: string;\n  app_instance_id_token: string;\n  app_id: string;\n  language_code: string;\n  /* eslint-enable camelcase */\n}\n\n/**\n * Implements the Client abstraction for the Remote Config REST API.\n */\nexport class RestClient implements RemoteConfigFetchClient {\n  constructor(\n    private readonly firebaseInstallations: FirebaseInstallations,\n    private readonly sdkVersion: string,\n    private readonly namespace: string,\n    private readonly projectId: string,\n    private readonly apiKey: string,\n    private readonly appId: string\n  ) {}\n\n  /**\n   * Fetches from the Remote Config REST API.\n   *\n   * @throws a {@link ErrorCode.FETCH_NETWORK} error if {@link GlobalFetch#fetch} can't\n   * connect to the network.\n   * @throws a {@link ErrorCode.FETCH_PARSE} error if {@link Response#json} can't parse the\n   * fetch response.\n   * @throws a {@link ErrorCode.FETCH_STATUS} error if the service returns an HTTP error status.\n   */\n  async fetch(request: FetchRequest): Promise<FetchResponse> {\n    const [installationId, installationToken] = await Promise.all([\n      this.firebaseInstallations.getId(),\n      this.firebaseInstallations.getToken()\n    ]);\n\n    const urlBase =\n      window.FIREBASE_REMOTE_CONFIG_URL_BASE ||\n      'https://firebaseremoteconfig.googleapis.com';\n\n    const url = `${urlBase}/v1/projects/${this.projectId}/namespaces/${this.namespace}:fetch?key=${this.apiKey}`;\n\n    const headers = {\n      'Content-Type': 'application/json',\n      'Content-Encoding': 'gzip',\n      // Deviates from pure decorator by not passing max-age header since we don't currently have\n      // service behavior using that header.\n      'If-None-Match': request.eTag || '*'\n    };\n\n    const requestBody: FetchRequestBody = {\n      /* eslint-disable camelcase */\n      sdk_version: this.sdkVersion,\n      app_instance_id: installationId,\n      app_instance_id_token: installationToken,\n      app_id: this.appId,\n      language_code: getUserLanguage()\n      /* eslint-enable camelcase */\n    };\n\n    const options = {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(requestBody)\n    };\n\n    // This logic isn't REST-specific, but shimming abort logic isn't worth another decorator.\n    const fetchPromise = fetch(url, options);\n    const timeoutPromise = new Promise((_resolve, reject) => {\n      // Maps async event listener to Promise API.\n      request.signal.addEventListener(() => {\n        // Emulates https://heycam.github.io/webidl/#aborterror\n        const error = new Error('The operation was aborted.');\n        error.name = 'AbortError';\n        reject(error);\n      });\n    });\n\n    let response;\n    try {\n      await Promise.race([fetchPromise, timeoutPromise]);\n      response = await fetchPromise;\n    } catch (originalError) {\n      let errorCode = ErrorCode.FETCH_NETWORK;\n      if (originalError.name === 'AbortError') {\n        errorCode = ErrorCode.FETCH_TIMEOUT;\n      }\n      throw ERROR_FACTORY.create(errorCode, {\n        originalErrorMessage: originalError.message\n      });\n    }\n\n    let status = response.status;\n\n    // Normalizes nullable header to optional.\n    const responseEtag = response.headers.get('ETag') || undefined;\n\n    let config: FirebaseRemoteConfigObject | undefined;\n    let state: string | undefined;\n\n    // JSON parsing throws SyntaxError if the response body isn't a JSON string.\n    // Requesting application/json and checking for a 200 ensures there's JSON data.\n    if (response.status === 200) {\n      let responseBody;\n      try {\n        responseBody = await response.json();\n      } catch (originalError) {\n        throw ERROR_FACTORY.create(ErrorCode.FETCH_PARSE, {\n          originalErrorMessage: originalError.message\n        });\n      }\n      config = responseBody['entries'];\n      state = responseBody['state'];\n    }\n\n    // Normalizes based on legacy state.\n    if (state === 'INSTANCE_STATE_UNSPECIFIED') {\n      status = 500;\n    } else if (state === 'NO_CHANGE') {\n      status = 304;\n    } else if (state === 'NO_TEMPLATE' || state === 'EMPTY_CONFIG') {\n      // These cases can be fixed remotely, so normalize to safe value.\n      config = {};\n    }\n\n    // Normalize to exception-based control flow for non-success cases.\n    // Encapsulates HTTP specifics in this class as much as possible. Status is still the best for\n    // differentiating success states (200 from 304; the state body param is undefined in a\n    // standard 304).\n    if (status !== 304 && status !== 200) {\n      throw ERROR_FACTORY.create(ErrorCode.FETCH_STATUS, {\n        httpStatus: status\n      });\n    }\n\n    return { status, eTag: responseEtag, config };\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 * Defines a client, as in https://en.wikipedia.org/wiki/Client%E2%80%93server_model, for the\n * Remote Config server (https://firebase.google.com/docs/reference/remote-config/rest).\n *\n * <p>Abstracts throttle, response cache and network implementation details.\n *\n * <p>Modeled after the native {@link GlobalFetch} interface, which is relatively modern and\n * convenient, but simplified for Remote Config's use case.\n *\n * Disambiguation: {@link GlobalFetch} interface and the Remote Config service define \"fetch\"\n * methods. The RestClient uses the former to make HTTP calls. This interface abstracts the latter.\n */\nexport interface RemoteConfigFetchClient {\n  /**\n   * @throws if response status is not 200 or 304.\n   */\n  fetch(request: FetchRequest): Promise<FetchResponse>;\n}\n\n/**\n * Defines a self-descriptive reference for config key-value pairs.\n */\nexport interface FirebaseRemoteConfigObject {\n  [key: string]: string;\n}\n\n/**\n * Shims a minimal AbortSignal.\n *\n * <p>AbortController's AbortSignal conveniently decouples fetch timeout logic from other aspects\n * of networking, such as retries. Firebase doesn't use AbortController enough to justify a\n * polyfill recommendation, like we do with the Fetch API, but this minimal shim can easily be\n * swapped out if/when we do.\n */\nexport class RemoteConfigAbortSignal {\n  listeners: Array<() => void> = [];\n  addEventListener(listener: () => void): void {\n    this.listeners.push(listener);\n  }\n  abort(): void {\n    this.listeners.forEach(listener => listener());\n  }\n}\n\n/**\n * Defines per-request inputs for the Remote Config fetch request.\n *\n * <p>Modeled after the native {@link Request} interface, but simplified for Remote Config's\n * use case.\n */\nexport interface FetchRequest {\n  /**\n   * Uses cached config if it is younger than this age.\n   *\n   * <p>Required because it's defined by settings, which always have a value.\n   *\n   * <p>Comparable to passing `headers = { 'Cache-Control': max-age <maxAge> }` to the native\n   * Fetch API.\n   */\n  cacheMaxAgeMillis: number;\n\n  /**\n   * An event bus for the signal to abort a request.\n   *\n   * <p>Required because all requests should be abortable.\n   *\n   * <p>Comparable to the native\n   * Fetch API's \"signal\" field on its request configuration object\n   * https://fetch.spec.whatwg.org/#dom-requestinit-signal.\n   *\n   * <p>Disambiguation: Remote Config commonly refers to API inputs as\n   * \"signals\". See the private ConfigFetchRequestBody interface for those:\n   * http://google3/firebase/remote_config/web/src/core/rest_client.ts?l=14&rcl=255515243.\n   */\n  signal: RemoteConfigAbortSignal;\n\n  /**\n   * The ETag header value from the last response.\n   *\n   * <p>Optional in case this is the first request.\n   *\n   * <p>Comparable to passing `headers = { 'If-None-Match': <eTag> }` to the native Fetch API.\n   */\n  eTag?: string;\n}\n\n/**\n * Defines a successful response (200 or 304).\n *\n * <p>Modeled after the native {@link Response} interface, but simplified for Remote Config's\n * use case.\n */\nexport interface FetchResponse {\n  /**\n   * The HTTP status, which is useful for differentiating success responses with data from\n   * those without.\n   *\n   * <p>{@link RemoteConfigClient} is modeled after the native {@link GlobalFetch} interface, so\n   * HTTP status is first-class.\n   *\n   * <p>Disambiguation: the fetch response returns a legacy \"state\" value that is redundant with the\n   * HTTP status code. The former is normalized into the latter.\n   */\n  status: number;\n\n  /**\n   * Defines the ETag response header value.\n   *\n   * <p>Only defined for 200 and 304 responses.\n   */\n  eTag?: string;\n\n  /**\n   * Defines the map of parameters returned as \"entries\" in the fetch response body.\n   *\n   * <p>Only defined for 200 responses.\n   */\n  config?: FirebaseRemoteConfigObject;\n\n  // Note: we're not extracting experiment metadata until\n  // ABT and Analytics have Web SDKs.\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 { Value as ValueType, ValueSource } from '@firebase/remote-config-types';\n\nconst DEFAULT_VALUE_FOR_BOOLEAN = false;\nconst DEFAULT_VALUE_FOR_STRING = '';\nconst DEFAULT_VALUE_FOR_NUMBER = 0;\n\nconst BOOLEAN_TRUTHY_VALUES = ['1', 'true', 't', 'yes', 'y', 'on'];\n\nexport class Value implements ValueType {\n  constructor(\n    private readonly _source: ValueSource,\n    private readonly _value: string = DEFAULT_VALUE_FOR_STRING\n  ) {}\n\n  asString(): string {\n    return this._value;\n  }\n\n  asBoolean(): boolean {\n    if (this._source === 'static') {\n      return DEFAULT_VALUE_FOR_BOOLEAN;\n    }\n    return BOOLEAN_TRUTHY_VALUES.indexOf(this._value.toLowerCase()) >= 0;\n  }\n\n  asNumber(): number {\n    if (this._source === 'static') {\n      return DEFAULT_VALUE_FOR_NUMBER;\n    }\n    let num = Number(this._value);\n    if (isNaN(num)) {\n      num = DEFAULT_VALUE_FOR_NUMBER;\n    }\n    return num;\n  }\n\n  getSource(): ValueSource {\n    return this._source;\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 { FirebaseApp } from '@firebase/app-types';\nimport {\n  RemoteConfig as RemoteConfigType,\n  FetchStatus,\n  Settings,\n  Value as ValueType,\n  LogLevel as RemoteConfigLogLevel\n} from '@firebase/remote-config-types';\nimport { StorageCache } from './storage/storage_cache';\nimport {\n  RemoteConfigFetchClient,\n  RemoteConfigAbortSignal\n} from './client/remote_config_fetch_client';\nimport { Value } from './value';\nimport { ErrorCode, hasErrorCode } from './errors';\nimport { Storage } from './storage/storage';\nimport { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger';\n\nconst DEFAULT_FETCH_TIMEOUT_MILLIS = 60 * 1000; // One minute\nconst DEFAULT_CACHE_MAX_AGE_MILLIS = 12 * 60 * 60 * 1000; // Twelve hours.\n\n/**\n * Encapsulates business logic mapping network and storage dependencies to the public SDK API.\n *\n * See {@link https://github.com/FirebasePrivate/firebase-js-sdk/blob/master/packages/firebase/index.d.ts|interface documentation} for method descriptions.\n */\nexport class RemoteConfig implements RemoteConfigType {\n  // Tracks completion of initialization promise.\n  private _isInitializationComplete = false;\n\n  // De-duplicates initialization calls.\n  private _initializePromise?: Promise<void>;\n\n  settings: Settings = {\n    fetchTimeoutMillis: DEFAULT_FETCH_TIMEOUT_MILLIS,\n    minimumFetchIntervalMillis: DEFAULT_CACHE_MAX_AGE_MILLIS\n  };\n\n  defaultConfig: { [key: string]: string | number | boolean } = {};\n\n  // Based on packages/firestore/src/util/log.ts but not static because we need per-instance levels\n  // to differentiate 2p and 3p use-cases.\n  setLogLevel(logLevel: RemoteConfigLogLevel): void {\n    switch (logLevel) {\n      case 'debug':\n        this._logger.logLevel = FirebaseLogLevel.DEBUG;\n        break;\n      case 'silent':\n        this._logger.logLevel = FirebaseLogLevel.SILENT;\n        break;\n      default:\n        this._logger.logLevel = FirebaseLogLevel.ERROR;\n    }\n  }\n\n  get fetchTimeMillis(): number {\n    return this._storageCache.getLastSuccessfulFetchTimestampMillis() || -1;\n  }\n\n  get lastFetchStatus(): FetchStatus {\n    return this._storageCache.getLastFetchStatus() || 'no-fetch-yet';\n  }\n\n  constructor(\n    // Required by FirebaseServiceFactory interface.\n    readonly app: FirebaseApp,\n    // JS doesn't support private yet\n    // (https://github.com/tc39/proposal-class-fields#private-fields), so we hint using an\n    // underscore prefix.\n    private readonly _client: RemoteConfigFetchClient,\n    private readonly _storageCache: StorageCache,\n    private readonly _storage: Storage,\n    private readonly _logger: Logger\n  ) {}\n\n  async activate(): Promise<boolean> {\n    const [lastSuccessfulFetchResponse, activeConfigEtag] = await Promise.all([\n      this._storage.getLastSuccessfulFetchResponse(),\n      this._storage.getActiveConfigEtag()\n    ]);\n    if (\n      !lastSuccessfulFetchResponse ||\n      !lastSuccessfulFetchResponse.config ||\n      !lastSuccessfulFetchResponse.eTag ||\n      lastSuccessfulFetchResponse.eTag === activeConfigEtag\n    ) {\n      // Either there is no successful fetched config, or is the same as current active\n      // config.\n      return false;\n    }\n    await Promise.all([\n      this._storageCache.setActiveConfig(lastSuccessfulFetchResponse.config),\n      this._storage.setActiveConfigEtag(lastSuccessfulFetchResponse.eTag)\n    ]);\n    return true;\n  }\n\n  ensureInitialized(): Promise<void> {\n    if (!this._initializePromise) {\n      this._initializePromise = this._storageCache\n        .loadFromStorage()\n        .then(() => {\n          this._isInitializationComplete = true;\n        });\n    }\n    return this._initializePromise;\n  }\n\n  /**\n   * @throws a {@link ErrorCode.FETCH_CLIENT_TIMEOUT} if the request takes longer than\n   * {@link Settings.fetchTimeoutInSeconds} or\n   * {@link DEFAULT_FETCH_TIMEOUT_SECONDS}.\n   */\n  async fetch(): Promise<void> {\n    // Aborts the request after the given timeout, causing the fetch call to\n    // reject with an AbortError.\n    //\n    // <p>Aborting after the request completes is a no-op, so we don't need a\n    // corresponding clearTimeout.\n    //\n    // Locating abort logic here because:\n    // * it uses a developer setting (timeout)\n    // * it applies to all retries (like curl's max-time arg)\n    // * it is consistent with the Fetch API's signal input\n    const abortSignal = new RemoteConfigAbortSignal();\n\n    setTimeout(async () => {\n      // Note a very low delay, eg < 10ms, can elapse before listeners are initialized.\n      abortSignal.abort();\n    }, this.settings.fetchTimeoutMillis);\n\n    // Catches *all* errors thrown by client so status can be set consistently.\n    try {\n      await this._client.fetch({\n        cacheMaxAgeMillis: this.settings.minimumFetchIntervalMillis,\n        signal: abortSignal\n      });\n\n      await this._storageCache.setLastFetchStatus('success');\n    } catch (e) {\n      const lastFetchStatus = hasErrorCode(e, ErrorCode.FETCH_THROTTLE)\n        ? 'throttle'\n        : 'failure';\n      await this._storageCache.setLastFetchStatus(lastFetchStatus);\n      throw e;\n    }\n  }\n\n  async fetchAndActivate(): Promise<boolean> {\n    await this.fetch();\n    return this.activate();\n  }\n\n  getAll(): { [key: string]: ValueType } {\n    return getAllKeys(\n      this._storageCache.getActiveConfig(),\n      this.defaultConfig\n    ).reduce((allConfigs, key) => {\n      allConfigs[key] = this.getValue(key);\n      return allConfigs;\n    }, {} as { [key: string]: ValueType });\n  }\n\n  getBoolean(key: string): boolean {\n    return this.getValue(key).asBoolean();\n  }\n\n  getNumber(key: string): number {\n    return this.getValue(key).asNumber();\n  }\n\n  getString(key: string): string {\n    return this.getValue(key).asString();\n  }\n\n  getValue(key: string): ValueType {\n    if (!this._isInitializationComplete) {\n      this._logger.debug(\n        `A value was requested for key \"${key}\" before SDK initialization completed.` +\n          ' Await on ensureInitialized if the intent was to get a previously activated value.'\n      );\n    }\n    const activeConfig = this._storageCache.getActiveConfig();\n    if (activeConfig && activeConfig[key] !== undefined) {\n      return new Value('remote', activeConfig[key]);\n    } else if (this.defaultConfig && this.defaultConfig[key] !== undefined) {\n      return new Value('default', String(this.defaultConfig[key]));\n    }\n    this._logger.debug(\n      `Returning static value for key \"${key}\".` +\n        ' Define a default or remote value if this is unintentional.'\n    );\n    return new Value('static');\n  }\n}\n\n/**\n * Dedupes and returns an array of all the keys of the received objects.\n */\nfunction getAllKeys(obj1: {} = {}, obj2: {} = {}): string[] {\n  return Object.keys({ ...obj1, ...obj2 });\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 { FetchStatus } from '@firebase/remote-config-types';\nimport {\n  FetchResponse,\n  FirebaseRemoteConfigObject\n} from '../client/remote_config_fetch_client';\nimport { ERROR_FACTORY, ErrorCode } from '../errors';\nimport { FirebaseError } from '@firebase/util';\n\n/**\n * Converts an error event associated with a {@link IDBRequest} to a {@link FirebaseError}.\n */\nfunction toFirebaseError(event: Event, errorCode: ErrorCode): FirebaseError {\n  const originalError = (event.target as IDBRequest).error || undefined;\n  return ERROR_FACTORY.create(errorCode, {\n    originalErrorMessage: originalError && originalError.message\n  });\n}\n\n/**\n * A general-purpose store keyed by app + namespace + {@link\n * ProjectNamespaceKeyFieldValue}.\n *\n * <p>The Remote Config SDK can be used with multiple app installations, and each app can interact\n * with multiple namespaces, so this store uses app (ID + name) and namespace as common parent keys\n * for a set of key-value pairs. See {@link Storage#createCompositeKey}.\n *\n * <p>Visible for testing.\n */\nexport const APP_NAMESPACE_STORE = 'app_namespace_store';\n\nconst DB_NAME = 'firebase_remote_config';\nconst DB_VERSION = 1;\n\n/**\n * Encapsulates metadata concerning throttled fetch requests.\n */\nexport interface ThrottleMetadata {\n  // The number of times fetch has backed off. Used for resuming backoff after a timeout.\n  backoffCount: number;\n  // The Unix timestamp in milliseconds when callers can retry a request.\n  throttleEndTimeMillis: number;\n}\n\n/**\n * Provides type-safety for the \"key\" field used by {@link APP_NAMESPACE_STORE}.\n *\n * <p>This seems like a small price to avoid potentially subtle bugs caused by a typo.\n */\ntype ProjectNamespaceKeyFieldValue =\n  | 'active_config'\n  | 'active_config_etag'\n  | 'last_fetch_status'\n  | 'last_successful_fetch_timestamp_millis'\n  | 'last_successful_fetch_response'\n  | 'settings'\n  | 'throttle_metadata';\n\n// Visible for testing.\nexport function openDatabase(): Promise<IDBDatabase> {\n  return new Promise((resolve, reject) => {\n    const request = indexedDB.open(DB_NAME, DB_VERSION);\n    request.onerror = event => {\n      reject(toFirebaseError(event, ErrorCode.STORAGE_OPEN));\n    };\n    request.onsuccess = event => {\n      resolve((event.target as IDBOpenDBRequest).result);\n    };\n    request.onupgradeneeded = event => {\n      const db = (event.target as IDBOpenDBRequest).result;\n\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 (event.oldVersion) {\n        case 0:\n          db.createObjectStore(APP_NAMESPACE_STORE, {\n            keyPath: 'compositeKey'\n          });\n      }\n    };\n  });\n}\n\n/**\n * Abstracts data persistence.\n */\nexport class Storage {\n  /**\n   * @param appId enables storage segmentation by app (ID + name).\n   * @param appName enables storage segmentation by app (ID + name).\n   * @param namespace enables storage segmentation by namespace.\n   */\n  constructor(\n    private readonly appId: string,\n    private readonly appName: string,\n    private readonly namespace: string,\n    private readonly openDbPromise = openDatabase()\n  ) {}\n\n  getLastFetchStatus(): Promise<FetchStatus | undefined> {\n    return this.get<FetchStatus>('last_fetch_status');\n  }\n\n  setLastFetchStatus(status: FetchStatus): Promise<void> {\n    return this.set<FetchStatus>('last_fetch_status', status);\n  }\n\n  // This is comparable to a cache entry timestamp. If we need to expire other data, we could\n  // consider adding timestamp to all storage records and an optional max age arg to getters.\n  getLastSuccessfulFetchTimestampMillis(): Promise<number | undefined> {\n    return this.get<number>('last_successful_fetch_timestamp_millis');\n  }\n\n  setLastSuccessfulFetchTimestampMillis(timestamp: number): Promise<void> {\n    return this.set<number>(\n      'last_successful_fetch_timestamp_millis',\n      timestamp\n    );\n  }\n\n  getLastSuccessfulFetchResponse(): Promise<FetchResponse | undefined> {\n    return this.get<FetchResponse>('last_successful_fetch_response');\n  }\n\n  setLastSuccessfulFetchResponse(response: FetchResponse): Promise<void> {\n    return this.set<FetchResponse>('last_successful_fetch_response', response);\n  }\n\n  getActiveConfig(): Promise<FirebaseRemoteConfigObject | undefined> {\n    return this.get<FirebaseRemoteConfigObject>('active_config');\n  }\n\n  setActiveConfig(config: FirebaseRemoteConfigObject): Promise<void> {\n    return this.set<FirebaseRemoteConfigObject>('active_config', config);\n  }\n\n  getActiveConfigEtag(): Promise<string | undefined> {\n    return this.get<string>('active_config_etag');\n  }\n\n  setActiveConfigEtag(etag: string): Promise<void> {\n    return this.set<string>('active_config_etag', etag);\n  }\n\n  getThrottleMetadata(): Promise<ThrottleMetadata | undefined> {\n    return this.get<ThrottleMetadata>('throttle_metadata');\n  }\n\n  setThrottleMetadata(metadata: ThrottleMetadata): Promise<void> {\n    return this.set<ThrottleMetadata>('throttle_metadata', metadata);\n  }\n\n  deleteThrottleMetadata(): Promise<void> {\n    return this.delete('throttle_metadata');\n  }\n\n  async get<T>(key: ProjectNamespaceKeyFieldValue): Promise<T | undefined> {\n    const db = await this.openDbPromise;\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');\n      const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);\n      const compositeKey = this.createCompositeKey(key);\n      try {\n        const request = objectStore.get(compositeKey);\n        request.onerror = event => {\n          reject(toFirebaseError(event, ErrorCode.STORAGE_GET));\n        };\n        request.onsuccess = event => {\n          const result = (event.target as IDBRequest).result;\n          if (result) {\n            resolve(result.value);\n          } else {\n            resolve(undefined);\n          }\n        };\n      } catch (e) {\n        reject(\n          ERROR_FACTORY.create(ErrorCode.STORAGE_GET, {\n            originalErrorMessage: e && e.message\n          })\n        );\n      }\n    });\n  }\n\n  async set<T>(key: ProjectNamespaceKeyFieldValue, value: T): Promise<void> {\n    const db = await this.openDbPromise;\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');\n      const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);\n      const compositeKey = this.createCompositeKey(key);\n      try {\n        const request = objectStore.put({\n          compositeKey,\n          value\n        });\n        request.onerror = (event: Event) => {\n          reject(toFirebaseError(event, ErrorCode.STORAGE_SET));\n        };\n        request.onsuccess = () => {\n          resolve();\n        };\n      } catch (e) {\n        reject(\n          ERROR_FACTORY.create(ErrorCode.STORAGE_SET, {\n            originalErrorMessage: e && e.message\n          })\n        );\n      }\n    });\n  }\n\n  async delete(key: ProjectNamespaceKeyFieldValue): Promise<void> {\n    const db = await this.openDbPromise;\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');\n      const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);\n      const compositeKey = this.createCompositeKey(key);\n      try {\n        const request = objectStore.delete(compositeKey);\n        request.onerror = (event: Event) => {\n          reject(toFirebaseError(event, ErrorCode.STORAGE_DELETE));\n        };\n        request.onsuccess = () => {\n          resolve();\n        };\n      } catch (e) {\n        reject(\n          ERROR_FACTORY.create(ErrorCode.STORAGE_DELETE, {\n            originalErrorMessage: e && e.message\n          })\n        );\n      }\n    });\n  }\n\n  // Facilitates composite key functionality (which is unsupported in IE).\n  createCompositeKey(key: ProjectNamespaceKeyFieldValue): string {\n    return [this.appId, this.appName, this.namespace, key].join();\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 { FetchStatus } from '@firebase/remote-config-types';\nimport { FirebaseRemoteConfigObject } from '../client/remote_config_fetch_client';\nimport { Storage } from './storage';\n\n/**\n * A memory cache layer over storage to support the SDK's synchronous read requirements.\n */\nexport class StorageCache {\n  constructor(private readonly storage: Storage) {}\n\n  /**\n   * Memory caches.\n   */\n  private lastFetchStatus?: FetchStatus;\n  private lastSuccessfulFetchTimestampMillis?: number;\n  private activeConfig?: FirebaseRemoteConfigObject;\n\n  /**\n   * Memory-only getters\n   */\n  getLastFetchStatus(): FetchStatus | undefined {\n    return this.lastFetchStatus;\n  }\n\n  getLastSuccessfulFetchTimestampMillis(): number | undefined {\n    return this.lastSuccessfulFetchTimestampMillis;\n  }\n\n  getActiveConfig(): FirebaseRemoteConfigObject | undefined {\n    return this.activeConfig;\n  }\n\n  /**\n   * Read-ahead getter\n   */\n  async loadFromStorage(): Promise<void> {\n    const lastFetchStatusPromise = this.storage.getLastFetchStatus();\n    const lastSuccessfulFetchTimestampMillisPromise = this.storage.getLastSuccessfulFetchTimestampMillis();\n    const activeConfigPromise = this.storage.getActiveConfig();\n\n    // Note:\n    // 1. we consistently check for undefined to avoid clobbering defined values\n    //   in memory\n    // 2. we defer awaiting to improve readability, as opposed to destructuring\n    //   a Promise.all result, for example\n\n    const lastFetchStatus = await lastFetchStatusPromise;\n    if (lastFetchStatus) {\n      this.lastFetchStatus = lastFetchStatus;\n    }\n\n    const lastSuccessfulFetchTimestampMillis = await lastSuccessfulFetchTimestampMillisPromise;\n    if (lastSuccessfulFetchTimestampMillis) {\n      this.lastSuccessfulFetchTimestampMillis = lastSuccessfulFetchTimestampMillis;\n    }\n\n    const activeConfig = await activeConfigPromise;\n    if (activeConfig) {\n      this.activeConfig = activeConfig;\n    }\n  }\n\n  /**\n   * Write-through setters\n   */\n  setLastFetchStatus(status: FetchStatus): Promise<void> {\n    this.lastFetchStatus = status;\n    return this.storage.setLastFetchStatus(status);\n  }\n\n  setLastSuccessfulFetchTimestampMillis(\n    timestampMillis: number\n  ): Promise<void> {\n    this.lastSuccessfulFetchTimestampMillis = timestampMillis;\n    return this.storage.setLastSuccessfulFetchTimestampMillis(timestampMillis);\n  }\n\n  setActiveConfig(activeConfig: FirebaseRemoteConfigObject): Promise<void> {\n    this.activeConfig = activeConfig;\n    return this.storage.setActiveConfig(activeConfig);\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 INTERVAL_MILLIS = 1000;\n\n/**\n * The factor to backoff by.\n * Should be a number greater than 1.\n */\nconst BACKOFF_FACTOR = 2;\n\n/**\n * The maximum milliseconds to increase to.\n *\n * <p>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 * <p>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(backoffCount: number): 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 =\n    INTERVAL_MILLIS * Math.pow(BACKOFF_FACTOR, 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 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  RemoteConfigAbortSignal,\n  RemoteConfigFetchClient,\n  FetchResponse,\n  FetchRequest\n} from './remote_config_fetch_client';\nimport { ThrottleMetadata, Storage } from '../storage/storage';\nimport { calculateBackoffMillis } from './exponential_backoff';\nimport { ErrorCode, ERROR_FACTORY } from '../errors';\nimport { FirebaseError } from '@firebase/util';\n\n/**\n * Supports waiting on a backoff by:\n *\n * <ul>\n *   <li>Promisifying setTimeout, so we can set a timeout in our Promise chain</li>\n *   <li>Listening on a signal bus for abort events, just like the Fetch API</li>\n *   <li>Failing in the same way the Fetch API fails, so timing out a live request and a throttled\n *       request appear the same.</li>\n * </ul>\n *\n * <p>Visible for testing.\n */\nexport function setAbortableTimeout(\n  signal: RemoteConfigAbortSignal,\n  throttleEndTimeMillis: number\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    // Derives backoff from given end time, normalizing negative numbers to zero.\n    const backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0);\n\n    const timeout = setTimeout(resolve, backoffMillis);\n\n    // Adds listener, rather than sets onabort, because signal is a shared object.\n    signal.addEventListener(() => {\n      clearTimeout(timeout);\n\n      // If the request completes before this timeout, the rejection has no effect.\n      reject(\n        ERROR_FACTORY.create(ErrorCode.FETCH_THROTTLE, {\n          throttleEndTimeMillis\n        })\n      );\n    });\n  });\n}\n\n/**\n * Returns true if the {@link Error} indicates a fetch request may succeed later.\n */\nfunction isRetriableError(e: Error): boolean {\n  if (!(e instanceof FirebaseError)) {\n    return false;\n  }\n\n  // Uses string index defined by ErrorData, which FirebaseError implements.\n  const httpStatus = Number(e['httpStatus']);\n\n  return (\n    httpStatus === 429 ||\n    httpStatus === 500 ||\n    httpStatus === 503 ||\n    httpStatus === 504\n  );\n}\n\n/**\n * Decorates a Client with retry logic.\n *\n * <p>Comparable to CachingClient, but uses backoff logic instead of cache max age and doesn't cache\n * responses (because the SDK has no use for error responses).\n */\nexport class RetryingClient implements RemoteConfigFetchClient {\n  constructor(\n    private readonly client: RemoteConfigFetchClient,\n    private readonly storage: Storage\n  ) {}\n\n  async fetch(request: FetchRequest): Promise<FetchResponse> {\n    const throttleMetadata = (await this.storage.getThrottleMetadata()) || {\n      backoffCount: 0,\n      throttleEndTimeMillis: Date.now()\n    };\n\n    return this.attemptFetch(request, throttleMetadata);\n  }\n\n  /**\n   * A recursive helper for attempting a fetch request repeatedly.\n   *\n   * @throws any non-retriable errors.\n   */\n  async attemptFetch(\n    request: FetchRequest,\n    { throttleEndTimeMillis, backoffCount }: ThrottleMetadata\n  ): Promise<FetchResponse> {\n    // Starts with a (potentially zero) timeout to support resumption from stored state.\n    // Ensures the throttle end time is honored if the last attempt timed out.\n    // Note the SDK will never make a request if the fetch timeout expires at this point.\n    await setAbortableTimeout(request.signal, throttleEndTimeMillis);\n\n    try {\n      const response = await this.client.fetch(request);\n\n      // Note the SDK only clears throttle state if response is success or non-retriable.\n      await this.storage.deleteThrottleMetadata();\n\n      return response;\n    } catch (e) {\n      if (!isRetriableError(e)) {\n        throw e;\n      }\n\n      // Increments backoff state.\n      const throttleMetadata = {\n        throttleEndTimeMillis:\n          Date.now() + calculateBackoffMillis(backoffCount),\n        backoffCount: backoffCount + 1\n      };\n\n      // Persists state.\n      await this.storage.setThrottleMetadata(throttleMetadata);\n\n      return this.attemptFetch(request, throttleMetadata);\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/**\n * @fileoverview Constants used in the Firebase Storage library.\n */\n\n/**\n * Domain name for firebase storage.\n */\nexport const DEFAULT_HOST = 'firebasestorage.googleapis.com';\n\n/**\n * The key in Firebase config json for the storage bucket.\n */\nexport const CONFIG_STORAGE_BUCKET_KEY = 'storageBucket';\n\n/**\n * 2 minutes\n *\n * The timeout for all operations except upload.\n */\nexport const DEFAULT_MAX_OPERATION_RETRY_TIME = 2 * 60 * 1000;\n\n/**\n * 10 minutes\n *\n * The timeout for upload.\n */\nexport const DEFAULT_MAX_UPLOAD_RETRY_TIME = 10 * 60 * 1000;\n\n/**\n * This is the value of Number.MIN_SAFE_INTEGER, which is not well supported\n * enough for us to use it directly.\n */\nexport const MIN_SAFE_INTEGER = -9007199254740991;\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 */\nimport { CONFIG_STORAGE_BUCKET_KEY } from './constants';\n\nexport class FirebaseStorageError implements Error {\n  private code_: string;\n  private message_: string;\n  private serverResponse_: string | null;\n  private name_: string;\n\n  constructor(code: Code, message: string) {\n    this.code_ = prependCode(code);\n    this.message_ = 'Firebase Storage: ' + message;\n    this.serverResponse_ = null;\n    this.name_ = 'FirebaseError';\n  }\n\n  codeProp(): string {\n    return this.code;\n  }\n\n  codeEquals(code: Code): boolean {\n    return prependCode(code) === this.codeProp();\n  }\n\n  serverResponseProp(): string | null {\n    return this.serverResponse_;\n  }\n\n  setServerResponseProp(serverResponse: string | null): void {\n    this.serverResponse_ = serverResponse;\n  }\n\n  get name(): string {\n    return this.name_;\n  }\n\n  get code(): string {\n    return this.code_;\n  }\n\n  get message(): string {\n    if (this.serverResponse_) {\n      return this.message_ + '\\n' + this.serverResponse_;\n    } else {\n      return this.message_;\n    }\n  }\n\n  get serverResponse(): null | string {\n    return this.serverResponse_;\n  }\n}\n\nexport const errors = {};\n\n/**\n * @enum {string}\n */\nexport type Code = string;\nexport const Code = {\n  // Shared between all platforms\n  UNKNOWN: 'unknown',\n  OBJECT_NOT_FOUND: 'object-not-found',\n  BUCKET_NOT_FOUND: 'bucket-not-found',\n  PROJECT_NOT_FOUND: 'project-not-found',\n  QUOTA_EXCEEDED: 'quota-exceeded',\n  UNAUTHENTICATED: 'unauthenticated',\n  UNAUTHORIZED: 'unauthorized',\n  RETRY_LIMIT_EXCEEDED: 'retry-limit-exceeded',\n  INVALID_CHECKSUM: 'invalid-checksum',\n  CANCELED: 'canceled',\n  // JS specific\n  INVALID_EVENT_NAME: 'invalid-event-name',\n  INVALID_URL: 'invalid-url',\n  INVALID_DEFAULT_BUCKET: 'invalid-default-bucket',\n  NO_DEFAULT_BUCKET: 'no-default-bucket',\n  CANNOT_SLICE_BLOB: 'cannot-slice-blob',\n  SERVER_FILE_WRONG_SIZE: 'server-file-wrong-size',\n  NO_DOWNLOAD_URL: 'no-download-url',\n  INVALID_ARGUMENT: 'invalid-argument',\n  INVALID_ARGUMENT_COUNT: 'invalid-argument-count',\n  APP_DELETED: 'app-deleted',\n  INVALID_ROOT_OPERATION: 'invalid-root-operation',\n  INVALID_FORMAT: 'invalid-format',\n  INTERNAL_ERROR: 'internal-error'\n};\n\nexport function prependCode(code: Code): string {\n  return 'storage/' + code;\n}\n\nexport function unknown(): FirebaseStorageError {\n  const message =\n    'An unknown error occurred, please check the error payload for ' +\n    'server response.';\n  return new FirebaseStorageError(Code.UNKNOWN, message);\n}\n\nexport function objectNotFound(path: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.OBJECT_NOT_FOUND,\n    \"Object '\" + path + \"' does not exist.\"\n  );\n}\n\nexport function bucketNotFound(bucket: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.BUCKET_NOT_FOUND,\n    \"Bucket '\" + bucket + \"' does not exist.\"\n  );\n}\n\nexport function projectNotFound(project: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.PROJECT_NOT_FOUND,\n    \"Project '\" + project + \"' does not exist.\"\n  );\n}\n\nexport function quotaExceeded(bucket: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.QUOTA_EXCEEDED,\n    \"Quota for bucket '\" +\n      bucket +\n      \"' exceeded, please view quota on \" +\n      'https://firebase.google.com/pricing/.'\n  );\n}\n\nexport function unauthenticated(): FirebaseStorageError {\n  const message =\n    'User is not authenticated, please authenticate using Firebase ' +\n    'Authentication and try again.';\n  return new FirebaseStorageError(Code.UNAUTHENTICATED, message);\n}\n\nexport function unauthorized(path: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.UNAUTHORIZED,\n    \"User does not have permission to access '\" + path + \"'.\"\n  );\n}\n\nexport function retryLimitExceeded(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.RETRY_LIMIT_EXCEEDED,\n    'Max retry time for operation exceeded, please try again.'\n  );\n}\n\nexport function invalidChecksum(\n  path: string,\n  checksum: string,\n  calculated: string\n): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_CHECKSUM,\n    \"Uploaded/downloaded object '\" +\n      path +\n      \"' has checksum '\" +\n      checksum +\n      \"' which does not match '\" +\n      calculated +\n      \"'. Please retry the upload/download.\"\n  );\n}\n\nexport function canceled(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.CANCELED,\n    'User canceled the upload/download.'\n  );\n}\n\nexport function invalidEventName(name: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_EVENT_NAME,\n    \"Invalid event name '\" + name + \"'.\"\n  );\n}\n\nexport function invalidUrl(url: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_URL,\n    \"Invalid URL '\" + url + \"'.\"\n  );\n}\n\nexport function invalidDefaultBucket(bucket: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_DEFAULT_BUCKET,\n    \"Invalid default bucket '\" + bucket + \"'.\"\n  );\n}\n\nexport function noDefaultBucket(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.NO_DEFAULT_BUCKET,\n    'No default bucket ' +\n      \"found. Did you set the '\" +\n      CONFIG_STORAGE_BUCKET_KEY +\n      \"' property when initializing the app?\"\n  );\n}\n\nexport function cannotSliceBlob(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.CANNOT_SLICE_BLOB,\n    'Cannot slice blob for upload. Please retry the upload.'\n  );\n}\n\nexport function serverFileWrongSize(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.SERVER_FILE_WRONG_SIZE,\n    'Server recorded incorrect upload file size, please retry the upload.'\n  );\n}\n\nexport function noDownloadURL(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.NO_DOWNLOAD_URL,\n    'The given file does not have any download URLs.'\n  );\n}\n\nexport function invalidArgument(\n  index: number,\n  fnName: string,\n  message: string\n): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_ARGUMENT,\n    'Invalid argument in `' + fnName + '` at index ' + index + ': ' + message\n  );\n}\n\nexport function invalidArgumentCount(\n  argMin: number,\n  argMax: number,\n  fnName: string,\n  real: number\n): FirebaseStorageError {\n  let countPart;\n  let plural;\n  if (argMin === argMax) {\n    countPart = argMin;\n    plural = argMin === 1 ? 'argument' : 'arguments';\n  } else {\n    countPart = 'between ' + argMin + ' and ' + argMax;\n    plural = 'arguments';\n  }\n  return new FirebaseStorageError(\n    Code.INVALID_ARGUMENT_COUNT,\n    'Invalid argument count in `' +\n      fnName +\n      '`: Expected ' +\n      countPart +\n      ' ' +\n      plural +\n      ', received ' +\n      real +\n      '.'\n  );\n}\n\nexport function appDeleted(): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.APP_DELETED,\n    'The Firebase app was deleted.'\n  );\n}\n\n/**\n * @param name The name of the operation that was invalid.\n */\nexport function invalidRootOperation(name: string): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_ROOT_OPERATION,\n    \"The operation '\" +\n      name +\n      \"' cannot be performed on a root reference, create a non-root \" +\n      \"reference using child, such as .child('file.png').\"\n  );\n}\n\n/**\n * @param format The format that was not valid.\n * @param message A message describing the format violation.\n */\nexport function invalidFormat(\n  format: string,\n  message: string\n): FirebaseStorageError {\n  return new FirebaseStorageError(\n    Code.INVALID_FORMAT,\n    \"String does not match format '\" + format + \"': \" + message\n  );\n}\n\n/**\n * @param message A message describing the internal error.\n */\nexport function internalError(message: string): FirebaseStorageError {\n  throw new FirebaseStorageError(\n    Code.INTERNAL_ERROR,\n    'Internal error: ' + 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 */\nimport * as errorsExports from './error';\n\n/**\n * @enum {string}\n */\nexport type StringFormat = string;\nexport const StringFormat = {\n  RAW: 'raw',\n  BASE64: 'base64',\n  BASE64URL: 'base64url',\n  DATA_URL: 'data_url'\n};\n\nexport function formatValidator(stringFormat: unknown): void {\n  switch (stringFormat) {\n    case StringFormat.RAW:\n    case StringFormat.BASE64:\n    case StringFormat.BASE64URL:\n    case StringFormat.DATA_URL:\n      return;\n    default:\n      throw (\n        'Expected one of the event types: [' +\n        StringFormat.RAW +\n        ', ' +\n        StringFormat.BASE64 +\n        ', ' +\n        StringFormat.BASE64URL +\n        ', ' +\n        StringFormat.DATA_URL +\n        '].'\n      );\n  }\n}\n\n/**\n * @struct\n */\nexport class StringData {\n  contentType: string | null;\n\n  constructor(public data: Uint8Array, contentType?: string | null) {\n    this.contentType = contentType || null;\n  }\n}\n\nexport function dataFromString(\n  format: StringFormat,\n  stringData: string\n): StringData {\n  switch (format) {\n    case StringFormat.RAW:\n      return new StringData(utf8Bytes_(stringData));\n    case StringFormat.BASE64:\n    case StringFormat.BASE64URL:\n      return new StringData(base64Bytes_(format, stringData));\n    case StringFormat.DATA_URL:\n      return new StringData(\n        dataURLBytes_(stringData),\n        dataURLContentType_(stringData)\n      );\n    default:\n    // do nothing\n  }\n\n  // assert(false);\n  throw errorsExports.unknown();\n}\n\nexport function utf8Bytes_(value: string): Uint8Array {\n  const b: number[] = [];\n  for (let i = 0; i < value.length; i++) {\n    let c = value.charCodeAt(i);\n    if (c <= 127) {\n      b.push(c);\n    } else {\n      if (c <= 2047) {\n        b.push(192 | (c >> 6), 128 | (c & 63));\n      } else {\n        if ((c & 64512) === 55296) {\n          // The start of a surrogate pair.\n          const valid =\n            i < value.length - 1 && (value.charCodeAt(i + 1) & 64512) === 56320;\n          if (!valid) {\n            // The second surrogate wasn't there.\n            b.push(239, 191, 189);\n          } else {\n            const hi = c;\n            const lo = value.charCodeAt(++i);\n            c = 65536 | ((hi & 1023) << 10) | (lo & 1023);\n            b.push(\n              240 | (c >> 18),\n              128 | ((c >> 12) & 63),\n              128 | ((c >> 6) & 63),\n              128 | (c & 63)\n            );\n          }\n        } else {\n          if ((c & 64512) === 56320) {\n            // Invalid low surrogate.\n            b.push(239, 191, 189);\n          } else {\n            b.push(224 | (c >> 12), 128 | ((c >> 6) & 63), 128 | (c & 63));\n          }\n        }\n      }\n    }\n  }\n  return new Uint8Array(b);\n}\n\nexport function percentEncodedBytes_(value: string): Uint8Array {\n  let decoded;\n  try {\n    decoded = decodeURIComponent(value);\n  } catch (e) {\n    throw errorsExports.invalidFormat(\n      StringFormat.DATA_URL,\n      'Malformed data URL.'\n    );\n  }\n  return utf8Bytes_(decoded);\n}\n\nexport function base64Bytes_(format: StringFormat, value: string): Uint8Array {\n  switch (format) {\n    case StringFormat.BASE64: {\n      const hasMinus = value.indexOf('-') !== -1;\n      const hasUnder = value.indexOf('_') !== -1;\n      if (hasMinus || hasUnder) {\n        const invalidChar = hasMinus ? '-' : '_';\n        throw errorsExports.invalidFormat(\n          format,\n          \"Invalid character '\" +\n            invalidChar +\n            \"' found: is it base64url encoded?\"\n        );\n      }\n      break;\n    }\n    case StringFormat.BASE64URL: {\n      const hasPlus = value.indexOf('+') !== -1;\n      const hasSlash = value.indexOf('/') !== -1;\n      if (hasPlus || hasSlash) {\n        const invalidChar = hasPlus ? '+' : '/';\n        throw errorsExports.invalidFormat(\n          format,\n          \"Invalid character '\" + invalidChar + \"' found: is it base64 encoded?\"\n        );\n      }\n      value = value.replace(/-/g, '+').replace(/_/g, '/');\n      break;\n    }\n    default:\n    // do nothing\n  }\n  let bytes;\n  try {\n    bytes = atob(value);\n  } catch (e) {\n    throw errorsExports.invalidFormat(format, 'Invalid character found');\n  }\n  const array = new Uint8Array(bytes.length);\n  for (let i = 0; i < bytes.length; i++) {\n    array[i] = bytes.charCodeAt(i);\n  }\n  return array;\n}\n\n/**\n * @struct\n */\nclass DataURLParts {\n  base64: boolean = false;\n  contentType: string | null = null;\n  rest: string;\n\n  constructor(dataURL: string) {\n    const matches = dataURL.match(/^data:([^,]+)?,/);\n    if (matches === null) {\n      throw errorsExports.invalidFormat(\n        StringFormat.DATA_URL,\n        \"Must be formatted 'data:[<mediatype>][;base64],<data>\"\n      );\n    }\n    const middle = matches[1] || null;\n    if (middle != null) {\n      this.base64 = endsWith(middle, ';base64');\n      this.contentType = this.base64\n        ? middle.substring(0, middle.length - ';base64'.length)\n        : middle;\n    }\n    this.rest = dataURL.substring(dataURL.indexOf(',') + 1);\n  }\n}\n\nexport function dataURLBytes_(dataUrl: string): Uint8Array {\n  const parts = new DataURLParts(dataUrl);\n  if (parts.base64) {\n    return base64Bytes_(StringFormat.BASE64, parts.rest);\n  } else {\n    return percentEncodedBytes_(parts.rest);\n  }\n}\n\nexport function dataURLContentType_(dataUrl: string): string | null {\n  const parts = new DataURLParts(dataUrl);\n  return parts.contentType;\n}\n\nfunction endsWith(s: string, end: string): boolean {\n  const longEnough = s.length >= end.length;\n  if (!longEnough) {\n    return false;\n  }\n\n  return s.substring(s.length - end.length) === end;\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 Enumerations used for upload tasks.\n */\n\n/**\n * Enum for task events.\n * @enum {string}\n */\nexport type TaskEvent = string;\nexport const TaskEvent = {\n  /** Triggered whenever the task changes or progress is updated. */\n  STATE_CHANGED: 'state_changed'\n};\n\n/**\n * Internal enum for task state.\n * @enum {string}\n */\nexport type InternalTaskState = string;\nexport const InternalTaskState = {\n  RUNNING: 'running',\n  PAUSING: 'pausing',\n  PAUSED: 'paused',\n  SUCCESS: 'success',\n  CANCELING: 'canceling',\n  CANCELED: 'canceled',\n  ERROR: 'error'\n};\n\n/**\n * External (API-surfaced) enum for task state.\n * @enum {string}\n */\nexport type TaskState = string;\nexport const TaskState = {\n  /** The task is currently transferring data. */\n  RUNNING: 'running',\n  /** The task was paused by the user. */\n  PAUSED: 'paused',\n  /** The task completed successfully. */\n  SUCCESS: 'success',\n  /** The task was canceled. */\n  CANCELED: 'canceled',\n  /** The task failed with an error. */\n  ERROR: 'error'\n};\n\nexport function taskStateFromInternalTaskState(\n  state: InternalTaskState\n): TaskState {\n  switch (state) {\n    case InternalTaskState.RUNNING:\n    case InternalTaskState.PAUSING:\n    case InternalTaskState.CANCELING:\n      return TaskState.RUNNING;\n    case InternalTaskState.PAUSED:\n      return TaskState.PAUSED;\n    case InternalTaskState.SUCCESS:\n      return TaskState.SUCCESS;\n    case InternalTaskState.CANCELED:\n      return TaskState.CANCELED;\n    case InternalTaskState.ERROR:\n      return TaskState.ERROR;\n    default:\n      // TODO(andysoto): assert(false);\n      return TaskState.ERROR;\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 * @return False if the object is undefined or null, true otherwise.\n */\nexport function isDef<T>(p: T | null | undefined): p is T {\n  return p != null;\n}\n\nexport function isJustDef<T>(p: T | null | undefined): p is T | null {\n  return p !== void 0;\n}\n\nexport function isFunction(p: unknown): p is Function {\n  return typeof p === 'function';\n}\n\nexport function isObject(p: unknown): p is { [key: string]: unknown } | null {\n  return typeof p === 'object';\n}\n\nexport function isNonNullObject(p: unknown): p is object {\n  return isObject(p) && p !== null;\n}\n\nexport function isNonArrayObject(p: unknown): boolean {\n  return isObject(p) && !Array.isArray(p);\n}\n\nexport function isString(p: unknown): p is string {\n  return typeof p === 'string' || p instanceof String;\n}\n\nexport function isInteger(p: unknown): p is number {\n  return isNumber(p) && Number.isInteger(p);\n}\n\nexport function isNumber(p: unknown): p is number {\n  return typeof p === 'number' || p instanceof Number;\n}\n\nexport function isNativeBlob(p: unknown): p is Blob {\n  return isNativeBlobDefined() && p instanceof Blob;\n}\n\nexport function isNativeBlobDefined(): boolean {\n  return typeof Blob !== 'undefined';\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 A lightweight wrapper around XMLHttpRequest with a\n * goog.net.XhrIo-like interface.\n */\n\nexport interface Headers {\n  [name: string]: string | number;\n}\n\nexport interface XhrIo {\n  send(\n    url: string,\n    method: string,\n    body?: ArrayBufferView | Blob | string | null,\n    headers?: Headers\n  ): Promise<XhrIo>;\n\n  getErrorCode(): ErrorCode;\n\n  getStatus(): number;\n\n  getResponseText(): string;\n\n  /**\n   * Abort the request.\n   */\n  abort(): void;\n\n  getResponseHeader(header: string): string | null;\n\n  addUploadProgressListener(listener: (p1: ProgressEvent) => void): void;\n\n  removeUploadProgressListener(listener: (p1: ProgressEvent) => void): void;\n}\n\n/**\n * @enum{number}\n */\nexport enum ErrorCode {\n  NO_ERROR = 0,\n  NETWORK_ERROR = 1,\n  ABORT = 2\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 */\nimport * as errorsExports from './error';\nimport * as type from './type';\nimport { Headers, XhrIo, ErrorCode } from './xhrio';\n\n/**\n * We use this instead of goog.net.XhrIo because goog.net.XhrIo is hyuuuuge and\n * doesn't work in React Native on Android.\n */\nexport class NetworkXhrIo implements XhrIo {\n  private xhr_: XMLHttpRequest;\n  private errorCode_: ErrorCode;\n  private sendPromise_: Promise<XhrIo>;\n  private sent_: boolean = false;\n\n  constructor() {\n    this.xhr_ = new XMLHttpRequest();\n    this.errorCode_ = ErrorCode.NO_ERROR;\n    this.sendPromise_ = new Promise(resolve => {\n      this.xhr_.addEventListener('abort', () => {\n        this.errorCode_ = ErrorCode.ABORT;\n        resolve(this);\n      });\n      this.xhr_.addEventListener('error', () => {\n        this.errorCode_ = ErrorCode.NETWORK_ERROR;\n        resolve(this);\n      });\n      this.xhr_.addEventListener('load', () => {\n        resolve(this);\n      });\n    });\n  }\n\n  /**\n   * @override\n   */\n  send(\n    url: string,\n    method: string,\n    body?: ArrayBufferView | Blob | string | null,\n    headers?: Headers\n  ): Promise<XhrIo> {\n    if (this.sent_) {\n      throw errorsExports.internalError('cannot .send() more than once');\n    }\n    this.sent_ = true;\n    this.xhr_.open(method, url, true);\n    if (type.isDef(headers)) {\n      for (const key in headers) {\n        if (headers.hasOwnProperty(key)) {\n          this.xhr_.setRequestHeader(key, headers[key].toString());\n        }\n      }\n    }\n    if (type.isDef(body)) {\n      this.xhr_.send(body);\n    } else {\n      this.xhr_.send();\n    }\n    return this.sendPromise_;\n  }\n\n  /**\n   * @override\n   */\n  getErrorCode(): ErrorCode {\n    if (!this.sent_) {\n      throw errorsExports.internalError(\n        'cannot .getErrorCode() before sending'\n      );\n    }\n    return this.errorCode_;\n  }\n\n  /**\n   * @override\n   */\n  getStatus(): number {\n    if (!this.sent_) {\n      throw errorsExports.internalError('cannot .getStatus() before sending');\n    }\n    try {\n      return this.xhr_.status;\n    } catch (e) {\n      return -1;\n    }\n  }\n\n  /**\n   * @override\n   */\n  getResponseText(): string {\n    if (!this.sent_) {\n      throw errorsExports.internalError(\n        'cannot .getResponseText() before sending'\n      );\n    }\n    return this.xhr_.responseText;\n  }\n\n  /**\n   * Aborts the request.\n   * @override\n   */\n  abort(): void {\n    this.xhr_.abort();\n  }\n\n  /**\n   * @override\n   */\n  getResponseHeader(header: string): string | null {\n    return this.xhr_.getResponseHeader(header);\n  }\n\n  /**\n   * @override\n   */\n  addUploadProgressListener(listener: (p1: ProgressEvent) => void): void {\n    if (type.isDef(this.xhr_.upload)) {\n      this.xhr_.upload.addEventListener('progress', listener);\n    }\n  }\n\n  /**\n   * @override\n   */\n  removeUploadProgressListener(listener: (p1: ProgressEvent) => void): void {\n    if (type.isDef(this.xhr_.upload)) {\n      this.xhr_.upload.removeEventListener('progress', listener);\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\n/**\n * @fileoverview Replacement for goog.net.XhrIoPool that works with fbs.XhrIo.\n */\nimport { XhrIo } from './xhrio';\nimport { NetworkXhrIo } from './xhrio_network';\n\n/**\n * Factory-like class for creating XhrIo instances.\n */\nexport class XhrIoPool {\n  createXhrIo(): XhrIo {\n    return new NetworkXhrIo();\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 * @fileoverview Some methods copied from goog.fs.\n * We don't include goog.fs because it pulls in a bunch of Deferred code that\n * bloats the size of the released binary.\n */\nimport * as type from './type';\n\nfunction getBlobBuilder(): typeof IBlobBuilder | undefined {\n  if (typeof BlobBuilder !== 'undefined') {\n    return BlobBuilder;\n  } else if (typeof WebKitBlobBuilder !== 'undefined') {\n    return WebKitBlobBuilder;\n  } else {\n    return undefined;\n  }\n}\n\n/**\n * Concatenates one or more values together and converts them to a Blob.\n *\n * @param args The values that will make up the resulting blob.\n * @return The blob.\n */\nexport function getBlob(...args: Array<string | Blob | ArrayBuffer>): Blob {\n  const BlobBuilder = getBlobBuilder();\n  if (BlobBuilder !== undefined) {\n    const bb = new BlobBuilder();\n    for (let i = 0; i < args.length; i++) {\n      bb.append(args[i]);\n    }\n    return bb.getBlob();\n  } else {\n    if (type.isNativeBlobDefined()) {\n      return new Blob(args);\n    } else {\n      throw Error(\"This browser doesn't seem to support creating Blobs\");\n    }\n  }\n}\n\n/**\n * Slices the blob. The returned blob contains data from the start byte\n * (inclusive) till the end byte (exclusive). Negative indices cannot be used.\n *\n * @param blob The blob to be sliced.\n * @param start Index of the starting byte.\n * @param end Index of the ending byte.\n * @return The blob slice or null if not supported.\n */\nexport function sliceBlob(blob: Blob, start: number, end: number): Blob | null {\n  if (blob.webkitSlice) {\n    return blob.webkitSlice(start, end);\n  } else if (blob.mozSlice) {\n    return blob.mozSlice(start, end);\n  } else if (blob.slice) {\n    return blob.slice(start, end);\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 * @file Provides a Blob-like wrapper for various binary types (including the\n * native Blob type). This makes it possible to upload types like ArrayBuffers,\n * making uploads possible in environments without the native Blob type.\n */\nimport * as fs from './fs';\nimport { StringFormat, dataFromString } from './string';\nimport * as type from './type';\n\n/**\n * @param opt_elideCopy If true, doesn't copy mutable input data\n *     (e.g. Uint8Arrays). Pass true only if you know the objects will not be\n *     modified after this blob's construction.\n */\nexport class FbsBlob {\n  private data_!: Blob | Uint8Array;\n  private size_: number;\n  private type_: string;\n\n  constructor(data: Blob | Uint8Array | ArrayBuffer, elideCopy?: boolean) {\n    let size: number = 0;\n    let blobType: string = '';\n    if (type.isNativeBlob(data)) {\n      this.data_ = data as Blob;\n      size = (data as Blob).size;\n      blobType = (data as Blob).type;\n    } else if (data instanceof ArrayBuffer) {\n      if (elideCopy) {\n        this.data_ = new Uint8Array(data);\n      } else {\n        this.data_ = new Uint8Array(data.byteLength);\n        this.data_.set(new Uint8Array(data));\n      }\n      size = this.data_.length;\n    } else if (data instanceof Uint8Array) {\n      if (elideCopy) {\n        this.data_ = data as Uint8Array;\n      } else {\n        this.data_ = new Uint8Array(data.length);\n        this.data_.set(data as Uint8Array);\n      }\n      size = data.length;\n    }\n    this.size_ = size;\n    this.type_ = blobType;\n  }\n\n  size(): number {\n    return this.size_;\n  }\n\n  type(): string {\n    return this.type_;\n  }\n\n  slice(startByte: number, endByte: number): FbsBlob | null {\n    if (type.isNativeBlob(this.data_)) {\n      const realBlob = this.data_ as Blob;\n      const sliced = fs.sliceBlob(realBlob, startByte, endByte);\n      if (sliced === null) {\n        return null;\n      }\n      return new FbsBlob(sliced);\n    } else {\n      const slice = new Uint8Array(\n        (this.data_ as Uint8Array).buffer,\n        startByte,\n        endByte - startByte\n      );\n      return new FbsBlob(slice, true);\n    }\n  }\n\n  static getBlob(...args: Array<string | FbsBlob>): FbsBlob | null {\n    if (type.isNativeBlobDefined()) {\n      const blobby: Array<Blob | Uint8Array | string> = args.map(\n        (val: string | FbsBlob): Blob | Uint8Array | string => {\n          if (val instanceof FbsBlob) {\n            return val.data_;\n          } else {\n            return val;\n          }\n        }\n      );\n      return new FbsBlob(fs.getBlob.apply(null, blobby));\n    } else {\n      const uint8Arrays: Uint8Array[] = args.map(\n        (val: string | FbsBlob): Uint8Array => {\n          if (type.isString(val)) {\n            return dataFromString(StringFormat.RAW, val as string).data;\n          } else {\n            // Blobs don't exist, so this has to be a Uint8Array.\n            return (val as FbsBlob).data_ as Uint8Array;\n          }\n        }\n      );\n      let finalLength = 0;\n      uint8Arrays.forEach((array: Uint8Array): void => {\n        finalLength += array.byteLength;\n      });\n      const merged = new Uint8Array(finalLength);\n      let index = 0;\n      uint8Arrays.forEach((array: Uint8Array) => {\n        for (let i = 0; i < array.length; i++) {\n          merged[index++] = array[i];\n        }\n      });\n      return new FbsBlob(merged, true);\n    }\n  }\n\n  uploadData(): Blob | Uint8Array {\n    return this.data_;\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 Functionality related to the parsing/composition of bucket/\n * object location.\n */\nimport * as errorsExports from './error';\nimport { DEFAULT_HOST } from './constants';\n\n/**\n * @struct\n */\nexport class Location {\n  private path_: string;\n\n  constructor(public readonly bucket: string, path: string) {\n    this.path_ = path;\n  }\n\n  get path(): string {\n    return this.path_;\n  }\n\n  get isRoot(): boolean {\n    return this.path.length === 0;\n  }\n\n  fullServerUrl(): string {\n    const encode = encodeURIComponent;\n    return '/b/' + encode(this.bucket) + '/o/' + encode(this.path);\n  }\n\n  bucketOnlyServerUrl(): string {\n    const encode = encodeURIComponent;\n    return '/b/' + encode(this.bucket) + '/o';\n  }\n\n  static makeFromBucketSpec(bucketString: string): Location {\n    let bucketLocation;\n    try {\n      bucketLocation = Location.makeFromUrl(bucketString);\n    } catch (e) {\n      // Not valid URL, use as-is. This lets you put bare bucket names in\n      // config.\n      return new Location(bucketString, '');\n    }\n    if (bucketLocation.path === '') {\n      return bucketLocation;\n    } else {\n      throw errorsExports.invalidDefaultBucket(bucketString);\n    }\n  }\n\n  static makeFromUrl(url: string): Location {\n    let location: Location | null = null;\n    const bucketDomain = '([A-Za-z0-9.\\\\-_]+)';\n\n    function gsModify(loc: Location): void {\n      if (loc.path.charAt(loc.path.length - 1) === '/') {\n        loc.path_ = loc.path_.slice(0, -1);\n      }\n    }\n    const gsPath = '(/(.*))?$';\n    const gsRegex = new RegExp('^gs://' + bucketDomain + gsPath, 'i');\n    const gsIndices = { bucket: 1, path: 3 };\n\n    function httpModify(loc: Location): void {\n      loc.path_ = decodeURIComponent(loc.path);\n    }\n    const version = 'v[A-Za-z0-9_]+';\n    const firebaseStorageHost = DEFAULT_HOST.replace(/[.]/g, '\\\\.');\n    const firebaseStoragePath = '(/([^?#]*).*)?$';\n    const firebaseStorageRegExp = new RegExp(\n      `^https?://${firebaseStorageHost}/${version}/b/${bucketDomain}/o${firebaseStoragePath}`,\n      'i'\n    );\n    const firebaseStorageIndices = { bucket: 1, path: 3 };\n\n    const cloudStorageHost =\n      '(?:storage.googleapis.com|storage.cloud.google.com)';\n    const cloudStoragePath = '([^?#]*)';\n    const cloudStorageRegExp = new RegExp(\n      `^https?://${cloudStorageHost}/${bucketDomain}/${cloudStoragePath}`,\n      'i'\n    );\n    const cloudStorageIndices = { bucket: 1, path: 2 };\n\n    const groups = [\n      { regex: gsRegex, indices: gsIndices, postModify: gsModify },\n      {\n        regex: firebaseStorageRegExp,\n        indices: firebaseStorageIndices,\n        postModify: httpModify\n      },\n      {\n        regex: cloudStorageRegExp,\n        indices: cloudStorageIndices,\n        postModify: httpModify\n      }\n    ];\n    for (let i = 0; i < groups.length; i++) {\n      const group = groups[i];\n      const captures = group.regex.exec(url);\n      if (captures) {\n        const bucketValue = captures[group.indices.bucket];\n        let pathValue = captures[group.indices.path];\n        if (!pathValue) {\n          pathValue = '';\n        }\n        location = new Location(bucketValue, pathValue);\n        group.postModify(location);\n        break;\n      }\n    }\n    if (location == null) {\n      throw errorsExports.invalidUrl(url);\n    }\n    return location;\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 */\nimport * as type from './type';\n\n/**\n * Returns the Object resulting from parsing the given JSON, or null if the\n * given string does not represent a JSON object.\n */\nexport function jsonObjectOrNull(\n  s: string\n): { [name: string]: unknown } | null {\n  let obj;\n  try {\n    obj = JSON.parse(s);\n  } catch (e) {\n    return null;\n  }\n  if (type.isNonArrayObject(obj)) {\n    return obj;\n  } else {\n    return null;\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 Contains helper methods for manipulating paths.\n */\n\n/**\n * @return Null if the path is already at the root.\n */\nexport function parent(path: string): string | null {\n  if (path.length === 0) {\n    return null;\n  }\n  const index = path.lastIndexOf('/');\n  if (index === -1) {\n    return '';\n  }\n  const newPath = path.slice(0, index);\n  return newPath;\n}\n\nexport function child(path: string, childPath: string): string {\n  const canonicalChildPath = childPath\n    .split('/')\n    .filter(component => component.length > 0)\n    .join('/');\n  if (path.length === 0) {\n    return canonicalChildPath;\n  } else {\n    return path + '/' + canonicalChildPath;\n  }\n}\n\n/**\n * Returns the last component of a path.\n * '/foo/bar' -> 'bar'\n * '/foo/bar/baz/' -> 'baz/'\n * '/a' -> 'a'\n */\nexport function lastComponent(path: string): string {\n  const index = path.lastIndexOf('/', path.length - 2);\n  if (index === -1) {\n    return path;\n  } else {\n    return path.slice(index + 1);\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 Functions to create and manipulate URLs for the server API.\n */\nimport { DEFAULT_HOST } from './constants';\nimport { UrlParams } from './requestinfo';\n\nexport function makeUrl(urlPart: string): string {\n  return `https://${DEFAULT_HOST}/v0${urlPart}`;\n}\n\nexport function makeQueryString(params: UrlParams): string {\n  const encode = encodeURIComponent;\n  let queryPart = '?';\n  for (const key in params) {\n    if (params.hasOwnProperty(key)) {\n      // @ts-ignore TODO: remove once typescript is upgraded to 3.5.x\n      const nextPart = encode(key) + '=' + encode(params[key]);\n      queryPart = queryPart + nextPart + '&';\n    }\n  }\n\n  // Chop off the extra '&' or '?' on the end\n  queryPart = queryPart.slice(0, -1);\n  return queryPart;\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 Documentation for the metadata format\n */\nimport { Metadata } from '../metadata';\n\nimport * as json from './json';\nimport { Location } from './location';\nimport * as path from './path';\nimport * as type from './type';\nimport * as UrlUtils from './url';\nimport { Reference } from '../reference';\nimport { StorageService } from '../service';\n\nexport function noXform_<T>(metadata: Metadata, value: T): T {\n  return value;\n}\n\n/**\n * @struct\n */\nclass Mapping<T> {\n  local: string;\n  writable: boolean;\n  xform: (p1: Metadata, p2?: T) => T | undefined;\n\n  constructor(\n    public server: string,\n    local?: string | null,\n    writable?: boolean,\n    xform?: ((p1: Metadata, p2?: T) => T | undefined) | null\n  ) {\n    this.local = local || server;\n    this.writable = !!writable;\n    this.xform = xform || noXform_;\n  }\n}\ntype Mappings = Array<Mapping<string> | Mapping<number>>;\n\nexport { Mappings };\n\nlet mappings_: Mappings | null = null;\n\nexport function xformPath(fullPath: string | undefined): string | undefined {\n  if (!type.isString(fullPath) || fullPath.length < 2) {\n    return fullPath;\n  } else {\n    return path.lastComponent(fullPath);\n  }\n}\n\nexport function getMappings(): Mappings {\n  if (mappings_) {\n    return mappings_;\n  }\n  const mappings: Mappings = [];\n  mappings.push(new Mapping<string>('bucket'));\n  mappings.push(new Mapping<string>('generation'));\n  mappings.push(new Mapping<string>('metageneration'));\n  mappings.push(new Mapping<string>('name', 'fullPath', true));\n\n  function mappingsXformPath(\n    _metadata: Metadata,\n    fullPath: string | undefined\n  ): string | undefined {\n    return xformPath(fullPath);\n  }\n  const nameMapping = new Mapping<string>('name');\n  nameMapping.xform = mappingsXformPath;\n  mappings.push(nameMapping);\n\n  /**\n   * Coerces the second param to a number, if it is defined.\n   */\n  function xformSize(\n    _metadata: Metadata,\n    size: number | string | undefined\n  ): number | undefined {\n    if (type.isDef(size)) {\n      return Number(size);\n    } else {\n      return size;\n    }\n  }\n  const sizeMapping = new Mapping<number>('size');\n  sizeMapping.xform = xformSize;\n  mappings.push(sizeMapping);\n  mappings.push(new Mapping<number>('timeCreated'));\n  mappings.push(new Mapping<string>('updated'));\n  mappings.push(new Mapping<string>('md5Hash', null, true));\n  mappings.push(new Mapping<string>('cacheControl', null, true));\n  mappings.push(new Mapping<string>('contentDisposition', null, true));\n  mappings.push(new Mapping<string>('contentEncoding', null, true));\n  mappings.push(new Mapping<string>('contentLanguage', null, true));\n  mappings.push(new Mapping<string>('contentType', null, true));\n  mappings.push(new Mapping<string>('metadata', 'customMetadata', true));\n  mappings_ = mappings;\n  return mappings_;\n}\n\nexport function addRef(metadata: Metadata, service: StorageService): void {\n  function generateRef(): Reference {\n    const bucket: string = metadata['bucket'] as string;\n    const path: string = metadata['fullPath'] as string;\n    const loc = new Location(bucket, path);\n    return service.makeStorageReference(loc);\n  }\n  Object.defineProperty(metadata, 'ref', { get: generateRef });\n}\n\nexport function fromResource(\n  service: StorageService,\n  resource: { [name: string]: unknown },\n  mappings: Mappings\n): Metadata {\n  const metadata: Metadata = {} as Metadata;\n  metadata['type'] = 'file';\n  const len = mappings.length;\n  for (let i = 0; i < len; i++) {\n    const mapping = mappings[i];\n    metadata[mapping.local] = (mapping as Mapping<unknown>).xform(\n      metadata,\n      resource[mapping.server]\n    );\n  }\n  addRef(metadata, service);\n  return metadata;\n}\n\nexport function fromResourceString(\n  service: StorageService,\n  resourceString: string,\n  mappings: Mappings\n): Metadata | null {\n  const obj = json.jsonObjectOrNull(resourceString);\n  if (obj === null) {\n    return null;\n  }\n  const resource = obj as Metadata;\n  return fromResource(service, resource, mappings);\n}\n\nexport function downloadUrlFromResourceString(\n  metadata: Metadata,\n  resourceString: string\n): string | null {\n  const obj = json.jsonObjectOrNull(resourceString);\n  if (obj === null) {\n    return null;\n  }\n  if (!type.isString(obj['downloadTokens'])) {\n    // This can happen if objects are uploaded through GCS and retrieved\n    // through list, so we don't want to throw an Error.\n    return null;\n  }\n  const tokens: string = obj['downloadTokens'] as string;\n  if (tokens.length === 0) {\n    return null;\n  }\n  const encode = encodeURIComponent;\n  const tokensList = tokens.split(',');\n  const urls = tokensList.map((token: string): string => {\n    const bucket: string = metadata['bucket'] as string;\n    const path: string = metadata['fullPath'] as string;\n    const urlPart = '/b/' + encode(bucket) + '/o/' + encode(path);\n    const base = UrlUtils.makeUrl(urlPart);\n    const queryString = UrlUtils.makeQueryString({\n      alt: 'media',\n      token\n    });\n    return base + queryString;\n  });\n  return urls[0];\n}\n\nexport function toResourceString(\n  metadata: Metadata,\n  mappings: Mappings\n): string {\n  const resource: {\n    [prop: string]: unknown;\n  } = {};\n  const len = mappings.length;\n  for (let i = 0; i < len; i++) {\n    const mapping = mappings[i];\n    if (mapping.writable) {\n      resource[mapping.server] = metadata[mapping.local];\n    }\n  }\n  return JSON.stringify(resource);\n}\n\nexport function metadataValidator(p: unknown): void {\n  if (!type.isObject(p) || !p) {\n    throw 'Expected Metadata object.';\n  }\n  for (const key in p) {\n    if (p.hasOwnProperty(key)) {\n      const val = p[key];\n      if (key === 'customMetadata') {\n        if (!type.isObject(val)) {\n          throw 'Expected object for \\'customMetadata\\' mapping.';\n        }\n      } else {\n        if (type.isNonNullObject(val)) {\n          throw \"Mapping for '\" + key + \"' cannot be an object.\";\n        }\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\n/**\n * @fileoverview Documentation for the listOptions and listResult format\n */\nimport { Location } from './location';\nimport * as json from './json';\nimport * as type from './type';\nimport { ListResult } from '../list';\nimport { StorageService } from '../service';\n\n/**\n * Represents the simplified object metadata returned by List API.\n * Other fields are filtered because list in Firebase Rules does not grant\n * the permission to read the metadata.\n */\ninterface ListMetadataResponse {\n  name: string;\n  bucket: string;\n}\n\n/**\n * Represents the JSON response of List API.\n */\ninterface ListResultResponse {\n  prefixes: string[];\n  items: ListMetadataResponse[];\n  nextPageToken?: string;\n}\n\nconst MAX_RESULTS_KEY = 'maxResults';\nconst MAX_MAX_RESULTS = 1000;\nconst PAGE_TOKEN_KEY = 'pageToken';\nconst PREFIXES_KEY = 'prefixes';\nconst ITEMS_KEY = 'items';\n\nfunction fromBackendResponse(\n  service: StorageService,\n  bucket: string,\n  resource: ListResultResponse\n): ListResult {\n  const listResult: ListResult = {\n    prefixes: [],\n    items: [],\n    nextPageToken: resource['nextPageToken']\n  };\n  if (resource[PREFIXES_KEY]) {\n    for (const path of resource[PREFIXES_KEY]) {\n      const pathWithoutTrailingSlash = path.replace(/\\/$/, '');\n      const reference = service.makeStorageReference(\n        new Location(bucket, pathWithoutTrailingSlash)\n      );\n      listResult.prefixes.push(reference);\n    }\n  }\n\n  if (resource[ITEMS_KEY]) {\n    for (const item of resource[ITEMS_KEY]) {\n      const reference = service.makeStorageReference(\n        new Location(bucket, item['name'])\n      );\n      listResult.items.push(reference);\n    }\n  }\n  return listResult;\n}\n\nexport function fromResponseString(\n  service: StorageService,\n  bucket: string,\n  resourceString: string\n): ListResult | null {\n  const obj = json.jsonObjectOrNull(resourceString);\n  if (obj === null) {\n    return null;\n  }\n  const resource = (obj as unknown) as ListResultResponse;\n  return fromBackendResponse(service, bucket, resource);\n}\n\nexport function listOptionsValidator(p: unknown): void {\n  if (!type.isObject(p) || !p) {\n    throw 'Expected ListOptions object.';\n  }\n  for (const key in p) {\n    if (key === MAX_RESULTS_KEY) {\n      if (\n        !type.isInteger(p[MAX_RESULTS_KEY]) ||\n        (p[MAX_RESULTS_KEY] as number) <= 0\n      ) {\n        throw 'Expected maxResults to be a positive number.';\n      }\n      if ((p[MAX_RESULTS_KEY] as number) > 1000) {\n        throw `Expected maxResults to be less than or equal to ${MAX_MAX_RESULTS}.`;\n      }\n    } else if (key === PAGE_TOKEN_KEY) {\n      if (p[PAGE_TOKEN_KEY] && !type.isString(p[PAGE_TOKEN_KEY])) {\n        throw 'Expected pageToken to be string.';\n      }\n    } else {\n      throw 'Unknown option: ' + key;\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 */\nimport { FirebaseStorageError } from './error';\nimport { Headers, XhrIo } from './xhrio';\n\nexport interface UrlParams {\n  [name: string]: string | number;\n}\n\nexport class RequestInfo<T> {\n  urlParams: UrlParams = {};\n  headers: Headers = {};\n  body: Blob | string | Uint8Array | null = null;\n\n  errorHandler:\n    | ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError)\n    | null = null;\n\n  /**\n   * Called with the current number of bytes uploaded and total size (-1 if not\n   * computable) of the request body (i.e. used to report upload progress).\n   */\n  progressCallback: ((p1: number, p2: number) => void) | null = null;\n  successCodes: number[] = [200];\n  additionalRetryCodes: number[] = [];\n\n  constructor(\n    public url: string,\n    public method: string,\n    /**\n     * Returns the value with which to resolve the request's promise. Only called\n     * if the request is successful. Throw from this function to reject the\n     * returned Request's promise with the thrown error.\n     * Note: The XhrIo passed to this function may be reused after this callback\n     * returns. Do not keep a reference to it in any way.\n     */\n    public handler: (p1: XhrIo, p2: string) => T,\n    public timeout: number\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 Defines methods for interacting with the network.\n */\n\nimport { Metadata } from '../metadata';\nimport { ListResult } from '../list';\nimport { FbsBlob } from './blob';\nimport {\n  FirebaseStorageError,\n  cannotSliceBlob,\n  unauthenticated,\n  quotaExceeded,\n  unauthorized,\n  objectNotFound,\n  serverFileWrongSize,\n  unknown\n} from './error';\nimport { Location } from './location';\nimport * as MetadataUtils from './metadata';\nimport * as ListResultUtils from './list';\nimport { RequestInfo, UrlParams } from './requestinfo';\nimport * as type from './type';\nimport * as UrlUtils from './url';\nimport { XhrIo } from './xhrio';\nimport { StorageService } from '../service';\n\n/**\n * Throws the UNKNOWN FirebaseStorageError if cndn is false.\n */\nexport function handlerCheck(cndn: boolean): void {\n  if (!cndn) {\n    throw unknown();\n  }\n}\n\nexport function metadataHandler(\n  service: StorageService,\n  mappings: MetadataUtils.Mappings\n): (p1: XhrIo, p2: string) => Metadata {\n  function handler(xhr: XhrIo, text: string): Metadata {\n    const metadata = MetadataUtils.fromResourceString(service, text, mappings);\n    handlerCheck(metadata !== null);\n    return metadata as Metadata;\n  }\n  return handler;\n}\n\nexport function listHandler(\n  service: StorageService,\n  bucket: string\n): (p1: XhrIo, p2: string) => ListResult {\n  function handler(xhr: XhrIo, text: string): ListResult {\n    const listResult = ListResultUtils.fromResponseString(\n      service,\n      bucket,\n      text\n    );\n    handlerCheck(listResult !== null);\n    return listResult as ListResult;\n  }\n  return handler;\n}\n\nexport function downloadUrlHandler(\n  service: StorageService,\n  mappings: MetadataUtils.Mappings\n): (p1: XhrIo, p2: string) => string | null {\n  function handler(xhr: XhrIo, text: string): string | null {\n    const metadata = MetadataUtils.fromResourceString(service, text, mappings);\n    handlerCheck(metadata !== null);\n    return MetadataUtils.downloadUrlFromResourceString(\n      metadata as Metadata,\n      text\n    );\n  }\n  return handler;\n}\n\nexport function sharedErrorHandler(\n  location: Location\n): (p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError {\n  function errorHandler(\n    xhr: XhrIo,\n    err: FirebaseStorageError\n  ): FirebaseStorageError {\n    let newErr;\n    if (xhr.getStatus() === 401) {\n      newErr = unauthenticated();\n    } else {\n      if (xhr.getStatus() === 402) {\n        newErr = quotaExceeded(location.bucket);\n      } else {\n        if (xhr.getStatus() === 403) {\n          newErr = unauthorized(location.path);\n        } else {\n          newErr = err;\n        }\n      }\n    }\n    newErr.setServerResponseProp(err.serverResponseProp());\n    return newErr;\n  }\n  return errorHandler;\n}\n\nexport function objectErrorHandler(\n  location: Location\n): (p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError {\n  const shared = sharedErrorHandler(location);\n\n  function errorHandler(\n    xhr: XhrIo,\n    err: FirebaseStorageError\n  ): FirebaseStorageError {\n    let newErr = shared(xhr, err);\n    if (xhr.getStatus() === 404) {\n      newErr = objectNotFound(location.path);\n    }\n    newErr.setServerResponseProp(err.serverResponseProp());\n    return newErr;\n  }\n  return errorHandler;\n}\n\nexport function getMetadata(\n  service: StorageService,\n  location: Location,\n  mappings: MetadataUtils.Mappings\n): RequestInfo<Metadata> {\n  const urlPart = location.fullServerUrl();\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'GET';\n  const timeout = service.maxOperationRetryTime;\n  const requestInfo = new RequestInfo(\n    url,\n    method,\n    metadataHandler(service, mappings),\n    timeout\n  );\n  requestInfo.errorHandler = objectErrorHandler(location);\n  return requestInfo;\n}\n\nexport function list(\n  service: StorageService,\n  location: Location,\n  delimiter?: string,\n  pageToken?: string | null,\n  maxResults?: number | null\n): RequestInfo<ListResult> {\n  const urlParams: UrlParams = {};\n  if (location.isRoot) {\n    urlParams['prefix'] = '';\n  } else {\n    urlParams['prefix'] = location.path + '/';\n  }\n  if (delimiter && delimiter.length > 0) {\n    urlParams['delimiter'] = delimiter;\n  }\n  if (pageToken) {\n    urlParams['pageToken'] = pageToken;\n  }\n  if (maxResults) {\n    urlParams['maxResults'] = maxResults;\n  }\n  const urlPart = location.bucketOnlyServerUrl();\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'GET';\n  const timeout = service.maxOperationRetryTime;\n  const requestInfo = new RequestInfo(\n    url,\n    method,\n    listHandler(service, location.bucket),\n    timeout\n  );\n  requestInfo.urlParams = urlParams;\n  requestInfo.errorHandler = sharedErrorHandler(location);\n  return requestInfo;\n}\n\nexport function getDownloadUrl(\n  service: StorageService,\n  location: Location,\n  mappings: MetadataUtils.Mappings\n): RequestInfo<string | null> {\n  const urlPart = location.fullServerUrl();\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'GET';\n  const timeout = service.maxOperationRetryTime;\n  const requestInfo = new RequestInfo(\n    url,\n    method,\n    downloadUrlHandler(service, mappings),\n    timeout\n  );\n  requestInfo.errorHandler = objectErrorHandler(location);\n  return requestInfo;\n}\n\nexport function updateMetadata(\n  service: StorageService,\n  location: Location,\n  metadata: Metadata,\n  mappings: MetadataUtils.Mappings\n): RequestInfo<Metadata> {\n  const urlPart = location.fullServerUrl();\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'PATCH';\n  const body = MetadataUtils.toResourceString(metadata, mappings);\n  const headers = { 'Content-Type': 'application/json; charset=utf-8' };\n  const timeout = service.maxOperationRetryTime;\n  const requestInfo = new RequestInfo(\n    url,\n    method,\n    metadataHandler(service, mappings),\n    timeout\n  );\n  requestInfo.headers = headers;\n  requestInfo.body = body;\n  requestInfo.errorHandler = objectErrorHandler(location);\n  return requestInfo;\n}\n\nexport function deleteObject(\n  service: StorageService,\n  location: Location\n): RequestInfo<void> {\n  const urlPart = location.fullServerUrl();\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'DELETE';\n  const timeout = service.maxOperationRetryTime;\n\n  function handler(_xhr: XhrIo, _text: string): void {}\n  const requestInfo = new RequestInfo(url, method, handler, timeout);\n  requestInfo.successCodes = [200, 204];\n  requestInfo.errorHandler = objectErrorHandler(location);\n  return requestInfo;\n}\n\nexport function determineContentType_(\n  metadata: Metadata | null,\n  blob: FbsBlob | null\n): string {\n  return (\n    (metadata && metadata['contentType']) ||\n    (blob && blob.type()) ||\n    'application/octet-stream'\n  );\n}\n\nexport function metadataForUpload_(\n  location: Location,\n  blob: FbsBlob,\n  metadata?: Metadata | null\n): Metadata {\n  const metadataClone = Object.assign({}, metadata);\n  metadataClone['fullPath'] = location.path;\n  metadataClone['size'] = blob.size();\n  if (!metadataClone['contentType']) {\n    metadataClone['contentType'] = determineContentType_(null, blob);\n  }\n  return metadataClone;\n}\n\nexport function multipartUpload(\n  service: StorageService,\n  location: Location,\n  mappings: MetadataUtils.Mappings,\n  blob: FbsBlob,\n  metadata?: Metadata | null\n): RequestInfo<Metadata> {\n  const urlPart = location.bucketOnlyServerUrl();\n  const headers: { [prop: string]: string } = {\n    'X-Goog-Upload-Protocol': 'multipart'\n  };\n\n  function genBoundary(): string {\n    let str = '';\n    for (let i = 0; i < 2; i++) {\n      str = str + Math.random().toString().slice(2);\n    }\n    return str;\n  }\n  const boundary = genBoundary();\n  headers['Content-Type'] = 'multipart/related; boundary=' + boundary;\n  const metadata_ = metadataForUpload_(location, blob, metadata);\n  const metadataString = MetadataUtils.toResourceString(metadata_, mappings);\n  const preBlobPart =\n    '--' +\n    boundary +\n    '\\r\\n' +\n    'Content-Type: application/json; charset=utf-8\\r\\n\\r\\n' +\n    metadataString +\n    '\\r\\n--' +\n    boundary +\n    '\\r\\n' +\n    'Content-Type: ' +\n    metadata_['contentType'] +\n    '\\r\\n\\r\\n';\n  const postBlobPart = '\\r\\n--' + boundary + '--';\n  const body = FbsBlob.getBlob(preBlobPart, blob, postBlobPart);\n  if (body === null) {\n    throw cannotSliceBlob();\n  }\n  const urlParams: UrlParams = { name: metadata_['fullPath']! };\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'POST';\n  const timeout = service.maxUploadRetryTime;\n  const requestInfo = new RequestInfo(\n    url,\n    method,\n    metadataHandler(service, mappings),\n    timeout\n  );\n  requestInfo.urlParams = urlParams;\n  requestInfo.headers = headers;\n  requestInfo.body = body.uploadData();\n  requestInfo.errorHandler = sharedErrorHandler(location);\n  return requestInfo;\n}\n\n/**\n * @param current The number of bytes that have been uploaded so far.\n * @param total The total number of bytes in the upload.\n * @param opt_finalized True if the server has finished the upload.\n * @param opt_metadata The upload metadata, should\n *     only be passed if opt_finalized is true.\n * @struct\n */\nexport class ResumableUploadStatus {\n  finalized: boolean;\n  metadata: Metadata | null;\n\n  constructor(\n    public current: number,\n    public total: number,\n    finalized?: boolean,\n    metadata?: Metadata | null\n  ) {\n    this.finalized = !!finalized;\n    this.metadata = metadata || null;\n  }\n}\n\nexport function checkResumeHeader_(xhr: XhrIo, allowed?: string[]): string {\n  let status: string | null = null;\n  try {\n    status = xhr.getResponseHeader('X-Goog-Upload-Status');\n  } catch (e) {\n    handlerCheck(false);\n  }\n  const allowedStatus = allowed || ['active'];\n  handlerCheck(!!status && allowedStatus.indexOf(status) !== -1);\n  return status as string;\n}\n\nexport function createResumableUpload(\n  service: StorageService,\n  location: Location,\n  mappings: MetadataUtils.Mappings,\n  blob: FbsBlob,\n  metadata?: Metadata | null\n): RequestInfo<string> {\n  const urlPart = location.bucketOnlyServerUrl();\n  const metadataForUpload = metadataForUpload_(location, blob, metadata);\n  const urlParams: UrlParams = { name: metadataForUpload['fullPath']! };\n  const url = UrlUtils.makeUrl(urlPart);\n  const method = 'POST';\n  const headers = {\n    'X-Goog-Upload-Protocol': 'resumable',\n    'X-Goog-Upload-Command': 'start',\n    'X-Goog-Upload-Header-Content-Length': blob.size(),\n    'X-Goog-Upload-Header-Content-Type': metadataForUpload['contentType']!,\n    'Content-Type': 'application/json; charset=utf-8'\n  };\n  const body = MetadataUtils.toResourceString(metadataForUpload, mappings);\n  const timeout = service.maxUploadRetryTime;\n\n  function handler(xhr: XhrIo): string {\n    checkResumeHeader_(xhr);\n    let url;\n    try {\n      url = xhr.getResponseHeader('X-Goog-Upload-URL');\n    } catch (e) {\n      handlerCheck(false);\n    }\n    handlerCheck(type.isString(url));\n    return url as string;\n  }\n  const requestInfo = new RequestInfo(url, method, handler, timeout);\n  requestInfo.urlParams = urlParams;\n  requestInfo.headers = headers;\n  requestInfo.body = body;\n  requestInfo.errorHandler = sharedErrorHandler(location);\n  return requestInfo;\n}\n\n/**\n * @param url From a call to fbs.requests.createResumableUpload.\n */\nexport function getResumableUploadStatus(\n  service: StorageService,\n  location: Location,\n  url: string,\n  blob: FbsBlob\n): RequestInfo<ResumableUploadStatus> {\n  const headers = { 'X-Goog-Upload-Command': 'query' };\n\n  function handler(xhr: XhrIo): ResumableUploadStatus {\n    const status = checkResumeHeader_(xhr, ['active', 'final']);\n    let sizeString: string | null = null;\n    try {\n      sizeString = xhr.getResponseHeader('X-Goog-Upload-Size-Received');\n    } catch (e) {\n      handlerCheck(false);\n    }\n\n    if (!sizeString) {\n      // null or empty string\n      handlerCheck(false);\n    }\n\n    const size = Number(sizeString);\n    handlerCheck(!isNaN(size));\n    return new ResumableUploadStatus(size, blob.size(), status === 'final');\n  }\n  const method = 'POST';\n  const timeout = service.maxUploadRetryTime;\n  const requestInfo = new RequestInfo(url, method, handler, timeout);\n  requestInfo.headers = headers;\n  requestInfo.errorHandler = sharedErrorHandler(location);\n  return requestInfo;\n}\n\n/**\n * Any uploads via the resumable upload API must transfer a number of bytes\n * that is a multiple of this number.\n */\nexport const resumableUploadChunkSize: number = 256 * 1024;\n\n/**\n * @param url From a call to fbs.requests.createResumableUpload.\n * @param chunkSize Number of bytes to upload.\n * @param status The previous status.\n *     If not passed or null, we start from the beginning.\n * @throws fbs.Error If the upload is already complete, the passed in status\n *     has a final size inconsistent with the blob, or the blob cannot be sliced\n *     for upload.\n */\nexport function continueResumableUpload(\n  location: Location,\n  service: StorageService,\n  url: string,\n  blob: FbsBlob,\n  chunkSize: number,\n  mappings: MetadataUtils.Mappings,\n  status?: ResumableUploadStatus | null,\n  progressCallback?: ((p1: number, p2: number) => void) | null\n): RequestInfo<ResumableUploadStatus> {\n  // TODO(andysoto): standardize on internal asserts\n  // assert(!(opt_status && opt_status.finalized));\n  const status_ = new ResumableUploadStatus(0, 0);\n  if (status) {\n    status_.current = status.current;\n    status_.total = status.total;\n  } else {\n    status_.current = 0;\n    status_.total = blob.size();\n  }\n  if (blob.size() !== status_.total) {\n    throw serverFileWrongSize();\n  }\n  const bytesLeft = status_.total - status_.current;\n  let bytesToUpload = bytesLeft;\n  if (chunkSize > 0) {\n    bytesToUpload = Math.min(bytesToUpload, chunkSize);\n  }\n  const startByte = status_.current;\n  const endByte = startByte + bytesToUpload;\n  const uploadCommand =\n    bytesToUpload === bytesLeft ? 'upload, finalize' : 'upload';\n  const headers = {\n    'X-Goog-Upload-Command': uploadCommand,\n    'X-Goog-Upload-Offset': status_.current\n  };\n  const body = blob.slice(startByte, endByte);\n  if (body === null) {\n    throw cannotSliceBlob();\n  }\n\n  function handler(xhr: XhrIo, text: string): ResumableUploadStatus {\n    // TODO(andysoto): Verify the MD5 of each uploaded range:\n    // the 'x-range-md5' header comes back with status code 308 responses.\n    // We'll only be able to bail out though, because you can't re-upload a\n    // range that you previously uploaded.\n    const uploadStatus = checkResumeHeader_(xhr, ['active', 'final']);\n    const newCurrent = status_.current + bytesToUpload;\n    const size = blob.size();\n    let metadata;\n    if (uploadStatus === 'final') {\n      metadata = metadataHandler(service, mappings)(xhr, text);\n    } else {\n      metadata = null;\n    }\n    return new ResumableUploadStatus(\n      newCurrent,\n      size,\n      uploadStatus === 'final',\n      metadata\n    );\n  }\n  const method = 'POST';\n  const timeout = service.maxUploadRetryTime;\n  const requestInfo = new RequestInfo(url, method, handler, timeout);\n  requestInfo.headers = headers;\n  requestInfo.body = body.uploadData();\n  requestInfo.progressCallback = progressCallback || null;\n  requestInfo.errorHandler = sharedErrorHandler(location);\n  return requestInfo;\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 */\nimport * as type from './type';\nimport { FirebaseStorageError } from './error';\n\nexport type NextFn<T> = (value: T) => void;\nexport type ErrorFn = (error: Error | FirebaseStorageError) => void;\nexport type CompleteFn = () => void;\nexport type Unsubscribe = () => void;\n\nexport interface StorageObserver<T> {\n  next?: NextFn<T> | null;\n  error?: ErrorFn | null;\n  complete?: CompleteFn | null;\n}\n\nexport type Subscribe<T> = (\n  next?: NextFn<T> | StorageObserver<T> | null,\n  error?: ErrorFn | null,\n  complete?: CompleteFn | null\n) => Unsubscribe;\n\n/**\n * @struct\n */\nexport class Observer<T> implements StorageObserver<T> {\n  next?: NextFn<T> | null;\n  error?: ErrorFn | null;\n  complete?: CompleteFn | null;\n\n  constructor(\n    nextOrObserver?: NextFn<T> | StorageObserver<T> | null,\n    error?: ErrorFn | null,\n    complete?: CompleteFn | null\n  ) {\n    const asFunctions =\n      type.isFunction(nextOrObserver) ||\n      type.isDef(error) ||\n      type.isDef(complete);\n    if (asFunctions) {\n      this.next = nextOrObserver as NextFn<T> | null;\n      this.error = error || null;\n      this.complete = complete || null;\n    } else {\n      const observer = nextOrObserver as {\n        next?: NextFn<T> | null;\n        error?: ErrorFn | null;\n        complete?: CompleteFn | null;\n      };\n      this.next = observer.next || null;\n      this.error = observer.error || null;\n      this.complete = observer.complete || null;\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 */\nimport { TaskState } from './implementation/taskenums';\nimport { Metadata } from './metadata';\nimport { Reference } from './reference';\nimport { UploadTask } from './task';\n\nexport class UploadTaskSnapshot {\n  constructor(\n    readonly bytesTransferred: number,\n    readonly totalBytes: number,\n    readonly state: TaskState,\n    readonly metadata: Metadata | null,\n    readonly task: UploadTask,\n    readonly ref: Reference\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 */\nimport * as errorsExports from './error';\nimport * as MetadataUtils from './metadata';\nimport * as ListOptionsUtils from './list';\nimport * as type from './type';\n\n/**\n * @param name Name of the function.\n * @param specs Argument specs.\n * @param passed The actual arguments passed to the function.\n * @throws {fbs.Error} If the arguments are invalid.\n */\nexport function validate(\n  name: string,\n  specs: ArgSpec[],\n  passed: IArguments\n): void {\n  let minArgs = specs.length;\n  const maxArgs = specs.length;\n  for (let i = 0; i < specs.length; i++) {\n    if (specs[i].optional) {\n      minArgs = i;\n      break;\n    }\n  }\n  const validLength = minArgs <= passed.length && passed.length <= maxArgs;\n  if (!validLength) {\n    throw errorsExports.invalidArgumentCount(\n      minArgs,\n      maxArgs,\n      name,\n      passed.length\n    );\n  }\n  for (let i = 0; i < passed.length; i++) {\n    try {\n      specs[i].validator(passed[i]);\n    } catch (e) {\n      if (e instanceof Error) {\n        throw errorsExports.invalidArgument(i, name, e.message);\n      } else {\n        throw errorsExports.invalidArgument(i, name, e);\n      }\n    }\n  }\n}\n\n/**\n * @struct\n */\nexport class ArgSpec {\n  validator: (p1: unknown) => void;\n  optional: boolean;\n\n  constructor(validator: (p1: unknown) => void, optional?: boolean) {\n    const self = this;\n    this.validator = function (p: unknown) {\n      if (self.optional && !type.isJustDef(p)) {\n        return;\n      }\n      validator(p);\n    };\n    this.optional = !!optional;\n  }\n}\n\nexport function and_(\n  v1: (p1: unknown) => void,\n  v2: (p1: unknown) => void\n): (p1: unknown) => void {\n  return function (p) {\n    v1(p);\n    v2(p);\n  };\n}\n\nexport function stringSpec(\n  validator?: (p1: unknown) => void | null,\n  optional?: boolean\n): ArgSpec {\n  function stringValidator(p: unknown): void {\n    if (!type.isString(p)) {\n      throw 'Expected string.';\n    }\n  }\n  let chainedValidator;\n  if (validator) {\n    chainedValidator = and_(stringValidator, validator);\n  } else {\n    chainedValidator = stringValidator;\n  }\n  return new ArgSpec(chainedValidator, optional);\n}\n\nexport function uploadDataSpec(): ArgSpec {\n  function validator(p: unknown): void {\n    const valid =\n      p instanceof Uint8Array ||\n      p instanceof ArrayBuffer ||\n      (type.isNativeBlobDefined() && p instanceof Blob);\n    if (!valid) {\n      throw 'Expected Blob or File.';\n    }\n  }\n  return new ArgSpec(validator);\n}\n\nexport function metadataSpec(optional?: boolean): ArgSpec {\n  return new ArgSpec(MetadataUtils.metadataValidator, optional);\n}\n\nexport function listOptionSpec(optional?: boolean): ArgSpec {\n  return new ArgSpec(ListOptionsUtils.listOptionsValidator, optional);\n}\n\nexport function nonNegativeNumberSpec(): ArgSpec {\n  function validator(p: unknown): void {\n    const valid = type.isNumber(p) && p >= 0;\n    if (!valid) {\n      throw 'Expected a number 0 or greater.';\n    }\n  }\n  return new ArgSpec(validator);\n}\n\nexport function looseObjectSpec(\n  validator?: ((p1: unknown) => void) | null,\n  optional?: boolean\n): ArgSpec {\n  function isLooseObjectValidator(p: unknown): void {\n    const isLooseObject = p === null || (type.isDef(p) && p instanceof Object);\n    if (!isLooseObject) {\n      throw 'Expected an Object.';\n    }\n    if (validator !== undefined && validator !== null) {\n      validator(p);\n    }\n  }\n  return new ArgSpec(isLooseObjectValidator, optional);\n}\n\nexport function nullFunctionSpec(optional?: boolean): ArgSpec {\n  function validator(p: unknown): void {\n    const valid = p === null || type.isFunction(p);\n    if (!valid) {\n      throw 'Expected a Function.';\n    }\n  }\n  return new ArgSpec(validator, optional);\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 function that invokes f with its arguments asynchronously as a\n * microtask, i.e. as soon as possible after the current script returns back\n * into browser code.\n */\nexport function async(f: Function): Function {\n  return (...argsToForward: unknown[]) => {\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    Promise.resolve().then(() => f(...argsToForward));\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 * @fileoverview Defines types for interacting with blob transfer tasks.\n */\n\nimport { FbsBlob } from './implementation/blob';\nimport { FirebaseStorageError, Code, canceled } from './implementation/error';\nimport {\n  InternalTaskState,\n  TaskEvent,\n  TaskState,\n  taskStateFromInternalTaskState\n} from './implementation/taskenums';\nimport { Metadata } from './metadata';\nimport {\n  CompleteFn,\n  ErrorFn,\n  NextFn,\n  Observer,\n  StorageObserver,\n  Subscribe,\n  Unsubscribe\n} from './implementation/observer';\nimport { Request } from './implementation/request';\nimport { UploadTaskSnapshot } from './tasksnapshot';\nimport {\n  ArgSpec,\n  nullFunctionSpec,\n  looseObjectSpec,\n  stringSpec,\n  validate\n} from './implementation/args';\nimport { async as fbsAsync } from './implementation/async';\nimport { Location } from './implementation/location';\nimport * as fbsMetadata from './implementation/metadata';\nimport * as fbsRequests from './implementation/requests';\nimport * as typeUtils from './implementation/type';\nimport { Reference } from './reference';\nimport { StorageService } from './service';\n\n/**\n * Represents a blob being uploaded. Can be used to pause/resume/cancel the\n * upload and manage callbacks for various events.\n */\nexport class UploadTask {\n  private ref_: Reference;\n  private service_: StorageService;\n  private location_: Location;\n  private blob_: FbsBlob;\n  private metadata_: Metadata | null;\n  private mappings_: fbsMetadata.Mappings;\n  private transferred_: number = 0;\n  private needToFetchStatus_: boolean = false;\n  private needToFetchMetadata_: boolean = false;\n  private observers_: Array<Observer<UploadTaskSnapshot>> = [];\n  private resumable_: boolean;\n  private state_: InternalTaskState;\n  private error_: Error | null = null;\n  private uploadUrl_: string | null = null;\n  private request_: Request<unknown> | null = null;\n  private chunkMultiplier_: number = 1;\n  private errorHandler_: (p1: FirebaseStorageError) => void;\n  private metadataErrorHandler_: (p1: FirebaseStorageError) => void;\n  private resolve_: ((p1: UploadTaskSnapshot) => void) | null = null;\n  private reject_: ((p1: Error) => void) | null = null;\n  private promise_: Promise<UploadTaskSnapshot>;\n\n  /**\n   * @param ref The firebaseStorage.Reference object this task came\n   *     from, untyped to avoid cyclic dependencies.\n   * @param blob The blob to upload.\n   */\n  constructor(\n    ref: Reference,\n    service: StorageService,\n    location: Location,\n    mappings: fbsMetadata.Mappings,\n    blob: FbsBlob,\n    metadata: Metadata | null = null\n  ) {\n    this.ref_ = ref;\n    this.service_ = service;\n    this.location_ = location;\n    this.blob_ = blob;\n    this.metadata_ = metadata;\n    this.mappings_ = mappings;\n    this.resumable_ = this.shouldDoResumable_(this.blob_);\n    this.state_ = InternalTaskState.RUNNING;\n    this.errorHandler_ = error => {\n      this.request_ = null;\n      this.chunkMultiplier_ = 1;\n      if (error.codeEquals(Code.CANCELED)) {\n        this.needToFetchStatus_ = true;\n        this.completeTransitions_();\n      } else {\n        this.error_ = error;\n        this.transition_(InternalTaskState.ERROR);\n      }\n    };\n    this.metadataErrorHandler_ = error => {\n      this.request_ = null;\n      if (error.codeEquals(Code.CANCELED)) {\n        this.completeTransitions_();\n      } else {\n        this.error_ = error;\n        this.transition_(InternalTaskState.ERROR);\n      }\n    };\n    this.promise_ = new Promise((resolve, reject) => {\n      this.resolve_ = resolve;\n      this.reject_ = reject;\n      this.start_();\n    });\n\n    // Prevent uncaught rejections on the internal promise from bubbling out\n    // to the top level with a dummy handler.\n    this.promise_.then(null, () => {});\n  }\n\n  private makeProgressCallback_(): (p1: number, p2: number) => void {\n    const sizeBefore = this.transferred_;\n    return loaded => this.updateProgress_(sizeBefore + loaded);\n  }\n\n  private shouldDoResumable_(blob: FbsBlob): boolean {\n    return blob.size() > 256 * 1024;\n  }\n\n  private start_(): void {\n    if (this.state_ !== InternalTaskState.RUNNING) {\n      // This can happen if someone pauses us in a resume callback, for example.\n      return;\n    }\n    if (this.request_ !== null) {\n      return;\n    }\n    if (this.resumable_) {\n      if (this.uploadUrl_ === null) {\n        this.createResumable_();\n      } else {\n        if (this.needToFetchStatus_) {\n          this.fetchStatus_();\n        } else {\n          if (this.needToFetchMetadata_) {\n            // Happens if we miss the metadata on upload completion.\n            this.fetchMetadata_();\n          } else {\n            this.continueUpload_();\n          }\n        }\n      }\n    } else {\n      this.oneShotUpload_();\n    }\n  }\n\n  private resolveToken_(callback: (p1: string | null) => void): void {\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.service_.getAuthToken().then(authToken => {\n      switch (this.state_) {\n        case InternalTaskState.RUNNING:\n          callback(authToken);\n          break;\n        case InternalTaskState.CANCELING:\n          this.transition_(InternalTaskState.CANCELED);\n          break;\n        case InternalTaskState.PAUSING:\n          this.transition_(InternalTaskState.PAUSED);\n          break;\n        default:\n      }\n    });\n  }\n\n  // TODO(andysoto): assert false\n\n  private createResumable_(): void {\n    this.resolveToken_(authToken => {\n      const requestInfo = fbsRequests.createResumableUpload(\n        this.service_,\n        this.location_,\n        this.mappings_,\n        this.blob_,\n        this.metadata_\n      );\n      const createRequest = this.service_.makeRequest(requestInfo, authToken);\n      this.request_ = createRequest;\n      createRequest.getPromise().then((url: string) => {\n        this.request_ = null;\n        this.uploadUrl_ = url;\n        this.needToFetchStatus_ = false;\n        this.completeTransitions_();\n      }, this.errorHandler_);\n    });\n  }\n\n  private fetchStatus_(): void {\n    // TODO(andysoto): assert(this.uploadUrl_ !== null);\n    const url = this.uploadUrl_ as string;\n    this.resolveToken_(authToken => {\n      const requestInfo = fbsRequests.getResumableUploadStatus(\n        this.service_,\n        this.location_,\n        url,\n        this.blob_\n      );\n      const statusRequest = this.service_.makeRequest(requestInfo, authToken);\n      this.request_ = statusRequest;\n      statusRequest.getPromise().then(status => {\n        status = status as fbsRequests.ResumableUploadStatus;\n        this.request_ = null;\n        this.updateProgress_(status.current);\n        this.needToFetchStatus_ = false;\n        if (status.finalized) {\n          this.needToFetchMetadata_ = true;\n        }\n        this.completeTransitions_();\n      }, this.errorHandler_);\n    });\n  }\n\n  private continueUpload_(): void {\n    const chunkSize =\n      fbsRequests.resumableUploadChunkSize * this.chunkMultiplier_;\n    const status = new fbsRequests.ResumableUploadStatus(\n      this.transferred_,\n      this.blob_.size()\n    );\n\n    // TODO(andysoto): assert(this.uploadUrl_ !== null);\n    const url = this.uploadUrl_ as string;\n    this.resolveToken_(authToken => {\n      let requestInfo;\n      try {\n        requestInfo = fbsRequests.continueResumableUpload(\n          this.location_,\n          this.service_,\n          url,\n          this.blob_,\n          chunkSize,\n          this.mappings_,\n          status,\n          this.makeProgressCallback_()\n        );\n      } catch (e) {\n        this.error_ = e;\n        this.transition_(InternalTaskState.ERROR);\n        return;\n      }\n      const uploadRequest = this.service_.makeRequest(requestInfo, authToken);\n      this.request_ = uploadRequest;\n      uploadRequest\n        .getPromise()\n        .then((newStatus: fbsRequests.ResumableUploadStatus) => {\n          this.increaseMultiplier_();\n          this.request_ = null;\n          this.updateProgress_(newStatus.current);\n          if (newStatus.finalized) {\n            this.metadata_ = newStatus.metadata;\n            this.transition_(InternalTaskState.SUCCESS);\n          } else {\n            this.completeTransitions_();\n          }\n        }, this.errorHandler_);\n    });\n  }\n\n  private increaseMultiplier_(): void {\n    const currentSize =\n      fbsRequests.resumableUploadChunkSize * this.chunkMultiplier_;\n\n    // Max chunk size is 32M.\n    if (currentSize < 32 * 1024 * 1024) {\n      this.chunkMultiplier_ *= 2;\n    }\n  }\n\n  private fetchMetadata_(): void {\n    this.resolveToken_(authToken => {\n      const requestInfo = fbsRequests.getMetadata(\n        this.service_,\n        this.location_,\n        this.mappings_\n      );\n      const metadataRequest = this.service_.makeRequest(requestInfo, authToken);\n      this.request_ = metadataRequest;\n      metadataRequest.getPromise().then(metadata => {\n        this.request_ = null;\n        this.metadata_ = metadata;\n        this.transition_(InternalTaskState.SUCCESS);\n      }, this.metadataErrorHandler_);\n    });\n  }\n\n  private oneShotUpload_(): void {\n    this.resolveToken_(authToken => {\n      const requestInfo = fbsRequests.multipartUpload(\n        this.service_,\n        this.location_,\n        this.mappings_,\n        this.blob_,\n        this.metadata_\n      );\n      const multipartRequest = this.service_.makeRequest(\n        requestInfo,\n        authToken\n      );\n      this.request_ = multipartRequest;\n      multipartRequest.getPromise().then(metadata => {\n        this.request_ = null;\n        this.metadata_ = metadata;\n        this.updateProgress_(this.blob_.size());\n        this.transition_(InternalTaskState.SUCCESS);\n      }, this.errorHandler_);\n    });\n  }\n\n  private updateProgress_(transferred: number): void {\n    const old = this.transferred_;\n    this.transferred_ = transferred;\n\n    // A progress update can make the \"transferred\" value smaller (e.g. a\n    // partial upload not completed by server, after which the \"transferred\"\n    // value may reset to the value at the beginning of the request).\n    if (this.transferred_ !== old) {\n      this.notifyObservers_();\n    }\n  }\n\n  private transition_(state: InternalTaskState): void {\n    if (this.state_ === state) {\n      return;\n    }\n    switch (state) {\n      case InternalTaskState.CANCELING:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.RUNNING ||\n        //        this.state_ === InternalTaskState.PAUSING);\n        this.state_ = state;\n        if (this.request_ !== null) {\n          this.request_.cancel();\n        }\n        break;\n      case InternalTaskState.PAUSING:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.RUNNING);\n        this.state_ = state;\n        if (this.request_ !== null) {\n          this.request_.cancel();\n        }\n        break;\n      case InternalTaskState.RUNNING:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.PAUSED ||\n        //        this.state_ === InternalTaskState.PAUSING);\n        const wasPaused = this.state_ === InternalTaskState.PAUSED;\n        this.state_ = state;\n        if (wasPaused) {\n          this.notifyObservers_();\n          this.start_();\n        }\n        break;\n      case InternalTaskState.PAUSED:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.PAUSING);\n        this.state_ = state;\n        this.notifyObservers_();\n        break;\n      case InternalTaskState.CANCELED:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.PAUSED ||\n        //        this.state_ === InternalTaskState.CANCELING);\n        this.error_ = canceled();\n        this.state_ = state;\n        this.notifyObservers_();\n        break;\n      case InternalTaskState.ERROR:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.RUNNING ||\n        //        this.state_ === InternalTaskState.PAUSING ||\n        //        this.state_ === InternalTaskState.CANCELING);\n        this.state_ = state;\n        this.notifyObservers_();\n        break;\n      case InternalTaskState.SUCCESS:\n        // TODO(andysoto):\n        // assert(this.state_ === InternalTaskState.RUNNING ||\n        //        this.state_ === InternalTaskState.PAUSING ||\n        //        this.state_ === InternalTaskState.CANCELING);\n        this.state_ = state;\n        this.notifyObservers_();\n        break;\n      default: // Ignore\n    }\n  }\n\n  private completeTransitions_(): void {\n    switch (this.state_) {\n      case InternalTaskState.PAUSING:\n        this.transition_(InternalTaskState.PAUSED);\n        break;\n      case InternalTaskState.CANCELING:\n        this.transition_(InternalTaskState.CANCELED);\n        break;\n      case InternalTaskState.RUNNING:\n        this.start_();\n        break;\n      default:\n        // TODO(andysoto): assert(false);\n        break;\n    }\n  }\n\n  get snapshot(): UploadTaskSnapshot {\n    const externalState = taskStateFromInternalTaskState(this.state_);\n    return new UploadTaskSnapshot(\n      this.transferred_,\n      this.blob_.size(),\n      externalState,\n      this.metadata_,\n      this,\n      this.ref_\n    );\n  }\n\n  /**\n   * Adds a callback for an event.\n   * @param type The type of event to listen for.\n   */\n  on(\n    type: TaskEvent,\n    nextOrObserver?:\n      | NextFn<UploadTaskSnapshot>\n      | StorageObserver<UploadTaskSnapshot>\n      | null,\n    error?: ErrorFn | null,\n    completed?: CompleteFn | null\n  ): Unsubscribe | Subscribe<UploadTaskSnapshot> {\n    function typeValidator(): void {\n      if (type !== TaskEvent.STATE_CHANGED) {\n        throw `Expected one of the event types: [${TaskEvent.STATE_CHANGED}].`;\n      }\n    }\n    const nextOrObserverMessage =\n      'Expected a function or an Object with one of ' +\n      '`next`, `error`, `complete` properties.';\n    const nextValidator = nullFunctionSpec(true).validator;\n    const observerValidator = looseObjectSpec(null, true).validator;\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    function nextOrObserverValidator(p: any): void {\n      try {\n        nextValidator(p);\n        return;\n      } catch (e) {}\n      try {\n        observerValidator(p);\n        const anyDefined =\n          typeUtils.isJustDef(p['next']) ||\n          typeUtils.isJustDef(p['error']) ||\n          typeUtils.isJustDef(p['complete']);\n        if (!anyDefined) {\n          throw '';\n        }\n        return;\n      } catch (e) {\n        throw nextOrObserverMessage;\n      }\n    }\n    const specs = [\n      stringSpec(typeValidator),\n      looseObjectSpec(nextOrObserverValidator, true),\n      nullFunctionSpec(true),\n      nullFunctionSpec(true)\n    ];\n    validate('on', specs, arguments);\n    const self = this;\n\n    function makeBinder(\n      specs: ArgSpec[] | null\n    ): Subscribe<UploadTaskSnapshot> {\n      function binder(\n        nextOrObserver?:\n          | NextFn<UploadTaskSnapshot>\n          | StorageObserver<UploadTaskSnapshot>\n          | null,\n        error?: ErrorFn | null,\n        complete?: CompleteFn | null\n      ): () => void {\n        if (specs !== null) {\n          validate('on', specs, arguments);\n        }\n        const observer = new Observer(nextOrObserver, error, completed);\n        self.addObserver_(observer);\n        return () => {\n          self.removeObserver_(observer);\n        };\n      }\n      return binder;\n    }\n\n    function binderNextOrObserverValidator(p: unknown): void {\n      if (p === null) {\n        throw nextOrObserverMessage;\n      }\n      nextOrObserverValidator(p);\n    }\n    const binderSpecs = [\n      looseObjectSpec(binderNextOrObserverValidator),\n      nullFunctionSpec(true),\n      nullFunctionSpec(true)\n    ];\n    const typeOnly = !(\n      typeUtils.isJustDef(nextOrObserver) ||\n      typeUtils.isJustDef(error) ||\n      typeUtils.isJustDef(completed)\n    );\n    if (typeOnly) {\n      return makeBinder(binderSpecs);\n    } else {\n      return makeBinder(null)(nextOrObserver, error, completed);\n    }\n  }\n\n  /**\n   * This object behaves like a Promise, and resolves with its snapshot data\n   * when the upload completes.\n   * @param onFulfilled The fulfillment callback. Promise chaining works as normal.\n   * @param onRejected The rejection callback.\n   */\n  then<U>(\n    onFulfilled?: ((value: UploadTaskSnapshot) => U | Promise<U>) | null,\n    onRejected?: ((error: Error) => U | Promise<U>) | null\n  ): Promise<U> {\n    // These casts are needed so that TypeScript can infer the types of the\n    // resulting Promise.\n    return this.promise_.then<U>(\n      onFulfilled as (value: UploadTaskSnapshot) => U | Promise<U>,\n      onRejected as ((error: unknown) => Promise<never>) | null\n    );\n  }\n\n  /**\n   * Equivalent to calling `then(null, onRejected)`.\n   */\n  catch<T>(onRejected: (p1: Error) => T | Promise<T>): Promise<T> {\n    return this.then(null, onRejected);\n  }\n\n  /**\n   * Adds the given observer.\n   */\n  private addObserver_(observer: Observer<UploadTaskSnapshot>): void {\n    this.observers_.push(observer);\n    this.notifyObserver_(observer);\n  }\n\n  /**\n   * Removes the given observer.\n   */\n  private removeObserver_(observer: Observer<UploadTaskSnapshot>): void {\n    const i = this.observers_.indexOf(observer);\n    if (i !== -1) {\n      this.observers_.splice(i, 1);\n    }\n  }\n\n  private notifyObservers_(): void {\n    this.finishPromise_();\n    const observers = this.observers_.slice();\n    observers.forEach(observer => {\n      this.notifyObserver_(observer);\n    });\n  }\n\n  private finishPromise_(): void {\n    if (this.resolve_ !== null) {\n      let triggered = true;\n      switch (taskStateFromInternalTaskState(this.state_)) {\n        case TaskState.SUCCESS:\n          fbsAsync(this.resolve_.bind(null, this.snapshot))();\n          break;\n        case TaskState.CANCELED:\n        case TaskState.ERROR:\n          const toCall = this.reject_ as (p1: Error) => void;\n          fbsAsync(toCall.bind(null, this.error_ as Error))();\n          break;\n        default:\n          triggered = false;\n          break;\n      }\n      if (triggered) {\n        this.resolve_ = null;\n        this.reject_ = null;\n      }\n    }\n  }\n\n  private notifyObserver_(observer: Observer<UploadTaskSnapshot>): void {\n    const externalState = taskStateFromInternalTaskState(this.state_);\n    switch (externalState) {\n      case TaskState.RUNNING:\n      case TaskState.PAUSED:\n        if (observer.next) {\n          fbsAsync(observer.next.bind(observer, this.snapshot))();\n        }\n        break;\n      case TaskState.SUCCESS:\n        if (observer.complete) {\n          fbsAsync(observer.complete.bind(observer))();\n        }\n        break;\n      case TaskState.CANCELED:\n      case TaskState.ERROR:\n        if (observer.error) {\n          fbsAsync(observer.error.bind(observer, this.error_ as Error))();\n        }\n        break;\n      default:\n        // TODO(andysoto): assert(false);\n        if (observer.error) {\n          fbsAsync(observer.error.bind(observer, this.error_ as Error))();\n        }\n    }\n  }\n\n  /**\n   * Resumes a paused task. Has no effect on a currently running or failed task.\n   * @return True if the operation took effect, false if ignored.\n   */\n  resume(): boolean {\n    validate('resume', [], arguments);\n    const valid =\n      this.state_ === InternalTaskState.PAUSED ||\n      this.state_ === InternalTaskState.PAUSING;\n    if (valid) {\n      this.transition_(InternalTaskState.RUNNING);\n    }\n    return valid;\n  }\n\n  /**\n   * Pauses a currently running task. Has no effect on a paused or failed task.\n   * @return True if the operation took effect, false if ignored.\n   */\n  pause(): boolean {\n    validate('pause', [], arguments);\n    const valid = this.state_ === InternalTaskState.RUNNING;\n    if (valid) {\n      this.transition_(InternalTaskState.PAUSING);\n    }\n    return valid;\n  }\n\n  /**\n   * Cancels a currently running or paused task. Has no effect on a complete or\n   * failed task.\n   * @return True if the operation took effect, false if ignored.\n   */\n  cancel(): boolean {\n    validate('cancel', [], arguments);\n    const valid =\n      this.state_ === InternalTaskState.RUNNING ||\n      this.state_ === InternalTaskState.PAUSING;\n    if (valid) {\n      this.transition_(InternalTaskState.CANCELING);\n    }\n    return valid;\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 * @fileoverview Defines the Firebase Storage Reference class.\n */\nimport { FbsBlob } from './implementation/blob';\nimport * as errorsExports from './implementation/error';\nimport { Location } from './implementation/location';\nimport * as metadata from './implementation/metadata';\nimport * as path from './implementation/path';\nimport * as requests from './implementation/requests';\nimport {\n  StringFormat,\n  formatValidator,\n  dataFromString\n} from './implementation/string';\nimport * as type from './implementation/type';\nimport { Metadata } from './metadata';\nimport { StorageService } from './service';\nimport { UploadTask } from './task';\nimport { ListOptions, ListResult } from './list';\nimport {\n  listOptionSpec,\n  stringSpec,\n  validate,\n  metadataSpec,\n  uploadDataSpec\n} from './implementation/args';\n\n/**\n * Provides methods to interact with a bucket in the Firebase Storage service.\n * @param location An fbs.location, or the URL at\n *     which to base this object, in one of the following forms:\n *         gs://<bucket>/<object-path>\n *         http[s]://firebasestorage.googleapis.com/\n *                     <api-version>/b/<bucket>/o/<object-path>\n *     Any query or fragment strings will be ignored in the http[s]\n *     format. If no value is passed, the storage object will use a URL based on\n *     the project ID of the base firebase.App instance.\n */\nexport class Reference {\n  protected location: Location;\n\n  constructor(protected service: StorageService, location: string | Location) {\n    if (location instanceof Location) {\n      this.location = location;\n    } else {\n      this.location = Location.makeFromUrl(location);\n    }\n  }\n\n  /**\n   * @return The URL for the bucket and path this object references,\n   *     in the form gs://<bucket>/<object-path>\n   * @override\n   */\n  toString(): string {\n    validate('toString', [], arguments);\n    return 'gs://' + this.location.bucket + '/' + this.location.path;\n  }\n\n  protected newRef(service: StorageService, location: Location): Reference {\n    return new Reference(service, location);\n  }\n\n  protected mappings(): metadata.Mappings {\n    return metadata.getMappings();\n  }\n\n  /**\n   * @return A reference to the object obtained by\n   *     appending childPath, removing any duplicate, beginning, or trailing\n   *     slashes.\n   */\n  child(childPath: string): Reference {\n    validate('child', [stringSpec()], arguments);\n    const newPath = path.child(this.location.path, childPath);\n    const location = new Location(this.location.bucket, newPath);\n    return this.newRef(this.service, location);\n  }\n\n  /**\n   * @return A reference to the parent of the\n   *     current object, or null if the current object is the root.\n   */\n  get parent(): Reference | null {\n    const newPath = path.parent(this.location.path);\n    if (newPath === null) {\n      return null;\n    }\n    const location = new Location(this.location.bucket, newPath);\n    return this.newRef(this.service, location);\n  }\n\n  /**\n   * @return An reference to the root of this\n   *     object's bucket.\n   */\n  get root(): Reference {\n    const location = new Location(this.location.bucket, '');\n    return this.newRef(this.service, location);\n  }\n\n  get bucket(): string {\n    return this.location.bucket;\n  }\n\n  get fullPath(): string {\n    return this.location.path;\n  }\n\n  get name(): string {\n    return path.lastComponent(this.location.path);\n  }\n\n  get storage(): StorageService {\n    return this.service;\n  }\n\n  /**\n   * Uploads a blob to this object's location.\n   * @param data The blob to upload.\n   * @return An UploadTask that lets you control and\n   *     observe the upload.\n   */\n  put(\n    data: Blob | Uint8Array | ArrayBuffer,\n    metadata: Metadata | null = null\n  ): UploadTask {\n    validate('put', [uploadDataSpec(), metadataSpec(true)], arguments);\n    this.throwIfRoot_('put');\n    return new UploadTask(\n      this,\n      this.service,\n      this.location,\n      this.mappings(),\n      new FbsBlob(data),\n      metadata\n    );\n  }\n\n  /**\n   * Uploads a string to this object's location.\n   * @param value The string to upload.\n   * @param format The format of the string to upload.\n   * @return An UploadTask that lets you control and\n   *     observe the upload.\n   */\n  putString(\n    value: string,\n    format: StringFormat = StringFormat.RAW,\n    metadata?: Metadata\n  ): UploadTask {\n    validate(\n      'putString',\n      [stringSpec(), stringSpec(formatValidator, true), metadataSpec(true)],\n      arguments\n    );\n    this.throwIfRoot_('putString');\n    const data = dataFromString(format, value);\n    const metadataClone = Object.assign({}, metadata);\n    if (\n      !type.isDef(metadataClone['contentType']) &&\n      type.isDef(data.contentType)\n    ) {\n      metadataClone['contentType'] = data.contentType!;\n    }\n    return new UploadTask(\n      this,\n      this.service,\n      this.location,\n      this.mappings(),\n      new FbsBlob(data.data, true),\n      metadataClone\n    );\n  }\n\n  /**\n   * Deletes the object at this location.\n   * @return A promise that resolves if the deletion succeeds.\n   */\n  delete(): Promise<void> {\n    validate('delete', [], arguments);\n    this.throwIfRoot_('delete');\n    return this.service.getAuthToken().then(authToken => {\n      const requestInfo = requests.deleteObject(this.service, this.location);\n      return this.service.makeRequest(requestInfo, authToken).getPromise();\n    });\n  }\n\n  /**\n   * List all items (files) and prefixes (folders) under this storage reference.\n   *\n   * This is a helper method for calling list() repeatedly until there are\n   * no more results. The default pagination size is 1000.\n   *\n   * Note: The results may not be consistent if objects are changed while this\n   * operation is running.\n   *\n   * Warning: listAll may potentially consume too many resources if there are\n   * too many results.\n   *\n   * @return A Promise that resolves with all the items and prefixes under\n   *      the current storage reference. `prefixes` contains references to\n   *      sub-directories and `items` contains references to objects in this\n   *      folder. `nextPageToken` is never returned.\n   */\n  listAll(): Promise<ListResult> {\n    validate('listAll', [], arguments);\n    const accumulator = {\n      prefixes: [],\n      items: []\n    };\n    return this.listAllHelper(accumulator).then(() => accumulator);\n  }\n\n  private async listAllHelper(\n    accumulator: ListResult,\n    pageToken?: string\n  ): Promise<void> {\n    const opt: ListOptions = {\n      // maxResults is 1000 by default.\n      pageToken\n    };\n    const nextPage = await this.list(opt);\n    accumulator.prefixes.push(...nextPage.prefixes);\n    accumulator.items.push(...nextPage.items);\n    if (nextPage.nextPageToken != null) {\n      await this.listAllHelper(accumulator, nextPage.nextPageToken);\n    }\n  }\n\n  /**\n   * List items (files) and prefixes (folders) under this storage reference.\n   *\n   * List API is only available for Firebase Rules Version 2.\n   *\n   * GCS is a key-blob store. Firebase Storage imposes the semantic of '/'\n   * delimited folder structure.\n   * Refer to GCS's List API if you want to learn more.\n   *\n   * To adhere to Firebase Rules's Semantics, Firebase Storage does not\n   * support objects whose paths end with \"/\" or contain two consecutive\n   * \"/\"s. Firebase Storage List API will filter these unsupported objects.\n   * list() may fail if there are too many unsupported objects in the bucket.\n   *\n   * @param options See ListOptions for details.\n   * @return A Promise that resolves with the items and prefixes.\n   *      `prefixes` contains references to sub-folders and `items`\n   *      contains references to objects in this folder. `nextPageToken`\n   *      can be used to get the rest of the results.\n   */\n  list(options?: ListOptions | null): Promise<ListResult> {\n    validate('list', [listOptionSpec(true)], arguments);\n    const self = this;\n    return this.service.getAuthToken().then(authToken => {\n      const op = options || {};\n      const requestInfo = requests.list(\n        self.service,\n        self.location,\n        /*delimiter= */ '/',\n        op.pageToken,\n        op.maxResults\n      );\n      return self.service.makeRequest(requestInfo, authToken).getPromise();\n    });\n  }\n\n  /**\n   *     A promise that resolves with the metadata for this object. If this\n   *     object doesn't exist or metadata cannot be retreived, the promise is\n   *     rejected.\n   */\n  getMetadata(): Promise<Metadata> {\n    validate('getMetadata', [], arguments);\n    this.throwIfRoot_('getMetadata');\n    return this.service.getAuthToken().then(authToken => {\n      const requestInfo = requests.getMetadata(\n        this.service,\n        this.location,\n        this.mappings()\n      );\n      return this.service.makeRequest(requestInfo, authToken).getPromise();\n    });\n  }\n\n  /**\n   * Updates the metadata for this object.\n   * @param metadata The new metadata for the object.\n   *     Only values that have been explicitly set will be changed. Explicitly\n   *     setting a value to null will remove the metadata.\n   * @return A promise that resolves\n   *     with the new metadata for this object.\n   *     @see firebaseStorage.Reference.prototype.getMetadata\n   */\n  updateMetadata(metadata: Metadata): Promise<Metadata> {\n    validate('updateMetadata', [metadataSpec()], arguments);\n    this.throwIfRoot_('updateMetadata');\n    return this.service.getAuthToken().then(authToken => {\n      const requestInfo = requests.updateMetadata(\n        this.service,\n        this.location,\n        metadata,\n        this.mappings()\n      );\n      return this.service.makeRequest(requestInfo, authToken).getPromise();\n    });\n  }\n\n  /**\n   * @return A promise that resolves with the download\n   *     URL for this object.\n   */\n  getDownloadURL(): Promise<string> {\n    validate('getDownloadURL', [], arguments);\n    this.throwIfRoot_('getDownloadURL');\n    return this.service.getAuthToken().then(authToken => {\n      const requestInfo = requests.getDownloadUrl(\n        this.service,\n        this.location,\n        this.mappings()\n      );\n      return this.service\n        .makeRequest(requestInfo, authToken)\n        .getPromise()\n        .then(url => {\n          if (url === null) {\n            throw errorsExports.noDownloadURL();\n          }\n          return url;\n        });\n    });\n  }\n\n  private throwIfRoot_(name: string): void {\n    if (this.location.path === '') {\n      throw errorsExports.invalidRootOperation(name);\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 */\nimport { FirebaseStorageError } from './error';\nimport { Request } from './request';\n\n/**\n * A request whose promise always fails.\n * @struct\n * @template T\n */\nexport class FailRequest<T> implements Request<T> {\n  promise_: Promise<T>;\n\n  constructor(error: FirebaseStorageError) {\n    this.promise_ = Promise.reject<T>(error);\n  }\n\n  /** @inheritDoc */\n  getPromise(): Promise<T> {\n    return this.promise_;\n  }\n\n  /** @inheritDoc */\n  cancel(_appDelete = false): void {}\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 Provides a method for running a function with exponential\n * backoff.\n */\ntype id = (p1: boolean) => void;\n\nexport { id };\n\n/**\n * @param f May be invoked\n *     before the function returns.\n * @param callback Get all the arguments passed to the function\n *     passed to f, including the initial boolean.\n */\nexport function start(\n  f: (p1: (success: boolean) => void, canceled: boolean) => void,\n  callback: Function,\n  timeout: number\n): id {\n  // TODO(andysoto): make this code cleaner (probably refactor into an actual\n  // type instead of a bunch of functions with state shared in the closure)\n  let waitSeconds = 1;\n  // Would type this as \"number\" but that doesn't work for Node so ¯\\_(ツ)_/¯\n  // TODO: find a way to exclude Node type definition for storage because storage only works in browser\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  let timeoutId: any = null;\n  let hitTimeout = false;\n  let cancelState = 0;\n\n  function canceled(): boolean {\n    return cancelState === 2;\n  }\n  let triggeredCallback = false;\n\n  // TODO: This disable can be removed and the 'ignoreRestArgs' option added to\n  // the no-explicit-any rule when ESlint releases it.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  function triggerCallback(...args: any[]): void {\n    if (!triggeredCallback) {\n      triggeredCallback = true;\n      callback.apply(null, args);\n    }\n  }\n\n  function callWithDelay(millis: number): void {\n    timeoutId = setTimeout(() => {\n      timeoutId = null;\n      f(handler, canceled());\n    }, millis);\n  }\n\n  // TODO: This disable can be removed and the 'ignoreRestArgs' option added to\n  // the no-explicit-any rule when ESlint releases it.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  function handler(success: boolean, ...args: any[]): void {\n    if (triggeredCallback) {\n      return;\n    }\n    if (success) {\n      triggerCallback.call(null, success, ...args);\n      return;\n    }\n    const mustStop = canceled() || hitTimeout;\n    if (mustStop) {\n      triggerCallback.call(null, success, ...args);\n      return;\n    }\n    if (waitSeconds < 64) {\n      /* TODO(andysoto): don't back off so quickly if we know we're offline. */\n      waitSeconds *= 2;\n    }\n    let waitMillis;\n    if (cancelState === 1) {\n      cancelState = 2;\n      waitMillis = 0;\n    } else {\n      waitMillis = (waitSeconds + Math.random()) * 1000;\n    }\n    callWithDelay(waitMillis);\n  }\n  let stopped = false;\n\n  function stop(wasTimeout: boolean): void {\n    if (stopped) {\n      return;\n    }\n    stopped = true;\n    if (triggeredCallback) {\n      return;\n    }\n    if (timeoutId !== null) {\n      if (!wasTimeout) {\n        cancelState = 2;\n      }\n      clearTimeout(timeoutId);\n      callWithDelay(0);\n    } else {\n      if (!wasTimeout) {\n        cancelState = 1;\n      }\n    }\n  }\n  callWithDelay(0);\n  setTimeout(() => {\n    hitTimeout = true;\n    stop(true);\n  }, timeout);\n  return stop;\n}\n\n/**\n * Stops the retry loop from repeating.\n * If the function is currently \"in between\" retries, it is invoked immediately\n * with the second parameter as \"true\". Otherwise, it will be invoked once more\n * after the current invocation finishes iff the current invocation would have\n * triggered another retry.\n */\nexport function stop(id: id): void {\n  id(false);\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 Defines methods used to actually send HTTP requests from\n * abstract representations.\n */\n\nimport firebase from '@firebase/app';\nimport * as backoff from './backoff';\nimport {\n  FirebaseStorageError,\n  unknown,\n  appDeleted,\n  canceled,\n  retryLimitExceeded\n} from './error';\nimport { RequestInfo } from './requestinfo';\nimport * as type from './type';\nimport * as UrlUtils from './url';\nimport { Headers, XhrIo, ErrorCode } from './xhrio';\nimport { XhrIoPool } from './xhriopool';\n\n/**\n * @template T\n */\nexport interface Request<T> {\n  getPromise(): Promise<T>;\n\n  /**\n   * Cancels the request. IMPORTANT: the promise may still be resolved with an\n   * appropriate value (if the request is finished before you call this method,\n   * but the promise has not yet been resolved), so don't just assume it will be\n   * rejected if you call this function.\n   * @param appDelete True if the cancelation came from the app being deleted.\n   */\n  cancel(appDelete?: boolean): void;\n}\n\n/**\n * @struct\n * @template T\n */\nclass NetworkRequest<T> implements Request<T> {\n  private url_: string;\n  private method_: string;\n  private headers_: Headers;\n  private body_: string | Blob | Uint8Array | null;\n  private successCodes_: number[];\n  private additionalRetryCodes_: number[];\n  private pendingXhr_: XhrIo | null = null;\n  private backoffId_: backoff.id | null = null;\n  private resolve_: Function | null = null;\n  private reject_: Function | null = null;\n  private canceled_: boolean = false;\n  private appDelete_: boolean = false;\n  private callback_: (p1: XhrIo, p2: string) => T;\n  private errorCallback_:\n    | ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError)\n    | null;\n  private progressCallback_: ((p1: number, p2: number) => void) | null;\n  private timeout_: number;\n  private pool_: XhrIoPool;\n  promise_: Promise<T>;\n\n  constructor(\n    url: string,\n    method: string,\n    headers: Headers,\n    body: string | Blob | Uint8Array | null,\n    successCodes: number[],\n    additionalRetryCodes: number[],\n    callback: (p1: XhrIo, p2: string) => T,\n    errorCallback:\n      | ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError)\n      | null,\n    timeout: number,\n    progressCallback: ((p1: number, p2: number) => void) | null,\n    pool: XhrIoPool\n  ) {\n    this.url_ = url;\n    this.method_ = method;\n    this.headers_ = headers;\n    this.body_ = body;\n    this.successCodes_ = successCodes.slice();\n    this.additionalRetryCodes_ = additionalRetryCodes.slice();\n    this.callback_ = callback;\n    this.errorCallback_ = errorCallback;\n    this.progressCallback_ = progressCallback;\n    this.timeout_ = timeout;\n    this.pool_ = pool;\n    this.promise_ = new Promise((resolve, reject) => {\n      this.resolve_ = resolve;\n      this.reject_ = reject;\n      this.start_();\n    });\n  }\n\n  /**\n   * Actually starts the retry loop.\n   */\n  private start_(): void {\n    const self = this;\n\n    function doTheRequest(\n      backoffCallback: (p1: boolean, ...p2: unknown[]) => void,\n      canceled: boolean\n    ): void {\n      if (canceled) {\n        backoffCallback(false, new RequestEndStatus(false, null, true));\n        return;\n      }\n      const xhr = self.pool_.createXhrIo();\n      self.pendingXhr_ = xhr;\n\n      function progressListener(progressEvent: ProgressEvent): void {\n        const loaded = progressEvent.loaded;\n        const total = progressEvent.lengthComputable ? progressEvent.total : -1;\n        if (self.progressCallback_ !== null) {\n          self.progressCallback_(loaded, total);\n        }\n      }\n      if (self.progressCallback_ !== null) {\n        xhr.addUploadProgressListener(progressListener);\n      }\n\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      xhr\n        .send(self.url_, self.method_, self.body_, self.headers_)\n        .then((xhr: XhrIo) => {\n          if (self.progressCallback_ !== null) {\n            xhr.removeUploadProgressListener(progressListener);\n          }\n          self.pendingXhr_ = null;\n          xhr = xhr as XhrIo;\n          const hitServer = xhr.getErrorCode() === ErrorCode.NO_ERROR;\n          const status = xhr.getStatus();\n          if (!hitServer || self.isRetryStatusCode_(status)) {\n            const wasCanceled = xhr.getErrorCode() === ErrorCode.ABORT;\n            backoffCallback(\n              false,\n              new RequestEndStatus(false, null, wasCanceled)\n            );\n            return;\n          }\n          const successCode = self.successCodes_.indexOf(status) !== -1;\n          backoffCallback(true, new RequestEndStatus(successCode, xhr));\n        });\n    }\n\n    /**\n     * @param requestWentThrough True if the request eventually went\n     *     through, false if it hit the retry limit or was canceled.\n     */\n    function backoffDone(\n      requestWentThrough: boolean,\n      status: RequestEndStatus\n    ): void {\n      const resolve = self.resolve_ as Function;\n      const reject = self.reject_ as Function;\n      const xhr = status.xhr as XhrIo;\n      if (status.wasSuccessCode) {\n        try {\n          const result = self.callback_(xhr, xhr.getResponseText());\n          if (type.isJustDef(result)) {\n            resolve(result);\n          } else {\n            resolve();\n          }\n        } catch (e) {\n          reject(e);\n        }\n      } else {\n        if (xhr !== null) {\n          const err = unknown();\n          err.setServerResponseProp(xhr.getResponseText());\n          if (self.errorCallback_) {\n            reject(self.errorCallback_(xhr, err));\n          } else {\n            reject(err);\n          }\n        } else {\n          if (status.canceled) {\n            const err = self.appDelete_ ? appDeleted() : canceled();\n            reject(err);\n          } else {\n            const err = retryLimitExceeded();\n            reject(err);\n          }\n        }\n      }\n    }\n    if (this.canceled_) {\n      backoffDone(false, new RequestEndStatus(false, null, true));\n    } else {\n      this.backoffId_ = backoff.start(doTheRequest, backoffDone, this.timeout_);\n    }\n  }\n\n  /** @inheritDoc */\n  getPromise(): Promise<T> {\n    return this.promise_;\n  }\n\n  /** @inheritDoc */\n  cancel(appDelete?: boolean): void {\n    this.canceled_ = true;\n    this.appDelete_ = appDelete || false;\n    if (this.backoffId_ !== null) {\n      backoff.stop(this.backoffId_);\n    }\n    if (this.pendingXhr_ !== null) {\n      this.pendingXhr_.abort();\n    }\n  }\n\n  private isRetryStatusCode_(status: number): boolean {\n    // The codes for which to retry came from this page:\n    // https://cloud.google.com/storage/docs/exponential-backoff\n    const isFiveHundredCode = status >= 500 && status < 600;\n    const extraRetryCodes = [\n      // Request Timeout: web server didn't receive full request in time.\n      408,\n      // Too Many Requests: you're getting rate-limited, basically.\n      429\n    ];\n    const isExtraRetryCode = extraRetryCodes.indexOf(status) !== -1;\n    const isRequestSpecificRetryCode =\n      this.additionalRetryCodes_.indexOf(status) !== -1;\n    return isFiveHundredCode || isExtraRetryCode || isRequestSpecificRetryCode;\n  }\n}\n\n/**\n * A collection of information about the result of a network request.\n * @param opt_canceled Defaults to false.\n * @struct\n */\nexport class RequestEndStatus {\n  /**\n   * True if the request was canceled.\n   */\n  canceled: boolean;\n\n  constructor(\n    public wasSuccessCode: boolean,\n    public xhr: XhrIo | null,\n    canceled?: boolean\n  ) {\n    this.canceled = !!canceled;\n  }\n}\n\nexport function addAuthHeader_(\n  headers: Headers,\n  authToken: string | null\n): void {\n  if (authToken !== null && authToken.length > 0) {\n    headers['Authorization'] = 'Firebase ' + authToken;\n  }\n}\n\nexport function addVersionHeader_(headers: Headers): void {\n  const version =\n    typeof firebase !== 'undefined' ? firebase.SDK_VERSION : 'AppManager';\n  headers['X-Firebase-Storage-Version'] = 'webjs/' + version;\n}\n\nexport function addGmpidHeader_(headers: Headers, appId: string | null): void {\n  if (appId) {\n    headers['X-Firebase-GMPID'] = appId;\n  }\n}\n\n/**\n * @template T\n */\nexport function makeRequest<T>(\n  requestInfo: RequestInfo<T>,\n  appId: string | null,\n  authToken: string | null,\n  pool: XhrIoPool\n): Request<T> {\n  const queryPart = UrlUtils.makeQueryString(requestInfo.urlParams);\n  const url = requestInfo.url + queryPart;\n  const headers = Object.assign({}, requestInfo.headers);\n  addGmpidHeader_(headers, appId);\n  addAuthHeader_(headers, authToken);\n  addVersionHeader_(headers);\n  return new NetworkRequest<T>(\n    url,\n    requestInfo.method,\n    headers,\n    requestInfo.body,\n    requestInfo.successCodes,\n    requestInfo.additionalRetryCodes,\n    requestInfo.handler,\n    requestInfo.errorHandler,\n    requestInfo.timeout,\n    requestInfo.progressCallback,\n    pool\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 { FirebaseApp } from '@firebase/app-types';\nimport * as args from './implementation/args';\nimport { Location } from './implementation/location';\nimport { FailRequest } from './implementation/failrequest';\nimport { Request, makeRequest } from './implementation/request';\nimport { RequestInfo } from './implementation/requestinfo';\nimport { XhrIoPool } from './implementation/xhriopool';\nimport { Reference } from './reference';\nimport { Provider } from '@firebase/component';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { FirebaseOptions } from '@firebase/app-types-exp';\nimport * as constants from '../src/implementation/constants';\nimport * as errorsExports from './implementation/error';\n\n/**\n * A service that provides firebaseStorage.Reference instances.\n * @param opt_url gs:// url to a custom Storage Bucket\n *\n * @struct\n */\nexport class StorageService {\n  private app_: FirebaseApp | null;\n  private readonly bucket_: Location | null = null;\n  private readonly internals_: ServiceInternals;\n  private readonly authProvider_: Provider<FirebaseAuthInternalName>;\n  private readonly appId_: string | null = null;\n  private readonly pool_: XhrIoPool;\n  private readonly requests_: Set<Request<unknown>>;\n  private deleted_: boolean = false;\n  private maxOperationRetryTime_: number;\n  private maxUploadRetryTime_: number;\n\n  constructor(\n    app: FirebaseApp | null,\n    authProvider: Provider<FirebaseAuthInternalName>,\n    pool: XhrIoPool,\n    url?: string\n  ) {\n    this.app_ = app;\n    this.authProvider_ = authProvider;\n    this.maxOperationRetryTime_ = constants.DEFAULT_MAX_OPERATION_RETRY_TIME;\n    this.maxUploadRetryTime_ = constants.DEFAULT_MAX_UPLOAD_RETRY_TIME;\n    this.requests_ = new Set();\n    this.pool_ = pool;\n    if (url != null) {\n      this.bucket_ = Location.makeFromBucketSpec(url);\n    } else {\n      this.bucket_ = StorageService.extractBucket_(this.app_?.options);\n    }\n    this.internals_ = new ServiceInternals(this);\n  }\n\n  private static extractBucket_(config?: FirebaseOptions): Location | null {\n    const bucketString = config?.[constants.CONFIG_STORAGE_BUCKET_KEY];\n    if (bucketString == null) {\n      return null;\n    }\n    return Location.makeFromBucketSpec(bucketString);\n  }\n\n  async getAuthToken(): Promise<string | null> {\n    const auth = this.authProvider_.getImmediate({ optional: true });\n    if (auth) {\n      const tokenData = await auth.getToken();\n      if (tokenData !== null) {\n        return tokenData.accessToken;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Stop running requests and prevent more from being created.\n   */\n  deleteApp(): void {\n    this.deleted_ = true;\n    this.app_ = null;\n    this.requests_.forEach(request => request.cancel());\n    this.requests_.clear();\n  }\n\n  /**\n   * Returns a new firebaseStorage.Reference object referencing this StorageService\n   * at the given Location.\n   * @param loc The Location.\n   * @return A firebaseStorage.Reference.\n   */\n  makeStorageReference(loc: Location): Reference {\n    return new Reference(this, loc);\n  }\n\n  makeRequest<T>(\n    requestInfo: RequestInfo<T>,\n    authToken: string | null\n  ): Request<T> {\n    if (!this.deleted_) {\n      const request = makeRequest(\n        requestInfo,\n        this.appId_,\n        authToken,\n        this.pool_\n      );\n      this.requests_.add(request);\n      // Request removes itself from set when complete.\n      request.getPromise().then(\n        () => this.requests_.delete(request),\n        () => this.requests_.delete(request)\n      );\n      return request;\n    } else {\n      return new FailRequest(errorsExports.appDeleted());\n    }\n  }\n\n  /**\n   * Returns a firebaseStorage.Reference for the given path in the default\n   * bucket.\n   */\n  ref(path?: string): Reference {\n    function validator(path: unknown): void {\n      if (typeof path !== 'string') {\n        throw 'Path is not a string.';\n      }\n      if (/^[A-Za-z]+:\\/\\//.test(path as string)) {\n        throw 'Expected child path but got a URL, use refFromURL instead.';\n      }\n    }\n    args.validate('ref', [args.stringSpec(validator, true)], arguments);\n    if (this.bucket_ == null) {\n      throw new Error('No Storage Bucket defined in Firebase Options.');\n    }\n\n    const ref = new Reference(this, this.bucket_);\n    if (path != null) {\n      return ref.child(path);\n    } else {\n      return ref;\n    }\n  }\n\n  /**\n   * Returns a firebaseStorage.Reference object for the given absolute URL,\n   * which must be a gs:// or http[s]:// URL.\n   */\n  refFromURL(url: string): Reference {\n    function validator(p: unknown): void {\n      if (typeof p !== 'string') {\n        throw 'Path is not a string.';\n      }\n      if (!/^[A-Za-z]+:\\/\\//.test(p as string)) {\n        throw 'Expected full URL but got a child path, use ref instead.';\n      }\n      try {\n        Location.makeFromUrl(p as string);\n      } catch (e) {\n        throw 'Expected valid full URL but got an invalid one.';\n      }\n    }\n    args.validate('refFromURL', [args.stringSpec(validator, false)], arguments);\n    return new Reference(this, url);\n  }\n\n  get maxUploadRetryTime(): number {\n    return this.maxUploadRetryTime_;\n  }\n\n  setMaxUploadRetryTime(time: number): void {\n    args.validate(\n      'setMaxUploadRetryTime',\n      [args.nonNegativeNumberSpec()],\n      arguments\n    );\n    this.maxUploadRetryTime_ = time;\n  }\n\n  get maxOperationRetryTime(): number {\n    return this.maxOperationRetryTime_;\n  }\n\n  setMaxOperationRetryTime(time: number): void {\n    args.validate(\n      'setMaxOperationRetryTime',\n      [args.nonNegativeNumberSpec()],\n      arguments\n    );\n    this.maxOperationRetryTime_ = time;\n  }\n\n  get app(): FirebaseApp | null {\n    return this.app_;\n  }\n\n  get INTERNAL(): ServiceInternals {\n    return this.internals_;\n  }\n}\n\n/**\n * @struct\n */\nexport class ServiceInternals {\n  service_: StorageService;\n\n  constructor(service: StorageService) {\n    this.service_ = service;\n  }\n\n  /**\n   * Called when the associated app is deleted.\n   */\n  delete(): Promise<void> {\n    this.service_.deleteApp();\n    return Promise.resolve();\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 { 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 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<T>(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 */\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    if (!source.hasOwnProperty(prop)) {\n      continue;\n    }\n    (target as { [key: string]: unknown })[prop] = deepExtend(\n      (target as { [key: string]: unknown })[prop],\n      (source as { [key: string]: unknown })[prop]\n    );\n  }\n\n  return target;\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<R> {\n  promise: Promise<R>;\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 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 'indexedDB' in self && indexedDB !== null;\n}\n\n/**\n * This method validates browser context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n */\nexport function validateIndexedDBOpenable(): Promise<boolean> {\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 = window.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          window.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 (!navigator || !navigator.cookieEnabled) {\n    return false;\n  }\n  return 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\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<T extends object>(obj: T, key: string): boolean {\n  return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet<T extends object, K extends keyof T>(\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<K extends string, V, U>(\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 * @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): object {\n  const obj: { [key: string]: unknown } = {};\n  const tokens = querystring.replace(/^\\?/, '').split('&');\n\n  tokens.forEach(token => {\n    if (token) {\n      const key = token.split('=');\n      obj[key[0]] = key[1];\n    }\n  });\n  return obj;\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<T> = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer<T> {\n  // Called once for each value in a stream of values.\n  next: NextFn<T>;\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<T> = Partial<Observer<T>>;\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<T> {\n  (next?: NextFn<T>, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n  (observer: PartialObserver<T>): Unsubscribe;\n}\n\nexport interface Observable<T> {\n  // Subscribe method\n  subscribe: Subscribe<T>;\n}\n\nexport type Executor<T> = (observer: Observer<T>) => 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<T>(\n  executor: Executor<T>,\n  onNoObservers?: Executor<T>\n): Subscribe<T> {\n  const proxy = new ObserverProxy<T>(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<T> implements Observer<T> {\n  private observers: Array<Observer<T>> | undefined = [];\n  private unsubscribes: Unsubscribe[] = [];\n  private onNoObservers: Executor<T> | 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<T>, onNoObservers?: Executor<T>) {\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<T>) => {\n      observer.next(value);\n    });\n  }\n\n  error(error: Error): void {\n    this.forEachObserver((observer: Observer<T>) => {\n      observer.error(error);\n    });\n    this.close(error);\n  }\n\n  complete(): void {\n    this.forEachObserver((observer: Observer<T>) => {\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?: PartialObserver<T> | Function,\n    error?: ErrorFn,\n    complete?: CompleteFn\n  ): Unsubscribe {\n    let observer: Observer<T>;\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<T>;\n    } else {\n      observer = {\n        next: nextOrObserver as NextFn<T>,\n        error,\n        complete\n      } as Observer<T>;\n    }\n\n    if (observer.next === undefined) {\n      observer.next = noop as NextFn<T>;\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<T>);\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<T>) => 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<T>) => 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. */\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 argumentNumber The index of the argument\n * @param optional Whether or not the argument is optional\n * @return The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(\n  fnName: string,\n  argumentNumber: number,\n  optional: boolean\n): string {\n  let argName = '';\n  switch (argumentNumber) {\n    case 1:\n      argName = optional ? 'first' : 'First';\n      break;\n    case 2:\n      argName = optional ? 'second' : 'Second';\n      break;\n    case 3:\n      argName = optional ? 'third' : 'Third';\n      break;\n    case 4:\n      argName = optional ? 'fourth' : 'Fourth';\n      break;\n    default:\n      throw new Error(\n        'errorPrefix called with argumentNumber > 4.  Need to update it?'\n      );\n  }\n\n  let error = fnName + ' failed: ';\n\n  error += argName + ' argument ';\n  return error;\n}\n\n/**\n * @param fnName\n * @param argumentNumber\n * @param namespace\n * @param optional\n */\nexport function validateNamespace(\n  fnName: string,\n  argumentNumber: number,\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, argumentNumber, optional) +\n        'must be a valid firebase namespace.'\n    );\n  }\n}\n\nexport function validateCallback(\n  fnName: string,\n  argumentNumber: number,\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, argumentNumber, optional) +\n        'must be a valid function.'\n    );\n  }\n}\n\nexport function validateContextObject(\n  fnName: string,\n  argumentNumber: number,\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, argumentNumber, optional) +\n        '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 The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Bootstrap for the Google JS Library (Closure).\n *\n * In uncompiled mode base.js will attempt to load Closure's deps file, unless\n * the global <code>CLOSURE_NO_DEPS</code> is set to true.  This allows projects\n * to include their own deps file(s) from different locations.\n *\n * Avoid including base.js more than once. This is strictly discouraged and not\n * supported. goog.require(...) won't work properly in that case.\n *\n * @provideGoog\n */\n\n\n/**\n * @define {boolean} Overridden to true by the compiler.\n */\nvar COMPILED = false;\n\n\n/**\n * Base namespace for the Closure library.  Checks to see goog is already\n * defined in the current scope before assigning to prevent clobbering if\n * base.js is loaded more than once.\n *\n * @const\n */\nvar goog = goog || {};\n\n/**\n * Reference to the global object.\n * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object\n *\n * More info on this implementation here:\n * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit\n *\n * @const\n * @suppress {undefinedVars} self won't be referenced unless `this` is falsy.\n * @type {!Global}\n */\ngoog.global =\n    // Check `this` first for backwards compatibility.\n    // Valid unless running as an ES module or in a function wrapper called\n    //   without setting `this` properly.\n    // Note that base.js can't usefully be imported as an ES module, but it may\n    // be compiled into bundles that are loadable as ES modules.\n    this ||\n    // https://developer.mozilla.org/en-US/docs/Web/API/Window/self\n    // For in-page browser environments and workers.\n    self;\n\n\n/**\n * A hook for overriding the define values in uncompiled mode.\n *\n * In uncompiled mode, `CLOSURE_UNCOMPILED_DEFINES` may be defined before\n * loading base.js.  If a key is defined in `CLOSURE_UNCOMPILED_DEFINES`,\n * `goog.define` will use the value instead of the default value.  This\n * allows flags to be overwritten without compilation (this is normally\n * accomplished with the compiler's \"define\" flag).\n *\n * Example:\n * <pre>\n *   var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};\n * </pre>\n *\n * @type {Object<string, (string|number|boolean)>|undefined}\n */\ngoog.global.CLOSURE_UNCOMPILED_DEFINES;\n\n\n/**\n * A hook for overriding the define values in uncompiled or compiled mode,\n * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code.  In\n * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.\n *\n * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or\n * string literals or the compiler will emit an error.\n *\n * While any @define value may be set, only those set with goog.define will be\n * effective for uncompiled code.\n *\n * Example:\n * <pre>\n *   var CLOSURE_DEFINES = {'goog.DEBUG': false} ;\n * </pre>\n *\n * @type {Object<string, (string|number|boolean)>|undefined}\n */\ngoog.global.CLOSURE_DEFINES;\n\n\n/**\n * Builds an object structure for the provided namespace path, ensuring that\n * names that already exist are not overwritten. For example:\n * \"a.b.c\" -> a = {};a.b={};a.b.c={};\n * Used by goog.provide and goog.exportSymbol.\n * @param {string} name The name of the object that this file defines.\n * @param {*=} object The object to expose at the end of the path.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n *     implicitly constructed the namespace given by name, this parameter\n *     controls whether object should overwrite the implicitly constructed\n *     namespace or be merged into it. Defaults to false.\n * @param {?Object=} objectToExportTo The object to add the path to; if this\n *     field is not specified, its value defaults to `goog.global`.\n * @private\n */\ngoog.exportPath_ = function(name, object, overwriteImplicit, objectToExportTo) {\n  var parts = name.split('.');\n  var cur = objectToExportTo || goog.global;\n\n  // Internet Explorer exhibits strange behavior when throwing errors from\n  // methods externed in this manner.  See the testExportSymbolExceptions in\n  // base_test.html for an example.\n  if (!(parts[0] in cur) && typeof cur.execScript != 'undefined') {\n    cur.execScript('var ' + parts[0]);\n  }\n\n  for (var part; parts.length && (part = parts.shift());) {\n    if (!parts.length && object !== undefined) {\n      if (!overwriteImplicit && goog.isObject(object) &&\n          goog.isObject(cur[part])) {\n        // Merge properties on object (the input parameter) with the existing\n        // implicitly defined namespace, so as to not clobber previously\n        // defined child namespaces.\n        for (var prop in object) {\n          if (object.hasOwnProperty(prop)) {\n            cur[part][prop] = object[prop];\n          }\n        }\n      } else {\n        // Either there is no existing implicit namespace, or overwriteImplicit\n        // is set to true, so directly assign object (the input parameter) to\n        // the namespace.\n        cur[part] = object;\n      }\n    } else if (cur[part] && cur[part] !== Object.prototype[part]) {\n      cur = cur[part];\n    } else {\n      cur = cur[part] = {};\n    }\n  }\n};\n\n\n/**\n * Defines a named value. In uncompiled mode, the value is retrieved from\n * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and\n * has the property specified, and otherwise used the defined defaultValue.\n * When compiled the default can be overridden using the compiler options or the\n * value set in the CLOSURE_DEFINES object. Returns the defined value so that it\n * can be used safely in modules. Note that the value type MUST be either\n * boolean, number, or string.\n *\n * @param {string} name The distinguished name to provide.\n * @param {T} defaultValue\n * @return {T} The defined value.\n * @template T\n */\ngoog.define = function(name, defaultValue) {\n  var value = defaultValue;\n  if (!COMPILED) {\n    var uncompiledDefines = goog.global.CLOSURE_UNCOMPILED_DEFINES;\n    var defines = goog.global.CLOSURE_DEFINES;\n    if (uncompiledDefines &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        /** @type {?} */ (uncompiledDefines).nodeType === undefined &&\n        Object.prototype.hasOwnProperty.call(uncompiledDefines, name)) {\n      value = uncompiledDefines[name];\n    } else if (\n        defines &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        /** @type {?} */ (defines).nodeType === undefined &&\n        Object.prototype.hasOwnProperty.call(defines, name)) {\n      value = defines[name];\n    }\n  }\n  return value;\n};\n\n\n/**\n * @define {number} Integer year indicating the set of browser features that are\n * guaranteed to be present.  This is defined to include exactly features that\n * work correctly on all \"modern\" browsers that are stable on January 1 of the\n * specified year.  For example,\n * ```js\n * if (goog.FEATURESET_YEAR >= 2019) {\n *   // use APIs known to be available on all major stable browsers Jan 1, 2019\n * } else {\n *   // polyfill for older browsers\n * }\n * ```\n * This is intended to be the primary define for removing\n * unnecessary browser compatibility code (such as ponyfills and workarounds),\n * and should inform the default value for most other defines:\n * ```js\n * const ASSUME_NATIVE_PROMISE =\n *     goog.define('ASSUME_NATIVE_PROMISE', goog.FEATURESET_YEAR >= 2016);\n * ```\n *\n * The default assumption is that IE9 is the lowest supported browser, which was\n * first available Jan 1, 2012.\n *\n * TODO(user): Reference more thorough documentation when it's available.\n */\ngoog.FEATURESET_YEAR = goog.define('goog.FEATURESET_YEAR', 2012);\n\n\n/**\n * @define {boolean} DEBUG is provided as a convenience so that debugging code\n * that should not be included in a production. It can be easily stripped\n * by specifying --define goog.DEBUG=false to the Closure Compiler aka\n * JSCompiler. For example, most toString() methods should be declared inside an\n * \"if (goog.DEBUG)\" conditional because they are generally used for debugging\n * purposes and it is difficult for the JSCompiler to statically determine\n * whether they are used.\n */\ngoog.DEBUG = goog.define('goog.DEBUG', true);\n\n\n/**\n * @define {string} LOCALE defines the locale being used for compilation. It is\n * used to select locale specific data to be compiled in js binary. BUILD rule\n * can specify this value by \"--define goog.LOCALE=<locale_name>\" as a compiler\n * option.\n *\n * Take into account that the locale code format is important. You should use\n * the canonical Unicode format with hyphen as a delimiter. Language must be\n * lowercase, Language Script - Capitalized, Region - UPPERCASE.\n * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.\n *\n * See more info about locale codes here:\n * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers\n *\n * For language codes you should use values defined by ISO 693-1. See it here\n * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from\n * this rule: the Hebrew language. For legacy reasons the old code (iw) should\n * be used instead of the new code (he).\n *\n */\ngoog.LOCALE = goog.define('goog.LOCALE', 'en');  // default to en\n\n\n/**\n * @define {boolean} Whether this code is running on trusted sites.\n *\n * On untrusted sites, several native functions can be defined or overridden by\n * external libraries like Prototype, Datejs, and JQuery and setting this flag\n * to false forces closure to use its own implementations when possible.\n *\n * If your JavaScript can be loaded by a third party site and you are wary about\n * relying on non-standard implementations, specify\n * \"--define goog.TRUSTED_SITE=false\" to the compiler.\n */\ngoog.TRUSTED_SITE = goog.define('goog.TRUSTED_SITE', true);\n\n\n/**\n * @define {boolean} Whether code that calls {@link goog.setTestOnly} should\n *     be disallowed in the compilation unit.\n */\ngoog.DISALLOW_TEST_ONLY_CODE =\n    goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);\n\n\n/**\n * @define {boolean} Whether to use a Chrome app CSP-compliant method for\n *     loading scripts via goog.require. @see appendScriptSrcNode_.\n */\ngoog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING =\n    goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);\n\n\n/**\n * Defines a namespace in Closure.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * The presence of one or more goog.provide() calls in a file indicates\n * that the file defines the given objects/namespaces.\n * Provided symbols must not be null or undefined.\n *\n * In addition, goog.provide() creates the object stubs for a namespace\n * (for example, goog.provide(\"goog.foo.bar\") will create the object\n * goog.foo.bar if it does not already exist).\n *\n * Build tools also scan for provide/require/module statements\n * to discern dependencies, build dependency files (see deps.js), etc.\n *\n * @see goog.require\n * @see goog.module\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\".\n * deprecated Use goog.module (see b/159289405)\n */\ngoog.provide = function(name) {\n  if (goog.isInModuleLoader_()) {\n    throw new Error('goog.provide cannot be used within a module.');\n  }\n  if (!COMPILED) {\n    // Ensure that the same namespace isn't provided twice.\n    // A goog.module/goog.provide maps a goog.require to a specific file\n    if (goog.isProvided_(name)) {\n      throw new Error('Namespace \"' + name + '\" already declared.');\n    }\n  }\n\n  goog.constructNamespace_(name);\n};\n\n\n/**\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\".\n * @param {?Object=} object The object to embed in the namespace.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n *     implicitly constructed the namespace given by name, this parameter\n *     controls whether opt_obj should overwrite the implicitly constructed\n *     namespace or be merged into it. Defaults to false.\n * @private\n */\ngoog.constructNamespace_ = function(name, object, overwriteImplicit) {\n  if (!COMPILED) {\n    delete goog.implicitNamespaces_[name];\n\n    var namespace = name;\n    while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {\n      if (goog.getObjectByName(namespace)) {\n        break;\n      }\n      goog.implicitNamespaces_[namespace] = true;\n    }\n  }\n\n  goog.exportPath_(name, object, overwriteImplicit);\n};\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {?Window=} opt_window The window context used to retrieve the nonce.\n *     Defaults to global context.\n * @return {string} CSP nonce or empty string if no nonce is present.\n */\ngoog.getScriptNonce = function(opt_window) {\n  if (opt_window && opt_window != goog.global) {\n    return goog.getScriptNonce_(opt_window.document);\n  }\n  if (goog.cspNonce_ === null) {\n    goog.cspNonce_ = goog.getScriptNonce_(goog.global.document);\n  }\n  return goog.cspNonce_;\n};\n\n\n/**\n * According to the CSP3 spec a nonce must be a valid base64 string.\n * @see https://www.w3.org/TR/CSP3/#grammardef-base64-value\n * @private @const\n */\ngoog.NONCE_PATTERN_ = /^[\\w+/_-]+[=]{0,2}$/;\n\n\n/**\n * @private {?string}\n */\ngoog.cspNonce_ = null;\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {!Document} doc\n * @return {string} CSP nonce or empty string if no nonce is present.\n * @private\n */\ngoog.getScriptNonce_ = function(doc) {\n  var script = doc.querySelector && doc.querySelector('script[nonce]');\n  if (script) {\n    // Try to get the nonce from the IDL property first, because browsers that\n    // implement additional nonce protection features (currently only Chrome) to\n    // prevent nonce stealing via CSS do not expose the nonce via attributes.\n    // See https://github.com/whatwg/html/issues/2369\n    var nonce = script['nonce'] || script.getAttribute('nonce');\n    if (nonce && goog.NONCE_PATTERN_.test(nonce)) {\n      return nonce;\n    }\n  }\n  return '';\n};\n\n\n/**\n * Module identifier validation regexp.\n * Note: This is a conservative check, it is very possible to be more lenient,\n *   the primary exclusion here is \"/\" and \"\\\" and a leading \".\", these\n *   restrictions are intended to leave the door open for using goog.require\n *   with relative file paths rather than module identifiers.\n * @private\n */\ngoog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\n\n\n/**\n * Defines a module in Closure.\n *\n * Marks that this file must be loaded as a module and claims the namespace.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * goog.module() has three requirements:\n * - goog.module may not be used in the same file as goog.provide.\n * - goog.module must be the first statement in the file.\n * - only one goog.module is allowed per file.\n *\n * When a goog.module annotated file is loaded, it is enclosed in\n * a strict function closure. This means that:\n * - any variables declared in a goog.module file are private to the file\n * (not global), though the compiler is expected to inline the module.\n * - The code must obey all the rules of \"strict\" JavaScript.\n * - the file will be marked as \"use strict\"\n *\n * NOTE: unlike goog.provide, goog.module does not declare any symbols by\n * itself. If declared symbols are desired, use\n * goog.module.declareLegacyNamespace().\n *\n *\n * See the public goog.module proposal: http://goo.gl/Va1hin\n *\n * @param {string} name Namespace provided by this file in the form\n *     \"goog.package.part\", is expected but not required.\n * @return {void}\n */\ngoog.module = function(name) {\n  if (typeof name !== 'string' || !name ||\n      name.search(goog.VALID_MODULE_RE_) == -1) {\n    throw new Error('Invalid module identifier');\n  }\n  if (!goog.isInGoogModuleLoader_()) {\n    throw new Error(\n        'Module ' + name + ' has been loaded incorrectly. Note, ' +\n        'modules cannot be loaded as normal scripts. They require some kind of ' +\n        'pre-processing step. You\\'re likely trying to load a module via a ' +\n        'script tag or as a part of a concatenated bundle without rewriting the ' +\n        'module. For more info see: ' +\n        'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.');\n  }\n  if (goog.moduleLoaderState_.moduleName) {\n    throw new Error('goog.module may only be called once per module.');\n  }\n\n  // Store the module name for the loader.\n  goog.moduleLoaderState_.moduleName = name;\n  if (!COMPILED) {\n    // Ensure that the same namespace isn't provided twice.\n    // A goog.module/goog.provide maps a goog.require to a specific file\n    if (goog.isProvided_(name)) {\n      throw new Error('Namespace \"' + name + '\" already declared.');\n    }\n    delete goog.implicitNamespaces_[name];\n  }\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n *\n * Note: This is not an alternative to goog.require, it does not\n * indicate a hard dependency, instead it is used to indicate\n * an optional dependency or to access the exports of a module\n * that has already been loaded.\n * @suppress {missingProvide}\n */\ngoog.module.get = function(name) {\n  return goog.module.getInternal_(name);\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n * @private\n */\ngoog.module.getInternal_ = function(name) {\n  if (!COMPILED) {\n    if (name in goog.loadedModules_) {\n      return goog.loadedModules_[name].exports;\n    } else if (!goog.implicitNamespaces_[name]) {\n      var ns = goog.getObjectByName(name);\n      return ns != null ? ns : null;\n    }\n  }\n  return null;\n};\n\n\n/**\n * Types of modules the debug loader can load.\n * @enum {string}\n */\ngoog.ModuleType = {\n  ES6: 'es6',\n  GOOG: 'goog'\n};\n\n\n/**\n * @private {?{\n *   moduleName: (string|undefined),\n *   declareLegacyNamespace:boolean,\n *   type: ?goog.ModuleType\n * }}\n */\ngoog.moduleLoaderState_ = null;\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module or an es6 module is currently being\n *     initialized.\n */\ngoog.isInModuleLoader_ = function() {\n  return goog.isInGoogModuleLoader_() || goog.isInEs6ModuleLoader_();\n};\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module is currently being initialized.\n */\ngoog.isInGoogModuleLoader_ = function() {\n  return !!goog.moduleLoaderState_ &&\n      goog.moduleLoaderState_.type == goog.ModuleType.GOOG;\n};\n\n\n/**\n * @private\n * @return {boolean} Whether an es6 module is currently being initialized.\n */\ngoog.isInEs6ModuleLoader_ = function() {\n  var inLoader = !!goog.moduleLoaderState_ &&\n      goog.moduleLoaderState_.type == goog.ModuleType.ES6;\n\n  if (inLoader) {\n    return true;\n  }\n\n  var jscomp = goog.global['$jscomp'];\n\n  if (jscomp) {\n    // jscomp may not have getCurrentModulePath if this is a compiled bundle\n    // that has some of the runtime, but not all of it. This can happen if\n    // optimizations are turned on so the unused runtime is removed but renaming\n    // and Closure pass are off (so $jscomp is still named $jscomp and the\n    // goog.provide/require calls still exist).\n    if (typeof jscomp.getCurrentModulePath != 'function') {\n      return false;\n    }\n\n    // Bundled ES6 module.\n    return !!jscomp.getCurrentModulePath();\n  }\n\n  return false;\n};\n\n\n/**\n * Provide the module's exports as a globally accessible object under the\n * module's declared name.  This is intended to ease migration to goog.module\n * for files that have existing usages.\n * @suppress {missingProvide}\n */\ngoog.module.declareLegacyNamespace = function() {\n  if (!COMPILED && !goog.isInGoogModuleLoader_()) {\n    throw new Error(\n        'goog.module.declareLegacyNamespace must be called from ' +\n        'within a goog.module');\n  }\n  if (!COMPILED && !goog.moduleLoaderState_.moduleName) {\n    throw new Error(\n        'goog.module must be called prior to ' +\n        'goog.module.declareLegacyNamespace.');\n  }\n  goog.moduleLoaderState_.declareLegacyNamespace = true;\n};\n\n\n/**\n * Associates an ES6 module with a Closure module ID so that is available via\n * goog.require. The associated ID  acts like a goog.module ID - it does not\n * create any global names, it is merely available via goog.require /\n * goog.module.get / goog.forwardDeclare / goog.requireType. goog.require and\n * goog.module.get will return the entire module as if it was import *'d. This\n * allows Closure files to reference ES6 modules for the sake of migration.\n *\n * @param {string} namespace\n * @suppress {missingProvide}\n */\ngoog.declareModuleId = function(namespace) {\n  if (!COMPILED) {\n    if (!goog.isInEs6ModuleLoader_()) {\n      throw new Error(\n          'goog.declareModuleId may only be called from ' +\n          'within an ES6 module');\n    }\n    if (goog.moduleLoaderState_ && goog.moduleLoaderState_.moduleName) {\n      throw new Error(\n          'goog.declareModuleId may only be called once per module.');\n    }\n    if (namespace in goog.loadedModules_) {\n      throw new Error(\n          'Module with namespace \"' + namespace + '\" already exists.');\n    }\n  }\n  if (goog.moduleLoaderState_) {\n    // Not bundled - debug loading.\n    goog.moduleLoaderState_.moduleName = namespace;\n  } else {\n    // Bundled - not debug loading, no module loader state.\n    var jscomp = goog.global['$jscomp'];\n    if (!jscomp || typeof jscomp.getCurrentModulePath != 'function') {\n      throw new Error(\n          'Module with namespace \"' + namespace +\n          '\" has been loaded incorrectly.');\n    }\n    var exports = jscomp.require(jscomp.getCurrentModulePath());\n    goog.loadedModules_[namespace] = {\n      exports: exports,\n      type: goog.ModuleType.ES6,\n      moduleId: namespace\n    };\n  }\n};\n\n\n/**\n * Marks that the current file should only be used for testing, and never for\n * live code in production.\n *\n * In the case of unit tests, the message may optionally be an exact namespace\n * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra\n * provide (if not explicitly defined in the code).\n *\n * @param {string=} opt_message Optional message to add to the error that's\n *     raised when used in production code.\n */\ngoog.setTestOnly = function(opt_message) {\n  if (goog.DISALLOW_TEST_ONLY_CODE) {\n    opt_message = opt_message || '';\n    throw new Error(\n        'Importing test-only code into non-debug environment' +\n        (opt_message ? ': ' + opt_message : '.'));\n  }\n};\n\n\n/**\n * Forward declares a symbol. This is an indication to the compiler that the\n * symbol may be used in the source yet is not required and may not be provided\n * in compilation.\n *\n * The most common usage of forward declaration is code that takes a type as a\n * function parameter but does not need to require it. By forward declaring\n * instead of requiring, no hard dependency is made, and (if not required\n * elsewhere) the namespace may never be required and thus, not be pulled\n * into the JavaScript binary. If it is required elsewhere, it will be type\n * checked as normal.\n *\n * Before using goog.forwardDeclare, please read the documentation at\n * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to\n * understand the options and tradeoffs when working with forward declarations.\n *\n * @param {string} name The namespace to forward declare in the form of\n *     \"goog.package.part\".\n * @deprecated See go/noforwarddeclaration, Use `goog.requireType` instead.\n */\ngoog.forwardDeclare = function(name) {};\n\n\n/**\n * Forward declare type information. Used to assign types to goog.global\n * referenced object that would otherwise result in unknown type references\n * and thus block property disambiguation.\n */\ngoog.forwardDeclare('Document');\ngoog.forwardDeclare('HTMLScriptElement');\ngoog.forwardDeclare('XMLHttpRequest');\n\n\nif (!COMPILED) {\n  /**\n   * Check if the given name has been goog.provided. This will return false for\n   * names that are available only as implicit namespaces.\n   * @param {string} name name of the object to look for.\n   * @return {boolean} Whether the name has been provided.\n   * @private\n   */\n  goog.isProvided_ = function(name) {\n    return (name in goog.loadedModules_) ||\n        (!goog.implicitNamespaces_[name] && goog.getObjectByName(name) != null);\n  };\n\n  /**\n   * Namespaces implicitly defined by goog.provide. For example,\n   * goog.provide('goog.events.Event') implicitly declares that 'goog' and\n   * 'goog.events' must be namespaces.\n   *\n   * @type {!Object<string, (boolean|undefined)>}\n   * @private\n   */\n  goog.implicitNamespaces_ = {'goog.module': true};\n\n  // NOTE: We add goog.module as an implicit namespace as goog.module is defined\n  // here and because the existing module package has not been moved yet out of\n  // the goog.module namespace. This satisifies both the debug loader and\n  // ahead-of-time dependency management.\n}\n\n\n/**\n * Returns an object based on its fully qualified external name.  The object\n * is not found if null or undefined.  If you are using a compilation pass that\n * renames property names beware that using this function will not find renamed\n * properties.\n *\n * @param {string} name The fully qualified name.\n * @param {Object=} opt_obj The object within which to look; default is\n *     |goog.global|.\n * @return {?} The value (object or primitive) or, if not found, null.\n */\ngoog.getObjectByName = function(name, opt_obj) {\n  var parts = name.split('.');\n  var cur = opt_obj || goog.global;\n  for (var i = 0; i < parts.length; i++) {\n    cur = cur[parts[i]];\n    if (cur == null) {\n      return null;\n    }\n  }\n  return cur;\n};\n\n\n/**\n * Adds a dependency from a file to the files it requires.\n * @param {string} relPath The path to the js file.\n * @param {!Array<string>} provides An array of strings with\n *     the names of the objects this file provides.\n * @param {!Array<string>} requires An array of strings with\n *     the names of the objects this file requires.\n * @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating\n *     how the file must be loaded.  The boolean 'true' is equivalent\n *     to {'module': 'goog'} for backwards-compatibility.  Valid properties\n *     and values include {'module': 'goog'} and {'lang': 'es6'}.\n */\ngoog.addDependency = function(relPath, provides, requires, opt_loadFlags) {\n  if (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n    goog.debugLoader_.addDependency(relPath, provides, requires, opt_loadFlags);\n  }\n};\n\n\n// NOTE(nnaze): The debug DOM loader was included in base.js as an original way\n// to do \"debug-mode\" development.  The dependency system can sometimes be\n// confusing, as can the debug DOM loader's asynchronous nature.\n//\n// With the DOM loader, a call to goog.require() is not blocking -- the script\n// will not load until some point after the current script.  If a namespace is\n// needed at runtime, it needs to be defined in a previous script, or loaded via\n// require() with its registered dependencies.\n//\n// User-defined namespaces may need their own deps file. For a reference on\n// creating a deps file, see:\n// Externally: https://developers.google.com/closure/library/docs/depswriter\n//\n// Because of legacy clients, the DOM loader can't be easily removed from\n// base.js.  Work was done to make it disableable or replaceable for\n// different environments (DOM-less JavaScript interpreters like Rhino or V8,\n// for example). See bootstrap/ for more information.\n\n\n/**\n * @define {boolean} Whether to enable the debug loader.\n *\n * If enabled, a call to goog.require() will attempt to load the namespace by\n * appending a script tag to the DOM (if the namespace has been registered).\n *\n * If disabled, goog.require() will simply assert that the namespace has been\n * provided (and depend on the fact that some outside tool correctly ordered\n * the script).\n */\ngoog.ENABLE_DEBUG_LOADER = goog.define('goog.ENABLE_DEBUG_LOADER', true);\n\n\n/**\n * @param {string} msg\n * @private\n */\ngoog.logToConsole_ = function(msg) {\n  if (goog.global.console) {\n    goog.global.console['error'](msg);\n  }\n};\n\n\n/**\n * Implements a system for the dynamic resolution of dependencies that works in\n * parallel with the BUILD system.\n *\n * Note that all calls to goog.require will be stripped by the compiler.\n *\n * @see goog.provide\n * @param {string} namespace Namespace (as was given in goog.provide,\n *     goog.module, or goog.declareModuleId) in the form\n *     \"goog.package.part\".\n * @return {?} If called within a goog.module or ES6 module file, the associated\n *     namespace or module otherwise null.\n */\ngoog.require = function(namespace) {\n  if (!COMPILED) {\n    // Might need to lazy load on old IE.\n    if (goog.ENABLE_DEBUG_LOADER) {\n      goog.debugLoader_.requested(namespace);\n    }\n\n    // If the object already exists we do not need to do anything.\n    if (goog.isProvided_(namespace)) {\n      if (goog.isInModuleLoader_()) {\n        return goog.module.getInternal_(namespace);\n      }\n    } else if (goog.ENABLE_DEBUG_LOADER) {\n      var moduleLoaderState = goog.moduleLoaderState_;\n      goog.moduleLoaderState_ = null;\n      try {\n        goog.debugLoader_.load_(namespace);\n      } finally {\n        goog.moduleLoaderState_ = moduleLoaderState;\n      }\n    }\n\n    return null;\n  }\n};\n\n\n/**\n * Requires a symbol for its type information. This is an indication to the\n * compiler that the symbol may appear in type annotations, yet it is not\n * referenced at runtime.\n *\n * When called within a goog.module or ES6 module file, the return value may be\n * assigned to or destructured into a variable, but it may not be otherwise used\n * in code outside of a type annotation.\n *\n * Note that all calls to goog.requireType will be stripped by the compiler.\n *\n * @param {string} namespace Namespace (as was given in goog.provide,\n *     goog.module, or goog.declareModuleId) in the form\n *     \"goog.package.part\".\n * @return {?}\n */\ngoog.requireType = function(namespace) {\n  // Return an empty object so that single-level destructuring of the return\n  // value doesn't crash at runtime when using the debug loader. Multi-level\n  // destructuring isn't supported.\n  return {};\n};\n\n\n/**\n * Path for included scripts.\n * @type {string}\n */\ngoog.basePath = '';\n\n\n/**\n * A hook for overriding the base path.\n * @type {string|undefined}\n */\ngoog.global.CLOSURE_BASE_PATH;\n\n\n/**\n * Whether to attempt to load Closure's deps file. By default, when uncompiled,\n * deps files will attempt to be loaded.\n * @type {boolean|undefined}\n */\ngoog.global.CLOSURE_NO_DEPS;\n\n\n/**\n * A function to import a single script. This is meant to be overridden when\n * Closure is being run in non-HTML contexts, such as web workers. It's defined\n * in the global scope so that it can be set before base.js is loaded, which\n * allows deps.js to be imported properly.\n *\n * The first parameter the script source, which is a relative URI. The second,\n * optional parameter is the script contents, in the event the script needed\n * transformation. It should return true if the script was imported, false\n * otherwise.\n * @type {(function(string, string=): boolean)|undefined}\n */\ngoog.global.CLOSURE_IMPORT_SCRIPT;\n\n\n/**\n * Null function used for default values of callbacks, etc.\n * @return {void} Nothing.\n * @deprecated use '()=>{}' or 'function(){}' instead.\n */\ngoog.nullFunction = function() {};\n\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = goog.abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @deprecated Use \"@abstract\" annotation instead of goog.abstractMethod in new\n *     code. See\n *     https://github.com/google/closure-compiler/wiki/@abstract-classes-and-methods\n */\ngoog.abstractMethod = function() {\n  throw new Error('unimplemented abstract method');\n};\n\n\n/**\n * Adds a `getInstance` static method that always returns the same\n * instance object.\n * @param {!Function} ctor The constructor for the class to add the static\n *     method to.\n * @suppress {missingProperties} 'instance_' isn't a property on 'Function'\n *     but we don't have a better type to use here.\n */\ngoog.addSingletonGetter = function(ctor) {\n  // instance_ is immediately set to prevent issues with sealed constructors\n  // such as are encountered when a constructor is returned as the export object\n  // of a goog.module in unoptimized code.\n  // Delcare type to avoid conformance violations that ctor.instance_ is unknown\n  /** @type {undefined|!Object} @suppress {underscore} */\n  ctor.instance_ = undefined;\n  ctor.getInstance = function() {\n    if (ctor.instance_) {\n      return ctor.instance_;\n    }\n    if (goog.DEBUG) {\n      // NOTE: JSCompiler can't optimize away Array#push.\n      goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;\n    }\n    // Cast to avoid conformance violations that ctor.instance_ is unknown\n    return /** @type {!Object|undefined} */ (ctor.instance_) = new ctor;\n  };\n};\n\n\n/**\n * All singleton classes that have been instantiated, for testing. Don't read\n * it directly, use the `goog.testing.singleton` module. The compiler\n * removes this variable if unused.\n * @type {!Array<!Function>}\n * @private\n */\ngoog.instantiatedSingletons_ = [];\n\n\n/**\n * @define {boolean} Whether to load goog.modules using `eval` when using\n * the debug loader.  This provides a better debugging experience as the\n * source is unmodified and can be edited using Chrome Workspaces or similar.\n * However in some environments the use of `eval` is banned\n * so we provide an alternative.\n */\ngoog.LOAD_MODULE_USING_EVAL = goog.define('goog.LOAD_MODULE_USING_EVAL', true);\n\n\n/**\n * @define {boolean} Whether the exports of goog.modules should be sealed when\n * possible.\n */\ngoog.SEAL_MODULE_EXPORTS = goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);\n\n\n/**\n * The registry of initialized modules:\n * The module identifier or path to module exports map.\n * @private @const {!Object<string, {exports:?,type:string,moduleId:string}>}\n */\ngoog.loadedModules_ = {};\n\n\n/**\n * True if the debug loader enabled and used.\n * @const {boolean}\n */\ngoog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;\n\n\n/**\n * @define {string} How to decide whether to transpile.  Valid values\n * are 'always', 'never', and 'detect'.  The default ('detect') is to\n * use feature detection to determine which language levels need\n * transpilation.\n */\n// NOTE(sdh): we could expand this to accept a language level to bypass\n// detection: e.g. goog.TRANSPILE == 'es5' would transpile ES6 files but\n// would leave ES3 and ES5 files alone.\ngoog.TRANSPILE = goog.define('goog.TRANSPILE', 'detect');\n\n/**\n * @define {boolean} If true assume that ES modules have already been\n * transpiled by the jscompiler (in the same way that transpile.js would\n * transpile them - to jscomp modules). Useful only for servers that wish to use\n * the debug loader and transpile server side. Thus this is only respected if\n * goog.TRANSPILE is \"never\".\n */\ngoog.ASSUME_ES_MODULES_TRANSPILED =\n    goog.define('goog.ASSUME_ES_MODULES_TRANSPILED', false);\n\n\n/**\n * @define {string} If a file needs to be transpiled what the output language\n * should be. By default this is the highest language level this file detects\n * the current environment supports. Generally this flag should not be set, but\n * it could be useful to override. Example: If the current environment supports\n * ES6 then by default ES7+ files will be transpiled to ES6, unless this is\n * overridden.\n *\n * Valid values include: es3, es5, es6, es7, and es8. Anything not recognized\n * is treated as es3.\n *\n * Note that setting this value does not force transpilation. Just if\n * transpilation occurs this will be the output. So this is most useful when\n * goog.TRANSPILE is set to 'always' and then forcing the language level to be\n * something lower than what the environment detects.\n */\ngoog.TRANSPILE_TO_LANGUAGE = goog.define('goog.TRANSPILE_TO_LANGUAGE', '');\n\n\n/**\n * @define {string} Path to the transpiler.  Executing the script at this\n * path (relative to base.js) should define a function $jscomp.transpile.\n */\ngoog.TRANSPILER = goog.define('goog.TRANSPILER', 'transpile.js');\n\n\n/**\n * @package {?boolean}\n * Visible for testing.\n */\ngoog.hasBadLetScoping = null;\n\n\n/**\n * @return {boolean}\n * @package Visible for testing.\n */\ngoog.useSafari10Workaround = function() {\n  if (goog.hasBadLetScoping == null) {\n    var hasBadLetScoping;\n    try {\n      hasBadLetScoping = !eval(\n          '\"use strict\";' +\n          'let x = 1; function f() { return typeof x; };' +\n          'f() == \"number\";');\n    } catch (e) {\n      // Assume that ES6 syntax isn't supported.\n      hasBadLetScoping = false;\n    }\n    goog.hasBadLetScoping = hasBadLetScoping;\n  }\n  return goog.hasBadLetScoping;\n};\n\n\n/**\n * @param {string} moduleDef\n * @return {string}\n * @package Visible for testing.\n */\ngoog.workaroundSafari10EvalBug = function(moduleDef) {\n  return '(function(){' + moduleDef +\n      '\\n' +  // Terminate any trailing single line comment.\n      ';' +   // Terminate any trailing expression.\n      '})();\\n';\n};\n\n\n/**\n * @param {function(?):?|string} moduleDef The module definition.\n */\ngoog.loadModule = function(moduleDef) {\n  // NOTE: we allow function definitions to be either in the from\n  // of a string to eval (which keeps the original source intact) or\n  // in a eval forbidden environment (CSP) we allow a function definition\n  // which in its body must call `goog.module`, and return the exports\n  // of the module.\n  var previousState = goog.moduleLoaderState_;\n  try {\n    goog.moduleLoaderState_ = {\n      moduleName: '',\n      declareLegacyNamespace: false,\n      type: goog.ModuleType.GOOG\n    };\n    var origExports = {};\n    var exports = origExports;\n    if (goog.isFunction(moduleDef)) {\n      exports = moduleDef.call(undefined, exports);\n    } else if (typeof moduleDef === 'string') {\n      if (goog.useSafari10Workaround()) {\n        moduleDef = goog.workaroundSafari10EvalBug(moduleDef);\n      }\n\n      exports = goog.loadModuleFromSource_.call(undefined, exports, moduleDef);\n    } else {\n      throw new Error('Invalid module definition');\n    }\n\n    var moduleName = goog.moduleLoaderState_.moduleName;\n    if (typeof moduleName === 'string' && moduleName) {\n      // Don't seal legacy namespaces as they may be used as a parent of\n      // another namespace\n      if (goog.moduleLoaderState_.declareLegacyNamespace) {\n        // Whether exports was overwritten via default export assignment.\n        // This is important for legacy namespaces as it dictates whether\n        // previously a previously loaded implicit namespace should be clobbered\n        // or not.\n        var isDefaultExport = origExports !== exports;\n        goog.constructNamespace_(moduleName, exports, isDefaultExport);\n      } else if (\n          goog.SEAL_MODULE_EXPORTS && Object.seal &&\n          typeof exports == 'object' && exports != null) {\n        Object.seal(exports);\n      }\n\n      var data = {\n        exports: exports,\n        type: goog.ModuleType.GOOG,\n        moduleId: goog.moduleLoaderState_.moduleName\n      };\n      goog.loadedModules_[moduleName] = data;\n    } else {\n      throw new Error('Invalid module name \\\"' + moduleName + '\\\"');\n    }\n  } finally {\n    goog.moduleLoaderState_ = previousState;\n  }\n};\n\n\n/**\n * @private @const\n */\ngoog.loadModuleFromSource_ =\n    /** @type {function(!Object, string):?} */ (function(exports) {\n      // NOTE: we avoid declaring parameters or local variables here to avoid\n      // masking globals or leaking values into the module definition.\n      'use strict';\n      eval(arguments[1]);\n      return exports;\n    });\n\n\n/**\n * Normalize a file path by removing redundant \"..\" and extraneous \".\" file\n * path components.\n * @param {string} path\n * @return {string}\n * @private\n */\ngoog.normalizePath_ = function(path) {\n  var components = path.split('/');\n  var i = 0;\n  while (i < components.length) {\n    if (components[i] == '.') {\n      components.splice(i, 1);\n    } else if (\n        i && components[i] == '..' && components[i - 1] &&\n        components[i - 1] != '..') {\n      components.splice(--i, 2);\n    } else {\n      i++;\n    }\n  }\n  return components.join('/');\n};\n\n\n/**\n * Provides a hook for loading a file when using Closure's goog.require() API\n * with goog.modules.  In particular this hook is provided to support Node.js.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_LOAD_FILE_SYNC;\n\n\n/**\n * Loads file by synchronous XHR. Should not be used in production environments.\n * @param {string} src Source URL.\n * @return {?string} File contents, or null if load failed.\n * @private\n */\ngoog.loadFileSync_ = function(src) {\n  if (goog.global.CLOSURE_LOAD_FILE_SYNC) {\n    return goog.global.CLOSURE_LOAD_FILE_SYNC(src);\n  } else {\n    try {\n      /** @type {XMLHttpRequest} */\n      var xhr = new goog.global['XMLHttpRequest']();\n      xhr.open('get', src, false);\n      xhr.send();\n      // NOTE: Successful http: requests have a status of 200, but successful\n      // file: requests may have a status of zero.  Any other status, or a\n      // thrown exception (particularly in case of file: requests) indicates\n      // some sort of error, which we treat as a missing or unavailable file.\n      return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;\n    } catch (err) {\n      // No need to rethrow or log, since errors should show up on their own.\n      return null;\n    }\n  }\n};\n\n\n/**\n * Lazily retrieves the transpiler and applies it to the source.\n * @param {string} code JS code.\n * @param {string} path Path to the code.\n * @param {string} target Language level output.\n * @return {string} The transpiled code.\n * @private\n */\ngoog.transpile_ = function(code, path, target) {\n  var jscomp = goog.global['$jscomp'];\n  if (!jscomp) {\n    goog.global['$jscomp'] = jscomp = {};\n  }\n  var transpile = jscomp.transpile;\n  if (!transpile) {\n    var transpilerPath = goog.basePath + goog.TRANSPILER;\n    var transpilerCode = goog.loadFileSync_(transpilerPath);\n    if (transpilerCode) {\n      // This must be executed synchronously, since by the time we know we\n      // need it, we're about to load and write the ES6 code synchronously,\n      // so a normal script-tag load will be too slow. Wrapped in a function\n      // so that code is eval'd in the global scope.\n      (function() {\n        (0, eval)(transpilerCode + '\\n//# sourceURL=' + transpilerPath);\n      }).call(goog.global);\n      // Even though the transpiler is optional, if $gwtExport is found, it's\n      // a sign the transpiler was loaded and the $jscomp.transpile *should*\n      // be there.\n      if (goog.global['$gwtExport'] && goog.global['$gwtExport']['$jscomp'] &&\n          !goog.global['$gwtExport']['$jscomp']['transpile']) {\n        throw new Error(\n            'The transpiler did not properly export the \"transpile\" ' +\n            'method. $gwtExport: ' + JSON.stringify(goog.global['$gwtExport']));\n      }\n      // transpile.js only exports a single $jscomp function, transpile. We\n      // grab just that and add it to the existing definition of $jscomp which\n      // contains the polyfills.\n      goog.global['$jscomp'].transpile =\n          goog.global['$gwtExport']['$jscomp']['transpile'];\n      jscomp = goog.global['$jscomp'];\n      transpile = jscomp.transpile;\n    }\n  }\n  if (!transpile) {\n    // The transpiler is an optional component.  If it's not available then\n    // replace it with a pass-through function that simply logs.\n    var suffix = ' requires transpilation but no transpiler was found.';\n    transpile = jscomp.transpile = function(code, path) {\n      // TODO(sdh): figure out some way to get this error to show up\n      // in test results, noting that the failure may occur in many\n      // different ways, including in loadModule() before the test\n      // runner even comes up.\n      goog.logToConsole_(path + suffix);\n      return code;\n    };\n  }\n  // Note: any transpilation errors/warnings will be logged to the console.\n  return transpile(code, path, target);\n};\n\n//==============================================================================\n// Language Enhancements\n//==============================================================================\n\n\n/**\n * This is a \"fixed\" version of the typeof operator.  It differs from the typeof\n * operator in such a way that null returns 'null' and arrays return 'array'.\n * @param {?} value The value to get the type of.\n * @return {string} The name of the type.\n */\ngoog.typeOf = function(value) {\n  var s = typeof value;\n\n  if (s != 'object') {\n    return s;\n  }\n\n  if (!value) {\n    return 'null';\n  }\n\n  if (Array.isArray(value)) {\n    return 'array';\n  }\n  return s;\n};\n\n\n/**\n * Returns true if the object looks like an array. To qualify as array like\n * the value needs to be either a NodeList or an object with a Number length\n * property. Note that for this function neither strings nor functions are\n * considered \"array-like\".\n *\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArrayLike = function(val) {\n  var type = goog.typeOf(val);\n  // We do not use goog.isObject here in order to exclude function values.\n  return type == 'array' || type == 'object' && typeof val.length == 'number';\n};\n\n\n/**\n * Returns true if the object looks like a Date. To qualify as Date-like the\n * value needs to be an object and have a getFullYear() function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a like a Date.\n */\ngoog.isDateLike = function(val) {\n  return goog.isObject(val) && typeof val.getFullYear == 'function';\n};\n\n\n/**\n * Returns true if the specified value is a function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a function.\n * @deprecated use \"typeof val === 'function'\" instead.\n */\ngoog.isFunction = function(val) {\n  return goog.typeOf(val) == 'function';\n};\n\n\n/**\n * Returns true if the specified value is an object.  This includes arrays and\n * functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\ngoog.isObject = function(val) {\n  var type = typeof val;\n  return type == 'object' && val != null || type == 'function';\n  // return Object(val) === val also works, but is slower, especially if val is\n  // not an object.\n};\n\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. The unique ID is\n * guaranteed to be unique across the current session amongst objects that are\n * passed into `getUid`. There is no guarantee that the ID is unique or\n * consistent across sessions. It is unsafe to generate unique ID for function\n * prototypes.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {number} The unique ID for the object.\n */\ngoog.getUid = function(obj) {\n  // TODO(arv): Make the type stricter, do not accept null.\n  return Object.prototype.hasOwnProperty.call(obj, goog.UID_PROPERTY_) &&\n      obj[goog.UID_PROPERTY_] ||\n      (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);\n};\n\n\n/**\n * Whether the given object is already assigned a unique ID.\n *\n * This does not modify the object.\n *\n * @param {!Object} obj The object to check.\n * @return {boolean} Whether there is an assigned unique id for the object.\n */\ngoog.hasUid = function(obj) {\n  return !!obj[goog.UID_PROPERTY_];\n};\n\n\n/**\n * Removes the unique ID from an object. This is useful if the object was\n * previously mutated using `goog.getUid` in which case the mutation is\n * undone.\n * @param {Object} obj The object to remove the unique ID field from.\n */\ngoog.removeUid = function(obj) {\n  // TODO(arv): Make the type stricter, do not accept null.\n\n  // In IE, DOM nodes are not instances of Object and throw an exception if we\n  // try to delete.  Instead we try to use removeAttribute.\n  if (obj !== null && 'removeAttribute' in obj) {\n    obj.removeAttribute(goog.UID_PROPERTY_);\n  }\n\n  try {\n    delete obj[goog.UID_PROPERTY_];\n  } catch (ex) {\n  }\n};\n\n\n/**\n * Name for unique ID property. Initialized in a way to help avoid collisions\n * with other closure JavaScript on the same page.\n * @type {string}\n * @private\n */\ngoog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * Counter for UID.\n * @type {number}\n * @private\n */\ngoog.uidCounter_ = 0;\n\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n *\n * WARNINGS:\n * <code>goog.cloneObject</code> does not detect reference loops. Objects that\n * refer to themselves will cause infinite recursion.\n *\n * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies\n * UIDs created by <code>getUid</code> into cloned results.\n *\n * @param {*} obj The value to clone.\n * @return {*} A clone of the input value.\n * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.\n */\ngoog.cloneObject = function(obj) {\n  var type = goog.typeOf(obj);\n  if (type == 'object' || type == 'array') {\n    if (typeof obj.clone === 'function') {\n      return obj.clone();\n    }\n    var clone = type == 'array' ? [] : {};\n    for (var key in obj) {\n      clone[key] = goog.cloneObject(obj[key]);\n    }\n    return clone;\n  }\n\n  return obj;\n};\n\n\n/**\n * A native implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindNative_ = function(fn, selfObj, var_args) {\n  return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));\n};\n\n\n/**\n * A pure-JS implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindJs_ = function(fn, selfObj, var_args) {\n  if (!fn) {\n    throw new Error();\n  }\n\n  if (arguments.length > 2) {\n    var boundArgs = Array.prototype.slice.call(arguments, 2);\n    return function() {\n      // Prepend the bound arguments to the current arguments.\n      var newArgs = Array.prototype.slice.call(arguments);\n      Array.prototype.unshift.apply(newArgs, boundArgs);\n      return fn.apply(selfObj, newArgs);\n    };\n\n  } else {\n    return function() {\n      return fn.apply(selfObj, arguments);\n    };\n  }\n};\n\n\n/**\n * Partially applies this function to a particular 'this object' and zero or\n * more arguments. The result is a new function with some arguments of the first\n * function pre-filled and the value of this 'pre-specified'.\n *\n * Remaining arguments specified at call-time are appended to the pre-specified\n * ones.\n *\n * Also see: {@link #partial}.\n *\n * Usage:\n * <pre>var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');\n * barMethBound('arg3', 'arg4');</pre>\n *\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n *     function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n *     function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n *     invoked as a method of.\n * @template T\n * @suppress {deprecated} See above.\n * @deprecated use `=> {}` or Function.prototype.bind instead.\n */\ngoog.bind = function(fn, selfObj, var_args) {\n  // TODO(nicksantos): narrow the type signature.\n  if (Function.prototype.bind &&\n      // NOTE(nicksantos): Somebody pulled base.js into the default Chrome\n      // extension environment. This means that for Chrome extensions, they get\n      // the implementation of Function.prototype.bind that calls goog.bind\n      // instead of the native one. Even worse, we don't want to introduce a\n      // circular dependency between goog.bind and Function.prototype.bind, so\n      // we have to hack this to make sure it works correctly.\n      Function.prototype.bind.toString().indexOf('native code') != -1) {\n    goog.bind = goog.bindNative_;\n  } else {\n    goog.bind = goog.bindJs_;\n  }\n  return goog.bind.apply(null, arguments);\n};\n\n\n/**\n * Like goog.bind(), except that a 'this object' is not required. Useful when\n * the target function is already bound.\n *\n * Usage:\n * var g = goog.partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function goog.partial()\n *     was invoked as a method of.\n */\ngoog.partial = function(fn, var_args) {\n  var args = Array.prototype.slice.call(arguments, 1);\n  return function() {\n    // Clone the array (with slice()) and append additional arguments\n    // to the existing arguments.\n    var newArgs = args.slice();\n    newArgs.push.apply(newArgs, arguments);\n    return fn.apply(/** @type {?} */ (this), newArgs);\n  };\n};\n\n\n/**\n * Copies all the members of a source object to a target object. This method\n * does not work on all browsers for all objects that contain keys such as\n * toString or hasOwnProperty. Use goog.object.extend for this purpose.\n *\n * NOTE: Some have advocated for the use of goog.mixin to setup classes\n * with multiple inheritence (traits, mixins, etc).  However, as it simply\n * uses \"for in\", this is not compatible with ES6 classes whose methods are\n * non-enumerable.  Changing this, would break cases where non-enumerable\n * properties are not expected.\n *\n * @param {Object} target Target.\n * @param {Object} source Source.\n * @deprecated Prefer Object.assign\n */\ngoog.mixin = function(target, source) {\n  for (var x in source) {\n    target[x] = source[x];\n  }\n\n  // For IE7 or lower, the for-in-loop does not contain any properties that are\n  // not enumerable on the prototype object (for example, isPrototypeOf from\n  // Object.prototype) but also it will not include 'replace' on objects that\n  // extend String and change 'replace' (not that it is common for anyone to\n  // extend anything except Object).\n};\n\n\n/**\n * @return {number} An integer value representing the number of milliseconds\n *     between midnight, January 1, 1970 and the current time.\n * @deprecated Use Date.now\n */\ngoog.now = Date.now;\n\n\n/**\n * Evals JavaScript in the global scope.\n *\n * Throws an exception if neither execScript or eval is defined.\n * @param {string} script JavaScript string.\n */\ngoog.globalEval = function(script) {\n  (0, eval)(script);\n};\n\n\n/**\n * Optional map of CSS class names to obfuscated names used with\n * goog.getCssName().\n * @private {!Object<string, string>|undefined}\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMapping_;\n\n\n/**\n * Optional obfuscation style for CSS class names. Should be set to either\n * 'BY_WHOLE' or 'BY_PART' if defined.\n * @type {string|undefined}\n * @private\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMappingStyle_;\n\n\n\n/**\n * A hook for modifying the default behavior goog.getCssName. The function\n * if present, will receive the standard output of the goog.getCssName as\n * its input.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAP_FN;\n\n\n/**\n * Handles strings that are intended to be used as CSS class names.\n *\n * This function works in tandem with @see goog.setCssNameMapping.\n *\n * Without any mapping set, the arguments are simple joined with a hyphen and\n * passed through unaltered.\n *\n * When there is a mapping, there are two possible styles in which these\n * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)\n * of the passed in css name is rewritten according to the map. In the BY_WHOLE\n * style, the full css name is looked up in the map directly. If a rewrite is\n * not specified by the map, the compiler will output a warning.\n *\n * When the mapping is passed to the compiler, it will replace calls to\n * goog.getCssName with the strings from the mapping, e.g.\n *     var x = goog.getCssName('foo');\n *     var y = goog.getCssName(this.baseClass, 'active');\n *  becomes:\n *     var x = 'foo';\n *     var y = this.baseClass + '-active';\n *\n * If one argument is passed it will be processed, if two are passed only the\n * modifier will be processed, as it is assumed the first argument was generated\n * as a result of calling goog.getCssName.\n *\n * @param {string} className The class name.\n * @param {string=} opt_modifier A modifier to be appended to the class name.\n * @return {string} The class name or the concatenation of the class name and\n *     the modifier.\n */\ngoog.getCssName = function(className, opt_modifier) {\n  // String() is used for compatibility with compiled soy where the passed\n  // className can be non-string objects.\n  if (String(className).charAt(0) == '.') {\n    throw new Error(\n        'className passed in goog.getCssName must not start with \".\".' +\n        ' You passed: ' + className);\n  }\n\n  var getMapping = function(cssName) {\n    return goog.cssNameMapping_[cssName] || cssName;\n  };\n\n  var renameByParts = function(cssName) {\n    // Remap all the parts individually.\n    var parts = cssName.split('-');\n    var mapped = [];\n    for (var i = 0; i < parts.length; i++) {\n      mapped.push(getMapping(parts[i]));\n    }\n    return mapped.join('-');\n  };\n\n  var rename;\n  if (goog.cssNameMapping_) {\n    rename =\n        goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts;\n  } else {\n    rename = function(a) {\n      return a;\n    };\n  }\n\n  var result =\n      opt_modifier ? className + '-' + rename(opt_modifier) : rename(className);\n\n  // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further\n  // processing of the class name.\n  if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {\n    return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);\n  }\n\n  return result;\n};\n\n\n/**\n * Sets the map to check when returning a value from goog.getCssName(). Example:\n * <pre>\n * goog.setCssNameMapping({\n *   \"goog\": \"a\",\n *   \"disabled\": \"b\",\n * });\n *\n * var x = goog.getCssName('goog');\n * // The following evaluates to: \"a a-b\".\n * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')\n * </pre>\n * When declared as a map of string literals to string literals, the JSCompiler\n * will replace all calls to goog.getCssName() using the supplied map if the\n * --process_closure_primitives flag is set.\n *\n * @param {!Object} mapping A map of strings to strings where keys are possible\n *     arguments to goog.getCssName() and values are the corresponding values\n *     that should be returned.\n * @param {string=} opt_style The style of css name mapping. There are two valid\n *     options: 'BY_PART', and 'BY_WHOLE'.\n * @see goog.getCssName for a description.\n */\ngoog.setCssNameMapping = function(mapping, opt_style) {\n  goog.cssNameMapping_ = mapping;\n  goog.cssNameMappingStyle_ = opt_style;\n};\n\n\n/**\n * To use CSS renaming in compiled mode, one of the input files should have a\n * call to goog.setCssNameMapping() with an object literal that the JSCompiler\n * can extract and use to replace all calls to goog.getCssName(). In uncompiled\n * mode, JavaScript code should be loaded before this base.js file that declares\n * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is\n * to ensure that the mapping is loaded before any calls to goog.getCssName()\n * are made in uncompiled mode.\n *\n * A hook for overriding the CSS name mapping.\n * @type {!Object<string, string>|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAPPING;\n\n\nif (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {\n  // This does not call goog.setCssNameMapping() because the JSCompiler\n  // requires that goog.setCssNameMapping() be called with an object literal.\n  goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;\n}\n\n\n/**\n * Gets a localized message.\n *\n * This function is a compiler primitive. If you give the compiler a localized\n * message bundle, it will replace the string at compile-time with a localized\n * version, and expand goog.getMsg call to a concatenated string.\n *\n * Messages must be initialized in the form:\n * <code>\n * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});\n * </code>\n *\n * This function produces a string which should be treated as plain text. Use\n * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to\n * produce SafeHtml.\n *\n * @param {string} str Translatable string, places holders in the form {$foo}.\n * @param {Object<string, string>=} opt_values Maps place holder name to value.\n * @param {{html: boolean}=} opt_options Options:\n *     html: Escape '<' in str to '&lt;'. Used by Closure Templates where the\n *     generated code size and performance is critical which is why {@link\n *     goog.html.SafeHtmlFormatter} is not used. The value must be literal true\n *     or false.\n * @return {string} message with placeholders filled.\n */\ngoog.getMsg = function(str, opt_values, opt_options) {\n  if (opt_options && opt_options.html) {\n    // Note that '&' is not replaced because the translation can contain HTML\n    // entities.\n    str = str.replace(/</g, '&lt;');\n  }\n  if (opt_values) {\n    str = str.replace(/\\{\\$([^}]+)}/g, function(match, key) {\n      return (opt_values != null && key in opt_values) ? opt_values[key] :\n                                                         match;\n    });\n  }\n  return str;\n};\n\n\n/**\n * Gets a localized message. If the message does not have a translation, gives a\n * fallback message.\n *\n * This is useful when introducing a new message that has not yet been\n * translated into all languages.\n *\n * This function is a compiler primitive. Must be used in the form:\n * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>\n * where MSG_A and MSG_B were initialized with goog.getMsg.\n *\n * @param {string} a The preferred message.\n * @param {string} b The fallback message.\n * @return {string} The best translated message.\n */\ngoog.getMsgWithFallback = function(a, b) {\n  return a;\n};\n\n\n/**\n * Exposes an unobfuscated global namespace path for the given object.\n * Note that fields of the exported object *will* be obfuscated, unless they are\n * exported in turn via this function or goog.exportProperty.\n *\n * Also handy for making public items that are defined in anonymous closures.\n *\n * ex. goog.exportSymbol('public.path.Foo', Foo);\n *\n * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);\n *     public.path.Foo.staticFunction();\n *\n * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',\n *                       Foo.prototype.myMethod);\n *     new public.path.Foo().myMethod();\n *\n * @param {string} publicPath Unobfuscated name to export.\n * @param {*} object Object the name should point to.\n * @param {?Object=} objectToExportTo The object to add the path to; default\n *     is goog.global.\n */\ngoog.exportSymbol = function(publicPath, object, objectToExportTo) {\n  goog.exportPath_(\n      publicPath, object, /* overwriteImplicit= */ true, objectToExportTo);\n};\n\n\n/**\n * Exports a property unobfuscated into the object's namespace.\n * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);\n * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);\n * @param {Object} object Object whose static property is being exported.\n * @param {string} publicName Unobfuscated name to export.\n * @param {*} symbol Object the name should point to.\n */\ngoog.exportProperty = function(object, publicName, symbol) {\n  object[publicName] = symbol;\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * Usage:\n * <pre>\n * function ParentClass(a, b) { }\n * ParentClass.prototype.foo = function(a) { };\n *\n * function ChildClass(a, b, c) {\n *   ChildClass.base(this, 'constructor', a, b);\n * }\n * goog.inherits(ChildClass, ParentClass);\n *\n * var child = new ChildClass('a', 'b', 'see');\n * child.foo(); // This works.\n * </pre>\n *\n * @param {!Function} childCtor Child class.\n * @param {!Function} parentCtor Parent class.\n * @suppress {strictMissingProperties} superClass_ and base is not defined on\n *    Function.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.inherits = function(childCtor, parentCtor) {\n  /** @constructor */\n  function tempCtor() {}\n  tempCtor.prototype = parentCtor.prototype;\n  childCtor.superClass_ = parentCtor.prototype;\n  childCtor.prototype = new tempCtor();\n  /** @override */\n  childCtor.prototype.constructor = childCtor;\n\n  /**\n   * Calls superclass constructor/method.\n   *\n   * This function is only available if you use goog.inherits to\n   * express inheritance relationships between classes.\n   *\n   * NOTE: This is a replacement for goog.base and for superClass_\n   * property defined in childCtor.\n   *\n   * @param {!Object} me Should always be \"this\".\n   * @param {string} methodName The method name to call. Calling\n   *     superclass constructor can be done with the special string\n   *     'constructor'.\n   * @param {...*} var_args The arguments to pass to superclass\n   *     method/constructor.\n   * @return {*} The return value of the superclass method/constructor.\n   */\n  childCtor.base = function(me, methodName, var_args) {\n    // Copying using loop to avoid deop due to passing arguments object to\n    // function. This is faster in many JS engines as of late 2014.\n    var args = new Array(arguments.length - 2);\n    for (var i = 2; i < arguments.length; i++) {\n      args[i - 2] = arguments[i];\n    }\n    return parentCtor.prototype[methodName].apply(me, args);\n  };\n};\n\n\n/**\n * Allow for aliasing within scope functions.  This function exists for\n * uncompiled code - in compiled code the calls will be inlined and the aliases\n * applied.  In uncompiled code the function is simply run since the aliases as\n * written are valid JavaScript.\n *\n *\n * @param {function()} fn Function to call.  This function can contain aliases\n *     to namespaces (e.g. \"var dom = goog.dom\") or classes\n *     (e.g. \"var Timer = goog.Timer\").\n * @deprecated Use goog.module instead.\n */\ngoog.scope = function(fn) {\n  if (goog.isInModuleLoader_()) {\n    throw new Error('goog.scope is not supported within a module.');\n  }\n  fn.call(goog.global);\n};\n\n\n/*\n * To support uncompiled, strict mode bundles that use eval to divide source\n * like so:\n *    eval('someSource;//# sourceUrl sourcefile.js');\n * We need to export the globally defined symbols \"goog\" and \"COMPILED\".\n * Exporting \"goog\" breaks the compiler optimizations, so we required that\n * be defined externally.\n * NOTE: We don't use goog.exportSymbol here because we don't want to trigger\n * extern generation when that compiler option is enabled.\n */\nif (!COMPILED) {\n  goog.global['COMPILED'] = COMPILED;\n}\n\n\n//==============================================================================\n// goog.defineClass implementation\n//==============================================================================\n\n\n/**\n * Creates a restricted form of a Closure \"class\":\n *   - from the compiler's perspective, the instance returned from the\n *     constructor is sealed (no new properties may be added).  This enables\n *     better checks.\n *   - the compiler will rewrite this definition to a form that is optimal\n *     for type checking and optimization (initially this will be a more\n *     traditional form).\n *\n * @param {Function} superClass The superclass, Object or null.\n * @param {goog.defineClass.ClassDescriptor} def\n *     An object literal describing\n *     the class.  It may have the following properties:\n *     \"constructor\": the constructor function\n *     \"statics\": an object literal containing methods to add to the constructor\n *        as \"static\" methods or a function that will receive the constructor\n *        function as its only parameter to which static properties can\n *        be added.\n *     all other properties are added to the prototype.\n * @return {!Function} The class constructor.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.defineClass = function(superClass, def) {\n  // TODO(johnlenz): consider making the superClass an optional parameter.\n  var constructor = def.constructor;\n  var statics = def.statics;\n  // Wrap the constructor prior to setting up the prototype and static methods.\n  if (!constructor || constructor == Object.prototype.constructor) {\n    constructor = function() {\n      throw new Error(\n          'cannot instantiate an interface (no constructor defined).');\n    };\n  }\n\n  var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);\n  if (superClass) {\n    goog.inherits(cls, superClass);\n  }\n\n  // Remove all the properties that should not be copied to the prototype.\n  delete def.constructor;\n  delete def.statics;\n\n  goog.defineClass.applyProperties_(cls.prototype, def);\n  if (statics != null) {\n    if (statics instanceof Function) {\n      statics(cls);\n    } else {\n      goog.defineClass.applyProperties_(cls, statics);\n    }\n  }\n\n  return cls;\n};\n\n\n/**\n * @typedef {{\n *   constructor: (!Function|undefined),\n *   statics: (Object|undefined|function(Function):void)\n * }}\n */\ngoog.defineClass.ClassDescriptor;\n\n\n/**\n * @define {boolean} Whether the instances returned by goog.defineClass should\n *     be sealed when possible.\n *\n * When sealing is disabled the constructor function will not be wrapped by\n * goog.defineClass, making it incompatible with ES6 class methods.\n */\ngoog.defineClass.SEAL_CLASS_INSTANCES =\n    goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);\n\n\n/**\n * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is\n * defined, this function will wrap the constructor in a function that seals the\n * results of the provided constructor function.\n *\n * @param {!Function} ctr The constructor whose results maybe be sealed.\n * @param {Function} superClass The superclass constructor.\n * @return {!Function} The replacement constructor.\n * @private\n */\ngoog.defineClass.createSealingConstructor_ = function(ctr, superClass) {\n  if (!goog.defineClass.SEAL_CLASS_INSTANCES) {\n    // Do now wrap the constructor when sealing is disabled. Angular code\n    // depends on this for injection to work properly.\n    return ctr;\n  }\n\n  // NOTE: The sealing behavior has been removed\n\n  /**\n   * @this {Object}\n   * @return {?}\n   */\n  var wrappedCtr = function() {\n    // Don't seal an instance of a subclass when it calls the constructor of\n    // its super class as there is most likely still setup to do.\n    var instance = ctr.apply(this, arguments) || this;\n    instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];\n\n    return instance;\n  };\n\n  return wrappedCtr;\n};\n\n\n\n// TODO(johnlenz): share these values with the goog.object\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {!Array<string>}\n * @private\n * @const\n */\ngoog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [\n  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n  'toLocaleString', 'toString', 'valueOf'\n];\n\n\n// TODO(johnlenz): share this function with the goog.object\n/**\n * @param {!Object} target The object to add properties to.\n * @param {!Object} source The object to copy properties from.\n * @private\n */\ngoog.defineClass.applyProperties_ = function(target, source) {\n  // TODO(johnlenz): update this to support ES5 getters/setters\n\n  var key;\n  for (key in source) {\n    if (Object.prototype.hasOwnProperty.call(source, key)) {\n      target[key] = source[key];\n    }\n  }\n\n  // For IE the for-in-loop does not contain any properties that are not\n  // enumerable on the prototype object (for example isPrototypeOf from\n  // Object.prototype) and it will also not include 'replace' on objects that\n  // extend String and change 'replace' (not that it is common for anyone to\n  // extend anything except Object).\n  for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {\n    key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];\n    if (Object.prototype.hasOwnProperty.call(source, key)) {\n      target[key] = source[key];\n    }\n  }\n};\n\n\n// There's a bug in the compiler where without collapse properties the\n// Closure namespace defines do not guard code correctly. To help reduce code\n// size also check for !COMPILED even though it redundant until this is fixed.\nif (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n\n  /**\n   * Tries to detect whether is in the context of an HTML document.\n   * @return {boolean} True if it looks like HTML document.\n   * @private\n   */\n  goog.inHtmlDocument_ = function() {\n    /** @type {!Document} */\n    var doc = goog.global.document;\n    return doc != null && 'write' in doc;  // XULDocument misses write.\n  };\n\n\n  /**\n   * We'd like to check for if the document readyState is 'loading'; however\n   * there are bugs on IE 10 and below where the readyState being anything other\n   * than 'complete' is not reliable.\n   * @return {boolean}\n   * @private\n   */\n  goog.isDocumentLoading_ = function() {\n    // attachEvent is available on IE 6 thru 10 only, and thus can be used to\n    // detect those browsers.\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n    return doc.attachEvent ? doc.readyState != 'complete' :\n                             doc.readyState == 'loading';\n  };\n\n\n  /**\n   * Tries to detect the base path of base.js script that bootstraps Closure.\n   * @private\n   */\n  goog.findBasePath_ = function() {\n    if (goog.global.CLOSURE_BASE_PATH != undefined &&\n        // Anti DOM-clobbering runtime check (b/37736576).\n        typeof goog.global.CLOSURE_BASE_PATH === 'string') {\n      goog.basePath = goog.global.CLOSURE_BASE_PATH;\n      return;\n    } else if (!goog.inHtmlDocument_()) {\n      return;\n    }\n    /** @type {!Document} */\n    var doc = goog.global.document;\n    // If we have a currentScript available, use it exclusively.\n    var currentScript = doc.currentScript;\n    if (currentScript) {\n      var scripts = [currentScript];\n    } else {\n      var scripts = doc.getElementsByTagName('SCRIPT');\n    }\n    // Search backwards since the current script is in almost all cases the one\n    // that has base.js.\n    for (var i = scripts.length - 1; i >= 0; --i) {\n      var script = /** @type {!HTMLScriptElement} */ (scripts[i]);\n      var src = script.src;\n      var qmark = src.lastIndexOf('?');\n      var l = qmark == -1 ? src.length : qmark;\n      if (src.substr(l - 7, 7) == 'base.js') {\n        goog.basePath = src.substr(0, l - 7);\n        return;\n      }\n    }\n  };\n\n  goog.findBasePath_();\n\n  /** @struct @constructor @final */\n  goog.Transpiler = function() {\n    /** @private {?Object<string, boolean>} */\n    this.requiresTranspilation_ = null;\n    /** @private {string} */\n    this.transpilationTarget_ = goog.TRANSPILE_TO_LANGUAGE;\n  };\n  /**\n   * Returns a newly created map from language mode string to a boolean\n   * indicating whether transpilation should be done for that mode as well as\n   * the highest level language that this environment supports.\n   *\n   * Guaranteed invariant:\n   * For any two modes, l1 and l2 where l2 is a newer mode than l1,\n   * `map[l1] == true` implies that `map[l2] == true`.\n   *\n   * Note this method is extracted and used elsewhere, so it cannot rely on\n   * anything external (it should easily be able to be transformed into a\n   * standalone, top level function).\n   *\n   * @private\n   * @return {{\n   *   target: string,\n   *   map: !Object<string, boolean>\n   * }}\n   */\n  goog.Transpiler.prototype.createRequiresTranspilation_ = function() {\n    var transpilationTarget = 'es3';\n    var /** !Object<string, boolean> */ requiresTranspilation = {'es3': false};\n    var transpilationRequiredForAllLaterModes = false;\n\n    /**\n     * Adds an entry to requiresTranspliation for the given language mode.\n     *\n     * IMPORTANT: Calls must be made in order from oldest to newest language\n     * mode.\n     * @param {string} modeName\n     * @param {function(): boolean} isSupported Returns true if the JS engine\n     *     supports the given mode.\n     */\n    function addNewerLanguageTranspilationCheck(modeName, isSupported) {\n      if (transpilationRequiredForAllLaterModes) {\n        requiresTranspilation[modeName] = true;\n      } else if (isSupported()) {\n        transpilationTarget = modeName;\n        requiresTranspilation[modeName] = false;\n      } else {\n        requiresTranspilation[modeName] = true;\n        transpilationRequiredForAllLaterModes = true;\n      }\n    }\n\n    /**\n     * Does the given code evaluate without syntax errors and return a truthy\n     * result?\n     */\n    function /** boolean */ evalCheck(/** string */ code) {\n      try {\n        return !!eval(code);\n      } catch (ignored) {\n        return false;\n      }\n    }\n\n    var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?\n        goog.global.navigator.userAgent :\n        '';\n\n    // Identify ES3-only browsers by their incorrect treatment of commas.\n    addNewerLanguageTranspilationCheck('es5', function() {\n      return evalCheck('[1,].length==1');\n    });\n    addNewerLanguageTranspilationCheck('es6', function() {\n      // Edge has a non-deterministic (i.e., not reproducible) bug with ES6:\n      // https://github.com/Microsoft/ChakraCore/issues/1496.\n      var re = /Edge\\/(\\d+)(\\.\\d)*/i;\n      var edgeUserAgent = userAgent.match(re);\n      if (edgeUserAgent) {\n        // The Reflect.construct test below is flaky on Edge. It can sometimes\n        // pass or fail on 40 15.15063, so just exit early for Edge and treat\n        // it as ES5. Until we're on a more up to date version just always use\n        // ES5. See https://github.com/Microsoft/ChakraCore/issues/3217.\n        return false;\n      }\n      // Test es6: [FF50 (?), Edge 14 (?), Chrome 50]\n      //   (a) default params (specifically shadowing locals),\n      //   (b) destructuring, (c) block-scoped functions,\n      //   (d) for-of (const), (e) new.target/Reflect.construct\n      var es6fullTest =\n          'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' +\n          'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' +\n          'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' +\n          'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' +\n          '==3}';\n\n      return evalCheck('(()=>{\"use strict\";' + es6fullTest + '})()');\n    });\n    // ** and **= are the only new features in 'es7'\n    addNewerLanguageTranspilationCheck('es7', function() {\n      return evalCheck('2 ** 2 == 4');\n    });\n    // async functions are the only new features in 'es8'\n    addNewerLanguageTranspilationCheck('es8', function() {\n      return evalCheck('async () => 1, true');\n    });\n    addNewerLanguageTranspilationCheck('es9', function() {\n      return evalCheck('({...rest} = {}), true');\n    });\n    addNewerLanguageTranspilationCheck('es_next', function() {\n      return false;  // assume it always need to transpile\n    });\n    return {target: transpilationTarget, map: requiresTranspilation};\n  };\n\n\n  /**\n   * Determines whether the given language needs to be transpiled.\n   * @param {string} lang\n   * @param {string|undefined} module\n   * @return {boolean}\n   */\n  goog.Transpiler.prototype.needsTranspile = function(lang, module) {\n    if (goog.TRANSPILE == 'always') {\n      return true;\n    } else if (goog.TRANSPILE == 'never') {\n      return false;\n    } else if (!this.requiresTranspilation_) {\n      var obj = this.createRequiresTranspilation_();\n      this.requiresTranspilation_ = obj.map;\n      this.transpilationTarget_ = this.transpilationTarget_ || obj.target;\n    }\n    if (lang in this.requiresTranspilation_) {\n      if (this.requiresTranspilation_[lang]) {\n        return true;\n      } else if (\n          goog.inHtmlDocument_() && module == 'es6' &&\n          !('noModule' in goog.global.document.createElement('script'))) {\n        return true;\n      } else {\n        return false;\n      }\n    } else {\n      throw new Error('Unknown language mode: ' + lang);\n    }\n  };\n\n\n  /**\n   * Lazily retrieves the transpiler and applies it to the source.\n   * @param {string} code JS code.\n   * @param {string} path Path to the code.\n   * @return {string} The transpiled code.\n   */\n  goog.Transpiler.prototype.transpile = function(code, path) {\n    // TODO(johnplaisted): We should delete goog.transpile_ and just have this\n    // function. But there's some compile error atm where goog.global is being\n    // stripped incorrectly without this.\n    return goog.transpile_(code, path, this.transpilationTarget_);\n  };\n\n\n  /** @private @final {!goog.Transpiler} */\n  goog.transpiler_ = new goog.Transpiler();\n\n  /**\n   * Rewrites closing script tags in input to avoid ending an enclosing script\n   * tag.\n   *\n   * @param {string} str\n   * @return {string}\n   * @private\n   */\n  goog.protectScriptTag_ = function(str) {\n    return str.replace(/<\\/(SCRIPT)/ig, '\\\\x3c/$1');\n  };\n\n\n  /**\n   * A debug loader is responsible for downloading and executing javascript\n   * files in an unbundled, uncompiled environment.\n   *\n   * This can be custimized via the setDependencyFactory method, or by\n   * CLOSURE_IMPORT_SCRIPT/CLOSURE_LOAD_FILE_SYNC.\n   *\n   * @struct @constructor @final @private\n   */\n  goog.DebugLoader_ = function() {\n    /** @private @const {!Object<string, !goog.Dependency>} */\n    this.dependencies_ = {};\n    /** @private @const {!Object<string, string>} */\n    this.idToPath_ = {};\n    /** @private @const {!Object<string, boolean>} */\n    this.written_ = {};\n    /** @private @const {!Array<!goog.Dependency>} */\n    this.loadingDeps_ = [];\n    /** @private {!Array<!goog.Dependency>} */\n    this.depsToLoad_ = [];\n    /** @private {boolean} */\n    this.paused_ = false;\n    /** @private {!goog.DependencyFactory} */\n    this.factory_ = new goog.DependencyFactory(goog.transpiler_);\n    /** @private @const {!Object<string, !Function>} */\n    this.deferredCallbacks_ = {};\n    /** @private @const {!Array<string>} */\n    this.deferredQueue_ = [];\n  };\n\n  /**\n   * @param {!Array<string>} namespaces\n   * @param {function(): undefined} callback Function to call once all the\n   *     namespaces have loaded.\n   */\n  goog.DebugLoader_.prototype.bootstrap = function(namespaces, callback) {\n    var cb = callback;\n    function resolve() {\n      if (cb) {\n        goog.global.setTimeout(cb, 0);\n        cb = null;\n      }\n    }\n\n    if (!namespaces.length) {\n      resolve();\n      return;\n    }\n\n    var deps = [];\n    for (var i = 0; i < namespaces.length; i++) {\n      var path = this.getPathFromDeps_(namespaces[i]);\n      if (!path) {\n        throw new Error('Unregonized namespace: ' + namespaces[i]);\n      }\n      deps.push(this.dependencies_[path]);\n    }\n\n    var require = goog.require;\n    var loaded = 0;\n    for (var i = 0; i < namespaces.length; i++) {\n      require(namespaces[i]);\n      deps[i].onLoad(function() {\n        if (++loaded == namespaces.length) {\n          resolve();\n        }\n      });\n    }\n  };\n\n\n  /**\n   * Loads the Closure Dependency file.\n   *\n   * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n   * loaded, setDependencyFactory called, and then this called. i.e. allows\n   * custom loading of the deps file.\n   */\n  goog.DebugLoader_.prototype.loadClosureDeps = function() {\n    // Circumvent addDependency, which would try to transpile deps.js if\n    // transpile is set to always.\n    var relPath = 'deps.js';\n    this.depsToLoad_.push(this.factory_.createDependency(\n        goog.normalizePath_(goog.basePath + relPath), relPath, [], [], {},\n        false));\n    this.loadDeps_();\n  };\n\n\n  /**\n   * Notifies the debug loader when a dependency has been requested.\n   *\n   * @param {string} absPathOrId Path of the dependency or goog id.\n   * @param {boolean=} opt_force\n   */\n  goog.DebugLoader_.prototype.requested = function(absPathOrId, opt_force) {\n    var path = this.getPathFromDeps_(absPathOrId);\n    if (path &&\n        (opt_force || this.areDepsLoaded_(this.dependencies_[path].requires))) {\n      var callback = this.deferredCallbacks_[path];\n      if (callback) {\n        delete this.deferredCallbacks_[path];\n        callback();\n      }\n    }\n  };\n\n\n  /**\n   * Sets the dependency factory, which can be used to create custom\n   * goog.Dependency implementations to control how dependencies are loaded.\n   *\n   * @param {!goog.DependencyFactory} factory\n   */\n  goog.DebugLoader_.prototype.setDependencyFactory = function(factory) {\n    this.factory_ = factory;\n  };\n\n\n  /**\n   * Travserses the dependency graph and queues the given dependency, and all of\n   * its transitive dependencies, for loading and then starts loading if not\n   * paused.\n   *\n   * @param {string} namespace\n   * @private\n   */\n  goog.DebugLoader_.prototype.load_ = function(namespace) {\n    if (!this.getPathFromDeps_(namespace)) {\n      var errorMessage = 'goog.require could not find: ' + namespace;\n\n      goog.logToConsole_(errorMessage);\n      throw Error(errorMessage);\n    } else {\n      var loader = this;\n\n      var deps = [];\n\n      /** @param {string} namespace */\n      var visit = function(namespace) {\n        var path = loader.getPathFromDeps_(namespace);\n\n        if (!path) {\n          throw new Error('Bad dependency path or symbol: ' + namespace);\n        }\n\n        if (loader.written_[path]) {\n          return;\n        }\n\n        loader.written_[path] = true;\n\n        var dep = loader.dependencies_[path];\n        for (var i = 0; i < dep.requires.length; i++) {\n          if (!goog.isProvided_(dep.requires[i])) {\n            visit(dep.requires[i]);\n          }\n        }\n\n        deps.push(dep);\n      };\n\n      visit(namespace);\n\n      var wasLoading = !!this.depsToLoad_.length;\n      this.depsToLoad_ = this.depsToLoad_.concat(deps);\n\n      if (!this.paused_ && !wasLoading) {\n        this.loadDeps_();\n      }\n    }\n  };\n\n\n  /**\n   * Loads any queued dependencies until they are all loaded or paused.\n   *\n   * @private\n   */\n  goog.DebugLoader_.prototype.loadDeps_ = function() {\n    var loader = this;\n    var paused = this.paused_;\n\n    while (this.depsToLoad_.length && !paused) {\n      (function() {\n        var loadCallDone = false;\n        var dep = loader.depsToLoad_.shift();\n\n        var loaded = false;\n        loader.loading_(dep);\n\n        var controller = {\n          pause: function() {\n            if (loadCallDone) {\n              throw new Error('Cannot call pause after the call to load.');\n            } else {\n              paused = true;\n            }\n          },\n          resume: function() {\n            if (loadCallDone) {\n              loader.resume_();\n            } else {\n              // Some dep called pause and then resume in the same load call.\n              // Just keep running this same loop.\n              paused = false;\n            }\n          },\n          loaded: function() {\n            if (loaded) {\n              throw new Error('Double call to loaded.');\n            }\n\n            loaded = true;\n            loader.loaded_(dep);\n          },\n          pending: function() {\n            // Defensive copy.\n            var pending = [];\n            for (var i = 0; i < loader.loadingDeps_.length; i++) {\n              pending.push(loader.loadingDeps_[i]);\n            }\n            return pending;\n          },\n          /**\n           * @param {goog.ModuleType} type\n           */\n          setModuleState: function(type) {\n            goog.moduleLoaderState_ = {\n              type: type,\n              moduleName: '',\n              declareLegacyNamespace: false\n            };\n          },\n          /** @type {function(string, string, string=)} */\n          registerEs6ModuleExports: function(\n              path, exports, opt_closureNamespace) {\n            if (opt_closureNamespace) {\n              goog.loadedModules_[opt_closureNamespace] = {\n                exports: exports,\n                type: goog.ModuleType.ES6,\n                moduleId: opt_closureNamespace || ''\n              };\n            }\n          },\n          /** @type {function(string, ?)} */\n          registerGoogModuleExports: function(moduleId, exports) {\n            goog.loadedModules_[moduleId] = {\n              exports: exports,\n              type: goog.ModuleType.GOOG,\n              moduleId: moduleId\n            };\n          },\n          clearModuleState: function() {\n            goog.moduleLoaderState_ = null;\n          },\n          defer: function(callback) {\n            if (loadCallDone) {\n              throw new Error(\n                  'Cannot register with defer after the call to load.');\n            }\n            loader.defer_(dep, callback);\n          },\n          areDepsLoaded: function() {\n            return loader.areDepsLoaded_(dep.requires);\n          }\n        };\n\n        try {\n          dep.load(controller);\n        } finally {\n          loadCallDone = true;\n        }\n      })();\n    }\n\n    if (paused) {\n      this.pause_();\n    }\n  };\n\n\n  /** @private */\n  goog.DebugLoader_.prototype.pause_ = function() {\n    this.paused_ = true;\n  };\n\n\n  /** @private */\n  goog.DebugLoader_.prototype.resume_ = function() {\n    if (this.paused_) {\n      this.paused_ = false;\n      this.loadDeps_();\n    }\n  };\n\n\n  /**\n   * Marks the given dependency as loading (load has been called but it has not\n   * yet marked itself as finished). Useful for dependencies that want to know\n   * what else is loading. Example: goog.modules cannot eval if there are\n   * loading dependencies.\n   *\n   * @param {!goog.Dependency} dep\n   * @private\n   */\n  goog.DebugLoader_.prototype.loading_ = function(dep) {\n    this.loadingDeps_.push(dep);\n  };\n\n\n  /**\n   * Marks the given dependency as having finished loading and being available\n   * for require.\n   *\n   * @param {!goog.Dependency} dep\n   * @private\n   */\n  goog.DebugLoader_.prototype.loaded_ = function(dep) {\n    for (var i = 0; i < this.loadingDeps_.length; i++) {\n      if (this.loadingDeps_[i] == dep) {\n        this.loadingDeps_.splice(i, 1);\n        break;\n      }\n    }\n\n    for (var i = 0; i < this.deferredQueue_.length; i++) {\n      if (this.deferredQueue_[i] == dep.path) {\n        this.deferredQueue_.splice(i, 1);\n        break;\n      }\n    }\n\n    if (this.loadingDeps_.length == this.deferredQueue_.length &&\n        !this.depsToLoad_.length) {\n      // Something has asked to load these, but they may not be directly\n      // required again later, so load them now that we know we're done loading\n      // everything else. e.g. a goog module entry point.\n      while (this.deferredQueue_.length) {\n        this.requested(this.deferredQueue_.shift(), true);\n      }\n    }\n\n    dep.loaded();\n  };\n\n\n  /**\n   * @param {!Array<string>} pathsOrIds\n   * @return {boolean}\n   * @private\n   */\n  goog.DebugLoader_.prototype.areDepsLoaded_ = function(pathsOrIds) {\n    for (var i = 0; i < pathsOrIds.length; i++) {\n      var path = this.getPathFromDeps_(pathsOrIds[i]);\n      if (!path ||\n          (!(path in this.deferredCallbacks_) &&\n           !goog.isProvided_(pathsOrIds[i]))) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n\n  /**\n   * @param {string} absPathOrId\n   * @return {?string}\n   * @private\n   */\n  goog.DebugLoader_.prototype.getPathFromDeps_ = function(absPathOrId) {\n    if (absPathOrId in this.idToPath_) {\n      return this.idToPath_[absPathOrId];\n    } else if (absPathOrId in this.dependencies_) {\n      return absPathOrId;\n    } else {\n      return null;\n    }\n  };\n\n\n  /**\n   * @param {!goog.Dependency} dependency\n   * @param {!Function} callback\n   * @private\n   */\n  goog.DebugLoader_.prototype.defer_ = function(dependency, callback) {\n    this.deferredCallbacks_[dependency.path] = callback;\n    this.deferredQueue_.push(dependency.path);\n  };\n\n\n  /**\n   * Interface for goog.Dependency implementations to have some control over\n   * loading of dependencies.\n   *\n   * @record\n   */\n  goog.LoadController = function() {};\n\n\n  /**\n   * Tells the controller to halt loading of more dependencies.\n   */\n  goog.LoadController.prototype.pause = function() {};\n\n\n  /**\n   * Tells the controller to resume loading of more dependencies if paused.\n   */\n  goog.LoadController.prototype.resume = function() {};\n\n\n  /**\n   * Tells the controller that this dependency has finished loading.\n   *\n   * This causes this to be removed from pending() and any load callbacks to\n   * fire.\n   */\n  goog.LoadController.prototype.loaded = function() {};\n\n\n  /**\n   * List of dependencies on which load has been called but which have not\n   * called loaded on their controller. This includes the current dependency.\n   *\n   * @return {!Array<!goog.Dependency>}\n   */\n  goog.LoadController.prototype.pending = function() {};\n\n\n  /**\n   * Registers an object as an ES6 module's exports so that goog.modules may\n   * require it by path.\n   *\n   * @param {string} path Full path of the module.\n   * @param {?} exports\n   * @param {string=} opt_closureNamespace Closure namespace to associate with\n   *     this module.\n   */\n  goog.LoadController.prototype.registerEs6ModuleExports = function(\n      path, exports, opt_closureNamespace) {};\n\n\n  /**\n   * Sets the current module state.\n   *\n   * @param {goog.ModuleType} type Type of module.\n   */\n  goog.LoadController.prototype.setModuleState = function(type) {};\n\n\n  /**\n   * Clears the current module state.\n   */\n  goog.LoadController.prototype.clearModuleState = function() {};\n\n\n  /**\n   * Registers a callback to call once the dependency is actually requested\n   * via goog.require + all of the immediate dependencies have been loaded or\n   * all other files have been loaded. Allows for lazy loading until\n   * require'd without pausing dependency loading, which is needed on old IE.\n   *\n   * @param {!Function} callback\n   */\n  goog.LoadController.prototype.defer = function(callback) {};\n\n\n  /**\n   * @return {boolean}\n   */\n  goog.LoadController.prototype.areDepsLoaded = function() {};\n\n\n  /**\n   * Basic super class for all dependencies Closure Library can load.\n   *\n   * This default implementation is designed to load untranspiled, non-module\n   * scripts in a web broswer.\n   *\n   * For transpiled non-goog.module files {@see goog.TranspiledDependency}.\n   * For goog.modules see {@see goog.GoogModuleDependency}.\n   * For untranspiled ES6 modules {@see goog.Es6ModuleDependency}.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   */\n  goog.Dependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    /** @const */\n    this.path = path;\n    /** @const */\n    this.relativePath = relativePath;\n    /** @const */\n    this.provides = provides;\n    /** @const */\n    this.requires = requires;\n    /** @const */\n    this.loadFlags = loadFlags;\n    /** @private {boolean} */\n    this.loaded_ = false;\n    /** @private {!Array<function()>} */\n    this.loadCallbacks_ = [];\n  };\n\n\n  /**\n   * @return {string} The pathname part of this dependency's path if it is a\n   *     URI.\n   */\n  goog.Dependency.prototype.getPathName = function() {\n    var pathName = this.path;\n    var protocolIndex = pathName.indexOf('://');\n    if (protocolIndex >= 0) {\n      pathName = pathName.substring(protocolIndex + 3);\n      var slashIndex = pathName.indexOf('/');\n      if (slashIndex >= 0) {\n        pathName = pathName.substring(slashIndex + 1);\n      }\n    }\n    return pathName;\n  };\n\n\n  /**\n   * @param {function()} callback Callback to fire as soon as this has loaded.\n   * @final\n   */\n  goog.Dependency.prototype.onLoad = function(callback) {\n    if (this.loaded_) {\n      callback();\n    } else {\n      this.loadCallbacks_.push(callback);\n    }\n  };\n\n\n  /**\n   * Marks this dependency as loaded and fires any callbacks registered with\n   * onLoad.\n   * @final\n   */\n  goog.Dependency.prototype.loaded = function() {\n    this.loaded_ = true;\n    var callbacks = this.loadCallbacks_;\n    this.loadCallbacks_ = [];\n    for (var i = 0; i < callbacks.length; i++) {\n      callbacks[i]();\n    }\n  };\n\n\n  /**\n   * Whether or not document.written / appended script tags should be deferred.\n   *\n   * @private {boolean}\n   */\n  goog.Dependency.defer_ = false;\n\n\n  /**\n   * Map of script ready / state change callbacks. Old IE cannot handle putting\n   * these properties on goog.global.\n   *\n   * @private @const {!Object<string, function(?):undefined>}\n   */\n  goog.Dependency.callbackMap_ = {};\n\n\n  /**\n   * @param {function(...?):?} callback\n   * @return {string}\n   * @private\n   */\n  goog.Dependency.registerCallback_ = function(callback) {\n    var key = Math.random().toString(32);\n    goog.Dependency.callbackMap_[key] = callback;\n    return key;\n  };\n\n\n  /**\n   * @param {string} key\n   * @private\n   */\n  goog.Dependency.unregisterCallback_ = function(key) {\n    delete goog.Dependency.callbackMap_[key];\n  };\n\n\n  /**\n   * @param {string} key\n   * @param {...?} var_args\n   * @private\n   * @suppress {unusedPrivateMembers}\n   */\n  goog.Dependency.callback_ = function(key, var_args) {\n    if (key in goog.Dependency.callbackMap_) {\n      var callback = goog.Dependency.callbackMap_[key];\n      var args = [];\n      for (var i = 1; i < arguments.length; i++) {\n        args.push(arguments[i]);\n      }\n      callback.apply(undefined, args);\n    } else {\n      var errorMessage = 'Callback key ' + key +\n          ' does not exist (was base.js loaded more than once?).';\n      throw Error(errorMessage);\n    }\n  };\n\n\n  /**\n   * Starts loading this dependency. This dependency can pause loading if it\n   * needs to and resume it later via the controller interface.\n   *\n   * When this is loaded it should call controller.loaded(). Note that this will\n   * end up calling the loaded method of this dependency; there is no need to\n   * call it explicitly.\n   *\n   * @param {!goog.LoadController} controller\n   */\n  goog.Dependency.prototype.load = function(controller) {\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    if (!goog.inHtmlDocument_()) {\n      goog.logToConsole_(\n          'Cannot use default debug loader outside of HTML documents.');\n      if (this.relativePath == 'deps.js') {\n        // Some old code is relying on base.js auto loading deps.js failing with\n        // no error before later setting CLOSURE_IMPORT_SCRIPT.\n        // CLOSURE_IMPORT_SCRIPT should be set *before* base.js is loaded, or\n        // CLOSURE_NO_DEPS set to true.\n        goog.logToConsole_(\n            'Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, ' +\n            'or setting CLOSURE_NO_DEPS to true.');\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n\n    // If the user tries to require a new symbol after document load,\n    // something has gone terribly wrong. Doing a document.write would\n    // wipe out the page. This does not apply to the CSP-compliant method\n    // of writing script tags.\n    if (doc.readyState == 'complete' &&\n        !goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {\n      // Certain test frameworks load base.js multiple times, which tries\n      // to write deps.js each time. If that happens, just fail silently.\n      // These frameworks wipe the page between each load of base.js, so this\n      // is OK.\n      var isDeps = /\\bdeps.js$/.test(this.path);\n      if (isDeps) {\n        controller.loaded();\n        return;\n      } else {\n        throw Error('Cannot write \"' + this.path + '\" after document load');\n      }\n    }\n\n    if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&\n        goog.isDocumentLoading_()) {\n      var key = goog.Dependency.registerCallback_(function(script) {\n        if (!goog.DebugLoader_.IS_OLD_IE_ || script.readyState == 'complete') {\n          goog.Dependency.unregisterCallback_(key);\n          controller.loaded();\n        }\n      });\n      var nonceAttr = !goog.DebugLoader_.IS_OLD_IE_ && goog.getScriptNonce() ?\n          ' nonce=\"' + goog.getScriptNonce() + '\"' :\n          '';\n      var event =\n          goog.DebugLoader_.IS_OLD_IE_ ? 'onreadystatechange' : 'onload';\n      var defer = goog.Dependency.defer_ ? 'defer' : '';\n      var script = '<script src=\"' + this.path + '\" ' + event +\n          '=\"goog.Dependency.callback_(\\'' + key +\n          '\\', this)\" type=\"text/javascript\" ' + defer + nonceAttr + '><' +\n          '/script>';\n      doc.write(\n          goog.TRUSTED_TYPES_POLICY_ ?\n              goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n              script);\n    } else {\n      var scriptEl =\n          /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n      scriptEl.defer = goog.Dependency.defer_;\n      scriptEl.async = false;\n      scriptEl.type = 'text/javascript';\n\n      // If CSP nonces are used, propagate them to dynamically created scripts.\n      // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n      var nonce = goog.getScriptNonce();\n      if (nonce) {\n        scriptEl.setAttribute('nonce', nonce);\n      }\n\n      if (goog.DebugLoader_.IS_OLD_IE_) {\n        // Execution order is not guaranteed on old IE, halt loading and write\n        // these scripts one at a time, after each loads.\n        controller.pause();\n        scriptEl.onreadystatechange = function() {\n          if (scriptEl.readyState == 'loaded' ||\n              scriptEl.readyState == 'complete') {\n            controller.loaded();\n            controller.resume();\n          }\n        };\n      } else {\n        scriptEl.onload = function() {\n          scriptEl.onload = null;\n          controller.loaded();\n        };\n      }\n\n      scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n          goog.TRUSTED_TYPES_POLICY_.createScriptURL(this.path) :\n          this.path;\n      doc.head.appendChild(scriptEl);\n    }\n  };\n\n\n  /**\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides Should be an empty array.\n   *     TODO(johnplaisted) add support for adding closure namespaces to ES6\n   *     modules for interop purposes.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   * @extends {goog.Dependency}\n   */\n  goog.Es6ModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.Es6ModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n  };\n  goog.inherits(goog.Es6ModuleDependency, goog.Dependency);\n\n\n  /** @override */\n  goog.Es6ModuleDependency.prototype.load = function(controller) {\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n    if (!goog.inHtmlDocument_()) {\n      goog.logToConsole_(\n          'Cannot use default debug loader outside of HTML documents.');\n      controller.pause();\n      return;\n    }\n\n    /** @type {!HTMLDocument} */\n    var doc = goog.global.document;\n\n    var dep = this;\n\n    // TODO(johnplaisted): Does document.writing really speed up anything? Any\n    // difference between this and just waiting for interactive mode and then\n    // appending?\n    function write(src, contents) {\n      if (contents) {\n        var script = '<script type=\"module\" crossorigin>' + contents + '</' +\n            'script>';\n        doc.write(\n            goog.TRUSTED_TYPES_POLICY_ ?\n                goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n                script);\n      } else {\n        var script = '<script type=\"module\" crossorigin src=\"' + src + '\"></' +\n            'script>';\n        doc.write(\n            goog.TRUSTED_TYPES_POLICY_ ?\n                goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n                script);\n      }\n    }\n\n    function append(src, contents) {\n      var scriptEl =\n          /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n      scriptEl.defer = true;\n      scriptEl.async = false;\n      scriptEl.type = 'module';\n      scriptEl.setAttribute('crossorigin', true);\n\n      // If CSP nonces are used, propagate them to dynamically created scripts.\n      // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n      var nonce = goog.getScriptNonce();\n      if (nonce) {\n        scriptEl.setAttribute('nonce', nonce);\n      }\n\n      if (contents) {\n        scriptEl.textContent = goog.TRUSTED_TYPES_POLICY_ ?\n            goog.TRUSTED_TYPES_POLICY_.createScript(contents) :\n            contents;\n      } else {\n        scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n            goog.TRUSTED_TYPES_POLICY_.createScriptURL(src) :\n            src;\n      }\n\n      doc.head.appendChild(scriptEl);\n    }\n\n    var create;\n\n    if (goog.isDocumentLoading_()) {\n      create = write;\n      // We can ONLY call document.write if we are guaranteed that any\n      // non-module script tags document.written after this are deferred.\n      // Small optimization, in theory document.writing is faster.\n      goog.Dependency.defer_ = true;\n    } else {\n      create = append;\n    }\n\n    // Write 4 separate tags here:\n    // 1) Sets the module state at the correct time (just before execution).\n    // 2) A src node for this, which just hopefully lets the browser load it a\n    //    little early (no need to parse #3).\n    // 3) Import the module and register it.\n    // 4) Clear the module state at the correct time. Guaranteed to run even\n    //    if there is an error in the module (#3 will not run if there is an\n    //    error in the module).\n    var beforeKey = goog.Dependency.registerCallback_(function() {\n      goog.Dependency.unregisterCallback_(beforeKey);\n      controller.setModuleState(goog.ModuleType.ES6);\n    });\n    create(undefined, 'goog.Dependency.callback_(\"' + beforeKey + '\")');\n\n    // TODO(johnplaisted): Does this really speed up anything?\n    create(this.path, undefined);\n\n    var registerKey = goog.Dependency.registerCallback_(function(exports) {\n      goog.Dependency.unregisterCallback_(registerKey);\n      controller.registerEs6ModuleExports(\n          dep.path, exports, goog.moduleLoaderState_.moduleName);\n    });\n    create(\n        undefined,\n        'import * as m from \"' + this.path + '\"; goog.Dependency.callback_(\"' +\n            registerKey + '\", m)');\n\n    var afterKey = goog.Dependency.registerCallback_(function() {\n      goog.Dependency.unregisterCallback_(afterKey);\n      controller.clearModuleState();\n      controller.loaded();\n    });\n    create(undefined, 'goog.Dependency.callback_(\"' + afterKey + '\")');\n  };\n\n\n  /**\n   * Superclass of any dependency that needs to be loaded into memory,\n   * transformed, and then eval'd (goog.modules and transpiled files).\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor @abstract\n   * @extends {goog.Dependency}\n   */\n  goog.TransformedDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.TransformedDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @private {?string} */\n    this.contents_ = null;\n\n    /**\n     * Whether to lazily make the synchronous XHR (when goog.require'd) or make\n     * the synchronous XHR when initially loading. On FireFox 61 there is a bug\n     * where an ES6 module cannot make a synchronous XHR (rather, it can, but if\n     * it does then no other ES6 modules will load after).\n     *\n     * tl;dr we lazy load due to bugs on older browsers and eager load due to\n     * bugs on newer ones.\n     *\n     * https://bugzilla.mozilla.org/show_bug.cgi?id=1477090\n     *\n     * @private @const {boolean}\n     */\n    this.lazyFetch_ = !goog.inHtmlDocument_() ||\n        !('noModule' in goog.global.document.createElement('script'));\n  };\n  goog.inherits(goog.TransformedDependency, goog.Dependency);\n\n\n  /** @override */\n  goog.TransformedDependency.prototype.load = function(controller) {\n    var dep = this;\n\n    function fetch() {\n      dep.contents_ = goog.loadFileSync_(dep.path);\n\n      if (dep.contents_) {\n        dep.contents_ = dep.transform(dep.contents_);\n        if (dep.contents_) {\n          dep.contents_ += '\\n//# sourceURL=' + dep.path;\n        }\n      }\n    }\n\n    if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n      fetch();\n      if (this.contents_ &&\n          goog.global.CLOSURE_IMPORT_SCRIPT('', this.contents_)) {\n        this.contents_ = null;\n        controller.loaded();\n      } else {\n        controller.pause();\n      }\n      return;\n    }\n\n\n    var isEs6 = this.loadFlags['module'] == goog.ModuleType.ES6;\n\n    if (!this.lazyFetch_) {\n      fetch();\n    }\n\n    function load() {\n      if (dep.lazyFetch_) {\n        fetch();\n      }\n\n      if (!dep.contents_) {\n        // loadFileSync_ or transform are responsible. Assume they logged an\n        // error.\n        return;\n      }\n\n      if (isEs6) {\n        controller.setModuleState(goog.ModuleType.ES6);\n      }\n\n      var namespace;\n\n      try {\n        var contents = dep.contents_;\n        dep.contents_ = null;\n        goog.globalEval(contents);\n        if (isEs6) {\n          namespace = goog.moduleLoaderState_.moduleName;\n        }\n      } finally {\n        if (isEs6) {\n          controller.clearModuleState();\n        }\n      }\n\n      if (isEs6) {\n        // Due to circular dependencies this may not be available for require\n        // right now.\n        goog.global['$jscomp']['require']['ensure'](\n            [dep.getPathName()], function() {\n              controller.registerEs6ModuleExports(\n                  dep.path,\n                  goog.global['$jscomp']['require'](dep.getPathName()),\n                  namespace);\n            });\n      }\n\n      controller.loaded();\n    }\n\n    // Do not fetch now; in FireFox 47 the synchronous XHR doesn't block all\n    // events. If we fetched now and then document.write'd the contents the\n    // document.write would be an eval and would execute too soon! Instead write\n    // a script tag to fetch and eval synchronously at the correct time.\n    function fetchInOwnScriptThenLoad() {\n      /** @type {!HTMLDocument} */\n      var doc = goog.global.document;\n\n      var key = goog.Dependency.registerCallback_(function() {\n        goog.Dependency.unregisterCallback_(key);\n        load();\n      });\n\n      var script = '<script type=\"text/javascript\">' +\n          goog.protectScriptTag_('goog.Dependency.callback_(\"' + key + '\");') +\n          '</' +\n          'script>';\n      doc.write(\n          goog.TRUSTED_TYPES_POLICY_ ?\n              goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n              script);\n    }\n\n    // If one thing is pending it is this.\n    var anythingElsePending = controller.pending().length > 1;\n\n    // If anything else is loading we need to lazy load due to bugs in old IE.\n    // Specifically script tags with src and script tags with contents could\n    // execute out of order if document.write is used, so we cannot use\n    // document.write. Do not pause here; it breaks old IE as well.\n    var useOldIeWorkAround =\n        anythingElsePending && goog.DebugLoader_.IS_OLD_IE_;\n\n    // Additionally if we are meant to defer scripts but the page is still\n    // loading (e.g. an ES6 module is loading) then also defer. Or if we are\n    // meant to defer and anything else is pending then defer (those may be\n    // scripts that did not need transformation and are just script tags with\n    // defer set to true, and we need to evaluate after that deferred script).\n    var needsAsyncLoading = goog.Dependency.defer_ &&\n        (anythingElsePending || goog.isDocumentLoading_());\n\n    if (useOldIeWorkAround || needsAsyncLoading) {\n      // Note that we only defer when we have to rather than 100% of the time.\n      // Always defering would work, but then in theory the order of\n      // goog.require calls would then matter. We want to enforce that most of\n      // the time the order of the require calls does not matter.\n      controller.defer(function() {\n        load();\n      });\n      return;\n    }\n    // TODO(johnplaisted): Externs are missing onreadystatechange for\n    // HTMLDocument.\n    /** @type {?} */\n    var doc = goog.global.document;\n\n    var isInternetExplorer =\n        goog.inHtmlDocument_() && 'ActiveXObject' in goog.global;\n\n    // Don't delay in any version of IE. There's bug around this that will\n    // cause out of order script execution. This means that on older IE ES6\n    // modules will load too early (while the document is still loading + the\n    // dom is not available). The other option is to load too late (when the\n    // document is complete and the onload even will never fire). This seems\n    // to be the lesser of two evils as scripts already act like the former.\n    if (isEs6 && goog.inHtmlDocument_() && goog.isDocumentLoading_() &&\n        !isInternetExplorer) {\n      goog.Dependency.defer_ = true;\n      // Transpiled ES6 modules still need to load like regular ES6 modules,\n      // aka only after the document is interactive.\n      controller.pause();\n      var oldCallback = doc.onreadystatechange;\n      doc.onreadystatechange = function() {\n        if (doc.readyState == 'interactive') {\n          doc.onreadystatechange = oldCallback;\n          load();\n          controller.resume();\n        }\n        if (goog.isFunction(oldCallback)) {\n          oldCallback.apply(undefined, arguments);\n        }\n      };\n    } else {\n      // Always eval on old IE.\n      if (goog.DebugLoader_.IS_OLD_IE_ || !goog.inHtmlDocument_() ||\n          !goog.isDocumentLoading_()) {\n        load();\n      } else {\n        fetchInOwnScriptThenLoad();\n      }\n    }\n  };\n\n\n  /**\n   * @param {string} contents\n   * @return {string}\n   * @abstract\n   */\n  goog.TransformedDependency.prototype.transform = function(contents) {};\n\n\n  /**\n   * Any non-goog.module dependency which needs to be transpiled before eval.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.TranspiledDependency = function(\n      path, relativePath, provides, requires, loadFlags, transpiler) {\n    goog.TranspiledDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @protected @const*/\n    this.transpiler = transpiler;\n  };\n  goog.inherits(goog.TranspiledDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.TranspiledDependency.prototype.transform = function(contents) {\n    // Transpile with the pathname so that ES6 modules are domain agnostic.\n    return this.transpiler.transpile(contents, this.getPathName());\n  };\n\n\n  /**\n   * An ES6 module dependency that was transpiled to a jscomp module outside\n   * of the debug loader, e.g. server side.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.PreTranspiledEs6ModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags) {\n    goog.PreTranspiledEs6ModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n  };\n  goog.inherits(\n      goog.PreTranspiledEs6ModuleDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.PreTranspiledEs6ModuleDependency.prototype.transform = function(\n      contents) {\n    return contents;\n  };\n\n\n  /**\n   * A goog.module, transpiled or not. Will always perform some minimal\n   * transformation even when not transpiled to wrap in a goog.loadModule\n   * statement.\n   *\n   * @param {string} path Absolute path of this script.\n   * @param {string} relativePath Path of this script relative to goog.basePath.\n   * @param {!Array<string>} provides goog.provided or goog.module symbols\n   *     in this file.\n   * @param {!Array<string>} requires goog symbols or relative paths to Closure\n   *     this depends on.\n   * @param {!Object<string, string>} loadFlags\n   * @param {boolean} needsTranspile\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   * @extends {goog.TransformedDependency}\n   */\n  goog.GoogModuleDependency = function(\n      path, relativePath, provides, requires, loadFlags, needsTranspile,\n      transpiler) {\n    goog.GoogModuleDependency.base(\n        this, 'constructor', path, relativePath, provides, requires, loadFlags);\n    /** @private @const */\n    this.needsTranspile_ = needsTranspile;\n    /** @private @const */\n    this.transpiler_ = transpiler;\n  };\n  goog.inherits(goog.GoogModuleDependency, goog.TransformedDependency);\n\n\n  /** @override */\n  goog.GoogModuleDependency.prototype.transform = function(contents) {\n    if (this.needsTranspile_) {\n      contents = this.transpiler_.transpile(contents, this.getPathName());\n    }\n\n    if (!goog.LOAD_MODULE_USING_EVAL || goog.global.JSON === undefined) {\n      return '' +\n          'goog.loadModule(function(exports) {' +\n          '\"use strict\";' + contents +\n          '\\n' +  // terminate any trailing single line comment.\n          ';return exports' +\n          '});' +\n          '\\n//# sourceURL=' + this.path + '\\n';\n    } else {\n      return '' +\n          'goog.loadModule(' +\n          goog.global.JSON.stringify(\n              contents + '\\n//# sourceURL=' + this.path + '\\n') +\n          ');';\n    }\n  };\n\n\n  /**\n   * Whether the browser is IE9 or earlier, which needs special handling\n   * for deferred modules.\n   * @const @private {boolean}\n   */\n  goog.DebugLoader_.IS_OLD_IE_ = !!(\n      !goog.global.atob && goog.global.document && goog.global.document['all']);\n\n\n  /**\n   * @param {string} relPath\n   * @param {!Array<string>|undefined} provides\n   * @param {!Array<string>} requires\n   * @param {boolean|!Object<string>=} opt_loadFlags\n   * @see goog.addDependency\n   */\n  goog.DebugLoader_.prototype.addDependency = function(\n      relPath, provides, requires, opt_loadFlags) {\n    provides = provides || [];\n    relPath = relPath.replace(/\\\\/g, '/');\n    var path = goog.normalizePath_(goog.basePath + relPath);\n    if (!opt_loadFlags || typeof opt_loadFlags === 'boolean') {\n      opt_loadFlags = opt_loadFlags ? {'module': goog.ModuleType.GOOG} : {};\n    }\n    var dep = this.factory_.createDependency(\n        path, relPath, provides, requires, opt_loadFlags,\n        goog.transpiler_.needsTranspile(\n            opt_loadFlags['lang'] || 'es3', opt_loadFlags['module']));\n    this.dependencies_[path] = dep;\n    for (var i = 0; i < provides.length; i++) {\n      this.idToPath_[provides[i]] = path;\n    }\n    this.idToPath_[relPath] = path;\n  };\n\n\n  /**\n   * Creates goog.Dependency instances for the debug loader to load.\n   *\n   * Should be overridden to have the debug loader use custom subclasses of\n   * goog.Dependency.\n   *\n   * @param {!goog.Transpiler} transpiler\n   * @struct @constructor\n   */\n  goog.DependencyFactory = function(transpiler) {\n    /** @protected @const */\n    this.transpiler = transpiler;\n  };\n\n\n  /**\n   * @param {string} path Absolute path of the file.\n   * @param {string} relativePath Path relative to closure’s base.js.\n   * @param {!Array<string>} provides Array of provided goog.provide/module ids.\n   * @param {!Array<string>} requires Array of required goog.provide/module /\n   *     relative ES6 module paths.\n   * @param {!Object<string, string>} loadFlags\n   * @param {boolean} needsTranspile True if the file needs to be transpiled\n   *     per the goog.Transpiler.\n   * @return {!goog.Dependency}\n   */\n  goog.DependencyFactory.prototype.createDependency = function(\n      path, relativePath, provides, requires, loadFlags, needsTranspile) {\n\n    if (loadFlags['module'] == goog.ModuleType.GOOG) {\n      return new goog.GoogModuleDependency(\n          path, relativePath, provides, requires, loadFlags, needsTranspile,\n          this.transpiler);\n    } else if (needsTranspile) {\n      return new goog.TranspiledDependency(\n          path, relativePath, provides, requires, loadFlags, this.transpiler);\n    } else {\n      if (loadFlags['module'] == goog.ModuleType.ES6) {\n        if (goog.TRANSPILE == 'never' && goog.ASSUME_ES_MODULES_TRANSPILED) {\n          return new goog.PreTranspiledEs6ModuleDependency(\n              path, relativePath, provides, requires, loadFlags);\n        } else {\n          return new goog.Es6ModuleDependency(\n              path, relativePath, provides, requires, loadFlags);\n        }\n      } else {\n        return new goog.Dependency(\n            path, relativePath, provides, requires, loadFlags);\n      }\n    }\n  };\n\n\n  /** @private @const */\n  goog.debugLoader_ = new goog.DebugLoader_();\n\n\n  /**\n   * Loads the Closure Dependency file.\n   *\n   * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n   * loaded, setDependencyFactory called, and then this called. i.e. allows\n   * custom loading of the deps file.\n   */\n  goog.loadClosureDeps = function() {\n    goog.debugLoader_.loadClosureDeps();\n  };\n\n\n  /**\n   * Sets the dependency factory, which can be used to create custom\n   * goog.Dependency implementations to control how dependencies are loaded.\n   *\n   * Note: if you wish to call this function and provide your own implemnetation\n   * it is a wise idea to set CLOSURE_NO_DEPS to true, otherwise the dependency\n   * file and all of its goog.addDependency calls will use the default factory.\n   * You can call goog.loadClosureDeps to load the Closure dependency file\n   * later, after your factory is injected.\n   *\n   * @param {!goog.DependencyFactory} factory\n   */\n  goog.setDependencyFactory = function(factory) {\n    goog.debugLoader_.setDependencyFactory(factory);\n  };\n\n\n  /**\n   * Trusted Types policy for the debug loader.\n   * @private @const {?TrustedTypePolicy}\n   */\n  goog.TRUSTED_TYPES_POLICY_ = goog.TRUSTED_TYPES_POLICY_NAME ?\n      goog.createTrustedTypesPolicy(goog.TRUSTED_TYPES_POLICY_NAME + '#base') :\n      null;\n\n  if (!goog.global.CLOSURE_NO_DEPS) {\n    goog.debugLoader_.loadClosureDeps();\n  }\n\n\n  /**\n   * Bootstraps the given namespaces and calls the callback once they are\n   * available either via goog.require. This is a replacement for using\n   * `goog.require` to bootstrap Closure JavaScript. Previously a `goog.require`\n   * in an HTML file would guarantee that the require'd namespace was available\n   * in the next immediate script tag. With ES6 modules this no longer a\n   * guarantee.\n   *\n   * @param {!Array<string>} namespaces\n   * @param {function(): ?} callback Function to call once all the namespaces\n   *     have loaded. Always called asynchronously.\n   */\n  goog.bootstrap = function(namespaces, callback) {\n    goog.debugLoader_.bootstrap(namespaces, callback);\n  };\n}\n\n\n/**\n * @define {string} Trusted Types policy name. If non-empty then Closure will\n * use Trusted Types.\n */\ngoog.TRUSTED_TYPES_POLICY_NAME =\n    goog.define('goog.TRUSTED_TYPES_POLICY_NAME', 'goog');\n\n\n/**\n * Returns the parameter.\n * @param {string} s\n * @return {string}\n * @private\n */\ngoog.identity_ = function(s) {\n  return s;\n};\n\n\n/**\n * Creates Trusted Types policy if Trusted Types are supported by the browser.\n * The policy just blesses any string as a Trusted Type. It is not visibility\n * restricted because anyone can also call TrustedTypes.createPolicy directly.\n * However, the allowed names should be restricted by a HTTP header and the\n * reference to the created policy should be visibility restricted.\n * @param {string} name\n * @return {?TrustedTypePolicy}\n */\ngoog.createTrustedTypesPolicy = function(name) {\n  var policy = null;\n  var policyFactory = goog.global.trustedTypes;\n  if (!policyFactory || !policyFactory.createPolicy) {\n    return policy;\n  }\n  // trustedTypes.createPolicy throws if called with a name that is already\n  // registered, even in report-only mode. Until the API changes, catch the\n  // error not to break the applications functionally. In such case, the code\n  // will fall back to using regular Safe Types.\n  // TODO(koto): Remove catching once createPolicy API stops throwing.\n  try {\n    policy = policyFactory.createPolicy(name, {\n      createHTML: goog.identity_,\n      createScript: goog.identity_,\n      createScriptURL: goog.identity_\n    });\n  } catch (e) {\n    goog.logToConsole_(e.message);\n  }\n  return policy;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements the disposable interface. The dispose method is used\n * to clean up references and resources.\n */\n\n\ngoog.provide('goog.Disposable');\ngoog.provide('goog.dispose');\ngoog.provide('goog.disposeAll');\n\ngoog.require('goog.disposable.IDisposable');\n\n\n\n/**\n * Class that provides the basic implementation for disposable objects. If your\n * class holds references or resources that can't be collected by standard GC,\n * it should extend this class or implement the disposable interface (defined\n * in goog.disposable.IDisposable). See description of\n * goog.disposable.IDisposable for examples of cleanup.\n * @constructor\n * @implements {goog.disposable.IDisposable}\n */\ngoog.Disposable = function() {\n  /**\n   * If monitoring the goog.Disposable instances is enabled, stores the creation\n   * stack trace of the Disposable instance.\n   * @type {string|undefined}\n   */\n  this.creationStack;\n\n  if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n    if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {\n      this.creationStack = new Error().stack;\n    }\n    goog.Disposable.instances_[goog.getUid(this)] = this;\n  }\n  // Support sealing\n  this.disposed_ = this.disposed_;\n  this.onDisposeCallbacks_ = this.onDisposeCallbacks_;\n};\n\n\n/**\n * @enum {number} Different monitoring modes for Disposable.\n */\ngoog.Disposable.MonitoringMode = {\n  /**\n   * No monitoring.\n   */\n  OFF: 0,\n  /**\n   * Creating and disposing the goog.Disposable instances is monitored. All\n   * disposable objects need to call the `goog.Disposable` base\n   * constructor. The PERMANENT mode must be switched on before creating any\n   * goog.Disposable instances.\n   */\n  PERMANENT: 1,\n  /**\n   * INTERACTIVE mode can be switched on and off on the fly without producing\n   * errors. It also doesn't warn if the disposable objects don't call the\n   * `goog.Disposable` base constructor.\n   */\n  INTERACTIVE: 2\n};\n\n\n/**\n * @define {number} The monitoring mode of the goog.Disposable\n *     instances. Default is OFF. Switching on the monitoring is only\n *     recommended for debugging because it has a significant impact on\n *     performance and memory usage. If switched off, the monitoring code\n *     compiles down to 0 bytes.\n */\ngoog.Disposable.MONITORING_MODE =\n    goog.define('goog.Disposable.MONITORING_MODE', 0);\n\n\n/**\n * @define {boolean} Whether to attach creation stack to each created disposable\n *     instance; This is only relevant for when MonitoringMode != OFF.\n */\ngoog.Disposable.INCLUDE_STACK_ON_CREATION =\n    goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);\n\n\n/**\n * Maps the unique ID of every undisposed `goog.Disposable` object to\n * the object itself.\n * @type {!Object<number, !goog.Disposable>}\n * @private\n */\ngoog.Disposable.instances_ = {};\n\n\n/**\n * @return {!Array<!goog.Disposable>} All `goog.Disposable` objects that\n *     haven't been disposed of.\n */\ngoog.Disposable.getUndisposedObjects = function() {\n  var ret = [];\n  for (var id in goog.Disposable.instances_) {\n    if (goog.Disposable.instances_.hasOwnProperty(id)) {\n      ret.push(goog.Disposable.instances_[Number(id)]);\n    }\n  }\n  return ret;\n};\n\n\n/**\n * Clears the registry of undisposed objects but doesn't dispose of them.\n */\ngoog.Disposable.clearUndisposedObjects = function() {\n  goog.Disposable.instances_ = {};\n};\n\n\n/**\n * Whether the object has been disposed of.\n * @type {boolean}\n * @private\n */\ngoog.Disposable.prototype.disposed_ = false;\n\n\n/**\n * Callbacks to invoke when this object is disposed.\n * @type {Array<!Function>}\n * @private\n */\ngoog.Disposable.prototype.onDisposeCallbacks_;\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @override\n */\ngoog.Disposable.prototype.isDisposed = function() {\n  return this.disposed_;\n};\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @deprecated Use {@link #isDisposed} instead.\n */\ngoog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;\n\n\n/**\n * Disposes of the object. If the object hasn't already been disposed of, calls\n * {@link #disposeInternal}. Classes that extend `goog.Disposable` should\n * override {@link #disposeInternal} in order to cleanup references, resources\n * and other disposable objects. Reentrant.\n *\n * @return {void} Nothing.\n * @override\n */\ngoog.Disposable.prototype.dispose = function() {\n  if (!this.disposed_) {\n    // Set disposed_ to true first, in case during the chain of disposal this\n    // gets disposed recursively.\n    this.disposed_ = true;\n    this.disposeInternal();\n    if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n      var uid = goog.getUid(this);\n      if (goog.Disposable.MONITORING_MODE ==\n              goog.Disposable.MonitoringMode.PERMANENT &&\n          !goog.Disposable.instances_.hasOwnProperty(uid)) {\n        throw new Error(\n            this + ' did not call the goog.Disposable base ' +\n            'constructor or was disposed of after a clearUndisposedObjects ' +\n            'call');\n      }\n      if (goog.Disposable.MONITORING_MODE !=\n              goog.Disposable.MonitoringMode.OFF &&\n          this.onDisposeCallbacks_ && this.onDisposeCallbacks_.length > 0) {\n        throw new Error(\n            this + ' did not empty its onDisposeCallbacks queue. This ' +\n            'probably means it overrode dispose() or disposeInternal() ' +\n            'without calling the superclass\\' method.');\n      }\n      delete goog.Disposable.instances_[uid];\n    }\n  }\n};\n\n\n/**\n * Associates a disposable object with this object so that they will be disposed\n * together.\n * @param {goog.disposable.IDisposable} disposable that will be disposed when\n *     this object is disposed.\n */\ngoog.Disposable.prototype.registerDisposable = function(disposable) {\n  this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));\n};\n\n\n/**\n * Invokes a callback function when this object is disposed. Callbacks are\n * invoked in the order in which they were added. If a callback is added to\n * an already disposed Disposable, it will be called immediately.\n * @param {function(this:T):?} callback The callback function.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @template T\n */\ngoog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {\n  if (this.disposed_) {\n    opt_scope !== undefined ? callback.call(opt_scope) : callback();\n    return;\n  }\n  if (!this.onDisposeCallbacks_) {\n    this.onDisposeCallbacks_ = [];\n  }\n\n  this.onDisposeCallbacks_.push(\n      opt_scope !== undefined ? goog.bind(callback, opt_scope) : callback);\n};\n\n\n/**\n * Performs appropriate cleanup. See description of goog.disposable.IDisposable\n * for examples. Classes that extend `goog.Disposable` should override this\n * method. Not reentrant. To avoid calling it twice, it must only be called from\n * the subclass' `disposeInternal` method. Everywhere else the public `dispose`\n * method must be used. For example:\n *\n * <pre>\n * mypackage.MyClass = function() {\n * mypackage.MyClass.base(this, 'constructor');\n *     // Constructor logic specific to MyClass.\n *     ...\n *   };\n *   goog.inherits(mypackage.MyClass, goog.Disposable);\n *\n *   mypackage.MyClass.prototype.disposeInternal = function() {\n *     // Dispose logic specific to MyClass.\n *     ...\n *     // Call superclass's disposeInternal at the end of the subclass's, like\n *     // in C++, to avoid hard-to-catch issues.\n *     mypackage.MyClass.base(this, 'disposeInternal');\n *   };\n * </pre>\n *\n * @protected\n */\ngoog.Disposable.prototype.disposeInternal = function() {\n  if (this.onDisposeCallbacks_) {\n    while (this.onDisposeCallbacks_.length) {\n      this.onDisposeCallbacks_.shift()();\n    }\n  }\n};\n\n\n/**\n * Returns True if we can verify the object is disposed.\n * Calls `isDisposed` on the argument if it supports it.  If obj\n * is not an object with an isDisposed() method, return false.\n * @param {*} obj The object to investigate.\n * @return {boolean} True if we can verify the object is disposed.\n */\ngoog.Disposable.isDisposed = function(obj) {\n  if (obj && typeof obj.isDisposed == 'function') {\n    return obj.isDisposed();\n  }\n  return false;\n};\n\n\n/**\n * Calls `dispose` on the argument if it supports it. If obj is not an\n *     object with a dispose() method, this is a no-op.\n * @param {*} obj The object to dispose of.\n */\ngoog.dispose = function(obj) {\n  if (obj && typeof obj.dispose == 'function') {\n    obj.dispose();\n  }\n};\n\n\n/**\n * Calls `dispose` on each member of the list that supports it. (If the\n * member is an ArrayLike, then `goog.disposeAll()` will be called\n * recursively on each of its members.) If the member is not an object with a\n * `dispose()` method, then it is ignored.\n * @param {...*} var_args The list.\n */\ngoog.disposeAll = function(var_args) {\n  for (var i = 0, len = arguments.length; i < len; ++i) {\n    var disposable = arguments[i];\n    if (goog.isArrayLike(disposable)) {\n      goog.disposeAll.apply(null, disposable);\n    } else {\n      goog.dispose(disposable);\n    }\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating arrays.\n */\n\n\ngoog.provide('goog.array');\n\ngoog.require('goog.asserts');\n\n\n/**\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\n * rely on Array.prototype functions, if available.\n *\n * The Array.prototype functions can be defined by external libraries like\n * Prototype and setting this flag to false forces closure to use its own\n * goog.array implementation.\n *\n * If your javascript can be loaded by a third party site and you are wary about\n * relying on the prototype functions, specify\n * \"--define goog.NATIVE_ARRAY_PROTOTYPES=false\" to the JSCompiler.\n *\n * Setting goog.TRUSTED_SITE to false will automatically set\n * NATIVE_ARRAY_PROTOTYPES to false.\n */\ngoog.NATIVE_ARRAY_PROTOTYPES =\n    goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\n\n\n/**\n * @define {boolean} If true, JSCompiler will use the native implementation of\n * array functions where appropriate (e.g., `Array#filter`) and remove the\n * unused pure JS implementation.\n */\ngoog.array.ASSUME_NATIVE_FUNCTIONS = goog.define(\n    'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.last.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.peek = function(array) {\n  return array[array.length - 1];\n};\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.peek.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.last = goog.array.peek;\n\n// NOTE(arv): Since most of the array functions are generic it allows you to\n// pass an array-like object. Strings have a length and are considered array-\n// like. However, the 'in' operator does not work on strings so we cannot just\n// use the array path even if the browser supports indexing into strings. We\n// therefore end up splitting the string.\n\n\n/**\n * Returns the index of the first element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\n *\n * @param {IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {number=} opt_fromIndex The index at which to start the search. If\n *     omitted the search starts at index 0.\n * @return {number} The index of the first matching array element.\n * @template T\n */\ngoog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n    function(arr, obj, opt_fromIndex) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n    } :\n    function(arr, obj, opt_fromIndex) {\n      var fromIndex = opt_fromIndex == null ?\n          0 :\n          (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\n                               opt_fromIndex);\n\n      if (typeof arr === 'string') {\n        // Array.prototype.indexOf uses === so only strings should be found.\n        if (typeof obj !== 'string' || obj.length != 1) {\n          return -1;\n        }\n        return arr.indexOf(obj, fromIndex);\n      }\n\n      for (var i = fromIndex; i < arr.length; i++) {\n        if (i in arr && arr[i] === obj) return i;\n      }\n      return -1;\n    };\n\n\n/**\n * Returns the index of the last element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\n *\n * @param {!IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {?number=} opt_fromIndex The index at which to start the search. If\n *     omitted the search starts at the end of the array.\n * @return {number} The index of the last matching array element.\n * @template T\n */\ngoog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n    function(arr, obj, opt_fromIndex) {\n      goog.asserts.assert(arr.length != null);\n\n      // Firefox treats undefined and null as 0 in the fromIndex argument which\n      // leads it to always return -1\n      var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n      return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n    } :\n    function(arr, obj, opt_fromIndex) {\n      var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n\n      if (fromIndex < 0) {\n        fromIndex = Math.max(0, arr.length + fromIndex);\n      }\n\n      if (typeof arr === 'string') {\n        // Array.prototype.lastIndexOf uses === so only strings should be found.\n        if (typeof obj !== 'string' || obj.length != 1) {\n          return -1;\n        }\n        return arr.lastIndexOf(obj, fromIndex);\n      }\n\n      for (var i = fromIndex; i >= 0; i--) {\n        if (i in arr && arr[i] === obj) return i;\n      }\n      return -1;\n    };\n\n\n/**\n * Calls a function for each element in an array. Skips holes in the array.\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\n *\n * @param {IArrayLike<T>|string} arr Array or array like object over\n *     which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n *     element. This function takes 3 arguments (the element, the index and the\n *     array). The return value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @template T,S\n */\ngoog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      Array.prototype.forEach.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n        }\n      }\n    };\n\n\n/**\n * Calls a function for each element in an array, starting from the last\n * element rather than the first.\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n *     element. This function\n *     takes 3 arguments (the element, the index and the array). The return\n *     value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @template T,S\n */\ngoog.array.forEachRight = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = l - 1; i >= 0; --i) {\n    if (i in arr2) {\n      f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n    }\n  }\n};\n\n\n/**\n * Calls a function for each element in an array, and if the function returns\n * true adds the element to a new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\n *     every element. This function\n *     takes 3 arguments (the element, the index and the array) and must\n *     return a Boolean. If the return value is true the element is added to the\n *     result array. If it is false the element is not included.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {!Array<T>} a new array in which only elements that passed the test\n *     are present.\n * @template T,S\n */\ngoog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.filter.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var res = [];\n      var resLength = 0;\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          var val = arr2[i];  // in case f mutates arr2\n          if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\n            res[resLength++] = val;\n          }\n        }\n      }\n      return res;\n    };\n\n\n/**\n * Calls a function for each element in an array and inserts the result into a\n * new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\n *\n * @param {IArrayLike<VALUE>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\n *     for every element. This function takes 3 arguments (the element,\n *     the index and the array) and should return something. The result will be\n *     inserted into a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the results from f.\n * @template THIS, VALUE, RESULT\n */\ngoog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.map.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var res = new Array(l);\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2) {\n          res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n        }\n      }\n      return res;\n    };\n\n\n/**\n * Passes every element of an array into a function and accumulates the result.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\n *\n * For example:\n * var a = [1, 2, 3, 4];\n * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);\n * returns 10\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\n *     every element. This function\n *     takes 4 arguments (the function's previous result or the initial value,\n *     the value of the current array element, the current array index, and the\n *     array itself)\n *     function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj  The object to be used as the value of 'this'\n *     within f.\n * @return {R} Result of evaluating f repeatedly across the values of the array.\n * @template T,S,R\n */\ngoog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n    function(arr, f, val, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n      if (opt_obj) {\n        f = goog.bind(f, opt_obj);\n      }\n      return Array.prototype.reduce.call(arr, f, val);\n    } :\n    function(arr, f, val, opt_obj) {\n      var rval = val;\n      goog.array.forEach(arr, function(val, index) {\n        rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n      });\n      return rval;\n    };\n\n\n/**\n * Passes every element of an array into a function and accumulates the result,\n * starting from the last element and working towards the first.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\n *\n * For example:\n * var a = ['a', 'b', 'c'];\n * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\n * returns 'cba'\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\n *     every element. This function\n *     takes 4 arguments (the function's previous result or the initial value,\n *     the value of the current array element, the current array index, and the\n *     array itself)\n *     function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {R} Object returned as a result of evaluating f repeatedly across the\n *     values of the array.\n * @template T,S,R\n */\ngoog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n    function(arr, f, val, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n      goog.asserts.assert(f != null);\n      if (opt_obj) {\n        f = goog.bind(f, opt_obj);\n      }\n      return Array.prototype.reduceRight.call(arr, f, val);\n    } :\n    function(arr, f, val, opt_obj) {\n      var rval = val;\n      goog.array.forEachRight(arr, function(val, index) {\n        rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n      });\n      return rval;\n    };\n\n\n/**\n * Calls f for each element of an array. If any call returns true, some()\n * returns true (without checking the remaining elements). If all calls\n * return false, some() returns false.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj  The object to be used as the value of 'this'\n *     within f.\n * @return {boolean} true if any element passes the test.\n * @template T,S\n */\ngoog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.some.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n          return true;\n        }\n      }\n      return false;\n    };\n\n\n/**\n * Call f for each element of an array. If all calls return true, every()\n * returns true. If any call returns false, every() returns false and\n * does not continue to check the remaining elements.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within f.\n * @return {boolean} false if any element fails the test.\n * @template T,S\n */\ngoog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&\n        (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n    function(arr, f, opt_obj) {\n      goog.asserts.assert(arr.length != null);\n\n      return Array.prototype.every.call(arr, f, opt_obj);\n    } :\n    function(arr, f, opt_obj) {\n      var l = arr.length;  // must be fixed during loop... see docs\n      var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n      for (var i = 0; i < l; i++) {\n        if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n          return false;\n        }\n      }\n      return true;\n    };\n\n\n/**\n * Counts the array elements that fulfill the predicate, i.e. for which the\n * callback function returns true. Skips holes in the array.\n *\n * @param {!IArrayLike<T>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\n *     every element. Takes 3 arguments (the element, the index and the array).\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @return {number} The number of the matching elements.\n * @template T,S\n */\ngoog.array.count = function(arr, f, opt_obj) {\n  var count = 0;\n  goog.array.forEach(arr, function(element, index, arr) {\n    if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\n      ++count;\n    }\n  }, opt_obj);\n  return count;\n};\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The first array element that passes the test, or null if no\n *     element is found.\n * @template T,S\n */\ngoog.array.find = function(arr, f, opt_obj) {\n  var i = goog.array.findIndex(arr, f, opt_obj);\n  return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n *     every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the first array element that passes the test,\n *     or -1 if no element is found.\n * @template T,S\n */\ngoog.array.findIndex = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = 0; i < l; i++) {\n    if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The last array element that passes the test, or null if no\n *     element is found.\n * @template T,S\n */\ngoog.array.findRight = function(arr, f, opt_obj) {\n  var i = goog.array.findIndexRight(arr, f, opt_obj);\n  return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the last array element that passes the test,\n *     or -1 if no element is found.\n * @template T,S\n */\ngoog.array.findIndexRight = function(arr, f, opt_obj) {\n  var l = arr.length;  // must be fixed during loop... see docs\n  var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n  for (var i = l - 1; i >= 0; i--) {\n    if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n\n/**\n * Whether the array contains the given object.\n * @param {IArrayLike<?>|string} arr The array to test for the presence of the\n *     element.\n * @param {*} obj The object for which to test.\n * @return {boolean} true if obj is present.\n */\ngoog.array.contains = function(arr, obj) {\n  return goog.array.indexOf(arr, obj) >= 0;\n};\n\n\n/**\n * Whether the array is empty.\n * @param {IArrayLike<?>|string} arr The array to test.\n * @return {boolean} true if empty.\n */\ngoog.array.isEmpty = function(arr) {\n  return arr.length == 0;\n};\n\n\n/**\n * Clears the array.\n * @param {IArrayLike<?>} arr Array or array like object to clear.\n */\ngoog.array.clear = function(arr) {\n  // For non real arrays we don't have the magic length so we delete the\n  // indices.\n  if (!Array.isArray(arr)) {\n    for (var i = arr.length - 1; i >= 0; i--) {\n      delete arr[i];\n    }\n  }\n  arr.length = 0;\n};\n\n\n/**\n * Pushes an item into an array, if it's not already in the array.\n * @param {Array<T>} arr Array into which to insert the item.\n * @param {T} obj Value to add.\n * @template T\n */\ngoog.array.insert = function(arr, obj) {\n  if (!goog.array.contains(arr, obj)) {\n    arr.push(obj);\n  }\n};\n\n\n/**\n * Inserts an object at the given index of the array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {*} obj The object to insert.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n *      treated as 0. A negative index is counted from the end of the array.\n */\ngoog.array.insertAt = function(arr, obj, opt_i) {\n  goog.array.splice(arr, opt_i, 0, obj);\n};\n\n\n/**\n * Inserts at the given index of the array, all elements of another array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {IArrayLike<?>} elementsToAdd The array of elements to add.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n *      treated as 0. A negative index is counted from the end of the array.\n */\ngoog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {\n  goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);\n};\n\n\n/**\n * Inserts an object into an array before a specified object.\n * @param {Array<T>} arr The array to modify.\n * @param {T} obj The object to insert.\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\n *     is omitted or not found, obj is inserted at the end of the array.\n * @template T\n */\ngoog.array.insertBefore = function(arr, obj, opt_obj2) {\n  var i;\n  if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {\n    arr.push(obj);\n  } else {\n    goog.array.insertAt(arr, obj, i);\n  }\n};\n\n\n/**\n * Removes the first occurrence of a particular value from an array.\n * @param {IArrayLike<T>} arr Array from which to remove\n *     value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\ngoog.array.remove = function(arr, obj) {\n  var i = goog.array.indexOf(arr, obj);\n  var rv;\n  if ((rv = i >= 0)) {\n    goog.array.removeAt(arr, i);\n  }\n  return rv;\n};\n\n\n/**\n * Removes the last occurrence of a particular value from an array.\n * @param {!IArrayLike<T>} arr Array from which to remove value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\ngoog.array.removeLast = function(arr, obj) {\n  var i = goog.array.lastIndexOf(arr, obj);\n  if (i >= 0) {\n    goog.array.removeAt(arr, i);\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes from an array the element at index i\n * @param {IArrayLike<?>} arr Array or array like object from which to\n *     remove value.\n * @param {number} i The index to remove.\n * @return {boolean} True if an element was removed.\n */\ngoog.array.removeAt = function(arr, i) {\n  goog.asserts.assert(arr.length != null);\n\n  // use generic form of splice\n  // splice returns the removed items and if successful the length of that\n  // will be 1\n  return Array.prototype.splice.call(arr, i, 1).length == 1;\n};\n\n\n/**\n * Removes the first value that satisfies the given condition.\n * @param {IArrayLike<T>} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {boolean} True if an element was removed.\n * @template T,S\n */\ngoog.array.removeIf = function(arr, f, opt_obj) {\n  var i = goog.array.findIndex(arr, f, opt_obj);\n  if (i >= 0) {\n    goog.array.removeAt(arr, i);\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes all values that satisfy the given condition.\n * @param {IArrayLike<T>} arr Array or array\n *     like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the element, the index and the array) and should\n *     return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The number of items removed\n * @template T,S\n */\ngoog.array.removeAllIf = function(arr, f, opt_obj) {\n  var removedCount = 0;\n  goog.array.forEachRight(arr, function(val, index) {\n    if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n      if (goog.array.removeAt(arr, index)) {\n        removedCount++;\n      }\n    }\n  });\n  return removedCount;\n};\n\n\n/**\n * Returns a new array that is the result of joining the arguments.  If arrays\n * are passed then their items are added, however, if non-arrays are passed they\n * will be added to the return array as is.\n *\n * Note that ArrayLike objects will be added as is, rather than having their\n * items added.\n *\n * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * goog.array.concat(0, [1, 2]) -> [0, 1, 2]\n * goog.array.concat([1, 2], null) -> [1, 2, null]\n *\n * There is bug in all current versions of IE (6, 7 and 8) where arrays created\n * in an iframe become corrupted soon (not immediately) after the iframe is\n * destroyed. This is common if loading data via goog.net.IframeIo, for example.\n * This corruption only affects the concat method which will start throwing\n * Catastrophic Errors (#-2147418113).\n *\n * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.\n *\n * Internally goog.array should use this, so that all methods will continue to\n * work on these broken array objects.\n *\n * @param {...*} var_args Items to concatenate.  Arrays will have each item\n *     added, while primitives and objects will be added as is.\n * @return {!Array<?>} The new resultant array.\n */\ngoog.array.concat = function(var_args) {\n  return Array.prototype.concat.apply([], arguments);\n};\n\n\n/**\n * Returns a new array that contains the contents of all the arrays passed.\n * @param {...!Array<T>} var_args\n * @return {!Array<T>}\n * @template T\n */\ngoog.array.join = function(var_args) {\n  return Array.prototype.concat.apply([], arguments);\n};\n\n\n/**\n * Converts an object to an array.\n * @param {IArrayLike<T>|string} object  The object to convert to an\n *     array.\n * @return {!Array<T>} The object converted into an array. If object has a\n *     length property, every property indexed with a non-negative number\n *     less than length will be included in the result. If object does not\n *     have a length property, an empty array will be returned.\n * @template T\n */\ngoog.array.toArray = function(object) {\n  var length = object.length;\n\n  // If length is not a number the following is false. This case is kept for\n  // backwards compatibility since there are callers that pass objects that are\n  // not array like.\n  if (length > 0) {\n    var rv = new Array(length);\n    for (var i = 0; i < length; i++) {\n      rv[i] = object[i];\n    }\n    return rv;\n  }\n  return [];\n};\n\n\n/**\n * Does a shallow copy of an array.\n * @param {IArrayLike<T>|string} arr  Array or array-like object to\n *     clone.\n * @return {!Array<T>} Clone of the input array.\n * @template T\n */\ngoog.array.clone = goog.array.toArray;\n\n\n/**\n * Extends an array with another array, element, or \"array like\" object.\n * This function operates 'in-place', it does not create a new Array.\n *\n * Example:\n * var a = [];\n * goog.array.extend(a, [0, 1]);\n * a; // [0, 1]\n * goog.array.extend(a, 2);\n * a; // [0, 1, 2]\n *\n * @param {Array<VALUE>} arr1  The array to modify.\n * @param {...(IArrayLike<VALUE>|VALUE)} var_args The elements or arrays of\n *     elements to add to arr1.\n * @template VALUE\n */\ngoog.array.extend = function(arr1, var_args) {\n  for (var i = 1; i < arguments.length; i++) {\n    var arr2 = arguments[i];\n    if (goog.isArrayLike(arr2)) {\n      var len1 = arr1.length || 0;\n      var len2 = arr2.length || 0;\n      arr1.length = len1 + len2;\n      for (var j = 0; j < len2; j++) {\n        arr1[len1 + j] = arr2[j];\n      }\n    } else {\n      arr1.push(arr2);\n    }\n  }\n};\n\n\n/**\n * Adds or removes elements from an array. This is a generic version of Array\n * splice. This means that it might work on other objects similar to arrays,\n * such as the arguments object.\n *\n * @param {IArrayLike<T>} arr The array to modify.\n * @param {number|undefined} index The index at which to start changing the\n *     array. If not defined, treated as 0.\n * @param {number} howMany How many elements to remove (0 means no removal. A\n *     value below 0 is treated as zero and so is any other non number. Numbers\n *     are floored).\n * @param {...T} var_args Optional, additional elements to insert into the\n *     array.\n * @return {!Array<T>} the removed elements.\n * @template T\n */\ngoog.array.splice = function(arr, index, howMany, var_args) {\n  goog.asserts.assert(arr.length != null);\n\n  return Array.prototype.splice.apply(arr, goog.array.slice(arguments, 1));\n};\n\n\n/**\n * Returns a new array from a segment of an array. This is a generic version of\n * Array slice. This means that it might work on other objects similar to\n * arrays, such as the arguments object.\n *\n * @param {IArrayLike<T>|string} arr The array from\n * which to copy a segment.\n * @param {number} start The index of the first element to copy.\n * @param {number=} opt_end The index after the last element to copy.\n * @return {!Array<T>} A new array containing the specified segment of the\n *     original array.\n * @template T\n */\ngoog.array.slice = function(arr, start, opt_end) {\n  goog.asserts.assert(arr.length != null);\n\n  // passing 1 arg to slice is not the same as passing 2 where the second is\n  // null or undefined (in that case the second argument is treated as 0).\n  // we could use slice on the arguments object and then use apply instead of\n  // testing the length\n  if (arguments.length <= 2) {\n    return Array.prototype.slice.call(arr, start);\n  } else {\n    return Array.prototype.slice.call(arr, start, opt_end);\n  }\n};\n\n\n/**\n * Removes all duplicates from an array (retaining only the first\n * occurrence of each array element).  This function modifies the\n * array in place and doesn't change the order of the non-duplicate items.\n *\n * For objects, duplicates are identified as having the same unique ID as\n * defined by {@link goog.getUid}.\n *\n * Alternatively you can specify a custom hash function that returns a unique\n * value for each item in the array it should consider unique.\n *\n * Runtime: N,\n * Worstcase space: 2N (no dupes)\n *\n * @param {IArrayLike<T>} arr The array from which to remove\n *     duplicates.\n * @param {Array=} opt_rv An optional array in which to return the results,\n *     instead of performing the removal inplace.  If specified, the original\n *     array will remain unchanged.\n * @param {function(T):string=} opt_hashFn An optional function to use to\n *     apply to every item in the array. This function should return a unique\n *     value for each item in the array it should consider unique.\n * @template T\n */\ngoog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {\n  var returnArray = opt_rv || arr;\n  var defaultHashFn = function(item) {\n    // Prefix each type with a single character representing the type to\n    // prevent conflicting keys (e.g. true and 'true').\n    return goog.isObject(item) ? 'o' + goog.getUid(item) :\n                                 (typeof item).charAt(0) + item;\n  };\n  var hashFn = opt_hashFn || defaultHashFn;\n\n  var seen = {}, cursorInsert = 0, cursorRead = 0;\n  while (cursorRead < arr.length) {\n    var current = arr[cursorRead++];\n    var key = hashFn(current);\n    if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n      seen[key] = true;\n      returnArray[cursorInsert++] = current;\n    }\n  }\n  returnArray.length = cursorInsert;\n};\n\n\n/**\n * Searches the specified array for the specified target using the binary\n * search algorithm.  If no opt_compareFn is specified, elements are compared\n * using <code>goog.array.defaultCompare</code>, which compares the elements\n * using the built in < and > operators.  This will produce the expected\n * behavior for homogeneous arrays of String(s) and Number(s). The array\n * specified <b>must</b> be sorted in ascending order (as defined by the\n * comparison function).  If the array is not sorted, results are undefined.\n * If the array contains multiple instances of the specified target value, the\n * left-most instance will be found.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {TARGET} target The sought value.\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, the target value and an element from your array, and return a\n *     negative number, zero, or a positive number depending on whether the\n *     first argument is less than, equal to, or greater than the second.\n * @return {number} Lowest index of the target value if found, otherwise\n *     (-(insertion point) - 1). The insertion point is where the value should\n *     be inserted into arr to preserve the sorted property.  Return value >= 0\n *     iff target is found.\n * @template TARGET, VALUE\n */\ngoog.array.binarySearch = function(arr, target, opt_compareFn) {\n  return goog.array.binarySearch_(\n      arr, opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,\n      target);\n};\n\n\n/**\n * Selects an index in the specified array using the binary search algorithm.\n * The evaluator receives an element and determines whether the desired index\n * is before, at, or after it.  The evaluator must be consistent (formally,\n * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)\n * must be monotonically non-increasing).\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\n *     Evaluator function that receives 3 arguments (the element, the index and\n *     the array). Should return a negative number, zero, or a positive number\n *     depending on whether the desired index is before, at, or after the\n *     element passed to it.\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\n *     within evaluator.\n * @return {number} Index of the leftmost element matched by the evaluator, if\n *     such exists; otherwise (-(insertion point) - 1). The insertion point is\n *     the index of the first element for which the evaluator returns negative,\n *     or arr.length if no such element exists. The return value is non-negative\n *     iff a match is found.\n * @template THIS, VALUE\n */\ngoog.array.binarySelect = function(arr, evaluator, opt_obj) {\n  return goog.array.binarySearch_(\n      arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n      opt_obj);\n};\n\n\n/**\n * Implementation of a binary search algorithm which knows how to use both\n * comparison functions and evaluators. If an evaluator is provided, will call\n * the evaluator with the given optional data object, conforming to the\n * interface defined in binarySelect. Otherwise, if a comparison function is\n * provided, will call the comparison function against the given data object.\n *\n * This implementation purposefully does not use goog.bind or goog.partial for\n * performance reasons.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<?>} arr The array to be searched.\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\n *     Either an evaluator or a comparison function, as defined by binarySearch\n *     and binarySelect above.\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\n *     comparison function.\n * @param {?=} opt_target If the function is a comparison function, then\n *     this is the target to binary search for.\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\n *     optional this object for the evaluator.\n * @return {number} Lowest index of the target value if found, otherwise\n *     (-(insertion point) - 1). The insertion point is where the value should\n *     be inserted into arr to preserve the sorted property.  Return value >= 0\n *     iff target is found.\n * @private\n */\ngoog.array.binarySearch_ = function(\n    arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n  var left = 0;            // inclusive\n  var right = arr.length;  // exclusive\n  var found;\n  while (left < right) {\n    var middle = left + ((right - left) >>> 1);\n    var compareResult;\n    if (isEvaluator) {\n      compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n    } else {\n      // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\n      // for the type of binarySearch_, which the type system can't express yet.\n      compareResult = /** @type {function(?, ?): number} */ (compareFn)(\n          opt_target, arr[middle]);\n    }\n    if (compareResult > 0) {\n      left = middle + 1;\n    } else {\n      right = middle;\n      // We are looking for the lowest index so we can't return immediately.\n      found = !compareResult;\n    }\n  }\n  // left is the index if found, or the insertion point otherwise.\n  // Avoiding bitwise not operator, as that causes a loss in precision for array\n  // indexes outside the bounds of a 32-bit signed integer.  Array indexes have\n  // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\n  return found ? left : -left - 1;\n};\n\n\n/**\n * Sorts the specified array into ascending order.  If no opt_compareFn is\n * specified, elements are compared using\n * <code>goog.array.defaultCompare</code>, which compares the elements using\n * the built in < and > operators.  This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\n * but will give unpredictable results for heterogeneous lists of strings and\n * numbers with different numbers of digits.\n *\n * This sort is not guaranteed to be stable.\n *\n * Runtime: Same as <code>Array.prototype.sort</code>\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\n *     function by which the\n *     array is to be ordered. Should take 2 arguments to compare, and return a\n *     negative number, zero, or a positive number depending on whether the\n *     first argument is less than, equal to, or greater than the second.\n * @template T\n */\ngoog.array.sort = function(arr, opt_compareFn) {\n  // TODO(arv): Update type annotation since null is not accepted.\n  arr.sort(opt_compareFn || goog.array.defaultCompare);\n};\n\n\n/**\n * Sorts the specified array into ascending order in a stable way.  If no\n * opt_compareFn is specified, elements are compared using\n * <code>goog.array.defaultCompare</code>, which compares the elements using\n * the built in < and > operators.  This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s).\n *\n * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional\n * O(n) overhead of copying the array twice.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\n *     by which the array is to be ordered. Should take 2 arguments to compare,\n *     and return a negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template T\n */\ngoog.array.stableSort = function(arr, opt_compareFn) {\n  var compArr = new Array(arr.length);\n  for (var i = 0; i < arr.length; i++) {\n    compArr[i] = {index: i, value: arr[i]};\n  }\n  var valueCompareFn = opt_compareFn || goog.array.defaultCompare;\n  function stableCompareFn(obj1, obj2) {\n    return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n  }\n  goog.array.sort(compArr, stableCompareFn);\n  for (var i = 0; i < arr.length; i++) {\n    arr[i] = compArr[i].value;\n  }\n};\n\n\n/**\n * Sort the specified array into ascending order based on item keys\n * returned by the specified key function.\n * If no opt_compareFn is specified, the keys are compared in ascending order\n * using <code>goog.array.defaultCompare</code>.\n *\n * Runtime: O(S(f(n)), where S is runtime of <code>goog.array.sort</code>\n * and f(n) is runtime of the key function.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {function(T): K} keyFn Function taking array element and returning\n *     a key used for sorting this element.\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\n *     by which the keys are to be ordered. Should take 2 arguments to compare,\n *     and return a negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template T,K\n */\ngoog.array.sortByKey = function(arr, keyFn, opt_compareFn) {\n  var keyCompareFn = opt_compareFn || goog.array.defaultCompare;\n  goog.array.sort(\n      arr, function(a, b) { return keyCompareFn(keyFn(a), keyFn(b)); });\n};\n\n\n/**\n * Sorts an array of objects by the specified object key and compare\n * function. If no compare function is provided, the key values are\n * compared in ascending order using <code>goog.array.defaultCompare</code>.\n * This won't work for keys that get renamed by the compiler. So use\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\n * @param {Array<Object>} arr An array of objects to sort.\n * @param {string} key The object key to sort by.\n * @param {Function=} opt_compareFn The function to use to compare key\n *     values.\n */\ngoog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {\n  goog.array.sortByKey(arr, function(obj) { return obj[key]; }, opt_compareFn);\n};\n\n\n/**\n * Tells if the array is sorted.\n * @param {!IArrayLike<T>} arr The array.\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\n *     array elements.\n *     Should take 2 arguments to compare, and return a negative number, zero,\n *     or a positive number depending on whether the first argument is less\n *     than, equal to, or greater than the second.\n * @param {boolean=} opt_strict If true no equal elements are allowed.\n * @return {boolean} Whether the array is sorted.\n * @template T\n */\ngoog.array.isSorted = function(arr, opt_compareFn, opt_strict) {\n  var compare = opt_compareFn || goog.array.defaultCompare;\n  for (var i = 1; i < arr.length; i++) {\n    var compareResult = compare(arr[i - 1], arr[i]);\n    if (compareResult > 0 || compareResult == 0 && opt_strict) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * Compares two arrays for equality. Two arrays are considered equal if they\n * have the same length and their corresponding elements are equal according to\n * the comparison function.\n *\n * @param {IArrayLike<A>} arr1 The first array to compare.\n * @param {IArrayLike<B>} arr2 The second array to compare.\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\n *     Should take 2 arguments to compare, and return true if the arguments\n *     are equal. Defaults to {@link goog.array.defaultCompareEquality} which\n *     compares the elements using the built-in '===' operator.\n * @return {boolean} Whether the two arrays are equal.\n * @template A\n * @template B\n */\ngoog.array.equals = function(arr1, arr2, opt_equalsFn) {\n  if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n      arr1.length != arr2.length) {\n    return false;\n  }\n  var l = arr1.length;\n  var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;\n  for (var i = 0; i < l; i++) {\n    if (!equalsFn(arr1[i], arr2[i])) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * 3-way array compare function.\n * @param {!IArrayLike<VALUE>} arr1 The first array to\n *     compare.\n * @param {!IArrayLike<VALUE>} arr2 The second array to\n *     compare.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is to be ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {number} Negative number, zero, or a positive number depending on\n *     whether the first argument is less than, equal to, or greater than the\n *     second.\n * @template VALUE\n */\ngoog.array.compare3 = function(arr1, arr2, opt_compareFn) {\n  var compare = opt_compareFn || goog.array.defaultCompare;\n  var l = Math.min(arr1.length, arr2.length);\n  for (var i = 0; i < l; i++) {\n    var result = compare(arr1[i], arr2[i]);\n    if (result != 0) {\n      return result;\n    }\n  }\n  return goog.array.defaultCompare(arr1.length, arr2.length);\n};\n\n\n/**\n * Compares its two arguments for order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n *     argument is less than, equal to, or greater than the second,\n *     respectively.\n * @template VALUE\n */\ngoog.array.defaultCompare = function(a, b) {\n  return a > b ? 1 : a < b ? -1 : 0;\n};\n\n\n/**\n * Compares its two arguments for inverse order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n *     argument is greater than, equal to, or less than the second,\n *     respectively.\n * @template VALUE\n */\ngoog.array.inverseDefaultCompare = function(a, b) {\n  return -goog.array.defaultCompare(a, b);\n};\n\n\n/**\n * Compares its two arguments for equality, using the built in === operator.\n * @param {*} a The first object to compare.\n * @param {*} b The second object to compare.\n * @return {boolean} True if the two arguments are equal, false otherwise.\n */\ngoog.array.defaultCompareEquality = function(a, b) {\n  return a === b;\n};\n\n\n/**\n * Inserts a value into a sorted array. The array is not modified if the\n * value is already present.\n * @param {IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to insert.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {boolean} True if an element was inserted.\n * @template VALUE\n */\ngoog.array.binaryInsert = function(array, value, opt_compareFn) {\n  var index = goog.array.binarySearch(array, value, opt_compareFn);\n  if (index < 0) {\n    goog.array.insertAt(array, value, -(index + 1));\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes a value from a sorted array.\n * @param {!IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to remove.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n *     function by which the array is ordered. Should take 2 arguments to\n *     compare, and return a negative number, zero, or a positive number\n *     depending on whether the first argument is less than, equal to, or\n *     greater than the second.\n * @return {boolean} True if an element was removed.\n * @template VALUE\n */\ngoog.array.binaryRemove = function(array, value, opt_compareFn) {\n  var index = goog.array.binarySearch(array, value, opt_compareFn);\n  return (index >= 0) ? goog.array.removeAt(array, index) : false;\n};\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {IArrayLike<T>} array The array.\n * @param {function(this:S, T, number, !IArrayLike<T>):?} sorter Function to\n *     call for every element.  This takes 3 arguments (the element, the index\n *     and the array) and must return a valid object key (a string, number,\n *     etc), or undefined, if that object should not be placed in a bucket.\n * @param {S=} opt_obj The object to be used as the value of 'this' within\n *     sorter.\n * @return {!Object<!Array<T>>} An object, with keys being all of the unique\n *     return values of sorter, and values being arrays containing the items for\n *     which the splitter returned that key.\n * @template T,S\n */\ngoog.array.bucket = function(array, sorter, opt_obj) {\n  var buckets = {};\n\n  for (var i = 0; i < array.length; i++) {\n    var value = array[i];\n    var key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\n    if (key !== undefined) {\n      // Push the value to the right bucket, creating it if necessary.\n      var bucket = buckets[key] || (buckets[key] = []);\n      bucket.push(value);\n    }\n  }\n\n  return buckets;\n};\n\n\n/**\n * Creates a new object built from the provided array and the key-generation\n * function.\n * @param {IArrayLike<T>} arr Array or array like object over\n *     which to iterate whose elements will be the values in the new object.\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\n *     call for every element. This function takes 3 arguments (the element, the\n *     index and the array) and should return a string that will be used as the\n *     key for the element in the new object. If the function returns the same\n *     key for more than one element, the value for that key is\n *     implementation-defined.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n *     within keyFunc.\n * @return {!Object<T>} The new object.\n * @template T,S\n */\ngoog.array.toObject = function(arr, keyFunc, opt_obj) {\n  var ret = {};\n  goog.array.forEach(arr, function(element, index) {\n    ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n        element;\n  });\n  return ret;\n};\n\n\n/**\n * Creates a range of numbers in an arithmetic progression.\n *\n * Range takes 1, 2, or 3 arguments:\n * <pre>\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\n * range(-2, -5, -1) produces [-2, -3, -4]\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\n * </pre>\n *\n * @param {number} startOrEnd The starting value of the range if an end argument\n *     is provided. Otherwise, the start value is 0, and this is the end value.\n * @param {number=} opt_end The optional end value of the range.\n * @param {number=} opt_step The step size between range values. Defaults to 1\n *     if opt_step is undefined or 0.\n * @return {!Array<number>} An array of numbers for the requested range. May be\n *     an empty array if adding the step would not converge toward the end\n *     value.\n */\ngoog.array.range = function(startOrEnd, opt_end, opt_step) {\n  var array = [];\n  var start = 0;\n  var end = startOrEnd;\n  var step = opt_step || 1;\n  if (opt_end !== undefined) {\n    start = startOrEnd;\n    end = opt_end;\n  }\n\n  if (step * (end - start) < 0) {\n    // Sign mismatch: start + step will never reach the end value.\n    return [];\n  }\n\n  if (step > 0) {\n    for (var i = start; i < end; i += step) {\n      array.push(i);\n    }\n  } else {\n    for (var i = start; i > end; i += step) {\n      array.push(i);\n    }\n  }\n  return array;\n};\n\n\n/**\n * Returns an array consisting of the given value repeated N times.\n *\n * @param {VALUE} value The value to repeat.\n * @param {number} n The repeat count.\n * @return {!Array<VALUE>} An array with the repeated value.\n * @template VALUE\n */\ngoog.array.repeat = function(value, n) {\n  var array = [];\n  for (var i = 0; i < n; i++) {\n    array[i] = value;\n  }\n  return array;\n};\n\n\n/**\n * Returns an array consisting of every argument with all arrays\n * expanded in-place recursively.\n *\n * @param {...*} var_args The values to flatten.\n * @return {!Array<?>} An array containing the flattened values.\n */\ngoog.array.flatten = function(var_args) {\n  var CHUNK_SIZE = 8192;\n\n  var result = [];\n  for (var i = 0; i < arguments.length; i++) {\n    var element = arguments[i];\n    if (Array.isArray(element)) {\n      for (var c = 0; c < element.length; c += CHUNK_SIZE) {\n        var chunk = goog.array.slice(element, c, c + CHUNK_SIZE);\n        var recurseResult = goog.array.flatten.apply(null, chunk);\n        for (var r = 0; r < recurseResult.length; r++) {\n          result.push(recurseResult[r]);\n        }\n      }\n    } else {\n      result.push(element);\n    }\n  }\n  return result;\n};\n\n\n/**\n * Rotates an array in-place. After calling this method, the element at\n * index i will be the element previously at index (i - n) %\n * array.length, for all values of i between 0 and array.length - 1,\n * inclusive.\n *\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\n *\n * @param {!Array<T>} array The array to rotate.\n * @param {number} n The amount to rotate.\n * @return {!Array<T>} The array.\n * @template T\n */\ngoog.array.rotate = function(array, n) {\n  goog.asserts.assert(array.length != null);\n\n  if (array.length) {\n    n %= array.length;\n    if (n > 0) {\n      Array.prototype.unshift.apply(array, array.splice(-n, n));\n    } else if (n < 0) {\n      Array.prototype.push.apply(array, array.splice(0, -n));\n    }\n  }\n  return array;\n};\n\n\n/**\n * Moves one item of an array to a new position keeping the order of the rest\n * of the items. Example use case: keeping a list of JavaScript objects\n * synchronized with the corresponding list of DOM elements after one of the\n * elements has been dragged to a new position.\n * @param {!IArrayLike<?>} arr The array to modify.\n * @param {number} fromIndex Index of the item to move between 0 and\n *     {@code arr.length - 1}.\n * @param {number} toIndex Target index between 0 and {@code arr.length - 1}.\n */\ngoog.array.moveItem = function(arr, fromIndex, toIndex) {\n  goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n  goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);\n  // Remove 1 item at fromIndex.\n  var removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n  // Insert the removed item at toIndex.\n  Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n  // We don't use goog.array.insertAt and goog.array.removeAt, because they're\n  // significantly slower than splice.\n};\n\n\n/**\n * Creates a new array for which the element at position i is an array of the\n * ith element of the provided arrays.  The returned array will only be as long\n * as the shortest array provided; additional values are ignored.  For example,\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\n *\n * This is similar to the zip() function in Python.  See {@link\n * http://docs.python.org/library/functions.html#zip}\n *\n * @param {...!IArrayLike<?>} var_args Arrays to be combined.\n * @return {!Array<!Array<?>>} A new array of arrays created from\n *     provided arrays.\n */\ngoog.array.zip = function(var_args) {\n  if (!arguments.length) {\n    return [];\n  }\n  var result = [];\n  var minLen = arguments[0].length;\n  for (var i = 1; i < arguments.length; i++) {\n    if (arguments[i].length < minLen) {\n      minLen = arguments[i].length;\n    }\n  }\n  for (var i = 0; i < minLen; i++) {\n    var value = [];\n    for (var j = 0; j < arguments.length; j++) {\n      value.push(arguments[j][i]);\n    }\n    result.push(value);\n  }\n  return result;\n};\n\n\n/**\n * Shuffles the values in the specified array using the Fisher-Yates in-place\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\n * and so resets the state of that random number generator. Similarly, may reset\n * the state of any other specified random number generator.\n *\n * Runtime: O(n)\n *\n * @param {!Array<?>} arr The array to be shuffled.\n * @param {function():number=} opt_randFn Optional random function to use for\n *     shuffling.\n *     Takes no arguments, and returns a random number on the interval [0, 1).\n *     Defaults to Math.random() using JavaScript's built-in Math library.\n */\ngoog.array.shuffle = function(arr, opt_randFn) {\n  var randFn = opt_randFn || Math.random;\n\n  for (var i = arr.length - 1; i > 0; i--) {\n    // Choose a random array index in [0, i] (inclusive with i).\n    var j = Math.floor(randFn() * (i + 1));\n\n    var tmp = arr[i];\n    arr[i] = arr[j];\n    arr[j] = tmp;\n  }\n};\n\n\n/**\n * Returns a new array of elements from arr, based on the indexes of elements\n * provided by index_arr. For example, the result of index copying\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\n *\n * @param {!IArrayLike<T>} arr The array to get a indexed copy from.\n * @param {!IArrayLike<number>} index_arr An array of indexes to get from arr.\n * @return {!Array<T>} A new array of elements from arr in index_arr order.\n * @template T\n */\ngoog.array.copyByIndex = function(arr, index_arr) {\n  var result = [];\n  goog.array.forEach(index_arr, function(index) { result.push(arr[index]); });\n  return result;\n};\n\n\n/**\n * Maps each element of the input array into zero or more elements of the output\n * array.\n *\n * @param {!IArrayLike<VALUE>|string} arr Array or array like object\n *     over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): !Array<RESULT>} f The function\n *     to call for every element. This function takes 3 arguments (the element,\n *     the index and the array) and should return an array. The result will be\n *     used to extend a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the concatenation of all arrays\n *     returned from f.\n * @template THIS, VALUE, RESULT\n */\ngoog.array.concatMap = function(arr, f, opt_obj) {\n  return goog.array.concat.apply([], goog.array.map(arr, f, opt_obj));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview String functions called from Closure packages that couldn't\n * depend on each other. Outside Closure, use goog.string function which\n * delegate to these.\n */\n\n\ngoog.provide('goog.string.internal');\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n * @see goog.string.startsWith\n */\ngoog.string.internal.startsWith = function(str, prefix) {\n  return str.lastIndexOf(prefix, 0) == 0;\n};\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n * @see goog.string.endsWith\n */\ngoog.string.internal.endsWith = function(str, suffix) {\n  const l = str.length - suffix.length;\n  return l >= 0 && str.indexOf(suffix, l) == l;\n};\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix  A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n *     case).\n * @see goog.string.caseInsensitiveStartsWith\n */\ngoog.string.internal.caseInsensitiveStartsWith = function(str, prefix) {\n  return goog.string.internal.caseInsensitiveCompare(\n             prefix, str.substr(0, prefix.length)) == 0;\n};\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n *     case).\n * @see goog.string.caseInsensitiveEndsWith\n */\ngoog.string.internal.caseInsensitiveEndsWith = function(str, suffix) {\n  return (\n      goog.string.internal.caseInsensitiveCompare(\n          suffix, str.substr(str.length - suffix.length, suffix.length)) == 0);\n};\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n *     ignoring case.\n * @see goog.string.caseInsensitiveEquals\n */\ngoog.string.internal.caseInsensitiveEquals = function(str1, str2) {\n  return str1.toLowerCase() == str2.toLowerCase();\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @see goog.string.isEmptyOrWhitespace\n */\ngoog.string.internal.isEmptyOrWhitespace = function(str) {\n  // testing length == 0 first is actually slower in all browsers (about the\n  // same in Opera).\n  // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n  // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n  // include it in the regexp to enforce consistent cross-browser behavior.\n  return /^[\\s\\xa0]*$/.test(str);\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.internal.trim =\n    (goog.TRUSTED_SITE && String.prototype.trim) ? function(str) {\n      return str.trim();\n    } : function(str) {\n      // Since IE doesn't include non-breaking-space (0xa0) in their \\s\n      // character class (as required by section 7.2 of the ECMAScript spec),\n      // we explicitly include it in the regexp to enforce consistent\n      // cross-browser behavior.\n      // NOTE: We don't use String#replace because it might have side effects\n      // causing this function to not compile to 0 bytes.\n      return /^[\\s\\xa0]*([\\s\\S]*?)[\\s\\xa0]*$/.exec(str)[1];\n    };\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n *  0 = str1 equals str2\n *  1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n * @see goog.string.caseInsensitiveCompare\n */\ngoog.string.internal.caseInsensitiveCompare = function(str1, str2) {\n  const test1 = String(str1).toLowerCase();\n  const test2 = String(str2).toLowerCase();\n\n  if (test1 < test2) {\n    return -1;\n  } else if (test1 == test2) {\n    return 0;\n  } else {\n    return 1;\n  }\n};\n\n\n/**\n * Converts \\n to <br>s or <br />s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n * @see goog.string.newLineToBr\n */\ngoog.string.internal.newLineToBr = function(str, opt_xml) {\n  return str.replace(/(\\r\\n|\\r|\\n)/g, opt_xml ? '<br />' : '<br>');\n};\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars\n * @return {string} An escaped copy of `str`.\n * @see goog.string.htmlEscape\n */\ngoog.string.internal.htmlEscape = function(\n    str, opt_isLikelyToContainHtmlChars) {\n  if (opt_isLikelyToContainHtmlChars) {\n    str = str.replace(goog.string.internal.AMP_RE_, '&amp;')\n              .replace(goog.string.internal.LT_RE_, '&lt;')\n              .replace(goog.string.internal.GT_RE_, '&gt;')\n              .replace(goog.string.internal.QUOT_RE_, '&quot;')\n              .replace(goog.string.internal.SINGLE_QUOTE_RE_, '&#39;')\n              .replace(goog.string.internal.NULL_RE_, '&#0;');\n    return str;\n\n  } else {\n    // quick test helps in the case when there are no chars to replace, in\n    // worst case this makes barely a difference to the time taken\n    if (!goog.string.internal.ALL_RE_.test(str)) return str;\n\n    // str.indexOf is faster than regex.test in this case\n    if (str.indexOf('&') != -1) {\n      str = str.replace(goog.string.internal.AMP_RE_, '&amp;');\n    }\n    if (str.indexOf('<') != -1) {\n      str = str.replace(goog.string.internal.LT_RE_, '&lt;');\n    }\n    if (str.indexOf('>') != -1) {\n      str = str.replace(goog.string.internal.GT_RE_, '&gt;');\n    }\n    if (str.indexOf('\"') != -1) {\n      str = str.replace(goog.string.internal.QUOT_RE_, '&quot;');\n    }\n    if (str.indexOf('\\'') != -1) {\n      str = str.replace(goog.string.internal.SINGLE_QUOTE_RE_, '&#39;');\n    }\n    if (str.indexOf('\\x00') != -1) {\n      str = str.replace(goog.string.internal.NULL_RE_, '&#0;');\n    }\n    return str;\n  }\n};\n\n\n/**\n * Regular expression that matches an ampersand, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.AMP_RE_ = /&/g;\n\n\n/**\n * Regular expression that matches a less than sign, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.LT_RE_ = /</g;\n\n\n/**\n * Regular expression that matches a greater than sign, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.GT_RE_ = />/g;\n\n\n/**\n * Regular expression that matches a double quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.QUOT_RE_ = /\"/g;\n\n\n/**\n * Regular expression that matches a single quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.SINGLE_QUOTE_RE_ = /'/g;\n\n\n/**\n * Regular expression that matches null character, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.NULL_RE_ = /\\x00/g;\n\n\n/**\n * Regular expression that matches any character that needs to be escaped.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.ALL_RE_ = /[\\x00&<>\"']/;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n * @see goog.string.whitespaceEscape\n */\ngoog.string.internal.whitespaceEscape = function(str, opt_xml) {\n  // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n  return goog.string.internal.newLineToBr(\n      str.replace(/  /g, ' &#160;'), opt_xml);\n};\n\n\n/**\n * Determines whether a string contains a substring.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.contains\n */\ngoog.string.internal.contains = function(str, subString) {\n  return str.indexOf(subString) != -1;\n};\n\n\n/**\n * Determines whether a string contains a substring, ignoring case.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.caseInsensitiveContains\n */\ngoog.string.internal.caseInsensitiveContains = function(str, subString) {\n  return goog.string.internal.contains(\n      str.toLowerCase(), subString.toLowerCase());\n};\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string|number} version1 Version of first item.\n * @param {string|number} version2 Version of second item.\n *\n * @return {number}  1 if `version1` is higher.\n *                   0 if arguments are equal.\n *                  -1 if `version2` is higher.\n * @see goog.string.compareVersions\n */\ngoog.string.internal.compareVersions = function(version1, version2) {\n  let order = 0;\n  // Trim leading and trailing whitespace and split the versions into\n  // subversions.\n  const v1Subs = goog.string.internal.trim(String(version1)).split('.');\n  const v2Subs = goog.string.internal.trim(String(version2)).split('.');\n  const subCount = Math.max(v1Subs.length, v2Subs.length);\n\n  // Iterate over the subversions, as long as they appear to be equivalent.\n  for (let subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {\n    let v1Sub = v1Subs[subIdx] || '';\n    let v2Sub = v2Subs[subIdx] || '';\n\n    do {\n      // Split the subversions into pairs of numbers and qualifiers (like 'b').\n      // Two different RegExp objects are use to make it clear the code\n      // is side-effect free\n      const v1Comp = /(\\d*)(\\D*)(.*)/.exec(v1Sub) || ['', '', '', ''];\n      const v2Comp = /(\\d*)(\\D*)(.*)/.exec(v2Sub) || ['', '', '', ''];\n      // Break if there are no more matches.\n      if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {\n        break;\n      }\n\n      // Parse the numeric part of the subversion. A missing number is\n      // equivalent to 0.\n      const v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);\n      const v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);\n\n      // Compare the subversion components. The number has the highest\n      // precedence. Next, if the numbers are equal, a subversion without any\n      // qualifier is always higher than a subversion with any qualifier. Next,\n      // the qualifiers are compared as strings.\n      order = goog.string.internal.compareElements_(v1CompNum, v2CompNum) ||\n          goog.string.internal.compareElements_(\n              v1Comp[2].length == 0, v2Comp[2].length == 0) ||\n          goog.string.internal.compareElements_(v1Comp[2], v2Comp[2]);\n      // Stop as soon as an inequality is discovered.\n\n      v1Sub = v1Comp[3];\n      v2Sub = v2Comp[3];\n    } while (order == 0);\n  }\n\n  return order;\n};\n\n\n/**\n * Compares elements of a version number.\n *\n * @param {string|number|boolean} left An element from a version number.\n * @param {string|number|boolean} right An element from a version number.\n *\n * @return {number}  1 if `left` is higher.\n *                   0 if arguments are equal.\n *                  -1 if `right` is higher.\n * @private\n */\ngoog.string.internal.compareElements_ = function(left, right) {\n  if (left < right) {\n    return -1;\n  } else if (left > right) {\n    return 1;\n  }\n  return 0;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities used by goog.labs.userAgent tools. These functions\n * should not be used outside of goog.labs.userAgent.*.\n *\n */\n\ngoog.provide('goog.labs.userAgent.util');\n\ngoog.require('goog.string.internal');\n\n\n/**\n * Gets the native userAgent string from navigator if it exists.\n * If navigator or navigator.userAgent string is missing, returns an empty\n * string.\n * @return {string}\n * @private\n */\ngoog.labs.userAgent.util.getNativeUserAgentString_ = function() {\n  var navigator = goog.labs.userAgent.util.getNavigator_();\n  if (navigator) {\n    var userAgent = navigator.userAgent;\n    if (userAgent) {\n      return userAgent;\n    }\n  }\n  return '';\n};\n\n\n/**\n * Getter for the native navigator.\n * This is a separate function so it can be stubbed out in testing.\n * @return {!Navigator}\n * @private\n */\ngoog.labs.userAgent.util.getNavigator_ = function() {\n  return goog.global.navigator;\n};\n\n\n/**\n * A possible override for applications which wish to not check\n * navigator.userAgent but use a specified value for detection instead.\n * @private {string}\n */\ngoog.labs.userAgent.util.userAgent_ =\n    goog.labs.userAgent.util.getNativeUserAgentString_();\n\n\n/**\n * Applications may override browser detection on the built in\n * navigator.userAgent object by setting this string. Set to null to use the\n * browser object instead.\n * @param {?string=} opt_userAgent The User-Agent override.\n */\ngoog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {\n  goog.labs.userAgent.util.userAgent_ =\n      opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();\n};\n\n\n/**\n * @return {string} The user agent string.\n */\ngoog.labs.userAgent.util.getUserAgent = function() {\n  return goog.labs.userAgent.util.userAgent_;\n};\n\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string.\n */\ngoog.labs.userAgent.util.matchUserAgent = function(str) {\n  var userAgent = goog.labs.userAgent.util.getUserAgent();\n  return goog.string.internal.contains(userAgent, str);\n};\n\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string, ignoring\n *     case.\n */\ngoog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {\n  var userAgent = goog.labs.userAgent.util.getUserAgent();\n  return goog.string.internal.caseInsensitiveContains(userAgent, str);\n};\n\n\n/**\n * Parses the user agent into tuples for each section.\n * @param {string} userAgent\n * @return {!Array<!Array<string>>} Tuples of key, version, and the contents\n *     of the parenthetical.\n */\ngoog.labs.userAgent.util.extractVersionTuples = function(userAgent) {\n  // Matches each section of a user agent string.\n  // Example UA:\n  // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)\n  // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405\n  // This has three version tuples: Mozilla, AppleWebKit, and Mobile.\n\n  var versionRegExp = new RegExp(\n      // Key. Note that a key may have a space.\n      // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')\n      '(\\\\w[\\\\w ]+)' +\n\n          '/' +                // slash\n          '([^\\\\s]+)' +        // version (i.e. '5.0b')\n          '\\\\s*' +             // whitespace\n          '(?:\\\\((.*?)\\\\))?',  // parenthetical info. parentheses not matched.\n      'g');\n\n  var data = [];\n  var match;\n\n  // Iterate and collect the version tuples.  Each iteration will be the\n  // next regex match.\n  while (match = versionRegExp.exec(userAgent)) {\n    data.push([\n      match[1],  // key\n      match[2],  // value\n      // || undefined as this is not undefined in IE7 and IE8\n      match[3] || undefined  // info\n    ]);\n  }\n\n  return data;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating objects/maps/hashes.\n */\n\ngoog.provide('goog.object');\n\n\n/**\n * Calls a function for each element in an object/map/hash.\n *\n * @param {Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,Object<K,V>):?} f The function to call\n *     for every element. This function takes 3 arguments (the value, the\n *     key and the object) and the return value is ignored.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @template T,K,V\n */\ngoog.object.forEach = function(obj, f, opt_obj) {\n  for (const key in obj) {\n    f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);\n  }\n};\n\n\n/**\n * Calls a function for each element in an object/map/hash. If that call returns\n * true, adds the element to a new object.\n *\n * @param {Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to call\n *     for every element. This\n *     function takes 3 arguments (the value, the key and the object)\n *     and should return a boolean. If the return value is true the\n *     element is added to the result object. If it is false the\n *     element is not included.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {!Object<K,V>} a new object in which only elements that passed the\n *     test are present.\n * @template T,K,V\n */\ngoog.object.filter = function(obj, f, opt_obj) {\n  const res = {};\n  for (const key in obj) {\n    if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n      res[key] = obj[key];\n    }\n  }\n  return res;\n};\n\n\n/**\n * For every element in an object/map/hash calls a function and inserts the\n * result into a new object.\n *\n * @param {Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,Object<K,V>):R} f The function to call\n *     for every element. This function\n *     takes 3 arguments (the value, the key and the object)\n *     and should return something. The result will be inserted\n *     into a new object.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {!Object<K,R>} a new object with the results from f.\n * @template T,K,V,R\n */\ngoog.object.map = function(obj, f, opt_obj) {\n  const res = {};\n  for (const key in obj) {\n    res[key] = f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);\n  }\n  return res;\n};\n\n\n/**\n * Calls a function for each element in an object/map/hash. If any\n * call returns true, returns true (without checking the rest). If\n * all calls return false, returns false.\n *\n * @param {Object<K,V>} obj The object to check.\n * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to\n *     call for every element. This function\n *     takes 3 arguments (the value, the key and the object) and should\n *     return a boolean.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {boolean} true if any element passes the test.\n * @template T,K,V\n */\ngoog.object.some = function(obj, f, opt_obj) {\n  for (const key in obj) {\n    if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Calls a function for each element in an object/map/hash. If\n * all calls return true, returns true. If any call returns false, returns\n * false at this point and does not continue to check the remaining elements.\n *\n * @param {Object<K,V>} obj The object to check.\n * @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to\n *     call for every element. This function\n *     takes 3 arguments (the value, the key and the object) and should\n *     return a boolean.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {boolean} false if any element fails the test.\n * @template T,K,V\n */\ngoog.object.every = function(obj, f, opt_obj) {\n  for (const key in obj) {\n    if (!f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * Returns the number of key-value pairs in the object map.\n *\n * @param {Object} obj The object for which to get the number of key-value\n *     pairs.\n * @return {number} The number of key-value pairs in the object map.\n */\ngoog.object.getCount = function(obj) {\n  let rv = 0;\n  for (const key in obj) {\n    rv++;\n  }\n  return rv;\n};\n\n\n/**\n * Returns one key from the object map, if any exists.\n * For map literals the returned key will be the first one in most of the\n * browsers (a know exception is Konqueror).\n *\n * @param {Object} obj The object to pick a key from.\n * @return {string|undefined} The key or undefined if the object is empty.\n */\ngoog.object.getAnyKey = function(obj) {\n  for (const key in obj) {\n    return key;\n  }\n};\n\n\n/**\n * Returns one value from the object map, if any exists.\n * For map literals the returned value will be the first one in most of the\n * browsers (a know exception is Konqueror).\n *\n * @param {Object<K,V>} obj The object to pick a value from.\n * @return {V|undefined} The value or undefined if the object is empty.\n * @template K,V\n */\ngoog.object.getAnyValue = function(obj) {\n  for (const key in obj) {\n    return obj[key];\n  }\n};\n\n\n/**\n * Whether the object/hash/map contains the given object as a value.\n * An alias for goog.object.containsValue(obj, val).\n *\n * @param {Object<K,V>} obj The object in which to look for val.\n * @param {V} val The object for which to check.\n * @return {boolean} true if val is present.\n * @template K,V\n */\ngoog.object.contains = function(obj, val) {\n  return goog.object.containsValue(obj, val);\n};\n\n\n/**\n * Returns the values of the object/map/hash.\n *\n * @param {Object<K,V>} obj The object from which to get the values.\n * @return {!Array<V>} The values in the object/map/hash.\n * @template K,V\n */\ngoog.object.getValues = function(obj) {\n  const res = [];\n  let i = 0;\n  for (const key in obj) {\n    res[i++] = obj[key];\n  }\n  return res;\n};\n\n\n/**\n * Returns the keys of the object/map/hash.\n *\n * @param {Object} obj The object from which to get the keys.\n * @return {!Array<string>} Array of property keys.\n */\ngoog.object.getKeys = function(obj) {\n  const res = [];\n  let i = 0;\n  for (const key in obj) {\n    res[i++] = key;\n  }\n  return res;\n};\n\n\n/**\n * Get a value from an object multiple levels deep.  This is useful for\n * pulling values from deeply nested objects, such as JSON responses.\n * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)\n *\n * @param {!Object} obj An object to get the value from.  Can be array-like.\n * @param {...(string|number|!IArrayLike<number|string>)}\n *     var_args A number of keys\n *     (as strings, or numbers, for array-like objects).  Can also be\n *     specified as a single array of keys.\n * @return {*} The resulting value.  If, at any point, the value for a key\n *     in the current object is null or undefined, returns undefined.\n */\ngoog.object.getValueByKeys = function(obj, var_args) {\n  const isArrayLike = goog.isArrayLike(var_args);\n  const keys = isArrayLike ?\n      /** @type {!IArrayLike<number|string>} */ (var_args) :\n      arguments;\n\n  // Start with the 2nd parameter for the variable parameters syntax.\n  for (let i = isArrayLike ? 0 : 1; i < keys.length; i++) {\n    if (obj == null) return undefined;\n    obj = obj[keys[i]];\n  }\n\n  return obj;\n};\n\n\n/**\n * Whether the object/map/hash contains the given key.\n *\n * @param {Object} obj The object in which to look for key.\n * @param {?} key The key for which to check.\n * @return {boolean} true If the map contains the key.\n */\ngoog.object.containsKey = function(obj, key) {\n  return obj !== null && key in obj;\n};\n\n\n/**\n * Whether the object/map/hash contains the given value. This is O(n).\n *\n * @param {Object<K,V>} obj The object in which to look for val.\n * @param {V} val The value for which to check.\n * @return {boolean} true If the map contains the value.\n * @template K,V\n */\ngoog.object.containsValue = function(obj, val) {\n  for (const key in obj) {\n    if (obj[key] == val) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Searches an object for an element that satisfies the given condition and\n * returns its key.\n * @param {Object<K,V>} obj The object to search in.\n * @param {function(this:T,V,string,Object<K,V>):boolean} f The\n *      function to call for every element. Takes 3 arguments (the value,\n *     the key and the object) and should return a boolean.\n * @param {T=} opt_this An optional \"this\" context for the function.\n * @return {string|undefined} The key of an element for which the function\n *     returns true or undefined if no such element is found.\n * @template T,K,V\n */\ngoog.object.findKey = function(obj, f, opt_this) {\n  for (const key in obj) {\n    if (f.call(/** @type {?} */ (opt_this), obj[key], key, obj)) {\n      return key;\n    }\n  }\n  return undefined;\n};\n\n\n/**\n * Searches an object for an element that satisfies the given condition and\n * returns its value.\n * @param {Object<K,V>} obj The object to search in.\n * @param {function(this:T,V,string,Object<K,V>):boolean} f The function\n *     to call for every element. Takes 3 arguments (the value, the key\n *     and the object) and should return a boolean.\n * @param {T=} opt_this An optional \"this\" context for the function.\n * @return {V} The value of an element for which the function returns true or\n *     undefined if no such element is found.\n * @template T,K,V\n */\ngoog.object.findValue = function(obj, f, opt_this) {\n  const key = goog.object.findKey(obj, f, opt_this);\n  return key && obj[key];\n};\n\n\n/**\n * Whether the object/map/hash is empty.\n *\n * @param {Object} obj The object to test.\n * @return {boolean} true if obj is empty.\n */\ngoog.object.isEmpty = function(obj) {\n  for (const key in obj) {\n    return false;\n  }\n  return true;\n};\n\n\n/**\n * Removes all key value pairs from the object/map/hash.\n *\n * @param {Object} obj The object to clear.\n */\ngoog.object.clear = function(obj) {\n  for (const i in obj) {\n    delete obj[i];\n  }\n};\n\n\n/**\n * Removes a key-value pair based on the key.\n *\n * @param {Object} obj The object from which to remove the key.\n * @param {?} key The key to remove.\n * @return {boolean} Whether an element was removed.\n */\ngoog.object.remove = function(obj, key) {\n  let rv;\n  if (rv = key in /** @type {!Object} */ (obj)) {\n    delete obj[key];\n  }\n  return rv;\n};\n\n\n/**\n * Adds a key-value pair to the object. Throws an exception if the key is\n * already in use. Use set if you want to change an existing pair.\n *\n * @param {Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} val The value to add.\n * @template K,V\n */\ngoog.object.add = function(obj, key, val) {\n  if (obj !== null && key in obj) {\n    throw new Error('The object already contains the key \"' + key + '\"');\n  }\n  goog.object.set(obj, key, val);\n};\n\n\n/**\n * Returns the value for the given key.\n *\n * @param {Object<K,V>} obj The object from which to get the value.\n * @param {string} key The key for which to get the value.\n * @param {R=} opt_val The value to return if no item is found for the given\n *     key (default is undefined).\n * @return {V|R|undefined} The value for the given key.\n * @template K,V,R\n */\ngoog.object.get = function(obj, key, opt_val) {\n  if (obj !== null && key in obj) {\n    return obj[key];\n  }\n  return opt_val;\n};\n\n\n/**\n * Adds a key-value pair to the object/map/hash.\n *\n * @param {Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} value The value to add.\n * @template K,V\n */\ngoog.object.set = function(obj, key, value) {\n  obj[key] = value;\n};\n\n\n/**\n * Adds a key-value pair to the object/map/hash if it doesn't exist yet.\n *\n * @param {Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} value The value to add if the key wasn't present.\n * @return {V} The value of the entry at the end of the function.\n * @template K,V\n */\ngoog.object.setIfUndefined = function(obj, key, value) {\n  return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value);\n};\n\n\n/**\n * Sets a key and value to an object if the key is not set. The value will be\n * the return value of the given function. If the key already exists, the\n * object will not be changed and the function will not be called (the function\n * will be lazily evaluated -- only called if necessary).\n *\n * This function is particularly useful when used with an `Object` which is\n * acting as a cache.\n *\n * @param {!Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {function():V} f The value to add if the key wasn't present.\n * @return {V} The value of the entry at the end of the function.\n * @template K,V\n */\ngoog.object.setWithReturnValueIfNotSet = function(obj, key, f) {\n  if (key in obj) {\n    return obj[key];\n  }\n\n  const val = f();\n  obj[key] = val;\n  return val;\n};\n\n\n/**\n * Compares two objects for equality using === on the values.\n *\n * @param {!Object<K,V>} a\n * @param {!Object<K,V>} b\n * @return {boolean}\n * @template K,V\n */\ngoog.object.equals = function(a, b) {\n  for (const k in a) {\n    if (!(k in b) || a[k] !== b[k]) {\n      return false;\n    }\n  }\n  for (const k in b) {\n    if (!(k in a)) {\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * Returns a shallow clone of the object.\n *\n * @param {Object<K,V>} obj Object to clone.\n * @return {!Object<K,V>} Clone of the input object.\n * @template K,V\n */\ngoog.object.clone = function(obj) {\n  const res = {};\n  for (const key in obj) {\n    res[key] = obj[key];\n  }\n  return res;\n};\n\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n *\n * WARNINGS:\n * <code>goog.object.unsafeClone</code> does not detect reference loops. Objects\n * that refer to themselves will cause infinite recursion.\n *\n * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and\n * copies UIDs created by <code>getUid</code> into cloned results.\n *\n * @param {T} obj The value to clone.\n * @return {T} A clone of the input value.\n * @template T\n */\ngoog.object.unsafeClone = function(obj) {\n  const type = goog.typeOf(obj);\n  if (type == 'object' || type == 'array') {\n    if (goog.isFunction(obj.clone)) {\n      return obj.clone();\n    }\n    const clone = type == 'array' ? [] : {};\n    for (const key in obj) {\n      clone[key] = goog.object.unsafeClone(obj[key]);\n    }\n    return clone;\n  }\n\n  return obj;\n};\n\n\n/**\n * Returns a new object in which all the keys and values are interchanged\n * (keys become values and values become keys). If multiple keys map to the\n * same value, the chosen transposed value is implementation-dependent.\n *\n * @param {Object} obj The object to transpose.\n * @return {!Object} The transposed object.\n */\ngoog.object.transpose = function(obj) {\n  const transposed = {};\n  for (const key in obj) {\n    transposed[obj[key]] = key;\n  }\n  return transposed;\n};\n\n\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {Array<string>}\n * @private\n */\ngoog.object.PROTOTYPE_FIELDS_ = [\n  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n  'toLocaleString', 'toString', 'valueOf'\n];\n\n\n/**\n * Extends an object with another object.\n * This operates 'in-place'; it does not create a new Object.\n *\n * Example:\n * var o = {};\n * goog.object.extend(o, {a: 0, b: 1});\n * o; // {a: 0, b: 1}\n * goog.object.extend(o, {b: 2, c: 3});\n * o; // {a: 0, b: 2, c: 3}\n *\n * @param {Object} target The object to modify. Existing properties will be\n *     overwritten if they are also present in one of the objects in\n *     `var_args`.\n * @param {...(Object|null|undefined)} var_args The objects from which values\n *     will be copied.\n * @deprecated Prefer Object.assign\n */\ngoog.object.extend = function(target, var_args) {\n  let key;\n  let source;\n  for (let i = 1; i < arguments.length; i++) {\n    source = arguments[i];\n    for (key in source) {\n      target[key] = source[key];\n    }\n\n    // For IE the for-in-loop does not contain any properties that are not\n    // enumerable on the prototype object (for example isPrototypeOf from\n    // Object.prototype) and it will also not include 'replace' on objects that\n    // extend String and change 'replace' (not that it is common for anyone to\n    // extend anything except Object).\n\n    for (let j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {\n      key = goog.object.PROTOTYPE_FIELDS_[j];\n      if (Object.prototype.hasOwnProperty.call(source, key)) {\n        target[key] = source[key];\n      }\n    }\n  }\n};\n\n\n/**\n * Creates a new object built from the key-value pairs provided as arguments.\n * @param {...*} var_args If only one argument is provided and it is an array\n *     then this is used as the arguments, otherwise even arguments are used as\n *     the property names and odd arguments are used as the property values.\n * @return {!Object} The new object.\n * @throws {Error} If there are uneven number of arguments or there is only one\n *     non array argument.\n */\ngoog.object.create = function(var_args) {\n  const argLength = arguments.length;\n  if (argLength == 1 && Array.isArray(arguments[0])) {\n    return goog.object.create.apply(null, arguments[0]);\n  }\n\n  if (argLength % 2) {\n    throw new Error('Uneven number of arguments');\n  }\n\n  const rv = {};\n  for (let i = 0; i < argLength; i += 2) {\n    rv[arguments[i]] = arguments[i + 1];\n  }\n  return rv;\n};\n\n\n/**\n * Creates a new object where the property names come from the arguments but\n * the value is always set to true\n * @param {...*} var_args If only one argument is provided and it is an array\n *     then this is used as the arguments, otherwise the arguments are used\n *     as the property names.\n * @return {!Object} The new object.\n */\ngoog.object.createSet = function(var_args) {\n  const argLength = arguments.length;\n  if (argLength == 1 && Array.isArray(arguments[0])) {\n    return goog.object.createSet.apply(null, arguments[0]);\n  }\n\n  const rv = {};\n  for (let i = 0; i < argLength; i++) {\n    rv[arguments[i]] = true;\n  }\n  return rv;\n};\n\n\n/**\n * Creates an immutable view of the underlying object, if the browser\n * supports immutable objects.\n *\n * In default mode, writes to this view will fail silently. In strict mode,\n * they will throw an error.\n *\n * @param {!Object<K,V>} obj An object.\n * @return {!Object<K,V>} An immutable view of that object, or the\n *     original object if this browser does not support immutables.\n * @template K,V\n */\ngoog.object.createImmutableView = function(obj) {\n  let result = obj;\n  if (Object.isFrozen && !Object.isFrozen(obj)) {\n    result = Object.create(obj);\n    Object.freeze(result);\n  }\n  return result;\n};\n\n\n/**\n * @param {!Object} obj An object.\n * @return {boolean} Whether this is an immutable view of the object.\n */\ngoog.object.isImmutableView = function(obj) {\n  return !!Object.isFrozen && Object.isFrozen(obj);\n};\n\n\n/**\n * Get all properties names on a given Object regardless of enumerability.\n *\n * <p> If the browser does not support `Object.getOwnPropertyNames` nor\n * `Object.getPrototypeOf` then this is equivalent to using\n * `goog.object.getKeys`\n *\n * @param {?Object} obj The object to get the properties of.\n * @param {boolean=} opt_includeObjectPrototype Whether properties defined on\n *     `Object.prototype` should be included in the result.\n * @param {boolean=} opt_includeFunctionPrototype Whether properties defined on\n *     `Function.prototype` should be included in the result.\n * @return {!Array<string>}\n * @public\n */\ngoog.object.getAllPropertyNames = function(\n    obj, opt_includeObjectPrototype, opt_includeFunctionPrototype) {\n  if (!obj) {\n    return [];\n  }\n\n  // Naively use a for..in loop to get the property names if the browser doesn't\n  // support any other APIs for getting it.\n  if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {\n    return goog.object.getKeys(obj);\n  }\n\n  const visitedSet = {};\n\n  // Traverse the prototype chain and add all properties to the visited set.\n  let proto = obj;\n  while (proto &&\n         (proto !== Object.prototype || !!opt_includeObjectPrototype) &&\n         (proto !== Function.prototype || !!opt_includeFunctionPrototype)) {\n    const names = Object.getOwnPropertyNames(proto);\n    for (let i = 0; i < names.length; i++) {\n      visitedSet[names[i]] = true;\n    }\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return goog.object.getKeys(visitedSet);\n};\n\n\n/**\n * Given a ES5 or ES6 class reference, return its super class / super\n * constructor.\n *\n * This should be used in rare cases where you need to walk up the inheritance\n * tree (this is generally a bad idea). But this work with ES5 and ES6 classes,\n * unlike relying on the superClass_ property.\n *\n * Note: To start walking up the hierarchy from an instance call this with its\n * `constructor` property; e.g. `getSuperClass(instance.constructor)`.\n *\n * @param {function(new: ?)} constructor\n * @return {?Object}\n */\ngoog.object.getSuperClass = function(constructor) {\n  var proto = Object.getPrototypeOf(constructor.prototype);\n  return proto && proto.constructor;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Useful compiler idioms.\n */\n\ngoog.provide('goog.reflect');\n\n\n/**\n * Syntax for object literal casts.\n * @see http://go/jscompiler-renaming\n * @see https://goo.gl/CRs09P\n *\n * Use this if you have an object literal whose keys need to have the same names\n * as the properties of some class even after they are renamed by the compiler.\n *\n * @param {!Function} type Type to cast to.\n * @param {Object} object Object literal to cast.\n * @return {Object} The object literal.\n */\ngoog.reflect.object = function(type, object) {\n  return object;\n};\n\n/**\n * Syntax for renaming property strings.\n * @see http://go/jscompiler-renaming\n * @see https://goo.gl/CRs09P\n *\n * Use this if you have an need to access a property as a string, but want\n * to also have the property renamed by the compiler. In contrast to\n * goog.reflect.object, this method takes an instance of an object.\n *\n * Properties must be simple names (not qualified names).\n *\n * @param {string} prop Name of the property\n * @param {!Object} object Instance of the object whose type will be used\n *     for renaming\n * @return {string} The renamed property.\n */\ngoog.reflect.objectProperty = function(prop, object) {\n  return prop;\n};\n\n/**\n * To assert to the compiler that an operation is needed when it would\n * otherwise be stripped. For example:\n * <code>\n *     // Force a layout\n *     goog.reflect.sinkValue(dialog.offsetHeight);\n * </code>\n * @param {T} x\n * @return {T}\n * @template T\n */\ngoog.reflect.sinkValue = function(x) {\n  goog.reflect.sinkValue[' '](x);\n  return x;\n};\n\n\n/**\n * The compiler should optimize this function away iff no one ever uses\n * goog.reflect.sinkValue.\n */\ngoog.reflect.sinkValue[' '] = goog.nullFunction;\n\n\n/**\n * Check if a property can be accessed without throwing an exception.\n * @param {Object} obj The owner of the property.\n * @param {string} prop The property name.\n * @return {boolean} Whether the property is accessible. Will also return true\n *     if obj is null.\n */\ngoog.reflect.canAccessProperty = function(obj, prop) {\n\n  try {\n    goog.reflect.sinkValue(obj[prop]);\n    return true;\n  } catch (e) {\n  }\n  return false;\n};\n\n\n/**\n * Retrieves a value from a cache given a key. The compiler provides special\n * consideration for this call such that it is generally considered side-effect\n * free. However, if the `opt_keyFn` or `valueFn` have side-effects\n * then the entire call is considered to have side-effects.\n *\n * Conventionally storing the value on the cache would be considered a\n * side-effect and preclude unused calls from being pruned, ie. even if\n * the value was never used, it would still always be stored in the cache.\n *\n * Providing a side-effect free `valueFn` and `opt_keyFn`\n * allows unused calls to `goog.reflect.cache` to be pruned.\n *\n * @param {!Object<K, V>} cacheObj The object that contains the cached values.\n * @param {?} key The key to lookup in the cache. If it is not string or number\n *     then a `opt_keyFn` should be provided. The key is also used as the\n *     parameter to the `valueFn`.\n * @param {function(?):V} valueFn The value provider to use to calculate the\n *     value to store in the cache. This function should be side-effect free\n *     to take advantage of the optimization.\n * @param {function(?):K=} opt_keyFn The key provider to determine the cache\n *     map key. This should be used if the given key is not a string or number.\n *     If not provided then the given key is used. This function should be\n *     side-effect free to take advantage of the optimization.\n * @return {V} The cached or calculated value.\n * @template K\n * @template V\n */\ngoog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {\n  const storedKey = opt_keyFn ? opt_keyFn(key) : key;\n\n  if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {\n    return cacheObj[storedKey];\n  }\n\n  return (cacheObj[storedKey] = valueFn(key));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Rendering engine detection.\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For information on the browser brand (such as Safari versus Chrome), see\n * goog.userAgent.product.\n * @see ../demos/useragent.html\n */\n\ngoog.provide('goog.userAgent');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.reflect');\ngoog.require('goog.string');\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is IE.\n */\ngoog.userAgent.ASSUME_IE = goog.define('goog.userAgent.ASSUME_IE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is EDGE,\n * referring to EdgeHTML based Edge.\n */\ngoog.userAgent.ASSUME_EDGE = goog.define('goog.userAgent.ASSUME_EDGE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is GECKO.\n */\ngoog.userAgent.ASSUME_GECKO = goog.define('goog.userAgent.ASSUME_GECKO', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is WEBKIT.\n */\ngoog.userAgent.ASSUME_WEBKIT =\n    goog.define('goog.userAgent.ASSUME_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is a\n *     mobile device running WebKit e.g. iPhone or Android.\n */\ngoog.userAgent.ASSUME_MOBILE_WEBKIT =\n    goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is OPERA,\n * referring to Presto-based Opera.\n */\ngoog.userAgent.ASSUME_OPERA = goog.define('goog.userAgent.ASSUME_OPERA', false);\n\n\n/**\n * @define {boolean} Whether the\n *     `goog.userAgent.isVersionOrHigher`\n *     function will return true for any version.\n */\ngoog.userAgent.ASSUME_ANY_VERSION =\n    goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);\n\n\n/**\n * Whether we know the browser engine at compile-time.\n * @type {boolean}\n * @private\n */\ngoog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||\n    goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||\n    goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||\n    goog.userAgent.ASSUME_OPERA;\n\n\n/**\n * Returns the userAgent string for the current browser.\n *\n * @return {string} The userAgent string.\n */\ngoog.userAgent.getUserAgentString = function() {\n  return goog.labs.userAgent.util.getUserAgent();\n};\n\n\n/**\n * @return {?Navigator} The native navigator object.\n */\ngoog.userAgent.getNavigatorTyped = function() {\n  // Need a local navigator reference instead of using the global one,\n  // to avoid the rare case where they reference different objects.\n  // (in a WorkerPool, for example).\n  return goog.global['navigator'] || null;\n};\n\n\n/**\n * TODO(nnaze): Change type to \"Navigator\" and update compilation targets.\n * @return {?Object} The native navigator object.\n */\ngoog.userAgent.getNavigator = function() {\n  return goog.userAgent.getNavigatorTyped();\n};\n\n\n/**\n * Whether the user agent is Presto-based Opera.\n * @type {boolean}\n */\ngoog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_OPERA :\n    goog.labs.userAgent.browser.isOpera();\n\n\n/**\n * Whether the user agent is Internet Explorer.\n * @type {boolean}\n */\ngoog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_IE :\n    goog.labs.userAgent.browser.isIE();\n\n\n/**\n * Whether the user agent is Microsoft Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_EDGE :\n    goog.labs.userAgent.engine.isEdge();\n\n\n/**\n * Whether the user agent is MS Internet Explorer or MS Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;\n\n\n/**\n * Whether the user agent is Gecko. Gecko is the rendering engine used by\n * Mozilla, Firefox, and others.\n * @type {boolean}\n */\ngoog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_GECKO :\n    goog.labs.userAgent.engine.isGecko();\n\n\n/**\n * Whether the user agent is WebKit. WebKit is the rendering engine that\n * Safari, Edge Chromium, Opera Chromium, Android and others use.\n * @type {boolean}\n */\ngoog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?\n    goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :\n    goog.labs.userAgent.engine.isWebKit();\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * This is a separate function so that the logic can be tested.\n *\n * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().\n *\n * @return {boolean} Whether the user agent is running on a mobile device.\n * @private\n */\ngoog.userAgent.isMobile_ = function() {\n  return goog.userAgent.WEBKIT &&\n      goog.labs.userAgent.util.matchUserAgent('Mobile');\n};\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent\n *   is promoted as the gecko/webkit logic is likely inaccurate.\n *\n * @type {boolean}\n */\ngoog.userAgent.MOBILE =\n    goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();\n\n\n/**\n * Used while transitioning code to use WEBKIT instead.\n * @type {boolean}\n * @deprecated Use {@link goog.userAgent.product.SAFARI} instead.\n * TODO(nicksantos): Delete this from goog.userAgent.\n */\ngoog.userAgent.SAFARI = goog.userAgent.WEBKIT;\n\n\n/**\n * @return {string} the platform (operating system) the user agent is running\n *     on. Default to empty string because navigator.platform may not be defined\n *     (on Rhino, for example).\n * @private\n */\ngoog.userAgent.determinePlatform_ = function() {\n  var navigator = goog.userAgent.getNavigatorTyped();\n  return navigator && navigator.platform || '';\n};\n\n\n/**\n * The platform (operating system) the user agent is running on. Default to\n * empty string because navigator.platform may not be defined (on Rhino, for\n * example).\n * @type {string}\n */\ngoog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Macintosh operating\n *     system.\n */\ngoog.userAgent.ASSUME_MAC = goog.define('goog.userAgent.ASSUME_MAC', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Windows operating\n *     system.\n */\ngoog.userAgent.ASSUME_WINDOWS =\n    goog.define('goog.userAgent.ASSUME_WINDOWS', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Linux operating\n *     system.\n */\ngoog.userAgent.ASSUME_LINUX = goog.define('goog.userAgent.ASSUME_LINUX', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a X11 windowing\n *     system.\n */\ngoog.userAgent.ASSUME_X11 = goog.define('goog.userAgent.ASSUME_X11', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on Android.\n */\ngoog.userAgent.ASSUME_ANDROID =\n    goog.define('goog.userAgent.ASSUME_ANDROID', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPhone.\n */\ngoog.userAgent.ASSUME_IPHONE =\n    goog.define('goog.userAgent.ASSUME_IPHONE', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPad.\n */\ngoog.userAgent.ASSUME_IPAD = goog.define('goog.userAgent.ASSUME_IPAD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPod.\n */\ngoog.userAgent.ASSUME_IPOD = goog.define('goog.userAgent.ASSUME_IPOD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on KaiOS.\n */\ngoog.userAgent.ASSUME_KAIOS = goog.define('goog.userAgent.ASSUME_KAIOS', false);\n\n\n/**\n * @type {boolean}\n * @private\n */\ngoog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||\n    goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||\n    goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||\n    goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n    goog.userAgent.ASSUME_IPOD;\n\n\n/**\n * Whether the user agent is running on a Macintosh operating system.\n * @type {boolean}\n */\ngoog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_MAC :\n    goog.labs.userAgent.platform.isMacintosh();\n\n\n/**\n * Whether the user agent is running on a Windows operating system.\n * @type {boolean}\n */\ngoog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_WINDOWS :\n    goog.labs.userAgent.platform.isWindows();\n\n\n/**\n * Whether the user agent is Linux per the legacy behavior of\n * goog.userAgent.LINUX, which considered ChromeOS to also be\n * Linux.\n * @return {boolean}\n * @private\n */\ngoog.userAgent.isLegacyLinux_ = function() {\n  return goog.labs.userAgent.platform.isLinux() ||\n      goog.labs.userAgent.platform.isChromeOS();\n};\n\n\n/**\n * Whether the user agent is running on a Linux operating system.\n *\n * Note that goog.userAgent.LINUX considers ChromeOS to be Linux,\n * while goog.labs.userAgent.platform considers ChromeOS and\n * Linux to be different OSes.\n *\n * @type {boolean}\n */\ngoog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_LINUX :\n    goog.userAgent.isLegacyLinux_();\n\n\n/**\n * @return {boolean} Whether the user agent is an X11 windowing system.\n * @private\n */\ngoog.userAgent.isX11_ = function() {\n  var navigator = goog.userAgent.getNavigatorTyped();\n  return !!navigator &&\n      goog.string.contains(navigator['appVersion'] || '', 'X11');\n};\n\n\n/**\n * Whether the user agent is running on a X11 windowing system.\n * @type {boolean}\n */\ngoog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_X11 :\n    goog.userAgent.isX11_();\n\n\n/**\n * Whether the user agent is running on Android.\n * @type {boolean}\n */\ngoog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_ANDROID :\n    goog.labs.userAgent.platform.isAndroid();\n\n\n/**\n * Whether the user agent is running on an iPhone.\n * @type {boolean}\n */\ngoog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPHONE :\n    goog.labs.userAgent.platform.isIphone();\n\n\n/**\n * Whether the user agent is running on an iPad.\n * @type {boolean}\n */\ngoog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPAD :\n    goog.labs.userAgent.platform.isIpad();\n\n\n/**\n * Whether the user agent is running on an iPod.\n * @type {boolean}\n */\ngoog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_IPOD :\n    goog.labs.userAgent.platform.isIpod();\n\n\n/**\n * Whether the user agent is running on iOS.\n * @type {boolean}\n */\ngoog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ?\n    (goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n     goog.userAgent.ASSUME_IPOD) :\n    goog.labs.userAgent.platform.isIos();\n\n/**\n * Whether the user agent is running on KaiOS.\n * @type {boolean}\n */\ngoog.userAgent.KAIOS = goog.userAgent.PLATFORM_KNOWN_ ?\n    goog.userAgent.ASSUME_KAIOS :\n    goog.labs.userAgent.platform.isKaiOS();\n\n\n/**\n * @return {string} The string that describes the version number of the user\n *     agent.\n * @private\n */\ngoog.userAgent.determineVersion_ = function() {\n  // All browsers have different ways to detect the version and they all have\n  // different naming schemes.\n  // version is a string rather than a number because it may contain 'b', 'a',\n  // and so on.\n  var version = '';\n  var arr = goog.userAgent.getVersionRegexResult_();\n  if (arr) {\n    version = arr ? arr[1] : '';\n  }\n\n  if (goog.userAgent.IE) {\n    // IE9 can be in document mode 9 but be reporting an inconsistent user agent\n    // version.  If it is identifying as a version lower than 9 we take the\n    // documentMode as the version instead.  IE8 has similar behavior.\n    // It is recommended to set the X-UA-Compatible header to ensure that IE9\n    // uses documentMode 9.\n    var docMode = goog.userAgent.getDocumentMode_();\n    if (docMode != null && docMode > parseFloat(version)) {\n      return String(docMode);\n    }\n  }\n\n  return version;\n};\n\n\n/**\n * @return {?IArrayLike<string>|undefined} The version regex matches from\n *     parsing the user\n *     agent string. These regex statements must be executed inline so they can\n *     be compiled out by the closure compiler with the rest of the useragent\n *     detection logic when ASSUME_* is specified.\n * @private\n */\ngoog.userAgent.getVersionRegexResult_ = function() {\n  var userAgent = goog.userAgent.getUserAgentString();\n  if (goog.userAgent.GECKO) {\n    return /rv\\:([^\\);]+)(\\)|;)/.exec(userAgent);\n  }\n  if (goog.userAgent.EDGE) {\n    return /Edge\\/([\\d\\.]+)/.exec(userAgent);\n  }\n  if (goog.userAgent.IE) {\n    return /\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(userAgent);\n  }\n  if (goog.userAgent.WEBKIT) {\n    // WebKit/125.4\n    return /WebKit\\/(\\S+)/.exec(userAgent);\n  }\n  if (goog.userAgent.OPERA) {\n    // If none of the above browsers were detected but the browser is Opera, the\n    // only string that is of interest is 'Version/<number>'.\n    return /(?:Version)[ \\/]?(\\S+)/.exec(userAgent);\n  }\n  return undefined;\n};\n\n\n/**\n * @return {number|undefined} Returns the document mode (for testing).\n * @private\n */\ngoog.userAgent.getDocumentMode_ = function() {\n  // NOTE(user): goog.userAgent may be used in context where there is no DOM.\n  var doc = goog.global['document'];\n  return doc ? doc['documentMode'] : undefined;\n};\n\n\n/**\n * The version of the user agent. This is a string because it might contain\n * 'b' (as in beta) as well as multiple dots.\n * @type {string}\n */\ngoog.userAgent.VERSION = goog.userAgent.determineVersion_();\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string} v1 Version of first item.\n * @param {string} v2 Version of second item.\n *\n * @return {number}  1 if first argument is higher\n *                   0 if arguments are equal\n *                  -1 if second argument is higher.\n * @deprecated Use goog.string.compareVersions.\n */\ngoog.userAgent.compare = function(v1, v2) {\n  return goog.string.compareVersions(v1, v2);\n};\n\n\n/**\n * Cache for {@link goog.userAgent.isVersionOrHigher}.\n * Calls to compareVersions are surprisingly expensive and, as a browser's\n * version number is unlikely to change during a session, we cache the results.\n * @const\n * @private\n */\ngoog.userAgent.isVersionOrHigherCache_ = {};\n\n\n/**\n * Whether the user agent version is higher or the same as the given version.\n * NOTE: When checking the version numbers for Firefox and Safari, be sure to\n * use the engine's version, not the browser's version number.  For example,\n * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.\n * Opera and Internet Explorer versions match the product release number.<br>\n * @see <a href=\"http://en.wikipedia.org/wiki/Safari_version_history\">\n *     Webkit</a>\n * @see <a href=\"http://en.wikipedia.org/wiki/Gecko_engine\">Gecko</a>\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n *     the given version.\n */\ngoog.userAgent.isVersionOrHigher = function(version) {\n  return goog.userAgent.ASSUME_ANY_VERSION ||\n      goog.reflect.cache(\n          goog.userAgent.isVersionOrHigherCache_, version, function() {\n            return goog.string.compareVersions(\n                       goog.userAgent.VERSION, version) >= 0;\n          });\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isVersionOrHigher`.\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n *     the given version.\n * @deprecated Use goog.userAgent.isVersionOrHigher().\n */\ngoog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;\n\n\n/**\n * Whether the IE effective document mode is higher or the same as the given\n * document mode version.\n * NOTE: Only for IE, return false for another browser.\n *\n * @param {number} documentMode The document mode version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n *     same as the given version.\n */\ngoog.userAgent.isDocumentModeOrHigher = function(documentMode) {\n  return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isDocumentModeOrHigher`.\n * @param {number} version The version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n *      same as the given version.\n * @deprecated Use goog.userAgent.isDocumentModeOrHigher().\n */\ngoog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;\n\n\n/**\n * For IE version < 7, documentMode is undefined, so attempt to use the\n * CSS1Compat property to see if we are in standards mode. If we are in\n * standards mode, treat the browser version as the document mode. Otherwise,\n * IE is emulating version 5.\n *\n * NOTE(user): Support for IE < 7 is long gone, so this is now simplified.\n * It returns document.documentMode for IE and undefined for everything else.\n *\n * @type {number|undefined}\n * @const\n */\ngoog.userAgent.DOCUMENT_MODE = (function() {\n  var doc = goog.global['document'];\n  if (!doc || !goog.userAgent.IE) return undefined;\n  // This must be an IE user agent.\n  var documentMode = goog.userAgent.getDocumentMode_();\n  if (documentMode) return documentMode;\n  // The user agent version string begins with the major version.\n  // Parse the major version and truncate anything following.\n  var ieVersion = parseInt(goog.userAgent.VERSION, 10);\n  return ieVersion || undefined;\n})();\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Browser capability checks for the events package.\n */\n\n\ngoog.provide('goog.events.BrowserFeature');\n\ngoog.require('goog.userAgent');\ngoog.scope(function() {\n\n\n\n/**\n * Enum of browser capabilities.\n * @enum {boolean}\n */\ngoog.events.BrowserFeature = {\n  /**\n   * Whether the button attribute of the event is W3C compliant.  False in\n   * Internet Explorer prior to version 9; document-version dependent.\n   */\n  HAS_W3C_BUTTON:\n      !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),\n\n  /**\n   * Whether the browser supports full W3C event model.\n   */\n  HAS_W3C_EVENT_SUPPORT:\n      !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),\n\n  /**\n   * To prevent default in IE7-8 for certain keydown events we need set the\n   * keyCode to -1.\n   */\n  SET_KEY_CODE_TO_PREVENT_DEFAULT:\n      goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),\n\n  /**\n   * Whether the `navigator.onLine` property is supported.\n   */\n  HAS_NAVIGATOR_ONLINE_PROPERTY:\n      !goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher('528'),\n\n  /**\n   * Whether HTML5 network online/offline events are supported.\n   */\n  HAS_HTML5_NETWORK_EVENT_SUPPORT:\n      goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9b') ||\n      goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8') ||\n      goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('9.5') ||\n      goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('528'),\n\n  /**\n   * Whether HTML5 network events fire on document.body, or otherwise the\n   * window.\n   */\n  HTML5_NETWORK_EVENTS_FIRE_ON_BODY:\n      goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('8') ||\n      goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),\n\n  /**\n   * Whether touch is enabled in the browser.\n   */\n  TOUCH_ENABLED:\n      ('ontouchstart' in goog.global ||\n       !!(goog.global['document'] && document.documentElement &&\n          'ontouchstart' in document.documentElement) ||\n       // IE10 uses non-standard touch events, so it has a different check.\n       !!(goog.global['navigator'] &&\n          (goog.global['navigator']['maxTouchPoints'] ||\n           goog.global['navigator']['msMaxTouchPoints']))),\n\n  /**\n   * Whether addEventListener supports W3C standard pointer events.\n   * http://www.w3.org/TR/pointerevents/\n   */\n  POINTER_EVENTS: ('PointerEvent' in goog.global),\n\n  /**\n   * Whether addEventListener supports MSPointer events (only used in IE10).\n   * http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx\n   * http://msdn.microsoft.com/library/hh673557(v=vs.85).aspx\n   */\n  MSPOINTER_EVENTS:\n      ('MSPointerEvent' in goog.global &&\n       !!(goog.global['navigator'] &&\n          goog.global['navigator']['msPointerEnabled'])),\n\n  /**\n   * Whether addEventListener supports {passive: true}.\n   * https://developers.google.com/web/updates/2016/06/passive-event-listeners\n   */\n  PASSIVE_EVENTS: purify(function() {\n    // If we're in a web worker or other custom environment, we can't tell.\n    if (!goog.global.addEventListener || !Object.defineProperty) {  // IE 8\n      return false;\n    }\n\n    var passive = false;\n    var options = Object.defineProperty({}, 'passive', {\n      get: function() {\n        passive = true;\n      }\n    });\n    try {\n      goog.global.addEventListener('test', goog.nullFunction, options);\n      goog.global.removeEventListener('test', goog.nullFunction, options);\n    } catch (e) {\n    }\n\n    return passive;\n  })\n};\n\n\n/**\n * Tricks Closure Compiler into believing that a function is pure.  The compiler\n * assumes that any `valueOf` function is pure, without analyzing its contents.\n *\n * @param {function(): T} fn\n * @return {T}\n * @template T\n */\nfunction purify(fn) {\n  return ({valueOf: fn}).valueOf();\n}\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A base class for event objects.\n */\n\n\ngoog.provide('goog.events.Event');\ngoog.provide('goog.events.EventLike');\n\n/**\n * goog.events.Event no longer depends on goog.Disposable. Keep requiring\n * goog.Disposable here to not break projects which assume this dependency.\n * @suppress {extraRequire}\n */\ngoog.require('goog.Disposable');\ngoog.require('goog.events.EventId');\n\n\n/**\n * A typedef for event like objects that are dispatchable via the\n * goog.events.dispatchEvent function. strings are treated as the type for a\n * goog.events.Event. Objects are treated as an extension of a new\n * goog.events.Event with the type property of the object being used as the type\n * of the Event.\n * @typedef {string|Object|goog.events.Event|goog.events.EventId}\n */\ngoog.events.EventLike;\n\n\n\n/**\n * A base class for event objects, so that they can support preventDefault and\n * stopPropagation.\n *\n * @param {string|!goog.events.EventId} type Event Type.\n * @param {Object=} opt_target Reference to the object that is the target of\n *     this event. It has to implement the `EventTarget` interface\n *     declared at {@link http://developer.mozilla.org/en/DOM/EventTarget}.\n * @constructor\n */\ngoog.events.Event = function(type, opt_target) {\n  /**\n   * Event type.\n   * @type {string}\n   */\n  this.type = type instanceof goog.events.EventId ? String(type) : type;\n\n  /**\n   * TODO(tbreisacher): The type should probably be\n   * EventTarget|goog.events.EventTarget.\n   *\n   * Target of the event.\n   * @type {Object|undefined}\n   */\n  this.target = opt_target;\n\n  /**\n   * Object that had the listener attached.\n   * @type {Object|undefined}\n   */\n  this.currentTarget = this.target;\n\n  /**\n   * Whether to cancel the event in internal capture/bubble processing for IE.\n   * @type {boolean}\n   * @private\n   */\n  this.propagationStopped_ = false;\n\n  /**\n   * Whether the default action has been prevented.\n   * This is a property to match the W3C specification at\n   * {@link http://www.w3.org/TR/DOM-Level-3-Events/\n   * #events-event-type-defaultPrevented}.\n   * Must be treated as read-only outside the class.\n   * @type {boolean}\n   */\n  this.defaultPrevented = false;\n};\n\n/**\n * @return {boolean} true iff internal propagation has been stopped.\n */\ngoog.events.Event.prototype.hasPropagationStopped = function() {\n  return this.propagationStopped_;\n};\n\n/**\n * Stops event propagation.\n */\ngoog.events.Event.prototype.stopPropagation = function() {\n  this.propagationStopped_ = true;\n};\n\n\n/**\n * Prevents the default action, for example a link redirecting to a url.\n */\ngoog.events.Event.prototype.preventDefault = function() {\n  this.defaultPrevented = true;\n};\n\n\n/**\n * Stops the propagation of the event. It is equivalent to\n * `e.stopPropagation()`, but can be used as the callback argument of\n * {@link goog.events.listen} without declaring another function.\n * @param {!goog.events.Event} e An event.\n */\ngoog.events.Event.stopPropagation = function(e) {\n  e.stopPropagation();\n};\n\n\n/**\n * Prevents the default action. It is equivalent to\n * `e.preventDefault()`, but can be used as the callback argument of\n * {@link goog.events.listen} without declaring another function.\n * @param {!goog.events.Event} e An event.\n */\ngoog.events.Event.preventDefault = function(e) {\n  e.preventDefault();\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A patched, standardized event object for browser events.\n *\n * <pre>\n * The patched event object contains the following members:\n * - type           {string}    Event type, e.g. 'click'\n * - target         {Object}    The element that actually triggered the event\n * - currentTarget  {Object}    The element the listener is attached to\n * - relatedTarget  {Object}    For mouseover and mouseout, the previous object\n * - offsetX        {number}    X-coordinate relative to target\n * - offsetY        {number}    Y-coordinate relative to target\n * - clientX        {number}    X-coordinate relative to viewport\n * - clientY        {number}    Y-coordinate relative to viewport\n * - screenX        {number}    X-coordinate relative to the edge of the screen\n * - screenY        {number}    Y-coordinate relative to the edge of the screen\n * - button         {number}    Mouse button. Use isButton() to test.\n * - keyCode        {number}    Key-code\n * - ctrlKey        {boolean}   Was ctrl key depressed\n * - altKey         {boolean}   Was alt key depressed\n * - shiftKey       {boolean}   Was shift key depressed\n * - metaKey        {boolean}   Was meta key depressed\n * - pointerId      {number}    Pointer ID\n * - pointerType    {string}    Pointer type, e.g. 'mouse', 'pen', or 'touch'\n * - defaultPrevented {boolean} Whether the default action has been prevented\n * - state          {Object}    History state object\n *\n * NOTE: The keyCode member contains the raw browser keyCode. For normalized\n * key and character code use {@link goog.events.KeyHandler}.\n * </pre>\n */\n\ngoog.provide('goog.events.BrowserEvent');\ngoog.provide('goog.events.BrowserEvent.MouseButton');\ngoog.provide('goog.events.BrowserEvent.PointerType');\n\ngoog.require('goog.debug');\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventType');\ngoog.require('goog.reflect');\ngoog.require('goog.userAgent');\n\n/**\n * @define {boolean} If true, use the layerX and layerY properties of a native\n * browser event over the offsetX and offsetY properties, which cause expensive\n * reflow. If layerX or layerY is not defined, offsetX and offsetY will be used\n * as usual.\n */\ngoog.events.USE_LAYER_XY_AS_OFFSET_XY =\n    goog.define('goog.events.USE_LAYER_XY_AS_OFFSET_XY', false);\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * The content of this object will not be initialized if no event object is\n * provided. If this is the case, init() needs to be invoked separately.\n * @param {Event=} opt_e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.events.BrowserEvent = function(opt_e, opt_currentTarget) {\n  goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : '');\n\n  /**\n   * Target that fired the event.\n   * @override\n   * @type {?Node}\n   */\n  this.target = null;\n\n  /**\n   * Node that had the listener attached.\n   * @override\n   * @type {?Node|undefined}\n   */\n  this.currentTarget = null;\n\n  /**\n   * For mouseover and mouseout events, the related object for the event.\n   * @type {?Node}\n   */\n  this.relatedTarget = null;\n\n  /**\n   * X-coordinate relative to target.\n   * @type {number}\n   */\n  this.offsetX = 0;\n\n  /**\n   * Y-coordinate relative to target.\n   * @type {number}\n   */\n  this.offsetY = 0;\n\n  /**\n   * X-coordinate relative to the window.\n   * @type {number}\n   */\n  this.clientX = 0;\n\n  /**\n   * Y-coordinate relative to the window.\n   * @type {number}\n   */\n  this.clientY = 0;\n\n  /**\n   * X-coordinate relative to the monitor.\n   * @type {number}\n   */\n  this.screenX = 0;\n\n  /**\n   * Y-coordinate relative to the monitor.\n   * @type {number}\n   */\n  this.screenY = 0;\n\n  /**\n   * Which mouse button was pressed.\n   * @type {number}\n   */\n  this.button = 0;\n\n  /**\n   * Key of key press.\n   * @type {string}\n   */\n  this.key = '';\n\n  /**\n   * Keycode of key press.\n   * @type {number}\n   */\n  this.keyCode = 0;\n\n  /**\n   * Keycode of key press.\n   * @type {number}\n   */\n  this.charCode = 0;\n\n  /**\n   * Whether control was pressed at time of event.\n   * @type {boolean}\n   */\n  this.ctrlKey = false;\n\n  /**\n   * Whether alt was pressed at time of event.\n   * @type {boolean}\n   */\n  this.altKey = false;\n\n  /**\n   * Whether shift was pressed at time of event.\n   * @type {boolean}\n   */\n  this.shiftKey = false;\n\n  /**\n   * Whether the meta key was pressed at time of event.\n   * @type {boolean}\n   */\n  this.metaKey = false;\n\n  /**\n   * History state object, only set for PopState events where it's a copy of the\n   * state object provided to pushState or replaceState.\n   * @type {?Object}\n   */\n  this.state = null;\n\n  /**\n   * Whether the default platform modifier key was pressed at time of event.\n   * (This is control for all platforms except Mac, where it's Meta.)\n   * @type {boolean}\n   */\n  this.platformModifierKey = false;\n\n  /**\n   * @type {number}\n   */\n  this.pointerId = 0;\n\n  /**\n   * @type {string}\n   */\n  this.pointerType = '';\n\n  /**\n   * The browser event object.\n   * @private {?Event}\n   */\n  this.event_ = null;\n\n  if (opt_e) {\n    this.init(opt_e, opt_currentTarget);\n  }\n};\ngoog.inherits(goog.events.BrowserEvent, goog.events.Event);\n\n\n/**\n * Normalized button constants for the mouse.\n * @enum {number}\n */\ngoog.events.BrowserEvent.MouseButton = {\n  LEFT: 0,\n  MIDDLE: 1,\n  RIGHT: 2\n};\n\n\n/**\n * Normalized pointer type constants for pointer events.\n * @enum {string}\n */\ngoog.events.BrowserEvent.PointerType = {\n  MOUSE: 'mouse',\n  PEN: 'pen',\n  TOUCH: 'touch'\n};\n\n\n/**\n * Static data for mapping mouse buttons.\n * @type {!Array<number>}\n * @deprecated Use `goog.events.BrowserEvent.IE_BUTTON_MAP` instead.\n */\ngoog.events.BrowserEvent.IEButtonMap = goog.debug.freeze([\n  1,  // LEFT\n  4,  // MIDDLE\n  2   // RIGHT\n]);\n\n\n/**\n * Static data for mapping mouse buttons.\n * @const {!Array<number>}\n */\ngoog.events.BrowserEvent.IE_BUTTON_MAP = goog.events.BrowserEvent.IEButtonMap;\n\n\n/**\n * Static data for mapping MSPointerEvent types to PointerEvent types.\n * @const {!Object<number, goog.events.BrowserEvent.PointerType>}\n */\ngoog.events.BrowserEvent.IE_POINTER_TYPE_MAP = goog.debug.freeze({\n  2: goog.events.BrowserEvent.PointerType.TOUCH,\n  3: goog.events.BrowserEvent.PointerType.PEN,\n  4: goog.events.BrowserEvent.PointerType.MOUSE\n});\n\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * @param {Event} e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n */\ngoog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {\n  var type = this.type = e.type;\n\n  /**\n   * On touch devices use the first \"changed touch\" as the relevant touch.\n   * @type {?Touch}\n   */\n  var relevantTouch =\n      e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : null;\n\n  // TODO(nicksantos): Change this.target to type EventTarget.\n  this.target = /** @type {Node} */ (e.target) || e.srcElement;\n\n  // TODO(nicksantos): Change this.currentTarget to type EventTarget.\n  this.currentTarget = /** @type {Node} */ (opt_currentTarget);\n\n  var relatedTarget = /** @type {Node} */ (e.relatedTarget);\n  if (relatedTarget) {\n    // There's a bug in FireFox where sometimes, relatedTarget will be a\n    // chrome element, and accessing any property of it will get a permission\n    // denied exception. See:\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=497780\n    if (goog.userAgent.GECKO) {\n      if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) {\n        relatedTarget = null;\n      }\n    }\n  } else if (type == goog.events.EventType.MOUSEOVER) {\n    relatedTarget = e.fromElement;\n  } else if (type == goog.events.EventType.MOUSEOUT) {\n    relatedTarget = e.toElement;\n  }\n\n  this.relatedTarget = relatedTarget;\n\n  if (relevantTouch) {\n    this.clientX = relevantTouch.clientX !== undefined ? relevantTouch.clientX :\n                                                         relevantTouch.pageX;\n    this.clientY = relevantTouch.clientY !== undefined ? relevantTouch.clientY :\n                                                         relevantTouch.pageY;\n    this.screenX = relevantTouch.screenX || 0;\n    this.screenY = relevantTouch.screenY || 0;\n  } else {\n    if (goog.events.USE_LAYER_XY_AS_OFFSET_XY) {\n      this.offsetX = (e.layerX !== undefined) ? e.layerX : e.offsetX;\n      this.offsetY = (e.layerY !== undefined) ? e.layerY : e.offsetY;\n    } else {\n      // Webkit emits a lame warning whenever layerX/layerY is accessed.\n      // http://code.google.com/p/chromium/issues/detail?id=101733\n      this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ?\n          e.offsetX :\n          e.layerX;\n      this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ?\n          e.offsetY :\n          e.layerY;\n    }\n    this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;\n    this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;\n    this.screenX = e.screenX || 0;\n    this.screenY = e.screenY || 0;\n  }\n\n  this.button = e.button;\n\n  this.keyCode = e.keyCode || 0;\n  this.key = e.key || '';\n  this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0);\n  this.ctrlKey = e.ctrlKey;\n  this.altKey = e.altKey;\n  this.shiftKey = e.shiftKey;\n  this.metaKey = e.metaKey;\n  this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;\n  this.pointerId = e.pointerId || 0;\n  this.pointerType = goog.events.BrowserEvent.getPointerType_(e);\n  this.state = e.state;\n  this.event_ = e;\n  if (e.defaultPrevented) {\n    this.preventDefault();\n  }\n};\n\n\n/**\n * Tests to see which button was pressed during the event. This is really only\n * useful in IE and Gecko browsers. And in IE, it's only useful for\n * mousedown/mouseup events, because click only fires for the left mouse button.\n *\n * Safari 2 only reports the left button being clicked, and uses the value '1'\n * instead of 0. Opera only reports a mousedown event for the middle button, and\n * no mouse events for the right button. Opera has default behavior for left and\n * middle click that can only be overridden via a configuration setting.\n *\n * There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.\n *\n * @param {goog.events.BrowserEvent.MouseButton} button The button\n *     to test for.\n * @return {boolean} True if button was pressed.\n */\ngoog.events.BrowserEvent.prototype.isButton = function(button) {\n  if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {\n    if (this.type == 'click') {\n      return button == goog.events.BrowserEvent.MouseButton.LEFT;\n    } else {\n      return !!(\n          this.event_.button & goog.events.BrowserEvent.IE_BUTTON_MAP[button]);\n    }\n  } else {\n    return this.event_.button == button;\n  }\n};\n\n\n/**\n * Whether this has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @return {boolean} The result.\n */\ngoog.events.BrowserEvent.prototype.isMouseActionButton = function() {\n  // Ctrl+click should never behave like a left-click on mac, regardless of\n  // whether or not the browser will actually ever emit such an event.  If\n  // we see it, treat it like right-click always.\n  return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&\n      !(goog.userAgent.MAC && this.ctrlKey);\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.stopPropagation = function() {\n  goog.events.BrowserEvent.superClass_.stopPropagation.call(this);\n  if (this.event_.stopPropagation) {\n    this.event_.stopPropagation();\n  } else {\n    this.event_.cancelBubble = true;\n  }\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.preventDefault = function() {\n  goog.events.BrowserEvent.superClass_.preventDefault.call(this);\n  var be = this.event_;\n  if (!be.preventDefault) {\n    be.returnValue = false;\n    if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {\n\n      try {\n        // Most keys can be prevented using returnValue. Some special keys\n        // require setting the keyCode to -1 as well:\n        //\n        // In IE7:\n        // F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6)\n        //\n        // In IE8:\n        // Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event)\n        //\n        // We therefore do this for all function keys as well as when Ctrl key\n        // is pressed.\n        var VK_F1 = 112;\n        var VK_F12 = 123;\n        if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {\n          be.keyCode = -1;\n        }\n      } catch (ex) {\n        // IE throws an 'access denied' exception when trying to change\n        // keyCode in some situations (e.g. srcElement is input[type=file],\n        // or srcElement is an anchor tag rewritten by parent's innerHTML).\n        // Do nothing in this case.\n      }\n    }\n  } else {\n    be.preventDefault();\n  }\n};\n\n\n/**\n * @return {Event} The underlying browser event object.\n */\ngoog.events.BrowserEvent.prototype.getBrowserEvent = function() {\n  return this.event_;\n};\n\n\n/**\n * Extracts the pointer type from the given event.\n * @param {!Event} e\n * @return {string} The pointer type, e.g. 'mouse', 'pen', or 'touch'.\n * @private\n */\ngoog.events.BrowserEvent.getPointerType_ = function(e) {\n  if (typeof (e.pointerType) === 'string') {\n    return e.pointerType;\n  }\n  // IE10 uses integer codes for pointer type.\n  // https://msdn.microsoft.com/en-us/library/hh772359(v=vs.85).aspx\n  return goog.events.BrowserEvent.IE_POINTER_TYPE_MAP[e.pointerType] || '';\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Event Types.\n */\n\n\ngoog.provide('goog.events.EventType');\ngoog.provide('goog.events.MouseAsMouseEventType');\ngoog.provide('goog.events.MouseEvents');\ngoog.provide('goog.events.PointerAsMouseEventType');\ngoog.provide('goog.events.PointerAsTouchEventType');\ngoog.provide('goog.events.PointerFallbackEventType');\ngoog.provide('goog.events.PointerTouchFallbackEventType');\n\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.userAgent');\n\n\n/**\n * Returns a prefixed event name for the current browser.\n * @param {string} eventName The name of the event.\n * @return {string} The prefixed event name.\n * @private\n */\ngoog.events.getVendorPrefixedName_ = function(eventName) {\n  return goog.userAgent.WEBKIT ?\n      'webkit' + eventName :\n      (goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() :\n                              eventName.toLowerCase());\n};\n\n\n/**\n * Constants for event names.\n * @enum {string}\n */\ngoog.events.EventType = {\n  // Mouse events\n  CLICK: 'click',\n  RIGHTCLICK: 'rightclick',\n  DBLCLICK: 'dblclick',\n  AUXCLICK: 'auxclick',\n  MOUSEDOWN: 'mousedown',\n  MOUSEUP: 'mouseup',\n  MOUSEOVER: 'mouseover',\n  MOUSEOUT: 'mouseout',\n  MOUSEMOVE: 'mousemove',\n  MOUSEENTER: 'mouseenter',\n  MOUSELEAVE: 'mouseleave',\n\n  // Non-existent event; will never fire. This exists as a mouse counterpart to\n  // POINTERCANCEL.\n  MOUSECANCEL: 'mousecancel',\n\n  // Selection events.\n  // https://www.w3.org/TR/selection-api/\n  SELECTIONCHANGE: 'selectionchange',\n  SELECTSTART: 'selectstart',  // IE, Safari, Chrome\n\n  // Wheel events\n  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents\n  WHEEL: 'wheel',\n\n  // Key events\n  KEYPRESS: 'keypress',\n  KEYDOWN: 'keydown',\n  KEYUP: 'keyup',\n\n  // Focus\n  BLUR: 'blur',\n  FOCUS: 'focus',\n  DEACTIVATE: 'deactivate',  // IE only\n  FOCUSIN: 'focusin',\n  FOCUSOUT: 'focusout',\n\n  // Forms\n  CHANGE: 'change',\n  RESET: 'reset',\n  SELECT: 'select',\n  SUBMIT: 'submit',\n  INPUT: 'input',\n  PROPERTYCHANGE: 'propertychange',  // IE only\n\n  // Drag and drop\n  DRAGSTART: 'dragstart',\n  DRAG: 'drag',\n  DRAGENTER: 'dragenter',\n  DRAGOVER: 'dragover',\n  DRAGLEAVE: 'dragleave',\n  DROP: 'drop',\n  DRAGEND: 'dragend',\n\n  // Touch events\n  // Note that other touch events exist, but we should follow the W3C list here.\n  // http://www.w3.org/TR/touch-events/#list-of-touchevent-types\n  TOUCHSTART: 'touchstart',\n  TOUCHMOVE: 'touchmove',\n  TOUCHEND: 'touchend',\n  TOUCHCANCEL: 'touchcancel',\n\n  // Misc\n  BEFOREUNLOAD: 'beforeunload',\n  CONSOLEMESSAGE: 'consolemessage',\n  CONTEXTMENU: 'contextmenu',\n  DEVICECHANGE: 'devicechange',\n  DEVICEMOTION: 'devicemotion',\n  DEVICEORIENTATION: 'deviceorientation',\n  DOMCONTENTLOADED: 'DOMContentLoaded',\n  ERROR: 'error',\n  HELP: 'help',\n  LOAD: 'load',\n  LOSECAPTURE: 'losecapture',\n  ORIENTATIONCHANGE: 'orientationchange',\n  READYSTATECHANGE: 'readystatechange',\n  RESIZE: 'resize',\n  SCROLL: 'scroll',\n  UNLOAD: 'unload',\n\n  // Media events\n  CANPLAY: 'canplay',\n  CANPLAYTHROUGH: 'canplaythrough',\n  DURATIONCHANGE: 'durationchange',\n  EMPTIED: 'emptied',\n  ENDED: 'ended',\n  LOADEDDATA: 'loadeddata',\n  LOADEDMETADATA: 'loadedmetadata',\n  PAUSE: 'pause',\n  PLAY: 'play',\n  PLAYING: 'playing',\n  PROGRESS: 'progress',\n  RATECHANGE: 'ratechange',\n  SEEKED: 'seeked',\n  SEEKING: 'seeking',\n  STALLED: 'stalled',\n  SUSPEND: 'suspend',\n  TIMEUPDATE: 'timeupdate',\n  VOLUMECHANGE: 'volumechange',\n  WAITING: 'waiting',\n\n  // Media Source Extensions events\n  // https://www.w3.org/TR/media-source/#mediasource-events\n  SOURCEOPEN: 'sourceopen',\n  SOURCEENDED: 'sourceended',\n  SOURCECLOSED: 'sourceclosed',\n  // https://www.w3.org/TR/media-source/#sourcebuffer-events\n  ABORT: 'abort',\n  UPDATE: 'update',\n  UPDATESTART: 'updatestart',\n  UPDATEEND: 'updateend',\n\n  // HTML 5 History events\n  // See http://www.w3.org/TR/html5/browsers.html#event-definitions-0\n  HASHCHANGE: 'hashchange',\n  PAGEHIDE: 'pagehide',\n  PAGESHOW: 'pageshow',\n  POPSTATE: 'popstate',\n\n  // Copy and Paste\n  // Support is limited. Make sure it works on your favorite browser\n  // before using.\n  // http://www.quirksmode.org/dom/events/cutcopypaste.html\n  COPY: 'copy',\n  PASTE: 'paste',\n  CUT: 'cut',\n  BEFORECOPY: 'beforecopy',\n  BEFORECUT: 'beforecut',\n  BEFOREPASTE: 'beforepaste',\n\n  // HTML5 online/offline events.\n  // http://www.w3.org/TR/offline-webapps/#related\n  ONLINE: 'online',\n  OFFLINE: 'offline',\n\n  // HTML 5 worker events\n  MESSAGE: 'message',\n  CONNECT: 'connect',\n\n  // Service Worker Events - ServiceWorkerGlobalScope context\n  // See https://w3c.github.io/ServiceWorker/#execution-context-events\n  // Note: message event defined in worker events section\n  INSTALL: 'install',\n  ACTIVATE: 'activate',\n  FETCH: 'fetch',\n  FOREIGNFETCH: 'foreignfetch',\n  MESSAGEERROR: 'messageerror',\n\n  // Service Worker Events - Document context\n  // See https://w3c.github.io/ServiceWorker/#document-context-events\n  STATECHANGE: 'statechange',\n  UPDATEFOUND: 'updatefound',\n  CONTROLLERCHANGE: 'controllerchange',\n\n  // CSS animation events.\n  ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'),\n  ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'),\n  ANIMATIONITERATION: goog.events.getVendorPrefixedName_('AnimationIteration'),\n\n  // CSS transition events. Based on the browser support described at:\n  // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility\n  TRANSITIONEND: goog.events.getVendorPrefixedName_('TransitionEnd'),\n\n  // W3C Pointer Events\n  // http://www.w3.org/TR/pointerevents/\n  POINTERDOWN: 'pointerdown',\n  POINTERUP: 'pointerup',\n  POINTERCANCEL: 'pointercancel',\n  POINTERMOVE: 'pointermove',\n  POINTEROVER: 'pointerover',\n  POINTEROUT: 'pointerout',\n  POINTERENTER: 'pointerenter',\n  POINTERLEAVE: 'pointerleave',\n  GOTPOINTERCAPTURE: 'gotpointercapture',\n  LOSTPOINTERCAPTURE: 'lostpointercapture',\n\n  // IE specific events.\n  // See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx\n  // Note: these events will be supplanted in IE11.\n  MSGESTURECHANGE: 'MSGestureChange',\n  MSGESTUREEND: 'MSGestureEnd',\n  MSGESTUREHOLD: 'MSGestureHold',\n  MSGESTURESTART: 'MSGestureStart',\n  MSGESTURETAP: 'MSGestureTap',\n  MSGOTPOINTERCAPTURE: 'MSGotPointerCapture',\n  MSINERTIASTART: 'MSInertiaStart',\n  MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture',\n  MSPOINTERCANCEL: 'MSPointerCancel',\n  MSPOINTERDOWN: 'MSPointerDown',\n  MSPOINTERENTER: 'MSPointerEnter',\n  MSPOINTERHOVER: 'MSPointerHover',\n  MSPOINTERLEAVE: 'MSPointerLeave',\n  MSPOINTERMOVE: 'MSPointerMove',\n  MSPOINTEROUT: 'MSPointerOut',\n  MSPOINTEROVER: 'MSPointerOver',\n  MSPOINTERUP: 'MSPointerUp',\n\n  // Native IMEs/input tools events.\n  TEXT: 'text',\n  // The textInput event is supported in IE9+, but only in lower case. All other\n  // browsers use the camel-case event name.\n  TEXTINPUT: goog.userAgent.IE ? 'textinput' : 'textInput',\n  COMPOSITIONSTART: 'compositionstart',\n  COMPOSITIONUPDATE: 'compositionupdate',\n  COMPOSITIONEND: 'compositionend',\n\n  // The beforeinput event is initially only supported in Safari. See\n  // https://bugs.chromium.org/p/chromium/issues/detail?id=342670 for Chrome\n  // implementation tracking.\n  BEFOREINPUT: 'beforeinput',\n\n  // Webview tag events\n  // See https://developer.chrome.com/apps/tags/webview\n  EXIT: 'exit',\n  LOADABORT: 'loadabort',\n  LOADCOMMIT: 'loadcommit',\n  LOADREDIRECT: 'loadredirect',\n  LOADSTART: 'loadstart',\n  LOADSTOP: 'loadstop',\n  RESPONSIVE: 'responsive',\n  SIZECHANGED: 'sizechanged',\n  UNRESPONSIVE: 'unresponsive',\n\n  // HTML5 Page Visibility API.  See details at\n  // `goog.labs.dom.PageVisibilityMonitor`.\n  VISIBILITYCHANGE: 'visibilitychange',\n\n  // LocalStorage event.\n  STORAGE: 'storage',\n\n  // DOM Level 2 mutation events (deprecated).\n  DOMSUBTREEMODIFIED: 'DOMSubtreeModified',\n  DOMNODEINSERTED: 'DOMNodeInserted',\n  DOMNODEREMOVED: 'DOMNodeRemoved',\n  DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument',\n  DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument',\n  DOMATTRMODIFIED: 'DOMAttrModified',\n  DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified',\n\n  // Print events.\n  BEFOREPRINT: 'beforeprint',\n  AFTERPRINT: 'afterprint',\n\n  // Web app manifest events.\n  BEFOREINSTALLPROMPT: 'beforeinstallprompt',\n  APPINSTALLED: 'appinstalled'\n};\n\n\n/**\n * Returns one of the given pointer fallback event names in order of preference:\n *   1. pointerEventName\n *   2. msPointerEventName\n *   3. fallbackEventName\n * @param {string} pointerEventName\n * @param {string} msPointerEventName\n * @param {string} fallbackEventName\n * @return {string} The supported pointer or fallback (mouse or touch) event\n *     name.\n * @private\n */\ngoog.events.getPointerFallbackEventName_ = function(\n    pointerEventName, msPointerEventName, fallbackEventName) {\n  if (goog.events.BrowserFeature.POINTER_EVENTS) {\n    return pointerEventName;\n  }\n  if (goog.events.BrowserFeature.MSPOINTER_EVENTS) {\n    return msPointerEventName;\n  }\n  return fallbackEventName;\n};\n\n\n/**\n * Constants for pointer event names that fall back to corresponding mouse event\n * names on unsupported platforms. These are intended to be drop-in replacements\n * for corresponding values in `goog.events.EventType`.\n * @enum {string}\n */\ngoog.events.PointerFallbackEventType = {\n  POINTERDOWN: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERDOWN, goog.events.EventType.MSPOINTERDOWN,\n      goog.events.EventType.MOUSEDOWN),\n  POINTERUP: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERUP, goog.events.EventType.MSPOINTERUP,\n      goog.events.EventType.MOUSEUP),\n  POINTERCANCEL: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERCANCEL,\n      goog.events.EventType.MSPOINTERCANCEL,\n      // When falling back to mouse events, there is no MOUSECANCEL equivalent\n      // of POINTERCANCEL. In this case POINTERUP already falls back to MOUSEUP\n      // which represents both UP and CANCEL. POINTERCANCEL does not fall back\n      // to MOUSEUP to prevent listening twice on the same event.\n      goog.events.EventType.MOUSECANCEL),\n  POINTERMOVE: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERMOVE, goog.events.EventType.MSPOINTERMOVE,\n      goog.events.EventType.MOUSEMOVE),\n  POINTEROVER: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTEROVER, goog.events.EventType.MSPOINTEROVER,\n      goog.events.EventType.MOUSEOVER),\n  POINTEROUT: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTEROUT, goog.events.EventType.MSPOINTEROUT,\n      goog.events.EventType.MOUSEOUT),\n  POINTERENTER: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERENTER, goog.events.EventType.MSPOINTERENTER,\n      goog.events.EventType.MOUSEENTER),\n  POINTERLEAVE: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERLEAVE, goog.events.EventType.MSPOINTERLEAVE,\n      goog.events.EventType.MOUSELEAVE)\n};\n\n\n/**\n * Constants for pointer event names that fall back to corresponding touch event\n * names on unsupported platforms. These are intended to be drop-in replacements\n * for corresponding values in `goog.events.EventType`.\n * @enum {string}\n */\ngoog.events.PointerTouchFallbackEventType = {\n  POINTERDOWN: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERDOWN, goog.events.EventType.MSPOINTERDOWN,\n      goog.events.EventType.TOUCHSTART),\n  POINTERUP: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERUP, goog.events.EventType.MSPOINTERUP,\n      goog.events.EventType.TOUCHEND),\n  POINTERCANCEL: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERCANCEL,\n      goog.events.EventType.MSPOINTERCANCEL, goog.events.EventType.TOUCHCANCEL),\n  POINTERMOVE: goog.events.getPointerFallbackEventName_(\n      goog.events.EventType.POINTERMOVE, goog.events.EventType.MSPOINTERMOVE,\n      goog.events.EventType.TOUCHMOVE)\n};\n\n\n/**\n * Mapping of mouse event names to underlying browser event names.\n * @typedef {{\n *     MOUSEDOWN: string,\n *     MOUSEUP: string,\n *     MOUSECANCEL:string,\n *     MOUSEMOVE:string,\n *     MOUSEOVER:string,\n *     MOUSEOUT:string,\n *     MOUSEENTER:string,\n *     MOUSELEAVE: string,\n * }}\n */\ngoog.events.MouseEvents;\n\n\n/**\n * An alias for `goog.events.EventType.MOUSE*` event types that is overridden by\n * corresponding `POINTER*` event types.\n * @const {!goog.events.MouseEvents}\n */\ngoog.events.PointerAsMouseEventType = {\n  MOUSEDOWN: goog.events.PointerFallbackEventType.POINTERDOWN,\n  MOUSEUP: goog.events.PointerFallbackEventType.POINTERUP,\n  MOUSECANCEL: goog.events.PointerFallbackEventType.POINTERCANCEL,\n  MOUSEMOVE: goog.events.PointerFallbackEventType.POINTERMOVE,\n  MOUSEOVER: goog.events.PointerFallbackEventType.POINTEROVER,\n  MOUSEOUT: goog.events.PointerFallbackEventType.POINTEROUT,\n  MOUSEENTER: goog.events.PointerFallbackEventType.POINTERENTER,\n  MOUSELEAVE: goog.events.PointerFallbackEventType.POINTERLEAVE\n};\n\n\n/**\n * An alias for `goog.events.EventType.MOUSE*` event types that continue to use\n * mouse events.\n * @const {!goog.events.MouseEvents}\n */\ngoog.events.MouseAsMouseEventType = {\n  MOUSEDOWN: goog.events.EventType.MOUSEDOWN,\n  MOUSEUP: goog.events.EventType.MOUSEUP,\n  MOUSECANCEL: goog.events.EventType.MOUSECANCEL,\n  MOUSEMOVE: goog.events.EventType.MOUSEMOVE,\n  MOUSEOVER: goog.events.EventType.MOUSEOVER,\n  MOUSEOUT: goog.events.EventType.MOUSEOUT,\n  MOUSEENTER: goog.events.EventType.MOUSEENTER,\n  MOUSELEAVE: goog.events.EventType.MOUSELEAVE\n};\n\n\n/**\n * An alias for `goog.events.EventType.TOUCH*` event types that is overridden by\n * corresponding `POINTER*` event types.\n * @enum {string}\n */\ngoog.events.PointerAsTouchEventType = {\n  TOUCHCANCEL: goog.events.PointerTouchFallbackEventType.POINTERCANCEL,\n  TOUCHEND: goog.events.PointerTouchFallbackEventType.POINTERUP,\n  TOUCHMOVE: goog.events.PointerTouchFallbackEventType.POINTERMOVE,\n  TOUCHSTART: goog.events.PointerTouchFallbackEventType.POINTERDOWN\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An interface for a listenable JavaScript object.\n */\n\ngoog.provide('goog.events.Listenable');\ngoog.provide('goog.events.ListenableKey');\n/** @suppress {extraRequire} */\ngoog.require('goog.events.EventId');\n\ngoog.requireType('goog.events.EventLike');\n\n\n/**\n * A listenable interface. A listenable is an object with the ability\n * to dispatch/broadcast events to \"event listeners\" registered via\n * listen/listenOnce.\n *\n * The interface allows for an event propagation mechanism similar\n * to one offered by native browser event targets, such as\n * capture/bubble mechanism, stopping propagation, and preventing\n * default actions. Capture/bubble mechanism depends on the ancestor\n * tree constructed via `#getParentEventTarget`; this tree\n * must be directed acyclic graph. The meaning of default action(s)\n * in preventDefault is specific to a particular use case.\n *\n * Implementations that do not support capture/bubble or can not have\n * a parent listenable can simply not implement any ability to set the\n * parent listenable (and have `#getParentEventTarget` return\n * null).\n *\n * Implementation of this class can be used with or independently from\n * goog.events.\n *\n * Implementation must call `#addImplementation(implClass)`.\n *\n * @interface\n * @see goog.events\n * @see http://www.w3.org/TR/DOM-Level-2-Events/events.html\n */\ngoog.events.Listenable = function() {};\n\n\n/**\n * An expando property to indicate that an object implements\n * goog.events.Listenable.\n *\n * See addImplementation/isImplementedBy.\n *\n * @type {string}\n * @const\n */\ngoog.events.Listenable.IMPLEMENTED_BY_PROP =\n    'closure_listenable_' + ((Math.random() * 1e6) | 0);\n\n\n/**\n * Marks a given class (constructor) as an implementation of\n * Listenable, so that we can query that fact at runtime. The class\n * must have already implemented the interface.\n * @param {function(new:goog.events.Listenable,...)} cls The class constructor.\n *     The corresponding class must have already implemented the interface.\n */\ngoog.events.Listenable.addImplementation = function(cls) {\n  cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true;\n};\n\n\n/**\n * @param {Object} obj The object to check.\n * @return {boolean} Whether a given instance implements Listenable. The\n *     class/superclass of the instance must call addImplementation.\n */\ngoog.events.Listenable.isImplementedBy = function(obj) {\n  return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]);\n};\n\n\n/**\n * Adds an event listener. A listener can only be added once to an\n * object and if it is added again the key for the listener is\n * returned. Note that if the existing listener is a one-off listener\n * (registered via listenOnce), it will no longer be a one-off\n * listener after a call to listen().\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n *     method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n *     (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.listen;\n\n\n/**\n * Adds an event listener that is removed automatically after the\n * listener fired once.\n *\n * If an existing listener already exists, listenOnce will do\n * nothing. In particular, if the listener was previously registered\n * via listen(), listenOnce() will not turn the listener into a\n * one-off listener. Similarly, if there is already an existing\n * one-off listener, listenOnce does not modify the listeners (it is\n * still a once listener).\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n *     method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n *     (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.listenOnce;\n\n\n/**\n * Removes an event listener which was added with listen() or listenOnce().\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n *     method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n *     (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call\n *     the listener.\n * @return {boolean} Whether any listener was removed.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.unlisten;\n\n\n/**\n * Removes an event listener which was added with listen() by the key\n * returned by listen().\n *\n * @param {!goog.events.ListenableKey} key The key returned by\n *     listen() or listenOnce().\n * @return {boolean} Whether any listener was removed.\n */\ngoog.events.Listenable.prototype.unlistenByKey;\n\n\n/**\n * Dispatches an event (or event like object) and calls all listeners\n * listening for events of this type. The type of the event is decided by the\n * type property on the event object.\n *\n * If any of the listeners returns false OR calls preventDefault then this\n * function will return false.  If one of the capture listeners calls\n * stopPropagation, then the bubble listeners won't fire.\n *\n * @param {goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n *     if any of the listeners returns false) this will also return false.\n */\ngoog.events.Listenable.prototype.dispatchEvent;\n\n\n/**\n * Removes all listeners from this listenable. If type is specified,\n * it will only remove listeners of the particular type. otherwise all\n * registered listeners will be removed.\n *\n * @param {string=} opt_type Type of event to remove, default is to\n *     remove all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.Listenable.prototype.removeAllListeners;\n\n\n/**\n * Returns the parent of this event target to use for capture/bubble\n * mechanism.\n *\n * NOTE(chrishenry): The name reflects the original implementation of\n * custom event target (`goog.events.EventTarget`). We decided\n * that changing the name is not worth it.\n *\n * @return {goog.events.Listenable} The parent EventTarget or null if\n *     there is no parent.\n */\ngoog.events.Listenable.prototype.getParentEventTarget;\n\n\n/**\n * Fires all registered listeners in this listenable for the given\n * type and capture mode, passing them the given eventObject. This\n * does not perform actual capture/bubble. Only implementors of the\n * interface should be using this.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The type of the\n *     listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @param {EVENTOBJ} eventObject The event object to fire.\n * @return {boolean} Whether all listeners succeeded without\n *     attempting to prevent default behavior. If any listener returns\n *     false or called goog.events.Event#preventDefault, this returns\n *     false.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.fireListeners;\n\n\n/**\n * Gets all listeners in this listenable for the given type and\n * capture mode.\n *\n * @param {string|!goog.events.EventId} type The type of the listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @return {!Array<!goog.events.ListenableKey>} An array of registered\n *     listeners.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.getListeners;\n\n\n/**\n * Gets the goog.events.ListenableKey for the event or null if no such\n * listener is in use.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The name of the event\n *     without the 'on' prefix.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The\n *     listener function to get.\n * @param {boolean} capture Whether the listener is a capturing listener.\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.getListener;\n\n\n/**\n * Whether there is any active listeners matching the specified\n * signature. If either the type or capture parameters are\n * unspecified, the function will match on the remaining criteria.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble\n *     listeners.\n * @return {boolean} Whether there is any active listeners matching\n *     the requested type and/or capture phase.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.hasListener;\n\n\n\n/**\n * An interface that describes a single registered listener.\n * @interface\n */\ngoog.events.ListenableKey = function() {};\n\n\n/**\n * Counter used to create a unique key\n * @type {number}\n * @private\n */\ngoog.events.ListenableKey.counter_ = 0;\n\n\n/**\n * Reserves a key to be used for ListenableKey#key field.\n * @return {number} A number to be used to fill ListenableKey#key\n *     field.\n */\ngoog.events.ListenableKey.reserveKey = function() {\n  return ++goog.events.ListenableKey.counter_;\n};\n\n\n/**\n * The source event target.\n * @type {?Object|?goog.events.Listenable}\n */\ngoog.events.ListenableKey.prototype.src;\n\n\n/**\n * The event type the listener is listening to.\n * @type {string}\n */\ngoog.events.ListenableKey.prototype.type;\n\n\n/**\n * The listener function.\n * @type {function(?):?|{handleEvent:function(?):?}|null}\n */\ngoog.events.ListenableKey.prototype.listener;\n\n\n/**\n * Whether the listener works on capture phase.\n * @type {boolean}\n */\ngoog.events.ListenableKey.prototype.capture;\n\n\n/**\n * The 'this' object for the listener function's scope.\n * @type {Object|undefined}\n */\ngoog.events.ListenableKey.prototype.handler;\n\n\n/**\n * A globally unique number to identify the key.\n * @type {number}\n */\ngoog.events.ListenableKey.prototype.key;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Listener object.\n * @see ../demos/events.html\n */\n\ngoog.provide('goog.events.Listener');\n\ngoog.require('goog.events.ListenableKey');\n\n\n\n/**\n * Simple class that stores information about a listener\n * @param {function(?):?} listener Callback function.\n * @param {Function} proxy Wrapper for the listener that patches the event.\n * @param {EventTarget|goog.events.Listenable} src Source object for\n *     the event.\n * @param {string} type Event type.\n * @param {boolean} capture Whether in capture or bubble phase.\n * @param {Object=} opt_handler Object in whose context to execute the callback.\n * @implements {goog.events.ListenableKey}\n * @constructor\n */\ngoog.events.Listener = function(\n    listener, proxy, src, type, capture, opt_handler) {\n  if (goog.events.Listener.ENABLE_MONITORING) {\n    this.creationStack = new Error().stack;\n  }\n\n  /** @override */\n  this.listener = listener;\n\n  /**\n   * A wrapper over the original listener. This is used solely to\n   * handle native browser events (it is used to simulate the capture\n   * phase and to patch the event object).\n   * @type {Function}\n   */\n  this.proxy = proxy;\n\n  /**\n   * Object or node that callback is listening to\n   * @type {EventTarget|goog.events.Listenable}\n   */\n  this.src = src;\n\n  /**\n   * The event type.\n   * @const {string}\n   */\n  this.type = type;\n\n  /**\n   * Whether the listener is being called in the capture or bubble phase\n   * @const {boolean}\n   */\n  this.capture = !!capture;\n\n  /**\n   * Optional object whose context to execute the listener in\n   * @type {Object|undefined}\n   */\n  this.handler = opt_handler;\n\n  /**\n   * The key of the listener.\n   * @const {number}\n   * @override\n   */\n  this.key = goog.events.ListenableKey.reserveKey();\n\n  /**\n   * Whether to remove the listener after it has been called.\n   * @type {boolean}\n   */\n  this.callOnce = false;\n\n  /**\n   * Whether the listener has been removed.\n   * @type {boolean}\n   */\n  this.removed = false;\n};\n\n\n/**\n * @define {boolean} Whether to enable the monitoring of the\n *     goog.events.Listener instances. Switching on the monitoring is only\n *     recommended for debugging because it has a significant impact on\n *     performance and memory usage. If switched off, the monitoring code\n *     compiles down to 0 bytes.\n */\ngoog.events.Listener.ENABLE_MONITORING =\n    goog.define('goog.events.Listener.ENABLE_MONITORING', false);\n\n\n/**\n * If monitoring the goog.events.Listener instances is enabled, stores the\n * creation stack trace of the Disposable instance.\n * @type {string}\n */\ngoog.events.Listener.prototype.creationStack;\n\n\n/**\n * Marks this listener as removed. This also remove references held by\n * this listener object (such as listener and event source).\n */\ngoog.events.Listener.prototype.markAsRemoved = function() {\n  this.removed = true;\n  this.listener = null;\n  this.proxy = null;\n  this.src = null;\n  this.handler = null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A map of listeners that provides utility functions to\n * deal with listeners on an event target. Used by\n * `goog.events.EventTarget`.\n *\n * WARNING: Do not use this class from outside goog.events package.\n *\n */\n\ngoog.provide('goog.events.ListenerMap');\n\ngoog.require('goog.array');\ngoog.require('goog.events.Listener');\ngoog.require('goog.object');\n\n\n\n/**\n * Creates a new listener map.\n * @param {EventTarget|goog.events.Listenable} src The src object.\n * @constructor\n * @final\n */\ngoog.events.ListenerMap = function(src) {\n  /** @type {EventTarget|goog.events.Listenable} */\n  this.src = src;\n\n  /**\n   * Maps of event type to an array of listeners.\n   * @type {!Object<string, !Array<!goog.events.Listener>>}\n   */\n  this.listeners = {};\n\n  /**\n   * The count of types in this map that have registered listeners.\n   * @private {number}\n   */\n  this.typeCount_ = 0;\n};\n\n\n/**\n * @return {number} The count of event types in this map that actually\n *     have registered listeners.\n */\ngoog.events.ListenerMap.prototype.getTypeCount = function() {\n  return this.typeCount_;\n};\n\n\n/**\n * @return {number} Total number of registered listeners.\n */\ngoog.events.ListenerMap.prototype.getListenerCount = function() {\n  var count = 0;\n  for (var type in this.listeners) {\n    count += this.listeners[type].length;\n  }\n  return count;\n};\n\n\n/**\n * Adds an event listener. A listener can only be added once to an\n * object and if it is added again the key for the listener is\n * returned.\n *\n * Note that a one-off listener will not change an existing listener,\n * if any. On the other hand a normal listener will change existing\n * one-off listener to become a normal listener.\n *\n * @param {string|!goog.events.EventId} type The listener event type.\n * @param {!Function} listener This listener callback method.\n * @param {boolean} callOnce Whether the listener is a one-off\n *     listener.\n * @param {boolean=} opt_useCapture The capture mode of the listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n */\ngoog.events.ListenerMap.prototype.add = function(\n    type, listener, callOnce, opt_useCapture, opt_listenerScope) {\n  var typeStr = type.toString();\n  var listenerArray = this.listeners[typeStr];\n  if (!listenerArray) {\n    listenerArray = this.listeners[typeStr] = [];\n    this.typeCount_++;\n  }\n\n  var listenerObj;\n  var index = goog.events.ListenerMap.findListenerIndex_(\n      listenerArray, listener, opt_useCapture, opt_listenerScope);\n  if (index > -1) {\n    listenerObj = listenerArray[index];\n    if (!callOnce) {\n      // Ensure that, if there is an existing callOnce listener, it is no\n      // longer a callOnce listener.\n      listenerObj.callOnce = false;\n    }\n  } else {\n    listenerObj = new goog.events.Listener(\n        listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);\n    listenerObj.callOnce = callOnce;\n    listenerArray.push(listenerObj);\n  }\n  return listenerObj;\n};\n\n\n/**\n * Removes a matching listener.\n * @param {string|!goog.events.EventId} type The listener event type.\n * @param {!Function} listener This listener callback method.\n * @param {boolean=} opt_useCapture The capture mode of the listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {boolean} Whether any listener was removed.\n */\ngoog.events.ListenerMap.prototype.remove = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  var typeStr = type.toString();\n  if (!(typeStr in this.listeners)) {\n    return false;\n  }\n\n  var listenerArray = this.listeners[typeStr];\n  var index = goog.events.ListenerMap.findListenerIndex_(\n      listenerArray, listener, opt_useCapture, opt_listenerScope);\n  if (index > -1) {\n    var listenerObj = listenerArray[index];\n    listenerObj.markAsRemoved();\n    goog.array.removeAt(listenerArray, index);\n    if (listenerArray.length == 0) {\n      delete this.listeners[typeStr];\n      this.typeCount_--;\n    }\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Removes the given listener object.\n * @param {!goog.events.ListenableKey} listener The listener to remove.\n * @return {boolean} Whether the listener is removed.\n */\ngoog.events.ListenerMap.prototype.removeByKey = function(listener) {\n  var type = listener.type;\n  if (!(type in this.listeners)) {\n    return false;\n  }\n\n  var removed = goog.array.remove(this.listeners[type], listener);\n  if (removed) {\n    /** @type {!goog.events.Listener} */ (listener).markAsRemoved();\n    if (this.listeners[type].length == 0) {\n      delete this.listeners[type];\n      this.typeCount_--;\n    }\n  }\n  return removed;\n};\n\n\n/**\n * Removes all listeners from this map. If opt_type is provided, only\n * listeners that match the given type are removed.\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove.\n * @return {number} Number of listeners removed.\n */\ngoog.events.ListenerMap.prototype.removeAll = function(opt_type) {\n  var typeStr = opt_type && opt_type.toString();\n  var count = 0;\n  for (var type in this.listeners) {\n    if (!typeStr || type == typeStr) {\n      var listenerArray = this.listeners[type];\n      for (var i = 0; i < listenerArray.length; i++) {\n        ++count;\n        listenerArray[i].markAsRemoved();\n      }\n      delete this.listeners[type];\n      this.typeCount_--;\n    }\n  }\n  return count;\n};\n\n\n/**\n * Gets all listeners that match the given type and capture mode. The\n * returned array is a copy (but the listener objects are not).\n * @param {string|!goog.events.EventId} type The type of the listeners\n *     to retrieve.\n * @param {boolean} capture The capture mode of the listeners to retrieve.\n * @return {!Array<!goog.events.ListenableKey>} An array of matching\n *     listeners.\n */\ngoog.events.ListenerMap.prototype.getListeners = function(type, capture) {\n  var listenerArray = this.listeners[type.toString()];\n  var rv = [];\n  if (listenerArray) {\n    for (var i = 0; i < listenerArray.length; ++i) {\n      var listenerObj = listenerArray[i];\n      if (listenerObj.capture == capture) {\n        rv.push(listenerObj);\n      }\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Gets the goog.events.ListenableKey for the event or null if no such\n * listener is in use.\n *\n * @param {string|!goog.events.EventId} type The type of the listener\n *     to retrieve.\n * @param {!Function} listener The listener function to get.\n * @param {boolean} capture Whether the listener is a capturing listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n *     listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n */\ngoog.events.ListenerMap.prototype.getListener = function(\n    type, listener, capture, opt_listenerScope) {\n  var listenerArray = this.listeners[type.toString()];\n  var i = -1;\n  if (listenerArray) {\n    i = goog.events.ListenerMap.findListenerIndex_(\n        listenerArray, listener, capture, opt_listenerScope);\n  }\n  return i > -1 ? listenerArray[i] : null;\n};\n\n\n/**\n * Whether there is a matching listener. If either the type or capture\n * parameters are unspecified, the function will match on the\n * remaining criteria.\n *\n * @param {string|!goog.events.EventId=} opt_type The type of the listener.\n * @param {boolean=} opt_capture The capture mode of the listener.\n * @return {boolean} Whether there is an active listener matching\n *     the requested type and/or capture phase.\n */\ngoog.events.ListenerMap.prototype.hasListener = function(\n    opt_type, opt_capture) {\n  var hasType = (opt_type !== undefined);\n  var typeStr = hasType ? opt_type.toString() : '';\n  var hasCapture = (opt_capture !== undefined);\n\n  return goog.object.some(this.listeners, function(listenerArray, type) {\n    for (var i = 0; i < listenerArray.length; ++i) {\n      if ((!hasType || listenerArray[i].type == typeStr) &&\n          (!hasCapture || listenerArray[i].capture == opt_capture)) {\n        return true;\n      }\n    }\n\n    return false;\n  });\n};\n\n\n/**\n * Finds the index of a matching goog.events.Listener in the given\n * listenerArray.\n * @param {!Array<!goog.events.Listener>} listenerArray Array of listener.\n * @param {!Function} listener The listener function.\n * @param {boolean=} opt_useCapture The capture flag for the listener.\n * @param {Object=} opt_listenerScope The listener scope.\n * @return {number} The index of the matching listener within the\n *     listenerArray.\n * @private\n */\ngoog.events.ListenerMap.findListenerIndex_ = function(\n    listenerArray, listener, opt_useCapture, opt_listenerScope) {\n  for (var i = 0; i < listenerArray.length; ++i) {\n    var listenerObj = listenerArray[i];\n    if (!listenerObj.removed && listenerObj.listener == listener &&\n        listenerObj.capture == !!opt_useCapture &&\n        listenerObj.handler == opt_listenerScope) {\n      return i;\n    }\n  }\n  return -1;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An event manager for both native browser event\n * targets and custom JavaScript event targets\n * (`goog.events.Listenable`). This provides an abstraction\n * over browsers' event systems.\n *\n * It also provides a simulation of W3C event model's capture phase in\n * Internet Explorer (IE 8 and below). Caveat: the simulation does not\n * interact well with listeners registered directly on the elements\n * (bypassing goog.events) or even with listeners registered via\n * goog.events in a separate JS binary. In these cases, we provide\n * no ordering guarantees.\n *\n * The listeners will receive a \"patched\" event object. Such event object\n * contains normalized values for certain event properties that differs in\n * different browsers.\n *\n * Example usage:\n * <pre>\n * goog.events.listen(myNode, 'click', function(e) { alert('woo') });\n * goog.events.listen(myNode, 'mouseover', mouseHandler, true);\n * goog.events.unlisten(myNode, 'mouseover', mouseHandler, true);\n * goog.events.removeAll(myNode);\n * </pre>\n *\n *                                            in IE and event object patching]\n *\n * @see ../demos/events.html\n * @see ../demos/event-propagation.html\n * @see ../demos/stopevent.html\n */\n\n// IMPLEMENTATION NOTES:\n// goog.events stores an auxiliary data structure on each EventTarget\n// source being listened on. This allows us to take advantage of GC,\n// having the data structure GC'd when the EventTarget is GC'd. This\n// GC behavior is equivalent to using W3C DOM Events directly.\n\ngoog.provide('goog.events');\ngoog.provide('goog.events.CaptureSimulationMode');\ngoog.provide('goog.events.Key');\ngoog.provide('goog.events.ListenableType');\n\ngoog.require('goog.asserts');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.BrowserEvent');\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\ngoog.requireType('goog.debug.ErrorHandler');\ngoog.requireType('goog.events.EventWrapper');\n\n\n/**\n * @typedef {number|goog.events.ListenableKey}\n */\ngoog.events.Key;\n\n\n/**\n * @typedef {EventTarget|goog.events.Listenable}\n */\ngoog.events.ListenableType;\n\n\n/**\n * Property name on a native event target for the listener map\n * associated with the event target.\n * @private @const {string}\n */\ngoog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0);\n\n\n/**\n * String used to prepend to IE event types.\n * @const\n * @private\n */\ngoog.events.onString_ = 'on';\n\n\n/**\n * Map of computed \"on<eventname>\" strings for IE event types. Caching\n * this removes an extra object allocation in goog.events.listen which\n * improves IE6 performance.\n * @const\n * @dict\n * @private\n */\ngoog.events.onStringMap_ = {};\n\n\n/**\n * @enum {number} Different capture simulation mode for IE8-.\n */\ngoog.events.CaptureSimulationMode = {\n  /**\n   * Does not perform capture simulation. Will asserts in IE8- when you\n   * add capture listeners.\n   */\n  OFF_AND_FAIL: 0,\n\n  /**\n   * Does not perform capture simulation, silently ignore capture\n   * listeners.\n   */\n  OFF_AND_SILENT: 1,\n\n  /**\n   * Performs capture simulation.\n   */\n  ON: 2\n};\n\n\n/**\n * @define {number} The capture simulation mode for IE8-. By default,\n *     this is ON.\n */\ngoog.events.CAPTURE_SIMULATION_MODE =\n    goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2);\n\n\n/**\n * Estimated count of total native listeners.\n * @private {number}\n */\ngoog.events.listenerCountEstimate_ = 0;\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. A listener can only be added once\n * to an object and if it is added again the key for the listener is\n * returned. Note that if the existing listener is a one-off listener\n * (registered via listenOnce), it will no longer be a one-off\n * listener after a call to listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n *     to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n *     listener Callback method, or an object with a handleEvent function.\n *     WARNING: passing an Object is now softly deprecated.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n */\ngoog.events.listen = function(src, type, listener, opt_options, opt_handler) {\n  if (opt_options && opt_options.once) {\n    return goog.events.listenOnce(\n        src, type, listener, opt_options, opt_handler);\n  }\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.listen(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    var capture =\n        goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n    return src.listen(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  } else {\n    return goog.events.listen_(\n        /** @type {!EventTarget} */ (src), type, listener,\n        /* callOnce */ false, opt_options, opt_handler);\n  }\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target. A listener can only be added once to an object and if it\n * is added again the key for the listener is returned.\n *\n * Note that a one-off listener will not change an existing listener,\n * if any. On the other hand a normal listener will change existing\n * one-off listener to become a normal listener.\n *\n * @param {EventTarget} src The node to listen to events on.\n * @param {string|?goog.events.EventId<EVENTOBJ>} type Event type.\n * @param {!Function} listener Callback function.\n * @param {boolean} callOnce Whether the listener is a one-off\n *     listener or otherwise.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} Unique key for the listener.\n * @template EVENTOBJ\n * @private\n */\ngoog.events.listen_ = function(\n    src, type, listener, callOnce, opt_options, opt_handler) {\n  if (!type) {\n    throw new Error('Invalid event type');\n  }\n\n  var capture =\n      goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n  if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n    if (goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.OFF_AND_FAIL) {\n      goog.asserts.fail('Can not register capture listener in IE8-.');\n      return null;\n    } else if (\n        goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.OFF_AND_SILENT) {\n      return null;\n    }\n  }\n\n  var listenerMap = goog.events.getListenerMap_(src);\n  if (!listenerMap) {\n    src[goog.events.LISTENER_MAP_PROP_] = listenerMap =\n        new goog.events.ListenerMap(src);\n  }\n\n  var listenerObj = /** @type {goog.events.Listener} */ (\n      listenerMap.add(type, listener, callOnce, capture, opt_handler));\n\n  // If the listenerObj already has a proxy, it has been set up\n  // previously. We simply return.\n  if (listenerObj.proxy) {\n    return listenerObj;\n  }\n\n  var proxy = goog.events.getProxy();\n  listenerObj.proxy = proxy;\n\n  proxy.src = src;\n  proxy.listener = listenerObj;\n\n  // Attach the proxy through the browser's API\n  if (src.addEventListener) {\n    // Don't pass an object as `capture` if the browser doesn't support that.\n    if (!goog.events.BrowserFeature.PASSIVE_EVENTS) {\n      opt_options = capture;\n    }\n    // Don't break tests that expect a boolean.\n    if (opt_options === undefined) opt_options = false;\n    src.addEventListener(type.toString(), proxy, opt_options);\n  } else if (src.attachEvent) {\n    // The else if above used to be an unconditional else. It would call\n    // attachEvent come gws or high water. This would sometimes throw an\n    // exception on IE11, spoiling the day of some callers. The previous\n    // incarnation of this code, from 2007, indicates that it replaced an\n    // earlier still version that caused excess allocations on IE6.\n    src.attachEvent(goog.events.getOnString_(type.toString()), proxy);\n  } else if (src.addListener && src.removeListener) {\n    // In IE, MediaQueryList uses addListener() insteadd of addEventListener. In\n    // Safari, there is no global for the MediaQueryList constructor, so we just\n    // check whether the object \"looks like\" MediaQueryList.\n    goog.asserts.assert(\n        type === 'change', 'MediaQueryList only has a change event');\n    src.addListener(proxy);\n  } else {\n    throw new Error('addEventListener and attachEvent are unavailable.');\n  }\n\n  goog.events.listenerCountEstimate_++;\n  return listenerObj;\n};\n\n\n/**\n * Helper function for returning a proxy function.\n * @return {!Function} A new or reused function object.\n */\ngoog.events.getProxy = function() {\n  var proxyCallbackFunction = goog.events.handleBrowserEvent_;\n  // Use a local var f to prevent one allocation.\n  var f =\n      goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) {\n        return proxyCallbackFunction.call(f.src, f.listener, eventObject);\n      } : function(eventObject) {\n        var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);\n        // NOTE(chrishenry): In IE, we hack in a capture phase. However, if\n        // there is inline event handler which tries to prevent default (for\n        // example <a href=\"...\" onclick=\"return false\">...</a>) in a\n        // descendant element, the prevent default will be overridden\n        // by this listener if this listener were to return true. Hence, we\n        // return undefined.\n        if (!v) return v;\n      };\n  return f;\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. After the event has fired the event\n * listener is removed from the target.\n *\n * If an existing listener already exists, listenOnce will do\n * nothing. In particular, if the listener was previously registered\n * via listen(), listenOnce() will not turn the listener into a\n * one-off listener. Similarly, if there is already an existing\n * one-off listener, listenOnce does not modify the listeners (it is\n * still a once listener).\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n *     to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n *     listener Callback method.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n */\ngoog.events.listenOnce = function(\n    src, type, listener, opt_options, opt_handler) {\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.listenOnce(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    var capture =\n        goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n    return src.listenOnce(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  } else {\n    return goog.events.listen_(\n        /** @type {!EventTarget} */ (src), type, listener,\n        /* callOnce */ true, opt_options, opt_handler);\n  }\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.Listenable}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.Listenable} src The target to\n *     listen to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener\n *     Callback method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n *     false).\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @template T\n */\ngoog.events.listenWithWrapper = function(\n    src, wrapper, listener, opt_capt, opt_handler) {\n  wrapper.listen(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes an event listener which was added with listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n *     listening to events on.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types to unlisten to.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to remove.\n * @param {(boolean|!EventListenerOptions)=} opt_options\n *     whether the listener is fired during the capture or bubble phase of the\n *     event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {?boolean} indicating whether the listener was there to remove.\n * @template EVENTOBJ\n */\ngoog.events.unlisten = function(src, type, listener, opt_options, opt_handler) {\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      goog.events.unlisten(src, type[i], listener, opt_options, opt_handler);\n    }\n    return null;\n  }\n  var capture =\n      goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n\n  listener = goog.events.wrapListener(listener);\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return src.unlisten(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n  }\n\n  if (!src) {\n    // TODO(chrishenry): We should tighten the API to only accept\n    // non-null objects, or add an assertion here.\n    return false;\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  if (listenerMap) {\n    var listenerObj = listenerMap.getListener(\n        /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n        opt_handler);\n    if (listenerObj) {\n      return goog.events.unlistenByKey(listenerObj);\n    }\n  }\n\n  return false;\n};\n\n\n/**\n * Removes an event listener which was added with listen() by the key\n * returned by listen().\n *\n * @param {goog.events.Key} key The key returned by listen() for this\n *     event listener.\n * @return {boolean} indicating whether the listener was there to remove.\n */\ngoog.events.unlistenByKey = function(key) {\n  // TODO(chrishenry): Remove this check when tests that rely on this\n  // are fixed.\n  if (typeof key === 'number') {\n    return false;\n  }\n\n  var listener = key;\n  if (!listener || listener.removed) {\n    return false;\n  }\n\n  var src = listener.src;\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return /** @type {!goog.events.Listenable} */ (src).unlistenByKey(listener);\n  }\n\n  var type = listener.type;\n  var proxy = listener.proxy;\n  if (src.removeEventListener) {\n    src.removeEventListener(type, proxy, listener.capture);\n  } else if (src.detachEvent) {\n    src.detachEvent(goog.events.getOnString_(type), proxy);\n  } else if (src.addListener && src.removeListener) {\n    src.removeListener(proxy);\n  }\n  goog.events.listenerCountEstimate_--;\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  // TODO(chrishenry): Try to remove this conditional and execute the\n  // first branch always. This should be safe.\n  if (listenerMap) {\n    listenerMap.removeByKey(listener);\n    if (listenerMap.getTypeCount() == 0) {\n      // Null the src, just because this is simple to do (and useful\n      // for IE <= 7).\n      listenerMap.src = null;\n      // We don't use delete here because IE does not allow delete\n      // on a window object.\n      src[goog.events.LISTENER_MAP_PROP_] = null;\n    }\n  } else {\n    /** @type {!goog.events.Listener} */ (listener).markAsRemoved();\n  }\n\n  return true;\n};\n\n\n/**\n * Removes an event listener which was added with listenWithWrapper().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n *     listening to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to remove.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase of the\n *     event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n */\ngoog.events.unlistenWithWrapper = function(\n    src, wrapper, listener, opt_capt, opt_handler) {\n  wrapper.unlisten(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes all listeners from an object. You can also optionally\n * remove listeners of a particular type.\n *\n * @param {Object|undefined} obj Object to remove listeners from. Must be an\n *     EventTarget or a goog.events.Listenable.\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove.\n *     Default is all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.removeAll = function(obj, opt_type) {\n  // TODO(chrishenry): Change the type of obj to\n  // (!EventTarget|!goog.events.Listenable).\n\n  if (!obj) {\n    return 0;\n  }\n\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {?} */ (obj).removeAllListeners(opt_type);\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (obj));\n  if (!listenerMap) {\n    return 0;\n  }\n\n  var count = 0;\n  var typeStr = opt_type && opt_type.toString();\n  for (var type in listenerMap.listeners) {\n    if (!typeStr || type == typeStr) {\n      // Clone so that we don't need to worry about unlistenByKey\n      // changing the content of the ListenerMap.\n      var listeners = listenerMap.listeners[type].concat();\n      for (var i = 0; i < listeners.length; ++i) {\n        if (goog.events.unlistenByKey(listeners[i])) {\n          ++count;\n        }\n      }\n    }\n  }\n  return count;\n};\n\n\n/**\n * Gets the listeners for a given object, type and capture phase.\n *\n * @param {Object} obj Object to get listeners for.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Capture phase?.\n * @return {!Array<!goog.events.Listener>} Array of listener objects.\n */\ngoog.events.getListeners = function(obj, type, capture) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {!goog.events.Listenable} */ (obj).getListeners(\n        type, capture);\n  } else {\n    if (!obj) {\n      // TODO(chrishenry): We should tighten the API to accept\n      // !EventTarget|goog.events.Listenable, and add an assertion here.\n      return [];\n    }\n\n    var listenerMap = goog.events.getListenerMap_(\n        /** @type {!EventTarget} */ (obj));\n    return listenerMap ? listenerMap.getListeners(type, capture) : [];\n  }\n};\n\n\n/**\n * Gets the goog.events.Listener for the event or null if no such listener is\n * in use.\n *\n * @param {EventTarget|goog.events.Listenable} src The target from\n *     which to get listeners.\n * @param {?string|!goog.events.EventId<EVENTOBJ>} type The type of the event.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to get.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n *                            whether the listener is fired during the\n *                            capture or bubble phase of the event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n * @template EVENTOBJ\n */\ngoog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {\n  // TODO(chrishenry): Change type from ?string to string, or add assertion.\n  type = /** @type {string} */ (type);\n  listener = goog.events.wrapListener(listener);\n  var capture = !!opt_capt;\n  if (goog.events.Listenable.isImplementedBy(src)) {\n    return src.getListener(type, listener, capture, opt_handler);\n  }\n\n  if (!src) {\n    // TODO(chrishenry): We should tighten the API to only accept\n    // non-null objects, or add an assertion here.\n    return null;\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (src));\n  if (listenerMap) {\n    return listenerMap.getListener(type, listener, capture, opt_handler);\n  }\n  return null;\n};\n\n\n/**\n * Returns whether an event target has any active listeners matching the\n * specified signature. If either the type or capture parameters are\n * unspecified, the function will match on the remaining criteria.\n *\n * @param {EventTarget|goog.events.Listenable} obj Target to get\n *     listeners for.\n * @param {string|!goog.events.EventId=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble-phase\n *     listeners.\n * @return {boolean} Whether an event target has one or more listeners matching\n *     the requested type and/or capture phase.\n */\ngoog.events.hasListener = function(obj, opt_type, opt_capture) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return obj.hasListener(opt_type, opt_capture);\n  }\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {!EventTarget} */ (obj));\n  return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);\n};\n\n\n/**\n * Provides a nice string showing the normalized event objects public members\n * @param {Object} e Event Object.\n * @return {string} String of the public members of the normalized event object.\n */\ngoog.events.expose = function(e) {\n  var str = [];\n  for (var key in e) {\n    if (e[key] && e[key].id) {\n      str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')');\n    } else {\n      str.push(key + ' = ' + e[key]);\n    }\n  }\n  return str.join('\\n');\n};\n\n\n/**\n * Returns a string with on prepended to the specified type. This is used for IE\n * which expects \"on\" to be prepended. This function caches the string in order\n * to avoid extra allocations in steady state.\n * @param {string} type Event type.\n * @return {string} The type string with 'on' prepended.\n * @private\n */\ngoog.events.getOnString_ = function(type) {\n  if (type in goog.events.onStringMap_) {\n    return goog.events.onStringMap_[type];\n  }\n  return goog.events.onStringMap_[type] = goog.events.onString_ + type;\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase\n *\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n */\ngoog.events.fireListeners = function(obj, type, capture, eventObject) {\n  if (goog.events.Listenable.isImplementedBy(obj)) {\n    return /** @type {!goog.events.Listenable} */ (obj).fireListeners(\n        type, capture, eventObject);\n  }\n\n  return goog.events.fireListeners_(obj, type, capture, eventObject);\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase.\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n * @private\n */\ngoog.events.fireListeners_ = function(obj, type, capture, eventObject) {\n  /** @type {boolean} */\n  var retval = true;\n\n  var listenerMap = goog.events.getListenerMap_(\n      /** @type {EventTarget} */ (obj));\n  if (listenerMap) {\n    // TODO(chrishenry): Original code avoids array creation when there\n    // is no listener, so we do the same. If this optimization turns\n    // out to be not required, we can replace this with\n    // listenerMap.getListeners(type, capture) instead, which is simpler.\n    var listenerArray = listenerMap.listeners[type.toString()];\n    if (listenerArray) {\n      listenerArray = listenerArray.concat();\n      for (var i = 0; i < listenerArray.length; i++) {\n        var listener = listenerArray[i];\n        // We might not have a listener if the listener was removed.\n        if (listener && listener.capture == capture && !listener.removed) {\n          var result = goog.events.fireListener(listener, eventObject);\n          retval = retval && (result !== false);\n        }\n      }\n    }\n  }\n  return retval;\n};\n\n\n/**\n * Fires a listener with a set of arguments\n *\n * @param {goog.events.Listener} listener The listener object to call.\n * @param {Object} eventObject The event object to pass to the listener.\n * @return {*} Result of listener.\n */\ngoog.events.fireListener = function(listener, eventObject) {\n  var listenerFn = listener.listener;\n  var listenerHandler = listener.handler || listener.src;\n\n  if (listener.callOnce) {\n    goog.events.unlistenByKey(listener);\n  }\n  return listenerFn.call(listenerHandler, eventObject);\n};\n\n\n/**\n * Gets the total number of listeners currently in the system.\n * @return {number} Number of listeners.\n * @deprecated This returns estimated count, now that Closure no longer\n * stores a central listener registry. We still return an estimation\n * to keep existing listener-related tests passing. In the near future,\n * this function will be removed.\n */\ngoog.events.getTotalListenerCount = function() {\n  return goog.events.listenerCountEstimate_;\n};\n\n\n/**\n * Dispatches an event (or event like object) and calls all listeners\n * listening for events of this type. The type of the event is decided by the\n * type property on the event object.\n *\n * If any of the listeners returns false OR calls preventDefault then this\n * function will return false.  If one of the capture listeners calls\n * stopPropagation, then the bubble listeners won't fire.\n *\n * @param {goog.events.Listenable} src The event target.\n * @param {goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n *     if any of the handlers returns false) this will also return false.\n *     If there are no handlers, or if all handlers return true, this returns\n *     true.\n */\ngoog.events.dispatchEvent = function(src, e) {\n  goog.asserts.assert(\n      goog.events.Listenable.isImplementedBy(src),\n      'Can not use goog.events.dispatchEvent with ' +\n          'non-goog.events.Listenable instance.');\n  return src.dispatchEvent(e);\n};\n\n\n/**\n * Installs exception protection for the browser event entry point using the\n * given error handler.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n *     protect the entry point.\n */\ngoog.events.protectBrowserEventEntryPoint = function(errorHandler) {\n  goog.events.handleBrowserEvent_ =\n      errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_);\n};\n\n\n/**\n * Handles an event and dispatches it to the correct listeners. This\n * function is a proxy for the real listener the user specified.\n *\n * @param {goog.events.Listener} listener The listener object.\n * @param {Event=} opt_evt Optional event object that gets passed in via the\n *     native event handlers.\n * @return {*} Result of the event handler.\n * @this {EventTarget} The object or Element that fired the event.\n * @private\n */\ngoog.events.handleBrowserEvent_ = function(listener, opt_evt) {\n  if (listener.removed) {\n    return true;\n  }\n\n  // Synthesize event propagation if the browser does not support W3C\n  // event model.\n  if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n    var ieEvent = opt_evt ||\n        /** @type {Event} */ (goog.getObjectByName('window.event'));\n    var evt = new goog.events.BrowserEvent(ieEvent, this);\n    /** @type {*} */\n    var retval = true;\n\n    if (goog.events.CAPTURE_SIMULATION_MODE ==\n        goog.events.CaptureSimulationMode.ON) {\n      // If we have not marked this event yet, we should perform capture\n      // simulation.\n      if (!goog.events.isMarkedIeEvent_(ieEvent)) {\n        goog.events.markIeEvent_(ieEvent);\n\n        var ancestors = [];\n        for (var parent = evt.currentTarget; parent;\n             parent = parent.parentNode) {\n          ancestors.push(parent);\n        }\n\n        // Fire capture listeners.\n        var type = listener.type;\n        for (var i = ancestors.length - 1;\n             !evt.hasPropagationStopped() && i >= 0; i--) {\n          evt.currentTarget = ancestors[i];\n          var result =\n              goog.events.fireListeners_(ancestors[i], type, true, evt);\n          retval = retval && result;\n        }\n\n        // Fire bubble listeners.\n        //\n        // We can technically rely on IE to perform bubble event\n        // propagation. However, it turns out that IE fires events in\n        // opposite order of attachEvent registration, which broke\n        // some code and tests that rely on the order. (While W3C DOM\n        // Level 2 Events TR leaves the event ordering unspecified,\n        // modern browsers and W3C DOM Level 3 Events Working Draft\n        // actually specify the order as the registration order.)\n        for (var i = 0; !evt.hasPropagationStopped() && i < ancestors.length;\n             i++) {\n          evt.currentTarget = ancestors[i];\n          var result =\n              goog.events.fireListeners_(ancestors[i], type, false, evt);\n          retval = retval && result;\n        }\n      }\n    } else {\n      retval = goog.events.fireListener(listener, evt);\n    }\n    return retval;\n  }\n\n  // Otherwise, simply fire the listener.\n  return goog.events.fireListener(\n      listener, new goog.events.BrowserEvent(opt_evt, this));\n};\n\n\n/**\n * This is used to mark the IE event object so we do not do the Closure pass\n * twice for a bubbling event.\n * @param {Event} e The IE browser event.\n * @private\n */\ngoog.events.markIeEvent_ = function(e) {\n  // Only the keyCode and the returnValue can be changed. We use keyCode for\n  // non keyboard events.\n  // event.returnValue is a bit more tricky. It is undefined by default. A\n  // boolean false prevents the default action. In a window.onbeforeunload and\n  // the returnValue is non undefined it will be alerted. However, we will only\n  // modify the returnValue for keyboard events. We can get a problem if non\n  // closure events sets the keyCode or the returnValue\n\n  var useReturnValue = false;\n\n  if (e.keyCode == 0) {\n    // We cannot change the keyCode in case that srcElement is input[type=file].\n    // We could test that that is the case but that would allocate 3 objects.\n    // If we use try/catch we will only allocate extra objects in the case of a\n    // failure.\n\n    try {\n      e.keyCode = -1;\n      return;\n    } catch (ex) {\n      useReturnValue = true;\n    }\n  }\n\n  if (useReturnValue ||\n      /** @type {boolean|undefined} */ (e.returnValue) == undefined) {\n    e.returnValue = true;\n  }\n};\n\n\n/**\n * This is used to check if an IE event has already been handled by the Closure\n * system so we do not do the Closure pass twice for a bubbling event.\n * @param {Event} e  The IE browser event.\n * @return {boolean} True if the event object has been marked.\n * @private\n */\ngoog.events.isMarkedIeEvent_ = function(e) {\n  return e.keyCode < 0 || e.returnValue != undefined;\n};\n\n\n/**\n * Counter to create unique event ids.\n * @private {number}\n */\ngoog.events.uniqueIdCounter_ = 0;\n\n\n/**\n * Creates a unique event id.\n *\n * @param {string} identifier The identifier.\n * @return {string} A unique identifier.\n * @idGenerator {unique}\n */\ngoog.events.getUniqueId = function(identifier) {\n  return identifier + '_' + goog.events.uniqueIdCounter_++;\n};\n\n\n/**\n * @param {EventTarget} src The source object.\n * @return {goog.events.ListenerMap} A listener map for the given\n *     source object, or null if none exists.\n * @private\n */\ngoog.events.getListenerMap_ = function(src) {\n  var listenerMap = src[goog.events.LISTENER_MAP_PROP_];\n  // IE serializes the property as well (e.g. when serializing outer\n  // HTML). So we must check that the value is of the correct type.\n  return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;\n};\n\n\n/**\n * Expando property for listener function wrapper for Object with\n * handleEvent.\n * @private @const {string}\n */\ngoog.events.LISTENER_WRAPPER_PROP_ =\n    '__closure_events_fn_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * @param {Object|Function} listener The listener function or an\n *     object that contains handleEvent method.\n * @return {!Function} Either the original function or a function that\n *     calls obj.handleEvent. If the same listener is passed to this\n *     function more than once, the same function is guaranteed to be\n *     returned.\n */\ngoog.events.wrapListener = function(listener) {\n  goog.asserts.assert(listener, 'Listener can not be null.');\n\n  if (goog.isFunction(listener)) {\n    return listener;\n  }\n\n  goog.asserts.assert(\n      listener.handleEvent, 'An object listener must have handleEvent method.');\n  if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {\n    listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {\n      return /** @type {?} */ (listener).handleEvent(e);\n    };\n  }\n  return listener[goog.events.LISTENER_WRAPPER_PROP_];\n};\n\n\n// Register the browser event handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) {\n      goog.events.handleBrowserEvent_ =\n          transformer(goog.events.handleBrowserEvent_);\n    });\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A disposable implementation of a custom\n * listenable/event target. See also: documentation for\n * `goog.events.Listenable`.\n *\n * @see ../demos/eventtarget.html\n * @see goog.events.Listenable\n */\n\ngoog.provide('goog.events.EventTarget');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.asserts');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\ngoog.require('goog.object');\n\n\n\n/**\n * An implementation of `goog.events.Listenable` with full W3C\n * EventTarget-like support (capture/bubble mechanism, stopping event\n * propagation, preventing default actions).\n *\n * You may subclass this class to turn your class into a Listenable.\n *\n * Unless propagation is stopped, an event dispatched by an\n * EventTarget will bubble to the parent returned by\n * `getParentEventTarget`. To set the parent, call\n * `setParentEventTarget`. Subclasses that don't support\n * changing the parent can override the setter to throw an error.\n *\n * Example usage:\n * <pre>\n *   var source = new goog.events.EventTarget();\n *   function handleEvent(e) {\n *     alert('Type: ' + e.type + '; Target: ' + e.target);\n *   }\n *   source.listen('foo', handleEvent);\n *   // Or: goog.events.listen(source, 'foo', handleEvent);\n *   ...\n *   source.dispatchEvent('foo');  // will call handleEvent\n *   ...\n *   source.unlisten('foo', handleEvent);\n *   // Or: goog.events.unlisten(source, 'foo', handleEvent);\n * </pre>\n *\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.events.Listenable}\n */\ngoog.events.EventTarget = function() {\n  goog.Disposable.call(this);\n\n  /**\n   * Maps of event type to an array of listeners.\n   * @private {!goog.events.ListenerMap}\n   */\n  this.eventTargetListeners_ = new goog.events.ListenerMap(this);\n\n  /**\n   * The object to use for event.target. Useful when mixing in an\n   * EventTarget to another object.\n   * @private {!Object}\n   */\n  this.actualEventTarget_ = this;\n\n  /**\n   * Parent event target, used during event bubbling.\n   *\n   * TODO(chrishenry): Change this to goog.events.Listenable. This\n   * currently breaks people who expect getParentEventTarget to return\n   * goog.events.EventTarget.\n   *\n   * @private {?goog.events.EventTarget}\n   */\n  this.parentEventTarget_ = null;\n};\ngoog.inherits(goog.events.EventTarget, goog.Disposable);\ngoog.events.Listenable.addImplementation(goog.events.EventTarget);\n\n\n/**\n * An artificial cap on the number of ancestors you can have. This is mainly\n * for loop detection.\n * @const {number}\n * @private\n */\ngoog.events.EventTarget.MAX_ANCESTORS_ = 1000;\n\n\n/**\n * Returns the parent of this event target to use for bubbling.\n *\n * @return {goog.events.EventTarget} The parent EventTarget or null if\n *     there is no parent.\n * @override\n */\ngoog.events.EventTarget.prototype.getParentEventTarget = function() {\n  return this.parentEventTarget_;\n};\n\n\n/**\n * Sets the parent of this event target to use for capture/bubble\n * mechanism.\n * @param {goog.events.EventTarget} parent Parent listenable (null if none).\n */\ngoog.events.EventTarget.prototype.setParentEventTarget = function(parent) {\n  this.parentEventTarget_ = parent;\n};\n\n\n/**\n * Adds an event listener to the event target. The same handler can only be\n * added once per the type. Even if you add the same handler multiple times\n * using the same type then it will only be called once when the event is\n * dispatched.\n *\n * @param {string|!goog.events.EventId} type The type of the event to listen for\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n *     to handle the event. The handler can also be an object that implements\n *     the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase\n *     of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n *     the listener.\n * @deprecated Use `#listen` instead, when possible. Otherwise, use\n *     `goog.events.listen` if you are passing Object\n *     (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.addEventListener = function(\n    type, handler, opt_capture, opt_handlerScope) {\n  goog.events.listen(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/**\n * Removes an event listener from the event target. The handler must be the\n * same object as the one added. If the handler has not been added then\n * nothing is done.\n *\n * @param {string} type The type of the event to listen for.\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n *     to handle the event. The handler can also be an object that implements\n *     the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase\n *     of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n *     the listener.\n * @deprecated Use `#unlisten` instead, when possible. Otherwise, use\n *     `goog.events.unlisten` if you are passing Object\n *     (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.removeEventListener = function(\n    type, handler, opt_capture, opt_handlerScope) {\n  goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.dispatchEvent = function(e) {\n  this.assertInitialized_();\n\n  var ancestorsTree, ancestor = this.getParentEventTarget();\n  if (ancestor) {\n    ancestorsTree = [];\n    var ancestorCount = 1;\n    for (; ancestor; ancestor = ancestor.getParentEventTarget()) {\n      ancestorsTree.push(ancestor);\n      goog.asserts.assert(\n          (++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_),\n          'infinite loop');\n    }\n  }\n\n  return goog.events.EventTarget.dispatchEventInternal_(\n      this.actualEventTarget_, e, ancestorsTree);\n};\n\n\n/**\n * Removes listeners from this object.  Classes that extend EventTarget may\n * need to override this method in order to remove references to DOM Elements\n * and additional listeners.\n * @override\n * @protected\n */\ngoog.events.EventTarget.prototype.disposeInternal = function() {\n  goog.events.EventTarget.superClass_.disposeInternal.call(this);\n\n  this.removeAllListeners();\n  this.parentEventTarget_ = null;\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listen = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  this.assertInitialized_();\n  return this.eventTargetListeners_.add(\n      String(type), listener, false /* callOnce */, opt_useCapture,\n      opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listenOnce = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  return this.eventTargetListeners_.add(\n      String(type), listener, true /* callOnce */, opt_useCapture,\n      opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlisten = function(\n    type, listener, opt_useCapture, opt_listenerScope) {\n  return this.eventTargetListeners_.remove(\n      String(type), listener, opt_useCapture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlistenByKey = function(key) {\n  return this.eventTargetListeners_.removeByKey(key);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {\n  // TODO(chrishenry): Previously, removeAllListeners can be called on\n  // uninitialized EventTarget, so we preserve that behavior. We\n  // should remove this when usages that rely on that fact are purged.\n  if (!this.eventTargetListeners_) {\n    return 0;\n  }\n  return this.eventTargetListeners_.removeAll(opt_type);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.fireListeners = function(\n    type, capture, eventObject) {\n  // TODO(chrishenry): Original code avoids array creation when there\n  // is no listener, so we do the same. If this optimization turns\n  // out to be not required, we can replace this with\n  // getListeners(type, capture) instead, which is simpler.\n  var listenerArray = this.eventTargetListeners_.listeners[String(type)];\n  if (!listenerArray) {\n    return true;\n  }\n  listenerArray = listenerArray.concat();\n\n  var rv = true;\n  for (var i = 0; i < listenerArray.length; ++i) {\n    var listener = listenerArray[i];\n    // We might not have a listener if the listener was removed.\n    if (listener && !listener.removed && listener.capture == capture) {\n      var listenerFn = listener.listener;\n      var listenerHandler = listener.handler || listener.src;\n\n      if (listener.callOnce) {\n        this.unlistenByKey(listener);\n      }\n      rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;\n    }\n  }\n\n  return rv && !eventObject.defaultPrevented;\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.getListeners = function(type, capture) {\n  return this.eventTargetListeners_.getListeners(String(type), capture);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.getListener = function(\n    type, listener, capture, opt_listenerScope) {\n  return this.eventTargetListeners_.getListener(\n      String(type), listener, capture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.hasListener = function(\n    opt_type, opt_capture) {\n  var id = (opt_type !== undefined) ? String(opt_type) : undefined;\n  return this.eventTargetListeners_.hasListener(id, opt_capture);\n};\n\n\n/**\n * Sets the target to be used for `event.target` when firing\n * event. Mainly used for testing. For example, see\n * `goog.testing.events.mixinListenable`.\n * @param {!Object} target The target.\n */\ngoog.events.EventTarget.prototype.setTargetForTesting = function(target) {\n  this.actualEventTarget_ = target;\n};\n\n\n/**\n * Asserts that the event target instance is initialized properly.\n * @private\n */\ngoog.events.EventTarget.prototype.assertInitialized_ = function() {\n  goog.asserts.assert(\n      this.eventTargetListeners_,\n      'Event target is not initialized. Did you call the superclass ' +\n          '(goog.events.EventTarget) constructor?');\n};\n\n\n/**\n * Dispatches the given event on the ancestorsTree.\n *\n * @param {!Object} target The target to dispatch on.\n * @param {goog.events.Event|Object|string} e The event object.\n * @param {Array<goog.events.Listenable>=} opt_ancestorsTree The ancestors\n *     tree of the target, in reverse order from the closest ancestor\n *     to the root event target. May be null if the target has no ancestor.\n * @return {boolean} If anyone called preventDefault on the event object (or\n *     if any of the listeners returns false) this will also return false.\n * @private\n */\ngoog.events.EventTarget.dispatchEventInternal_ = function(\n    target, e, opt_ancestorsTree) {\n  /** @suppress {missingProperties} */\n  var type = e.type || /** @type {string} */ (e);\n\n  // If accepting a string or object, create a custom event object so that\n  // preventDefault and stopPropagation work with the event.\n  if (typeof e === 'string') {\n    e = new goog.events.Event(e, target);\n  } else if (!(e instanceof goog.events.Event)) {\n    var oldEvent = e;\n    e = new goog.events.Event(type, target);\n    goog.object.extend(e, oldEvent);\n  } else {\n    e.target = e.target || target;\n  }\n\n  var rv = true, currentTarget;\n\n  // Executes all capture listeners on the ancestors, if any.\n  if (opt_ancestorsTree) {\n    for (var i = opt_ancestorsTree.length - 1;\n         !e.hasPropagationStopped() && i >= 0; i--) {\n      currentTarget = e.currentTarget = opt_ancestorsTree[i];\n      rv = currentTarget.fireListeners(type, true, e) && rv;\n    }\n  }\n\n  // Executes capture and bubble listeners on the target.\n  if (!e.hasPropagationStopped()) {\n    currentTarget = /** @type {?} */ (e.currentTarget = target);\n    rv = currentTarget.fireListeners(type, true, e) && rv;\n    if (!e.hasPropagationStopped()) {\n      rv = currentTarget.fireListeners(type, false, e) && rv;\n    }\n  }\n\n  // Executes all bubble listeners on the ancestors, if any.\n  if (opt_ancestorsTree) {\n    for (i = 0; !e.hasPropagationStopped() && i < opt_ancestorsTree.length;\n         i++) {\n      currentTarget = e.currentTarget = opt_ancestorsTree[i];\n      rv = currentTarget.fireListeners(type, false, e) && rv;\n    }\n  }\n\n  return rv;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview JSON utility functions.\n */\n\n\ngoog.provide('goog.json');\ngoog.provide('goog.json.Replacer');\ngoog.provide('goog.json.Reviver');\ngoog.provide('goog.json.Serializer');\n\n\n/**\n * @define {boolean} If true, use the native JSON parsing API.\n * NOTE: The default `goog.json.parse` implementation is able to handle\n * invalid JSON. JSPB used to produce invalid JSON which is not the case\n * anymore so this is safe to enable for parsing JSPB. Using native JSON is\n * faster and safer than the default implementation using `eval`.\n */\ngoog.json.USE_NATIVE_JSON = goog.define('goog.json.USE_NATIVE_JSON', false);\n\n/**\n * @define {boolean} If true, try the native JSON parsing API first. If it\n * fails, log an error and use `eval` instead. This is useful when\n * transitioning to `goog.json.USE_NATIVE_JSON`. The error logger needs to\n * be set by `goog.json.setErrorLogger`. If it is not set then the error\n * is ignored.\n */\ngoog.json.TRY_NATIVE_JSON = goog.define('goog.json.TRY_NATIVE_JSON', false);\n\n\n/**\n * Tests if a string is an invalid JSON string. This only ensures that we are\n * not using any invalid characters\n * @param {string} s The string to test.\n * @return {boolean} True if the input is a valid JSON string.\n */\ngoog.json.isValid = function(s) {\n  // All empty whitespace is not valid.\n  if (/^\\s*$/.test(s)) {\n    return false;\n  }\n\n  // This is taken from http://www.json.org/json2.js which is released to the\n  // public domain.\n  // Changes: We dissallow \\u2028 Line separator and \\u2029 Paragraph separator\n  // inside strings.  We also treat \\u2028 and \\u2029 as whitespace which they\n  // are in the RFC but IE and Safari does not match \\s to these so we need to\n  // include them in the reg exps in all places where whitespace is allowed.\n  // We allowed \\x7f inside strings because some tools don't escape it,\n  // e.g. http://www.json.org/java/org/json/JSONObject.java\n\n  // Parsing happens in three stages. In the first stage, we run the text\n  // against regular expressions that look for non-JSON patterns. We are\n  // especially concerned with '()' and 'new' because they can cause invocation,\n  // and '=' because it can cause mutation. But just to be safe, we want to\n  // reject all unexpected forms.\n\n  // We split the first stage into 4 regexp operations in order to work around\n  // crippling inefficiencies in IE's and Safari's regexp engines. First we\n  // replace all backslash pairs with '@' (a non-JSON character). Second, we\n  // replace all simple value tokens with ']' characters, but only when followed\n  // by a colon, comma, closing bracket or end of string. Third, we delete all\n  // open brackets that follow a colon or comma or that begin the text. Finally,\n  // we look to see that the remaining characters are only whitespace or ']' or\n  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n  // Don't make these static since they have the global flag.\n  const backslashesRe = /\\\\[\"\\\\\\/bfnrtu]/g;\n  const simpleValuesRe =\n      /(?:\"[^\"\\\\\\n\\r\\u2028\\u2029\\x00-\\x08\\x0a-\\x1f]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)[\\s\\u2028\\u2029]*(?=:|,|]|}|$)/g;\n  const openBracketsRe = /(?:^|:|,)(?:[\\s\\u2028\\u2029]*\\[)+/g;\n  const remainderRe = /^[\\],:{}\\s\\u2028\\u2029]*$/;\n\n  return remainderRe.test(\n      s.replace(backslashesRe, '@')\n          .replace(simpleValuesRe, ']')\n          .replace(openBracketsRe, ''));\n};\n\n/**\n * Logs a parsing error in `JSON.parse` solvable by using `eval`\n * if `goog.json.TRY_NATIVE_JSON` is enabled.\n * @private {function(string, !Error)} The first parameter is the error message,\n *     the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.errorLogger_ = goog.nullFunction;\n\n\n/**\n * Sets an error logger to use if there's a recoverable parsing error and\n * `goog.json.TRY_NATIVE_JSON` is enabled.\n * @param {function(string, !Error)} errorLogger The first parameter is the\n *     error message, the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.setErrorLogger = function(errorLogger) {\n  goog.json.errorLogger_ = errorLogger;\n};\n\n\n/**\n * Parses a JSON string and returns the result. This throws an exception if\n * the string is an invalid JSON string.\n *\n * Note that this is very slow on large strings. Use JSON.parse if possible.\n *\n * @param {*} s The JSON string to parse.\n * @throws Error if s is invalid JSON.\n * @return {Object} The object generated from the JSON string, or null.\n * @deprecated Use JSON.parse.\n */\ngoog.json.parse = goog.json.USE_NATIVE_JSON ?\n    /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :\n    function(s) {\n      let error;\n      if (goog.json.TRY_NATIVE_JSON) {\n        try {\n          return goog.global['JSON']['parse'](s);\n        } catch (ex) {\n          error = ex;\n        }\n      }\n      const o = String(s);\n      if (goog.json.isValid(o)) {\n\n        try {\n          const result = /** @type {?Object} */ (eval('(' + o + ')'));\n          if (error) {\n            goog.json.errorLogger_('Invalid JSON: ' + o, error);\n          }\n          return result;\n        } catch (ex) {\n        }\n      }\n      throw new Error('Invalid JSON string: ' + o);\n    };\n\n\n/**\n * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * TODO(nicksantos): Array should also be a valid replacer.\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Replacer;\n\n\n/**\n * JSON reviver, as defined in Section 15.12.2 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Reviver;\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @param {?goog.json.Replacer=} opt_replacer A replacer function\n *     called for each (key, value) pair that determines how the value\n *     should be serialized. By defult, this just returns the value\n *     and allows default serialization to kick in.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.serialize = goog.json.USE_NATIVE_JSON ?\n    /** @type {function(*, ?goog.json.Replacer=):string} */\n    (goog.global['JSON']['stringify']) :\n    function(object, opt_replacer) {\n      // NOTE(nicksantos): Currently, we never use JSON.stringify.\n      //\n      // The last time I evaluated this, JSON.stringify had subtle bugs and\n      // behavior differences on all browsers, and the performance win was not\n      // large enough to justify all the issues. This may change in the future\n      // as browser implementations get better.\n      //\n      // assertSerialize in json_test contains if branches for the cases\n      // that fail.\n      return new goog.json.Serializer(opt_replacer).serialize(object);\n    };\n\n\n\n/**\n * Class that is used to serialize JSON objects to a string.\n * @param {?goog.json.Replacer=} opt_replacer Replacer.\n * @constructor\n */\ngoog.json.Serializer = function(opt_replacer) {\n  /**\n   * @type {goog.json.Replacer|null|undefined}\n   * @private\n   */\n  this.replacer_ = opt_replacer;\n};\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.Serializer.prototype.serialize = function(object) {\n  const sb = [];\n  this.serializeInternal(object, sb);\n  return sb.join('');\n};\n\n\n/**\n * Serializes a generic value to a JSON string\n * @protected\n * @param {*} object The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @throws Error if there are loops in the object graph.\n */\ngoog.json.Serializer.prototype.serializeInternal = function(object, sb) {\n  if (object == null) {\n    // undefined == null so this branch covers undefined as well as null\n    sb.push('null');\n    return;\n  }\n\n  if (typeof object == 'object') {\n    if (Array.isArray(object)) {\n      this.serializeArray(object, sb);\n      return;\n    } else if (\n        object instanceof String || object instanceof Number ||\n        object instanceof Boolean) {\n      object = object.valueOf();\n      // Fall through to switch below.\n    } else {\n      this.serializeObject_(/** @type {!Object} */ (object), sb);\n      return;\n    }\n  }\n\n  switch (typeof object) {\n    case 'string':\n      this.serializeString_(object, sb);\n      break;\n    case 'number':\n      this.serializeNumber_(object, sb);\n      break;\n    case 'boolean':\n      sb.push(String(object));\n      break;\n    case 'function':\n      sb.push('null');\n      break;\n    default:\n      throw new Error('Unknown type: ' + typeof object);\n  }\n};\n\n\n/**\n * Character mappings used internally for goog.string.quote\n * @private\n * @type {!Object}\n */\ngoog.json.Serializer.charToJsonCharCache_ = {\n  '\\\"': '\\\\\"',\n  '\\\\': '\\\\\\\\',\n  '/': '\\\\/',\n  '\\b': '\\\\b',\n  '\\f': '\\\\f',\n  '\\n': '\\\\n',\n  '\\r': '\\\\r',\n  '\\t': '\\\\t',\n\n  '\\x0B': '\\\\u000b'  // '\\v' is not supported in JScript\n};\n\n\n/**\n * Regular expression used to match characters that need to be replaced.\n * The S60 browser has a bug where unicode characters are not matched by\n * regular expressions. The condition below detects such behaviour and\n * adjusts the regular expression accordingly.\n * @private\n * @type {!RegExp}\n */\ngoog.json.Serializer.charsToReplace_ = /\\uffff/.test('\\uffff') ?\n    /[\\\\\\\"\\x00-\\x1f\\x7f-\\uffff]/g :\n    /[\\\\\\\"\\x00-\\x1f\\x7f-\\xff]/g;\n\n\n/**\n * Serializes a string to a JSON string\n * @private\n * @param {string} s The string to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeString_ = function(s, sb) {\n  // The official JSON implementation does not work with international\n  // characters.\n  sb.push('\"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {\n    // caching the result improves performance by a factor 2-3\n    let rv = goog.json.Serializer.charToJsonCharCache_[c];\n    if (!rv) {\n      rv = '\\\\u' + (c.charCodeAt(0) | 0x10000).toString(16).substr(1);\n      goog.json.Serializer.charToJsonCharCache_[c] = rv;\n    }\n    return rv;\n  }), '\"');\n};\n\n\n/**\n * Serializes a number to a JSON string\n * @private\n * @param {number} n The number to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {\n  sb.push(isFinite(n) && !isNaN(n) ? String(n) : 'null');\n};\n\n\n/**\n * Serializes an array to a JSON string\n * @param {Array<string>} arr The array to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @protected\n */\ngoog.json.Serializer.prototype.serializeArray = function(arr, sb) {\n  const l = arr.length;\n  sb.push('[');\n  let sep = '';\n  for (let i = 0; i < l; i++) {\n    sb.push(sep);\n\n    const value = arr[i];\n    this.serializeInternal(\n        this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,\n        sb);\n\n    sep = ',';\n  }\n  sb.push(']');\n};\n\n\n/**\n * Serializes an object to a JSON string\n * @private\n * @param {!Object} obj The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {\n  sb.push('{');\n  let sep = '';\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      const value = obj[key];\n      // Skip functions.\n      if (typeof value != 'function') {\n        sb.push(sep);\n        this.serializeString_(key, sb);\n        sb.push(':');\n\n        this.serializeInternal(\n            this.replacer_ ? this.replacer_.call(obj, key, value) : value, sb);\n\n        sep = ',';\n      }\n    }\n  }\n  sb.push('}');\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.async.WorkItem');\ngoog.provide('goog.async.WorkQueue');\n\ngoog.require('goog.asserts');\ngoog.require('goog.async.FreeList');\n\n\n// TODO(johnlenz): generalize the WorkQueue if this is used by more\n// than goog.async.run.\n\n\n\n/**\n * A low GC workqueue. The key elements of this design:\n *   - avoids the need for goog.bind or equivalent by carrying scope\n *   - avoids the need for array reallocation by using a linked list\n *   - minimizes work entry objects allocation by recycling objects\n * @constructor\n * @final\n * @struct\n */\ngoog.async.WorkQueue = function() {\n  this.workHead_ = null;\n  this.workTail_ = null;\n};\n\n\n/** @define {number} The maximum number of entries to keep for recycling. */\ngoog.async.WorkQueue.DEFAULT_MAX_UNUSED =\n    goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);\n\n\n/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */\ngoog.async.WorkQueue.freelist_ = new goog.async.FreeList(\n    function() { return new goog.async.WorkItem(); },\n    function(item) { item.reset(); }, goog.async.WorkQueue.DEFAULT_MAX_UNUSED);\n\n\n/**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\ngoog.async.WorkQueue.prototype.add = function(fn, scope) {\n  var item = this.getUnusedItem_();\n  item.set(fn, scope);\n\n  if (this.workTail_) {\n    this.workTail_.next = item;\n    this.workTail_ = item;\n  } else {\n    goog.asserts.assert(!this.workHead_);\n    this.workHead_ = item;\n    this.workTail_ = item;\n  }\n};\n\n\n/**\n * @return {goog.async.WorkItem}\n */\ngoog.async.WorkQueue.prototype.remove = function() {\n  var item = null;\n\n  if (this.workHead_) {\n    item = this.workHead_;\n    this.workHead_ = this.workHead_.next;\n    if (!this.workHead_) {\n      this.workTail_ = null;\n    }\n    item.next = null;\n  }\n  return item;\n};\n\n\n/**\n * @param {goog.async.WorkItem} item\n */\ngoog.async.WorkQueue.prototype.returnUnused = function(item) {\n  goog.async.WorkQueue.freelist_.put(item);\n};\n\n\n/**\n * @return {goog.async.WorkItem}\n * @private\n */\ngoog.async.WorkQueue.prototype.getUnusedItem_ = function() {\n  return goog.async.WorkQueue.freelist_.get();\n};\n\n\n\n/**\n * @constructor\n * @final\n * @struct\n */\ngoog.async.WorkItem = function() {\n  /** @type {?function()} */\n  this.fn = null;\n  /** @type {?Object|null|undefined} */\n  this.scope = null;\n  /** @type {?goog.async.WorkItem} */\n  this.next = null;\n};\n\n\n/**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\ngoog.async.WorkItem.prototype.set = function(fn, scope) {\n  this.fn = fn;\n  this.scope = scope;\n  this.next = null;\n};\n\n\n/** Reset the work item so they don't prevent GC before reuse */\ngoog.async.WorkItem.prototype.reset = function() {\n  this.fn = null;\n  this.scope = null;\n  this.next = null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple freelist.\n *\n * An anterative to goog.structs.SimplePool, it imposes the requirement that the\n * objects in the list contain a \"next\" property that can be used to maintain\n * the pool.\n */\n\ngoog.provide('goog.async.FreeList');\n\n\n/**\n * @template ITEM\n */\ngoog.async.FreeList = class {\n  /**\n   * @param {function():ITEM} create\n   * @param {function(ITEM):void} reset\n   * @param {number} limit\n   */\n  constructor(create, reset, limit) {\n    /** @private @const {number} */\n    this.limit_ = limit;\n    /** @private @const {function()} */\n    this.create_ = create;\n    /** @private @const {function(ITEM):void} */\n    this.reset_ = reset;\n\n    /** @private {number} */\n    this.occupants_ = 0;\n    /** @private {ITEM} */\n    this.head_ = null;\n  }\n\n  /**\n   * @return {ITEM}\n   */\n  get() {\n    let item;\n    if (this.occupants_ > 0) {\n      this.occupants_--;\n      item = this.head_;\n      this.head_ = item.next;\n      item.next = null;\n    } else {\n      item = this.create_();\n    }\n    return item;\n  }\n\n  /**\n   * @param {ITEM} item An item available for possible future reuse.\n   */\n  put(item) {\n    this.reset_(item);\n    if (this.occupants_ < this.limit_) {\n      this.occupants_++;\n      item.next = this.head_;\n      this.head_ = item;\n    }\n  }\n\n  /**\n   * Visible for testing.\n   * @package\n   * @return {number}\n   */\n  occupants() {\n    return this.occupants_;\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a function to schedule running a function as soon\n * as possible after the current JS execution stops and yields to the event\n * loop.\n */\n\ngoog.provide('goog.async.nextTick');\ngoog.provide('goog.async.throwException');\n\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.functions');\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\n\n\n/**\n * Throw an item without interrupting the current execution context.  For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\ngoog.async.throwException = function(exception) {\n  // Each throw needs to be in its own context.\n  goog.global.setTimeout(function() { throw exception; }, 0);\n};\n\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) takes at least 4ms when called from\n * within another setTimeout(…, 0) for legacy reasons.\n *\n * This will not schedule the callback as a microtask (i.e. a task that can\n * preempt user input or networking callbacks). It is meant to emulate what\n * setTimeout(_, 0) would do if it were not throttled. If you desire microtask\n * behavior, use {@see goog.Promise} instead.\n *\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n *     possible.\n * @param {SCOPE=} opt_context Object in whose scope to call the listener.\n * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that\n *     ensures correctness at the cost of speed. See comments for details.\n * @template SCOPE\n */\ngoog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {\n  var cb = callback;\n  if (opt_context) {\n    cb = goog.bind(callback, opt_context);\n  }\n  cb = goog.async.nextTick.wrapCallback_(cb);\n  // Note we do allow callers to also request setImmediate if they are willing\n  // to accept the possible tradeoffs of incorrectness in exchange for speed.\n  // The IE fallback of readystate change is much slower. See useSetImmediate_\n  // for details.\n  if (goog.isFunction(goog.global.setImmediate) &&\n      (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {\n    goog.global.setImmediate(cb);\n    return;\n  }\n\n  // Look for and cache the custom fallback version of setImmediate.\n  if (!goog.async.nextTick.setImmediate_) {\n    goog.async.nextTick.setImmediate_ =\n        goog.async.nextTick.getSetImmediateEmulator_();\n  }\n  goog.async.nextTick.setImmediate_(cb);\n};\n\n\n/**\n * Returns whether should use setImmediate implementation currently on window.\n *\n * window.setImmediate was introduced and currently only supported by IE10+,\n * but due to a bug in the implementation it is not guaranteed that\n * setImmediate is faster than setTimeout nor that setImmediate N is before\n * setImmediate N+1. That is why we do not use the native version if\n * available. We do, however, call setImmediate if it is a non-native function\n * because that indicates that it has been replaced by goog.testing.MockClock\n * which we do want to support.\n * See\n * http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10\n *\n * @return {boolean} Whether to use the implementation of setImmediate defined\n *     on Window.\n * @private\n * @suppress {missingProperties} For \"Window.prototype.setImmediate\"\n */\ngoog.async.nextTick.useSetImmediate_ = function() {\n  // Not a browser environment.\n  if (!goog.global.Window || !goog.global.Window.prototype) {\n    return true;\n  }\n\n  // MS Edge has window.setImmediate natively, but it's not on Window.prototype.\n  // Also, there's no clean way to detect if the goog.global.setImmediate has\n  // been replaced by mockClock as its replacement also shows up as \"[native\n  // code]\" when using toString. Therefore, just always use\n  // goog.global.setImmediate for Edge. It's unclear if it suffers the same\n  // issues as IE10/11, but based on\n  // https://dev.modern.ie/testdrive/demos/setimmediatesorting/\n  // it seems they've been working to ensure it's WAI.\n  if (goog.labs.userAgent.browser.isEdge() ||\n      goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {\n    // Something redefined setImmediate in which case we decide to use it (This\n    // is so that we use the mockClock setImmediate).\n    return true;\n  }\n\n  return false;\n};\n\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\ngoog.async.nextTick.setImmediate_;\n\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\ngoog.async.nextTick.getSetImmediateEmulator_ = function() {\n  // Create a private message channel and use it to postMessage empty messages\n  // to ourselves.\n  /** @type {!Function|undefined} */\n  var Channel = goog.global['MessageChannel'];\n  // If MessageChannel is not available and we are in a browser, implement\n  // an iframe based polyfill in browsers that have postMessage and\n  // document.addEventListener. The latter excludes IE8 because it has a\n  // synchronous postMessage implementation.\n  if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&\n      window.postMessage && window.addEventListener &&\n      // Presto (The old pre-blink Opera engine) has problems with iframes\n      // and contentWindow.\n      !goog.labs.userAgent.engine.isPresto()) {\n    /** @constructor */\n    Channel = function() {\n      // Make an empty, invisible iframe.\n      var iframe = goog.dom.createElement(goog.dom.TagName.IFRAME);\n      iframe.style.display = 'none';\n      document.documentElement.appendChild(iframe);\n      var win = iframe.contentWindow;\n      var doc = win.document;\n      doc.open();\n      doc.close();\n      // Do not post anything sensitive over this channel, as the workaround for\n      // pages with file: origin could allow that information to be modified or\n      // intercepted.\n      var message = 'callImmediate' + Math.random();\n      // The same origin policy rejects attempts to postMessage from file: urls\n      // unless the origin is '*'.\n      var origin = win.location.protocol == 'file:' ?\n          '*' :\n          win.location.protocol + '//' + win.location.host;\n      var onmessage = goog.bind(function(e) {\n        // Validate origin and message to make sure that this message was\n        // intended for us. If the origin is set to '*' (see above) only the\n        // message needs to match since, for example, '*' != 'file://'. Allowing\n        // the wildcard is ok, as we are not concerned with security here.\n        if ((origin != '*' && e.origin != origin) || e.data != message) {\n          return;\n        }\n        this['port1'].onmessage();\n      }, this);\n      win.addEventListener('message', onmessage, false);\n      this['port1'] = {};\n      this['port2'] = {\n        postMessage: function() { win.postMessage(message, origin); }\n      };\n    };\n  }\n  if (typeof Channel !== 'undefined' && !goog.labs.userAgent.browser.isIE()) {\n    // Exclude all of IE due to\n    // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/\n    // which allows starving postMessage with a busy setTimeout loop.\n    // This currently affects IE10 and IE11 which would otherwise be able\n    // to use the postMessage based fallbacks.\n    var channel = new Channel();\n    // Use a fifo linked list to call callbacks in the right order.\n    var head = {};\n    var tail = head;\n    channel['port1'].onmessage = function() {\n      if (head.next !== undefined) {\n        head = head.next;\n        var cb = head.cb;\n        head.cb = null;\n        cb();\n      }\n    };\n    return function(cb) {\n      tail.next = {cb: cb};\n      tail = tail.next;\n      channel['port2'].postMessage(0);\n    };\n  }\n  // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n  // or more.\n  // NOTE(user): This fallback is used for IE.\n  return function(cb) {\n    goog.global.setTimeout(/** @type {function()} */ (cb), 0);\n  };\n};\n\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\ngoog.async.nextTick.wrapCallback_ = goog.functions.identity;\n\n\n// Register the callback function as an entry point, so that it can be\n// monitored for exception handling, etc. This has to be done in this file\n// since it requires special code to handle all browsers.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) { goog.async.nextTick.wrapCallback_ = transformer; });\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.async.run');\n\ngoog.require('goog.async.WorkQueue');\ngoog.require('goog.async.nextTick');\ngoog.require('goog.async.throwException');\n\n/**\n * @define {boolean} If true, use the global Promise to implement goog.async.run\n * assuming either the native, or polyfill version will be used. Does still\n * permit tests to use forceNextTick.\n */\ngoog.ASSUME_NATIVE_PROMISE = goog.define('goog.ASSUME_NATIVE_PROMISE', false);\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} opt_context Object to use as the \"this value\" when calling\n *     the provided function.\n * @template THIS\n */\ngoog.async.run = function(callback, opt_context) {\n  if (!goog.async.run.schedule_) {\n    goog.async.run.initializeRunner_();\n  }\n  if (!goog.async.run.workQueueScheduled_) {\n    // Nothing is currently scheduled, schedule it now.\n    goog.async.run.schedule_();\n    goog.async.run.workQueueScheduled_ = true;\n  }\n\n  goog.async.run.workQueue_.add(callback, opt_context);\n};\n\n\n/**\n * Initializes the function to use to process the work queue.\n * @private\n */\ngoog.async.run.initializeRunner_ = function() {\n  if (goog.ASSUME_NATIVE_PROMISE ||\n      (goog.global.Promise && goog.global.Promise.resolve)) {\n    // Use goog.global.Promise instead of just Promise because the relevant\n    // externs may be missing, and don't alias it because this could confuse the\n    // compiler into thinking the polyfill is required when it should be treated\n    // as optional.\n    var promise = goog.global.Promise.resolve(undefined);\n    goog.async.run.schedule_ = function() {\n      promise.then(goog.async.run.processWorkQueue);\n    };\n  } else {\n    goog.async.run.schedule_ = function() {\n      goog.async.nextTick(goog.async.run.processWorkQueue);\n    };\n  }\n};\n\n\n/**\n * Forces goog.async.run to use nextTick instead of Promise.\n *\n * This should only be done in unit tests. It's useful because MockClock\n * replaces nextTick, but not the browser Promise implementation, so it allows\n * Promise-based code to be tested with MockClock.\n *\n * However, we also want to run promises if the MockClock is no longer in\n * control so we schedule a backup \"setTimeout\" to the unmocked timeout if\n * provided.\n *\n * @param {function(function())=} opt_realSetTimeout\n */\ngoog.async.run.forceNextTick = function(opt_realSetTimeout) {\n  goog.async.run.schedule_ = function() {\n    goog.async.nextTick(goog.async.run.processWorkQueue);\n    if (opt_realSetTimeout) {\n      opt_realSetTimeout(goog.async.run.processWorkQueue);\n    }\n  };\n};\n\n\n/**\n * The function used to schedule work asynchronousely.\n * @private {function()}\n */\ngoog.async.run.schedule_;\n\n\n/** @private {boolean} */\ngoog.async.run.workQueueScheduled_ = false;\n\n\n/** @private {!goog.async.WorkQueue} */\ngoog.async.run.workQueue_ = new goog.async.WorkQueue();\n\n\nif (goog.DEBUG) {\n  /**\n   * Reset the work queue. Only available for tests in debug mode.\n   */\n  goog.async.run.resetQueue = function() {\n    goog.async.run.workQueueScheduled_ = false;\n    goog.async.run.workQueue_ = new goog.async.WorkQueue();\n  };\n}\n\n\n/**\n * Run any pending goog.async.run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * goog.async.nextTick.\n */\ngoog.async.run.processWorkQueue = function() {\n  // NOTE: additional work queue items may be added while processing.\n  var item = null;\n  while (item = goog.async.run.workQueue_.remove()) {\n    try {\n      item.fn.call(item.scope);\n    } catch (e) {\n      goog.async.throwException(e);\n    }\n    goog.async.run.workQueue_.returnUnused(item);\n  }\n\n  // There are no more work items, allow processing to be scheduled again.\n  goog.async.run.workQueueScheduled_ = false;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A timer class to which other classes and objects can listen on.\n * This is only an abstraction above `setInterval`.\n *\n * @see ../demos/timers.html\n */\n\ngoog.provide('goog.Timer');\n\ngoog.require('goog.Promise');\ngoog.require('goog.events.EventTarget');\n\n\n\n/**\n * Class for handling timing events.\n *\n * @param {number=} opt_interval Number of ms between ticks (default: 1ms).\n * @param {Object=} opt_timerObject  An object that has `setTimeout`,\n *     `setInterval`, `clearTimeout` and `clearInterval`\n *     (e.g., `window`).\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.Timer = function(opt_interval, opt_timerObject) {\n  goog.events.EventTarget.call(this);\n\n  /**\n   * Number of ms between ticks\n   * @private {number}\n   */\n  this.interval_ = opt_interval || 1;\n\n  /**\n   * An object that implements `setTimeout`, `setInterval`,\n   * `clearTimeout` and `clearInterval`. We default to the window\n   * object. Changing this on {@link goog.Timer.prototype} changes the object\n   * for all timer instances which can be useful if your environment has some\n   * other implementation of timers than the `window` object.\n   * @private {{setTimeout:!Function, clearTimeout:!Function}}\n   */\n  this.timerObject_ = /** @type {{setTimeout, clearTimeout}} */ (\n      opt_timerObject || goog.Timer.defaultTimerObject);\n\n  /**\n   * Cached `tick_` bound to the object for later use in the timer.\n   * @private {Function}\n   * @const\n   */\n  this.boundTick_ = goog.bind(this.tick_, this);\n\n  /**\n   * Firefox browser often fires the timer event sooner (sometimes MUCH sooner)\n   * than the requested timeout. So we compare the time to when the event was\n   * last fired, and reschedule if appropriate. See also\n   * {@link goog.Timer.intervalScale}.\n   * @private {number}\n   */\n  this.last_ = goog.now();\n};\ngoog.inherits(goog.Timer, goog.events.EventTarget);\n\n\n/**\n * Maximum timeout value.\n *\n * Timeout values too big to fit into a signed 32-bit integer may cause overflow\n * in FF, Safari, and Chrome, resulting in the timeout being scheduled\n * immediately. It makes more sense simply not to schedule these timeouts, since\n * 24.8 days is beyond a reasonable expectation for the browser to stay open.\n *\n * @private {number}\n * @const\n */\ngoog.Timer.MAX_TIMEOUT_ = 2147483647;\n\n\n/**\n * A timer ID that cannot be returned by any known implementation of\n * `window.setTimeout`. Passing this value to `window.clearTimeout`\n * should therefore be a no-op.\n *\n * @private {number}\n * @const\n */\ngoog.Timer.INVALID_TIMEOUT_ID_ = -1;\n\n\n/**\n * Whether this timer is enabled\n * @type {boolean}\n */\ngoog.Timer.prototype.enabled = false;\n\n\n/**\n * An object that implements `setTimeout`, `setInterval`,\n * `clearTimeout` and `clearInterval`. We default to the global\n * object. Changing `goog.Timer.defaultTimerObject` changes the object for\n * all timer instances which can be useful if your environment has some other\n * implementation of timers you'd like to use.\n * @type {{setTimeout, clearTimeout}}\n */\ngoog.Timer.defaultTimerObject = goog.global;\n\n\n/**\n * Variable that controls the timer error correction. If the timer is called\n * before the requested interval times `intervalScale`, which often\n * happens on Mozilla, the timer is rescheduled.\n * @see {@link #last_}\n * @type {number}\n */\ngoog.Timer.intervalScale = 0.8;\n\n\n/**\n * Variable for storing the result of `setInterval`.\n * @private {?number}\n */\ngoog.Timer.prototype.timer_ = null;\n\n\n/**\n * Gets the interval of the timer.\n * @return {number} interval Number of ms between ticks.\n */\ngoog.Timer.prototype.getInterval = function() {\n  return this.interval_;\n};\n\n\n/**\n * Sets the interval of the timer.\n * @param {number} interval Number of ms between ticks.\n */\ngoog.Timer.prototype.setInterval = function(interval) {\n  this.interval_ = interval;\n  if (this.timer_ && this.enabled) {\n    // Stop and then start the timer to reset the interval.\n    this.stop();\n    this.start();\n  } else if (this.timer_) {\n    this.stop();\n  }\n};\n\n\n/**\n * Callback for the `setTimeout` used by the timer.\n * @private\n */\ngoog.Timer.prototype.tick_ = function() {\n  if (this.enabled) {\n    var elapsed = goog.now() - this.last_;\n    if (elapsed > 0 && elapsed < this.interval_ * goog.Timer.intervalScale) {\n      this.timer_ = this.timerObject_.setTimeout(\n          this.boundTick_, this.interval_ - elapsed);\n      return;\n    }\n\n    // Prevents setInterval from registering a duplicate timeout when called\n    // in the timer event handler.\n    if (this.timer_) {\n      this.timerObject_.clearTimeout(this.timer_);\n      this.timer_ = null;\n    }\n\n    this.dispatchTick();\n    // The timer could be stopped in the timer event handler.\n    if (this.enabled) {\n      // Stop and start to ensure there is always only one timeout even if\n      // start is called in the timer event handler.\n      this.stop();\n      this.start();\n    }\n  }\n};\n\n\n/**\n * Dispatches the TICK event. This is its own method so subclasses can override.\n */\ngoog.Timer.prototype.dispatchTick = function() {\n  this.dispatchEvent(goog.Timer.TICK);\n};\n\n\n/**\n * Starts the timer.\n */\ngoog.Timer.prototype.start = function() {\n  this.enabled = true;\n\n  // If there is no interval already registered, start it now\n  if (!this.timer_) {\n    // IMPORTANT!\n    // window.setInterval in FireFox has a bug - it fires based on\n    // absolute time, rather than on relative time. What this means\n    // is that if a computer is sleeping/hibernating for 24 hours\n    // and the timer interval was configured to fire every 1000ms,\n    // then after the PC wakes up the timer will fire, in rapid\n    // succession, 3600*24 times.\n    // This bug is described here and is already fixed, but it will\n    // take time to propagate, so for now I am switching this over\n    // to setTimeout logic.\n    //     https://bugzilla.mozilla.org/show_bug.cgi?id=376643\n    //\n    this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_);\n    this.last_ = goog.now();\n  }\n};\n\n\n/**\n * Stops the timer.\n */\ngoog.Timer.prototype.stop = function() {\n  this.enabled = false;\n  if (this.timer_) {\n    this.timerObject_.clearTimeout(this.timer_);\n    this.timer_ = null;\n  }\n};\n\n\n/** @override */\ngoog.Timer.prototype.disposeInternal = function() {\n  goog.Timer.superClass_.disposeInternal.call(this);\n  this.stop();\n  delete this.timerObject_;\n};\n\n\n/**\n * Constant for the timer's event type.\n * @const\n */\ngoog.Timer.TICK = 'tick';\n\n\n/**\n * Calls the given function once, after the optional pause.\n * <p>\n * The function is always called asynchronously, even if the delay is 0. This\n * is a common trick to schedule a function to run after a batch of browser\n * event processing.\n *\n * @param {function(this:SCOPE)|{handleEvent:function()}|null} listener Function\n *     or object that has a handleEvent method.\n * @param {number=} opt_delay Milliseconds to wait; default is 0.\n * @param {SCOPE=} opt_handler Object in whose scope to call the listener.\n * @return {number} A handle to the timer ID.\n * @template SCOPE\n */\ngoog.Timer.callOnce = function(listener, opt_delay, opt_handler) {\n  if (goog.isFunction(listener)) {\n    if (opt_handler) {\n      listener = goog.bind(listener, opt_handler);\n    }\n  } else if (listener && typeof listener.handleEvent == 'function') {\n    // using typeof to prevent strict js warning\n    listener = goog.bind(listener.handleEvent, listener);\n  } else {\n    throw new Error('Invalid listener argument');\n  }\n\n  if (Number(opt_delay) > goog.Timer.MAX_TIMEOUT_) {\n    // Timeouts greater than MAX_INT return immediately due to integer\n    // overflow in many browsers.  Since MAX_INT is 24.8 days, just don't\n    // schedule anything at all.\n    return goog.Timer.INVALID_TIMEOUT_ID_;\n  } else {\n    return goog.Timer.defaultTimerObject.setTimeout(listener, opt_delay || 0);\n  }\n};\n\n\n/**\n * Clears a timeout initiated by {@link #callOnce}.\n * @param {?number} timerId A timer ID.\n */\ngoog.Timer.clear = function(timerId) {\n  goog.Timer.defaultTimerObject.clearTimeout(timerId);\n};\n\n\n/**\n * @param {number} delay Milliseconds to wait.\n * @param {(RESULT|goog.Thenable<RESULT>|Thenable)=} opt_result The value\n *     with which the promise will be resolved.\n * @return {!goog.Promise<RESULT>} A promise that will be resolved after\n *     the specified delay, unless it is canceled first.\n * @template RESULT\n */\ngoog.Timer.promise = function(delay, opt_result) {\n  var timerKey = null;\n  return new goog\n      .Promise(function(resolve, reject) {\n        timerKey =\n            goog.Timer.callOnce(function() { resolve(opt_result); }, delay);\n        if (timerKey == goog.Timer.INVALID_TIMEOUT_ID_) {\n          reject(new Error('Failed to schedule timer.'));\n        }\n      })\n      .thenCatch(function(error) {\n        // Clear the timer. The most likely reason is \"cancel\" signal.\n        goog.Timer.clear(timerKey);\n        throw error;\n      });\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the goog.async.Throttle class.\n *\n * @see ../demos/timers.html\n */\n\ngoog.module('goog.async.Throttle');\ngoog.module.declareLegacyNamespace();\n\nconst Disposable = goog.require('goog.Disposable');\nconst Timer = goog.require('goog.Timer');\n\n\n/**\n * Throttle will perform an action that is passed in no more than once\n * per interval (specified in milliseconds). If it gets multiple signals\n * to perform the action while it is waiting, it will only perform the action\n * once at the end of the interval.\n * @final\n * @template T\n */\nclass Throttle extends Disposable {\n  /**\n   * @param {function(this: T, ...?)} listener Function to callback when the\n   *     action is triggered.\n   * @param {number} interval Interval over which to throttle. The listener can\n   *     only be called once per interval.\n   * @param {T=} handler Object in whose scope to call the listener.\n   */\n  constructor(listener, interval, handler) {\n    super();\n    /**\n     * Function to callback\n     * @type {function(this: T, ...?)}\n     * @private\n     */\n    this.listener_ = handler != null ? listener.bind(handler) : listener;\n\n    /**\n     * Interval for the throttle time\n     * @type {number}\n     * @private\n     */\n    this.interval_ = interval;\n\n    /**\n     * The last arguments passed into `fire`, or null if there is no pending\n     * call.\n     * @private {?IArrayLike}\n     */\n    this.args_ = null;\n\n    /**\n     * Indicates that the action is pending and needs to be fired.\n     * @type {boolean}\n     * @private\n     */\n    this.shouldFire_ = false;\n\n    /**\n     * Indicates the count of nested pauses currently in effect on the throttle.\n     * When this count is not zero, fired actions will be postponed until the\n     * throttle is resumed enough times to drop the pause count to zero.\n     * @type {number}\n     * @private\n     */\n    this.pauseCount_ = 0;\n\n    /**\n     * Timer for scheduling the next callback\n     * @type {?number}\n     * @private\n     */\n    this.timer_ = null;\n  }\n\n  /**\n   * Notifies the throttle that the action has happened. It will throttle\n   * the call so that the callback is not called too often according to the\n   * interval parameter passed to the constructor, passing the arguments\n   * from the last call of this function into the throttled function.\n   * @param {...?} var_args Arguments to pass on to the throttled function.\n   */\n  fire(var_args) {\n    this.args_ = arguments;\n    if (!this.timer_ && !this.pauseCount_) {\n      this.doAction_();\n    } else {\n      this.shouldFire_ = true;\n    }\n  }\n\n  /**\n   * Cancels any pending action callback. The throttle can be restarted by\n   * calling {@link #fire}.\n   */\n  stop() {\n    if (this.timer_) {\n      Timer.clear(this.timer_);\n      this.timer_ = null;\n      this.shouldFire_ = false;\n      this.args_ = null;\n    }\n  }\n\n  /**\n   * Pauses the throttle.  All pending and future action callbacks will be\n   * delayed until the throttle is resumed.  Pauses can be nested.\n   */\n  pause() {\n    this.pauseCount_++;\n  }\n\n  /**\n   * Resumes the throttle.  If doing so drops the pausing count to zero,\n   * pending action callbacks will be executed as soon as possible, but\n   * still no sooner than an interval's delay after the previous call.\n   * Future action callbacks will be executed as normal.\n   */\n  resume() {\n    this.pauseCount_--;\n    if (!this.pauseCount_ && this.shouldFire_ && !this.timer_) {\n      this.shouldFire_ = false;\n      this.doAction_();\n    }\n  }\n\n  /** @override */\n  disposeInternal() {\n    super.disposeInternal();\n    this.stop();\n  }\n\n  /**\n   * Handler for the timer to fire the throttle\n   * @private\n   */\n  onTimer_() {\n    this.timer_ = null;\n\n    if (this.shouldFire_ && !this.pauseCount_) {\n      this.shouldFire_ = false;\n      this.doAction_();\n    }\n  }\n\n  /**\n   * Calls the callback\n   * @private\n   */\n  doAction_() {\n    this.timer_ = Timer.callOnce(() => this.onTimer_(), this.interval_);\n    const args = this.args_;\n    // release memory first so it always happens even if listener throws\n    this.args_ = null;\n    this.listener_.apply(null, args);\n  }\n}\n\nexports = Throttle;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class to create objects which want to handle multiple events\n * and have their listeners easily cleaned up via a dispose method.\n *\n * Example:\n * <pre>\n * function Something() {\n *   Something.base(this);\n *\n *   ... set up object ...\n *\n *   // Add event listeners\n *   this.listen(this.starEl, goog.events.EventType.CLICK, this.handleStar);\n *   this.listen(this.headerEl, goog.events.EventType.CLICK, this.expand);\n *   this.listen(this.collapseEl, goog.events.EventType.CLICK, this.collapse);\n *   this.listen(this.infoEl, goog.events.EventType.MOUSEOVER, this.showHover);\n *   this.listen(this.infoEl, goog.events.EventType.MOUSEOUT, this.hideHover);\n * }\n * goog.inherits(Something, goog.events.EventHandler);\n *\n * Something.prototype.disposeInternal = function() {\n *   Something.base(this, 'disposeInternal');\n *   goog.dom.removeNode(this.container);\n * };\n *\n *\n * // Then elsewhere:\n *\n * var activeSomething = null;\n * function openSomething() {\n *   activeSomething = new Something();\n * }\n *\n * function closeSomething() {\n *   if (activeSomething) {\n *     activeSomething.dispose();  // Remove event listeners\n *     activeSomething = null;\n *   }\n * }\n * </pre>\n */\n\ngoog.provide('goog.events.EventHandler');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.events');\ngoog.require('goog.object');\ngoog.requireType('goog.events.EventTarget');\ngoog.requireType('goog.events.EventWrapper');\n\n\n\n/**\n * Super class for objects that want to easily manage a number of event\n * listeners.  It allows a short cut to listen and also provides a quick way\n * to remove all events listeners belonging to this object.\n * @param {SCOPE=} opt_scope Object in whose scope to call the listeners.\n * @constructor\n * @extends {goog.Disposable}\n * @template SCOPE\n */\ngoog.events.EventHandler = function(opt_scope) {\n  goog.Disposable.call(this);\n  // TODO(mknichel): Rename this to this.scope_ and fix the classes in google3\n  // that access this private variable. :(\n  this.handler_ = opt_scope;\n\n  /**\n   * Keys for events that are being listened to.\n   * @type {!Object<!goog.events.Key>}\n   * @private\n   */\n  this.keys_ = {};\n};\ngoog.inherits(goog.events.EventHandler, goog.Disposable);\n\n\n/**\n * Utility array used to unify the cases of listening for an array of types\n * and listening for a single event, without using recursion or allocating\n * an array each time.\n * @type {!Array<string>}\n * @const\n * @private\n */\ngoog.events.EventHandler.typeArray_ = [];\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n *     opt_fn Optional callback function to be used as the listener or an object\n *     with handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listen = function(\n    src, type, opt_fn, opt_options) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  return self.listen_(src, type, opt_fn, opt_options);\n};\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}|\n *     null|undefined} fn Optional callback function to be used as the\n *     listener or an object with handleEvent function.\n * @param {boolean|!AddEventListenerOptions|undefined} options\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenWithScope = function(\n    src, type, fn, options, scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  // TODO(mknichel): Deprecate this function.\n  return self.listen_(src, type, fn, options, scope);\n};\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn\n *     Optional callback function to be used as the listener or an object with\n *     handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listen_ = function(\n    src, type, opt_fn, opt_options, opt_scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  if (!Array.isArray(type)) {\n    if (type) {\n      goog.events.EventHandler.typeArray_[0] = type.toString();\n    }\n    type = goog.events.EventHandler.typeArray_;\n  }\n  for (var i = 0; i < type.length; i++) {\n    var listenerObj = goog.events.listen(\n        src, type[i], opt_fn || self.handleEvent, opt_options || false,\n        opt_scope || self.handler_ || self);\n\n    if (!listenerObj) {\n      // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT\n      // (goog.events.CaptureSimulationMode) in IE8-, it will return null\n      // value.\n      return self;\n    }\n\n    var key = listenerObj.key;\n    self.keys_[key] = listenerObj;\n  }\n\n  return self;\n};\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired the\n * event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n * opt_fn\n *    Optional callback function to be used as the listener or an object with\n *    handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenOnce = function(\n    src, type, opt_fn, opt_options) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  return self.listenOnce_(src, type, opt_fn, opt_options);\n};\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired the\n * event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}|\n *     null|undefined} fn Optional callback function to be used as the\n *     listener or an object with handleEvent function.\n * @param {boolean|undefined} capture Optional whether to use capture phase.\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenOnceWithScope = function(\n    src, type, fn, capture, scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  // TODO(mknichel): Deprecate this function.\n  return self.listenOnce_(src, type, fn, capture, scope);\n};\n\n\n/**\n * Listen to an event on a Listenable.  If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired\n * the event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type to listen for or array of event types.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn\n *    Optional callback function to be used as the listener or an object with\n *    handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listenOnce_ = function(\n    src, type, opt_fn, opt_options, opt_scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      self.listenOnce_(src, type[i], opt_fn, opt_options, opt_scope);\n    }\n  } else {\n    var listenerObj = goog.events.listenOnce(\n        src, type, opt_fn || self.handleEvent, opt_options,\n        opt_scope || self.handler_ || self);\n    if (!listenerObj) {\n      // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT\n      // (goog.events.CaptureSimulationMode) in IE8-, it will return null\n      // value.\n      return self;\n    }\n\n    var key = listenerObj.key;\n    self.keys_[key] = listenerObj;\n  }\n\n  return self;\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n *     events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:SCOPE, ?):?|{handleEvent:function(?):?}|null} listener\n *     Callback method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n *     false).\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n */\ngoog.events.EventHandler.prototype.listenWithWrapper = function(\n    src, wrapper, listener, opt_capt) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  // TODO(mknichel): Remove the opt_scope from this function and then\n  // templatize it.\n  return self.listenWithWrapper_(src, wrapper, listener, opt_capt);\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n *     events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:T, ?):?|{handleEvent:function(this:T, ?):?}|null}\n *     listener Optional callback function to be used as the\n *     listener or an object with handleEvent function.\n * @param {boolean|undefined} capture Optional whether to use capture phase.\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, THIS\n */\ngoog.events.EventHandler.prototype.listenWithWrapperAndScope = function(\n    src, wrapper, listener, capture, scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  // TODO(mknichel): Deprecate this function.\n  return self.listenWithWrapper_(src, wrapper, listener, capture, scope);\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n *     events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback\n *     method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n *     false).\n * @param {Object=} opt_scope Element in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listenWithWrapper_ = function(\n    src, wrapper, listener, opt_capt, opt_scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  wrapper.listen(\n      src, listener, opt_capt, opt_scope || self.handler_ || self, self);\n  return self;\n};\n\n\n/**\n * @return {number} Number of listeners registered by this handler.\n */\ngoog.events.EventHandler.prototype.getListenerCount = function() {\n  var count = 0;\n  for (var key in this.keys_) {\n    if (Object.prototype.hasOwnProperty.call(this.keys_, key)) {\n      count++;\n    }\n  }\n  return count;\n};\n\n\n/**\n * Unlistens on an event.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n *     !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n *     type Event type or array of event types to unlisten to.\n * @param {function(this:?, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n *     opt_fn Optional callback function to be used as the listener or an object\n *     with handleEvent function.\n * @param {(boolean|!EventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.unlisten = function(\n    src, type, opt_fn, opt_options, opt_scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  if (Array.isArray(type)) {\n    for (var i = 0; i < type.length; i++) {\n      self.unlisten(src, type[i], opt_fn, opt_options, opt_scope);\n    }\n  } else {\n    var capture =\n        goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n    var listener = goog.events.getListener(\n        src, type, opt_fn || self.handleEvent, capture,\n        opt_scope || self.handler_ || self);\n\n    if (listener) {\n      goog.events.unlistenByKey(listener);\n      delete self.keys_[listener.key];\n    }\n  }\n\n  return self;\n};\n\n\n/**\n * Removes an event listener which was added with listenWithWrapper().\n *\n * @param {EventTarget|goog.events.EventTarget} src The target to stop\n *     listening to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n *     listener function to remove.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n *     whether the listener is fired during the capture or bubble phase of the\n *     event.\n * @param {Object=} opt_scope Element in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n */\ngoog.events.EventHandler.prototype.unlistenWithWrapper = function(\n    src, wrapper, listener, opt_capt, opt_scope) {\n  var self = /** @type {!goog.events.EventHandler} */ (this);\n  wrapper.unlisten(\n      src, listener, opt_capt, opt_scope || self.handler_ || self, self);\n  return self;\n};\n\n\n/**\n * Unlistens to all events.\n */\ngoog.events.EventHandler.prototype.removeAll = function() {\n  goog.object.forEach(this.keys_, function(listenerObj, key) {\n    if (this.keys_.hasOwnProperty(key)) {\n      goog.events.unlistenByKey(listenerObj);\n    }\n  }, this);\n\n  this.keys_ = {};\n};\n\n\n/**\n * Disposes of this EventHandler and removes all listeners that it registered.\n * @override\n * @protected\n */\ngoog.events.EventHandler.prototype.disposeInternal = function() {\n  goog.events.EventHandler.superClass_.disposeInternal.call(this);\n  this.removeAll();\n};\n\n\n/**\n * Default event handler\n * @param {goog.events.Event} e Event object.\n */\ngoog.events.EventHandler.prototype.handleEvent = function(e) {\n  throw new Error('EventHandler.handleEvent not implemented');\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a utility for tracing and debugging WebChannel\n *     requests.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WebChannelDebug');\n\ngoog.require('goog.json');\ngoog.require('goog.log');\ngoog.requireType('goog.Uri');\ngoog.requireType('goog.net.XmlHttp.ReadyState');\n\n\n\n/**\n * Logs and keeps a buffer of debugging info for the Channel.\n *\n * @constructor\n * @struct\n * @final\n */\ngoog.labs.net.webChannel.WebChannelDebug = function() {\n  /**\n   * The logger instance.\n   * @const\n   * @private {?goog.log.Logger}\n   */\n  this.logger_ = goog.log.getLogger('goog.labs.net.webChannel.WebChannelDebug');\n\n  /**\n   * Whether to enable redact. Defaults to true.\n   * @private {boolean}\n   */\n  this.redactEnabled_ = true;\n};\n\n\ngoog.scope(function() {\nvar WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\n\n\n/**\n * Turns off redact.\n */\nWebChannelDebug.prototype.disableRedact = function() {\n  this.redactEnabled_ = false;\n};\n\n\n/**\n * Logs that the browser went offline during the lifetime of a request.\n * @param {goog.Uri} url The URL being requested.\n */\nWebChannelDebug.prototype.browserOfflineResponse = function(url) {\n  this.info(function() {\n    return 'BROWSER_OFFLINE: ' + url;\n  });\n};\n\n\n/**\n * Logs an XmlHttp request..\n * @param {string} verb The request type (GET/POST).\n * @param {goog.Uri} uri The request destination.\n * @param {string|number|undefined} id The request id.\n * @param {number} attempt Which attempt # the request was.\n * @param {?string} postData The data posted in the request.\n */\nWebChannelDebug.prototype.xmlHttpChannelRequest = function(\n    verb, uri, id, attempt, postData) {\n  var self = this;\n  this.info(function() {\n    return 'XMLHTTP REQ (' + id + ') [attempt ' + attempt + ']: ' + verb +\n        '\\n' + uri + '\\n' + self.maybeRedactPostData_(postData);\n  });\n};\n\n\n/**\n * Logs the meta data received from an XmlHttp request.\n * @param {string} verb The request type (GET/POST).\n * @param {goog.Uri} uri The request destination.\n * @param {string|number|undefined} id The request id.\n * @param {number} attempt Which attempt # the request was.\n * @param {goog.net.XmlHttp.ReadyState} readyState The ready state.\n * @param {number} statusCode The HTTP status code.\n */\nWebChannelDebug.prototype.xmlHttpChannelResponseMetaData = function(\n    verb, uri, id, attempt, readyState, statusCode) {\n  this.info(function() {\n    return 'XMLHTTP RESP (' + id + ') [ attempt ' + attempt + ']: ' + verb +\n        '\\n' + uri + '\\n' + readyState + ' ' + statusCode;\n  });\n};\n\n\n/**\n * Logs the response data received from an XmlHttp request.\n * @param {string|number|undefined} id The request id.\n * @param {?string} responseText The response text.\n * @param {?string=} opt_desc Optional request description.\n */\nWebChannelDebug.prototype.xmlHttpChannelResponseText = function(\n    id, responseText, opt_desc) {\n  var self = this;\n  this.info(function() {\n    return 'XMLHTTP TEXT (' + id + '): ' + self.redactResponse_(responseText) +\n        (opt_desc ? ' ' + opt_desc : '');\n  });\n};\n\n\n/**\n * Logs a request timeout.\n * @param {goog.Uri} uri The uri that timed out.\n */\nWebChannelDebug.prototype.timeoutResponse = function(uri) {\n  this.info(function() {\n    return 'TIMEOUT: ' + uri;\n  });\n};\n\n\n/**\n * Logs a debug message.\n * @param {!goog.debug.Loggable} text The message.\n */\nWebChannelDebug.prototype.debug = function(text) {\n  goog.log.fine(this.logger_, text);\n};\n\n\n/**\n * Logs an exception\n * @param {Error} e The error or error event.\n * @param {goog.debug.Loggable=} opt_msg The optional message,\n *     defaults to 'Exception'.\n */\nWebChannelDebug.prototype.dumpException = function(e, opt_msg) {\n  goog.log.error(this.logger_, opt_msg || 'Exception', e);\n};\n\n\n/**\n * Logs an info message.\n * @param {!goog.debug.Loggable} text The message.\n */\nWebChannelDebug.prototype.info = function(text) {\n  goog.log.info(this.logger_, text);\n};\n\n\n/**\n * Logs a warning message.\n * @param {!goog.debug.Loggable} text The message.\n */\nWebChannelDebug.prototype.warning = function(text) {\n  goog.log.warning(this.logger_, text);\n};\n\n\n/**\n * Logs a severe message.\n * @param {!goog.debug.Loggable} text The message.\n */\nWebChannelDebug.prototype.severe = function(text) {\n  goog.log.error(this.logger_, text);\n};\n\n\n/**\n * Removes potentially private data from a response so that we don't\n * accidentally save private and personal data to the server logs.\n * @param {?string} responseText A JSON response to clean.\n * @return {?string} The cleaned response.\n * @private\n */\nWebChannelDebug.prototype.redactResponse_ = function(responseText) {\n  if (!this.redactEnabled_) {\n    return responseText;\n  }\n\n  if (!responseText) {\n    return null;\n  }\n\n  try {\n    var responseArray = JSON.parse(responseText);\n    if (responseArray) {\n      for (var i = 0; i < responseArray.length; i++) {\n        if (Array.isArray(responseArray[i])) {\n          this.maybeRedactArray_(responseArray[i]);\n        }\n      }\n    }\n\n    return goog.json.serialize(responseArray);\n  } catch (e) {\n    this.debug('Exception parsing expected JS array - probably was not JS');\n    return responseText;\n  }\n};\n\n\n/**\n * Removes data from a response array that may be sensitive.\n * @param {!Array<?>} array The array to clean.\n * @private\n */\nWebChannelDebug.prototype.maybeRedactArray_ = function(array) {\n  if (array.length < 2) {\n    return;\n  }\n  var dataPart = array[1];\n  if (!Array.isArray(dataPart)) {\n    return;\n  }\n  if (dataPart.length < 1) {\n    return;\n  }\n\n  var type = dataPart[0];\n  if (type != 'noop' && type != 'stop' && type != 'close') {\n    // redact all fields in the array\n    for (var i = 1; i < dataPart.length; i++) {\n      dataPart[i] = '';\n    }\n  }\n};\n\n\n/**\n * Removes potentially private data from a request POST body so that we don't\n * accidentally save private and personal data to the server logs.\n * @param {?string} data The data string to clean.\n * @return {?string} The data string with sensitive data replaced by 'redacted'.\n * @private\n */\nWebChannelDebug.prototype.maybeRedactPostData_ = function(data) {\n  if (!this.redactEnabled_) {\n    return data;\n  }\n\n  if (!data) {\n    return null;\n  }\n  var out = '';\n  var params = data.split('&');\n  for (var i = 0; i < params.length; i++) {\n    var param = params[i];\n    var keyValue = param.split('=');\n    if (keyValue.length > 1) {\n      var key = keyValue[0];\n      var value = keyValue[1];\n\n      var keyParts = key.split('_');\n      if (keyParts.length >= 2 && keyParts[1] == 'type') {\n        out += key + '=' + value + '&';\n      } else {\n        out += key + '=' +\n            'redacted' +\n            '&';\n      }\n    }\n  }\n  return out;\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Static utilities for collecting stats associated with\n * ChannelRequest.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.requestStats');\ngoog.provide('goog.labs.net.webChannel.requestStats.Event');\ngoog.provide('goog.labs.net.webChannel.requestStats.ServerReachability');\ngoog.provide('goog.labs.net.webChannel.requestStats.ServerReachabilityEvent');\ngoog.provide('goog.labs.net.webChannel.requestStats.Stat');\ngoog.provide('goog.labs.net.webChannel.requestStats.StatEvent');\ngoog.provide('goog.labs.net.webChannel.requestStats.TimingEvent');\n\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\n\n\ngoog.scope(function() {\nvar requestStats = goog.labs.net.webChannel.requestStats;\n\n\n/**\n * Events fired.\n * @const\n */\nrequestStats.Event = {};\n\n\n/**\n * Singleton event target for firing stat events\n * @type {?goog.events.EventTarget}\n * @private\n */\nrequestStats.eventTarget_ = null;\n\n/**\n * Singleton event target for firing stat events\n * @return {!goog.events.EventTarget}\n * @private\n */\nrequestStats.getStatEventTarget_ = function() {\n  requestStats.eventTarget_ =\n      requestStats.eventTarget_ || new goog.events.EventTarget();\n  return requestStats.eventTarget_;\n};\n\n/**\n * The type of event that occurs every time some information about how reachable\n * the server is is discovered.\n */\nrequestStats.Event.SERVER_REACHABILITY_EVENT = 'serverreachability';\n\n\n/**\n * Types of events which reveal information about the reachability of the\n * server.\n * @enum {number}\n */\nrequestStats.ServerReachability = {\n  REQUEST_MADE: 1,\n  REQUEST_SUCCEEDED: 2,\n  REQUEST_FAILED: 3,\n  BACK_CHANNEL_ACTIVITY: 4  // any response data received\n};\n\n\n\n/**\n * Event class for SERVER_REACHABILITY_EVENT.\n *\n * @param {goog.events.EventTarget} target The stat event target for\n       the channel.\n * @param {requestStats.ServerReachability} reachabilityType\n *     The reachability event type.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.ServerReachabilityEvent = function(target, reachabilityType) {\n  goog.events.Event.call(\n      this, requestStats.Event.SERVER_REACHABILITY_EVENT, target);\n\n  /**\n   * @type {requestStats.ServerReachability}\n   */\n  this.reachabilityType = reachabilityType;\n};\ngoog.inherits(requestStats.ServerReachabilityEvent, goog.events.Event);\n\n\n/**\n * Notify the channel that a particular fine grained network event has occurred.\n * Should be considered package-private.\n * @param {requestStats.ServerReachability} reachabilityType\n *     The reachability event type.\n */\nrequestStats.notifyServerReachabilityEvent = function(reachabilityType) {\n  var target = requestStats.getStatEventTarget_();\n  target.dispatchEvent(\n      new requestStats.ServerReachabilityEvent(target, reachabilityType));\n};\n\n\n/**\n * Stat Event that fires when things of interest happen that may be useful for\n * applications to know about for stats or debugging purposes.\n */\nrequestStats.Event.STAT_EVENT = 'statevent';\n\n\n/**\n * Enum that identifies events for statistics that are interesting to track.\n * @enum {number}\n */\nrequestStats.Stat = {\n  /** Event indicating a new connection attempt. */\n  CONNECT_ATTEMPT: 0,\n\n  /** Event indicating a connection error due to a general network problem. */\n  ERROR_NETWORK: 1,\n\n  /**\n   * Event indicating a connection error that isn't due to a general network\n   * problem.\n   */\n  ERROR_OTHER: 2,\n\n  /** Event indicating the start of test stage one. */\n  TEST_STAGE_ONE_START: 3,\n\n  /** Event indicating the start of test stage two. */\n  TEST_STAGE_TWO_START: 4,\n\n  /** Event indicating the first piece of test data was received. */\n  TEST_STAGE_TWO_DATA_ONE: 5,\n\n  /**\n   * Event indicating that the second piece of test data was received and it was\n   * received separately from the first.\n   */\n  TEST_STAGE_TWO_DATA_TWO: 6,\n\n  /** Event indicating both pieces of test data were received simultaneously. */\n  TEST_STAGE_TWO_DATA_BOTH: 7,\n\n  /** Event indicating stage one of the test request failed. */\n  TEST_STAGE_ONE_FAILED: 8,\n\n  /** Event indicating stage two of the test request failed. */\n  TEST_STAGE_TWO_FAILED: 9,\n\n  /**\n   * Event indicating that a buffering proxy is likely between the client and\n   * the server.\n   */\n  PROXY: 10,\n\n  /**\n   * Event indicating that no buffering proxy is likely between the client and\n   * the server.\n   */\n  NOPROXY: 11,\n\n  /** Event indicating an unknown SID error. */\n  REQUEST_UNKNOWN_SESSION_ID: 12,\n\n  /** Event indicating a bad status code was received. */\n  REQUEST_BAD_STATUS: 13,\n\n  /** Event indicating incomplete data was received */\n  REQUEST_INCOMPLETE_DATA: 14,\n\n  /** Event indicating bad data was received */\n  REQUEST_BAD_DATA: 15,\n\n  /** Event indicating no data was received when data was expected. */\n  REQUEST_NO_DATA: 16,\n\n  /** Event indicating a request timeout. */\n  REQUEST_TIMEOUT: 17,\n\n  /**\n   * Event indicating that the server never received our hanging GET and so it\n   * is being retried.\n   */\n  BACKCHANNEL_MISSING: 18,\n\n  /**\n   * Event indicating that we have determined that our hanging GET is not\n   * receiving data when it should be. Thus it is dead dead and will be retried.\n   */\n  BACKCHANNEL_DEAD: 19,\n\n  /**\n   * The browser declared itself offline during the lifetime of a request, or\n   * was offline when a request was initially made.\n   */\n  BROWSER_OFFLINE: 20\n};\n\n\n\n/**\n * Event class for STAT_EVENT.\n *\n * @param {goog.events.EventTarget} eventTarget The stat event target for\n       the channel.\n * @param {requestStats.Stat} stat The stat.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.StatEvent = function(eventTarget, stat) {\n  goog.events.Event.call(this, requestStats.Event.STAT_EVENT, eventTarget);\n\n  /**\n   * The stat\n   * @type {requestStats.Stat}\n   */\n  this.stat = stat;\n\n};\ngoog.inherits(requestStats.StatEvent, goog.events.Event);\n\n\n/**\n * Returns the singleton event target for stat events.\n * @return {!goog.events.EventTarget} The event target for stat events.\n */\nrequestStats.getStatEventTarget = function() {\n  return requestStats.getStatEventTarget_();\n};\n\n\n/**\n * Helper function to call the stat event callback.\n * @param {requestStats.Stat} stat The stat.\n */\nrequestStats.notifyStatEvent = function(stat) {\n  var target = requestStats.getStatEventTarget_();\n  target.dispatchEvent(new requestStats.StatEvent(target, stat));\n};\n\n\n/**\n * An event that fires when POST requests complete successfully, indicating\n * the size of the POST and the round trip time.\n */\nrequestStats.Event.TIMING_EVENT = 'timingevent';\n\n\n\n/**\n * Event class for requestStats.Event.TIMING_EVENT\n *\n * @param {goog.events.EventTarget} target The stat event target for\n       the channel.\n * @param {number} size The number of characters in the POST data.\n * @param {number} rtt The total round trip time from POST to response in MS.\n * @param {number} retries The number of times the POST had to be retried.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.TimingEvent = function(target, size, rtt, retries) {\n  goog.events.Event.call(this, requestStats.Event.TIMING_EVENT, target);\n\n  /**\n   * @type {number}\n   */\n  this.size = size;\n\n  /**\n   * @type {number}\n   */\n  this.rtt = rtt;\n\n  /**\n   * @type {number}\n   */\n  this.retries = retries;\n\n};\ngoog.inherits(requestStats.TimingEvent, goog.events.Event);\n\n\n/**\n * Helper function to notify listeners about POST request performance.\n *\n * @param {number} size Number of characters in the POST data.\n * @param {number} rtt The amount of time from POST start to response.\n * @param {number} retries The number of times the POST had to be retried.\n */\nrequestStats.notifyTimingEvent = function(size, rtt, retries) {\n  var target = requestStats.getStatEventTarget_();\n  target.dispatchEvent(\n      new requestStats.TimingEvent(target, size, rtt, retries));\n};\n\n\n/**\n * Allows the application to set an execution hooks for when a channel\n * starts processing requests. This is useful to track timing or logging\n * special information. The function takes no parameters and return void.\n * @param {Function} startHook  The function for the start hook.\n */\nrequestStats.setStartThreadExecutionHook = function(startHook) {\n  requestStats.startExecutionHook_ = startHook;\n};\n\n\n/**\n * Allows the application to set an execution hooks for when a channel\n * stops processing requests. This is useful to track timing or logging\n * special information. The function takes no parameters and return void.\n * @param {Function} endHook  The function for the end hook.\n */\nrequestStats.setEndThreadExecutionHook = function(endHook) {\n  requestStats.endExecutionHook_ = endHook;\n};\n\n\n/**\n * Application provided execution hook for the start hook.\n *\n * @type {Function}\n * @private\n */\nrequestStats.startExecutionHook_ = function() {};\n\n\n/**\n * Application provided execution hook for the end hook.\n *\n * @type {Function}\n * @private\n */\nrequestStats.endExecutionHook_ = function() {};\n\n\n/**\n * Helper function to call the start hook\n */\nrequestStats.onStartExecution = function() {\n  requestStats.startExecutionHook_();\n};\n\n\n/**\n * Helper function to call the end hook\n */\nrequestStats.onEndExecution = function() {\n  requestStats.endExecutionHook_();\n};\n\n\n/**\n * Wrapper around SafeTimeout which calls the start and end execution hooks\n * with a try...finally block.\n * @param {Function} fn The callback function.\n * @param {number} ms The time in MS for the timer.\n * @return {number} The ID of the timer.\n */\nrequestStats.setTimeout = function(fn, ms) {\n  if (!goog.isFunction(fn)) {\n    throw new Error('Fn must not be null and must be a function');\n  }\n  return goog.global.setTimeout(function() {\n    requestStats.onStartExecution();\n    try {\n      fn();\n    } finally {\n      requestStats.onEndExecution();\n    }\n  }, ms);\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Error codes shared between goog.net.IframeIo and\n * goog.net.XhrIo.\n */\n\ngoog.provide('goog.net.ErrorCode');\n\n\n/**\n * Error codes\n * @enum {number}\n */\ngoog.net.ErrorCode = {\n\n  /**\n   * There is no error condition.\n   */\n  NO_ERROR: 0,\n\n  /**\n   * The most common error from iframeio, unfortunately, is that the browser\n   * responded with an error page that is classed as a different domain. The\n   * situations, are when a browser error page  is shown -- 404, access denied,\n   * DNS failure, connection reset etc.)\n   *\n   */\n  ACCESS_DENIED: 1,\n\n  /**\n   * Currently the only case where file not found will be caused is when the\n   * code is running on the local file system and a non-IE browser makes a\n   * request to a file that doesn't exist.\n   */\n  FILE_NOT_FOUND: 2,\n\n  /**\n   * If Firefox shows a browser error page, such as a connection reset by\n   * server or access denied, then it will fail silently without the error or\n   * load handlers firing.\n   */\n  FF_SILENT_ERROR: 3,\n\n  /**\n   * Custom error provided by the client through the error check hook.\n   */\n  CUSTOM_ERROR: 4,\n\n  /**\n   * Exception was thrown while processing the request.\n   */\n  EXCEPTION: 5,\n\n  /**\n   * The Http response returned a non-successful http status code.\n   */\n  HTTP_ERROR: 6,\n\n  /**\n   * The request was aborted.\n   */\n  ABORT: 7,\n\n  /**\n   * The request timed out.\n   */\n  TIMEOUT: 8,\n\n  /**\n   * The resource is not available offline.\n   */\n  OFFLINE: 9,\n};\n\n\n/**\n * Returns a friendly error message for an error code. These messages are for\n * debugging and are not localized.\n * @param {goog.net.ErrorCode} errorCode An error code.\n * @return {string} A message for debugging.\n */\ngoog.net.ErrorCode.getDebugMessage = function(errorCode) {\n  switch (errorCode) {\n    case goog.net.ErrorCode.NO_ERROR:\n      return 'No Error';\n\n    case goog.net.ErrorCode.ACCESS_DENIED:\n      return 'Access denied to content document';\n\n    case goog.net.ErrorCode.FILE_NOT_FOUND:\n      return 'File not found';\n\n    case goog.net.ErrorCode.FF_SILENT_ERROR:\n      return 'Firefox silently errored';\n\n    case goog.net.ErrorCode.CUSTOM_ERROR:\n      return 'Application custom error';\n\n    case goog.net.ErrorCode.EXCEPTION:\n      return 'An exception occurred';\n\n    case goog.net.ErrorCode.HTTP_ERROR:\n      return 'Http response at 400 or 500 level';\n\n    case goog.net.ErrorCode.ABORT:\n      return 'Request was aborted';\n\n    case goog.net.ErrorCode.TIMEOUT:\n      return 'Request timed out';\n\n    case goog.net.ErrorCode.OFFLINE:\n      return 'The resource is not available offline';\n\n    default:\n      return 'Unrecognized error code';\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Common events for the network classes.\n */\n\n\ngoog.provide('goog.net.EventType');\n\n\n/**\n * Event names for network events\n * @enum {string}\n */\ngoog.net.EventType = {\n  COMPLETE: 'complete',\n  SUCCESS: 'success',\n  ERROR: 'error',\n  ABORT: 'abort',\n  READY: 'ready',\n  READY_STATE_CHANGE: 'readystatechange',\n  TIMEOUT: 'timeout',\n  INCREMENTAL_DATA: 'incrementaldata',\n  PROGRESS: 'progress',\n  // DOWNLOAD_PROGRESS and UPLOAD_PROGRESS are special events dispatched by\n  // goog.net.XhrIo to allow binding listeners specific to each type of\n  // progress.\n  DOWNLOAD_PROGRESS: 'downloadprogress',\n  UPLOAD_PROGRESS: 'uploadprogress',\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Interface for a factory for creating XMLHttpRequest objects\n * and metadata about them.\n */\n\ngoog.provide('goog.net.XmlHttpFactory');\n\n/** @suppress {extraRequire} Typedef. */\ngoog.require('goog.net.XhrLike');\n\n\n\n/**\n * Abstract base class for an XmlHttpRequest factory.\n * @constructor\n */\ngoog.net.XmlHttpFactory = function() {};\n\n\n/**\n * Cache of options - we only actually call internalGetOptions once.\n * @type {?Object}\n * @private\n */\ngoog.net.XmlHttpFactory.prototype.cachedOptions_ = null;\n\n\n/**\n * @return {!goog.net.XhrLike.OrNative} A new XhrLike instance.\n */\ngoog.net.XmlHttpFactory.prototype.createInstance = goog.abstractMethod;\n\n\n/**\n * @return {Object} Options describing how xhr objects obtained from this\n *     factory should be used.\n */\ngoog.net.XmlHttpFactory.prototype.getOptions = function() {\n  return this.cachedOptions_ ||\n      (this.cachedOptions_ = this.internalGetOptions());\n};\n\n\n/**\n * Override this method in subclasses to preserve the caching offered by\n * getOptions().\n * @return {Object} Options describing how xhr objects obtained from this\n *     factory should be used.\n * @protected\n */\ngoog.net.XmlHttpFactory.prototype.internalGetOptions = goog.abstractMethod;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The API spec for the WebChannel messaging library.\n *\n * Similar to HTML5 WebSocket, WebChannel offers an abstraction for\n * point-to-point socket-like communication between a browser client and\n * a remote origin.\n *\n * WebChannels are created via <code>WebChannel</code>. Multiple WebChannels\n * may be multiplexed over the same WebChannelTransport, which represents\n * the underlying physical connectivity over standard wire protocols\n * such as HTTP.\n *\n * A WebChannel in turn represents a logical communication channel between\n * the client and server end point. A WebChannel remains open for as long\n * as the client or server end-point allows.\n *\n * Messages are delivered in-order and reliably over the same WebChannel,\n * and the choice of the underlying wire protocols is completely transparent\n * to the API users.\n *\n * Note that we have no immediate plan to move this API out of labs. While\n * the implementation is production ready, the API is subject to change.\n */\n\ngoog.provide('goog.net.WebChannel');\ngoog.provide('goog.net.WebChannel.Options');\n\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * A WebChannel represents a logical bi-directional channel over which the\n * client communicates with a remote server that holds the other endpoint\n * of the channel. A WebChannel is always created in the context of a shared\n * {@link WebChannelTransport} instance. It is up to the underlying client-side\n * and server-side implementations to decide how or when multiplexing is\n * to be enabled.\n *\n * @interface\n * @extends {EventTarget}\n * @extends {goog.events.Listenable}\n */\ngoog.net.WebChannel = function() {};\n\n\n\n/**\n * This interface defines a pluggable API to allow WebChannel runtime to support\n * customized algorithms in order to recover from transient failures such as\n * those failures caused by network or proxies (intermediaries).\n *\n * The algorithm may also choose to fail-fast, e.g. switch the client to some\n * offline mode.\n *\n * Extra measurements and logging could also be implemented in the custom\n * module, which has the full knowledge of all the state transitions\n * (due to failures).\n *\n * A default algorithm will be provided by the webchannel library itself. Custom\n * algorithms are expected to be tailored to specific client platforms or\n * networking environments, e.g. mobile, cellular network.\n *\n * @interface\n */\ngoog.net.WebChannel.FailureRecovery = function() {};\n\n\n/**\n * Configuration spec for newly created WebChannel instances.\n *\n * WebChannels are configured in the context of the containing\n * {@link WebChannelTransport}. The configuration parameters are specified\n * when a new instance of WebChannel is created via {@link WebChannelTransport}.\n * @record\n */\ngoog.net.WebChannel.Options = function() {};\n\n/**\n * Custom headers to be added to every message sent to the\n * server. This object is mutable, and custom headers may be changed, removed,\n * or added during the runtime after a channel has been\n * opened\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageHeaders;\n\n/**\n * Similar to messageHeaders, but any custom headers will\n * be sent only once when the channel is opened. Typical usage is to send\n * an auth header to the server, which only checks the auth header at the time\n * when the channel is opened.\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.initMessageHeaders;\n\n/**\n * Sent as initMessageHeaders via X-WebChannel-Content-Type,\n * to inform the server the MIME type of WebChannel messages.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageContentType;\n\n/**\n * Custom url query parameters to be added to every message\n * sent to the server. This object is mutable, and custom parameters may be\n * changed, removed or added during the runtime after a channel has been opened.\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageUrlParams;\n\n/**\n * Whether a special header should be added to\n * each message so that the server can dispatch webchannel messages without\n * knowing the URL path prefix. Defaults to false.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.clientProtocolHeaderRequired;\n\n/**\n * The maximum number of in-flight HTTP requests allowed\n * when SPDY is enabled. Currently we only detect SPDY in Chrome.\n * This parameter defaults to 10. When SPDY is not enabled, this parameter\n * will have no effect.\n * @type {number|undefined}\n */\ngoog.net.WebChannel.Options.prototype.concurrentRequestLimit;\n\n/**\n * Setting this to true to allow the use of sub-domains\n * (as configured by the server) to send XHRs with the CORS withCredentials\n * bit set to true.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.supportsCrossDomainXhr;\n\n/**\n * Whether to bypass v8 encoding of client-sent messages.\n * This defaults to false now due to legacy servers. New applications should\n * always configure this option to true.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.sendRawJson;\n\n/**\n * The URL parameter name that contains the session id (for sticky routing of\n * HTTP requests). When this param is specified, a server that supports this\n * option will respond with an opaque session id as part of the initial\n * handshake (via the X-HTTP-Session-Id header); and all the subsequent requests\n * will contain the httpSessionIdParam. This option will take precedence over\n * any duplicated parameter specified with messageUrlParams, whose value will be\n * ignored.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.httpSessionIdParam;\n\n/**\n * The URL parameter name to allow custom HTTP\n * headers to be overwritten as a URL param to bypass CORS preflight.\n * goog.net.rpc.HttpCors is used to encode the HTTP headers.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.httpHeadersOverwriteParam;\n\n/**\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.backgroundChannelTest;\n\n/**\n * Whether to force long-polling from client to server.\n * This defaults to false. Long-polling may be necessary when a (MITM) proxy\n * is buffering data sent by the server.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.forceLongPolling;\n\n/**\n * Whether to enable automatic detection of buffering proxies. In the presence\n * of any buffering proxy, webchannel will use long-polling to send messages\n * from the server to the client. This option defaults to false.\n * Currently when fastHandshake is enabled, this option will be ignored.\n * Compared to \"forceLongPolling\", this option may introduce up to 2-RTT\n * extra latency for delivering messages generated immediately after the\n * handshake.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.detectBufferingProxy;\n\n/**\n * Enable true 0-RTT message delivery, including\n * leveraging QUIC 0-RTT (which requires GET to be used). This option\n * defaults to false. Note it is allowed to send messages before Open event is\n * received, after a channel has been opened. In order to enable 0-RTT,\n * messages will be encoded as part of URL and therefore there needs be a size\n * limit for those initial messages that are sent immediately as part of the\n * GET handshake request. With sendRawJson=true, this limit is currently set\n * to 4K chars and data beyond this limit will be buffered till the handshake\n * (1-RTT) finishes. With sendRawJson=false, it's up to the application\n * to limit the amount of data that is sent as part of the handshake.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.fastHandshake;\n\n/**\n * Enable the blocking RPC semantics for the handshake:\n * 1) the completion of handshake is blocked by the server-side application\n * logic for handling the handshake (HTTP) request; 2) the client application\n * will inspect the handshake (HTTP) response headers as generated\n * by the server application (v.s. by only the webchannel runtime). This option\n * defaults to false.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.blockingHandshake;\n\n/**\n * Whether to disable logging redact. By default, redact is\n * enabled to remove any message payload or user-provided info\n * from closure logs.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.disableRedact;\n\n/**\n * Inform the server about the client profile to enable\n * customized configs that are optimized for certain clients or environments.\n * Currently this information is sent via X-WebChannel-Client-Profile header.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.clientProfile;\n\n/**\n * The internal channel parameter name to allow\n * experimental channel configurations. Supported options include fastfail,\n * baseRetryDelayMs, retryDelaySeedMs, forwardChannelMaxRetries and\n * forwardChannelRequestTimeoutMs. Note that these options are subject to\n * change.\n * @type {!Object<string, boolean|number>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.internalChannelParams;\n\n/**\n * Allows the caller to override the factory used to create\n * XMLHttpRequest objects. This is introduced to disable CORS on firefox OS.\n * @type {!goog.net.XmlHttpFactory|undefined}\n */\ngoog.net.WebChannel.Options.prototype.xmlHttpFactory;\n\n/**\n * Client-side thresholds that decide when to refresh\n * an underlying HTTP request, to limit memory consumption due to XHR buffering\n * or compression context. The client-side thresholds should be signficantly\n * smaller than the server-side thresholds. This allows the client to eliminate\n * any latency introduced by request refreshing, i.e. an RTT window during which\n * messages may be buffered on the server-side. Supported params include\n * totalBytesReceived, totalDurationMs.\n * @type {!Object<string, number>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.requestRefreshThresholds;\n\n\n/**\n * Types that are allowed as message data.\n *\n * Note that JS objects (sent by the client) can only have string encoded\n * values due to the limitation of the current wire protocol.\n *\n * Unicode strings (sent by the server) may or may not need be escaped, as\n * decided by the server.\n *\n * @typedef {(!ArrayBuffer|!Blob|!Object<string, !Object|string>|!Array|string)}\n */\ngoog.net.WebChannel.MessageData;\n\n\n/**\n * Open the WebChannel against the URI specified in the constructor.\n */\ngoog.net.WebChannel.prototype.open = goog.abstractMethod;\n\n\n/**\n * Close the WebChannel.\n *\n * This is a full close (shutdown) with no guarantee of FIFO delivery in respect\n * to any in-flight messages sent to the server.\n *\n * If you need such a guarantee, see the Half the halfClose() method.\n */\ngoog.net.WebChannel.prototype.close = goog.abstractMethod;\n\n\n/**\n * Half-close the WebChannel.\n *\n * Half-close semantics:\n * 1. delivered as a regular message in FIFO programming order\n * 2. the server is expected to return a half-close too (with or without\n *    application involved), which will trigger a full close (shutdown)\n *    on the client side\n * 3. for now, the half-close event defined for server-initiated\n *    half-close is not exposed to the client application\n * 4. a client-side half-close may be triggered internally when the client\n *    receives a half-close from the server; and the client is expected to\n *    do a full close after the half-close is acked and delivered\n *    on the server-side.\n * 5. Full close is always a forced one. See the close() method.\n *\n * New messages sent after halfClose() will be dropped.\n *\n * NOTE: This is not yet implemented, and will throw an exception if called.\n */\ngoog.net.WebChannel.prototype.halfClose = goog.abstractMethod;\n\n\n/**\n * Sends a message to the server that maintains the other end point of\n * the WebChannel.\n *\n * O-RTT behavior:\n * 1. messages sent before open() is called will always be delivered as\n *    part of the handshake, i.e. with 0-RTT\n * 2. messages sent after open() is called but before the OPEN event\n *    is received will be delivered as part of the handshake if\n *    send() is called from the same execution context as open().\n * 3. otherwise, those messages will be buffered till the handshake\n *    is completed (which will fire the OPEN event).\n *\n * @param {!goog.net.WebChannel.MessageData} message The message to send.\n */\ngoog.net.WebChannel.prototype.send = goog.abstractMethod;\n\n\n/**\n * Common events fired by WebChannels.\n * @enum {string}\n */\ngoog.net.WebChannel.EventType = {\n  /** Dispatched when the channel is opened. */\n  OPEN: goog.events.getUniqueId('open'),\n\n  /** Dispatched when the channel is closed. */\n  CLOSE: goog.events.getUniqueId('close'),\n\n  /**\n   * Dispatched when the channel is aborted due to errors.\n   *\n   * For backward compatibility reasons, a CLOSE event will also be\n   * dispatched, following the ERROR event, which indicates that the channel\n   * has been completely shutdown .\n   */\n  ERROR: goog.events.getUniqueId('error'),\n\n  /** Dispatched when the channel has received a new message. */\n  MESSAGE: goog.events.getUniqueId('message')\n};\n\n\n\n/**\n * The event interface for the MESSAGE event.\n *\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.net.WebChannel.MessageEvent = function() {\n  goog.net.WebChannel.MessageEvent.base(\n      this, 'constructor', goog.net.WebChannel.EventType.MESSAGE);\n};\ngoog.inherits(goog.net.WebChannel.MessageEvent, goog.events.Event);\n\n\n/**\n * The content of the message received from the server.\n *\n * @type {!goog.net.WebChannel.MessageData}\n */\ngoog.net.WebChannel.MessageEvent.prototype.data;\n\n\n/**\n * The metadata key when the MESSAGE event represents a metadata message.\n *\n * @type {string|undefined}\n */\ngoog.net.WebChannel.MessageEvent.prototype.metadataKey;\n\n\n/**\n * WebChannel level error conditions.\n *\n * Summary of error debugging and reporting in WebChannel:\n *\n * Network Error\n * 1. By default the webchannel library will set the error status to\n *    NETWORK_ERROR when a channel has to be aborted or closed. NETWORK_ERROR\n *    may be recovered by the application by retrying and opening a new channel.\n * 2. There may be lost messages (not acked by the server) when a channel is\n *    aborted. Currently we don't have a public API to retrieve messages that\n *    are waiting to be acked on the client side. File a bug if you think it\n *    is useful to expose such an API.\n * 3. Details of why a channel fails are available via closure debug logs,\n *    and stats events (see webchannel/requeststats.js). Those are internal\n *    stats and are subject to change. File a bug if you think it's useful to\n *    version and expose such stats as part of the WebChannel API.\n *\n * Server Error\n * 1. SERVER_ERROR is intended to indicate a non-recoverable condition, e.g.\n *    when auth fails.\n * 2. We don't currently generate any such errors, because most of the time\n *    it's the responsibility of upper-layer frameworks or the application\n *    itself to indicate to the client why a webchannel has been failed\n *    by the server.\n * 3. When a channel is failed by the server explicitly, we still signal\n *    NETWORK_ERROR to the client. Explicit server failure may happen when the\n *    server does a fail-over, or becomes overloaded, or conducts a forced\n *    shutdown etc.\n * 4. We use some heuristic to decide if the network (aka cloud) is down\n *    v.s. the actual server is down.\n *\n *  RuntimeProperties.getLastStatusCode is a useful state that we expose to\n *  the client to indicate the HTTP response status code of the last HTTP\n *  request initiated by the WebChannel client library, for debugging\n *  purposes only.\n *\n *  See WebChannel.Options.backChannelFailureRecovery and\n *  WebChannel.FailureRecovery to install a custom failure-recovery algorithm.\n *\n * @enum {number}\n */\ngoog.net.WebChannel.ErrorStatus = {\n  /** No error has occurred. */\n  OK: 0,\n\n  /** Communication to the server has failed. */\n  NETWORK_ERROR: 1,\n\n  /** The server fails to accept or process the WebChannel. */\n  SERVER_ERROR: 2\n};\n\n\n\n/**\n * The event interface for the ERROR event.\n *\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.net.WebChannel.ErrorEvent = function() {\n  goog.net.WebChannel.ErrorEvent.base(\n      this, 'constructor', goog.net.WebChannel.EventType.ERROR);\n};\ngoog.inherits(goog.net.WebChannel.ErrorEvent, goog.events.Event);\n\n\n/**\n * The error status.\n *\n * @type {!goog.net.WebChannel.ErrorStatus}\n */\ngoog.net.WebChannel.ErrorEvent.prototype.status;\n\n\n/**\n * @return {!goog.net.WebChannel.RuntimeProperties} The runtime properties\n * of the WebChannel instance.\n */\ngoog.net.WebChannel.prototype.getRuntimeProperties = goog.abstractMethod;\n\n\n\n/**\n * The runtime properties of the WebChannel instance.\n *\n * This class is defined for debugging and monitoring purposes, as well as for\n * runtime functions that the application may choose to manage by itself.\n *\n * @interface\n */\ngoog.net.WebChannel.RuntimeProperties = function() {};\n\n\n/**\n * @return {number} The effective limit for the number of concurrent HTTP\n * requests that are allowed to be made for sending messages from the client\n * to the server. When SPDY is not enabled, this limit will be one.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getConcurrentRequestLimit =\n    goog.abstractMethod;\n\n\n/**\n * For applications that need support multiple channels (e.g. from\n * different tabs) to the same origin, use this method to decide if SPDY is\n * enabled and therefore it is safe to open multiple channels.\n *\n * If SPDY is disabled, the application may choose to limit the number of active\n * channels to one or use other means such as sub-domains to work around\n * the browser connection limit.\n *\n * @return {boolean} Whether SPDY is enabled for the origin against which\n * the channel is created.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.isSpdyEnabled =\n    goog.abstractMethod;\n\n\n/**\n * @return {number} The number of requests (for sending messages to the server)\n * that are pending. If this number is approaching the value of\n * getConcurrentRequestLimit(), client-to-server message delivery may experience\n * a higher latency.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getPendingRequestCount =\n    goog.abstractMethod;\n\n\n/**\n * For applications to query the current HTTP session id, sent by the server\n * during the initial handshake.\n *\n * @return {?string} the HTTP session id or null if no HTTP session is in use.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getHttpSessionId =\n    goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method generates an in-band commit request to the server, which will\n * ack the commit request as soon as all messages sent prior to this commit\n * request have been committed by the application.\n *\n * Committing a message has a stronger semantics than delivering a message\n * to the application. Detail spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * Timeout or cancellation is not supported and the application is expected to\n * abort the channel if the commit-ack fails to arrive in time.\n *\n * ===\n *\n * This is currently implemented only in the client layer and the commit\n * callback will be invoked after all the pending client-sent messages have been\n * delivered by the server-side webchannel end-point. This semantics is\n * different and weaker than what's required for end-to-end ack which requires\n * the server application to ack the in-order delivery of messages that are sent\n * before the commit request is issued.\n *\n * Commit should only be called after the channel open event is received.\n * Duplicated commits are allowed and only the last callback is guaranteed.\n * Commit called after the channel has been closed will be ignored.\n *\n * @param {function()} callback The callback will be invoked once an\n * ack has been received for the current commit or any newly issued commit.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.commit = goog.abstractMethod;\n\n\n/**\n * This method may be used by the application to recover from a peer failure\n * or to enable sender-initiated flow-control.\n *\n * Detail spec: https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * This is not yet implemented.\n *\n * @return {number} The total number of messages that have not received\n * commit-ack from the server; or if no commit has been issued, the number\n * of messages that have not been delivered to the server application.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getNonAckedMessageCount =\n    goog.abstractMethod;\n\n\n/**\n * A low water-mark message count to notify the application when the\n * flow-control condition is cleared, that is, when the application is\n * able to send more messages.\n *\n * We expect the application to configure a high water-mark message count,\n * which is checked via getNonAckedMessageCount(). When the high water-mark\n * is exceeded, the application should install a callback via this method\n * to be notified when to start to send new messages.\n *\n * This is not yet implemented.\n *\n * @param {number} count The low water-mark count. It is an error to pass\n * a non-positive value.\n * @param {function()} callback The call back to notify the application\n * when NonAckedMessageCount is below the specified low water-mark count.\n * Any previously registered callback is cleared. This new callback will\n * be cleared once it has been fired, or when the channel is closed or aborted.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.notifyNonAckedMessageCount =\n    goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method registers a callback to handle the commit request sent\n * by the server. Commit protocol spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * This is not yet implemented.\n *\n * @param {function(!Object)} callback The callback will take an opaque\n * commitId which needs be passed back to the server when an ack-commit\n * response is generated by the client application, via ackCommit().\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.onCommit = goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method is used by the application to generate an ack-commit response\n * for the given commitId. Commit protocol spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * This is not yet implemented.\n *\n * @param {!Object} commitId The commitId which denotes the commit request\n * from the server that needs be ack'ed.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.ackCommit = goog.abstractMethod;\n\n\n/**\n * @return {number} The last HTTP status code received by the channel.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getLastStatusCode =\n    goog.abstractMethod;\n\n\n/**\n * Enum to indicate the current recovery state.\n *\n * @enum {string}\n */\ngoog.net.WebChannel.FailureRecovery.State = {\n  /** Initial state. */\n  INIT: 'init',\n\n  /** Once a failure has been detected. */\n  FAILED: 'failed',\n\n  /**\n   * Once a recovery operation has been issued, e.g. a new request to resume\n   * communication.\n   */\n  RECOVERING: 'recovering',\n\n  /** The channel has been closed.  */\n  CLOSED: 'closed'\n};\n\n\n/**\n * Enum to indicate different failure conditions as detected by the webchannel\n * runtime.\n *\n * This enum is to be used only between the runtime and FailureRecovery module,\n * and new states are expected to be introduced in future.\n *\n * @enum {string}\n */\ngoog.net.WebChannel.FailureRecovery.FailureCondition = {\n  /**\n   * The HTTP response returned a non-successful http status code.\n   */\n  HTTP_ERROR: 'http_error',\n\n  /**\n   * The request was aborted.\n   */\n  ABORT: 'abort',\n\n  /**\n   * The request timed out.\n   */\n  TIMEOUT: 'timeout',\n\n  /**\n   * Exception was thrown while processing the request/response.\n   */\n  EXCEPTION: 'exception'\n};\n\n\n/**\n * @return {!goog.net.WebChannel.FailureRecovery.State} the current state,\n * mainly for debugging use.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.getState = goog.abstractMethod;\n\n\n/**\n * This method is for WebChannel runtime to set the current failure condition\n * and to provide a callback for the algorithm to signal to the runtime\n * when it is time to issue a recovery operation, e.g. a new request to the\n * server.\n *\n * Supported transitions include:\n *   INIT->FAILED\n *   FAILED->FAILED (re-entry ok)\n *   RECOVERY->FAILED.\n *\n * Ignored if state == CLOSED.\n *\n * Advanced implementations are expected to track all the state transitions\n * and their timestamps for monitoring purposes.\n *\n * @param {!goog.net.WebChannel.FailureRecovery.FailureCondition} failure The\n * new failure condition generated by the WebChannel runtime.\n * @param {!Function} operation The callback function to the WebChannel\n * runtime to issue a recovery operation, e.g. a new request. E.g. the default\n * recovery algorithm will issue timeout-based recovery operations.\n * Post-condition for the callback: state transition to RECOVERING.\n *\n * @return {!goog.net.WebChannel.FailureRecovery.State} The updated state\n * as decided by the failure recovery module. Upon a recoverable failure event,\n * the state is transitioned to RECOVERING; or the state is transitioned to\n * FAILED which indicates a fail-fast decision for the runtime to execute.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.setFailure = goog.abstractMethod;\n\n\n/**\n * The Webchannel runtime needs call this method when webchannel is closed or\n * aborted.\n *\n * Once the instance is closed, any access to the instance will be a no-op.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.close = goog.abstractMethod;\n\n\n/**\n * A request header to indicate to the server the messaging protocol\n * each HTTP message is speaking.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_PROTOCOL = 'X-Client-Protocol';\n\n\n/**\n * The value for x-client-protocol when the messaging protocol is WebChannel.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL = 'webchannel';\n\n\n/**\n * A response header for the server to signal the wire-protocol that\n * the browser establishes with the server (or proxy), e.g. \"spdy\" (aka http/2)\n * \"quic\". This information avoids the need to use private APIs to decide if\n * HTTP requests are multiplexed etc.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_WIRE_PROTOCOL = 'X-Client-Wire-Protocol';\n\n\n/**\n * A response header for the server to send back the HTTP session id as part of\n * the initial handshake. The value of the HTTP session id is opaque to the\n * WebChannel protocol.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_HTTP_SESSION_ID = 'X-HTTP-Session-Id';\n\n\n/**\n * A response header for the server to send back any initial response data as a\n * header to avoid any possible buffering by an intermediary, which may\n * be undesired during the handshake.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_HTTP_INITIAL_RESPONSE = 'X-HTTP-Initial-Response';\n\n\n/**\n * A request header for specifying the content-type of WebChannel messages,\n * e.g. application-defined JSON encoding styles. Currently this header\n * is sent by the client via initMessageHeaders when the channel is opened.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE = 'X-WebChannel-Content-Type';\n\n\n/**\n * A request header for specifying the client profile in order to apply\n * customized config params on the server side, e.g. timeouts.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE = 'X-WebChannel-Client-Profile';\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Low level handling of XMLHttpRequest.\n */\n\ngoog.provide('goog.net.DefaultXmlHttpFactory');\ngoog.provide('goog.net.XmlHttp');\ngoog.provide('goog.net.XmlHttp.OptionType');\ngoog.provide('goog.net.XmlHttp.ReadyState');\ngoog.provide('goog.net.XmlHttpDefines');\n\ngoog.require('goog.asserts');\ngoog.require('goog.net.WrapperXmlHttpFactory');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n/**\n * Static class for creating XMLHttpRequest objects.\n * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object.\n */\ngoog.net.XmlHttp = function() {\n  return goog.net.XmlHttp.factory_.createInstance();\n};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n *     true bypasses the ActiveX probing code.\n * NOTE(ruilopes): Due to the way JSCompiler works, this define *will not* strip\n * out the ActiveX probing code from binaries.  To achieve this, use\n * `goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR` instead.\n * TODO(ruilopes): Collapse both defines.\n */\ngoog.net.XmlHttp.ASSUME_NATIVE_XHR =\n    goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);\n\n\n/** @const */\ngoog.net.XmlHttpDefines = {};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n *     true eliminates the ActiveX probing code.\n */\ngoog.net.XmlHttpDefines.ASSUME_NATIVE_XHR =\n    goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false);\n\n\n/**\n * Gets the options to use with the XMLHttpRequest objects obtained using\n * the static methods.\n * @return {Object} The options.\n */\ngoog.net.XmlHttp.getOptions = function() {\n  return goog.net.XmlHttp.factory_.getOptions();\n};\n\n\n/**\n * Type of options that an XmlHttp object can have.\n * @enum {number}\n */\ngoog.net.XmlHttp.OptionType = {\n  /**\n   * Whether a goog.nullFunction should be used to clear the onreadystatechange\n   * handler instead of null.\n   */\n  USE_NULL_FUNCTION: 0,\n\n  /**\n   * NOTE(user): In IE if send() errors on a *local* request the readystate\n   * is still changed to COMPLETE.  We need to ignore it and allow the\n   * try/catch around send() to pick up the error.\n   */\n  LOCAL_REQUEST_ERROR: 1,\n};\n\n\n/**\n * Status constants for XMLHTTP, matches:\n * https://msdn.microsoft.com/en-us/library/ms534361(v=vs.85).aspx\n * @enum {number}\n */\ngoog.net.XmlHttp.ReadyState = {\n  /**\n   * Constant for when xmlhttprequest.readyState is uninitialized\n   */\n  UNINITIALIZED: 0,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is loading.\n   */\n  LOADING: 1,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is loaded.\n   */\n  LOADED: 2,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is in an interactive state.\n   */\n  INTERACTIVE: 3,\n\n  /**\n   * Constant for when xmlhttprequest.readyState is completed\n   */\n  COMPLETE: 4,\n};\n\n\n/**\n * The global factory instance for creating XMLHttpRequest objects.\n * @type {goog.net.XmlHttpFactory}\n * @private\n */\ngoog.net.XmlHttp.factory_;\n\n\n/**\n * Sets the factories for creating XMLHttpRequest objects and their options.\n * @param {Function} factory The factory for XMLHttpRequest objects.\n * @param {Function} optionsFactory The factory for options.\n * @deprecated Use setGlobalFactory instead.\n */\ngoog.net.XmlHttp.setFactory = function(factory, optionsFactory) {\n  goog.net.XmlHttp.setGlobalFactory(\n      new goog.net.WrapperXmlHttpFactory(\n          goog.asserts.assert(factory), goog.asserts.assert(optionsFactory)));\n};\n\n\n/**\n * Sets the global factory object.\n * @param {!goog.net.XmlHttpFactory} factory New global factory object.\n */\ngoog.net.XmlHttp.setGlobalFactory = function(factory) {\n  goog.net.XmlHttp.factory_ = factory;\n};\n\n\n\n/**\n * Default factory to use when creating xhr objects.  You probably shouldn't be\n * instantiating this directly, but rather using it via goog.net.XmlHttp.\n * @extends {goog.net.XmlHttpFactory}\n * @constructor\n */\ngoog.net.DefaultXmlHttpFactory = function() {\n  goog.net.XmlHttpFactory.call(this);\n};\ngoog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {\n  var progId = this.getProgId_();\n  if (progId) {\n    return new ActiveXObject(progId);\n  } else {\n    return new XMLHttpRequest();\n  }\n};\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {\n  var progId = this.getProgId_();\n  var options = {};\n  if (progId) {\n    options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;\n    options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;\n  }\n  return options;\n};\n\n\n/**\n * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.\n * @type {string|undefined}\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.ieProgId_;\n\n\n/**\n * Initialize the private state used by other functions.\n * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {\n  if (goog.net.XmlHttp.ASSUME_NATIVE_XHR ||\n      goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) {\n    return '';\n  }\n\n  // The following blog post describes what PROG IDs to use to create the\n  // XMLHTTP object in Internet Explorer:\n  // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx\n  // However we do not (yet) fully trust that this will be OK for old versions\n  // of IE on Win9x so we therefore keep the last 2.\n  if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&\n      typeof ActiveXObject != 'undefined') {\n    // Candidate Active X types.\n    var ACTIVE_X_IDENTS = [\n      'MSXML2.XMLHTTP.6.0',\n      'MSXML2.XMLHTTP.3.0',\n      'MSXML2.XMLHTTP',\n      'Microsoft.XMLHTTP',\n    ];\n    for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {\n      var candidate = ACTIVE_X_IDENTS[i];\n\n      try {\n        new ActiveXObject(candidate);\n        // NOTE(user): cannot assign progid and return candidate in one line\n        // because JSCompiler complaings: BUG 658126\n        this.ieProgId_ = candidate;\n        return candidate;\n      } catch (e) {\n        // do nothing; try next choice\n      }\n    }\n\n    // couldn't find any matches\n    throw new Error(\n        'Could not create ActiveXObject. ActiveX might be disabled,' +\n        ' or MSXML might not be installed');\n  }\n\n  return /** @type {string} */ (this.ieProgId_);\n};\n\n\n// Set the global factory to an instance of the default factory.\ngoog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the ChannelRequest class. The request\n * object encapsulates the logic for making a single request, either for the\n * forward channel, back channel, or test channel, to the server. It contains\n * the logic for the two types of transports we use:\n * XMLHTTP and Image request. It provides timeout detection. More transports\n * to be added in future, such as Fetch, WebSocket.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.ChannelRequest');\n\ngoog.require('goog.Timer');\ngoog.require('goog.asserts');\ngoog.require('goog.async.Throttle');\ngoog.require('goog.events.EventHandler');\ngoog.require('goog.labs.net.webChannel.Channel');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\ngoog.require('goog.labs.net.webChannel.environment');\ngoog.require('goog.labs.net.webChannel.requestStats');\ngoog.require('goog.net.ErrorCode');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\ngoog.requireType('goog.labs.net.webChannel.Wire.QueuedMap');\ngoog.requireType('goog.net.XhrIo');\n\n\n\n/**\n * A new ChannelRequest is created for each request to the server.\n *\n * @param {goog.labs.net.webChannel.Channel} channel\n *     The channel that owns this request.\n * @param {goog.labs.net.webChannel.WebChannelDebug} channelDebug A\n *     WebChannelDebug to use for logging.\n * @param {string=} opt_sessionId The session id for the channel.\n * @param {string|number=} opt_requestId The request id for this request.\n * @param {number=} opt_retryId The retry id for this request.\n * @constructor\n * @struct\n * @final\n */\ngoog.labs.net.webChannel.ChannelRequest = function(\n    channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {\n  /**\n   * The channel object that owns the request.\n   * @private {goog.labs.net.webChannel.Channel}\n   */\n  this.channel_ = channel;\n\n  /**\n   * The channel debug to use for logging\n   * @private {goog.labs.net.webChannel.WebChannelDebug}\n   */\n  this.channelDebug_ = channelDebug;\n\n  /**\n   * The Session ID for the channel.\n   * @private {string|undefined}\n   */\n  this.sid_ = opt_sessionId;\n\n  /**\n   * The RID (request ID) for the request.\n   * @private {string|number|undefined}\n   */\n  this.rid_ = opt_requestId;\n\n  /**\n   * The attempt number of the current request.\n   * @private {number}\n   */\n  this.retryId_ = opt_retryId || 1;\n\n  /**\n   * An object to keep track of the channel request event listeners.\n   * @private {!goog.events.EventHandler<\n   *     !goog.labs.net.webChannel.ChannelRequest>}\n   */\n  this.eventHandler_ = new goog.events.EventHandler(this);\n\n  /**\n   * The timeout in ms before failing the request.\n   * @private {number}\n   */\n  this.timeout_ = goog.labs.net.webChannel.ChannelRequest.TIMEOUT_MS_;\n\n  /**\n   * A timer for polling responseText in browsers that don't fire\n   * onreadystatechange during incremental loading of responseText.\n   * @private {goog.Timer}\n   */\n  this.pollingTimer_ =\n      new goog.Timer(goog.labs.net.webChannel.environment.getPollingInterval());\n\n  /**\n   * Extra HTTP headers to add to all the requests sent to the server.\n   * @private {?Object}\n   */\n  this.extraHeaders_ = null;\n\n\n  /**\n   * Whether the request was successful. This is only set to true after the\n   * request successfully completes.\n   * @private {boolean}\n   */\n  this.successful_ = false;\n\n\n  /**\n   * The TimerID of the timer used to detect if the request has timed-out.\n   * @type {?number}\n   * @private\n   */\n  this.watchDogTimerId_ = null;\n\n  /**\n   * The time in the future when the request will timeout.\n   * @private {?number}\n   */\n  this.watchDogTimeoutTime_ = null;\n\n  /**\n   * The time the request started.\n   * @private {?number}\n   */\n  this.requestStartTime_ = null;\n\n  /**\n   * The type of request (XMLHTTP, IMG)\n   * @private {?number}\n   */\n  this.type_ = null;\n\n  /**\n   * The base Uri for the request. The includes all the parameters except the\n   * one that indicates the retry number.\n   * @private {?goog.Uri}\n   */\n  this.baseUri_ = null;\n\n  /**\n   * The request Uri that was actually used for the most recent request attempt.\n   * @private {?goog.Uri}\n   */\n  this.requestUri_ = null;\n\n  /**\n   * The post data, if the request is a post.\n   * @private {?string}\n   */\n  this.postData_ = null;\n\n  /**\n   * An array of pending messages that we have either received a non-successful\n   * response for, or no response at all, and which therefore may or may not\n   * have been received by the server.\n   * @private {!Array<goog.labs.net.webChannel.Wire.QueuedMap>}\n   */\n  this.pendingMessages_ = [];\n\n  /**\n   * The XhrLte request if the request is using XMLHTTP\n   * @private {?goog.net.XhrIo}\n   */\n  this.xmlHttp_ = null;\n\n  /**\n   * The position of where the next unprocessed chunk starts in the response\n   * text.\n   * @private {number}\n   */\n  this.xmlHttpChunkStart_ = 0;\n\n  /**\n   * The verb (Get or Post) for the request.\n   * @private {?string}\n   */\n  this.verb_ = null;\n\n  /**\n   * The last error if the request failed.\n   * @private {?goog.labs.net.webChannel.ChannelRequest.Error}\n   */\n  this.lastError_ = null;\n\n  /**\n   * The last status code received.\n   * @private {number}\n   */\n  this.lastStatusCode_ = -1;\n\n  /**\n   * Whether the request has been cancelled due to a call to cancel.\n   * @private {boolean}\n   */\n  this.cancelled_ = false;\n\n  /**\n   * A throttle time in ms for readystatechange events for the backchannel.\n   * Useful for throttling when ready state is INTERACTIVE (partial data).\n   * If set to zero no throttle is used.\n   *\n   * See WebChannelBase.prototype.readyStateChangeThrottleMs_\n   *\n   * @private {number}\n   */\n  this.readyStateChangeThrottleMs_ = 0;\n\n  /**\n   * The throttle for readystatechange events for the current request, or null\n   * if there is none.\n   * @private {?goog.async.Throttle}\n   */\n  this.readyStateChangeThrottle_ = null;\n\n  /**\n   * Whether to the result is expected to be encoded for chunking and thus\n   * requires decoding.\n   * @private {boolean}\n   */\n  this.decodeChunks_ = false;\n\n  /**\n   * Whether to decode x-http-initial-response.\n   * @private {boolean}\n   */\n  this.decodeInitialResponse_ = false;\n\n  /**\n   * Whether x-http-initial-response has been decoded (dispatched).\n   * @private {boolean}\n   */\n  this.initialResponseDecoded_ = false;\n\n  /**\n   * Whether the first byte of response body has arrived, for a successful\n   * response.\n   * @private {boolean}\n   */\n  this.firstByteReceived_ = false;\n};\n\n\ngoog.scope(function() {\nvar WebChannel = goog.net.WebChannel;\nvar Channel = goog.labs.net.webChannel.Channel;\nvar ChannelRequest = goog.labs.net.webChannel.ChannelRequest;\nvar requestStats = goog.labs.net.webChannel.requestStats;\nvar WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\nvar environment = goog.labs.net.webChannel.environment;\n\n\n/**\n * Default timeout in MS for a request. The server must return data within this\n * time limit for the request to not timeout.\n * @private {number}\n */\nChannelRequest.TIMEOUT_MS_ = 45 * 1000;\n\n\n/**\n * Enum for channel requests type\n * @enum {number}\n * @private\n */\nChannelRequest.Type_ = {\n  /**\n   * XMLHTTP requests.\n   */\n  XML_HTTP: 1,\n\n  /**\n   * IMG requests.\n   */\n  CLOSE_REQUEST: 2\n};\n\n\n/**\n * Enum type for identifying an error.\n * @enum {number}\n */\nChannelRequest.Error = {\n  /**\n   * Errors due to a non-200 status code.\n   */\n  STATUS: 0,\n\n  /**\n   * Errors due to no data being returned.\n   */\n  NO_DATA: 1,\n\n  /**\n   * Errors due to a timeout.\n   */\n  TIMEOUT: 2,\n\n  /**\n   * Errors due to the server returning an unknown.\n   */\n  UNKNOWN_SESSION_ID: 3,\n\n  /**\n   * Errors due to bad data being received.\n   */\n  BAD_DATA: 4,\n\n  /**\n   * Errors due to the handler throwing an exception.\n   */\n  HANDLER_EXCEPTION: 5,\n\n  /**\n   * The browser declared itself offline during the request.\n   */\n  BROWSER_OFFLINE: 6\n};\n\n\n/**\n * Returns a useful error string for debugging based on the specified error\n * code.\n * @param {?ChannelRequest.Error} errorCode The error code.\n * @param {number} statusCode The HTTP status code.\n * @return {string} The error string for the given code combination.\n */\nChannelRequest.errorStringFromCode = function(errorCode, statusCode) {\n  switch (errorCode) {\n    case ChannelRequest.Error.STATUS:\n      return 'Non-200 return code (' + statusCode + ')';\n    case ChannelRequest.Error.NO_DATA:\n      return 'XMLHTTP failure (no data)';\n    case ChannelRequest.Error.TIMEOUT:\n      return 'HttpConnection timeout';\n    default:\n      return 'Unknown error';\n  }\n};\n\n\n/**\n * Sentinel value used to indicate an invalid chunk in a multi-chunk response.\n * @private {Object}\n */\nChannelRequest.INVALID_CHUNK_ = {};\n\n\n/**\n * Sentinel value used to indicate an incomplete chunk in a multi-chunk\n * response.\n * @private {Object}\n */\nChannelRequest.INCOMPLETE_CHUNK_ = {};\n\n\n/**\n * Returns whether XHR streaming is supported on this browser.\n *\n * @return {boolean} Whether XHR streaming is supported.\n * @see http://code.google.com/p/closure-library/issues/detail?id=346\n */\nChannelRequest.supportsXhrStreaming = function() {\n  return !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(10);\n};\n\n\n/**\n * Sets extra HTTP headers to add to all the requests sent to the server.\n *\n * @param {Object} extraHeaders The HTTP headers.\n */\nChannelRequest.prototype.setExtraHeaders = function(extraHeaders) {\n  this.extraHeaders_ = extraHeaders;\n};\n\n\n/**\n * Overrides the default HTTP method.\n *\n * @param {string} verb The HTTP method\n */\nChannelRequest.prototype.setVerb = function(verb) {\n  this.verb_ = verb;\n};\n\n\n/**\n * Sets the timeout for a request\n *\n * @param {number} timeout   The timeout in MS for when we fail the request.\n */\nChannelRequest.prototype.setTimeout = function(timeout) {\n  this.timeout_ = timeout;\n};\n\n\n/**\n * Sets the throttle for handling onreadystatechange events for the request.\n *\n * @param {number} throttle The throttle in ms.  A value of zero indicates\n *     no throttle.\n */\nChannelRequest.prototype.setReadyStateChangeThrottle = function(throttle) {\n  this.readyStateChangeThrottleMs_ = throttle;\n};\n\n\n/**\n * Sets the pending messages that this request is handling.\n *\n * @param {!Array<goog.labs.net.webChannel.Wire.QueuedMap>} pendingMessages\n *     The pending messages for this request.\n */\nChannelRequest.prototype.setPendingMessages = function(pendingMessages) {\n  this.pendingMessages_ = pendingMessages;\n};\n\n\n/**\n * Gets the pending messages that this request is handling, in case of a retry.\n *\n * @return {!Array<goog.labs.net.webChannel.Wire.QueuedMap>} The pending\n *     messages for this request.\n */\nChannelRequest.prototype.getPendingMessages = function() {\n  return this.pendingMessages_;\n};\n\n\n/**\n * Uses XMLHTTP to send an HTTP POST to the server.\n *\n * @param {goog.Uri} uri  The uri of the request.\n * @param {?string} postData  The data for the post body.\n * @param {boolean} decodeChunks  Whether to the result is expected to be\n *     encoded for chunking and thus requires decoding.\n */\nChannelRequest.prototype.xmlHttpPost = function(uri, postData, decodeChunks) {\n  this.type_ = ChannelRequest.Type_.XML_HTTP;\n  this.baseUri_ = uri.clone().makeUnique();\n  this.postData_ = postData;\n  this.decodeChunks_ = decodeChunks;\n  this.sendXmlHttp_(null /* hostPrefix */);\n};\n\n\n/**\n * Uses XMLHTTP to send an HTTP GET to the server.\n *\n * @param {goog.Uri} uri  The uri of the request.\n * @param {boolean} decodeChunks  Whether to the result is expected to be\n *     encoded for chunking and thus requires decoding.\n * @param {?string} hostPrefix  The host prefix, if we might be using a\n *     secondary domain.  Note that it should also be in the URL, adding this\n *     won't cause it to be added to the URL.\n */\nChannelRequest.prototype.xmlHttpGet = function(uri, decodeChunks, hostPrefix) {\n  this.type_ = ChannelRequest.Type_.XML_HTTP;\n  this.baseUri_ = uri.clone().makeUnique();\n  this.postData_ = null;\n  this.decodeChunks_ = decodeChunks;\n\n  this.sendXmlHttp_(hostPrefix);\n};\n\n\n/**\n * Sends a request via XMLHTTP according to the current state of the request\n * object.\n *\n * @param {?string} hostPrefix The host prefix, if we might be using a secondary\n *     domain.\n * @private\n */\nChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {\n  this.requestStartTime_ = goog.now();\n  this.ensureWatchDogTimer_();\n\n  // clone the base URI to create the request URI. The request uri has the\n  // attempt number as a parameter which helps in debugging.\n  this.requestUri_ = this.baseUri_.clone();\n  this.requestUri_.setParameterValues('t', this.retryId_);\n\n  // send the request either as a POST or GET\n  this.xmlHttpChunkStart_ = 0;\n  var useSecondaryDomains = this.channel_.shouldUseSecondaryDomains();\n  this.xmlHttp_ =\n      this.channel_.createXhrIo(useSecondaryDomains ? hostPrefix : null);\n\n  if (this.readyStateChangeThrottleMs_ > 0) {\n    this.readyStateChangeThrottle_ = new goog.async.Throttle(\n        goog.bind(this.xmlHttpHandler_, this, this.xmlHttp_),\n        this.readyStateChangeThrottleMs_);\n  }\n\n  this.eventHandler_.listen(\n      this.xmlHttp_, goog.net.EventType.READY_STATE_CHANGE,\n      this.readyStateChangeHandler_);\n\n  var headers = this.extraHeaders_ ? goog.object.clone(this.extraHeaders_) : {};\n  if (this.postData_) {\n    if (!this.verb_) {\n      this.verb_ = 'POST';\n    }\n    headers['Content-Type'] = 'application/x-www-form-urlencoded';\n    this.xmlHttp_.send(this.requestUri_, this.verb_, this.postData_, headers);\n  } else {\n    this.verb_ = 'GET';\n    this.xmlHttp_.send(this.requestUri_, this.verb_, null, headers);\n  }\n  requestStats.notifyServerReachabilityEvent(\n      requestStats.ServerReachability.REQUEST_MADE);\n  this.channelDebug_.xmlHttpChannelRequest(\n      this.verb_, this.requestUri_, this.rid_, this.retryId_, this.postData_);\n};\n\n\n/**\n * Handles a readystatechange event.\n * @param {goog.events.Event} evt The event.\n * @private\n */\nChannelRequest.prototype.readyStateChangeHandler_ = function(evt) {\n  var xhr = /** @type {goog.net.XhrIo} */ (evt.target);\n  var throttle = this.readyStateChangeThrottle_;\n  if (throttle &&\n      xhr.getReadyState() == goog.net.XmlHttp.ReadyState.INTERACTIVE) {\n    // Only throttle in the partial data case.\n    this.channelDebug_.debug('Throttling readystatechange.');\n    throttle.fire();\n  } else {\n    // If we haven't throttled, just handle response directly.\n    this.xmlHttpHandler_(xhr);\n  }\n};\n\n\n/**\n * XmlHttp handler\n * @param {goog.net.XhrIo} xmlhttp The XhrIo object for the current request.\n * @private\n */\nChannelRequest.prototype.xmlHttpHandler_ = function(xmlhttp) {\n  requestStats.onStartExecution();\n\n  try {\n    if (xmlhttp == this.xmlHttp_) {\n      this.onXmlHttpReadyStateChanged_();\n    } else {\n      this.channelDebug_.warning(\n          'Called back with an ' +\n          'unexpected xmlhttp');\n    }\n  } catch (ex) {\n    this.channelDebug_.debug('Failed call to OnXmlHttpReadyStateChanged_');\n    if (this.xmlHttp_ && this.xmlHttp_.getResponseText()) {\n      var channelRequest = this;\n      this.channelDebug_.dumpException(ex, function() {\n        return 'ResponseText: ' + channelRequest.xmlHttp_.getResponseText();\n      });\n    } else {\n      this.channelDebug_.dumpException(ex, 'No response text');\n    }\n  } finally {\n    requestStats.onEndExecution();\n  }\n};\n\n\n/**\n * Called by the readystate handler for XMLHTTP requests.\n *\n * @private\n */\nChannelRequest.prototype.onXmlHttpReadyStateChanged_ = function() {\n  var readyState = this.xmlHttp_.getReadyState();\n  var errorCode = this.xmlHttp_.getLastErrorCode();\n  var statusCode = this.xmlHttp_.getStatus();\n\n  // we get partial results in browsers that support ready state interactive.\n  // We also make sure that getResponseText is not null in interactive mode\n  // before we continue.\n  if (readyState < goog.net.XmlHttp.ReadyState.INTERACTIVE ||\n      (readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE &&\n       !environment.isPollingRequired() &&  // otherwise, go on to startPolling\n       !this.xmlHttp_.getResponseText())) {\n    return;  // not yet ready\n  }\n\n  // Dispatch any appropriate network events.\n  if (!this.cancelled_ && readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&\n      errorCode != goog.net.ErrorCode.ABORT) {\n    // Pretty conservative, these are the only known scenarios which we'd\n    // consider indicative of a truly non-functional network connection.\n    if (errorCode == goog.net.ErrorCode.TIMEOUT || statusCode <= 0) {\n      requestStats.notifyServerReachabilityEvent(\n          requestStats.ServerReachability.REQUEST_FAILED);\n    } else {\n      requestStats.notifyServerReachabilityEvent(\n          requestStats.ServerReachability.REQUEST_SUCCEEDED);\n    }\n  }\n\n  // got some data so cancel the watchdog timer\n  this.cancelWatchDogTimer_();\n\n  var status = this.xmlHttp_.getStatus();\n  this.lastStatusCode_ = status;\n  var responseText = this.xmlHttp_.getResponseText();\n  if (!responseText) {\n    var channelRequest = this;\n    this.channelDebug_.debug(function() {\n      return 'No response text for uri ' + channelRequest.requestUri_ +\n          ' status ' + status;\n    });\n  }\n  this.successful_ = (status == 200);\n\n  this.channelDebug_.xmlHttpChannelResponseMetaData(\n      /** @type {string} */ (this.verb_), this.requestUri_, this.rid_,\n      this.retryId_, readyState, status);\n\n  if (!this.successful_) {\n    if (status == 400 && responseText.indexOf('Unknown SID') > 0) {\n      // the server error string will include 'Unknown SID' which indicates the\n      // server doesn't know about the session (maybe it got restarted, maybe\n      // the user got moved to another server, etc.,). Handlers can special\n      // case this error\n      this.lastError_ = ChannelRequest.Error.UNKNOWN_SESSION_ID;\n      requestStats.notifyStatEvent(\n          requestStats.Stat.REQUEST_UNKNOWN_SESSION_ID);\n      this.channelDebug_.warning('XMLHTTP Unknown SID (' + this.rid_ + ')');\n    } else {\n      this.lastError_ = ChannelRequest.Error.STATUS;\n      requestStats.notifyStatEvent(requestStats.Stat.REQUEST_BAD_STATUS);\n      this.channelDebug_.warning(\n          'XMLHTTP Bad status ' + status + ' (' + this.rid_ + ')');\n    }\n    this.cleanup_();\n    this.dispatchFailure_();\n    return;\n  }\n\n  if (this.shouldCheckInitialResponse_()) {\n    var initialResponse = this.getInitialResponse_();\n    if (initialResponse) {\n      this.channelDebug_.xmlHttpChannelResponseText(\n          this.rid_, initialResponse,\n          'Initial handshake response via ' +\n              WebChannel.X_HTTP_INITIAL_RESPONSE);\n      this.initialResponseDecoded_ = true;\n      this.safeOnRequestData_(initialResponse);\n    } else {\n      this.successful_ = false;\n      this.lastError_ = ChannelRequest.Error.UNKNOWN_SESSION_ID;  // fail-fast\n      requestStats.notifyStatEvent(\n          requestStats.Stat.REQUEST_UNKNOWN_SESSION_ID);\n      this.channelDebug_.warning(\n          'XMLHTTP Missing X_HTTP_INITIAL_RESPONSE' +\n          ' (' + this.rid_ + ')');\n      this.cleanup_();\n      this.dispatchFailure_();\n      return;\n    }\n  }\n\n  if (this.decodeChunks_) {\n    this.decodeNextChunks_(readyState, responseText);\n    if (environment.isPollingRequired() && this.successful_ &&\n        readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE) {\n      this.startPolling_();\n    }\n  } else {\n    this.channelDebug_.xmlHttpChannelResponseText(\n        this.rid_, responseText, null);\n    this.safeOnRequestData_(responseText);\n  }\n\n  if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n    this.cleanup_();\n  }\n\n  if (!this.successful_) {\n    return;\n  }\n\n  if (!this.cancelled_) {\n    if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n      this.channel_.onRequestComplete(this);\n    } else {\n      // The default is false, the result from this callback shouldn't carry\n      // over to the next callback, otherwise the request looks successful if\n      // the watchdog timer gets called\n      this.successful_ = false;\n      this.ensureWatchDogTimer_();\n    }\n  }\n};\n\n\n/**\n * Whether we need check the initial-response header that is sent during the\n * fast handshake.\n *\n * @return {boolean} true if the initial-response header is yet to be processed.\n * @private\n */\nChannelRequest.prototype.shouldCheckInitialResponse_ = function() {\n  return this.decodeInitialResponse_ && !this.initialResponseDecoded_;\n};\n\n\n/**\n * Queries the initial response header that is sent during the handshake.\n *\n * @return {?string} The non-empty header value or null.\n * @private\n */\nChannelRequest.prototype.getInitialResponse_ = function() {\n  if (this.xmlHttp_) {\n    var value = this.xmlHttp_.getStreamingResponseHeader(\n        WebChannel.X_HTTP_INITIAL_RESPONSE);\n    if (value && !goog.string.isEmptyOrWhitespace(value)) {\n      return value;\n    }\n  }\n\n  return null;\n};\n\n\n/**\n * Check if the initial response header has been handled.\n *\n * @return {boolean} true if X_HTTP_INITIAL_RESPONSE has been handled.\n */\nChannelRequest.prototype.isInitialResponseDecoded = function() {\n  return this.initialResponseDecoded_;\n};\n\n\n/**\n * Decodes X_HTTP_INITIAL_RESPONSE if present.\n */\nChannelRequest.prototype.setDecodeInitialResponse = function() {\n  this.decodeInitialResponse_ = true;\n};\n\n\n/**\n * Decodes the next set of available chunks in the response.\n * @param {number} readyState The value of readyState.\n * @param {string} responseText The value of responseText.\n * @private\n */\nChannelRequest.prototype.decodeNextChunks_ = function(\n    readyState, responseText) {\n  var decodeNextChunksSuccessful = true;\n\n  while (!this.cancelled_ && this.xmlHttpChunkStart_ < responseText.length) {\n    var chunkText = this.getNextChunk_(responseText);\n    if (chunkText == ChannelRequest.INCOMPLETE_CHUNK_) {\n      if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n        // should have consumed entire response when the request is done\n        this.lastError_ = ChannelRequest.Error.BAD_DATA;\n        requestStats.notifyStatEvent(requestStats.Stat.REQUEST_INCOMPLETE_DATA);\n        decodeNextChunksSuccessful = false;\n      }\n      this.channelDebug_.xmlHttpChannelResponseText(\n          this.rid_, null, '[Incomplete Response]');\n      break;\n    } else if (chunkText == ChannelRequest.INVALID_CHUNK_) {\n      this.lastError_ = ChannelRequest.Error.BAD_DATA;\n      requestStats.notifyStatEvent(requestStats.Stat.REQUEST_BAD_DATA);\n      this.channelDebug_.xmlHttpChannelResponseText(\n          this.rid_, responseText, '[Invalid Chunk]');\n      decodeNextChunksSuccessful = false;\n      break;\n    } else {\n      this.channelDebug_.xmlHttpChannelResponseText(\n          this.rid_, /** @type {string} */ (chunkText), null);\n      this.safeOnRequestData_(/** @type {string} */ (chunkText));\n    }\n  }\n\n  if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&\n      responseText.length == 0) {\n    // also an error if we didn't get any response\n    this.lastError_ = ChannelRequest.Error.NO_DATA;\n    requestStats.notifyStatEvent(requestStats.Stat.REQUEST_NO_DATA);\n    decodeNextChunksSuccessful = false;\n  }\n\n  this.successful_ = this.successful_ && decodeNextChunksSuccessful;\n\n  if (!decodeNextChunksSuccessful) {\n    // malformed response - we make this trigger retry logic\n    this.channelDebug_.xmlHttpChannelResponseText(\n        this.rid_, responseText, '[Invalid Chunked Response]');\n    this.cleanup_();\n    this.dispatchFailure_();\n  } else {\n    if (responseText.length > 0 && !this.firstByteReceived_) {\n      this.firstByteReceived_ = true;\n      this.channel_.onFirstByteReceived(this, responseText);\n    }\n  }\n};\n\n\n/**\n * Polls the response for new data.\n * @private\n */\nChannelRequest.prototype.pollResponse_ = function() {\n  if (!this.xmlHttp_) {\n    return;  // already closed\n  }\n  var readyState = this.xmlHttp_.getReadyState();\n  var responseText = this.xmlHttp_.getResponseText();\n  if (this.xmlHttpChunkStart_ < responseText.length) {\n    this.cancelWatchDogTimer_();\n    this.decodeNextChunks_(readyState, responseText);\n    if (this.successful_ &&\n        readyState != goog.net.XmlHttp.ReadyState.COMPLETE) {\n      this.ensureWatchDogTimer_();\n    }\n  }\n};\n\n\n/**\n * Starts a polling interval for changes to responseText of the\n * XMLHttpRequest, for browsers that don't fire onreadystatechange\n * as data comes in incrementally.  This timer is disabled in\n * cleanup_().\n * @private\n */\nChannelRequest.prototype.startPolling_ = function() {\n  this.eventHandler_.listen(\n      this.pollingTimer_, goog.Timer.TICK, this.pollResponse_);\n  this.pollingTimer_.start();\n};\n\n\n/**\n * Returns the next chunk of a chunk-encoded response. This is not standard\n * HTTP chunked encoding because browsers don't expose the chunk boundaries to\n * the application through XMLHTTP. So we have an additional chunk encoding at\n * the application level that lets us tell where the beginning and end of\n * individual responses are so that we can only try to eval a complete JS array.\n *\n * The encoding is the size of the chunk encoded as a decimal string followed\n * by a newline followed by the data.\n *\n * @param {string} responseText The response text from the XMLHTTP response.\n * @return {string|Object} The next chunk string or a sentinel object\n *                         indicating a special condition.\n * @private\n */\nChannelRequest.prototype.getNextChunk_ = function(responseText) {\n  var sizeStartIndex = this.xmlHttpChunkStart_;\n  var sizeEndIndex = responseText.indexOf('\\n', sizeStartIndex);\n  if (sizeEndIndex == -1) {\n    return ChannelRequest.INCOMPLETE_CHUNK_;\n  }\n\n  var sizeAsString = responseText.substring(sizeStartIndex, sizeEndIndex);\n  var size = Number(sizeAsString);\n  if (isNaN(size)) {\n    return ChannelRequest.INVALID_CHUNK_;\n  }\n\n  var chunkStartIndex = sizeEndIndex + 1;\n  if (chunkStartIndex + size > responseText.length) {\n    return ChannelRequest.INCOMPLETE_CHUNK_;\n  }\n\n  var chunkText = responseText.substr(chunkStartIndex, size);\n  this.xmlHttpChunkStart_ = chunkStartIndex + size;\n  return chunkText;\n};\n\n\n/**\n * Uses an IMG tag or navigator.sendBeacon to send an HTTP get to the server.\n *\n * This is only currently used to terminate the connection, as an IMG tag is\n * the most reliable way to send something to the server while the page\n * is getting torn down.\n *\n * Navigator.sendBeacon is available on Chrome and Firefox as a formal\n * solution to ensure delivery without blocking window close. See\n * https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon\n *\n * For Chrome Apps, sendBeacon is always necessary due to Content Security\n * Policy (CSP) violation of using an IMG tag.\n *\n * For react-native, we use xhr to send the actual close request, and assume\n * there is no page-close issue with react-native.\n *\n * @param {goog.Uri} uri The uri to send a request to.\n */\nChannelRequest.prototype.sendCloseRequest = function(uri) {\n  this.type_ = ChannelRequest.Type_.CLOSE_REQUEST;\n  this.baseUri_ = uri.clone().makeUnique();\n\n  var requestSent = false;\n\n  if (goog.global.navigator && goog.global.navigator.sendBeacon) {\n    // empty string body to avoid 413 error on chrome < 41\n    requestSent =\n        goog.global.navigator.sendBeacon(this.baseUri_.toString(), '');\n  }\n\n  if (!requestSent && goog.global.Image) {\n    var eltImg = new Image();\n    eltImg.src = this.baseUri_;\n    requestSent = true;\n  }\n\n  if (!requestSent) {\n    // no handler is set to match the sendBeacon/Image behavior\n    this.xmlHttp_ = this.channel_.createXhrIo(null);\n    this.xmlHttp_.send(this.baseUri_);\n  }\n\n  this.requestStartTime_ = goog.now();\n  this.ensureWatchDogTimer_();\n};\n\n\n/**\n * Cancels the request no matter what the underlying transport is.\n */\nChannelRequest.prototype.cancel = function() {\n  this.cancelled_ = true;\n  this.cleanup_();\n};\n\n\n/**\n * Resets the timeout.\n *\n * @param {number=} opt_timeout The new timeout\n */\nChannelRequest.prototype.resetTimeout = function(opt_timeout) {\n  if (opt_timeout) {\n    this.setTimeout(opt_timeout);\n  }\n  // restart only if a timer is currently set\n  if (this.watchDogTimerId_) {\n    this.cancelWatchDogTimer_();\n    this.ensureWatchDogTimer_();\n  }\n};\n\n\n/**\n * Ensures that there is watchdog timeout which is used to ensure that\n * the connection completes in time.\n *\n * @private\n */\nChannelRequest.prototype.ensureWatchDogTimer_ = function() {\n  this.watchDogTimeoutTime_ = goog.now() + this.timeout_;\n  this.startWatchDogTimer_(this.timeout_);\n};\n\n\n/**\n * Starts the watchdog timer which is used to ensure that the connection\n * completes in time.\n * @param {number} time The number of milliseconds to wait.\n * @private\n */\nChannelRequest.prototype.startWatchDogTimer_ = function(time) {\n  if (this.watchDogTimerId_ != null) {\n    // assertion\n    throw new Error('WatchDog timer not null');\n  }\n  this.watchDogTimerId_ =\n      requestStats.setTimeout(goog.bind(this.onWatchDogTimeout_, this), time);\n};\n\n\n/**\n * Cancels the watchdog timer if it has been started.\n *\n * @private\n */\nChannelRequest.prototype.cancelWatchDogTimer_ = function() {\n  if (this.watchDogTimerId_) {\n    goog.global.clearTimeout(this.watchDogTimerId_);\n    this.watchDogTimerId_ = null;\n  }\n};\n\n\n/**\n * Called when the watchdog timer is triggered. It also handles a case where it\n * is called too early which we suspect may be happening sometimes\n * (not sure why)\n *\n * @private\n */\nChannelRequest.prototype.onWatchDogTimeout_ = function() {\n  this.watchDogTimerId_ = null;\n  var now = goog.now();\n  goog.asserts.assert(\n      this.watchDogTimeoutTime_, 'WatchDog timeout time missing?');\n  if (now - this.watchDogTimeoutTime_ >= 0) {\n    this.handleTimeout_();\n  } else {\n    // got called too early for some reason\n    this.channelDebug_.warning('WatchDog timer called too early');\n    this.startWatchDogTimer_(this.watchDogTimeoutTime_ - now);\n  }\n};\n\n\n/**\n * Called when the request has actually timed out. Will cleanup and notify the\n * channel of the failure.\n *\n * @private\n */\nChannelRequest.prototype.handleTimeout_ = function() {\n  if (this.successful_) {\n    // Should never happen.\n    this.channelDebug_.severe(\n        'Received watchdog timeout even though request loaded successfully');\n  }\n\n  this.channelDebug_.timeoutResponse(this.requestUri_);\n\n  // IMG or SendBeacon requests never notice if they were successful,\n  // and always 'time out'. This fact says nothing about reachability.\n  if (this.type_ != ChannelRequest.Type_.CLOSE_REQUEST) {\n    requestStats.notifyServerReachabilityEvent(\n        requestStats.ServerReachability.REQUEST_FAILED);\n    requestStats.notifyStatEvent(requestStats.Stat.REQUEST_TIMEOUT);\n  }\n\n  this.cleanup_();\n\n  // Set error and dispatch failure.\n  // This is called for CLOSE_REQUEST too to ensure channel_.onRequestComplete.\n  this.lastError_ = ChannelRequest.Error.TIMEOUT;\n  this.dispatchFailure_();\n};\n\n\n/**\n * Notifies the channel that this request failed.\n * @private\n */\nChannelRequest.prototype.dispatchFailure_ = function() {\n  if (this.channel_.isClosed() || this.cancelled_) {\n    return;\n  }\n\n  this.channel_.onRequestComplete(this);\n};\n\n\n/**\n * Cleans up the objects used to make the request. This function is\n * idempotent.\n *\n * @private\n */\nChannelRequest.prototype.cleanup_ = function() {\n  this.cancelWatchDogTimer_();\n\n  goog.dispose(this.readyStateChangeThrottle_);\n  this.readyStateChangeThrottle_ = null;\n\n  // Stop the polling timer, if necessary.\n  this.pollingTimer_.stop();\n\n  // Unhook all event handlers.\n  this.eventHandler_.removeAll();\n\n  if (this.xmlHttp_) {\n    // clear out this.xmlHttp_ before aborting so we handle getting reentered\n    // inside abort\n    var xmlhttp = this.xmlHttp_;\n    this.xmlHttp_ = null;\n    xmlhttp.abort();\n    xmlhttp.dispose();\n  }\n};\n\n\n/**\n * Indicates whether the request was successful. Only valid after the handler\n * is called to indicate completion of the request.\n *\n * @return {boolean} True if the request succeeded.\n */\nChannelRequest.prototype.getSuccess = function() {\n  return this.successful_;\n};\n\n\n/**\n * If the request was not successful, returns the reason.\n *\n * @return {?ChannelRequest.Error}  The last error.\n */\nChannelRequest.prototype.getLastError = function() {\n  return this.lastError_;\n};\n\n\n/**\n * Returns the status code of the last request.\n * @return {number} The status code of the last request.\n */\nChannelRequest.prototype.getLastStatusCode = function() {\n  return this.lastStatusCode_;\n};\n\n\n/**\n * Returns the session id for this channel.\n *\n * @return {string|undefined} The session ID.\n */\nChannelRequest.prototype.getSessionId = function() {\n  return this.sid_;\n};\n\n\n/**\n * Returns the request id for this request. Each request has a unique request\n * id and the request IDs are a sequential increasing count.\n *\n * @return {string|number|undefined} The request ID.\n */\nChannelRequest.prototype.getRequestId = function() {\n  return this.rid_;\n};\n\n\n/**\n * Returns the data for a post, if this request is a post.\n *\n * @return {?string} The POST data provided by the request initiator.\n */\nChannelRequest.prototype.getPostData = function() {\n  return this.postData_;\n};\n\n\n/**\n * Returns the XhrIo request object.\n *\n * @return {?goog.net.XhrIo} Any XhrIo request created for this object.\n */\nChannelRequest.prototype.getXhr = function() {\n  return this.xmlHttp_;\n};\n\n\n/**\n * Returns the time that the request started, if it has started.\n *\n * @return {?number} The time the request started, as returned by goog.now().\n */\nChannelRequest.prototype.getRequestStartTime = function() {\n  return this.requestStartTime_;\n};\n\n\n/**\n * Helper to call the callback's onRequestData, which catches any\n * exception.\n * @param {string} data The request data.\n * @private\n */\nChannelRequest.prototype.safeOnRequestData_ = function(data) {\n  try {\n    this.channel_.onRequestData(this, data);\n    var stats = requestStats.ServerReachability;\n    requestStats.notifyServerReachabilityEvent(stats.BACK_CHANNEL_ACTIVITY);\n  } catch (e) {\n    // Dump debug info, but keep going without closing the channel.\n    this.channelDebug_.dumpException(e, 'Error in httprequest callback');\n  }\n};\n\n\n/**\n * Convenience factory method.\n *\n * @param {Channel} channel The channel object that owns this request.\n * @param {WebChannelDebug} channelDebug A WebChannelDebug to use for logging.\n * @param {string=} opt_sessionId  The session id for the channel.\n * @param {string|number=} opt_requestId  The request id for this request.\n * @param {number=} opt_retryId  The retry id for this request.\n * @return {!ChannelRequest} The created channel request.\n */\nChannelRequest.createChannelRequest = function(\n    channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {\n  return new ChannelRequest(\n      channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId);\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrapper class for handling XmlHttpRequests.\n *\n * One off requests can be sent through goog.net.XhrIo.send() or an\n * instance can be created to send multiple requests.  Each request uses its\n * own XmlHttpRequest object and handles clearing of the event callback to\n * ensure no leaks.\n *\n * XhrIo is event based, it dispatches events on success, failure, finishing,\n * ready-state change, or progress (download and upload).\n *\n * The ready-state or timeout event fires first, followed by\n * a generic completed event. Then the abort, error, or success event\n * is fired as appropriate. Progress events are fired as they are\n * received. Lastly, the ready event will fire to indicate that the\n * object may be used to make another request.\n *\n * The error event may also be called before completed and\n * ready-state-change if the XmlHttpRequest.open() or .send() methods throw.\n *\n * This class does not support multiple requests, queuing, or prioritization.\n *\n * When progress events are supported by the browser, and progress is\n * enabled via .setProgressEventsEnabled(true), the\n * goog.net.EventType.PROGRESS event will be the re-dispatched browser\n * progress event. Additionally, a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event\n * will be fired for download and upload progress respectively.\n */\n\n\ngoog.provide('goog.net.XhrIo');\ngoog.provide('goog.net.XhrIo.ResponseType');\n\ngoog.require('goog.Timer');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.json.hybrid');\ngoog.require('goog.log');\ngoog.require('goog.net.ErrorCode');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.HttpStatus');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.structs.Map');\ngoog.require('goog.uri.utils');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\n\ngoog.scope(function() {\n\n/**\n * Basic class for handling XMLHttpRequests.\n * @param {goog.net.XmlHttpFactory=} opt_xmlHttpFactory Factory to use when\n *     creating XMLHttpRequest objects.\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.net.XhrIo = function(opt_xmlHttpFactory) {\n  XhrIo.base(this, 'constructor');\n\n  /**\n   * Map of default headers to add to every request, use:\n   * XhrIo.headers.set(name, value)\n   * @type {!goog.structs.Map}\n   */\n  this.headers = new goog.structs.Map();\n\n  /**\n   * Optional XmlHttpFactory\n   * @private {goog.net.XmlHttpFactory}\n   */\n  this.xmlHttpFactory_ = opt_xmlHttpFactory || null;\n\n  /**\n   * Whether XMLHttpRequest is active.  A request is active from the time send()\n   * is called until onReadyStateChange() is complete, or error() or abort()\n   * is called.\n   * @private {boolean}\n   */\n  this.active_ = false;\n\n  /**\n   * The XMLHttpRequest object that is being used for the transfer.\n   * @private {?goog.net.XhrLike.OrNative}\n   */\n  this.xhr_ = null;\n\n  /**\n   * The options to use with the current XMLHttpRequest object.\n   * @private {?Object}\n   */\n  this.xhrOptions_ = null;\n\n  /**\n   * Last URL that was requested.\n   * @private {string|goog.Uri}\n   */\n  this.lastUri_ = '';\n\n  /**\n   * Method for the last request.\n   * @private {string}\n   */\n  this.lastMethod_ = '';\n\n  /**\n   * Last error code.\n   * @private {!goog.net.ErrorCode}\n   */\n  this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n\n  /**\n   * Last error message.\n   * @private {Error|string}\n   */\n  this.lastError_ = '';\n\n  /**\n   * Used to ensure that we don't dispatch an multiple ERROR events. This can\n   * happen in IE when it does a synchronous load and one error is handled in\n   * the ready state change and one is handled due to send() throwing an\n   * exception.\n   * @private {boolean}\n   */\n  this.errorDispatched_ = false;\n\n  /**\n   * Used to make sure we don't fire the complete event from inside a send call.\n   * @private {boolean}\n   */\n  this.inSend_ = false;\n\n  /**\n   * Used in determining if a call to {@link #onReadyStateChange_} is from\n   * within a call to this.xhr_.open.\n   * @private {boolean}\n   */\n  this.inOpen_ = false;\n\n  /**\n   * Used in determining if a call to {@link #onReadyStateChange_} is from\n   * within a call to this.xhr_.abort.\n   * @private {boolean}\n   */\n  this.inAbort_ = false;\n\n  /**\n   * Number of milliseconds after which an incomplete request will be aborted\n   * and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout\n   * is set.\n   * @private {number}\n   */\n  this.timeoutInterval_ = 0;\n\n  /**\n   * Timer to track request timeout.\n   * @private {?number}\n   */\n  this.timeoutId_ = null;\n\n  /**\n   * The requested type for the response. The empty string means use the default\n   * XHR behavior.\n   * @private {goog.net.XhrIo.ResponseType}\n   */\n  this.responseType_ = ResponseType.DEFAULT;\n\n  /**\n   * Whether a \"credentialed\" request is to be sent (one that is aware of\n   * cookies and authentication). This is applicable only for cross-domain\n   * requests and more recent browsers that support this part of the HTTP Access\n   * Control standard.\n   *\n   * @see http://www.w3.org/TR/XMLHttpRequest/#the-withcredentials-attribute\n   *\n   * @private {boolean}\n   */\n  this.withCredentials_ = false;\n\n  /**\n   * Whether progress events are enabled for this request. This is\n   * disabled by default because setting a progress event handler\n   * causes pre-flight OPTIONS requests to be sent for CORS requests,\n   * even in cases where a pre-flight request would not otherwise be\n   * sent.\n   *\n   * @see http://xhr.spec.whatwg.org/#security-considerations\n   *\n   * Note that this can cause problems for Firefox 22 and below, as an\n   * older \"LSProgressEvent\" will be dispatched by the browser. That\n   * progress event is no longer supported, and can lead to failures,\n   * including throwing exceptions.\n   *\n   * @see http://bugzilla.mozilla.org/show_bug.cgi?id=845631\n   * @see b/23469793\n   *\n   * @private {boolean}\n   */\n  this.progressEventsEnabled_ = false;\n\n  /**\n   * True if we can use XMLHttpRequest's timeout directly.\n   * @private {boolean}\n   */\n  this.useXhr2Timeout_ = false;\n};\ngoog.inherits(goog.net.XhrIo, goog.events.EventTarget);\n\nvar XhrIo = goog.net.XhrIo;\n\n/**\n * Response types that may be requested for XMLHttpRequests.\n * @enum {string}\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute\n */\ngoog.net.XhrIo.ResponseType = {\n  DEFAULT: '',\n  TEXT: 'text',\n  DOCUMENT: 'document',\n  // Not supported as of Chrome 10.0.612.1 dev\n  BLOB: 'blob',\n  ARRAY_BUFFER: 'arraybuffer',\n};\n\nvar ResponseType = goog.net.XhrIo.ResponseType;\n\n\n/**\n * A reference to the XhrIo logger\n * @private {?goog.log.Logger}\n * @const\n */\ngoog.net.XhrIo.prototype.logger_ = goog.log.getLogger('goog.net.XhrIo');\n\n\n/**\n * The Content-Type HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TYPE_HEADER = 'Content-Type';\n\n\n/**\n * The Content-Transfer-Encoding HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding';\n\n\n/**\n * The pattern matching the 'http' and 'https' URI schemes\n * @type {!RegExp}\n */\ngoog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i;\n\n\n/**\n * The methods that typically come along with form data.  We set different\n * headers depending on whether the HTTP action is one of these.\n * @type {!Array<string>}\n */\ngoog.net.XhrIo.METHODS_WITH_FORM_DATA = ['POST', 'PUT'];\n\n\n/**\n * The Content-Type HTTP header value for a url-encoded form\n * @type {string}\n */\ngoog.net.XhrIo.FORM_CONTENT_TYPE =\n    'application/x-www-form-urlencoded;charset=utf-8';\n\n\n/**\n * The XMLHttpRequest Level two timeout delay ms property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_TIMEOUT_ = 'timeout';\n\n\n/**\n * The XMLHttpRequest Level two ontimeout handler property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_ON_TIMEOUT_ = 'ontimeout';\n\n\n/**\n * All non-disposed instances of goog.net.XhrIo created\n * by {@link goog.net.XhrIo.send} are in this Array.\n * @see goog.net.XhrIo.cleanup\n * @private {!Array<!goog.net.XhrIo>}\n */\ngoog.net.XhrIo.sendInstances_ = [];\n\n\n/**\n * Static send that creates a short lived instance of XhrIo to send the\n * request.\n * @see goog.net.XhrIo.cleanup\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {?function(this:goog.net.XhrIo, ?)=} opt_callback Callback function\n *     for when request is complete.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n *     opt_content Body data.\n * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the\n *     request.\n * @param {number=} opt_timeoutInterval Number of milliseconds after which an\n *     incomplete request will be aborted; 0 means no timeout is set.\n * @param {boolean=} opt_withCredentials Whether to send credentials with the\n *     request. Default to false. See {@link goog.net.XhrIo#setWithCredentials}.\n * @return {!goog.net.XhrIo} The sent XhrIo.\n */\ngoog.net.XhrIo.send = function(\n    url, opt_callback, opt_method, opt_content, opt_headers,\n    opt_timeoutInterval, opt_withCredentials) {\n  var x = new goog.net.XhrIo();\n  goog.net.XhrIo.sendInstances_.push(x);\n  if (opt_callback) {\n    x.listen(goog.net.EventType.COMPLETE, opt_callback);\n  }\n  x.listenOnce(goog.net.EventType.READY, x.cleanupSend_);\n  if (opt_timeoutInterval) {\n    x.setTimeoutInterval(opt_timeoutInterval);\n  }\n  if (opt_withCredentials) {\n    x.setWithCredentials(opt_withCredentials);\n  }\n  x.send(url, opt_method, opt_content, opt_headers);\n  return x;\n};\n\n\n/**\n * Disposes all non-disposed instances of goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send}.\n * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance\n * it creates when the request completes or fails.  However, if\n * the request never completes, then the goog.net.XhrIo is not disposed.\n * This can occur if the window is unloaded before the request completes.\n * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo\n * it creates and make the client of {@link goog.net.XhrIo.send} be\n * responsible for disposing it in this case.  However, this makes things\n * significantly more complicated for the client, and the whole point\n * of {@link goog.net.XhrIo.send} is that it's simple and easy to use.\n * Clients of {@link goog.net.XhrIo.send} should call\n * {@link goog.net.XhrIo.cleanup} when doing final\n * cleanup on window unload.\n */\ngoog.net.XhrIo.cleanup = function() {\n  var instances = goog.net.XhrIo.sendInstances_;\n  while (instances.length) {\n    instances.pop().dispose();\n  }\n};\n\n\n/**\n * Installs exception protection for all entry point introduced by\n * goog.net.XhrIo instances which are not protected by\n * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},\n * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or\n * {@link goog.events.protectBrowserEventEntryPoint}.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n *     protect the entry point(s).\n */\ngoog.net.XhrIo.protectEntryPoints = function(errorHandler) {\n  goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n      errorHandler.protectEntryPoint(\n          goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n};\n\n\n/**\n * Disposes of the specified goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send} and removes it from\n * {@link goog.net.XhrIo.pendingStaticSendInstances_}.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanupSend_ = function() {\n  this.dispose();\n  goog.array.remove(goog.net.XhrIo.sendInstances_, this);\n};\n\n\n/**\n * Returns the number of milliseconds after which an incomplete request will be\n * aborted, or 0 if no timeout is set.\n * @return {number} Timeout interval in milliseconds.\n */\ngoog.net.XhrIo.prototype.getTimeoutInterval = function() {\n  return this.timeoutInterval_;\n};\n\n\n/**\n * Sets the number of milliseconds after which an incomplete request will be\n * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no\n * timeout is set.\n * @param {number} ms Timeout interval in milliseconds; 0 means none.\n */\ngoog.net.XhrIo.prototype.setTimeoutInterval = function(ms) {\n  this.timeoutInterval_ = Math.max(0, ms);\n};\n\n\n/**\n * Sets the desired type for the response. At time of writing, this is only\n * supported in very recent versions of WebKit (10.0.612.1 dev and later).\n *\n * If this is used, the response may only be accessed via {@link #getResponse}.\n *\n * @param {goog.net.XhrIo.ResponseType} type The desired type for the response.\n */\ngoog.net.XhrIo.prototype.setResponseType = function(type) {\n  this.responseType_ = type;\n};\n\n\n/**\n * Gets the desired type for the response.\n * @return {goog.net.XhrIo.ResponseType} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getResponseType = function() {\n  return this.responseType_;\n};\n\n\n/**\n * Sets whether a \"credentialed\" request that is aware of cookie and\n * authentication information should be made. This option is only supported by\n * browsers that support HTTP Access Control. As of this writing, this option\n * is not supported in IE.\n *\n * @param {boolean} withCredentials Whether this should be a \"credentialed\"\n *     request.\n */\ngoog.net.XhrIo.prototype.setWithCredentials = function(withCredentials) {\n  this.withCredentials_ = withCredentials;\n};\n\n\n/**\n * Gets whether a \"credentialed\" request is to be sent.\n * @return {boolean} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getWithCredentials = function() {\n  return this.withCredentials_;\n};\n\n\n/**\n * Sets whether progress events are enabled for this request. Note\n * that progress events require pre-flight OPTIONS request handling\n * for CORS requests, and may cause trouble with older browsers. See\n * progressEventsEnabled_ for details.\n * @param {boolean} enabled Whether progress events should be enabled.\n */\ngoog.net.XhrIo.prototype.setProgressEventsEnabled = function(enabled) {\n  this.progressEventsEnabled_ = enabled;\n};\n\n\n/**\n * Gets whether progress events are enabled.\n * @return {boolean} Whether progress events are enabled for this request.\n */\ngoog.net.XhrIo.prototype.getProgressEventsEnabled = function() {\n  return this.progressEventsEnabled_;\n};\n\n\n/**\n * Instance send that actually uses XMLHttpRequest to make a server call.\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n *     opt_content Body data.\n * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the\n *     request.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters for opt_headers.\n */\ngoog.net.XhrIo.prototype.send = function(\n    url, opt_method, opt_content, opt_headers) {\n  if (this.xhr_) {\n    throw new Error(\n        '[goog.net.XhrIo] Object is active with another request=' +\n        this.lastUri_ + '; newUri=' + url);\n  }\n\n  var method = opt_method ? opt_method.toUpperCase() : 'GET';\n\n  this.lastUri_ = url;\n  this.lastError_ = '';\n  this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n  this.lastMethod_ = method;\n  this.errorDispatched_ = false;\n  this.active_ = true;\n\n  // Use the factory to create the XHR object and options\n  this.xhr_ = this.createXhr();\n  this.xhrOptions_ = this.xmlHttpFactory_ ? this.xmlHttpFactory_.getOptions() :\n                                            goog.net.XmlHttp.getOptions();\n\n  // Set up the onreadystatechange callback\n  this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this);\n\n  // Set up upload/download progress events, if progress events are supported.\n  if (this.getProgressEventsEnabled() && 'onprogress' in this.xhr_) {\n    this.xhr_.onprogress =\n        goog.bind(function(e) { this.onProgressHandler_(e, true); }, this);\n    if (this.xhr_.upload) {\n      this.xhr_.upload.onprogress = goog.bind(this.onProgressHandler_, this);\n    }\n  }\n\n  /**\n   * Try to open the XMLHttpRequest (always async), if an error occurs here it\n   * is generally permission denied\n   */\n  try {\n    goog.log.fine(this.logger_, this.formatMsg_('Opening Xhr'));\n    this.inOpen_ = true;\n    this.xhr_.open(method, String(url), true);  // Always async!\n    this.inOpen_ = false;\n  } catch (err) {\n    goog.log.fine(\n        this.logger_, this.formatMsg_('Error opening Xhr: ' + err.message));\n    this.error_(goog.net.ErrorCode.EXCEPTION, err);\n    return;\n  }\n\n  // We can't use null since this won't allow requests with form data to have a\n  // content length specified which will cause some proxies to return a 411\n  // error.\n  var content = opt_content || '';\n\n  var headers = this.headers.clone();\n\n  // Add headers specific to this request\n  if (opt_headers) {\n    goog.structs.forEach(\n        opt_headers, function(value, key) { headers.set(key, value); });\n  }\n\n  // Find whether a content type header is set, ignoring case.\n  // HTTP header names are case-insensitive.  See:\n  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2\n  var contentTypeKey =\n      goog.array.find(headers.getKeys(), goog.net.XhrIo.isContentTypeHeader_);\n\n  var contentIsFormData =\n      (goog.global['FormData'] && (content instanceof goog.global['FormData']));\n  if (goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) &&\n      !contentTypeKey && !contentIsFormData) {\n    // For requests typically with form data, default to the url-encoded form\n    // content type unless this is a FormData request.  For FormData,\n    // the browser will automatically add a multipart/form-data content type\n    // with an appropriate multipart boundary.\n    headers.set(\n        goog.net.XhrIo.CONTENT_TYPE_HEADER, goog.net.XhrIo.FORM_CONTENT_TYPE);\n  }\n\n  // Add the headers to the Xhr object\n  headers.forEach(function(value, key) {\n    this.xhr_.setRequestHeader(key, value);\n  }, this);\n\n  if (this.responseType_) {\n    this.xhr_.responseType = this.responseType_;\n  }\n  // Set xhr_.withCredentials only when the value is different, or else in\n  // synchronous XMLHtppRequest.open Firefox will throw an exception.\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=736340\n  if ('withCredentials' in this.xhr_ &&\n      this.xhr_.withCredentials !== this.withCredentials_) {\n    this.xhr_.withCredentials = this.withCredentials_;\n  }\n\n  /**\n   * Try to send the request, or other wise report an error (404 not found).\n   */\n  try {\n    this.cleanUpTimeoutTimer_();  // Paranoid, should never be running.\n    if (this.timeoutInterval_ > 0) {\n      this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_);\n      goog.log.fine(\n          this.logger_, this.formatMsg_(\n                            'Will abort after ' + this.timeoutInterval_ +\n                            'ms if incomplete, xhr2 ' + this.useXhr2Timeout_));\n      if (this.useXhr2Timeout_) {\n        this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_;\n        this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] =\n            goog.bind(this.timeout_, this);\n      } else {\n        this.timeoutId_ =\n            goog.Timer.callOnce(this.timeout_, this.timeoutInterval_, this);\n      }\n    }\n    goog.log.fine(this.logger_, this.formatMsg_('Sending request'));\n    this.inSend_ = true;\n    this.xhr_.send(content);\n    this.inSend_ = false;\n\n  } catch (err) {\n    goog.log.fine(this.logger_, this.formatMsg_('Send error: ' + err.message));\n    this.error_(goog.net.ErrorCode.EXCEPTION, err);\n  }\n};\n\n\n/**\n * Determines if the argument is an XMLHttpRequest that supports the level 2\n * timeout value and event.\n *\n * Currently, FF 21.0 OS X has the fields but won't actually call the timeout\n * handler.  Perhaps the confusion in the bug referenced below hasn't\n * entirely been resolved.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n * @see https://bugzilla.mozilla.org/show_bug.cgi?id=525816\n *\n * @param {!goog.net.XhrLike.OrNative} xhr The request.\n * @return {boolean} True if the request supports level 2 timeout.\n * @private\n */\ngoog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) {\n  return goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9) &&\n      typeof xhr[goog.net.XhrIo.XHR2_TIMEOUT_] === 'number' &&\n      xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_] !== undefined;\n};\n\n\n/**\n * @param {string} header An HTTP header key.\n * @return {boolean} Whether the key is a content type header (ignoring\n *     case.\n * @private\n */\ngoog.net.XhrIo.isContentTypeHeader_ = function(header) {\n  return goog.string.caseInsensitiveEquals(\n      goog.net.XhrIo.CONTENT_TYPE_HEADER, header);\n};\n\n\n/**\n * Creates a new XHR object.\n * @return {!goog.net.XhrLike.OrNative} The newly created XHR object.\n * @protected\n */\ngoog.net.XhrIo.prototype.createXhr = function() {\n  return this.xmlHttpFactory_ ? this.xmlHttpFactory_.createInstance() :\n                                goog.net.XmlHttp();\n};\n\n\n/**\n * The request didn't complete after {@link goog.net.XhrIo#timeoutInterval_}\n * milliseconds; raises a {@link goog.net.EventType.TIMEOUT} event and aborts\n * the request.\n * @private\n */\ngoog.net.XhrIo.prototype.timeout_ = function() {\n  if (typeof goog == 'undefined') {\n    // If goog is undefined then the callback has occurred as the application\n    // is unloading and will error.  Thus we let it silently fail.\n  } else if (this.xhr_) {\n    this.lastError_ =\n        'Timed out after ' + this.timeoutInterval_ + 'ms, aborting';\n    this.lastErrorCode_ = goog.net.ErrorCode.TIMEOUT;\n    goog.log.fine(this.logger_, this.formatMsg_(this.lastError_));\n    this.dispatchEvent(goog.net.EventType.TIMEOUT);\n    this.abort(goog.net.ErrorCode.TIMEOUT);\n  }\n};\n\n\n/**\n * Something errorred, so inactivate, fire error callback and clean up\n * @param {goog.net.ErrorCode} errorCode The error code.\n * @param {Error} err The error object.\n * @private\n */\ngoog.net.XhrIo.prototype.error_ = function(errorCode, err) {\n  this.active_ = false;\n  if (this.xhr_) {\n    this.inAbort_ = true;\n    this.xhr_.abort();  // Ensures XHR isn't hung (FF)\n    this.inAbort_ = false;\n  }\n  this.lastError_ = err;\n  this.lastErrorCode_ = errorCode;\n  this.dispatchErrors_();\n  this.cleanUpXhr_();\n};\n\n\n/**\n * Dispatches COMPLETE and ERROR in case of an error. This ensures that we do\n * not dispatch multiple error events.\n * @private\n */\ngoog.net.XhrIo.prototype.dispatchErrors_ = function() {\n  if (!this.errorDispatched_) {\n    this.errorDispatched_ = true;\n    this.dispatchEvent(goog.net.EventType.COMPLETE);\n    this.dispatchEvent(goog.net.EventType.ERROR);\n  }\n};\n\n\n/**\n * Abort the current XMLHttpRequest\n * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -\n *     defaults to ABORT.\n */\ngoog.net.XhrIo.prototype.abort = function(opt_failureCode) {\n  if (this.xhr_ && this.active_) {\n    goog.log.fine(this.logger_, this.formatMsg_('Aborting'));\n    this.active_ = false;\n    this.inAbort_ = true;\n    this.xhr_.abort();\n    this.inAbort_ = false;\n    this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;\n    this.dispatchEvent(goog.net.EventType.COMPLETE);\n    this.dispatchEvent(goog.net.EventType.ABORT);\n    this.cleanUpXhr_();\n  }\n};\n\n\n/**\n * Nullifies all callbacks to reduce risks of leaks.\n * @override\n * @protected\n */\ngoog.net.XhrIo.prototype.disposeInternal = function() {\n  if (this.xhr_) {\n    // We explicitly do not call xhr_.abort() unless active_ is still true.\n    // This is to avoid unnecessarily aborting a successful request when\n    // dispose() is called in a callback triggered by a complete response, but\n    // in which browser cleanup has not yet finished.\n    // (See http://b/issue?id=1684217.)\n    if (this.active_) {\n      this.active_ = false;\n      this.inAbort_ = true;\n      this.xhr_.abort();\n      this.inAbort_ = false;\n    }\n    this.cleanUpXhr_(true);\n  }\n\n  XhrIo.base(this, 'disposeInternal');\n};\n\n\n/**\n * Internal handler for the XHR object's readystatechange event.  This method\n * checks the status and the readystate and fires the correct callbacks.\n * If the request has ended, the handlers are cleaned up and the XHR object is\n * nullified.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChange_ = function() {\n  if (this.isDisposed()) {\n    // This method is the target of an untracked goog.Timer.callOnce().\n    return;\n  }\n  if (!this.inOpen_ && !this.inSend_ && !this.inAbort_) {\n    // Were not being called from within a call to this.xhr_.send\n    // this.xhr_.abort, or this.xhr_.open, so this is an entry point\n    this.onReadyStateChangeEntryPoint_();\n  } else {\n    this.onReadyStateChangeHelper_();\n  }\n};\n\n\n/**\n * Used to protect the onreadystatechange handler entry point.  Necessary\n * as {#onReadyStateChange_} maybe called from within send or abort, this\n * method is only called when {#onReadyStateChange_} is called as an\n * entry point.\n * {@see #protectEntryPoints}\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() {\n  this.onReadyStateChangeHelper_();\n};\n\n\n/**\n * Helper for {@link #onReadyStateChange_}.  This is used so that\n * entry point calls to {@link #onReadyStateChange_} can be routed through\n * {@link #onReadyStateChangeEntryPoint_}.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() {\n  if (!this.active_) {\n    // can get called inside abort call\n    return;\n  }\n\n  if (typeof goog == 'undefined') {\n    // NOTE(user): If goog is undefined then the callback has occurred as the\n    // application is unloading and will error.  Thus we let it silently fail.\n\n  } else if (\n      this.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] &&\n      this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE &&\n      this.getStatus() == 2) {\n    // NOTE(user): In IE if send() errors on a *local* request the readystate\n    // is still changed to COMPLETE.  We need to ignore it and allow the\n    // try/catch around send() to pick up the error.\n    goog.log.fine(\n        this.logger_,\n        this.formatMsg_('Local request error detected and ignored'));\n\n  } else {\n    // In IE when the response has been cached we sometimes get the callback\n    // from inside the send call and this usually breaks code that assumes that\n    // XhrIo is asynchronous.  If that is the case we delay the callback\n    // using a timer.\n    if (this.inSend_ &&\n        this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE) {\n      goog.Timer.callOnce(this.onReadyStateChange_, 0, this);\n      return;\n    }\n\n    this.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE);\n\n    // readyState indicates the transfer has finished\n    if (this.isComplete()) {\n      goog.log.fine(this.logger_, this.formatMsg_('Request complete'));\n\n      this.active_ = false;\n\n      try {\n        // Call the specific callbacks for success or failure. Only call the\n        // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)\n        if (this.isSuccess()) {\n          this.dispatchEvent(goog.net.EventType.COMPLETE);\n          this.dispatchEvent(goog.net.EventType.SUCCESS);\n        } else {\n          this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;\n          this.lastError_ =\n              this.getStatusText() + ' [' + this.getStatus() + ']';\n          this.dispatchErrors_();\n        }\n      } finally {\n        this.cleanUpXhr_();\n      }\n    }\n  }\n};\n\n\n/**\n * Internal handler for the XHR object's onprogress event. Fires both a generic\n * PROGRESS event and either a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event to\n * allow specific binding for each XHR progress event.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {boolean=} opt_isDownload Whether the current progress event is from a\n *     download. Used to determine whether DOWNLOAD_PROGRESS or UPLOAD_PROGRESS\n *     event should be dispatched.\n * @private\n */\ngoog.net.XhrIo.prototype.onProgressHandler_ = function(e, opt_isDownload) {\n  goog.asserts.assert(\n      e.type === goog.net.EventType.PROGRESS,\n      'goog.net.EventType.PROGRESS is of the same type as raw XHR progress.');\n  this.dispatchEvent(\n      goog.net.XhrIo.buildProgressEvent_(e, goog.net.EventType.PROGRESS));\n  this.dispatchEvent(\n      goog.net.XhrIo.buildProgressEvent_(\n          e, opt_isDownload ? goog.net.EventType.DOWNLOAD_PROGRESS :\n                              goog.net.EventType.UPLOAD_PROGRESS));\n};\n\n\n/**\n * Creates a representation of the native ProgressEvent. IE doesn't support\n * constructing ProgressEvent via \"new\", and the alternatives (e.g.,\n * ProgressEvent.initProgressEvent) are non-standard or deprecated.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {!goog.net.EventType} eventType The type of the event.\n * @return {!ProgressEvent} The progress event.\n * @private\n */\ngoog.net.XhrIo.buildProgressEvent_ = function(e, eventType) {\n  return /** @type {!ProgressEvent} */ ({\n    type: eventType,\n    lengthComputable: e.lengthComputable,\n    loaded: e.loaded,\n    total: e.total,\n  });\n};\n\n\n/**\n * Remove the listener to protect against leaks, and nullify the XMLHttpRequest\n * object.\n * @param {boolean=} opt_fromDispose If this is from the dispose (don't want to\n *     fire any events).\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpXhr_ = function(opt_fromDispose) {\n  if (this.xhr_) {\n    // Cancel any pending timeout event handler.\n    this.cleanUpTimeoutTimer_();\n\n    // Save reference so we can mark it as closed after the READY event.  The\n    // READY event may trigger another request, thus we must nullify this.xhr_\n    var xhr = this.xhr_;\n    var clearedOnReadyStateChange =\n        this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ?\n        goog.nullFunction :\n        null;\n    this.xhr_ = null;\n    this.xhrOptions_ = null;\n\n    if (!opt_fromDispose) {\n      this.dispatchEvent(goog.net.EventType.READY);\n    }\n\n    try {\n      // NOTE(user): Not nullifying in FireFox can still leak if the callbacks\n      // are defined in the same scope as the instance of XhrIo. But, IE doesn't\n      // allow you to set the onreadystatechange to NULL so nullFunction is\n      // used.\n      xhr.onreadystatechange = clearedOnReadyStateChange;\n    } catch (e) {\n      // This seems to occur with a Gears HTTP request. Delayed the setting of\n      // this onreadystatechange until after READY is sent out and catching the\n      // error to see if we can track down the problem.\n      goog.log.error(\n          this.logger_,\n          'Problem encountered resetting onreadystatechange: ' + e.message);\n    }\n  }\n};\n\n\n/**\n * Make sure the timeout timer isn't running.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpTimeoutTimer_ = function() {\n  if (this.xhr_ && this.useXhr2Timeout_) {\n    this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null;\n  }\n  if (this.timeoutId_) {\n    goog.Timer.clear(this.timeoutId_);\n    this.timeoutId_ = null;\n  }\n};\n\n\n/**\n * @return {boolean} Whether there is an active request.\n */\ngoog.net.XhrIo.prototype.isActive = function() {\n  return !!this.xhr_;\n};\n\n\n/**\n * @return {boolean} Whether the request has completed.\n */\ngoog.net.XhrIo.prototype.isComplete = function() {\n  return this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE;\n};\n\n\n/**\n * @return {boolean} Whether the request completed with a success.\n */\ngoog.net.XhrIo.prototype.isSuccess = function() {\n  var status = this.getStatus();\n  // A zero status code is considered successful for local files.\n  return goog.net.HttpStatus.isSuccess(status) ||\n      status === 0 && !this.isLastUriEffectiveSchemeHttp_();\n};\n\n\n/**\n * @return {boolean} whether the effective scheme of the last URI that was\n *     fetched was 'http' or 'https'.\n * @private\n */\ngoog.net.XhrIo.prototype.isLastUriEffectiveSchemeHttp_ = function() {\n  var scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_));\n  return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme);\n};\n\n\n/**\n * Get the readystate from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {goog.net.XmlHttp.ReadyState} goog.net.XmlHttp.ReadyState.*.\n */\ngoog.net.XhrIo.prototype.getReadyState = function() {\n  return this.xhr_ ?\n      /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) :\n                                                 goog.net.XmlHttp.ReadyState\n                                                     .UNINITIALIZED;\n};\n\n\n/**\n * Get the status from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {number} Http status.\n */\ngoog.net.XhrIo.prototype.getStatus = function() {\n  /**\n   * IE doesn't like you checking status until the readystate is greater than 2\n   * (i.e. it is receiving or complete).  The try/catch is used for when the\n   * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n   */\n  try {\n    return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n        this.xhr_.status :\n        -1;\n  } catch (e) {\n    return -1;\n  }\n};\n\n\n/**\n * Get the status text from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {string} Status text.\n */\ngoog.net.XhrIo.prototype.getStatusText = function() {\n  /**\n   * IE doesn't like you checking status until the readystate is greater than 2\n   * (i.e. it is receiving or complete).  The try/catch is used for when the\n   * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n   */\n  try {\n    return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n        this.xhr_.statusText :\n        '';\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get status: ' + e.message);\n    return '';\n  }\n};\n\n\n/**\n * Get the last Uri that was requested\n * @return {string} Last Uri.\n */\ngoog.net.XhrIo.prototype.getLastUri = function() {\n  return String(this.lastUri_);\n};\n\n\n/**\n * Get the response text from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {string} Result from the server, or '' if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseText = function() {\n  try {\n    return this.xhr_ ? this.xhr_.responseText : '';\n  } catch (e) {\n    // http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute\n    // states that responseText should return '' (and responseXML null)\n    // when the state is not LOADING or DONE. Instead, IE can\n    // throw unexpected exceptions, for example when a request is aborted\n    // or no data is available yet.\n    goog.log.fine(this.logger_, 'Can not get responseText: ' + e.message);\n    return '';\n  }\n};\n\n\n/**\n * Get the response body from the Xhr object. This property is only available\n * in IE since version 7 according to MSDN:\n * http://msdn.microsoft.com/en-us/library/ie/ms534368(v=vs.85).aspx\n * Will only return correct result when called from the context of a callback.\n *\n * One option is to construct a VBArray from the returned object and convert\n * it to a JavaScript array using the toArray method:\n * `(new window['VBArray'](xhrIo.getResponseBody())).toArray()`\n * This will result in an array of numbers in the range of [0..255]\n *\n * Another option is to use the VBScript CStr method to convert it into a\n * string as outlined in http://stackoverflow.com/questions/1919972\n *\n * @return {Object} Binary result from the server or null if not available.\n */\ngoog.net.XhrIo.prototype.getResponseBody = function() {\n  try {\n    if (this.xhr_ && 'responseBody' in this.xhr_) {\n      return this.xhr_['responseBody'];\n    }\n  } catch (e) {\n    // IE can throw unexpected exceptions, for example when a request is aborted\n    // or no data is yet available.\n    goog.log.fine(this.logger_, 'Can not get responseBody: ' + e.message);\n  }\n  return null;\n};\n\n\n/**\n * Get the response XML from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {Document} The DOM Document representing the XML file, or null\n * if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseXml = function() {\n  try {\n    return this.xhr_ ? this.xhr_.responseXML : null;\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get responseXML: ' + e.message);\n    return null;\n  }\n};\n\n\n/**\n * Get the response and evaluates it as JSON from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @param {string=} opt_xssiPrefix Optional XSSI prefix string to use for\n *     stripping of the response before parsing. This needs to be set only if\n *     your backend server prepends the same prefix string to the JSON response.\n * @throws Error if the response text is invalid JSON.\n * @return {Object|undefined} JavaScript object.\n */\ngoog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) {\n  if (!this.xhr_) {\n    return undefined;\n  }\n\n  var responseText = this.xhr_.responseText;\n  if (opt_xssiPrefix && responseText.indexOf(opt_xssiPrefix) == 0) {\n    responseText = responseText.substring(opt_xssiPrefix.length);\n  }\n\n  return goog.json.hybrid.parse(responseText);\n};\n\n\n/**\n * Get the response as the type specificed by {@link #setResponseType}. At time\n * of writing, this is only directly supported in very recent versions of WebKit\n * (10.0.612.1 dev and later). If the field is not supported directly, we will\n * try to emulate it.\n *\n * Emulating the response means following the rules laid out at\n * http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute\n *\n * On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only\n * response types of DEFAULT or TEXT may be used, and the response returned will\n * be the text response.\n *\n * On browsers with Mozilla's draft support for array buffers (Firefox 4, 5),\n * only response types of DEFAULT, TEXT, and ARRAY_BUFFER may be used, and the\n * response returned will be either the text response or the Mozilla\n * implementation of the array buffer response.\n *\n * On browsers will full support, any valid response type supported by the\n * browser may be used, and the response provided by the browser will be\n * returned.\n *\n * @return {*} The response.\n */\ngoog.net.XhrIo.prototype.getResponse = function() {\n  try {\n    if (!this.xhr_) {\n      return null;\n    }\n    if ('response' in this.xhr_) {\n      return this.xhr_.response;\n    }\n    switch (this.responseType_) {\n      case ResponseType.DEFAULT:\n      case ResponseType.TEXT:\n        return this.xhr_.responseText;\n      // DOCUMENT and BLOB don't need to be handled here because they are\n      // introduced in the same spec that adds the .response field, and would\n      // have been caught above.\n      // ARRAY_BUFFER needs an implementation for Firefox 4, where it was\n      // implemented using a draft spec rather than the final spec.\n      case ResponseType.ARRAY_BUFFER:\n        if ('mozResponseArrayBuffer' in this.xhr_) {\n          return this.xhr_.mozResponseArrayBuffer;\n        }\n    }\n    // Fell through to a response type that is not supported on this browser.\n    goog.log.error(\n        this.logger_, 'Response type ' + this.responseType_ + ' is not ' +\n            'supported on this browser');\n    return null;\n  } catch (e) {\n    goog.log.fine(this.logger_, 'Can not get response: ' + e.message);\n    return null;\n  }\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object\n * Will only return correct result when called from the context of a callback\n * and the request has completed\n * @param {string} key The name of the response-header to retrieve.\n * @return {string|undefined} The value of the response-header named key.\n */\ngoog.net.XhrIo.prototype.getResponseHeader = function(key) {\n  if (!this.xhr_ || !this.isComplete()) {\n    return undefined;\n  }\n\n  var value = this.xhr_.getResponseHeader(key);\n  return value === null ? undefined : value;\n};\n\n\n/**\n * Gets the text of all the headers in the response.\n * Will only return correct result when called from the context of a callback\n * and the request has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllResponseHeaders = function() {\n  // getAllResponseHeaders can return null if no response has been received,\n  // ensure we always return an empty string.\n  return this.xhr_ && this.isComplete() ?\n      (this.xhr_.getAllResponseHeaders() || '') :\n      '';\n};\n\n\n/**\n * Returns all response headers as a key-value map.\n * Multiple values for the same header key can be combined into one,\n * separated by a comma and a space.\n * Note that the native getResponseHeader method for retrieving a single header\n * does a case insensitive match on the header name. This method does not\n * include any case normalization logic, it will just return a key-value\n * representation of the headers.\n * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method\n * @return {!Object<string, string>} An object with the header keys as keys\n *     and header values as values.\n */\ngoog.net.XhrIo.prototype.getResponseHeaders = function() {\n  // TODO(user): Make this function parse headers as per the spec\n  // (https://tools.ietf.org/html/rfc2616#section-4.2).\n\n  var headersObject = {};\n  var headersArray = this.getAllResponseHeaders().split('\\r\\n');\n  for (var i = 0; i < headersArray.length; i++) {\n    if (goog.string.isEmptyOrWhitespace(headersArray[i])) {\n      continue;\n    }\n    var keyValue =\n        goog.string.splitLimit(headersArray[i], ':', /* maxSplitCount= */ 1);\n    var key = keyValue[0];\n    var value = keyValue[1];\n\n    if (typeof value !== 'string') {\n      // There must be a value but it can be the empty string.\n      continue;\n    }\n\n    // Whitespace at the start and end of the value is meaningless.\n    value = value.trim();\n    // The key should not contain whitespace but we currently ignore that.\n\n    var values = headersObject[key] || [];\n    headersObject[key] = values;\n    values.push(value);\n  }\n\n  return goog.object.map(headersObject, function(values) {\n    return values.join(', ');\n  });\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object.\n * As opposed to {@link #getResponseHeader}, this method does not require that\n * the request has completed.\n * @param {string} key The name of the response-header to retrieve.\n * @return {?string} The value of the response-header, or null if it is\n *     unavailable.\n */\ngoog.net.XhrIo.prototype.getStreamingResponseHeader = function(key) {\n  return this.xhr_ ? this.xhr_.getResponseHeader(key) : null;\n};\n\n\n/**\n * Gets the text of all the headers in the response. As opposed to\n * {@link #getAllResponseHeaders}, this method does not require that the request\n * has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllStreamingResponseHeaders = function() {\n  return this.xhr_ ? this.xhr_.getAllResponseHeaders() : '';\n};\n\n\n/**\n * Get the last error message\n * @return {!goog.net.ErrorCode} Last error code.\n */\ngoog.net.XhrIo.prototype.getLastErrorCode = function() {\n  return this.lastErrorCode_;\n};\n\n\n/**\n * Get the last error message\n * @return {string} Last error message.\n */\ngoog.net.XhrIo.prototype.getLastError = function() {\n  return typeof this.lastError_ === 'string' ? this.lastError_ :\n                                               String(this.lastError_);\n};\n\n\n/**\n * Adds the last method, status and URI to the message.  This is used to add\n * this information to the logging calls.\n * @param {string} msg The message text that we want to add the extra text to.\n * @return {string} The message with the extra text appended.\n * @private\n */\ngoog.net.XhrIo.prototype.formatMsg_ = function(msg) {\n  return msg + ' [' + this.lastMethod_ + ' ' + this.lastUri_ + ' ' +\n      this.getStatus() + ']';\n};\n\n\n// Register the xhr handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n    /**\n     * @param {function(!Function): !Function} transformer The transforming\n     *     function.\n     */\n    function(transformer) {\n      goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n          transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n    });\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Base WebChannel implementation.\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WebChannelBase');\n\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.async.run');\ngoog.require('goog.json');\ngoog.require('goog.labs.net.webChannel.Channel');\ngoog.require('goog.labs.net.webChannel.ChannelRequest');\ngoog.require('goog.labs.net.webChannel.ConnectionState');\ngoog.require('goog.labs.net.webChannel.ForwardChannelRequestPool');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.labs.net.webChannel.WireV8');\ngoog.require('goog.labs.net.webChannel.netUtils');\ngoog.require('goog.labs.net.webChannel.requestStats');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.XhrIo');\ngoog.require('goog.net.XmlHttpFactory');\ngoog.require('goog.net.rpc.HttpCors');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.structs');\n\ngoog.scope(function() {\nvar WebChannel = goog.net.WebChannel;\nvar ChannelRequest = goog.labs.net.webChannel.ChannelRequest;\nvar ConnectionState = goog.labs.net.webChannel.ConnectionState;\nvar ForwardChannelRequestPool =\n    goog.labs.net.webChannel.ForwardChannelRequestPool;\nvar WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\nvar Wire = goog.labs.net.webChannel.Wire;\nvar WireV8 = goog.labs.net.webChannel.WireV8;\nvar netUtils = goog.labs.net.webChannel.netUtils;\nvar requestStats = goog.labs.net.webChannel.requestStats;\n\nvar httpCors = goog.module.get('goog.net.rpc.HttpCors');\n\n/**\n * Gets an internal channel parameter in a type-safe way.\n *\n * @param {string} paramName the key of the parameter to fetch.\n * @param {!T} defaultValue the default value to return\n * @param {!goog.net.WebChannel.Options=} options Configuration for the\n *        WebChannel instance.\n * @return {T}\n * @template T\n */\nfunction getInternalChannelParam(paramName, defaultValue, options) {\n  if (!options || !options.internalChannelParams) {\n    return defaultValue;\n  }\n  return /** @type {T} */ (options.internalChannelParams[paramName]) ||\n      defaultValue;\n}\n\n/**\n * This WebChannel implementation is branched off goog.net.BrowserChannel\n * for now. Ongoing changes to goog.net.BrowserChannel will be back\n * ported to this implementation as needed.\n *\n * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the\n *        WebChannel instance.\n * @param {number=} opt_clientVersion An application-specific version number\n *        that is sent to the server when connected.\n * @param {!ConnectionState=} opt_conn Previously determined connection\n *        conditions.\n * @constructor\n * @struct\n * @implements {goog.labs.net.webChannel.Channel}\n */\ngoog.labs.net.webChannel.WebChannelBase = function(\n    opt_options, opt_clientVersion, opt_conn) {\n  /**\n   * The client library version (capabilities).\n   * @private {number}\n   */\n  this.clientVersion_ = opt_clientVersion || 0;\n\n  /**\n   * The server library version (capabilities).\n   * @private {number}\n   */\n  this.serverVersion_ = 0;\n\n\n  /**\n   * An array of queued maps that need to be sent to the server.\n   * @private {!Array<Wire.QueuedMap>}\n   */\n  this.outgoingMaps_ = [];\n\n  /**\n   * The channel debug used for logging\n   * @private {!WebChannelDebug}\n   */\n  this.channelDebug_ = new WebChannelDebug();\n\n  /**\n   * Connectivity state.\n   * @private {!ConnectionState}\n   */\n  this.connState_ = opt_conn || new ConnectionState();\n\n  /**\n   * Extra HTTP headers to add to all the requests sent to the server.\n   * @private {?Object}\n   */\n  this.extraHeaders_ = null;\n\n  /**\n   * Extra HTTP headers to add to the init request(s) sent to the server.\n   * @private {?Object}\n   */\n  this.initHeaders_ = null;\n\n  /**\n   * @private {?string} The URL param name to overwrite custom HTTP headers\n   * to bypass CORS preflight.\n   */\n  this.httpHeadersOverwriteParam_ = null;\n\n  /**\n   * Extra parameters to add to all the requests sent to the server.\n   * @private {?Object}\n   */\n  this.extraParams_ = null;\n\n  /**\n   * Parameter name for the http session id.\n   * @private {?string}\n   */\n  this.httpSessionIdParam_ = null;\n\n  /**\n   * The http session id, to be sent with httpSessionIdParam_ with each\n   * request after the initial handshake.\n   * @private {?string}\n   */\n  this.httpSessionId_ = null;\n\n  /**\n   * The ChannelRequest object for the backchannel.\n   * @private {?ChannelRequest}\n   */\n  this.backChannelRequest_ = null;\n\n  /**\n   * The relative path (in the context of the page hosting the browser channel)\n   * for making requests to the server.\n   * @private {?string}\n   */\n  this.path_ = null;\n\n  /**\n   * The absolute URI for the forwardchannel request.\n   * @private {?goog.Uri}\n   */\n  this.forwardChannelUri_ = null;\n\n  /**\n   * The absolute URI for the backchannel request.\n   * @private {?goog.Uri}\n   */\n  this.backChannelUri_ = null;\n\n  /**\n   * A subdomain prefix for using a subdomain in IE for the backchannel\n   * requests.\n   * @private {?string}\n   */\n  this.hostPrefix_ = null;\n\n  /**\n   * Whether we allow the use of a subdomain in IE for the backchannel requests.\n   * @private {boolean}\n   */\n  this.allowHostPrefix_ = true;\n\n  /**\n   * The next id to use for the RID (request identifier) parameter. This\n   * identifier uniquely identifies the forward channel request.\n   * @private {number}\n   */\n  this.nextRid_ = 0;\n\n  /**\n   * The id to use for the next outgoing map. This identifier uniquely\n   * identifies a sent map.\n   * @private {number}\n   */\n  this.nextMapId_ = 0;\n\n  /**\n   * Whether to fail forward-channel requests after one try or a few tries.\n   * @private {boolean}\n   */\n  this.failFast_ = getInternalChannelParam('failFast', false, opt_options);\n\n  /**\n   * The handler that receive callbacks for state changes and data.\n   * @private {?goog.labs.net.webChannel.WebChannelBase.Handler}\n   */\n  this.handler_ = null;\n\n  /**\n   * Timer identifier for asynchronously making a forward channel request.\n   * This is set to true if the func is scheduled with async.run, which\n   * is equivalent to setTimeout(0).\n   * @private {?number|?boolean}\n   */\n  this.forwardChannelTimerId_ = null;\n\n  /**\n   * Timer identifier for asynchronously making a back channel request.\n   * @private {?number}\n   */\n  this.backChannelTimerId_ = null;\n\n  /**\n   * Timer identifier for the timer that waits for us to retry the backchannel\n   * in the case where it is dead and no longer receiving data.\n   * @private {?number}\n   */\n  this.deadBackChannelTimerId_ = null;\n\n  /**\n   * Whether the client's network conditions can support streamed responses.\n   * @private {?boolean}\n   */\n  this.enableStreaming_ = null;\n\n  /**\n   * Whether streaming mode is allowed. In certain debugging situations, it's\n   * useful to disable this.\n   * @private {boolean}\n   */\n  this.allowStreamingMode_ = true;\n\n  /**\n   * The array identifier of the last array received from the server for the\n   * backchannel request.\n   * @private {number}\n   */\n  this.lastArrayId_ = -1;\n\n  /**\n   * The array id of the last array sent by the server that we know about.\n   * @private {number}\n   */\n  this.lastPostResponseArrayId_ = -1;\n\n  /**\n   * The last status code received.\n   * @private {number}\n   */\n  this.lastStatusCode_ = -1;\n\n  /**\n   * Number of times we have retried the current forward channel request.\n   * @private {number}\n   */\n  this.forwardChannelRetryCount_ = 0;\n\n  /**\n   * Number of times in a row that we have retried the current back channel\n   * request and received no data.\n   * @private {number}\n   */\n  this.backChannelRetryCount_ = 0;\n\n  /**\n   * The attempt id for the current back channel request. Starts at 1 and\n   * increments for each reconnect. The server uses this to log if our\n   * connection is flaky or not.\n   * @private {number}\n   */\n  this.backChannelAttemptId_ = 0;\n\n  /**\n   * The base part of the time before firing next retry request. Default is 5\n   * seconds. Note that a random delay is added (see {@link retryDelaySeedMs_})\n   * for all retries, and linear backoff is applied to the sum for subsequent\n   * retries.\n   * @private {number}\n   */\n  this.baseRetryDelayMs_ =\n      getInternalChannelParam('baseRetryDelayMs', 5 * 1000, opt_options);\n\n  /**\n   * A random time between 0 and this number of MS is added to the\n   * {@link baseRetryDelayMs_}. Default is 10 seconds.\n   * @private {number}\n   */\n  this.retryDelaySeedMs_ =\n      getInternalChannelParam('retryDelaySeedMs', 10 * 1000, opt_options);\n\n  /**\n   * Maximum number of attempts to connect to the server for forward channel\n   * requests. Defaults to 2.\n   * @private {number}\n   */\n  this.forwardChannelMaxRetries_ =\n      getInternalChannelParam('forwardChannelMaxRetries', 2, opt_options);\n\n  /**\n   * The timeout in milliseconds for a forward channel request. Defaults to 20\n   * seconds. Note that part of this timeout can be randomized.\n   * @private {number}\n   */\n  this.forwardChannelRequestTimeoutMs_ = getInternalChannelParam(\n      'forwardChannelRequestTimeoutMs', 20 * 1000, opt_options);\n\n  /**\n   * The custom factory used to create XMLHttpRequest objects.\n   * @private {!goog.net.XmlHttpFactory | undefined}\n   */\n  this.xmlHttpFactory_ =\n      (opt_options && opt_options.xmlHttpFactory) || undefined;\n\n  /**\n   * The timeout in milliseconds for a back channel request. Defaults to using\n   * the timeout configured in ChannelRequest (45s). If server-side\n   * keepaliveInterval is known to the client, set the backchannel request\n   * timeout to 1.5 * keepaliveInterval (ms).\n   *\n   * @private {number|undefined}\n   */\n  this.backChannelRequestTimeoutMs_ = undefined;\n\n  /**\n   * A throttle time in ms for readystatechange events for the backchannel.\n   * Useful for throttling when ready state is INTERACTIVE (partial data).\n   *\n   * This throttle is useful if the server sends large data chunks down the\n   * backchannel.  It prevents examining XHR partial data on every readystate\n   * change event.  This is useful because large chunks can trigger hundreds\n   * of readystatechange events, each of which takes ~5ms or so to handle,\n   * in turn making the UI unresponsive for a significant period.\n   *\n   * If set to zero no throttle is used.\n   * @private {number}\n   */\n  this.readyStateChangeThrottleMs_ = 0;\n\n  /**\n   * Whether cross origin requests are supported for the channel.\n   *\n   * See {@link goog.net.XhrIo#setWithCredentials}.\n   * @private {boolean}\n   */\n  this.supportsCrossDomainXhrs_ =\n      (opt_options && opt_options.supportsCrossDomainXhr) || false;\n\n  /**\n   * The current session id.\n   * @private {string}\n   */\n  this.sid_ = '';\n\n  /**\n   * The current ChannelRequest pool for the forward channel.\n   * @private {!ForwardChannelRequestPool}\n   */\n  this.forwardChannelRequestPool_ = new ForwardChannelRequestPool(\n      opt_options && opt_options.concurrentRequestLimit);\n\n  /**\n   * The V8 codec.\n   * @private {!WireV8}\n   */\n  this.wireCodec_ = new WireV8();\n\n  /**\n   * Whether to turn on the fast handshake behavior.\n   *\n   * @private {boolean}\n   */\n  this.fastHandshake_ = (opt_options && opt_options.fastHandshake) || false;\n\n  /**\n   * Whether to signal to the server to enable blocking handshake.\n   *\n   * @private {boolean}\n   */\n  this.blockingHandshake_ =\n      (opt_options && opt_options.blockingHandshake) || false;\n\n\n  if (opt_options && opt_options.disableRedact) {\n    this.channelDebug_.disableRedact();\n  }\n\n  if (opt_options && opt_options.forceLongPolling) {\n    this.allowStreamingMode_ = false;\n  }\n\n  /**\n   * Whether to detect buffering proxies.\n   *\n   * fastHandshake + detectBufferingProxy are yet to be implemented.\n   *\n   * @private {boolean}\n   */\n  this.detectBufferingProxy_ =\n      (!this.fastHandshake_ && this.allowStreamingMode_ && opt_options &&\n       opt_options.detectBufferingProxy) ||\n      false;\n\n  /**\n   * Callback when all the pending client-sent messages have been flushed.\n   *\n   * @private {function()|undefined}\n   */\n  this.forwardChannelFlushedCallback_ = undefined;\n\n  /**\n   * TODO(user): move all backchannel states to its own class similar to\n   * forwardchannelrequestpool.js and log more stats.\n   *\n   * The estimated handshake RTT (ms) as measured from when the handshake\n   * request is sent and when the handshake response headers are received.\n   * If the value is 0, the RTT is unknown.\n   *\n   * @private {number}\n   */\n  this.handshakeRttMs_ = 0;\n\n  /**\n   * If BP detection is done or still in progress.\n   * Should only be checked when detectBufferingProxy is turned on.\n   * @private {boolean}\n   */\n  this.bpDetectionDone_ = false;\n\n  /**\n   * The timer for detecting buffering proxy. This needs be reset with each\n   * backchannel request. If this is not null, bpDetectionDone_ == false.\n   * @private {?number}\n   */\n  this.bpDetectionTimerId_ = null;\n};\n\nvar WebChannelBase = goog.labs.net.webChannel.WebChannelBase;\n\n\n/**\n * The channel version that we negotiated with the server for this session.\n * Starts out as the version we request, and then is changed to the negotiated\n * version after the initial open.\n * @private {number}\n */\nWebChannelBase.prototype.channelVersion_ = Wire.LATEST_CHANNEL_VERSION;\n\n\n/**\n * Enum type for the channel state machine.\n * @enum {number}\n */\nWebChannelBase.State = {\n  /** The channel is closed. */\n  CLOSED: 0,\n\n  /** The channel has been initialized but hasn't yet initiated a connection. */\n  INIT: 1,\n\n  /** The channel is in the process of opening a connection to the server. */\n  OPENING: 2,\n\n  /** The channel is open. */\n  OPENED: 3\n};\n\n\n/**\n * The current state of the WebChannel.\n * @private {!WebChannelBase.State}\n */\nWebChannelBase.prototype.state_ = WebChannelBase.State.INIT;\n\n\n/**\n * The timeout in milliseconds for a forward channel request.\n * @type {number}\n */\nWebChannelBase.FORWARD_CHANNEL_RETRY_TIMEOUT = 20 * 1000;\n\n\n/**\n * Maximum number of attempts to connect to the server for back channel\n * requests.\n * @type {number}\n */\nWebChannelBase.BACK_CHANNEL_MAX_RETRIES = 3;\n\n\n/**\n * A number in MS of how long we guess the maxmium amount of time a round trip\n * to the server should take. In the future this could be substituted with a\n * real measurement of the RTT.\n * @type {number}\n */\nWebChannelBase.RTT_ESTIMATE = 3 * 1000;\n\n\n/**\n * When retrying for an inactive channel, we will multiply the total delay by\n * this number.\n * @type {number}\n */\nWebChannelBase.INACTIVE_CHANNEL_RETRY_FACTOR = 2;\n\n\n/**\n * Enum type for identifying an error.\n * @enum {number}\n */\nWebChannelBase.Error = {\n  /** Value that indicates no error has occurred. */\n  OK: 0,\n\n  /** An error due to a request failing. */\n  REQUEST_FAILED: 2,\n\n  /** An error due to the user being logged out. */\n  LOGGED_OUT: 4,\n\n  /** An error due to server response which contains no data. */\n  NO_DATA: 5,\n\n  /** An error due to a server response indicating an unknown session id */\n  UNKNOWN_SESSION_ID: 6,\n\n  /** An error due to a server response requesting to stop the channel. */\n  STOP: 7,\n\n  /** A general network error. */\n  NETWORK: 8,\n\n  /** An error due to bad data being returned from the server. */\n  BAD_DATA: 10,\n\n  /** An error due to a response that is not parsable. */\n  BAD_RESPONSE: 11\n};\n\n\n/**\n * Internal enum type for the two channel types.\n * @enum {number}\n * @private\n */\nWebChannelBase.ChannelType_ = {\n  FORWARD_CHANNEL: 1,\n\n  BACK_CHANNEL: 2\n};\n\n\n/**\n * The maximum number of maps that can be sent in one POST. Should match\n * MAX_MAPS_PER_REQUEST on the server code.\n * @type {number}\n * @private\n */\nWebChannelBase.MAX_MAPS_PER_REQUEST_ = 1000;\n\n\n/**\n * The maximum number of utf-8 chars that can be sent in one GET to enable 0-RTT\n * handshake.\n *\n *  @const @private {number}\n */\nWebChannelBase.MAX_CHARS_PER_GET_ = 4 * 1024;\n\n\n/**\n * A guess at a cutoff at which to no longer assume the backchannel is dead\n * when we are slow to receive data. Number in bytes.\n *\n * Assumption: The worst bandwidth we work on is 50 kilobits/sec\n * 50kbits/sec * (1 byte / 8 bits) * 6 sec dead backchannel timeout\n * @type {number}\n */\nWebChannelBase.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF = 37500;\n\n\n/**\n * @return {number} The server version or 0 if undefined\n */\nWebChannelBase.prototype.getServerVersion = function() {\n  return this.serverVersion_;\n};\n\n\n/**\n * @return {!ForwardChannelRequestPool} The forward channel request pool.\n */\nWebChannelBase.prototype.getForwardChannelRequestPool = function() {\n  return this.forwardChannelRequestPool_;\n};\n\n\n/**\n * @return {!Object} The codec object.\n */\nWebChannelBase.prototype.getWireCodec = function() {\n  return this.wireCodec_;\n};\n\n\n/**\n * Returns the logger.\n *\n * @return {!WebChannelDebug} The channel debug object.\n */\nWebChannelBase.prototype.getChannelDebug = function() {\n  return this.channelDebug_;\n};\n\n\n/**\n * Sets the logger.\n *\n * @param {!WebChannelDebug} channelDebug The channel debug object.\n */\nWebChannelBase.prototype.setChannelDebug = function(channelDebug) {\n  this.channelDebug_ = channelDebug;\n};\n\n\n/**\n * Starts the channel. This initiates connections to the server.\n *\n * @param {string} channelPath  The path for the channel connection.\n * @param {!Object=} opt_extraParams Extra parameter keys and values to add to\n *     the requests.\n * @param {string=} opt_oldSessionId  Session ID from a previous session.\n * @param {number=} opt_oldArrayId  The last array ID from a previous session.\n */\nWebChannelBase.prototype.connect = function(\n    channelPath, opt_extraParams, opt_oldSessionId, opt_oldArrayId) {\n  this.channelDebug_.debug('connect()');\n\n  requestStats.notifyStatEvent(requestStats.Stat.CONNECT_ATTEMPT);\n\n  this.path_ = channelPath;\n  this.extraParams_ = opt_extraParams || {};\n\n  // Attach parameters about the previous session if reconnecting.\n  if (opt_oldSessionId && opt_oldArrayId !== undefined) {\n    this.extraParams_['OSID'] = opt_oldSessionId;\n    this.extraParams_['OAID'] = opt_oldArrayId;\n  }\n\n  this.enableStreaming_ = this.allowStreamingMode_;\n  this.connectChannel_();\n};\n\n\n/**\n * Disconnects and closes the channel.\n */\nWebChannelBase.prototype.disconnect = function() {\n  this.channelDebug_.debug('disconnect()');\n\n  this.cancelRequests_();\n\n  if (this.state_ == WebChannelBase.State.OPENED) {\n    var rid = this.nextRid_++;\n    var uri = this.forwardChannelUri_.clone();\n    uri.setParameterValue('SID', this.sid_);\n    uri.setParameterValue('RID', rid);\n    uri.setParameterValue('TYPE', 'terminate');\n\n    // Add the reconnect parameters.\n    this.addAdditionalParams_(uri);\n\n    var request = ChannelRequest.createChannelRequest(\n        this, this.channelDebug_, this.sid_, rid);\n    request.sendCloseRequest(uri);\n  }\n\n  this.onClose_();\n};\n\n\n/**\n * Returns the session id of the channel. Only available after the\n * channel has been opened.\n * @return {string} Session ID.\n */\nWebChannelBase.prototype.getSessionId = function() {\n  return this.sid_;\n};\n\n\n/**\n * Starts the connection.\n * @private\n */\nWebChannelBase.prototype.connectChannel_ = function() {\n  this.channelDebug_.debug('connectChannel_()');\n  this.ensureInState_(WebChannelBase.State.INIT, WebChannelBase.State.CLOSED);\n  this.forwardChannelUri_ =\n      this.getForwardChannelUri(/** @type {string} */ (this.path_));\n  this.ensureForwardChannel_();\n};\n\n\n/**\n * Cancels backchannel request.\n * @private\n */\nWebChannelBase.prototype.cancelBackChannelRequest_ = function() {\n  if (this.backChannelRequest_) {\n    this.clearBpDetectionTimer_();\n    this.backChannelRequest_.cancel();\n    this.backChannelRequest_ = null;\n  }\n};\n\n\n/**\n * Cancels all outstanding requests.\n * @private\n */\nWebChannelBase.prototype.cancelRequests_ = function() {\n  this.cancelBackChannelRequest_();\n\n  if (this.backChannelTimerId_) {\n    goog.global.clearTimeout(this.backChannelTimerId_);\n    this.backChannelTimerId_ = null;\n  }\n\n  this.clearDeadBackchannelTimer_();\n\n  this.forwardChannelRequestPool_.cancel();\n\n  if (this.forwardChannelTimerId_) {\n    this.clearForwardChannelTimer_();\n  }\n};\n\n\n/**\n * Clears the forward channel timer.\n * @private\n */\nWebChannelBase.prototype.clearForwardChannelTimer_ = function() {\n  if (typeof this.forwardChannelTimerId_ === 'number') {\n    goog.global.clearTimeout(this.forwardChannelTimerId_);\n  }\n\n  this.forwardChannelTimerId_ = null;\n};\n\n\n/**\n * Returns the extra HTTP headers to add to all the requests sent to the server.\n *\n * @return {Object} The HTTP headers, or null.\n */\nWebChannelBase.prototype.getExtraHeaders = function() {\n  return this.extraHeaders_;\n};\n\n\n/**\n * Sets extra HTTP headers to add to all the requests sent to the server.\n *\n * @param {Object} extraHeaders The HTTP headers, or null.\n */\nWebChannelBase.prototype.setExtraHeaders = function(extraHeaders) {\n  this.extraHeaders_ = extraHeaders;\n};\n\n\n/**\n * Returns the extra HTTP headers to add to the init requests\n * sent to the server.\n *\n * @return {Object} The HTTP headers, or null.\n */\nWebChannelBase.prototype.getInitHeaders = function() {\n  return this.initHeaders_;\n};\n\n\n/**\n * Sets extra HTTP headers to add to the init requests sent to the server.\n *\n * @param {Object} initHeaders The HTTP headers, or null.\n */\nWebChannelBase.prototype.setInitHeaders = function(initHeaders) {\n  this.initHeaders_ = initHeaders;\n};\n\n\n/**\n * Sets the URL param name to overwrite custom HTTP headers.\n *\n * @param {string} httpHeadersOverwriteParam The URL param name.\n */\nWebChannelBase.prototype.setHttpHeadersOverwriteParam = function(\n    httpHeadersOverwriteParam) {\n  this.httpHeadersOverwriteParam_ = httpHeadersOverwriteParam;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.setHttpSessionIdParam = function(httpSessionIdParam) {\n  this.httpSessionIdParam_ = httpSessionIdParam;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getHttpSessionIdParam = function() {\n  return this.httpSessionIdParam_;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.setHttpSessionId = function(httpSessionId) {\n  this.httpSessionId_ = httpSessionId;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getHttpSessionId = function() {\n  return this.httpSessionId_;\n};\n\n\n/**\n * Sets the throttle for handling onreadystatechange events for the request.\n *\n * @param {number} throttle The throttle in ms.  A value of zero indicates\n *     no throttle.\n */\nWebChannelBase.prototype.setReadyStateChangeThrottle = function(throttle) {\n  this.readyStateChangeThrottleMs_ = throttle;\n};\n\n\n/**\n * Sets whether cross origin requests are supported for the channel.\n *\n * Setting this allows the creation of requests to secondary domains and\n * sends XHRs with the CORS withCredentials bit set to true.\n *\n * In order for cross-origin requests to work, the server will also need to set\n * CORS response headers as per:\n * https://developer.mozilla.org/en-US/docs/HTTP_access_control\n *\n * See {@link goog.net.XhrIo#setWithCredentials}.\n * @param {boolean} supportCrossDomain Whether cross domain XHRs are supported.\n */\nWebChannelBase.prototype.setSupportsCrossDomainXhrs = function(\n    supportCrossDomain) {\n  this.supportsCrossDomainXhrs_ = supportCrossDomain;\n};\n\n\n/**\n * Returns the handler used for channel callback events.\n *\n * @return {WebChannelBase.Handler} The handler.\n */\nWebChannelBase.prototype.getHandler = function() {\n  return this.handler_;\n};\n\n\n/**\n * Sets the handler used for channel callback events.\n * @param {WebChannelBase.Handler} handler The handler to set.\n */\nWebChannelBase.prototype.setHandler = function(handler) {\n  this.handler_ = handler;\n};\n\n\n/**\n * Returns whether the channel allows the use of a subdomain. There may be\n * cases where this isn't allowed.\n * @return {boolean} Whether a host prefix is allowed.\n */\nWebChannelBase.prototype.getAllowHostPrefix = function() {\n  return this.allowHostPrefix_;\n};\n\n\n/**\n * Sets whether the channel allows the use of a subdomain. There may be cases\n * where this isn't allowed, for example, logging in with troutboard where\n * using a subdomain causes Apache to force the user to authenticate twice.\n * @param {boolean} allowHostPrefix Whether a host prefix is allowed.\n */\nWebChannelBase.prototype.setAllowHostPrefix = function(allowHostPrefix) {\n  this.allowHostPrefix_ = allowHostPrefix;\n};\n\n\n/**\n * Returns whether the channel is buffered or not.  This may be\n * queried in the WebChannelBase.okToMakeRequest() callback.\n *\n * @return {boolean} Whether the channel is buffered.\n */\nWebChannelBase.prototype.isBuffered = function() {\n  return !this.enableStreaming_;\n};\n\n\n/**\n * Returns whether streaming mode is allowed. In certain debugging situations,\n * it's useful for the application to have a way to disable streaming mode for a\n * user.\n\n * @return {boolean} Whether streaming mode is allowed.\n */\nWebChannelBase.prototype.getAllowStreamingMode = function() {\n  return this.allowStreamingMode_;\n};\n\n\n/**\n * Sets whether streaming mode is allowed. In certain debugging situations, it's\n * useful for the application to have a way to disable streaming mode for a\n * user.\n * @param {boolean} allowStreamingMode  Whether streaming mode is allowed.\n */\nWebChannelBase.prototype.setAllowStreamingMode = function(allowStreamingMode) {\n  this.allowStreamingMode_ = allowStreamingMode;\n};\n\n\n/**\n * Sends a request to the server. The format of the request is a Map data\n * structure of key/value pairs. These maps are then encoded in a format\n * suitable for the wire and then reconstituted as a Map data structure that\n * the server can process.\n * @param {!Object|!goog.structs.Map} map The map to send.\n * @param {!Object=} opt_context The context associated with the map.\n */\nWebChannelBase.prototype.sendMap = function(map, opt_context) {\n  goog.asserts.assert(\n      this.state_ != WebChannelBase.State.CLOSED,\n      'Invalid operation: sending map when state is closed');\n\n  // We can only send 1000 maps per POST, but typically we should never have\n  // that much to send, so warn if we exceed that (we still send all the maps).\n  if (this.outgoingMaps_.length == WebChannelBase.MAX_MAPS_PER_REQUEST_) {\n    // severe() is temporary so that we get these uploaded and can figure out\n    // what's causing them. Afterwards can change to warning().\n    this.channelDebug_.severe(function() {\n      return 'Already have ' + WebChannelBase.MAX_MAPS_PER_REQUEST_ +\n          ' queued maps upon queueing ' + goog.json.serialize(map);\n    });\n  }\n\n  this.outgoingMaps_.push(\n      new Wire.QueuedMap(this.nextMapId_++, map, opt_context));\n\n  // Messages need be buffered during OPENING to avoid server-side race\n  if (this.state_ == WebChannelBase.State.OPENED) {\n    this.ensureForwardChannel_();\n  }\n};\n\n\n/**\n * When set to true, this changes the behavior of the forward channel so it\n * will not retry requests; it will fail after one network failure, and if\n * there was already one network failure, the request will fail immediately.\n * @param {boolean} failFast  Whether or not to fail fast.\n */\nWebChannelBase.prototype.setFailFast = function(failFast) {\n  this.failFast_ = failFast;\n  this.channelDebug_.info('setFailFast: ' + failFast);\n  if ((this.forwardChannelRequestPool_.hasPendingRequest() ||\n       this.forwardChannelTimerId_) &&\n      this.forwardChannelRetryCount_ > this.getForwardChannelMaxRetries()) {\n    var self = this;\n    this.channelDebug_.info(function() {\n      return 'Retry count ' + self.forwardChannelRetryCount_ +\n          ' > new maxRetries ' + self.getForwardChannelMaxRetries() +\n          '. Fail immediately!';\n    });\n\n    if (!this.forwardChannelRequestPool_.forceComplete(\n            goog.bind(this.onRequestComplete, this))) {\n      // i.e., this.forwardChannelTimerId_\n      this.clearForwardChannelTimer_();\n      // The error code from the last failed request is gone, so just use a\n      // generic one.\n      this.signalError_(WebChannelBase.Error.REQUEST_FAILED);\n    }\n  }\n};\n\n\n/**\n * @return {number} The max number of forward-channel retries, which will be 0\n * in fail-fast mode.\n */\nWebChannelBase.prototype.getForwardChannelMaxRetries = function() {\n  return this.failFast_ ? 0 : this.forwardChannelMaxRetries_;\n};\n\n\n/**\n * Sets the maximum number of attempts to connect to the server for forward\n * channel requests.\n * @param {number} retries The maximum number of attempts.\n */\nWebChannelBase.prototype.setForwardChannelMaxRetries = function(retries) {\n  this.forwardChannelMaxRetries_ = retries;\n};\n\n\n/**\n * Sets the timeout for a forward channel request.\n * @param {number} timeoutMs The timeout in milliseconds.\n */\nWebChannelBase.prototype.setForwardChannelRequestTimeout = function(timeoutMs) {\n  this.forwardChannelRequestTimeoutMs_ = timeoutMs;\n};\n\n\n/**\n * @return {number} The max number of back-channel retries, which is a constant.\n */\nWebChannelBase.prototype.getBackChannelMaxRetries = function() {\n  // Back-channel retries is a constant.\n  return WebChannelBase.BACK_CHANNEL_MAX_RETRIES;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.isClosed = function() {\n  return this.state_ == WebChannelBase.State.CLOSED;\n};\n\n\n/**\n * Returns the channel state.\n * @return {WebChannelBase.State} The current state of the channel.\n */\nWebChannelBase.prototype.getState = function() {\n  return this.state_;\n};\n\n\n/**\n * Return the last status code received for a request.\n * @return {number} The last status code received for a request.\n */\nWebChannelBase.prototype.getLastStatusCode = function() {\n  return this.lastStatusCode_;\n};\n\n\n/**\n * @return {number} The last array id received.\n */\nWebChannelBase.prototype.getLastArrayId = function() {\n  return this.lastArrayId_;\n};\n\n\n/**\n * Returns whether there are outstanding requests servicing the channel.\n * @return {boolean} true if there are outstanding requests.\n */\nWebChannelBase.prototype.hasOutstandingRequests = function() {\n  return this.getOutstandingRequests_() != 0;\n};\n\n\n/**\n * Returns the number of outstanding requests.\n * @return {number} The number of outstanding requests to the server.\n * @private\n */\nWebChannelBase.prototype.getOutstandingRequests_ = function() {\n  var count = 0;\n  if (this.backChannelRequest_) {\n    count++;\n  }\n  count += this.forwardChannelRequestPool_.getRequestCount();\n  return count;\n};\n\n\n/**\n * Ensures that a forward channel request is scheduled.\n * @private\n */\nWebChannelBase.prototype.ensureForwardChannel_ = function() {\n  if (this.forwardChannelRequestPool_.isFull()) {\n    // enough connection in process - no need to start a new request\n    return;\n  }\n\n  if (this.forwardChannelTimerId_) {\n    // no need to start a new request - one is already scheduled\n    return;\n  }\n\n  // Use async.run instead of setTimeout(0) to avoid the 1s message delay\n  // from chrome/firefox background tabs\n  this.forwardChannelTimerId_ = true;\n  goog.async.run(this.onStartForwardChannelTimer_, this);\n\n  this.forwardChannelRetryCount_ = 0;\n};\n\n\n/**\n * Schedules a forward-channel retry for the specified request, unless the max\n * retries has been reached.\n * @param {!ChannelRequest} request The failed request to retry.\n * @return {boolean} true iff a retry was scheduled.\n * @private\n */\nWebChannelBase.prototype.maybeRetryForwardChannel_ = function(request) {\n  if (this.forwardChannelRequestPool_.getRequestCount() >=\n      this.forwardChannelRequestPool_.getMaxSize() -\n          (this.forwardChannelTimerId_ ? 1 : 0)) {\n    // Should be impossible to be called in this state.\n    this.channelDebug_.severe('Unexpected retry request is scheduled.');\n    return false;\n  }\n\n  if (this.forwardChannelTimerId_) {\n    this.channelDebug_.debug(\n        'Use the retry request that is already scheduled.');\n    this.outgoingMaps_ =\n        request.getPendingMessages().concat(this.outgoingMaps_);\n    return true;\n  }\n\n  // No retry for open_() and fail-fast\n  if (this.state_ == WebChannelBase.State.INIT ||\n      this.state_ == WebChannelBase.State.OPENING ||\n      (this.forwardChannelRetryCount_ >= this.getForwardChannelMaxRetries())) {\n    return false;\n  }\n\n  this.channelDebug_.debug('Going to retry POST');\n\n  this.forwardChannelTimerId_ = requestStats.setTimeout(\n      goog.bind(this.onStartForwardChannelTimer_, this, request),\n      this.getRetryTime_(this.forwardChannelRetryCount_));\n  this.forwardChannelRetryCount_++;\n  return true;\n};\n\n\n/**\n * Timer callback for ensureForwardChannel\n * @param {ChannelRequest=} opt_retryRequest A failed request\n * to retry.\n * @private\n */\nWebChannelBase.prototype.onStartForwardChannelTimer_ = function(\n    opt_retryRequest) {\n  // null is possible if scheduled with async.run\n  if (this.forwardChannelTimerId_) {\n    this.forwardChannelTimerId_ = null;\n    this.startForwardChannel_(opt_retryRequest);\n  }\n};\n\n\n/**\n * Begins a new forward channel operation to the server.\n * @param {ChannelRequest=} opt_retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.startForwardChannel_ = function(opt_retryRequest) {\n  this.channelDebug_.debug('startForwardChannel_');\n  if (!this.okToMakeRequest_()) {\n    return;  // channel is cancelled\n  } else if (this.state_ == WebChannelBase.State.INIT) {\n    if (opt_retryRequest) {\n      this.channelDebug_.severe('Not supposed to retry the open');\n      return;\n    }\n    this.open_();\n    this.state_ = WebChannelBase.State.OPENING;\n  } else if (this.state_ == WebChannelBase.State.OPENED) {\n    if (opt_retryRequest) {\n      this.makeForwardChannelRequest_(opt_retryRequest);\n      return;\n    }\n\n    if (this.outgoingMaps_.length == 0) {\n      this.channelDebug_.debug(\n          'startForwardChannel_ returned: ' +\n          'nothing to send');\n      // no need to start a new forward channel request\n      return;\n    }\n\n    if (this.forwardChannelRequestPool_.isFull()) {\n      // Should be impossible to be called in this state.\n      this.channelDebug_.severe(\n          'startForwardChannel_ returned: ' +\n          'connection already in progress');\n      return;\n    }\n\n    this.makeForwardChannelRequest_();\n    this.channelDebug_.debug('startForwardChannel_ finished, sent request');\n  }\n};\n\n\n/**\n * Establishes a new channel session with the server.\n * @private\n */\nWebChannelBase.prototype.open_ = function() {\n  this.channelDebug_.debug('open_()');\n  this.nextRid_ = Math.floor(Math.random() * 100000);\n\n  var rid = this.nextRid_++;\n  var request =\n      ChannelRequest.createChannelRequest(this, this.channelDebug_, '', rid);\n\n  // mix the init headers\n  var extraHeaders = this.extraHeaders_;\n  if (this.initHeaders_) {\n    if (extraHeaders) {\n      extraHeaders = goog.object.clone(extraHeaders);\n      goog.object.extend(extraHeaders, this.initHeaders_);\n    } else {\n      extraHeaders = this.initHeaders_;\n    }\n  }\n\n  if (this.httpHeadersOverwriteParam_ === null) {\n    request.setExtraHeaders(extraHeaders);\n  }\n\n  var requestText = this.dequeueOutgoingMaps_(\n      request,\n      this.fastHandshake_ ? this.getMaxNumMessagesForFastHandshake_() :\n                            WebChannelBase.MAX_MAPS_PER_REQUEST_);\n\n  var uri = this.forwardChannelUri_.clone();\n  uri.setParameterValue('RID', rid);\n\n  if (this.clientVersion_ > 0) {\n    uri.setParameterValue('CVER', this.clientVersion_);\n  }\n\n  // http-session-id to be generated as the response\n  if (this.getHttpSessionIdParam()) {\n    uri.setParameterValue(\n        WebChannel.X_HTTP_SESSION_ID, this.getHttpSessionIdParam());\n  }\n\n  // Add the reconnect parameters.\n  this.addAdditionalParams_(uri);\n\n  if (this.httpHeadersOverwriteParam_ && extraHeaders) {\n    httpCors.setHttpHeadersWithOverwriteParam(\n        uri, this.httpHeadersOverwriteParam_, extraHeaders);\n  }\n\n  this.forwardChannelRequestPool_.addRequest(request);\n\n  if (this.blockingHandshake_) {\n    uri.setParameterValue('TYPE', 'init');  // default to blocking in future\n  }\n\n  // Check the option and use GET to enable QUIC 0-RTT\n  if (this.fastHandshake_) {\n    uri.setParameterValue('$req', requestText);\n\n    // enable handshake upgrade\n    uri.setParameterValue('SID', 'null');\n    request.setDecodeInitialResponse();\n\n    request.xmlHttpPost(uri, null, true);  // Send as a GET\n  } else {\n    request.xmlHttpPost(uri, requestText, true);\n  }\n};\n\n\n/**\n * @return {number} The number of raw JSON messages to be encoded\n * with the fast-handshake (GET) request, including zero. If messages are not\n * encoded as raw JSON data, return WebChannelBase.MAX_MAPS_PER_REQUEST_\n * @private\n */\nWebChannelBase.prototype.getMaxNumMessagesForFastHandshake_ = function() {\n  var total = 0;\n  for (var i = 0; i < this.outgoingMaps_.length; i++) {\n    var map = this.outgoingMaps_[i];\n    var size = map.getRawDataSize();\n    if (size === undefined) {\n      break;\n    }\n    total += size;\n\n    if (total > WebChannelBase.MAX_CHARS_PER_GET_) {\n      return i;\n    }\n\n    if (total === WebChannelBase.MAX_CHARS_PER_GET_ ||\n        i === this.outgoingMaps_.length - 1) {\n      return i + 1;\n    }\n  }\n\n  return WebChannelBase.MAX_MAPS_PER_REQUEST_;\n};\n\n\n\n/**\n * Makes a forward channel request using XMLHTTP.\n * @param {!ChannelRequest=} opt_retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.makeForwardChannelRequest_ = function(\n    opt_retryRequest) {\n  var rid;\n  if (opt_retryRequest) {\n    rid = opt_retryRequest.getRequestId();  // Reuse the same RID for a retry\n  } else {\n    rid = this.nextRid_++;\n  }\n\n  var uri = this.forwardChannelUri_.clone();\n  uri.setParameterValue('SID', this.sid_);\n  uri.setParameterValue('RID', rid);\n  uri.setParameterValue('AID', this.lastArrayId_);\n  // Add the additional reconnect parameters.\n  this.addAdditionalParams_(uri);\n\n  if (this.httpHeadersOverwriteParam_ && this.extraHeaders_) {\n    httpCors.setHttpHeadersWithOverwriteParam(\n        uri, this.httpHeadersOverwriteParam_, this.extraHeaders_);\n  }\n\n  var request = ChannelRequest.createChannelRequest(\n      this, this.channelDebug_, this.sid_, rid,\n      this.forwardChannelRetryCount_ + 1);\n\n  if (this.httpHeadersOverwriteParam_ === null) {\n    request.setExtraHeaders(this.extraHeaders_);\n  }\n\n  var requestText;\n  if (opt_retryRequest) {\n    this.requeuePendingMaps_(opt_retryRequest);\n  }\n  requestText =\n      this.dequeueOutgoingMaps_(request, WebChannelBase.MAX_MAPS_PER_REQUEST_);\n\n  // Randomize from 50%-100% of the forward channel timeout to avoid\n  // a big hit if servers happen to die at once.\n  request.setTimeout(\n      Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50) +\n      Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50 * Math.random()));\n  this.forwardChannelRequestPool_.addRequest(request);\n  request.xmlHttpPost(uri, requestText, true);\n};\n\n\n/**\n * Adds the additional parameters from the handler to the given URI.\n * @param {!goog.Uri} uri The URI to add the parameters to.\n * @private\n */\nWebChannelBase.prototype.addAdditionalParams_ = function(uri) {\n  // Add the additional reconnect parameters as needed.\n  if (this.handler_) {\n    var params = this.handler_.getAdditionalParams(this);\n    if (params) {\n      goog.structs.forEach(params, function(value, key, coll) {\n        uri.setParameterValue(key, value);\n      });\n    }\n  }\n};\n\n\n/**\n * Returns the request text from the outgoing maps and resets it.\n * @param {!ChannelRequest} request The new request for sending the messages.\n * @param {number} maxNum The maximum number of messages to be encoded\n * @return {string} The encoded request text created from all the currently\n *                  queued outgoing maps.\n * @private\n */\nWebChannelBase.prototype.dequeueOutgoingMaps_ = function(request, maxNum) {\n  var count = Math.min(this.outgoingMaps_.length, maxNum);\n\n  var badMapHandler = this.handler_ ?\n      goog.bind(this.handler_.badMapError, this.handler_, this) :\n      null;\n  var result = this.wireCodec_.encodeMessageQueue(\n      this.outgoingMaps_, count, badMapHandler);\n\n  request.setPendingMessages(this.outgoingMaps_.splice(0, count));\n\n  return result;\n};\n\n\n/**\n * Requeues unacknowledged sent arrays for retransmission in the next forward\n * channel request.\n * @param {!ChannelRequest} retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.requeuePendingMaps_ = function(retryRequest) {\n  this.outgoingMaps_ =\n      retryRequest.getPendingMessages().concat(this.outgoingMaps_);\n};\n\n\n/**\n * Ensures there is a backchannel request for receiving data from the server.\n * @private\n */\nWebChannelBase.prototype.ensureBackChannel_ = function() {\n  if (this.backChannelRequest_) {\n    // already have one\n    return;\n  }\n\n  if (this.backChannelTimerId_) {\n    // no need to start a new request - one is already scheduled\n    return;\n  }\n\n  this.backChannelAttemptId_ = 1;\n\n  // Use async.run instead of setTimeout(0) to avoid the 1s message delay\n  // from chrome/firefox background tabs\n  // backChannelTimerId_ stays unset, as with setTimeout(0)\n  goog.async.run(this.onStartBackChannelTimer_, this);\n\n  this.backChannelRetryCount_ = 0;\n};\n\n\n/**\n * Schedules a back-channel retry, unless the max retries has been reached.\n * @return {boolean} true iff a retry was scheduled.\n * @private\n */\nWebChannelBase.prototype.maybeRetryBackChannel_ = function() {\n  if (this.backChannelRequest_ || this.backChannelTimerId_) {\n    // Should be impossible to be called in this state.\n    this.channelDebug_.severe('Request already in progress');\n    return false;\n  }\n\n  if (this.backChannelRetryCount_ >= this.getBackChannelMaxRetries()) {\n    return false;\n  }\n\n  this.channelDebug_.debug('Going to retry GET');\n\n  this.backChannelAttemptId_++;\n  this.backChannelTimerId_ = requestStats.setTimeout(\n      goog.bind(this.onStartBackChannelTimer_, this),\n      this.getRetryTime_(this.backChannelRetryCount_));\n  this.backChannelRetryCount_++;\n  return true;\n};\n\n\n/**\n * Timer callback for ensureBackChannel_.\n * @private\n */\nWebChannelBase.prototype.onStartBackChannelTimer_ = function() {\n  this.backChannelTimerId_ = null;\n  this.startBackChannel_();\n\n  if (!this.detectBufferingProxy_) {\n    return;\n  }\n\n  if (this.bpDetectionDone_) {\n    return;\n  }\n\n  if (this.backChannelRequest_ == null || this.handshakeRttMs_ <= 0) {\n    this.channelDebug_.warning(\n        'Skip bpDetectionTimerId_ ' + this.backChannelRequest_ + ' ' +\n        this.handshakeRttMs_);\n    return;\n  }\n\n  // This goes with each new request until bpDetectionDone_\n  var bpDetectionTimeout = 2 * this.handshakeRttMs_;\n  this.channelDebug_.info('BP detection timer enabled: ' + bpDetectionTimeout);\n\n  this.bpDetectionTimerId_ = requestStats.setTimeout(\n      goog.bind(this.onBpDetectionTimer_, this), bpDetectionTimeout);\n};\n\n\n/**\n * Timer callback for bpDetection.\n * @private\n */\nWebChannelBase.prototype.onBpDetectionTimer_ = function() {\n  if (!this.bpDetectionTimerId_) {\n    this.channelDebug_.warning('Invalid operation.');\n    return;\n  }\n\n  this.bpDetectionTimerId_ = null;\n  this.channelDebug_.info('BP detection timeout reached.');\n\n  goog.asserts.assert(\n      this.backChannelRequest_ != null,\n      'Invalid state: no backchannel request');\n\n  // We wait for extra response payload in addition to just headers to\n  // cancel the timer.\n  if (this.backChannelRequest_.getXhr() != null) {\n    var responseData = this.backChannelRequest_.getXhr().getResponseText();\n    if (responseData) {\n      this.channelDebug_.warning(\n          'Timer should have been cancelled : ' + responseData);\n    }\n  }\n\n  // Enable long-polling\n  this.channelDebug_.info(\n      'Buffering proxy detected and switch to long-polling!');\n  this.enableStreaming_ = false;\n\n  this.bpDetectionDone_ = true;\n\n  // Cancel the request and start a new one immediately\n  this.cancelBackChannelRequest_();\n  this.startBackChannel_();\n};\n\n\n/**\n * Clears the timer for BP detection.\n * @private\n */\nWebChannelBase.prototype.clearBpDetectionTimer_ = function() {\n  if (this.bpDetectionTimerId_ != null) {\n    this.channelDebug_.debug('Cancel the BP detection timer.');\n    goog.global.clearTimeout(this.bpDetectionTimerId_);\n    this.bpDetectionTimerId_ = null;\n  }\n};\n\n\n/**\n * Begins a new back channel operation to the server.\n * @private\n */\nWebChannelBase.prototype.startBackChannel_ = function() {\n  if (!this.okToMakeRequest_()) {\n    // channel is cancelled\n    return;\n  }\n\n  this.channelDebug_.debug('Creating new HttpRequest');\n  this.backChannelRequest_ = ChannelRequest.createChannelRequest(\n      this, this.channelDebug_, this.sid_, 'rpc', this.backChannelAttemptId_);\n\n  if (this.httpHeadersOverwriteParam_ === null) {\n    this.backChannelRequest_.setExtraHeaders(this.extraHeaders_);\n  }\n\n  this.backChannelRequest_.setReadyStateChangeThrottle(\n      this.readyStateChangeThrottleMs_);\n  var uri = this.backChannelUri_.clone();\n  uri.setParameterValue('RID', 'rpc');\n  uri.setParameterValue('SID', this.sid_);\n  uri.setParameterValue('CI', this.enableStreaming_ ? '0' : '1');\n  uri.setParameterValue('AID', this.lastArrayId_);\n\n  // Add the reconnect parameters.\n  this.addAdditionalParams_(uri);\n\n  uri.setParameterValue('TYPE', 'xmlhttp');\n\n  if (this.httpHeadersOverwriteParam_ && this.extraHeaders_) {\n    httpCors.setHttpHeadersWithOverwriteParam(\n        uri, this.httpHeadersOverwriteParam_, this.extraHeaders_);\n  }\n\n  if (this.backChannelRequestTimeoutMs_) {\n    this.backChannelRequest_.setTimeout(this.backChannelRequestTimeoutMs_);\n  }\n\n  this.backChannelRequest_.xmlHttpGet(\n      uri, true /* decodeChunks */, this.hostPrefix_);\n\n  this.channelDebug_.debug('New Request created');\n};\n\n\n/**\n * Gives the handler a chance to return an error code and stop channel\n * execution. A handler might want to do this to check that the user is still\n * logged in, for example.\n * @private\n * @return {boolean} If it's OK to make a request.\n */\nWebChannelBase.prototype.okToMakeRequest_ = function() {\n  if (this.handler_) {\n    var result = this.handler_.okToMakeRequest(this);\n    if (result != WebChannelBase.Error.OK) {\n      this.channelDebug_.debug(\n          'Handler returned error code from okToMakeRequest');\n      this.signalError_(result);\n      return false;\n    }\n  }\n  return true;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.onFirstByteReceived = function(request, responseText) {\n  if (this.backChannelRequest_ == request && this.detectBufferingProxy_) {\n    if (!this.bpDetectionDone_) {\n      this.channelDebug_.info(\n          'Great, no buffering proxy detected. Bytes received: ' +\n          responseText.length);\n      goog.asserts.assert(\n          this.bpDetectionTimerId_, 'Timer should not have been cancelled.');\n      this.clearBpDetectionTimer_();\n      this.bpDetectionDone_ = true;\n    }\n  }\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.onRequestData = function(request, responseText) {\n  if (this.state_ == WebChannelBase.State.CLOSED ||\n      (this.backChannelRequest_ != request &&\n       !this.forwardChannelRequestPool_.hasRequest(request))) {\n    // either CLOSED or a request we don't know about (perhaps an old request)\n    return;\n  }\n  this.lastStatusCode_ = request.getLastStatusCode();\n\n  // first to check if request has been upgraded to backchannel\n  if (!request.isInitialResponseDecoded() &&\n      this.forwardChannelRequestPool_.hasRequest(request) &&\n      this.state_ == WebChannelBase.State.OPENED) {\n    var response;\n    try {\n      response = this.wireCodec_.decodeMessage(responseText);\n    } catch (ex) {\n      response = null;\n    }\n    if (Array.isArray(response) && response.length == 3) {\n      this.handlePostResponse_(/** @type {!Array<?>} */ (response), request);\n      this.onForwardChannelFlushed_();\n    } else {\n      this.channelDebug_.debug('Bad POST response data returned');\n      this.signalError_(WebChannelBase.Error.BAD_RESPONSE);\n    }\n  } else {\n    if (request.isInitialResponseDecoded() ||\n        this.backChannelRequest_ == request) {\n      this.clearDeadBackchannelTimer_();\n    }\n\n    if (!goog.string.isEmptyOrWhitespace(responseText)) {\n      var response = this.wireCodec_.decodeMessage(responseText);\n      this.onInput_(/** @type {!Array<?>} */ (response), request);\n    }\n  }\n};\n\n\n/**\n * Checks if we need call the flush callback.\n *\n * @private\n */\nWebChannelBase.prototype.onForwardChannelFlushed_ = function() {\n  if (this.forwardChannelRequestPool_.getRequestCount() <= 1) {\n    if (this.forwardChannelFlushedCallback_) {\n      try {\n        this.forwardChannelFlushedCallback_();\n      } catch (ex) {\n        this.channelDebug_.dumpException(\n            ex, 'Exception from forwardChannelFlushedCallback_ ');\n      }\n      // reset\n      this.forwardChannelFlushedCallback_ = undefined;\n    }\n  }\n};\n\n\n/**\n * Handles a POST response from the server.\n * @param {Array<number>} responseValues The key value pairs in\n *     the POST response.\n * @param {!ChannelRequest} forwardReq The forward channel request that\n * triggers this function call.\n * @private\n */\nWebChannelBase.prototype.handlePostResponse_ = function(\n    responseValues, forwardReq) {\n  // The first response value is set to 0 if server is missing backchannel.\n  if (responseValues[0] == 0) {\n    this.handleBackchannelMissing_(forwardReq);\n    return;\n  }\n  this.lastPostResponseArrayId_ = responseValues[1];\n  var outstandingArrays = this.lastPostResponseArrayId_ - this.lastArrayId_;\n  if (0 < outstandingArrays) {\n    var numOutstandingBackchannelBytes = responseValues[2];\n    this.channelDebug_.debug(\n        numOutstandingBackchannelBytes + ' bytes (in ' + outstandingArrays +\n        ' arrays) are outstanding on the BackChannel');\n    if (!this.shouldRetryBackChannel_(numOutstandingBackchannelBytes)) {\n      return;\n    }\n    if (!this.deadBackChannelTimerId_) {\n      // We expect to receive data within 2 RTTs or we retry the backchannel.\n      this.deadBackChannelTimerId_ = requestStats.setTimeout(\n          goog.bind(this.onBackChannelDead_, this),\n          2 * WebChannelBase.RTT_ESTIMATE);\n    }\n  }\n};\n\n\n/**\n * Handles a POST response from the server telling us that it has detected that\n * we have no hanging GET connection.\n * @param {!ChannelRequest} forwardReq The forward channel request that\n * triggers this function call.\n * @private\n */\nWebChannelBase.prototype.handleBackchannelMissing_ = function(forwardReq) {\n  // As long as the back channel was started before the POST was sent,\n  // we should retry the backchannel. We give a slight buffer of RTT_ESTIMATE\n  // so as not to excessively retry the backchannel\n  this.channelDebug_.debug('Server claims our backchannel is missing.');\n  if (this.backChannelTimerId_) {\n    this.channelDebug_.debug('But we are currently starting the request.');\n    return;\n  } else if (!this.backChannelRequest_) {\n    this.channelDebug_.warning('We do not have a BackChannel established');\n  } else if (\n      this.backChannelRequest_.getRequestStartTime() +\n          WebChannelBase.RTT_ESTIMATE <\n      forwardReq.getRequestStartTime()) {\n    this.clearDeadBackchannelTimer_();\n    this.cancelBackChannelRequest_();\n  } else {\n    return;\n  }\n  this.maybeRetryBackChannel_();\n  requestStats.notifyStatEvent(requestStats.Stat.BACKCHANNEL_MISSING);\n};\n\n\n/**\n * Determines whether we should start the process of retrying a possibly\n * dead backchannel.\n * @param {number} outstandingBytes The number of bytes for which the server has\n *     not yet received acknowledgement.\n * @return {boolean} Whether to start the backchannel retry timer.\n * @private\n */\nWebChannelBase.prototype.shouldRetryBackChannel_ = function(outstandingBytes) {\n  // Not too many outstanding bytes, not buffered and not after a retry.\n  return outstandingBytes <\n      WebChannelBase.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF &&\n      !this.isBuffered() && this.backChannelRetryCount_ == 0;\n};\n\n\n/**\n * Decides which host prefix should be used, if any.  If there is a handler,\n * allows the handler to validate a host prefix provided by the server, and\n * optionally override it.\n * @param {?string} serverHostPrefix The host prefix provided by the server.\n * @return {?string} The host prefix to actually use, if any. Will return null\n *     if the use of host prefixes was disabled via setAllowHostPrefix().\n * @override\n */\nWebChannelBase.prototype.correctHostPrefix = function(serverHostPrefix) {\n  if (this.allowHostPrefix_) {\n    if (this.handler_) {\n      return this.handler_.correctHostPrefix(serverHostPrefix);\n    }\n    return serverHostPrefix;\n  }\n  return null;\n};\n\n\n/**\n * Handles the timer that indicates that our backchannel is no longer able to\n * successfully receive data from the server.\n * @private\n */\nWebChannelBase.prototype.onBackChannelDead_ = function() {\n  if (this.deadBackChannelTimerId_ != null) {\n    this.deadBackChannelTimerId_ = null;\n    this.cancelBackChannelRequest_();\n    this.maybeRetryBackChannel_();\n    requestStats.notifyStatEvent(requestStats.Stat.BACKCHANNEL_DEAD);\n  }\n};\n\n\n/**\n * Clears the timer that indicates that our backchannel is no longer able to\n * successfully receive data from the server.\n * @private\n */\nWebChannelBase.prototype.clearDeadBackchannelTimer_ = function() {\n  if (this.deadBackChannelTimerId_ != null) {\n    goog.global.clearTimeout(this.deadBackChannelTimerId_);\n    this.deadBackChannelTimerId_ = null;\n  }\n};\n\n\n/**\n * Returns whether or not the given error/status combination is fatal or not.\n * On fatal errors we immediately close the session rather than retrying the\n * failed request.\n * @param {?ChannelRequest.Error} error The error code for the\n * failed request.\n * @param {number} statusCode The last HTTP status code.\n * @return {boolean} Whether or not the error is fatal.\n * @private\n */\nWebChannelBase.isFatalError_ = function(error, statusCode) {\n  return error == ChannelRequest.Error.UNKNOWN_SESSION_ID ||\n      (error == ChannelRequest.Error.STATUS && statusCode > 0);\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.onRequestComplete = function(request) {\n  this.channelDebug_.debug('Request complete');\n  var type;\n  var pendingMessages = null;\n  if (this.backChannelRequest_ == request) {\n    this.clearDeadBackchannelTimer_();\n    this.clearBpDetectionTimer_();\n    this.backChannelRequest_ = null;\n    type = WebChannelBase.ChannelType_.BACK_CHANNEL;\n  } else if (this.forwardChannelRequestPool_.hasRequest(request)) {\n    pendingMessages = request.getPendingMessages();\n    this.forwardChannelRequestPool_.removeRequest(request);\n    type = WebChannelBase.ChannelType_.FORWARD_CHANNEL;\n  } else {\n    // return if it was an old request from a previous session\n    return;\n  }\n\n  this.lastStatusCode_ = request.getLastStatusCode();\n\n  if (this.state_ == WebChannelBase.State.CLOSED) {\n    return;\n  }\n\n  if (request.getSuccess()) {\n    if (type == WebChannelBase.ChannelType_.FORWARD_CHANNEL) {\n      var size = request.getPostData() ? request.getPostData().length : 0;\n      requestStats.notifyTimingEvent(\n          size, goog.now() - request.getRequestStartTime(),\n          this.forwardChannelRetryCount_);\n      this.ensureForwardChannel_();\n      this.onSuccess_(request);\n    } else {  // i.e., back-channel\n      this.ensureBackChannel_();\n    }\n    return;\n  }\n  // Else unsuccessful. Fall through.\n\n  var lastError = request.getLastError();\n  if (!WebChannelBase.isFatalError_(lastError, this.lastStatusCode_)) {\n    // Maybe retry.\n    var self = this;\n    this.channelDebug_.debug(function() {\n      return 'Maybe retrying, last error: ' +\n          ChannelRequest.errorStringFromCode(lastError, self.lastStatusCode_);\n    });\n    if (type == WebChannelBase.ChannelType_.FORWARD_CHANNEL) {\n      if (this.maybeRetryForwardChannel_(request)) {\n        return;\n      }\n    }\n    if (type == WebChannelBase.ChannelType_.BACK_CHANNEL) {\n      if (this.maybeRetryBackChannel_()) {\n        return;\n      }\n    }\n    // Else exceeded max retries. Fall through.\n    this.channelDebug_.debug('Exceeded max number of retries');\n  } else {\n    // Else fatal error. Fall through and mark the pending maps as failed.\n    this.channelDebug_.debug('Not retrying due to error type');\n  }\n\n\n  // Abort the channel now\n\n  // Record pending messages from the failed request\n  if (pendingMessages && pendingMessages.length > 0) {\n    this.forwardChannelRequestPool_.addPendingMessages(pendingMessages);\n  }\n\n  this.channelDebug_.debug('Error: HTTP request failed');\n  switch (lastError) {\n    case ChannelRequest.Error.NO_DATA:\n      this.signalError_(WebChannelBase.Error.NO_DATA);\n      break;\n    case ChannelRequest.Error.BAD_DATA:\n      this.signalError_(WebChannelBase.Error.BAD_DATA);\n      break;\n    case ChannelRequest.Error.UNKNOWN_SESSION_ID:\n      this.signalError_(WebChannelBase.Error.UNKNOWN_SESSION_ID);\n      break;\n    default:\n      this.signalError_(WebChannelBase.Error.REQUEST_FAILED);\n      break;\n  }\n};\n\n\n/**\n * @param {number} retryCount Number of retries so far.\n * @return {number} Time in ms before firing next retry request.\n * @private\n */\nWebChannelBase.prototype.getRetryTime_ = function(retryCount) {\n  var retryTime = this.baseRetryDelayMs_ +\n      Math.floor(Math.random() * this.retryDelaySeedMs_);\n  if (!this.isActive()) {\n    this.channelDebug_.debug('Inactive channel');\n    retryTime = retryTime * WebChannelBase.INACTIVE_CHANNEL_RETRY_FACTOR;\n  }\n  // Backoff for subsequent retries\n  retryTime *= retryCount;\n  return retryTime;\n};\n\n\n/**\n * @param {number} baseDelayMs The base part of the retry delay, in ms.\n * @param {number} delaySeedMs A random delay between 0 and this is added to\n *     the base part.\n */\nWebChannelBase.prototype.setRetryDelay = function(baseDelayMs, delaySeedMs) {\n  this.baseRetryDelayMs_ = baseDelayMs;\n  this.retryDelaySeedMs_ = delaySeedMs;\n};\n\n\n/**\n * Apply any handshake control headers.\n * @param {!ChannelRequest} request The underlying request object\n * @private\n */\nWebChannelBase.prototype.applyControlHeaders_ = function(request) {\n  var xhr = request.getXhr();\n  if (xhr) {\n    var clientProtocol =\n        xhr.getStreamingResponseHeader(WebChannel.X_CLIENT_WIRE_PROTOCOL);\n    if (clientProtocol) {\n      this.forwardChannelRequestPool_.applyClientProtocol(clientProtocol);\n    }\n\n    if (this.getHttpSessionIdParam()) {\n      var httpSessionIdHeader =\n          xhr.getStreamingResponseHeader(WebChannel.X_HTTP_SESSION_ID);\n      if (httpSessionIdHeader) {\n        this.setHttpSessionId(httpSessionIdHeader);\n        // update the cached uri\n        var httpSessionIdParam = this.getHttpSessionIdParam();\n\n        this.forwardChannelUri_.setParameterValue(\n            /** @type {string} */ (httpSessionIdParam),  // never null\n            httpSessionIdHeader);\n      } else {\n        this.channelDebug_.warning(\n            'Missing X_HTTP_SESSION_ID in the handshake response');\n      }\n    }\n  }\n};\n\n\n/**\n * Processes the data returned by the server.\n * @param {!Array<!Array<?>>} respArray The response array returned\n *     by the server.\n * @param {!ChannelRequest} request The underlying request object\n * @private\n */\nWebChannelBase.prototype.onInput_ = function(respArray, request) {\n  var batch =\n      this.handler_ && this.handler_.channelHandleMultipleArrays ? [] : null;\n  for (var i = 0; i < respArray.length; i++) {\n    var nextArray = respArray[i];\n    this.lastArrayId_ = nextArray[0];\n    nextArray = nextArray[1];\n    if (this.state_ == WebChannelBase.State.OPENING) {\n      if (nextArray[0] == 'c') {\n        this.sid_ = nextArray[1];\n        this.hostPrefix_ = this.correctHostPrefix(nextArray[2]);\n\n        var negotiatedVersion = nextArray[3];\n        if (negotiatedVersion != null) {\n          this.channelVersion_ = negotiatedVersion;\n          this.channelDebug_.info('VER=' + this.channelVersion_);\n        }\n\n        var negotiatedServerVersion = nextArray[4];\n        if (negotiatedServerVersion != null) {\n          this.serverVersion_ = negotiatedServerVersion;\n          this.channelDebug_.info('SVER=' + this.serverVersion_);\n        }\n\n        // CVER=22\n        var serverKeepaliveMs = nextArray[5];\n        if (serverKeepaliveMs != null &&\n            typeof serverKeepaliveMs === 'number' && serverKeepaliveMs > 0) {\n          var timeout = 1.5 * serverKeepaliveMs;\n          this.backChannelRequestTimeoutMs_ = timeout;\n          this.channelDebug_.info('backChannelRequestTimeoutMs_=' + timeout);\n        }\n\n        this.applyControlHeaders_(request);\n\n        this.state_ = WebChannelBase.State.OPENED;\n        if (this.handler_) {\n          this.handler_.channelOpened(this);\n        }\n\n        if (this.detectBufferingProxy_) {\n          this.handshakeRttMs_ = goog.now() - request.getRequestStartTime();\n          this.channelDebug_.info(\n              'Handshake RTT: ' + this.handshakeRttMs_ + 'ms');\n        }\n\n        this.startBackchannelAfterHandshake_(request);\n\n        if (this.outgoingMaps_.length > 0) {\n          this.ensureForwardChannel_();\n        }\n      } else if (nextArray[0] == 'stop' || nextArray[0] == 'close') {\n        // treat close also as an abort\n        this.signalError_(WebChannelBase.Error.STOP);\n      }\n    } else if (this.state_ == WebChannelBase.State.OPENED) {\n      if (nextArray[0] == 'stop' || nextArray[0] == 'close') {\n        if (batch && !goog.array.isEmpty(batch)) {\n          this.handler_.channelHandleMultipleArrays(this, batch);\n          batch.length = 0;\n        }\n        if (nextArray[0] == 'stop') {\n          this.signalError_(WebChannelBase.Error.STOP);\n        } else {\n          this.disconnect();\n        }\n      } else if (nextArray[0] == 'noop') {\n        // ignore - noop to keep connection happy\n      } else {\n        if (batch) {\n          batch.push(nextArray);\n        } else if (this.handler_) {\n          this.handler_.channelHandleArray(this, nextArray);\n        }\n      }\n      // We have received useful data on the back-channel, so clear its retry\n      // count. We do this because back-channels by design do not complete\n      // quickly, so on a flaky connection we could have many fail to complete\n      // fully but still deliver a lot of data before they fail. We don't want\n      // to count such failures towards the retry limit, because we don't want\n      // to give up on a session if we can still receive data.\n      this.backChannelRetryCount_ = 0;\n    }\n  }\n  if (batch && !goog.array.isEmpty(batch)) {\n    this.handler_.channelHandleMultipleArrays(this, batch);\n  }\n};\n\n\n/**\n * Starts the backchannel after the handshake.\n *\n * @param {!ChannelRequest} request The underlying request object\n * @private\n */\nWebChannelBase.prototype.startBackchannelAfterHandshake_ = function(request) {\n  this.backChannelUri_ = this.getBackChannelUri(\n      this.hostPrefix_, /** @type {string} */ (this.path_));\n\n  if (request.isInitialResponseDecoded()) {\n    this.channelDebug_.debug('Upgrade the handshake request to a backchannel.');\n    this.forwardChannelRequestPool_.removeRequest(request);\n    request.resetTimeout(this.backChannelRequestTimeoutMs_);\n    this.backChannelRequest_ = request;\n  } else {\n    this.ensureBackChannel_();\n  }\n};\n\n\n/**\n * Helper to ensure the channel is in the expected state.\n * @param {...number} var_args The channel must be in one of the indicated\n *     states.\n * @private\n */\nWebChannelBase.prototype.ensureInState_ = function(var_args) {\n  goog.asserts.assert(\n      goog.array.contains(arguments, this.state_),\n      'Unexpected channel state: %s', this.state_);\n};\n\n\n/**\n * Signals an error has occurred.\n * @param {WebChannelBase.Error} error The error code for the failure.\n * @private\n */\nWebChannelBase.prototype.signalError_ = function(error) {\n  this.channelDebug_.info('Error code ' + error);\n  if (error == WebChannelBase.Error.REQUEST_FAILED) {\n    // Create a separate Internet connection to check\n    // if it's a server error or user's network error.\n    var imageUri = null;\n    if (this.handler_) {\n      imageUri = this.handler_.getNetworkTestImageUri(this);\n    }\n    netUtils.testNetwork(goog.bind(this.testNetworkCallback_, this), imageUri);\n  } else {\n    requestStats.notifyStatEvent(requestStats.Stat.ERROR_OTHER);\n  }\n  this.onError_(error);\n};\n\n\n/**\n * Callback for netUtils.testNetwork during error handling.\n * @param {boolean} networkUp Whether the network is up.\n * @private\n */\nWebChannelBase.prototype.testNetworkCallback_ = function(networkUp) {\n  if (networkUp) {\n    this.channelDebug_.info('Successfully pinged google.com');\n    requestStats.notifyStatEvent(requestStats.Stat.ERROR_OTHER);\n  } else {\n    this.channelDebug_.info('Failed to ping google.com');\n    requestStats.notifyStatEvent(requestStats.Stat.ERROR_NETWORK);\n    // Do not call onError_ again to eliminate duplicated Error events.\n  }\n};\n\n\n/**\n * Called when messages have been successfully sent from the queue.\n * @param {!ChannelRequest} request The request object\n * @private\n */\nWebChannelBase.prototype.onSuccess_ = function(request) {\n  if (this.handler_) {\n    this.handler_.channelSuccess(this, request);\n  }\n};\n\n\n/**\n * Called when we've determined the final error for a channel. It closes the\n * notifiers the handler of the error and closes the channel.\n * @param {WebChannelBase.Error} error  The error code for the failure.\n * @private\n */\nWebChannelBase.prototype.onError_ = function(error) {\n  this.channelDebug_.debug('HttpChannel: error - ' + error);\n  this.state_ = WebChannelBase.State.CLOSED;\n  if (this.handler_) {\n    this.handler_.channelError(this, error);\n  }\n  this.onClose_();\n  this.cancelRequests_();\n};\n\n\n/**\n * Called when the channel has been closed. It notifiers the handler of the\n * event, and reports any pending or undelivered maps.\n * @private\n */\nWebChannelBase.prototype.onClose_ = function() {\n  this.state_ = WebChannelBase.State.CLOSED;\n  this.lastStatusCode_ = -1;\n  if (this.handler_) {\n    var pendingMessages = this.forwardChannelRequestPool_.getPendingMessages();\n\n    if (pendingMessages.length == 0 && this.outgoingMaps_.length == 0) {\n      this.handler_.channelClosed(this);\n    } else {\n      var self = this;\n      this.channelDebug_.debug(function() {\n        return 'Number of undelivered maps' +\n            ', pending: ' + pendingMessages.length +\n            ', outgoing: ' + self.outgoingMaps_.length;\n      });\n\n      this.forwardChannelRequestPool_.clearPendingMessages();\n\n      var copyOfUndeliveredMaps = goog.array.clone(this.outgoingMaps_);\n      this.outgoingMaps_.length = 0;\n\n      this.handler_.channelClosed(this, pendingMessages, copyOfUndeliveredMaps);\n    }\n  }\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getForwardChannelUri = function(path) {\n  var uri = this.createDataUri(null, path);\n  this.channelDebug_.debug('GetForwardChannelUri: ' + uri);\n  return uri;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getConnectionState = function() {\n  return this.connState_;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getBackChannelUri = function(hostPrefix, path) {\n  var uri = this.createDataUri(\n      this.shouldUseSecondaryDomains() ? hostPrefix : null, path);\n  this.channelDebug_.debug('GetBackChannelUri: ' + uri);\n  return uri;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.createDataUri = function(\n    hostPrefix, path, opt_overridePort) {\n  var uri = goog.Uri.parse(path);\n  var uriAbsolute = (uri.getDomain() != '');\n  if (uriAbsolute) {\n    if (hostPrefix) {\n      uri.setDomain(hostPrefix + '.' + uri.getDomain());\n    }\n\n    uri.setPort(opt_overridePort || uri.getPort());\n  } else {\n    var locationPage = goog.global.location;\n    var hostName;\n    if (hostPrefix) {\n      hostName = hostPrefix + '.' + locationPage.hostname;\n    } else {\n      hostName = locationPage.hostname;\n    }\n\n    var port = opt_overridePort || +locationPage.port;\n\n    uri = goog.Uri.create(locationPage.protocol, null, hostName, port, path);\n  }\n\n  if (this.extraParams_) {\n    goog.object.forEach(this.extraParams_, function(value, key) {\n      uri.setParameterValue(key, value);\n    });\n  }\n\n  var param = this.getHttpSessionIdParam();\n  var value = this.getHttpSessionId();\n  if (param && value) {\n    uri.setParameterValue(param, value);\n  }\n\n  // Add the protocol version to the URI.\n  uri.setParameterValue('VER', this.channelVersion_);\n\n  // Add the reconnect parameters.\n  this.addAdditionalParams_(uri);\n\n  return uri;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.createXhrIo = function(hostPrefix) {\n  if (hostPrefix && !this.supportsCrossDomainXhrs_) {\n    throw new Error('Can\\'t create secondary domain capable XhrIo object.');\n  }\n  var xhr = new goog.net.XhrIo(this.xmlHttpFactory_);\n  xhr.setWithCredentials(this.supportsCrossDomainXhrs_);\n  return xhr;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.isActive = function() {\n  return !!this.handler_ && this.handler_.isActive(this);\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.shouldUseSecondaryDomains = function() {\n  return this.supportsCrossDomainXhrs_;\n};\n\n\n/**\n * Sets (overwrites) the forward channel flush callback.\n *\n * @param {function()} callback The callback to be invoked.\n */\nWebChannelBase.prototype.setForwardChannelFlushCallback = function(callback) {\n  this.forwardChannelFlushedCallback_ = callback;\n};\n\n\n/**\n * Abstract base class for the channel handler\n * @constructor\n * @struct\n */\nWebChannelBase.Handler = function() {};\n\n\n/**\n * Callback handler for when a batch of response arrays is received from the\n * server. When null, batched dispatching is disabled.\n * @type {?function(!WebChannelBase, !Array<!Array<?>>)}\n */\nWebChannelBase.Handler.prototype.channelHandleMultipleArrays = null;\n\n\n/**\n * Whether it's okay to make a request to the server. A handler can return\n * false if the channel should fail. For example, if the user has logged out,\n * the handler may want all requests to fail immediately.\n * @param {WebChannelBase} channel The channel.\n * @return {WebChannelBase.Error} An error code. The code should\n * return WebChannelBase.Error.OK to indicate it's okay. Any other\n * error code will cause a failure.\n */\nWebChannelBase.Handler.prototype.okToMakeRequest = function(channel) {\n  return WebChannelBase.Error.OK;\n};\n\n\n/**\n * Indicates the WebChannel has successfully negotiated with the server\n * and can now send and receive data.\n * @param {WebChannelBase} channel The channel.\n */\nWebChannelBase.Handler.prototype.channelOpened = function(channel) {};\n\n\n/**\n * New input is available for the application to process.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {Array<?>} array The data array.\n */\nWebChannelBase.Handler.prototype.channelHandleArray = function(\n    channel, array) {};\n\n\n/**\n * Indicates messages that have been successfully sent on the channel.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {!ChannelRequest} request The request object that contains\n *     the pending messages that have been successfully delivered to the server.\n */\nWebChannelBase.Handler.prototype.channelSuccess = function(channel, request) {};\n\n\n/**\n * Indicates an error occurred on the WebChannel.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {WebChannelBase.Error} error The error code.\n */\nWebChannelBase.Handler.prototype.channelError = function(channel, error) {};\n\n\n/**\n * Indicates the WebChannel is closed. Also notifies about which maps,\n * if any, that may not have been delivered to the server.\n * @param {WebChannelBase} channel The channel.\n * @param {Array<Wire.QueuedMap>=} opt_pendingMaps The\n *     array of pending maps, which may or may not have been delivered to the\n *     server.\n * @param {Array<Wire.QueuedMap>=} opt_undeliveredMaps\n *     The array of undelivered maps, which have definitely not been delivered\n *     to the server.\n */\nWebChannelBase.Handler.prototype.channelClosed = function(\n    channel, opt_pendingMaps, opt_undeliveredMaps) {};\n\n\n/**\n * Gets any parameters that should be added at the time another connection is\n * made to the server.\n * @param {WebChannelBase} channel The channel.\n * @return {!Object} Extra parameter keys and values to add to the requests.\n */\nWebChannelBase.Handler.prototype.getAdditionalParams = function(channel) {\n  return {};\n};\n\n\n/**\n * Gets the URI of an image that can be used to test network connectivity.\n * @param {WebChannelBase} channel The channel.\n * @return {goog.Uri?} A custom URI to load for the network test.\n */\nWebChannelBase.Handler.prototype.getNetworkTestImageUri = function(channel) {\n  return null;\n};\n\n\n/**\n * Gets whether this channel is currently active. This is used to determine the\n * length of time to wait before retrying.\n * @param {WebChannelBase} channel The channel.\n * @return {boolean} Whether the channel is currently active.\n */\nWebChannelBase.Handler.prototype.isActive = function(channel) {\n  return true;\n};\n\n\n/**\n * Called by the channel if enumeration of the map throws an exception.\n * @param {WebChannelBase} channel The channel.\n * @param {Object} map The map that can't be enumerated.\n */\nWebChannelBase.Handler.prototype.badMapError = function(channel, map) {};\n\n\n/**\n * Allows the handler to override a host prefix provided by the server. Will\n * be called whenever the channel has received such a prefix and is considering\n * its use.\n * @param {?string} serverHostPrefix The host prefix provided by the server.\n * @return {?string} The host prefix the client should use.\n */\nWebChannelBase.Handler.prototype.correctHostPrefix = function(\n    serverHostPrefix) {\n  return serverHostPrefix;\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A pool of forward channel requests to enable real-time\n * messaging from the client to server.\n *\n */\n\ngoog.module('goog.labs.net.webChannel.ForwardChannelRequestPool');\n\ngoog.module.declareLegacyNamespace();\n\nvar ChannelRequest = goog.require('goog.labs.net.webChannel.ChannelRequest');\nvar Wire = goog.require('goog.labs.net.webChannel.Wire');\nvar array = goog.require('goog.array');\nvar googString = goog.require('goog.string');\n\n\n/**\n * This class represents the state of all forward channel requests.\n *\n * @param {number=} opt_maxPoolSize The maximum pool size.\n *\n * @struct @constructor @final\n */\nvar ForwardChannelRequestPool = function(opt_maxPoolSize) {\n  /**\n   * The max pool size as configured.\n   *\n   * @private {number}\n   */\n  this.maxPoolSizeConfigured_ =\n      opt_maxPoolSize || ForwardChannelRequestPool.MAX_POOL_SIZE_;\n\n  /**\n   * The current size limit of the request pool. This limit is meant to be\n   * read-only after the channel is fully opened.\n   *\n   * If SPDY or HTTP2 is enabled, set it to the max pool size, which is also\n   * configurable.\n   *\n   * @private {number}\n   */\n  this.maxSize_ = ForwardChannelRequestPool.isSpdyOrHttp2Enabled_() ?\n      this.maxPoolSizeConfigured_ :\n      1;\n\n  /**\n   * The container for all the pending request objects.\n   *\n   * @private {?Set<?ChannelRequest>}\n   */\n  this.requestPool_ = null;\n\n  if (this.maxSize_ > 1) {\n    this.requestPool_ = new Set();\n  }\n\n  /**\n   * The single request object when the pool size is limited to one.\n   *\n   * @private {?ChannelRequest}\n   */\n  this.request_ = null;\n\n  /**\n   * Saved pending messages when the pool is cancelled.\n   *\n   * @private {!Array<Wire.QueuedMap>}\n   */\n  this.pendingMessages_ = [];\n};\n\n\n/**\n * The default size limit of the request pool.\n *\n * @private {number}\n */\nForwardChannelRequestPool.MAX_POOL_SIZE_ = 10;\n\n\n/**\n * @return {boolean} True if SPDY or HTTP2 is enabled. Uses chrome-specific APIs\n *     as a fallback and will always return false for other browsers where\n *     PerformanceNavigationTiming is not available.\n * @private\n */\nForwardChannelRequestPool.isSpdyOrHttp2Enabled_ = function() {\n  if (goog.global.PerformanceNavigationTiming) {\n    var entrys = /** @type {!Array<!PerformanceNavigationTiming>} */ (\n        goog.global.performance.getEntriesByType('navigation'));\n    return entrys.length > 0 &&\n        (entrys[0].nextHopProtocol == 'hq' ||\n         entrys[0].nextHopProtocol == 'h2');\n  }\n  return !!(\n      goog.global.chrome && goog.global.chrome.loadTimes &&\n      goog.global.chrome.loadTimes() &&\n      goog.global.chrome.loadTimes().wasFetchedViaSpdy);\n};\n\n\n/**\n * Once we know the client protocol (from the handshake), check if we need\n * enable the request pool accordingly. This is more robust than using\n * browser-internal APIs (specific to Chrome).\n *\n * @param {string} clientProtocol The client protocol\n */\nForwardChannelRequestPool.prototype.applyClientProtocol = function(\n    clientProtocol) {\n  if (this.requestPool_) {\n    return;\n  }\n\n  if (googString.contains(clientProtocol, 'spdy') ||\n      googString.contains(clientProtocol, 'quic') ||\n      googString.contains(clientProtocol, 'h2')) {\n    this.maxSize_ = this.maxPoolSizeConfigured_;\n    this.requestPool_ = new Set();\n    if (this.request_) {\n      this.addRequest(this.request_);\n      this.request_ = null;\n    }\n  }\n};\n\n\n/**\n * @return {boolean} True if the pool is full.\n */\nForwardChannelRequestPool.prototype.isFull = function() {\n  if (this.request_) {\n    return true;\n  }\n\n  if (this.requestPool_) {\n    return this.requestPool_.size >= this.maxSize_;\n  }\n\n  return false;\n};\n\n\n/**\n * @return {number} The current size limit.\n */\nForwardChannelRequestPool.prototype.getMaxSize = function() {\n  return this.maxSize_;\n};\n\n\n/**\n * @return {number} The number of pending requests in the pool.\n */\nForwardChannelRequestPool.prototype.getRequestCount = function() {\n  if (this.request_) {\n    return 1;\n  }\n\n  if (this.requestPool_) {\n    return this.requestPool_.size;\n  }\n\n  return 0;\n};\n\n\n/**\n * @param {ChannelRequest} req The channel request.\n * @return {boolean} True if the request is a included inside the pool.\n */\nForwardChannelRequestPool.prototype.hasRequest = function(req) {\n  if (this.request_) {\n    return this.request_ == req;\n  }\n\n  if (this.requestPool_) {\n    return this.requestPool_.has(req);\n  }\n\n  return false;\n};\n\n\n/**\n * Adds a new request to the pool.\n *\n * @param {!ChannelRequest} req The new channel request.\n */\nForwardChannelRequestPool.prototype.addRequest = function(req) {\n  if (this.requestPool_) {\n    this.requestPool_.add(req);\n  } else {\n    this.request_ = req;\n  }\n};\n\n\n/**\n * Removes the given request from the pool.\n *\n * @param {ChannelRequest} req The channel request.\n * @return {boolean} Whether the request has been removed from the pool.\n */\nForwardChannelRequestPool.prototype.removeRequest = function(req) {\n  if (this.request_ && this.request_ == req) {\n    this.request_ = null;\n    return true;\n  }\n\n  if (this.requestPool_ && this.requestPool_.has(req)) {\n    this.requestPool_.delete(req);\n    return true;\n  }\n\n  return false;\n};\n\n\n/**\n * Clears the pool and cancel all the pending requests.\n */\nForwardChannelRequestPool.prototype.cancel = function() {\n  // save any pending messages\n  this.pendingMessages_ = this.getPendingMessages();\n\n  if (this.request_) {\n    this.request_.cancel();\n    this.request_ = null;\n    return;\n  }\n\n  if (this.requestPool_ && this.requestPool_.size !== 0) {\n    for (const val of this.requestPool_.values()) {\n      val.cancel();\n    }\n    this.requestPool_.clear();\n  }\n};\n\n\n/**\n * @return {boolean} Whether there are any pending requests.\n */\nForwardChannelRequestPool.prototype.hasPendingRequest = function() {\n  return (this.request_ != null) ||\n      (this.requestPool_ != null && this.requestPool_.size !== 0);\n};\n\n\n/**\n * @return {!Array<Wire.QueuedMap>} All the pending messages from the pool,\n *     as a new array.\n */\nForwardChannelRequestPool.prototype.getPendingMessages = function() {\n  if (this.request_ != null) {\n    return this.pendingMessages_.concat(this.request_.getPendingMessages());\n  }\n\n  if (this.requestPool_ != null && this.requestPool_.size !== 0) {\n    let result = this.pendingMessages_;\n    for (const val of this.requestPool_.values()) {\n      result = result.concat(val.getPendingMessages());\n    }\n    return result;\n  }\n\n  return array.clone(this.pendingMessages_);\n};\n\n\n/**\n * Records pending messages, e.g. when a request receives a failed response.\n *\n * @param {!Array<Wire.QueuedMap>} messages Pending messages.\n */\nForwardChannelRequestPool.prototype.addPendingMessages = function(messages) {\n  this.pendingMessages_ = this.pendingMessages_.concat(messages);\n};\n\n\n/**\n * Clears any recorded pending messages.\n */\nForwardChannelRequestPool.prototype.clearPendingMessages = function() {\n  this.pendingMessages_.length = 0;\n};\n\n\n/**\n * Cancels all pending requests and force the completion of channel requests.\n *\n * Need go through the standard onRequestComplete logic to expose the max-retry\n * failure in the standard way.\n *\n * @param {function(!ChannelRequest)} onComplete The completion callback.\n * @return {boolean} true if any request has been forced to complete.\n */\nForwardChannelRequestPool.prototype.forceComplete = function(onComplete) {\n  if (this.request_ != null) {\n    this.request_.cancel();\n    onComplete(this.request_);\n    return true;\n  }\n\n  if (this.requestPool_ && this.requestPool_.size !== 0) {\n    for (const val of this.requestPool_.values()) {\n      val.cancel();\n      onComplete(val);\n    }\n    return true;\n  }\n\n  return false;\n};\n\nexports = ForwardChannelRequestPool;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Generics method for collection-like classes and objects.\n *\n *\n * This file contains functions to work with collections. It supports using\n * Map, Set, Array and Object and other classes that implement collection-like\n * methods.\n * @suppress {strictMissingProperties}\n */\n\n\ngoog.provide('goog.structs');\n\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n// We treat an object as a dictionary if it has getKeys or it is an object that\n// isn't arrayLike.\n\n\n/**\n * Returns the number of values in the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {number} The number of values in the collection-like object.\n */\ngoog.structs.getCount = function(col) {\n  if (col.getCount && typeof col.getCount == 'function') {\n    return col.getCount();\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return col.length;\n  }\n  return goog.object.getCount(col);\n};\n\n\n/**\n * Returns the values of the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {!Array<?>} The values in the collection-like object.\n */\ngoog.structs.getValues = function(col) {\n  if (col.getValues && typeof col.getValues == 'function') {\n    return col.getValues();\n  }\n  if (typeof col === 'string') {\n    return col.split('');\n  }\n  if (goog.isArrayLike(col)) {\n    var rv = [];\n    var l = col.length;\n    for (var i = 0; i < l; i++) {\n      rv.push(col[i]);\n    }\n    return rv;\n  }\n  return goog.object.getValues(col);\n};\n\n\n/**\n * Returns the keys of the collection. Some collections have no notion of\n * keys/indexes and this function will return undefined in those cases.\n * @param {Object} col The collection-like object.\n * @return {!Array|undefined} The keys in the collection.\n */\ngoog.structs.getKeys = function(col) {\n  if (col.getKeys && typeof col.getKeys == 'function') {\n    return col.getKeys();\n  }\n  // if we have getValues but no getKeys we know this is a key-less collection\n  if (col.getValues && typeof col.getValues == 'function') {\n    return undefined;\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    var rv = [];\n    var l = col.length;\n    for (var i = 0; i < l; i++) {\n      rv.push(i);\n    }\n    return rv;\n  }\n\n  return goog.object.getKeys(col);\n};\n\n\n/**\n * Whether the collection contains the given value. This is O(n) and uses\n * equals (==) to test the existence.\n * @param {Object} col The collection-like object.\n * @param {*} val The value to check for.\n * @return {boolean} True if the map contains the value.\n */\ngoog.structs.contains = function(col, val) {\n  if (col.contains && typeof col.contains == 'function') {\n    return col.contains(val);\n  }\n  if (col.containsValue && typeof col.containsValue == 'function') {\n    return col.containsValue(val);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.contains(/** @type {!Array<?>} */ (col), val);\n  }\n  return goog.object.containsValue(col, val);\n};\n\n\n/**\n * Whether the collection is empty.\n * @param {Object} col The collection-like object.\n * @return {boolean} True if empty.\n */\ngoog.structs.isEmpty = function(col) {\n  if (col.isEmpty && typeof col.isEmpty == 'function') {\n    return col.isEmpty();\n  }\n\n  // We do not use goog.string.isEmptyOrWhitespace because here we treat the\n  // string as\n  // collection and as such even whitespace matters\n\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.isEmpty(/** @type {!Array<?>} */ (col));\n  }\n  return goog.object.isEmpty(col);\n};\n\n\n/**\n * Removes all the elements from the collection.\n * @param {Object} col The collection-like object.\n */\ngoog.structs.clear = function(col) {\n  // NOTE(arv): This should not contain strings because strings are immutable\n  if (col.clear && typeof col.clear == 'function') {\n    col.clear();\n  } else if (goog.isArrayLike(col)) {\n    goog.array.clear(/** @type {IArrayLike<?>} */ (col));\n  } else {\n    goog.object.clear(col);\n  }\n};\n\n\n/**\n * Calls a function for each value in a collection. The function takes\n * three arguments; the value, the key and the collection.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):?} f The function to call for every value.\n *     This function takes\n *     3 arguments (the value, the key or undefined if the collection has no\n *     notion of keys, and the collection) and the return value is irrelevant.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n *     within `f`.\n * @template T,S\n * @deprecated Use a more specific method, e.g. goog.array.forEach,\n *     goog.object.forEach, or for-of.\n */\ngoog.structs.forEach = function(col, f, opt_obj) {\n  if (col.forEach && typeof col.forEach == 'function') {\n    col.forEach(f, opt_obj);\n  } else if (goog.isArrayLike(col) || typeof col === 'string') {\n    goog.array.forEach(/** @type {!Array<?>} */ (col), f, opt_obj);\n  } else {\n    var keys = goog.structs.getKeys(col);\n    var values = goog.structs.getValues(col);\n    var l = values.length;\n    for (var i = 0; i < l; i++) {\n      f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col);\n    }\n  }\n};\n\n\n/**\n * Calls a function for every value in the collection. When a call returns true,\n * adds the value to a new collection (Array is returned by default).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes\n *     3 arguments (the value, the key or undefined if the collection has no\n *     notion of keys, and the collection) and should return a Boolean. If the\n *     return value is true the value is added to the result collection. If it\n *     is false the value is not included.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n *     within `f`.\n * @return {!Object|!Array<?>} A new collection where the passed values are\n *     present. If col is a key-less collection an array is returned.  If col\n *     has keys and values a plain old JS object is returned.\n * @template T,S\n */\ngoog.structs.filter = function(col, f, opt_obj) {\n  if (typeof col.filter == 'function') {\n    return col.filter(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.filter(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n\n  var rv;\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  if (keys) {\n    rv = {};\n    for (var i = 0; i < l; i++) {\n      if (f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col)) {\n        rv[keys[i]] = values[i];\n      }\n    }\n  } else {\n    // We should not use goog.array.filter here since we want to make sure that\n    // the index is undefined as well as make sure that col is passed to the\n    // function.\n    rv = [];\n    for (var i = 0; i < l; i++) {\n      if (f.call(opt_obj, values[i], undefined, col)) {\n        rv.push(values[i]);\n      }\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Calls a function for every value in the collection and adds the result into a\n * new collection (defaults to creating a new Array).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):V} f The function to call for every value.\n *     This function takes 3 arguments (the value, the key or undefined if the\n *     collection has no notion of keys, and the collection) and should return\n *     something. The result will be used as the value in the new collection.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {!Object<V>|!Array<V>} A new collection with the new values.  If\n *     col is a key-less collection an array is returned.  If col has keys and\n *     values a plain old JS object is returned.\n * @template T,S,V\n */\ngoog.structs.map = function(col, f, opt_obj) {\n  if (typeof col.map == 'function') {\n    return col.map(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.map(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n\n  var rv;\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  if (keys) {\n    rv = {};\n    for (var i = 0; i < l; i++) {\n      rv[keys[i]] = f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col);\n    }\n  } else {\n    // We should not use goog.array.map here since we want to make sure that\n    // the index is undefined as well as make sure that col is passed to the\n    // function.\n    rv = [];\n    for (var i = 0; i < l; i++) {\n      rv[i] = f.call(/** @type {?} */ (opt_obj), values[i], undefined, col);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Calls f for each value in a collection. If any call returns true this returns\n * true (without checking the rest). If all returns false this returns false.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes 3 arguments (the value, the key or undefined\n *     if the collection has no notion of keys, and the collection) and should\n *     return a boolean.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {boolean} True if any value passes the test.\n * @template T,S\n */\ngoog.structs.some = function(col, f, opt_obj) {\n  if (typeof col.some == 'function') {\n    return col.some(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.some(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  for (var i = 0; i < l; i++) {\n    if (f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Calls f for each value in a collection. If all calls return true this return\n * true this returns true. If any returns false this returns false at this point\n *  and does not continue to check the remaining values.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n *     value. This function takes 3 arguments (the value, the key or\n *     undefined if the collection has no notion of keys, and the collection)\n *     and should return a boolean.\n * @param {T=} opt_obj  The object to be used as the value of 'this'\n *     within `f`.\n * @return {boolean} True if all key-value pairs pass the test.\n * @template T,S\n */\ngoog.structs.every = function(col, f, opt_obj) {\n  if (typeof col.every == 'function') {\n    return col.every(f, opt_obj);\n  }\n  if (goog.isArrayLike(col) || typeof col === 'string') {\n    return goog.array.every(/** @type {!Array<?>} */ (col), f, opt_obj);\n  }\n  var keys = goog.structs.getKeys(col);\n  var values = goog.structs.getValues(col);\n  var l = values.length;\n  for (var i = 0; i < l; i++) {\n    if (!f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n      return false;\n    }\n  }\n  return true;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Datastructure: Hash Map.\n *\n *\n * This file contains an implementation of a Map structure. It implements a lot\n * of the methods used in goog.structs so those functions work on hashes. This\n * is best suited for complex key types. For simple keys such as numbers and\n * strings consider using the lighter-weight utilities in goog.object.\n */\n\n\ngoog.provide('goog.structs.Map');\n\ngoog.require('goog.iter.Iterator');\ngoog.require('goog.iter.StopIteration');\n\n\n\n/**\n * Class for Hash Map datastructure.\n * @param {*=} opt_map Map or Object to initialize the map with.\n * @param {...*} var_args If 2 or more arguments are present then they\n *     will be used as key-value pairs.\n * @constructor\n * @template K, V\n * @deprecated This type is misleading: use ES6 Map instead.\n */\ngoog.structs.Map = function(opt_map, var_args) {\n\n  /**\n   * Underlying JS object used to implement the map.\n   * @private {!Object}\n   */\n  this.map_ = {};\n\n  /**\n   * An array of keys. This is necessary for two reasons:\n   *   1. Iterating the keys using for (var key in this.map_) allocates an\n   *      object for every key in IE which is really bad for IE6 GC perf.\n   *   2. Without a side data structure, we would need to escape all the keys\n   *      as that would be the only way we could tell during iteration if the\n   *      key was an internal key or a property of the object.\n   *\n   * This array can contain deleted keys so it's necessary to check the map\n   * as well to see if the key is still in the map (this doesn't require a\n   * memory allocation in IE).\n   * @private {!Array<string>}\n   */\n  this.keys_ = [];\n\n  /**\n   * The number of key value pairs in the map.\n   * @private {number}\n   */\n  this.count_ = 0;\n\n  /**\n   * Version used to detect changes while iterating.\n   * @private {number}\n   */\n  this.version_ = 0;\n\n  var argLength = arguments.length;\n\n  if (argLength > 1) {\n    if (argLength % 2) {\n      throw new Error('Uneven number of arguments');\n    }\n    for (var i = 0; i < argLength; i += 2) {\n      this.set(arguments[i], arguments[i + 1]);\n    }\n  } else if (opt_map) {\n    this.addAll(/** @type {!Object} */ (opt_map));\n  }\n};\n\n\n/**\n * @return {number} The number of key-value pairs in the map.\n */\ngoog.structs.Map.prototype.getCount = function() {\n  return this.count_;\n};\n\n\n/**\n * Returns the values of the map.\n * @return {!Array<V>} The values in the map.\n */\ngoog.structs.Map.prototype.getValues = function() {\n  this.cleanupKeysArray_();\n\n  var rv = [];\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    rv.push(this.map_[key]);\n  }\n  return rv;\n};\n\n\n/**\n * Returns the keys of the map.\n * @return {!Array<string>} Array of string values.\n */\ngoog.structs.Map.prototype.getKeys = function() {\n  this.cleanupKeysArray_();\n  return /** @type {!Array<string>} */ (this.keys_.concat());\n};\n\n\n/**\n * Whether the map contains the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the map contains the key.\n */\ngoog.structs.Map.prototype.containsKey = function(key) {\n  return goog.structs.Map.hasKey_(this.map_, key);\n};\n\n\n/**\n * Whether the map contains the given value. This is O(n).\n * @param {V} val The value to check for.\n * @return {boolean} Whether the map contains the value.\n */\ngoog.structs.Map.prototype.containsValue = function(val) {\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {\n      return true;\n    }\n  }\n  return false;\n};\n\n\n/**\n * Whether this map is equal to the argument map.\n * @param {goog.structs.Map} otherMap The map against which to test equality.\n * @param {function(V, V): boolean=} opt_equalityFn Optional equality function\n *     to test equality of values. If not specified, this will test whether\n *     the values contained in each map are identical objects.\n * @return {boolean} Whether the maps are equal.\n */\ngoog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {\n  if (this === otherMap) {\n    return true;\n  }\n\n  if (this.count_ != otherMap.getCount()) {\n    return false;\n  }\n\n  var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;\n\n  this.cleanupKeysArray_();\n  for (var key, i = 0; key = this.keys_[i]; i++) {\n    if (!equalityFn(this.get(key), otherMap.get(key))) {\n      return false;\n    }\n  }\n\n  return true;\n};\n\n\n/**\n * Default equality test for values.\n * @param {*} a The first value.\n * @param {*} b The second value.\n * @return {boolean} Whether a and b reference the same object.\n */\ngoog.structs.Map.defaultEquals = function(a, b) {\n  return a === b;\n};\n\n\n/**\n * @return {boolean} Whether the map is empty.\n */\ngoog.structs.Map.prototype.isEmpty = function() {\n  return this.count_ == 0;\n};\n\n\n/**\n * Removes all key-value pairs from the map.\n */\ngoog.structs.Map.prototype.clear = function() {\n  this.map_ = {};\n  this.keys_.length = 0;\n  this.count_ = 0;\n  this.version_ = 0;\n};\n\n\n/**\n * Removes a key-value pair based on the key. This is O(logN) amortized due to\n * updating the keys array whenever the count becomes half the size of the keys\n * in the keys array.\n * @param {*} key  The key to remove.\n * @return {boolean} Whether object was removed.\n */\ngoog.structs.Map.prototype.remove = function(key) {\n  if (goog.structs.Map.hasKey_(this.map_, key)) {\n    delete this.map_[key];\n    this.count_--;\n    this.version_++;\n\n    // clean up the keys array if the threshold is hit\n    if (this.keys_.length > 2 * this.count_) {\n      this.cleanupKeysArray_();\n    }\n\n    return true;\n  }\n  return false;\n};\n\n\n/**\n * Cleans up the temp keys array by removing entries that are no longer in the\n * map.\n * @private\n */\ngoog.structs.Map.prototype.cleanupKeysArray_ = function() {\n  if (this.count_ != this.keys_.length) {\n    // First remove keys that are no longer in the map.\n    var srcIndex = 0;\n    var destIndex = 0;\n    while (srcIndex < this.keys_.length) {\n      var key = this.keys_[srcIndex];\n      if (goog.structs.Map.hasKey_(this.map_, key)) {\n        this.keys_[destIndex++] = key;\n      }\n      srcIndex++;\n    }\n    this.keys_.length = destIndex;\n  }\n\n  if (this.count_ != this.keys_.length) {\n    // If the count still isn't correct, that means we have duplicates. This can\n    // happen when the same key is added and removed multiple times. Now we have\n    // to allocate one extra Object to remove the duplicates. This could have\n    // been done in the first pass, but in the common case, we can avoid\n    // allocating an extra object by only doing this when necessary.\n    var seen = {};\n    var srcIndex = 0;\n    var destIndex = 0;\n    while (srcIndex < this.keys_.length) {\n      var key = this.keys_[srcIndex];\n      if (!(goog.structs.Map.hasKey_(seen, key))) {\n        this.keys_[destIndex++] = key;\n        seen[key] = 1;\n      }\n      srcIndex++;\n    }\n    this.keys_.length = destIndex;\n  }\n};\n\n\n/**\n * Returns the value for the given key.  If the key is not found and the default\n * value is not given this will return `undefined`.\n * @param {*} key The key to get the value for.\n * @param {DEFAULT=} opt_val The value to return if no item is found for the\n *     given key, defaults to undefined.\n * @return {V|DEFAULT} The value for the given key.\n * @template DEFAULT\n */\ngoog.structs.Map.prototype.get = function(key, opt_val) {\n  if (goog.structs.Map.hasKey_(this.map_, key)) {\n    return this.map_[key];\n  }\n  return opt_val;\n};\n\n\n/**\n * Adds a key-value pair to the map.\n * @param {*} key The key.\n * @param {V} value The value to add.\n * @return {*} Some subclasses return a value.\n */\ngoog.structs.Map.prototype.set = function(key, value) {\n  if (!(goog.structs.Map.hasKey_(this.map_, key))) {\n    this.count_++;\n    // TODO(johnlenz): This class lies, it claims to return an array of string\n    // keys, but instead returns the original object used.\n    this.keys_.push(/** @type {?} */ (key));\n    // Only change the version if we add a new key.\n    this.version_++;\n  }\n  this.map_[key] = value;\n};\n\n\n/**\n * Adds multiple key-value pairs from another goog.structs.Map or Object.\n * @param {?Object} map Object containing the data to add.\n */\ngoog.structs.Map.prototype.addAll = function(map) {\n  if (map instanceof goog.structs.Map) {\n    var keys = map.getKeys();\n    for (var i = 0; i < keys.length; i++) {\n      this.set(keys[i], map.get(keys[i]));\n    }\n  } else {\n    for (var key in map) {\n      this.set(key, map[key]);\n    }\n  }\n};\n\n\n/**\n * Calls the given function on each entry in the map.\n * @param {function(this:T, V, K, goog.structs.Map<K,V>)} f\n * @param {T=} opt_obj The value of \"this\" inside f.\n * @template T\n */\ngoog.structs.Map.prototype.forEach = function(f, opt_obj) {\n  var keys = this.getKeys();\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var value = this.get(key);\n    f.call(opt_obj, value, key, this);\n  }\n};\n\n\n/**\n * Clones a map and returns a new map.\n * @return {!goog.structs.Map} A new map with the same key-value pairs.\n */\ngoog.structs.Map.prototype.clone = function() {\n  return new goog.structs.Map(this);\n};\n\n\n/**\n * Returns a new map in which all the keys and values are interchanged\n * (keys become values and values become keys). If multiple keys map to the\n * same value, the chosen transposed value is implementation-dependent.\n *\n * It acts very similarly to {goog.object.transpose(Object)}.\n *\n * @return {!goog.structs.Map} The transposed map.\n */\ngoog.structs.Map.prototype.transpose = function() {\n  var transposed = new goog.structs.Map();\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    var value = this.map_[key];\n    transposed.set(value, key);\n  }\n\n  return transposed;\n};\n\n\n/**\n * @return {!Object} Object representation of the map.\n */\ngoog.structs.Map.prototype.toObject = function() {\n  this.cleanupKeysArray_();\n  var obj = {};\n  for (var i = 0; i < this.keys_.length; i++) {\n    var key = this.keys_[i];\n    obj[key] = this.map_[key];\n  }\n  return obj;\n};\n\n\n/**\n * Returns an iterator that iterates over the keys in the map.  Removal of keys\n * while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the keys in the map.\n */\ngoog.structs.Map.prototype.getKeyIterator = function() {\n  return this.__iterator__(true);\n};\n\n\n/**\n * Returns an iterator that iterates over the values in the map.  Removal of\n * keys while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the values in the map.\n */\ngoog.structs.Map.prototype.getValueIterator = function() {\n  return this.__iterator__(false);\n};\n\n\n/**\n * Returns an iterator that iterates over the values or the keys in the map.\n * This throws an exception if the map was mutated since the iterator was\n * created.\n * @param {boolean=} opt_keys True to iterate over the keys. False to iterate\n *     over the values.  The default value is false.\n * @return {!goog.iter.Iterator} An iterator over the values or keys in the map.\n */\ngoog.structs.Map.prototype.__iterator__ = function(opt_keys) {\n  // Clean up keys to minimize the risk of iterating over dead keys.\n  this.cleanupKeysArray_();\n\n  var i = 0;\n  var version = this.version_;\n  var selfObj = this;\n\n  var newIter = new goog.iter.Iterator;\n  newIter.next = function() {\n    if (version != selfObj.version_) {\n      throw new Error('The map has changed since the iterator was created');\n    }\n    if (i >= selfObj.keys_.length) {\n      throw goog.iter.StopIteration;\n    }\n    var key = selfObj.keys_[i++];\n    return opt_keys ? key : selfObj.map_[key];\n  };\n  return newIter;\n};\n\n\n/**\n * Safe way to test for hasOwnProperty.  It even allows testing for\n * 'hasOwnProperty'.\n * @param {!Object} obj The object to test for presence of the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the object has the key.\n * @private\n */\ngoog.structs.Map.hasKey_ = function(obj, key) {\n  return Object.prototype.hasOwnProperty.call(obj, key);\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple utilities for dealing with URI strings.\n *\n * This is intended to be a lightweight alternative to constructing goog.Uri\n * objects.  Whereas goog.Uri adds several kilobytes to the binary regardless\n * of how much of its functionality you use, this is designed to be a set of\n * mostly-independent utilities so that the compiler includes only what is\n * necessary for the task.  Estimated savings of porting is 5k pre-gzip and\n * 1.5k post-gzip.  To ensure the savings remain, future developers should\n * avoid adding new functionality to existing functions, but instead create\n * new ones and factor out shared code.\n *\n * Many of these utilities have limited functionality, tailored to common\n * cases.  The query parameter utilities assume that the parameter keys are\n * already encoded, since most keys are compile-time alphanumeric strings.  The\n * query parameter mutation utilities also do not tolerate fragment identifiers.\n *\n * By design, these functions can be slower than goog.Uri equivalents.\n * Repeated calls to some of functions may be quadratic in behavior for IE,\n * although the effect is somewhat limited given the 2kb limit.\n *\n * One advantage of the limited functionality here is that this approach is\n * less sensitive to differences in URI encodings than goog.Uri, since these\n * functions operate on strings directly, rather than decoding them and\n * then re-encoding.\n *\n * Uses features of RFC 3986 for parsing/formatting URIs:\n *   http://www.ietf.org/rfc/rfc3986.txt\n */\n\ngoog.provide('goog.uri.utils');\ngoog.provide('goog.uri.utils.ComponentIndex');\ngoog.provide('goog.uri.utils.QueryArray');\ngoog.provide('goog.uri.utils.QueryValue');\ngoog.provide('goog.uri.utils.StandardQueryParam');\n\ngoog.require('goog.asserts');\ngoog.require('goog.string');\n\n\n/**\n * Character codes inlined to avoid object allocations due to charCode.\n * @enum {number}\n * @private\n */\ngoog.uri.utils.CharCode_ = {\n  AMPERSAND: 38,\n  EQUAL: 61,\n  HASH: 35,\n  QUESTION: 63\n};\n\n\n/**\n * Builds a URI string from already-encoded parts.\n *\n * No encoding is performed.  Any component may be omitted as either null or\n * undefined.\n *\n * @param {?string=} opt_scheme The scheme such as 'http'.\n * @param {?string=} opt_userInfo The user name before the '@'.\n * @param {?string=} opt_domain The domain such as 'www.google.com', already\n *     URI-encoded.\n * @param {(string|number|null)=} opt_port The port number.\n * @param {?string=} opt_path The path, already URI-encoded.  If it is not\n *     empty, it must begin with a slash.\n * @param {?string=} opt_queryData The URI-encoded query data.\n * @param {?string=} opt_fragment The URI-encoded fragment identifier.\n * @return {string} The fully combined URI.\n */\ngoog.uri.utils.buildFromEncodedParts = function(\n    opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData,\n    opt_fragment) {\n  var out = '';\n\n  if (opt_scheme) {\n    out += opt_scheme + ':';\n  }\n\n  if (opt_domain) {\n    out += '//';\n\n    if (opt_userInfo) {\n      out += opt_userInfo + '@';\n    }\n\n    out += opt_domain;\n\n    if (opt_port) {\n      out += ':' + opt_port;\n    }\n  }\n\n  if (opt_path) {\n    out += opt_path;\n  }\n\n  if (opt_queryData) {\n    out += '?' + opt_queryData;\n  }\n\n  if (opt_fragment) {\n    out += '#' + opt_fragment;\n  }\n\n  return out;\n};\n\n\n/**\n * A regular expression for breaking a URI into its component parts.\n *\n * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B\n * As the \"first-match-wins\" algorithm is identical to the \"greedy\"\n * disambiguation method used by POSIX regular expressions, it is natural and\n * commonplace to use a regular expression for parsing the potential five\n * components of a URI reference.\n *\n * The following line is the regular expression for breaking-down a\n * well-formed URI reference into its components.\n *\n * <pre>\n * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?\n *  12            3  4          5       6  7        8 9\n * </pre>\n *\n * The numbers in the second line above are only to assist readability; they\n * indicate the reference points for each subexpression (i.e., each paired\n * parenthesis). We refer to the value matched for subexpression <n> as $<n>.\n * For example, matching the above expression to\n * <pre>\n *     http://www.ics.uci.edu/pub/ietf/uri/#Related\n * </pre>\n * results in the following subexpression matches:\n * <pre>\n *    $1 = http:\n *    $2 = http\n *    $3 = //www.ics.uci.edu\n *    $4 = www.ics.uci.edu\n *    $5 = /pub/ietf/uri/\n *    $6 = <undefined>\n *    $7 = <undefined>\n *    $8 = #Related\n *    $9 = Related\n * </pre>\n * where <undefined> indicates that the component is not present, as is the\n * case for the query component in the above example. Therefore, we can\n * determine the value of the five components as\n * <pre>\n *    scheme    = $2\n *    authority = $4\n *    path      = $5\n *    query     = $7\n *    fragment  = $9\n * </pre>\n *\n * The regular expression has been modified slightly to expose the\n * userInfo, domain, and port separately from the authority.\n * The modified version yields\n * <pre>\n *    $1 = http              scheme\n *    $2 = <undefined>       userInfo -\\\n *    $3 = www.ics.uci.edu   domain     | authority\n *    $4 = <undefined>       port     -/\n *    $5 = /pub/ietf/uri/    path\n *    $6 = <undefined>       query without ?\n *    $7 = Related           fragment without #\n * </pre>\n *\n * TODO(user): separate out the authority terminating characters once this\n * file is moved to ES6.\n * @type {!RegExp}\n * @private\n */\ngoog.uri.utils.splitRe_ = new RegExp(\n    '^' +  // Anchor against the entire string.\n    '(?:' +\n    '([^:/?#.]+)' +  // scheme - ignore special characters\n                     // used by other URL parts such as :,\n                     // ?, /, #, and .\n    ':)?' +\n    '(?://' +\n    '(?:([^\\\\\\\\/?#]*)@)?' +  // userInfo\n    '([^\\\\\\\\/?#]*?)' +       // domain\n    '(?::([0-9]+))?' +       // port\n    '(?=[\\\\\\\\/?#]|$)' +      // authority-terminating character.\n    ')?' +\n    '([^?#]+)?' +          // path\n    '(?:\\\\?([^#]*))?' +    // query\n    '(?:#([\\\\s\\\\S]*))?' +  // fragment. Can't use '.*' with 's' flag as Firefox\n                           // doesn't support the flag, and can't use an\n                           // \"everything set\" ([^]) as IE10 doesn't match any\n                           // characters with it.\n    '$');\n\n\n/**\n * The index of each URI component in the return value of goog.uri.utils.split.\n * @enum {number}\n */\ngoog.uri.utils.ComponentIndex = {\n  SCHEME: 1,\n  USER_INFO: 2,\n  DOMAIN: 3,\n  PORT: 4,\n  PATH: 5,\n  QUERY_DATA: 6,\n  FRAGMENT: 7\n};\n\n/**\n * @type {?function(string)}\n * @private\n */\ngoog.uri.utils.urlPackageSupportLoggingHandler_ = null;\n\n/**\n * @param {?function(string)} handler The handler function to call when a URI\n *     with a protocol that is better supported by the Closure URL package is\n *     detected.\n */\ngoog.uri.utils.setUrlPackageSupportLoggingHandler = function(handler) {\n  goog.uri.utils.urlPackageSupportLoggingHandler_ = handler;\n};\n\n/**\n * Splits a URI into its component parts.\n *\n * Each component can be accessed via the component indices; for example:\n * <pre>\n * goog.uri.utils.split(someStr)[goog.uri.utils.ComponentIndex.QUERY_DATA];\n * </pre>\n *\n * @param {string} uri The URI string to examine.\n * @return {!Array<string|undefined>} Each component still URI-encoded.\n *     Each component that is present will contain the encoded value, whereas\n *     components that are not present will be undefined or empty, depending\n *     on the browser's regular expression implementation.  Never null, since\n *     arbitrary strings may still look like path names.\n */\ngoog.uri.utils.split = function(uri) {\n  // See @return comment -- never null.\n  var result = /** @type {!Array<string|undefined>} */ (\n      uri.match(goog.uri.utils.splitRe_));\n  if (goog.uri.utils.urlPackageSupportLoggingHandler_ &&\n      ['http', 'https', 'ws', 'wss',\n       'ftp'].indexOf(result[goog.uri.utils.ComponentIndex.SCHEME]) >= 0) {\n    goog.uri.utils.urlPackageSupportLoggingHandler_(uri);\n  }\n  return result;\n};\n\n\n/**\n * @param {?string} uri A possibly null string.\n * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986\n *     reserved characters will not be removed.\n * @return {?string} The string URI-decoded, or null if uri is null.\n * @private\n */\ngoog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) {\n  if (!uri) {\n    return uri;\n  }\n\n  return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri);\n};\n\n\n/**\n * Gets a URI component by index.\n *\n * It is preferred to use the getPathEncoded() variety of functions ahead,\n * since they are more readable.\n *\n * @param {goog.uri.utils.ComponentIndex} componentIndex The component index.\n * @param {string} uri The URI to examine.\n * @return {?string} The still-encoded component, or null if the component\n *     is not present.\n * @private\n */\ngoog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {\n  // Convert undefined, null, and empty string into null.\n  return goog.uri.utils.split(uri)[componentIndex] || null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The protocol or scheme, or null if none.  Does not\n *     include trailing colons or slashes.\n */\ngoog.uri.utils.getScheme = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.SCHEME, uri);\n};\n\n\n/**\n * Gets the effective scheme for the URL.  If the URL is relative then the\n * scheme is derived from the page's location.\n * @param {string} uri The URI to examine.\n * @return {string} The protocol or scheme, always lower case.\n */\ngoog.uri.utils.getEffectiveScheme = function(uri) {\n  var scheme = goog.uri.utils.getScheme(uri);\n  if (!scheme && goog.global.self && goog.global.self.location) {\n    var protocol = goog.global.self.location.protocol;\n    scheme = protocol.substr(0, protocol.length - 1);\n  }\n  // NOTE: When called from a web worker in Firefox 3.5, location may be null.\n  // All other browsers with web workers support self.location from the worker.\n  return scheme ? scheme.toLowerCase() : '';\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The user name still encoded, or null if none.\n */\ngoog.uri.utils.getUserInfoEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.USER_INFO, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded user info, or null if none.\n */\ngoog.uri.utils.getUserInfo = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getUserInfoEncoded(uri));\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The domain name still encoded, or null if none.\n */\ngoog.uri.utils.getDomainEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.DOMAIN, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded domain, or null if none.\n */\ngoog.uri.utils.getDomain = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?number} The port number, or null if none.\n */\ngoog.uri.utils.getPort = function(uri) {\n  // Coerce to a number.  If the result of getComponentByIndex_ is null or\n  // non-numeric, the number coersion yields NaN.  This will then return\n  // null for all non-numeric cases (though also zero, which isn't a relevant\n  // port number).\n  return Number(\n             goog.uri.utils.getComponentByIndex_(\n                 goog.uri.utils.ComponentIndex.PORT, uri)) ||\n      null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The path still encoded, or null if none. Includes the\n *     leading slash, if any.\n */\ngoog.uri.utils.getPathEncoded = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.PATH, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded path, or null if none.  Includes the leading\n *     slash, if any.\n */\ngoog.uri.utils.getPath = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The query data still encoded, or null if none.  Does not\n *     include the question mark itself.\n */\ngoog.uri.utils.getQueryData = function(uri) {\n  return goog.uri.utils.getComponentByIndex_(\n      goog.uri.utils.ComponentIndex.QUERY_DATA, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The fragment identifier, or null if none.  Does not\n *     include the hash mark itself.\n */\ngoog.uri.utils.getFragmentEncoded = function(uri) {\n  // The hash mark may not appear in any other part of the URL.\n  var hashIndex = uri.indexOf('#');\n  return hashIndex < 0 ? null : uri.substr(hashIndex + 1);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @param {?string} fragment The encoded fragment identifier, or null if none.\n *     Does not include the hash mark itself.\n * @return {string} The URI with the fragment set.\n */\ngoog.uri.utils.setFragmentEncoded = function(uri, fragment) {\n  return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : '');\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded fragment identifier, or null if none.  Does\n *     not include the hash mark.\n */\ngoog.uri.utils.getFragment = function(uri) {\n  return goog.uri.utils.decodeIfPossible_(\n      goog.uri.utils.getFragmentEncoded(uri));\n};\n\n\n/**\n * Extracts everything up to the port of the URI.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getHost = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      pieces[goog.uri.utils.ComponentIndex.SCHEME],\n      pieces[goog.uri.utils.ComponentIndex.USER_INFO],\n      pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n      pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Returns the origin for a given URL.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getOrigin = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      pieces[goog.uri.utils.ComponentIndex.SCHEME], null /* opt_userInfo */,\n      pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n      pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Extracts the path of the URL and everything after.\n * @param {string} uri The URI string.\n * @return {string} The URI, starting at the path and including the query\n *     parameters and fragment identifier.\n */\ngoog.uri.utils.getPathAndAfter = function(uri) {\n  var pieces = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH],\n      pieces[goog.uri.utils.ComponentIndex.QUERY_DATA],\n      pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Gets the URI with the fragment identifier removed.\n * @param {string} uri The URI to examine.\n * @return {string} Everything preceding the hash mark.\n */\ngoog.uri.utils.removeFragment = function(uri) {\n  // The hash mark may not appear in any other part of the URL.\n  var hashIndex = uri.indexOf('#');\n  return hashIndex < 0 ? uri : uri.substr(0, hashIndex);\n};\n\n\n/**\n * Ensures that two URI's have the exact same domain, scheme, and port.\n *\n * Unlike the version in goog.Uri, this checks protocol, and therefore is\n * suitable for checking against the browser's same-origin policy.\n *\n * @param {string} uri1 The first URI.\n * @param {string} uri2 The second URI.\n * @return {boolean} Whether they have the same scheme, domain and port.\n */\ngoog.uri.utils.haveSameDomain = function(uri1, uri2) {\n  var pieces1 = goog.uri.utils.split(uri1);\n  var pieces2 = goog.uri.utils.split(uri2);\n  return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n      pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n      pieces1[goog.uri.utils.ComponentIndex.SCHEME] ==\n      pieces2[goog.uri.utils.ComponentIndex.SCHEME] &&\n      pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n      pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n/**\n * Asserts that there are no fragment or query identifiers, only in uncompiled\n * mode.\n * @param {string} uri The URI to examine.\n * @private\n */\ngoog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {\n  goog.asserts.assert(\n      uri.indexOf('#') < 0 && uri.indexOf('?') < 0,\n      'goog.uri.utils: Fragment or query identifiers are not supported: [%s]',\n      uri);\n};\n\n\n/**\n * Supported query parameter values by the parameter serializing utilities.\n *\n * If a value is null or undefined, the key-value pair is skipped, as an easy\n * way to omit parameters conditionally.  Non-array parameters are converted\n * to a string and URI encoded.  Array values are expanded into multiple\n * &key=value pairs, with each element stringized and URI-encoded.\n *\n * @typedef {*}\n */\ngoog.uri.utils.QueryValue;\n\n\n/**\n * An array representing a set of query parameters with alternating keys\n * and values.\n *\n * Keys are assumed to be URI encoded already and live at even indices.  See\n * goog.uri.utils.QueryValue for details on how parameter values are encoded.\n *\n * Example:\n * <pre>\n * var data = [\n *   // Simple param: ?name=BobBarker\n *   'name', 'BobBarker',\n *   // Conditional param -- may be omitted entirely.\n *   'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,\n *   // Multi-valued param: &house=LosAngeles&house=NewYork&house=null\n *   'house', ['LosAngeles', 'NewYork', null]\n * ];\n * </pre>\n *\n * @typedef {!Array<string|goog.uri.utils.QueryValue>}\n */\ngoog.uri.utils.QueryArray;\n\n\n/**\n * Parses encoded query parameters and calls callback function for every\n * parameter found in the string.\n *\n * Missing value of parameter (e.g. “…&key&…”) is treated as if the value was an\n * empty string.  Keys may be empty strings (e.g. “…&=value&…”) which also means\n * that “…&=&…” and “…&&…” will result in an empty key and value.\n *\n * @param {string} encodedQuery Encoded query string excluding question mark at\n *     the beginning.\n * @param {function(string, string)} callback Function called for every\n *     parameter found in query string.  The first argument (name) will not be\n *     urldecoded (so the function is consistent with buildQueryData), but the\n *     second will.  If the parameter has no value (i.e. “=” was not present)\n *     the second argument (value) will be an empty string.\n */\ngoog.uri.utils.parseQueryData = function(encodedQuery, callback) {\n  if (!encodedQuery) {\n    return;\n  }\n  var pairs = encodedQuery.split('&');\n  for (var i = 0; i < pairs.length; i++) {\n    var indexOfEquals = pairs[i].indexOf('=');\n    var name = null;\n    var value = null;\n    if (indexOfEquals >= 0) {\n      name = pairs[i].substring(0, indexOfEquals);\n      value = pairs[i].substring(indexOfEquals + 1);\n    } else {\n      name = pairs[i];\n    }\n    callback(name, value ? goog.string.urlDecode(value) : '');\n  }\n};\n\n\n/**\n * Split the URI into 3 parts where the [1] is the queryData without a leading\n * '?'. For example, the URI http://foo.com/bar?a=b#abc returns\n * ['http://foo.com/bar','a=b','#abc'].\n * @param {string} uri The URI to parse.\n * @return {!Array<string>} An array representation of uri of length 3 where the\n *     middle value is the queryData without a leading '?'.\n * @private\n */\ngoog.uri.utils.splitQueryData_ = function(uri) {\n  // Find the query data and hash.\n  var hashIndex = uri.indexOf('#');\n  if (hashIndex < 0) {\n    hashIndex = uri.length;\n  }\n  var questionIndex = uri.indexOf('?');\n  var queryData;\n  if (questionIndex < 0 || questionIndex > hashIndex) {\n    questionIndex = hashIndex;\n    queryData = '';\n  } else {\n    queryData = uri.substring(questionIndex + 1, hashIndex);\n  }\n  return [uri.substr(0, questionIndex), queryData, uri.substr(hashIndex)];\n};\n\n\n/**\n * Join an array created by splitQueryData_ back into a URI.\n * @param {!Array<string>} parts A URI in the form generated by splitQueryData_.\n * @return {string} The joined URI.\n * @private\n */\ngoog.uri.utils.joinQueryData_ = function(parts) {\n  return parts[0] + (parts[1] ? '?' + parts[1] : '') + parts[2];\n};\n\n\n/**\n * @param {string} queryData\n * @param {string} newData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryData_ = function(queryData, newData) {\n  if (!newData) {\n    return queryData;\n  }\n  return queryData ? queryData + '&' + newData : newData;\n};\n\n\n/**\n * @param {string} uri\n * @param {string} queryData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryDataToUri_ = function(uri, queryData) {\n  if (!queryData) {\n    return uri;\n  }\n  var parts = goog.uri.utils.splitQueryData_(uri);\n  parts[1] = goog.uri.utils.appendQueryData_(parts[1], queryData);\n  return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Appends key=value pairs to an array, supporting multi-valued objects.\n * @param {*} key The key prefix.\n * @param {goog.uri.utils.QueryValue} value The value to serialize.\n * @param {!Array<string>} pairs The array to which the 'key=value' strings\n *     should be appended.\n * @private\n */\ngoog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {\n  goog.asserts.assertString(key);\n  if (Array.isArray(value)) {\n    // Convince the compiler it's an array.\n    goog.asserts.assertArray(value);\n    for (var j = 0; j < value.length; j++) {\n      // Convert to string explicitly, to short circuit the null and array\n      // logic in this function -- this ensures that null and undefined get\n      // written as literal 'null' and 'undefined', and arrays don't get\n      // expanded out but instead encoded in the default way.\n      goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);\n    }\n  } else if (value != null) {\n    // Skip a top-level null or undefined entirely.\n    pairs.push(\n        key +\n        // Check for empty string. Zero gets encoded into the url as literal\n        // strings.  For empty string, skip the equal sign, to be consistent\n        // with UriBuilder.java.\n        (value === '' ? '' : '=' + goog.string.urlEncode(value)));\n  }\n};\n\n\n/**\n * Builds a query data string from a sequence of alternating keys and values.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!IArrayLike<string|goog.uri.utils.QueryValue>} keysAndValues\n *     Alternating keys and values. See the QueryArray typedef.\n * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {\n  goog.asserts.assert(\n      Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2 == 0,\n      'goog.uri.utils: Key/value lists must be even in length.');\n\n  var params = [];\n  for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {\n    var key = /** @type {string} */ (keysAndValues[i]);\n    goog.uri.utils.appendKeyValuePairs_(key, keysAndValues[i + 1], params);\n  }\n  return params.join('&');\n};\n\n\n/**\n * Builds a query data string from a map.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys\n *     are URI-encoded parameter keys, and the values are arbitrary types\n *     or arrays. Keys with a null value are dropped.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryDataFromMap = function(map) {\n  var params = [];\n  for (var key in map) {\n    goog.uri.utils.appendKeyValuePairs_(key, map[key], params);\n  }\n  return params.join('&');\n};\n\n\n/**\n * Appends URI parameters to an existing URI.\n *\n * The variable arguments may contain alternating keys and values.  Keys are\n * assumed to be already URI encoded.  The values should not be URI-encoded,\n * and will instead be encoded by this function.\n * <pre>\n * appendParams('http://www.foo.com?existing=true',\n *     'key1', 'value1',\n *     'key2', 'value?willBeEncoded',\n *     'key3', ['valueA', 'valueB', 'valueC'],\n *     'key4', null);\n * result: 'http://www.foo.com?existing=true&' +\n *     'key1=value1&' +\n *     'key2=value%3FwillBeEncoded&' +\n *     'key3=valueA&key3=valueB&key3=valueC'\n * </pre>\n *\n * A single call to this function will not exhibit quadratic behavior in IE,\n * whereas multiple repeated calls may, although the effect is limited by\n * fact that URL's generally can't exceed 2kb.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {...(goog.uri.utils.QueryArray|goog.uri.utils.QueryValue)}\n * var_args\n *     An array or argument list conforming to goog.uri.utils.QueryArray.\n * @return {string} The URI with all query parameters added.\n */\ngoog.uri.utils.appendParams = function(uri, var_args) {\n  var queryData = arguments.length == 2 ?\n      goog.uri.utils.buildQueryData(arguments[1], 0) :\n      goog.uri.utils.buildQueryData(arguments, 1);\n  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends query parameters from a map.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {!Object<goog.uri.utils.QueryValue>} map An object where keys are\n *     URI-encoded parameter keys, and the values are arbitrary types or arrays.\n *     Keys with a null value are dropped.\n * @return {string} The new parameters.\n */\ngoog.uri.utils.appendParamsFromMap = function(uri, map) {\n  var queryData = goog.uri.utils.buildQueryDataFromMap(map);\n  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends a single URI parameter.\n *\n * Repeated calls to this can exhibit quadratic behavior in IE6 due to the\n * way string append works, though it should be limited given the 2kb limit.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} key The key, which must already be URI encoded.\n * @param {*=} opt_value The value, which will be stringized and encoded\n *     (assumed not already to be encoded).  If omitted, undefined, or null, the\n *     key will be added as a valueless parameter.\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.appendParam = function(uri, key, opt_value) {\n  var value = (opt_value != null) ? '=' + goog.string.urlEncode(opt_value) : '';\n  return goog.uri.utils.appendQueryDataToUri_(uri, key + value);\n};\n\n\n/**\n * Finds the next instance of a query parameter with the specified name.\n *\n * Does not instantiate any objects.\n *\n * @param {string} uri The URI to search.  May contain a fragment identifier\n *     if opt_hashIndex is specified.\n * @param {number} startIndex The index to begin searching for the key at.  A\n *     match may be found even if this is one character after the ampersand.\n * @param {string} keyEncoded The URI-encoded key.\n * @param {number} hashOrEndIndex Index to stop looking at.  If a hash\n *     mark is present, it should be its index, otherwise it should be the\n *     length of the string.\n * @return {number} The position of the first character in the key's name,\n *     immediately after either a question mark or a dot.\n * @private\n */\ngoog.uri.utils.findParam_ = function(\n    uri, startIndex, keyEncoded, hashOrEndIndex) {\n  var index = startIndex;\n  var keyLength = keyEncoded.length;\n\n  // Search for the key itself and post-filter for surronuding punctuation,\n  // rather than expensively building a regexp.\n  while ((index = uri.indexOf(keyEncoded, index)) >= 0 &&\n         index < hashOrEndIndex) {\n    var precedingChar = uri.charCodeAt(index - 1);\n    // Ensure that the preceding character is '&' or '?'.\n    if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n        precedingChar == goog.uri.utils.CharCode_.QUESTION) {\n      // Ensure the following character is '&', '=', '#', or NaN\n      // (end of string).\n      var followingChar = uri.charCodeAt(index + keyLength);\n      if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL ||\n          followingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n          followingChar == goog.uri.utils.CharCode_.HASH) {\n        return index;\n      }\n    }\n    index += keyLength + 1;\n  }\n\n  return -1;\n};\n\n\n/**\n * Regular expression for finding a hash mark or end of string.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.hashOrEndRe_ = /#|$/;\n\n\n/**\n * Determines if the URI contains a specific key.\n *\n * Performs no object instantiations.\n *\n * @param {string} uri The URI to process.  May contain a fragment\n *     identifier.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {boolean} Whether the key is present.\n */\ngoog.uri.utils.hasParam = function(uri, keyEncoded) {\n  return goog.uri.utils.findParam_(\n             uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;\n};\n\n\n/**\n * Gets the first value of a query parameter.\n * @param {string} uri The URI to process.  May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {?string} The first value of the parameter (URI-decoded), or null\n *     if the parameter is not found.\n */\ngoog.uri.utils.getParamValue = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var foundIndex =\n      goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex);\n\n  if (foundIndex < 0) {\n    return null;\n  } else {\n    var endPosition = uri.indexOf('&', foundIndex);\n    if (endPosition < 0 || endPosition > hashOrEndIndex) {\n      endPosition = hashOrEndIndex;\n    }\n    // Progress forth to the end of the \"key=\" or \"key&\" substring.\n    foundIndex += keyEncoded.length + 1;\n    // Use substr, because it (unlike substring) will return empty string\n    // if foundIndex > endPosition.\n    return goog.string.urlDecode(\n        uri.substr(foundIndex, endPosition - foundIndex));\n  }\n};\n\n\n/**\n * Gets all values of a query parameter.\n * @param {string} uri The URI to process.  May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.  Case-sensitive.\n * @return {!Array<string>} All URI-decoded values with the given key.\n *     If the key is not found, this will have length 0, but never be null.\n */\ngoog.uri.utils.getParamValues = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var position = 0;\n  var foundIndex;\n  var result = [];\n\n  while ((foundIndex = goog.uri.utils.findParam_(\n              uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n    // Find where this parameter ends, either the '&' or the end of the\n    // query parameters.\n    position = uri.indexOf('&', foundIndex);\n    if (position < 0 || position > hashOrEndIndex) {\n      position = hashOrEndIndex;\n    }\n\n    // Progress forth to the end of the \"key=\" or \"key&\" substring.\n    foundIndex += keyEncoded.length + 1;\n    // Use substr, because it (unlike substring) will return empty string\n    // if foundIndex > position.\n    result.push(\n        goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex)));\n  }\n\n  return result;\n};\n\n\n/**\n * Regexp to find trailing question marks and ampersands.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;\n\n\n/**\n * Removes all instances of a query parameter.\n * @param {string} uri The URI to process.  Must not contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.\n * @return {string} The URI with all instances of the parameter removed.\n */\ngoog.uri.utils.removeParam = function(uri, keyEncoded) {\n  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n  var position = 0;\n  var foundIndex;\n  var buffer = [];\n\n  // Look for a query parameter.\n  while ((foundIndex = goog.uri.utils.findParam_(\n              uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n    // Get the portion of the query string up to, but not including, the ?\n    // or & starting the parameter.\n    buffer.push(uri.substring(position, foundIndex));\n    // Progress to immediately after the '&'.  If not found, go to the end.\n    // Avoid including the hash mark.\n    position = Math.min(\n        (uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex, hashOrEndIndex);\n  }\n\n  // Append everything that is remaining.\n  buffer.push(uri.substr(position));\n\n  // Join the buffer, and remove trailing punctuation that remains.\n  return buffer.join('').replace(\n      goog.uri.utils.trailingQueryPunctuationRe_, '$1');\n};\n\n\n/**\n * Replaces all existing definitions of a parameter with a single definition.\n *\n * Repeated calls to this can exhibit quadratic behavior due to the need to\n * find existing instances and reconstruct the string, though it should be\n * limited given the 2kb limit.  Consider using appendParams or setParamsFromMap\n * to update multiple parameters in bulk.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} keyEncoded The key, which must already be URI encoded.\n * @param {*} value The value, which will be stringized and encoded (assumed\n *     not already to be encoded).\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.setParam = function(uri, keyEncoded, value) {\n  return goog.uri.utils.appendParam(\n      goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);\n};\n\n\n/**\n * Effeciently set or remove multiple query parameters in a URI. Order of\n * unchanged parameters will not be modified, all updated parameters will be\n * appended to the end of the query. Params with values of null or undefined are\n * removed.\n *\n * @param {string} uri The URI to process.\n * @param {!Object<string, goog.uri.utils.QueryValue>} params A list of\n *     parameters to update. If null or undefined, the param will be removed.\n * @return {string} An updated URI where the query data has been updated with\n *     the params.\n */\ngoog.uri.utils.setParamsFromMap = function(uri, params) {\n  var parts = goog.uri.utils.splitQueryData_(uri);\n  var queryData = parts[1];\n  var buffer = [];\n  if (queryData) {\n    queryData.split('&').forEach(function(pair) {\n      var indexOfEquals = pair.indexOf('=');\n      var name = indexOfEquals >= 0 ? pair.substr(0, indexOfEquals) : pair;\n      if (!params.hasOwnProperty(name)) {\n        buffer.push(pair);\n      }\n    });\n  }\n  parts[1] = goog.uri.utils.appendQueryData_(\n      buffer.join('&'), goog.uri.utils.buildQueryDataFromMap(params));\n  return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Generates a URI path using a given URI and a path with checks to\n * prevent consecutive \"//\". The baseUri passed in must not contain\n * query or fragment identifiers. The path to append may not contain query or\n * fragment identifiers.\n *\n * @param {string} baseUri URI to use as the base.\n * @param {string} path Path to append.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.appendPath = function(baseUri, path) {\n  goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);\n\n  // Remove any trailing '/'\n  if (goog.string.endsWith(baseUri, '/')) {\n    baseUri = baseUri.substr(0, baseUri.length - 1);\n  }\n  // Remove any leading '/'\n  if (goog.string.startsWith(path, '/')) {\n    path = path.substr(1);\n  }\n  return goog.string.buildString(baseUri, '/', path);\n};\n\n\n/**\n * Replaces the path.\n * @param {string} uri URI to use as the base.\n * @param {string} path New path.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.setPath = function(uri, path) {\n  // Add any missing '/'.\n  if (!goog.string.startsWith(path, '/')) {\n    path = '/' + path;\n  }\n  var parts = goog.uri.utils.split(uri);\n  return goog.uri.utils.buildFromEncodedParts(\n      parts[goog.uri.utils.ComponentIndex.SCHEME],\n      parts[goog.uri.utils.ComponentIndex.USER_INFO],\n      parts[goog.uri.utils.ComponentIndex.DOMAIN],\n      parts[goog.uri.utils.ComponentIndex.PORT], path,\n      parts[goog.uri.utils.ComponentIndex.QUERY_DATA],\n      parts[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Standard supported query parameters.\n * @enum {string}\n */\ngoog.uri.utils.StandardQueryParam = {\n\n  /** Unused parameter for unique-ifying. */\n  RANDOM: 'zx'\n};\n\n\n/**\n * Sets the zx parameter of a URI to a random value.\n * @param {string} uri Any URI.\n * @return {string} That URI with the \"zx\" parameter added or replaced to\n *     contain a random string.\n */\ngoog.uri.utils.makeUnique = function(uri) {\n  return goog.uri.utils.setParam(\n      uri, goog.uri.utils.StandardQueryParam.RANDOM,\n      goog.string.getRandomString());\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class for parsing and formatting URIs.\n *\n * Use goog.Uri(string) to parse a URI string.  Use goog.Uri.create(...) to\n * create a new instance of the goog.Uri object from Uri parts.\n *\n * e.g: <code>var myUri = new goog.Uri(window.location);</code>\n *\n * Implements RFC 3986 for parsing/formatting URIs.\n * http://www.ietf.org/rfc/rfc3986.txt\n *\n * Some changes have been made to the interface (more like .NETs), though the\n * internal representation is now of un-encoded parts, this will change the\n * behavior slightly.\n */\n\ngoog.provide('goog.Uri');\ngoog.provide('goog.Uri.QueryData');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.structs.Map');\ngoog.require('goog.uri.utils');\ngoog.require('goog.uri.utils.ComponentIndex');\ngoog.require('goog.uri.utils.StandardQueryParam');\n\n\n\n/**\n * This class contains setters and getters for the parts of the URI.\n * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part\n * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the\n * decoded path, <code>/foo bar</code>.\n *\n * Reserved characters (see RFC 3986 section 2.2) can be present in\n * their percent-encoded form in scheme, domain, and path URI components and\n * will not be auto-decoded. For example:\n * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will\n * return <code>relative/path%2fto/resource</code>.\n *\n * The constructor accepts an optional unparsed, raw URI string.  The parser\n * is relaxed, so special characters that aren't escaped but don't cause\n * ambiguities will not cause parse failures.\n *\n * All setters return <code>this</code> and so may be chained, a la\n * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.\n *\n * @param {*=} opt_uri Optional string URI to parse\n *        (use goog.Uri.create() to create a URI from parts), or if\n *        a goog.Uri is passed, a clone is created.\n * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore\n * the case of the parameter name.\n *\n * @throws URIError If opt_uri is provided and URI is malformed (that is,\n *     if decodeURIComponent fails on any of the URI components).\n * @constructor\n * @struct\n */\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\n  /**\n   * Scheme such as \"http\".\n   * @private {string}\n   */\n  this.scheme_ = '';\n\n  /**\n   * User credentials in the form \"username:password\".\n   * @private {string}\n   */\n  this.userInfo_ = '';\n\n  /**\n   * Domain part, e.g. \"www.google.com\".\n   * @private {string}\n   */\n  this.domain_ = '';\n\n  /**\n   * Port, e.g. 8080.\n   * @private {?number}\n   */\n  this.port_ = null;\n\n  /**\n   * Path, e.g. \"/tests/img.png\".\n   * @private {string}\n   */\n  this.path_ = '';\n\n  /**\n   * The fragment without the #.\n   * @private {string}\n   */\n  this.fragment_ = '';\n\n  /**\n   * Whether or not this Uri should be treated as Read Only.\n   * @private {boolean}\n   */\n  this.isReadOnly_ = false;\n\n  /**\n   * Whether or not to ignore case when comparing query params.\n   * @private {boolean}\n   */\n  this.ignoreCase_ = false;\n\n  /**\n   * Object representing query data.\n   * @private {!goog.Uri.QueryData}\n   */\n  this.queryData_;\n\n  // Parse in the uri string\n  var m;\n  if (opt_uri instanceof goog.Uri) {\n    this.ignoreCase_ = (opt_ignoreCase !== undefined) ? opt_ignoreCase :\n                                                        opt_uri.getIgnoreCase();\n    this.setScheme(opt_uri.getScheme());\n    this.setUserInfo(opt_uri.getUserInfo());\n    this.setDomain(opt_uri.getDomain());\n    this.setPort(opt_uri.getPort());\n    this.setPath(opt_uri.getPath());\n    this.setQueryData(opt_uri.getQueryData().clone());\n    this.setFragment(opt_uri.getFragment());\n  } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\n    this.ignoreCase_ = !!opt_ignoreCase;\n\n    // Set the parts -- decoding as we do so.\n    // COMPATIBILITY NOTE - In IE, unmatched fields may be empty strings,\n    // whereas in other browsers they will be undefined.\n    this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);\n    this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);\n    this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);\n    this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\n    this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);\n    this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);\n    this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);\n\n  } else {\n    this.ignoreCase_ = !!opt_ignoreCase;\n    this.queryData_ = new goog.Uri.QueryData(null, this.ignoreCase_);\n  }\n};\n\n\n/**\n * Parameter name added to stop caching.\n * @type {string}\n */\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\n\n\n/**\n * @return {string} The string form of the url.\n * @override\n */\ngoog.Uri.prototype.toString = function() {\n  var out = [];\n\n  var scheme = this.getScheme();\n  if (scheme) {\n    out.push(\n        goog.Uri.encodeSpecialChars_(\n            scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n        ':');\n  }\n\n  var domain = this.getDomain();\n  if (domain || scheme == 'file') {\n    out.push('//');\n\n    var userInfo = this.getUserInfo();\n    if (userInfo) {\n      out.push(\n          goog.Uri.encodeSpecialChars_(\n              userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n          '@');\n    }\n\n    out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\n\n    var port = this.getPort();\n    if (port != null) {\n      out.push(':', String(port));\n    }\n  }\n\n  var path = this.getPath();\n  if (path) {\n    if (this.hasDomain() && path.charAt(0) != '/') {\n      out.push('/');\n    }\n    out.push(goog.Uri.encodeSpecialChars_(\n        path,\n        path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ :\n                                goog.Uri.reDisallowedInRelativePath_,\n        true));\n  }\n\n  var query = this.getEncodedQuery();\n  if (query) {\n    out.push('?', query);\n  }\n\n  var fragment = this.getFragment();\n  if (fragment) {\n    out.push(\n        '#',\n        goog.Uri.encodeSpecialChars_(\n            fragment, goog.Uri.reDisallowedInFragment_));\n  }\n  return out.join('');\n};\n\n\n/**\n * Resolves the given relative URI (a goog.Uri object), using the URI\n * represented by this instance as the base URI.\n *\n * There are several kinds of relative URIs:<br>\n * 1. foo - replaces the last part of the path, the whole query and fragment<br>\n * 2. /foo - replaces the path, the query and fragment<br>\n * 3. //foo - replaces everything from the domain on.  foo is a domain name<br>\n * 4. ?foo - replace the query and fragment<br>\n * 5. #foo - replace the fragment only\n *\n * Additionally, if relative URI has a non-empty path, all \"..\" and \".\"\n * segments will be resolved, as described in RFC 3986.\n *\n * @param {!goog.Uri} relativeUri The relative URI to resolve.\n * @return {!goog.Uri} The resolved URI.\n */\ngoog.Uri.prototype.resolve = function(relativeUri) {\n  var absoluteUri = this.clone();\n\n  // we satisfy these conditions by looking for the first part of relativeUri\n  // that is not blank and applying defaults to the rest\n\n  var overridden = relativeUri.hasScheme();\n\n  if (overridden) {\n    absoluteUri.setScheme(relativeUri.getScheme());\n  } else {\n    overridden = relativeUri.hasUserInfo();\n  }\n\n  if (overridden) {\n    absoluteUri.setUserInfo(relativeUri.getUserInfo());\n  } else {\n    overridden = relativeUri.hasDomain();\n  }\n\n  if (overridden) {\n    absoluteUri.setDomain(relativeUri.getDomain());\n  } else {\n    overridden = relativeUri.hasPort();\n  }\n\n  var path = relativeUri.getPath();\n  if (overridden) {\n    absoluteUri.setPort(relativeUri.getPort());\n  } else {\n    overridden = relativeUri.hasPath();\n    if (overridden) {\n      // resolve path properly\n      if (path.charAt(0) != '/') {\n        // path is relative\n        if (this.hasDomain() && !this.hasPath()) {\n          // RFC 3986, section 5.2.3, case 1\n          path = '/' + path;\n        } else {\n          // RFC 3986, section 5.2.3, case 2\n          var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');\n          if (lastSlashIndex != -1) {\n            path = absoluteUri.getPath().substr(0, lastSlashIndex + 1) + path;\n          }\n        }\n      }\n      path = goog.Uri.removeDotSegments(path);\n    }\n  }\n\n  if (overridden) {\n    absoluteUri.setPath(path);\n  } else {\n    overridden = relativeUri.hasQuery();\n  }\n\n  if (overridden) {\n    absoluteUri.setQueryData(relativeUri.getQueryData().clone());\n  } else {\n    overridden = relativeUri.hasFragment();\n  }\n\n  if (overridden) {\n    absoluteUri.setFragment(relativeUri.getFragment());\n  }\n\n  return absoluteUri;\n};\n\n\n/**\n * Clones the URI instance.\n * @return {!goog.Uri} New instance of the URI object.\n */\ngoog.Uri.prototype.clone = function() {\n  return new goog.Uri(this);\n};\n\n\n/**\n * @return {string} The encoded scheme/protocol for the URI.\n */\ngoog.Uri.prototype.getScheme = function() {\n  return this.scheme_;\n};\n\n\n/**\n * Sets the scheme/protocol.\n * @throws URIError If opt_decode is true and newScheme is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newScheme New scheme value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\n  this.enforceReadOnly();\n  this.scheme_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\n\n  // remove an : at the end of the scheme so somebody can pass in\n  // window.location.protocol\n  if (this.scheme_) {\n    this.scheme_ = this.scheme_.replace(/:$/, '');\n  }\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the scheme has been set.\n */\ngoog.Uri.prototype.hasScheme = function() {\n  return !!this.scheme_;\n};\n\n\n/**\n * @return {string} The decoded user info.\n */\ngoog.Uri.prototype.getUserInfo = function() {\n  return this.userInfo_;\n};\n\n\n/**\n * Sets the userInfo.\n * @throws URIError If opt_decode is true and newUserInfo is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newUserInfo New userInfo value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\n  this.enforceReadOnly();\n  this.userInfo_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the user info has been set.\n */\ngoog.Uri.prototype.hasUserInfo = function() {\n  return !!this.userInfo_;\n};\n\n\n/**\n * @return {string} The decoded domain.\n */\ngoog.Uri.prototype.getDomain = function() {\n  return this.domain_;\n};\n\n\n/**\n * Sets the domain.\n * @throws URIError If opt_decode is true and newDomain is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newDomain New domain value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\n  this.enforceReadOnly();\n  this.domain_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the domain has been set.\n */\ngoog.Uri.prototype.hasDomain = function() {\n  return !!this.domain_;\n};\n\n\n/**\n * @return {?number} The port number.\n */\ngoog.Uri.prototype.getPort = function() {\n  return this.port_;\n};\n\n\n/**\n * Sets the port number.\n * @param {*} newPort Port number. Will be explicitly casted to a number.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPort = function(newPort) {\n  this.enforceReadOnly();\n\n  if (newPort) {\n    newPort = Number(newPort);\n    if (isNaN(newPort) || newPort < 0) {\n      throw new Error('Bad port number ' + newPort);\n    }\n    this.port_ = newPort;\n  } else {\n    this.port_ = null;\n  }\n\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the port has been set.\n */\ngoog.Uri.prototype.hasPort = function() {\n  return this.port_ != null;\n};\n\n\n/**\n * @return {string} The decoded path.\n */\ngoog.Uri.prototype.getPath = function() {\n  return this.path_;\n};\n\n\n/**\n * Sets the path.\n * @throws URIError If opt_decode is true and newPath is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newPath New path value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\n  this.enforceReadOnly();\n  this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the path has been set.\n */\ngoog.Uri.prototype.hasPath = function() {\n  return !!this.path_;\n};\n\n\n/**\n * @return {boolean} Whether the query string has been set.\n */\ngoog.Uri.prototype.hasQuery = function() {\n  return this.queryData_.toString() !== '';\n};\n\n\n/**\n * Sets the query data.\n * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n *     Applies only if queryData is a string.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\n  this.enforceReadOnly();\n\n  if (queryData instanceof goog.Uri.QueryData) {\n    this.queryData_ = queryData;\n    this.queryData_.setIgnoreCase(this.ignoreCase_);\n  } else {\n    if (!opt_decode) {\n      // QueryData accepts encoded query string, so encode it if\n      // opt_decode flag is not true.\n      queryData = goog.Uri.encodeSpecialChars_(\n          queryData, goog.Uri.reDisallowedInQuery_);\n    }\n    this.queryData_ = new goog.Uri.QueryData(queryData, this.ignoreCase_);\n  }\n\n  return this;\n};\n\n\n/**\n * Sets the URI query.\n * @param {string} newQuery New query value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\n  return this.setQueryData(newQuery, opt_decode);\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getEncodedQuery = function() {\n  return this.queryData_.toString();\n};\n\n\n/**\n * @return {string} The decoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getDecodedQuery = function() {\n  return this.queryData_.toDecodedString();\n};\n\n\n/**\n * Returns the query data.\n * @return {!goog.Uri.QueryData} QueryData object.\n */\ngoog.Uri.prototype.getQueryData = function() {\n  return this.queryData_;\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n *\n * Warning: This method, unlike other getter methods, returns encoded\n * value, instead of decoded one.\n */\ngoog.Uri.prototype.getQuery = function() {\n  return this.getEncodedQuery();\n};\n\n\n/**\n * Sets the value of the named query parameters, clearing previous values for\n * that key.\n *\n * @param {string} key The parameter to set.\n * @param {*} value The new value. Value does not need to be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValue = function(key, value) {\n  this.enforceReadOnly();\n  this.queryData_.set(key, value);\n  return this;\n};\n\n\n/**\n * Sets the values of the named query parameters, clearing previous values for\n * that key.  Not new values will currently be moved to the end of the query\n * string.\n *\n * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])\n * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>\n *\n * @param {string} key The parameter to set.\n * @param {*} values The new values. If values is a single\n *     string then it will be treated as the sole value. Values do not need to\n *     be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValues = function(key, values) {\n  this.enforceReadOnly();\n\n  if (!Array.isArray(values)) {\n    values = [String(values)];\n  }\n\n  this.queryData_.setValues(key, values);\n\n  return this;\n};\n\n\n/**\n * Returns the value<b>s</b> for a given cgi parameter as a list of decoded\n * query parameter values.\n * @param {string} name The parameter to get values for.\n * @return {!Array<?>} The values for a given cgi parameter as a list of\n *     decoded query parameter values.\n */\ngoog.Uri.prototype.getParameterValues = function(name) {\n  return this.queryData_.getValues(name);\n};\n\n\n/**\n * Returns the first value for a given cgi parameter or undefined if the given\n * parameter name does not appear in the query string.\n * @param {string} paramName Unescaped parameter name.\n * @return {string|undefined} The first value for a given cgi parameter or\n *     undefined if the given parameter name does not appear in the query\n *     string.\n */\ngoog.Uri.prototype.getParameterValue = function(paramName) {\n  return /** @type {string|undefined} */ (this.queryData_.get(paramName));\n};\n\n\n/**\n * @return {string} The URI fragment, not including the #.\n */\ngoog.Uri.prototype.getFragment = function() {\n  return this.fragment_;\n};\n\n\n/**\n * Sets the URI fragment.\n * @throws URIError If opt_decode is true and newFragment is malformed (that is,\n *     if decodeURIComponent fails).\n * @param {string} newFragment New fragment value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\n  this.enforceReadOnly();\n  this.fragment_ =\n      opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI has a fragment set.\n */\ngoog.Uri.prototype.hasFragment = function() {\n  return !!this.fragment_;\n};\n\n\n/**\n * Returns true if this has the same domain as that of uri2.\n * @param {!goog.Uri} uri2 The URI object to compare to.\n * @return {boolean} true if same domain; false otherwise.\n */\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\n  return ((!this.hasDomain() && !uri2.hasDomain()) ||\n          this.getDomain() == uri2.getDomain()) &&\n      ((!this.hasPort() && !uri2.hasPort()) ||\n       this.getPort() == uri2.getPort());\n};\n\n\n/**\n * Adds a random parameter to the Uri.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.makeUnique = function() {\n  this.enforceReadOnly();\n  this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\n\n  return this;\n};\n\n\n/**\n * Removes the named query parameter.\n *\n * @param {string} key The parameter to remove.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.removeParameter = function(key) {\n  this.enforceReadOnly();\n  this.queryData_.remove(key);\n  return this;\n};\n\n\n/**\n * Sets whether Uri is read only. If this goog.Uri is read-only,\n * enforceReadOnly_ will be called at the start of any function that may modify\n * this Uri.\n * @param {boolean} isReadOnly whether this goog.Uri should be read only.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\n  this.isReadOnly_ = isReadOnly;\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI is read only.\n */\ngoog.Uri.prototype.isReadOnly = function() {\n  return this.isReadOnly_;\n};\n\n\n/**\n * Checks if this Uri has been marked as read only, and if so, throws an error.\n * This should be called whenever any modifying function is called.\n */\ngoog.Uri.prototype.enforceReadOnly = function() {\n  if (this.isReadOnly_) {\n    throw new Error('Tried to modify a read-only Uri');\n  }\n};\n\n\n/**\n * Sets whether to ignore case.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\n  this.ignoreCase_ = ignoreCase;\n  if (this.queryData_) {\n    this.queryData_.setIgnoreCase(ignoreCase);\n  }\n  return this;\n};\n\n\n/**\n * @return {boolean} Whether to ignore case.\n */\ngoog.Uri.prototype.getIgnoreCase = function() {\n  return this.ignoreCase_;\n};\n\n\n//==============================================================================\n// Static members\n//==============================================================================\n\n\n/**\n * Creates a uri from the string form.  Basically an alias of new goog.Uri().\n * If a Uri object is passed to parse then it will return a clone of the object.\n *\n * @throws URIError If parsing the URI is malformed. The passed URI components\n *     should all be parseable by decodeURIComponent.\n * @param {*} uri Raw URI string or instance of Uri\n *     object.\n * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter\n * names in #getParameterValue.\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\n  return uri instanceof goog.Uri ? uri.clone() :\n                                   new goog.Uri(uri, opt_ignoreCase);\n};\n\n\n/**\n * Creates a new goog.Uri object from unencoded parts.\n *\n * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.\n * @param {?string=} opt_userInfo username:password.\n * @param {?string=} opt_domain www.google.com.\n * @param {?number=} opt_port 9830.\n * @param {?string=} opt_path /some/path/to/a/file.html.\n * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.\n * @param {?string=} opt_fragment The fragment without the #.\n * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in\n *     #getParameterValue.\n *\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.create = function(\n    opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query,\n    opt_fragment, opt_ignoreCase) {\n  var uri = new goog.Uri(null, opt_ignoreCase);\n\n  // Only set the parts if they are defined and not empty strings.\n  opt_scheme && uri.setScheme(opt_scheme);\n  opt_userInfo && uri.setUserInfo(opt_userInfo);\n  opt_domain && uri.setDomain(opt_domain);\n  opt_port && uri.setPort(opt_port);\n  opt_path && uri.setPath(opt_path);\n  opt_query && uri.setQueryData(opt_query);\n  opt_fragment && uri.setFragment(opt_fragment);\n\n  return uri;\n};\n\n\n/**\n * Resolves a relative Uri against a base Uri, accepting both strings and\n * Uri objects.\n *\n * @param {*} base Base Uri.\n * @param {*} rel Relative Uri.\n * @return {!goog.Uri} Resolved uri.\n */\ngoog.Uri.resolve = function(base, rel) {\n  if (!(base instanceof goog.Uri)) {\n    base = goog.Uri.parse(base);\n  }\n\n  if (!(rel instanceof goog.Uri)) {\n    rel = goog.Uri.parse(rel);\n  }\n\n  return base.resolve(rel);\n};\n\n\n/**\n * Removes dot segments in given path component, as described in\n * RFC 3986, section 5.2.4.\n *\n * @param {string} path A non-empty path component.\n * @return {string} Path component with removed dot segments.\n */\ngoog.Uri.removeDotSegments = function(path) {\n  if (path == '..' || path == '.') {\n    return '';\n\n  } else if (\n      !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) {\n    // This optimization detects uris which do not contain dot-segments,\n    // and as a consequence do not require any processing.\n    return path;\n\n  } else {\n    var leadingSlash = goog.string.startsWith(path, '/');\n    var segments = path.split('/');\n    var out = [];\n\n    for (var pos = 0; pos < segments.length;) {\n      var segment = segments[pos++];\n\n      if (segment == '.') {\n        if (leadingSlash && pos == segments.length) {\n          out.push('');\n        }\n      } else if (segment == '..') {\n        if (out.length > 1 || out.length == 1 && out[0] != '') {\n          out.pop();\n        }\n        if (leadingSlash && pos == segments.length) {\n          out.push('');\n        }\n      } else {\n        out.push(segment);\n        leadingSlash = true;\n      }\n    }\n\n    return out.join('/');\n  }\n};\n\n\n/**\n * Decodes a value or returns the empty string if it isn't defined or empty.\n * @throws URIError If decodeURIComponent fails to decode val.\n * @param {string|undefined} val Value to decode.\n * @param {boolean=} opt_preserveReserved If true, restricted characters will\n *     not be decoded.\n * @return {string} Decoded value.\n * @private\n */\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\n  // Don't use UrlDecode() here because val is not a query parameter.\n  if (!val) {\n    return '';\n  }\n\n  // decodeURI has the same output for '%2f' and '%252f'. We double encode %25\n  // so that we can distinguish between the 2 inputs. This is later undone by\n  // removeDoubleEncoding_.\n  return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) :\n                                decodeURIComponent(val);\n};\n\n\n/**\n * If unescapedPart is non null, then escapes any characters in it that aren't\n * valid characters in a url and also escapes any special characters that\n * appear in extra.\n *\n * @param {*} unescapedPart The string to encode.\n * @param {RegExp} extra A character set of characters in [\\01-\\177].\n * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent\n *     encoding.\n * @return {?string} null iff unescapedPart == null.\n * @private\n */\ngoog.Uri.encodeSpecialChars_ = function(\n    unescapedPart, extra, opt_removeDoubleEncoding) {\n  if (typeof unescapedPart === 'string') {\n    var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\n    if (opt_removeDoubleEncoding) {\n      // encodeURI double-escapes %XX sequences used to represent restricted\n      // characters in some URI components, remove the double escaping here.\n      encoded = goog.Uri.removeDoubleEncoding_(encoded);\n    }\n    return encoded;\n  }\n  return null;\n};\n\n\n/**\n * Converts a character in [\\01-\\177] to its unicode character equivalent.\n * @param {string} ch One character string.\n * @return {string} Encoded string.\n * @private\n */\ngoog.Uri.encodeChar_ = function(ch) {\n  var n = ch.charCodeAt(0);\n  return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);\n};\n\n\n/**\n * Removes double percent-encoding from a string.\n * @param  {string} doubleEncodedString String\n * @return {string} String with double encoding removed.\n * @private\n */\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\n  return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');\n};\n\n\n/**\n * Regular expression for characters that are disallowed in the scheme or\n * userInfo part of the URI.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\/\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in a relative path.\n * Colon is included due to RFC 3986 3.3.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInRelativePath_ = /[\\#\\?:]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in an absolute path.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInAbsolutePath_ = /[\\#\\?]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the query.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInQuery_ = /[\\#\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the fragment.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInFragment_ = /#/g;\n\n\n/**\n * Checks whether two URIs have the same domain.\n * @param {string} uri1String First URI string.\n * @param {string} uri2String Second URI string.\n * @return {boolean} true if the two URIs have the same domain; false otherwise.\n */\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\n  // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.\n  // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.\n  var pieces1 = goog.uri.utils.split(uri1String);\n  var pieces2 = goog.uri.utils.split(uri2String);\n  return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n      pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n      pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n      pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n\n/**\n * Class used to represent URI query parameters.  It is essentially a hash of\n * name-value pairs, though a name can be present more than once.\n *\n * Has the same interface as the collections in goog.structs.\n *\n * @param {?string=} opt_query Optional encoded query string to parse into\n *     the object.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @constructor\n * @struct\n * @final\n */\ngoog.Uri.QueryData = function(opt_query, opt_ignoreCase) {\n  /**\n   * The map containing name/value or name/array-of-values pairs.\n   * May be null if it requires parsing from the query string.\n   *\n   * We need to use a Map because we cannot guarantee that the key names will\n   * not be problematic for IE.\n   *\n   * @private {?goog.structs.Map<string, !Array<*>>}\n   */\n  this.keyMap_ = null;\n\n  /**\n   * The number of params, or null if it requires computing.\n   * @private {?number}\n   */\n  this.count_ = null;\n\n  /**\n   * Encoded query string, or null if it requires computing from the key map.\n   * @private {?string}\n   */\n  this.encodedQuery_ = opt_query || null;\n\n  /**\n   * If true, ignore the case of the parameter name in #get.\n   * @private {boolean}\n   */\n  this.ignoreCase_ = !!opt_ignoreCase;\n};\n\n\n/**\n * If the underlying key map is not yet initialized, it parses the\n * query string and fills the map with parsed data.\n * @private\n */\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\n  if (!this.keyMap_) {\n    this.keyMap_ = new goog.structs.Map();\n    this.count_ = 0;\n    if (this.encodedQuery_) {\n      var self = this;\n      goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\n        self.add(goog.string.urlDecode(name), value);\n      });\n    }\n  }\n};\n\n\n/**\n * Creates a new query data instance from a map of names and values.\n *\n * @param {!goog.structs.Map<string, ?>|!Object} map Map of string parameter\n *     names to parameter value. If parameter value is an array, it is\n *     treated as if the key maps to each individual value in the\n *     array.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromMap = function(map, opt_ignoreCase) {\n  var keys = goog.structs.getKeys(map);\n  if (typeof keys == 'undefined') {\n    throw new Error('Keys are undefined');\n  }\n\n  var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n  var values = goog.structs.getValues(map);\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var value = values[i];\n    if (!Array.isArray(value)) {\n      queryData.add(key, value);\n    } else {\n      queryData.setValues(key, value);\n    }\n  }\n  return queryData;\n};\n\n\n/**\n * Creates a new query data instance from parallel arrays of parameter names\n * and values. Allows for duplicate parameter names. Throws an error if the\n * lengths of the arrays differ.\n *\n * @param {!Array<string>} keys Parameter names.\n * @param {!Array<?>} values Parameter values.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n *     name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromKeysValues = function(\n    keys, values, opt_ignoreCase) {\n  if (keys.length != values.length) {\n    throw new Error('Mismatched lengths for keys/values');\n  }\n  var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n  for (var i = 0; i < keys.length; i++) {\n    queryData.add(keys[i], values[i]);\n  }\n  return queryData;\n};\n\n\n/**\n * @return {?number} The number of parameters.\n */\ngoog.Uri.QueryData.prototype.getCount = function() {\n  this.ensureKeyMapInitialized_();\n  return this.count_;\n};\n\n\n/**\n * Adds a key value pair.\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.add = function(key, value) {\n  this.ensureKeyMapInitialized_();\n  this.invalidateCache_();\n\n  key = this.getKeyName_(key);\n  var values = this.keyMap_.get(key);\n  if (!values) {\n    this.keyMap_.set(key, (values = []));\n  }\n  values.push(value);\n  this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n  return this;\n};\n\n\n/**\n * Removes all the params with the given key.\n * @param {string} key Name.\n * @return {boolean} Whether any parameter was removed.\n */\ngoog.Uri.QueryData.prototype.remove = function(key) {\n  this.ensureKeyMapInitialized_();\n\n  key = this.getKeyName_(key);\n  if (this.keyMap_.containsKey(key)) {\n    this.invalidateCache_();\n\n    // Decrement parameter count.\n    this.count_ =\n        goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n    return this.keyMap_.remove(key);\n  }\n  return false;\n};\n\n\n/**\n * Clears the parameters.\n */\ngoog.Uri.QueryData.prototype.clear = function() {\n  this.invalidateCache_();\n  this.keyMap_ = null;\n  this.count_ = 0;\n};\n\n\n/**\n * @return {boolean} Whether we have any parameters.\n */\ngoog.Uri.QueryData.prototype.isEmpty = function() {\n  this.ensureKeyMapInitialized_();\n  return this.count_ == 0;\n};\n\n\n/**\n * Whether there is a parameter with the given name\n * @param {string} key The parameter name to check for.\n * @return {boolean} Whether there is a parameter with the given name.\n */\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\n  this.ensureKeyMapInitialized_();\n  key = this.getKeyName_(key);\n  return this.keyMap_.containsKey(key);\n};\n\n\n/**\n * Whether there is a parameter with the given value.\n * @param {*} value The value to check for.\n * @return {boolean} Whether there is a parameter with the given value.\n */\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\n  // NOTE(arv): This solution goes through all the params even if it was the\n  // first param. We can get around this by not reusing code or by switching to\n  // iterators.\n  var vals = this.getValues();\n  return goog.array.contains(vals, value);\n};\n\n\n/**\n * Runs a callback on every key-value pair in the map, including duplicate keys.\n * This won't maintain original order when duplicate keys are interspersed (like\n * getKeys() / getValues()).\n * @param {function(this:SCOPE, ?, string, !goog.Uri.QueryData)} f\n * @param {SCOPE=} opt_scope The value of \"this\" inside f.\n * @template SCOPE\n */\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\n  this.ensureKeyMapInitialized_();\n  this.keyMap_.forEach(function(values, key) {\n    goog.array.forEach(values, function(value) {\n      f.call(opt_scope, value, key, this);\n    }, this);\n  }, this);\n};\n\n\n/**\n * Returns all the keys of the parameters. If a key is used multiple times\n * it will be included multiple times in the returned array\n * @return {!Array<string>} All the keys of the parameters.\n */\ngoog.Uri.QueryData.prototype.getKeys = function() {\n  this.ensureKeyMapInitialized_();\n  // We need to get the values to know how many keys to add.\n  var vals = this.keyMap_.getValues();\n  var keys = this.keyMap_.getKeys();\n  var rv = [];\n  for (var i = 0; i < keys.length; i++) {\n    var val = vals[i];\n    for (var j = 0; j < val.length; j++) {\n      rv.push(keys[i]);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Returns all the values of the parameters with the given name. If the query\n * data has no such key this will return an empty array. If no key is given\n * all values wil be returned.\n * @param {string=} opt_key The name of the parameter to get the values for.\n * @return {!Array<?>} All the values of the parameters with the given name.\n */\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\n  this.ensureKeyMapInitialized_();\n  var rv = [];\n  if (typeof opt_key === 'string') {\n    if (this.containsKey(opt_key)) {\n      rv = goog.array.concat(rv, this.keyMap_.get(this.getKeyName_(opt_key)));\n    }\n  } else {\n    // Return all values.\n    var values = this.keyMap_.getValues();\n    for (var i = 0; i < values.length; i++) {\n      rv = goog.array.concat(rv, values[i]);\n    }\n  }\n  return rv;\n};\n\n\n/**\n * Sets a key value pair and removes all other keys with the same value.\n *\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.set = function(key, value) {\n  this.ensureKeyMapInitialized_();\n  this.invalidateCache_();\n\n  // TODO(chrishenry): This could be better written as\n  // this.remove(key), this.add(key, value), but that would reorder\n  // the key (since the key is first removed and then added at the\n  // end) and we would have to fix unit tests that depend on key\n  // ordering.\n  key = this.getKeyName_(key);\n  if (this.containsKey(key)) {\n    this.count_ =\n        goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n  }\n  this.keyMap_.set(key, [value]);\n  this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n  return this;\n};\n\n\n/**\n * Returns the first value associated with the key. If the query data has no\n * such key this will return undefined or the optional default.\n * @param {string} key The name of the parameter to get the value for.\n * @param {*=} opt_default The default value to return if the query data\n *     has no such key.\n * @return {*} The first string value associated with the key, or opt_default\n *     if there's no value.\n */\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\n  if (!key) {\n    return opt_default;\n  }\n  var values = this.getValues(key);\n  return values.length > 0 ? String(values[0]) : opt_default;\n};\n\n\n/**\n * Sets the values for a key. If the key already exists, this will\n * override all of the existing values that correspond to the key.\n * @param {string} key The key to set values for.\n * @param {!Array<?>} values The values to set.\n */\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\n  this.remove(key);\n\n  if (values.length > 0) {\n    this.invalidateCache_();\n    this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\n    this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\n  }\n};\n\n\n/**\n * @return {string} Encoded query string.\n * @override\n */\ngoog.Uri.QueryData.prototype.toString = function() {\n  if (this.encodedQuery_) {\n    return this.encodedQuery_;\n  }\n\n  if (!this.keyMap_) {\n    return '';\n  }\n\n  var sb = [];\n\n  // In the past, we use this.getKeys() and this.getVals(), but that\n  // generates a lot of allocations as compared to simply iterating\n  // over the keys.\n  var keys = this.keyMap_.getKeys();\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i];\n    var encodedKey = goog.string.urlEncode(key);\n    var val = this.getValues(key);\n    for (var j = 0; j < val.length; j++) {\n      var param = encodedKey;\n      // Ensure that null and undefined are encoded into the url as\n      // literal strings.\n      if (val[j] !== '') {\n        param += '=' + goog.string.urlEncode(val[j]);\n      }\n      sb.push(param);\n    }\n  }\n\n  return this.encodedQuery_ = sb.join('&');\n};\n\n\n/**\n * @throws URIError If URI is malformed (that is, if decodeURIComponent fails on\n *     any of the URI components).\n * @return {string} Decoded query string.\n */\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\n  return goog.Uri.decodeOrEmpty_(this.toString());\n};\n\n\n/**\n * Invalidate the cache.\n * @private\n */\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\n  this.encodedQuery_ = null;\n};\n\n\n/**\n * Removes all keys that are not in the provided list. (Modifies this object.)\n * @param {Array<string>} keys The desired keys.\n * @return {!goog.Uri.QueryData} a reference to this object.\n */\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\n  this.ensureKeyMapInitialized_();\n  this.keyMap_.forEach(function(value, key) {\n    if (!goog.array.contains(keys, key)) {\n      this.remove(key);\n    }\n  }, this);\n  return this;\n};\n\n\n/**\n * Clone the query data instance.\n * @return {!goog.Uri.QueryData} New instance of the QueryData object.\n */\ngoog.Uri.QueryData.prototype.clone = function() {\n  var rv = new goog.Uri.QueryData();\n  rv.encodedQuery_ = this.encodedQuery_;\n  if (this.keyMap_) {\n    rv.keyMap_ = this.keyMap_.clone();\n    rv.count_ = this.count_;\n  }\n  return rv;\n};\n\n\n/**\n * Helper function to get the key name from a JavaScript object. Converts\n * the object to a string, and to lower case if necessary.\n * @private\n * @param {*} arg The object to get a key name from.\n * @return {string} valid key name which can be looked up in #keyMap_.\n */\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\n  var keyName = String(arg);\n  if (this.ignoreCase_) {\n    keyName = keyName.toLowerCase();\n  }\n  return keyName;\n};\n\n\n/**\n * Ignore case in parameter names.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n */\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\n  var resetKeys = ignoreCase && !this.ignoreCase_;\n  if (resetKeys) {\n    this.ensureKeyMapInitialized_();\n    this.invalidateCache_();\n    this.keyMap_.forEach(function(value, key) {\n      var lowerCase = key.toLowerCase();\n      if (key != lowerCase) {\n        this.remove(key);\n        this.setValues(lowerCase, value);\n      }\n    }, this);\n  }\n  this.ignoreCase_ = ignoreCase;\n};\n\n\n/**\n * Extends a query data object with another query data or map like object. This\n * operates 'in-place', it does not create a new QueryData object.\n *\n * @param {...(?goog.Uri.QueryData|?goog.structs.Map<?, ?>|?Object)} var_args\n *     The object from which key value pairs will be copied. Note: does not\n *     accept null.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters.\n */\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\n  for (var i = 0; i < arguments.length; i++) {\n    var data = arguments[i];\n    goog.structs.forEach(data, function(value, key) {\n      this.add(key, value);\n    }, this);\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Interface and shared data structures for implementing\n * different wire protocol versions.\n */\ngoog.provide('goog.labs.net.webChannel.Wire');\ngoog.provide('goog.labs.net.webChannel.Wire.QueuedMap');\n\ngoog.requireType('goog.structs.Map');\n\n\n\n/**\n * The interface class.\n *\n * @interface\n */\ngoog.labs.net.webChannel.Wire = function() {};\n\n\n/**\n * The latest protocol version that this class supports. We request this version\n * from the server when opening the connection. Should match\n * LATEST_CHANNEL_VERSION on the server code.\n * @type {number}\n */\ngoog.labs.net.webChannel.Wire.LATEST_CHANNEL_VERSION = 8;\n\n\n/**\n * The JSON field key for the raw data wrapper object.\n * @type {string}\n */\ngoog.labs.net.webChannel.Wire.RAW_DATA_KEY = '__data__';\n\n\n\n/**\n * Simple container class for a (mapId, map) pair.\n * @param {number} mapId The id for this map.\n * @param {!Object|!goog.structs.Map} map The map itself.\n * @param {!Object=} opt_context The context associated with the map.\n * @constructor\n * @struct\n */\ngoog.labs.net.webChannel.Wire.QueuedMap = function(mapId, map, opt_context) {\n  /**\n   * The id for this map.\n   * @type {number}\n   */\n  this.mapId = mapId;\n\n  /**\n   * The map itself.\n   * @type {!Object|!goog.structs.Map}\n   */\n  this.map = map;\n\n  /**\n   * The context for the map.\n   * @type {Object}\n   */\n  this.context = opt_context || null;\n};\n\n\n/**\n * @return {number|undefined} the size of the raw JSON message or\n * undefined if the message is not encoded as a raw JSON message\n */\ngoog.labs.net.webChannel.Wire.QueuedMap.prototype.getRawDataSize = function() {\n  if (goog.labs.net.webChannel.Wire.RAW_DATA_KEY in this.map) {\n    const data = this.map[goog.labs.net.webChannel.Wire.RAW_DATA_KEY];\n    if (typeof data === 'string') {\n      return data.length;\n    }\n  }\n\n  return undefined;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Defines a class for parsing JSON using the browser's built in\n * JSON library.\n */\n\ngoog.provide('goog.json.NativeJsonProcessor');\n\ngoog.require('goog.asserts');\ngoog.require('goog.json.Processor');\n\n\n\n/**\n * A class that parses and stringifies JSON using the browser's built-in JSON\n * library, if it is available.\n *\n * Note that the native JSON api has subtle differences across browsers, so\n * use this implementation with care.  See json_test#assertSerialize\n * for details on the differences from goog.json.\n *\n * This implementation is signficantly faster than goog.json, at least on\n * Chrome.  See json_perf.html for a perf test showing the difference.\n *\n * @param {?goog.json.Replacer=} opt_replacer An optional replacer to use during\n *     serialization.\n * @param {?goog.json.Reviver=} opt_reviver An optional reviver to use during\n *     parsing.\n * @constructor\n * @implements {goog.json.Processor}\n * @final\n */\ngoog.json.NativeJsonProcessor = function(opt_replacer, opt_reviver) {\n  goog.asserts.assert(goog.global['JSON'] !== undefined, 'JSON not defined');\n\n  /**\n   * @type {goog.json.Replacer|null|undefined}\n   * @private\n   */\n  this.replacer_ = opt_replacer;\n\n  /**\n   * @type {goog.json.Reviver|null|undefined}\n   * @private\n   */\n  this.reviver_ = opt_reviver;\n};\n\n\n/** @override */\ngoog.json.NativeJsonProcessor.prototype.stringify = function(object) {\n  return goog.global['JSON'].stringify(object, this.replacer_);\n};\n\n\n/** @override */\ngoog.json.NativeJsonProcessor.prototype.parse = function(s) {\n  return goog.global['JSON'].parse(s, this.reviver_);\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Codec functions of the v8 wire protocol. Eventually we'd want\n * to support pluggable wire-format to improve wire efficiency and to enable\n * binary encoding. Such support will require an interface class, which\n * will be added later.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WireV8');\n\ngoog.require('goog.asserts');\ngoog.require('goog.json');\ngoog.require('goog.json.NativeJsonProcessor');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.structs');\ngoog.requireType('goog.structs.Map');\n\n\n\n/**\n * The v8 codec class.\n *\n * @constructor\n * @struct\n */\ngoog.labs.net.webChannel.WireV8 = function() {\n  /**\n   * Parser for a response payload. The parser should return an array.\n   * @private {!goog.string.Parser}\n   */\n  this.parser_ = new goog.json.NativeJsonProcessor();\n};\n\n\ngoog.scope(function() {\nvar WireV8 = goog.labs.net.webChannel.WireV8;\nvar Wire = goog.labs.net.webChannel.Wire;\n\n\n/**\n * Encodes a standalone message into the wire format.\n *\n * May throw exception if the message object contains any invalid elements.\n *\n * @param {!Object|!goog.structs.Map} message The message data.\n *     V8 only support JS objects (or Map).\n * @param {!Array<string>} buffer The text buffer to write the message to.\n * @param {string=} opt_prefix The prefix for each field of the object.\n */\nWireV8.prototype.encodeMessage = function(message, buffer, opt_prefix) {\n  var prefix = opt_prefix || '';\n  try {\n    goog.structs.forEach(message, function(value, key) {\n      var encodedValue = value;\n      if (goog.isObject(value)) {\n        encodedValue = goog.json.serialize(value);\n      }  // keep the fast-path for primitive types\n      buffer.push(prefix + key + '=' + encodeURIComponent(encodedValue));\n    });\n  } catch (ex) {\n    // We send a map here because lots of the retry logic relies on map IDs,\n    // so we have to send something (possibly redundant).\n    buffer.push(\n        prefix + 'type' +\n        '=' + encodeURIComponent('_badmap'));\n    throw ex;\n  }\n};\n\n\n/**\n * Encodes all the buffered messages of the forward channel.\n *\n * @param {!Array<Wire.QueuedMap>} messageQueue The message data.\n *     V8 only support JS objects.\n * @param {number} count The number of messages to be encoded.\n * @param {?function(!Object)} badMapHandler Callback for bad messages.\n * @return {string} the encoded messages\n */\nWireV8.prototype.encodeMessageQueue = function(\n    messageQueue, count, badMapHandler) {\n  var offset = -1;\n  while (true) {\n    var sb = ['count=' + count];\n    // To save a bit of bandwidth, specify the base mapId and the rest as\n    // offsets from it.\n    if (offset == -1) {\n      if (count > 0) {\n        offset = messageQueue[0].mapId;\n        sb.push('ofs=' + offset);\n      } else {\n        offset = 0;\n      }\n    } else {\n      sb.push('ofs=' + offset);\n    }\n    var done = true;\n    for (var i = 0; i < count; i++) {\n      var mapId = messageQueue[i].mapId;\n      var map = messageQueue[i].map;\n      mapId -= offset;\n      if (mapId < 0) {\n        // redo the encoding in case of retry/reordering, plus extra space\n        offset = Math.max(0, messageQueue[i].mapId - 100);\n        done = false;\n        continue;\n      }\n      try {\n        this.encodeMessage(map, sb, 'req' + mapId + '_');\n      } catch (ex) {\n        if (badMapHandler) {\n          badMapHandler(map);\n        }\n      }\n    }\n    if (done) {\n      return sb.join('&');\n    }\n  }\n};\n\n\n/**\n * Decodes a standalone message received from the wire. May throw exception\n * if text is ill-formatted.\n *\n * Must be valid JSON as it is insecure to use eval() to decode JS literals;\n * and eval() is disallowed in Chrome apps too.\n *\n * Invalid JS literals include null array elements, quotas etc.\n *\n * @param {string} messageText The string content as received from the wire.\n * @return {*} The decoded message object.\n */\nWireV8.prototype.decodeMessage = function(messageText) {\n  var response = this.parser_.parse(messageText);\n  goog.asserts.assert(Array.isArray(response));  // throw exception\n  return response;\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utility functions for managing networking, such as\n * testing network connectivity.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.netUtils');\n\ngoog.require('goog.Uri');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\n\ngoog.scope(function() {\nvar netUtils = goog.labs.net.webChannel.netUtils;\nvar WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\n\n\n/**\n * Default timeout to allow for URI pings.\n * @type {number}\n */\nnetUtils.NETWORK_TIMEOUT = 10000;\n\n\n/**\n * Pings the network with an image URI to check if an error is a server error\n * or user's network error.\n *\n * The caller needs to add a 'rand' parameter to make sure the response is\n * not fulfilled by browser cache.\n *\n * @param {function(boolean)} callback The function to call back with results.\n * @param {goog.Uri=} opt_imageUri The URI (of an image) to use for the network\n *     test.\n */\nnetUtils.testNetwork = function(callback, opt_imageUri) {\n  var uri = opt_imageUri;\n  if (!uri) {\n    // default google.com image\n    uri = new goog.Uri('//www.google.com/images/cleardot.gif');\n\n    if (!(goog.global.location && goog.global.location.protocol == 'http')) {\n      uri.setScheme('https');  // e.g. chrome-extension\n    }\n    uri.makeUnique();\n  }\n\n  netUtils.testLoadImage(uri.toString(), netUtils.NETWORK_TIMEOUT, callback);\n};\n\n\n/**\n * Test loading the given image, retrying if necessary.\n * @param {string} url URL to the image.\n * @param {number} timeout Milliseconds before giving up.\n * @param {function(boolean)} callback Function to call with results.\n * @param {number} retries The number of times to retry.\n * @param {!WebChannelDebug} channelDebug The debug object\n * @param {number=} opt_pauseBetweenRetriesMS Optional number of milliseconds\n *     between retries - defaults to 0.\n */\nnetUtils.testLoadImageWithRetries = function(\n    url, timeout, callback, retries, channelDebug, opt_pauseBetweenRetriesMS) {\n  channelDebug.debug('TestLoadImageWithRetries: ' + opt_pauseBetweenRetriesMS);\n  if (retries == 0) {\n    // no more retries, give up\n    callback(false);\n    return;\n  }\n\n  var pauseBetweenRetries = opt_pauseBetweenRetriesMS || 0;\n  retries--;\n  netUtils.testLoadImage(url, timeout, function(succeeded) {\n    if (succeeded) {\n      callback(true);\n    } else {\n      // try again\n      goog.global.setTimeout(function() {\n        netUtils.testLoadImageWithRetries(\n            url, timeout, callback, retries, channelDebug, pauseBetweenRetries);\n      }, pauseBetweenRetries);\n    }\n  });\n};\n\n\n/**\n * Test loading the given image.\n * @param {string} url URL to the image.\n * @param {number} timeout Milliseconds before giving up.\n * @param {function(boolean)} callback Function to call with results.\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\nnetUtils.testLoadImage = function(url, timeout, callback) {\n  var channelDebug = new WebChannelDebug();\n  channelDebug.debug('TestLoadImage: loading ' + url);\n  if (goog.global.Image) {\n    var img = new Image();\n    img.onload = goog.partial(\n        netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: loaded',\n        true, callback);\n    img.onerror = goog.partial(\n        netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: error',\n        false, callback);\n    img.onabort = goog.partial(\n        netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: abort',\n        false, callback);\n    img.ontimeout = goog.partial(\n        netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: timeout',\n        false, callback);\n\n    goog.global.setTimeout(function() {\n      if (img.ontimeout) {\n        img.ontimeout();\n      }\n    }, timeout);\n    img.src = url;\n  } else {\n    // log ERROR_OTHER from environements where Image is not supported\n    callback(false);\n  }\n};\n\n\n/**\n * Wrap the image callback with debug and cleanup logic.\n * @param {!WebChannelDebug} channelDebug The WebChannelDebug object.\n * @param {!Image} img The image element.\n * @param {string} debugText The debug text.\n * @param {boolean} result The result of image loading.\n * @param {function(boolean)} callback The image callback.\n * @private\n */\nnetUtils.imageCallback_ = function(\n    channelDebug, img, debugText, result, callback) {\n  try {\n    channelDebug.debug(debugText);\n    netUtils.clearImageCallbacks_(img);\n    callback(result);\n  } catch (e) {\n    channelDebug.dumpException(e);\n  }\n};\n\n\n/**\n * Clears handlers to avoid memory leaks.\n * @param {Image} img The image to clear handlers from.\n * @private\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\nnetUtils.clearImageCallbacks_ = function(img) {\n  img.onload = null;\n  img.onerror = null;\n  img.onabort = null;\n  img.ontimeout = null;\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Utility to attempt native JSON processing, falling back to\n *     goog.json if not available.\n *\n *     This is intended as a drop-in for current users of goog.json who want\n *     to take advantage of native JSON if present.\n */\n\ngoog.provide('goog.json.hybrid');\n\ngoog.require('goog.asserts');\ngoog.require('goog.json');\n\n\n/**\n * Attempts to serialize the JSON string natively, falling back to\n * `goog.json.serialize` if unsuccessful.\n * @param {!Object} obj JavaScript object to serialize to JSON.\n * @return {string} Resulting JSON string.\n */\ngoog.json.hybrid.stringify =\n    goog.json.USE_NATIVE_JSON ? goog.global['JSON']['stringify'] : function(\n                                                                       obj) {\n      if (goog.global.JSON) {\n        try {\n          return goog.global.JSON.stringify(obj);\n        } catch (e) {\n          // Native serialization failed.  Fall through to retry with\n          // goog.json.serialize.\n        }\n      }\n\n      return goog.json.serialize(obj);\n    };\n\n\n/**\n * Attempts to parse the JSON string natively, falling back to\n * the supplied `fallbackParser` if unsuccessful.\n * @param {string} jsonString JSON string to parse.\n * @param {function(string):Object} fallbackParser Fallback JSON parser used\n *     if native\n * @return {?Object} Resulting JSON object.\n * @private\n */\ngoog.json.hybrid.parse_ = function(jsonString, fallbackParser) {\n  if (goog.global.JSON) {\n    try {\n      var obj = goog.global.JSON.parse(jsonString);\n      goog.asserts.assert(typeof obj == 'object');\n      return /** @type {?Object} */ (obj);\n    } catch (e) {\n      // Native parse failed.  Fall through to retry with goog.json.parse.\n    }\n  }\n\n  return fallbackParser(jsonString);\n};\n\n\n/**\n * Attempts to parse the JSON string natively, falling back to\n * `goog.json.parse` if unsuccessful.\n * @param {string} jsonString JSON string to parse.\n * @return {?Object} Resulting JSON object.\n */\ngoog.json.hybrid.parse =\n    goog.json.USE_NATIVE_JSON ? goog.global['JSON']['parse'] : function(\n                                                                   jsonString) {\n      return goog.json.hybrid.parse_(jsonString, goog.json.parse);\n    };\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Constants for HTTP status codes.\n */\n\ngoog.provide('goog.net.HttpStatus');\n\n\n/**\n * HTTP Status Codes defined in RFC 2616, RFC 6585, RFC 4918 and RFC 7538.\n * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html\n * @see http://tools.ietf.org/html/rfc6585\n * @see https://tools.ietf.org/html/rfc4918\n * @see https://tools.ietf.org/html/rfc7538\n * @enum {number}\n */\ngoog.net.HttpStatus = {\n  // Informational 1xx\n  CONTINUE: 100,\n  SWITCHING_PROTOCOLS: 101,\n\n  // Successful 2xx\n  OK: 200,\n  CREATED: 201,\n  ACCEPTED: 202,\n  NON_AUTHORITATIVE_INFORMATION: 203,\n  NO_CONTENT: 204,\n  RESET_CONTENT: 205,\n  PARTIAL_CONTENT: 206,\n  MULTI_STATUS: 207,\n\n  // Redirection 3xx\n  MULTIPLE_CHOICES: 300,\n  MOVED_PERMANENTLY: 301,\n  FOUND: 302,\n  SEE_OTHER: 303,\n  NOT_MODIFIED: 304,\n  USE_PROXY: 305,\n  TEMPORARY_REDIRECT: 307,\n  PERMANENT_REDIRECT: 308,\n\n  // Client Error 4xx\n  BAD_REQUEST: 400,\n  UNAUTHORIZED: 401,\n  PAYMENT_REQUIRED: 402,\n  FORBIDDEN: 403,\n  NOT_FOUND: 404,\n  METHOD_NOT_ALLOWED: 405,\n  NOT_ACCEPTABLE: 406,\n  PROXY_AUTHENTICATION_REQUIRED: 407,\n  REQUEST_TIMEOUT: 408,\n  CONFLICT: 409,\n  GONE: 410,\n  LENGTH_REQUIRED: 411,\n  PRECONDITION_FAILED: 412,\n  REQUEST_ENTITY_TOO_LARGE: 413,\n  REQUEST_URI_TOO_LONG: 414,\n  UNSUPPORTED_MEDIA_TYPE: 415,\n  REQUEST_RANGE_NOT_SATISFIABLE: 416,\n  EXPECTATION_FAILED: 417,\n  UNPROCESSABLE_ENTITY: 422,\n  LOCKED: 423,\n  FAILED_DEPENDENCY: 424,\n  PRECONDITION_REQUIRED: 428,\n  TOO_MANY_REQUESTS: 429,\n  REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n\n  // Server Error 5xx\n  INTERNAL_SERVER_ERROR: 500,\n  NOT_IMPLEMENTED: 501,\n  BAD_GATEWAY: 502,\n  SERVICE_UNAVAILABLE: 503,\n  GATEWAY_TIMEOUT: 504,\n  HTTP_VERSION_NOT_SUPPORTED: 505,\n  INSUFFICIENT_STORAGE: 507,\n  NETWORK_AUTHENTICATION_REQUIRED: 511,\n\n  /*\n   * IE returns this code for 204 due to its use of URLMon, which returns this\n   * code for 'Operation Aborted'. The status text is 'Unknown', the response\n   * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7.\n   */\n  QUIRK_IE_NO_CONTENT: 1223,\n};\n\n\n/**\n * Returns whether the given status should be considered successful.\n *\n * Successful codes are OK (200), CREATED (201), ACCEPTED (202),\n * NO CONTENT (204), PARTIAL CONTENT (206), NOT MODIFIED (304),\n * and IE's no content code (1223).\n *\n * @param {number} status The status code to test.\n * @return {boolean} Whether the status code should be considered successful.\n */\ngoog.net.HttpStatus.isSuccess = function(status) {\n  switch (status) {\n    case goog.net.HttpStatus.OK:\n    case goog.net.HttpStatus.CREATED:\n    case goog.net.HttpStatus.ACCEPTED:\n    case goog.net.HttpStatus.NO_CONTENT:\n    case goog.net.HttpStatus.PARTIAL_CONTENT:\n    case goog.net.HttpStatus.NOT_MODIFIED:\n    case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:\n      return true;\n\n    default:\n      return false;\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides CORS support for HTTP based RPC requests.\n *\n * As part of net.rpc package, CORS features provided by this class\n * depend on the server support. Please check related specs to decide how\n * to enable any of the features provided by this class.\n */\n\ngoog.module('goog.net.rpc.HttpCors');\n\nvar GoogUri = goog.require('goog.Uri');\nvar googObject = goog.require('goog.object');\nvar googString = goog.require('goog.string');\nvar googUriUtils = goog.require('goog.uri.utils');\n\n\n/**\n * The default URL parameter name to overwrite http headers with a URL param\n * to avoid CORS preflight.\n *\n * See https://github.com/whatwg/fetch/issues/210#issue-129531743 for the spec.\n *\n * @type {string}\n */\nexports.HTTP_HEADERS_PARAM_NAME = '$httpHeaders';\n\n\n/**\n * The default URL parameter name to overwrite http method with a URL param\n * to avoid CORS preflight.\n *\n * See https://github.com/whatwg/fetch/issues/210#issue-129531743 for the spec.\n *\n * @type {string}\n */\nexports.HTTP_METHOD_PARAM_NAME = '$httpMethod';\n\n\n/**\n * Generates the URL parameter value with custom headers encoded as\n * HTTP/1.1 headers block.\n *\n * @param {!Object<string, string>} headers The custom headers.\n * @return {string} The URL param to overwrite custom HTTP headers.\n */\nexports.generateHttpHeadersOverwriteParam = function(headers) {\n  var result = '';\n  googObject.forEach(headers, function(value, key) {\n    result += key;\n    result += ':';\n    result += value;\n    result += '\\r\\n';\n  });\n  return result;\n};\n\n\n/**\n * Generates the URL-encoded URL parameter value with custom headers encoded as\n * HTTP/1.1 headers block.\n *\n * @param {!Object<string, string>} headers The custom headers.\n * @return {string} The URL param to overwrite custom HTTP headers.\n */\nexports.generateEncodedHttpHeadersOverwriteParam = function(headers) {\n  return googString.urlEncode(\n      exports.generateHttpHeadersOverwriteParam(headers));\n};\n\n\n/**\n * Sets custom HTTP headers via an overwrite URL param.\n *\n * @param {!GoogUri|string} url The URI object or a string path.\n * @param {string} urlParam The URL param name.\n * @param {!Object<string, string>} extraHeaders The HTTP headers.\n * @return {!GoogUri|string} The URI object or a string path with headers\n * encoded as a url param.\n */\nexports.setHttpHeadersWithOverwriteParam = function(\n    url, urlParam, extraHeaders) {\n  if (googObject.isEmpty(extraHeaders)) {\n    return url;\n  }\n  var httpHeaders = exports.generateHttpHeadersOverwriteParam(extraHeaders);\n  if (typeof url === 'string') {\n    return googUriUtils.appendParam(\n        url, googString.urlEncode(urlParam), httpHeaders);\n  } else {\n    url.setParameterValue(urlParam, httpHeaders);  // duplicate removed!\n    return url;\n  }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implementation of a WebChannel transport using WebChannelBase.\n *\n * When WebChannelBase is used as the underlying transport, the capabilities\n * of the WebChannel are limited to what's supported by the implementation.\n * Particularly, multiplexing is not possible, and only strings are\n * supported as message types.\n */\n\ngoog.provide('goog.labs.net.webChannel.WebChannelBaseTransport');\n\ngoog.require('goog.asserts');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.json');\ngoog.require('goog.labs.net.webChannel.ChannelRequest');\ngoog.require('goog.labs.net.webChannel.WebChannelBase');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.log');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.WebChannelTransport');\ngoog.require('goog.object');\ngoog.require('goog.string');\n\n\n\n/**\n * Implementation of {@link goog.net.WebChannelTransport} with\n * {@link goog.labs.net.webChannel.WebChannelBase} as the underlying channel\n * implementation.\n *\n * @constructor\n * @struct\n * @implements {goog.net.WebChannelTransport}\n * @final\n */\ngoog.labs.net.webChannel.WebChannelBaseTransport = function() {\n  if (!goog.labs.net.webChannel.ChannelRequest.supportsXhrStreaming()) {\n    throw new Error('Environmental error: no available transport.');\n  }\n};\n\n\ngoog.scope(function() {\nvar WebChannelBaseTransport = goog.labs.net.webChannel.WebChannelBaseTransport;\nvar WebChannelBase = goog.labs.net.webChannel.WebChannelBase;\nvar Wire = goog.labs.net.webChannel.Wire;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.prototype.createWebChannel = function(\n    url, opt_options) {\n  return new WebChannelBaseTransport.Channel(url, opt_options);\n};\n\n\n\n/**\n * Implementation of the {@link goog.net.WebChannel} interface.\n *\n * @param {string} url The URL path for the new WebChannel instance.\n * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the\n *     new WebChannel instance.\n *\n * @constructor\n * @implements {goog.net.WebChannel}\n * @extends {goog.events.EventTarget}\n * @final\n */\nWebChannelBaseTransport.Channel = function(url, opt_options) {\n  WebChannelBaseTransport.Channel.base(this, 'constructor');\n\n  /**\n   * @private {!WebChannelBase} The underlying channel object.\n   */\n  this.channel_ = new WebChannelBase(\n      opt_options, goog.net.WebChannelTransport.CLIENT_VERSION);\n\n  /**\n   * @private {string} The URL of the target server end-point.\n   */\n  this.url_ = url;\n\n  /**\n   * @private {goog.log.Logger} The logger for this class.\n   */\n  this.logger_ =\n      goog.log.getLogger('goog.labs.net.webChannel.WebChannelBaseTransport');\n\n  /**\n   * @private {Object<string, string>} Extra URL parameters\n   * to be added to each HTTP request.\n   */\n  this.messageUrlParams_ =\n      (opt_options && opt_options.messageUrlParams) || null;\n\n  var messageHeaders = (opt_options && opt_options.messageHeaders) || null;\n\n  // default is false\n  if (opt_options && opt_options.clientProtocolHeaderRequired) {\n    if (messageHeaders) {\n      goog.object.set(\n          messageHeaders, goog.net.WebChannel.X_CLIENT_PROTOCOL,\n          goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);\n    } else {\n      messageHeaders = goog.object.create(\n          goog.net.WebChannel.X_CLIENT_PROTOCOL,\n          goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);\n    }\n  }\n\n  this.channel_.setExtraHeaders(messageHeaders);\n\n  var initHeaders = (opt_options && opt_options.initMessageHeaders) || null;\n\n  if (opt_options && opt_options.messageContentType) {\n    if (initHeaders) {\n      goog.object.set(\n          initHeaders, goog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE,\n          opt_options.messageContentType);\n    } else {\n      initHeaders = goog.object.create(\n          goog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE,\n          opt_options.messageContentType);\n    }\n  }\n\n  if (opt_options && opt_options.clientProfile) {\n    if (initHeaders) {\n      goog.object.set(\n          initHeaders, goog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE,\n          opt_options.clientProfile);\n    } else {\n      initHeaders = goog.object.create(\n          goog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE,\n          opt_options.clientProfile);\n    }\n  }\n\n  this.channel_.setInitHeaders(initHeaders);\n\n  var httpHeadersOverwriteParam =\n      opt_options && opt_options.httpHeadersOverwriteParam;\n  if (httpHeadersOverwriteParam &&\n      !goog.string.isEmptyOrWhitespace(httpHeadersOverwriteParam)) {\n    this.channel_.setHttpHeadersOverwriteParam(httpHeadersOverwriteParam);\n  }\n\n  /**\n   * @private {boolean} Whether to enable CORS.\n   */\n  this.supportsCrossDomainXhr_ =\n      (opt_options && opt_options.supportsCrossDomainXhr) || false;\n\n  /**\n   * @private {boolean} Whether to send raw Json and bypass v8 wire format.\n   */\n  this.sendRawJson_ = (opt_options && opt_options.sendRawJson) || false;\n\n  // Note that httpSessionIdParam will be ignored if the same parameter name\n  // has already been specified with messageUrlParams\n  var httpSessionIdParam = opt_options && opt_options.httpSessionIdParam;\n  if (httpSessionIdParam &&\n      !goog.string.isEmptyOrWhitespace(httpSessionIdParam)) {\n    this.channel_.setHttpSessionIdParam(httpSessionIdParam);\n    if (goog.object.containsKey(this.messageUrlParams_, httpSessionIdParam)) {\n      goog.object.remove(this.messageUrlParams_, httpSessionIdParam);\n      goog.log.warning(this.logger_,\n          'Ignore httpSessionIdParam also specified with messageUrlParams: '\n          + httpSessionIdParam);\n    }\n  }\n\n  /**\n   * The channel handler.\n   *\n   * @private {!WebChannelBaseTransport.Channel.Handler_}\n   */\n  this.channelHandler_ = new WebChannelBaseTransport.Channel.Handler_(this);\n};\ngoog.inherits(WebChannelBaseTransport.Channel, goog.events.EventTarget);\n\n\n/**\n * @override\n * @suppress {checkTypes}\n */\nWebChannelBaseTransport.Channel.prototype.addEventListener = function(\n    type, handler, /** boolean= */ opt_capture, opt_handlerScope) {\n  WebChannelBaseTransport.Channel.base(\n      this, 'addEventListener', type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/**\n * @override\n * @suppress {checkTypes}\n */\nWebChannelBaseTransport.Channel.prototype.removeEventListener = function(\n    type, handler, /** boolean= */ opt_capture, opt_handlerScope) {\n  WebChannelBaseTransport.Channel.base(\n      this, 'removeEventListener', type, handler, opt_capture,\n      opt_handlerScope);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.open = function() {\n  this.channel_.setHandler(this.channelHandler_);\n  if (this.supportsCrossDomainXhr_) {\n    this.channel_.setSupportsCrossDomainXhrs(true);\n  }\n  this.channel_.connect(this.url_, (this.messageUrlParams_ || undefined));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.close = function() {\n  this.channel_.disconnect();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.halfClose = function() {\n  // to be implemented\n  throw new Error('Not implemented');\n};\n\n\n/**\n * The WebChannelBase only supports object types.\n *\n * @param {!goog.net.WebChannel.MessageData} message The message to send.\n *\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.send = function(message) {\n  goog.asserts.assert(\n      goog.isObject(message) || typeof message === 'string',\n      'only object type or raw string is supported');\n\n  if (typeof message === 'string') {\n    var rawJson = {};\n    rawJson[Wire.RAW_DATA_KEY] = message;\n    this.channel_.sendMap(rawJson);\n  } else if (this.sendRawJson_) {\n    var rawJson = {};\n    rawJson[Wire.RAW_DATA_KEY] = goog.json.serialize(message);\n    this.channel_.sendMap(rawJson);\n  } else {\n    this.channel_.sendMap(message);\n  }\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.disposeInternal = function() {\n  this.channel_.setHandler(null);\n  delete this.channelHandler_;\n  this.channel_.disconnect();\n  delete this.channel_;\n\n  WebChannelBaseTransport.Channel.base(this, 'disposeInternal');\n};\n\n\n\n/**\n * The message event.\n *\n * @param {!Array<?>|!Object} array The data array from the underlying channel.\n * @constructor\n * @extends {goog.net.WebChannel.MessageEvent}\n * @final\n */\nWebChannelBaseTransport.Channel.MessageEvent = function(array) {\n  WebChannelBaseTransport.Channel.MessageEvent.base(this, 'constructor');\n\n  // single-metadata only\n  var metadata = array['__sm__'];\n  if (metadata) {\n    this.metadataKey = goog.object.getAnyKey(metadata);\n    if (this.metadataKey) {\n      this.data = goog.object.get(metadata, this.metadataKey);\n    } else {\n      this.data = metadata;  // empty\n    }\n  } else {\n    this.data = array;\n  }\n};\ngoog.inherits(\n    WebChannelBaseTransport.Channel.MessageEvent,\n    goog.net.WebChannel.MessageEvent);\n\n\n\n/**\n * The error event.\n *\n * @param {WebChannelBase.Error} error The error code.\n * @constructor\n * @extends {goog.net.WebChannel.ErrorEvent}\n * @final\n */\nWebChannelBaseTransport.Channel.ErrorEvent = function(error) {\n  WebChannelBaseTransport.Channel.ErrorEvent.base(this, 'constructor');\n\n  /**\n   * High-level status code.\n   */\n  this.status = goog.net.WebChannel.ErrorStatus.NETWORK_ERROR;\n\n  /**\n   * @const {WebChannelBase.Error} Internal error code, for debugging use only.\n   */\n  this.errorCode = error;\n};\ngoog.inherits(\n    WebChannelBaseTransport.Channel.ErrorEvent, goog.net.WebChannel.ErrorEvent);\n\n\n\n/**\n * Implementation of {@link WebChannelBase.Handler} interface.\n *\n * @param {!WebChannelBaseTransport.Channel} channel The enclosing WebChannel.\n *\n * @constructor\n * @extends {WebChannelBase.Handler}\n * @private\n */\nWebChannelBaseTransport.Channel.Handler_ = function(channel) {\n  WebChannelBaseTransport.Channel.Handler_.base(this, 'constructor');\n\n  /**\n   * @type {!WebChannelBaseTransport.Channel}\n   * @private\n   */\n  this.channel_ = channel;\n};\ngoog.inherits(WebChannelBaseTransport.Channel.Handler_, WebChannelBase.Handler);\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelOpened = function(\n    channel) {\n  goog.log.info(\n      this.channel_.logger_, 'WebChannel opened on ' + this.channel_.url_);\n  this.channel_.dispatchEvent(goog.net.WebChannel.EventType.OPEN);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelHandleArray =\n    function(channel, array) {\n  goog.asserts.assert(array, 'array expected to be defined');\n  this.channel_.dispatchEvent(\n      new WebChannelBaseTransport.Channel.MessageEvent(array));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelError = function(\n    channel, error) {\n  goog.log.info(\n      this.channel_.logger_, 'WebChannel aborted on ' + this.channel_.url_ +\n          ' due to channel error: ' + error);\n  this.channel_.dispatchEvent(\n      new WebChannelBaseTransport.Channel.ErrorEvent(error));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelClosed = function(\n    channel, opt_pendingMaps, opt_undeliveredMaps) {\n  goog.log.info(\n      this.channel_.logger_, 'WebChannel closed on ' + this.channel_.url_);\n  this.channel_.dispatchEvent(goog.net.WebChannel.EventType.CLOSE);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.getRuntimeProperties = function() {\n  return new WebChannelBaseTransport.ChannelProperties(this.channel_);\n};\n\n\n\n/**\n * Implementation of the {@link goog.net.WebChannel.RuntimeProperties}.\n *\n * @param {!WebChannelBase} channel The underlying channel object.\n *\n * @constructor\n * @implements {goog.net.WebChannel.RuntimeProperties}\n * @final\n */\nWebChannelBaseTransport.ChannelProperties = function(channel) {\n  /**\n   * The underlying channel object.\n   *\n   * @private {!WebChannelBase}\n   */\n  this.channel_ = channel;\n\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getConcurrentRequestLimit =\n    function() {\n  return this.channel_.getForwardChannelRequestPool().getMaxSize();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.isSpdyEnabled = function() {\n  return this.getConcurrentRequestLimit() > 1;\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getPendingRequestCount =\n    function() {\n  return this.channel_.getForwardChannelRequestPool().getRequestCount();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getHttpSessionId =\n    function() {\n  return this.channel_.getHttpSessionId();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.commit = function(\n    callback) {\n  this.channel_.setForwardChannelFlushCallback(callback);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getNonAckedMessageCount =\n    goog.abstractMethod;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.notifyNonAckedMessageCount =\n    goog.abstractMethod;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.onCommit =\n    goog.abstractMethod;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.ackCommit =\n    goog.abstractMethod;\n\n\n/** @override */\nWebChannelBaseTransport.ChannelProperties.prototype.getLastStatusCode =\n    function() {\n  return this.channel_.getLastStatusCode();\n};\n});  // goog.scope\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 * Bring in closure-library dependencies\n */\n\ngoog.provide('firebase.webchannel.wrapper');\n\n// goog.net.WebChannelTransport\ngoog.require('goog.net.createWebChannelTransport');\ngoog.require('goog.labs.net.webChannel.WebChannelBaseTransport');\n/**\n * NOTE: The `createWebChannel` function takes an options object as a second param\n * whose properties are typically mangled. We override these in externs/overrides.js\n * Without those externs, this does not function properly.\n */\ngoog.labs.net.webChannel.WebChannelBaseTransport.prototype['createWebChannel'] =\n  goog.labs.net.webChannel.WebChannelBaseTransport.prototype.createWebChannel;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['send'] =\n  goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.send;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['open'] =\n  goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.open;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['close'] =\n  goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.close;\n\n// goog.net.ErrorCode\ngoog.require('goog.net.ErrorCode');\ngoog.net.ErrorCode['NO_ERROR'] = goog.net.ErrorCode.NO_ERROR;\ngoog.net.ErrorCode['TIMEOUT'] = goog.net.ErrorCode.TIMEOUT;\ngoog.net.ErrorCode['HTTP_ERROR'] = goog.net.ErrorCode.HTTP_ERROR;\n\n// goog.net.ErrorType\ngoog.require('goog.net.EventType');\ngoog.net.EventType['COMPLETE'] = goog.net.EventType.COMPLETE;\n\n// goog.net.WebChannel\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.events.EventTarget');\ngoog.net.WebChannel['EventType'] = goog.net.WebChannel.EventType;\ngoog.net.WebChannel.EventType['OPEN'] = goog.net.WebChannel.EventType.OPEN;\ngoog.net.WebChannel.EventType['CLOSE'] = goog.net.WebChannel.EventType.CLOSE;\ngoog.net.WebChannel.EventType['ERROR'] = goog.net.WebChannel.EventType.ERROR;\ngoog.net.WebChannel.EventType['MESSAGE'] =\n  goog.net.WebChannel.EventType.MESSAGE;\ngoog.events.EventTarget.prototype['listen'] =\n  goog.events.EventTarget.prototype.listen;\n\n// goog.net.XhrIo\ngoog.require('goog.net.XhrIo');\ngoog.net.XhrIo.prototype['listenOnce'] = goog.net.XhrIo.prototype.listenOnce;\ngoog.net.XhrIo.prototype['getLastError'] =\n  goog.net.XhrIo.prototype.getLastError;\ngoog.net.XhrIo.prototype['getLastErrorCode'] =\n  goog.net.XhrIo.prototype.getLastErrorCode;\ngoog.net.XhrIo.prototype['getStatus'] = goog.net.XhrIo.prototype.getStatus;\ngoog.net.XhrIo.prototype['getResponseJson'] =\n  goog.net.XhrIo.prototype.getResponseJson;\ngoog.net.XhrIo.prototype['getResponseText'] =\n  goog.net.XhrIo.prototype.getResponseText;\ngoog.net.XhrIo.prototype['send'] = goog.net.XhrIo.prototype.send;\n\n/**\n * This ignore statement is required as closure will minify these properties\n * if done in the typical prettier format\n */\n// prettier-ignore\nmodule['exports'] = {\n  'createWebChannelTransport': goog.net.createWebChannelTransport,\n  'ErrorCode': goog.net.ErrorCode,\n  'EventType': goog.net.EventType,\n  'WebChannel': goog.net.WebChannel,\n  'XhrIo': goog.net.XhrIo\n};\n","'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar env = require('exenv');\nvar PropTypes = require('prop-types');\nvar React = require('react');\n\nfunction _typeof(obj) {\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function (obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}\n\nfunction _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction _inherits(subClass, superClass) {\n  if (typeof superClass !== \"function\" && superClass !== null) {\n    throw new TypeError(\"Super expression must either be null or a function\");\n  }\n\n  subClass.prototype = Object.create(superClass && superClass.prototype, {\n    constructor: {\n      value: subClass,\n      writable: true,\n      configurable: true\n    }\n  });\n  if (superClass) _setPrototypeOf(subClass, superClass);\n}\n\nfunction _getPrototypeOf(o) {\n  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n    return o.__proto__ || Object.getPrototypeOf(o);\n  };\n  return _getPrototypeOf(o);\n}\n\nfunction _setPrototypeOf(o, p) {\n  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n    o.__proto__ = p;\n    return o;\n  };\n\n  return _setPrototypeOf(o, p);\n}\n\nfunction _assertThisInitialized(self) {\n  if (self === void 0) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return self;\n}\n\nfunction _possibleConstructorReturn(self, call) {\n  if (call && (typeof call === \"object\" || typeof call === \"function\")) {\n    return call;\n  }\n\n  return _assertThisInitialized(self);\n}\n\n/**\n * The current implementation was chosen by performance and compatibility reasons, feel free to play\n * with benchmarks and submit PR with faster alternative. Each method contains links to benchmarks.\n */\nvar EventSet =\n/*#__PURE__*/\nfunction () {\n  /**\n   * @see https://jsperf.com/suir-eventset-constructor\n   */\n  function EventSet(eventHandlers) {\n    _classCallCheck(this, EventSet);\n\n    _defineProperty(this, \"handlers\", void 0);\n\n    this.handlers = eventHandlers.slice(0);\n  }\n  /**\n   * @see https://jsperf.com/suir-eventset-addhandlers\n   */\n\n\n  _createClass(EventSet, [{\n    key: \"addHandlers\",\n    value: function addHandlers(additionalHandlers) {\n      var newHandlers = this.handlers.slice(0);\n      var length = additionalHandlers.length; // Heads up!\n      // Previously we use Set there, it granted uniqueness of handlers, now dispatchEvent() is\n      // responsible for this.\n\n      for (var i = 0; i < length; i += 1) {\n        newHandlers.push(additionalHandlers[i]);\n      }\n\n      return new EventSet(newHandlers);\n    }\n    /**\n     * @see https://jsperf.com/suir-eventset-dispatchsingle\n     * @see https://jsperf.com/suir-eventset-dispatchmultiple2\n     */\n\n  }, {\n    key: \"dispatchEvent\",\n    value: function dispatchEvent(event, dispatchAll) {\n      var count = this.handlers.length - 1;\n\n      if (!dispatchAll) {\n        // Heads up!\n        // We don't use .pop() there because it will mutate the array.\n        var recentHandler = this.handlers[count];\n        recentHandler(event);\n        return;\n      }\n\n      for (var i = count; i >= 0; i -= 1) {\n        if (!this.handlers[i].called) {\n          this.handlers[i].called = true;\n          this.handlers[i](event);\n        }\n      }\n\n      for (var _i = count; _i >= 0; _i -= 1) {\n        this.handlers[_i].called = false;\n      }\n    }\n  }, {\n    key: \"hasHandlers\",\n    value: function hasHandlers() {\n      return this.handlers.length > 0;\n    }\n    /**\n     * @see https://jsperf.com/suir-eventset-removehandlers\n     */\n\n  }, {\n    key: \"removeHandlers\",\n    value: function removeHandlers(removalHandlers) {\n      var newHandlers = [];\n      var length = this.handlers.length;\n\n      for (var i = 0; i < length; i += 1) {\n        var handler = this.handlers[i];\n\n        if (removalHandlers.indexOf(handler) === -1) {\n          newHandlers.push(handler);\n        }\n      }\n\n      return new EventSet(newHandlers);\n    }\n  }]);\n\n  return EventSet;\n}();\n\n/**\n * An IE11-compatible function.\n *\n * @see https://jsperf.com/suir-clone-map\n */\nfunction cloneMap(map) {\n  var newMap = new Map();\n  map.forEach(function (value, key) {\n    newMap.set(key, value);\n  });\n  return newMap;\n}\nfunction normalizeHandlers(handlers) {\n  return Array.isArray(handlers) ? handlers : [handlers];\n}\n/**\n * Asserts that the passed value is React.RefObject\n *\n * @see https://github.com/facebook/react/blob/v16.8.2/packages/react-reconciler/src/ReactFiberCommitWork.js#L665\n */\n\nvar isRefObject = function isRefObject(ref // eslint-disable-next-line\n) {\n  return ref !== null && _typeof(ref) === 'object' && ref.hasOwnProperty('current');\n};\n/**\n * Normalizes `target` for EventStack, because `target` can be passed as `boolean` or `string`.\n *\n * @see https://jsperf.com/suir-normalize-target\n */\n\nfunction normalizeTarget(target) {\n  if (target === 'document') return document;\n  if (target === 'window') return window;\n  if (isRefObject(target)) return target.current || document;\n  return target || document;\n}\n\nvar EventPool =\n/*#__PURE__*/\nfunction () {\n  function EventPool(poolName, handlerSets) {\n    _classCallCheck(this, EventPool);\n\n    _defineProperty(this, \"handlerSets\", void 0);\n\n    _defineProperty(this, \"poolName\", void 0);\n\n    this.handlerSets = handlerSets;\n    this.poolName = poolName;\n  }\n\n  _createClass(EventPool, [{\n    key: \"addHandlers\",\n    value: function addHandlers(eventType, eventHandlers) {\n      var handlerSets = cloneMap(this.handlerSets);\n\n      if (handlerSets.has(eventType)) {\n        var eventSet = handlerSets.get(eventType);\n        handlerSets.set(eventType, eventSet.addHandlers(eventHandlers));\n      } else {\n        handlerSets.set(eventType, new EventSet(eventHandlers));\n      }\n\n      return new EventPool(this.poolName, handlerSets);\n    }\n  }, {\n    key: \"dispatchEvent\",\n    value: function dispatchEvent(eventType, event) {\n      var handlerSet = this.handlerSets.get(eventType);\n      var shouldDispatchAll = this.poolName === 'default';\n\n      if (handlerSet) {\n        handlerSet.dispatchEvent(event, shouldDispatchAll);\n      }\n    }\n  }, {\n    key: \"hasHandlers\",\n    value: function hasHandlers(eventType) {\n      if (!eventType) {\n        return this.handlerSets.size > 0;\n      }\n\n      var eventSet = this.handlerSets.get(eventType);\n\n      if (eventSet) {\n        return eventSet.hasHandlers();\n      }\n\n      return false;\n    }\n  }, {\n    key: \"removeHandlers\",\n    value: function removeHandlers(eventType, eventHandlers) {\n      var handlerSets = cloneMap(this.handlerSets);\n\n      if (!handlerSets.has(eventType)) {\n        return new EventPool(this.poolName, handlerSets);\n      }\n\n      var currentSet = handlerSets.get(eventType);\n      var nextSet = currentSet.removeHandlers(eventHandlers);\n\n      if (nextSet.hasHandlers()) {\n        handlerSets.set(eventType, nextSet);\n      } else {\n        handlerSets.delete(eventType);\n      }\n\n      return new EventPool(this.poolName, handlerSets);\n    }\n  }]);\n\n  return EventPool;\n}();\n\n_defineProperty(EventPool, \"createByType\", function (poolName, eventType, eventHandlers) {\n  var handlerSets = new Map();\n  handlerSets.set(eventType, new EventSet(eventHandlers));\n  return new EventPool(poolName, handlerSets);\n});\n\nvar EventTarget =\n/*#__PURE__*/\nfunction () {\n  function EventTarget(target) {\n    var _this = this;\n\n    _classCallCheck(this, EventTarget);\n\n    _defineProperty(this, \"handlers\", new Map());\n\n    _defineProperty(this, \"pools\", new Map());\n\n    _defineProperty(this, \"target\", void 0);\n\n    _defineProperty(this, \"createEmitter\", function (eventType) {\n      return function (event) {\n        _this.pools.forEach(function (pool) {\n          pool.dispatchEvent(eventType, event);\n        });\n      };\n    });\n\n    this.target = target;\n  }\n\n  _createClass(EventTarget, [{\n    key: \"addHandlers\",\n    value: function addHandlers(poolName, eventType, eventHandlers) {\n      if (this.pools.has(poolName)) {\n        var eventPool = this.pools.get(poolName);\n        this.pools.set(poolName, eventPool.addHandlers(eventType, eventHandlers));\n      } else {\n        this.pools.set(poolName, EventPool.createByType(poolName, eventType, eventHandlers));\n      }\n\n      if (!this.handlers.has(eventType)) {\n        this.addTargetHandler(eventType);\n      }\n    }\n  }, {\n    key: \"hasHandlers\",\n    value: function hasHandlers() {\n      return this.handlers.size > 0;\n    }\n  }, {\n    key: \"removeHandlers\",\n    value: function removeHandlers(poolName, eventType, eventHandlers) {\n      if (!this.pools.has(poolName)) {\n        return;\n      }\n\n      var pool = this.pools.get(poolName);\n      var newPool = pool.removeHandlers(eventType, eventHandlers);\n\n      if (newPool.hasHandlers()) {\n        this.pools.set(poolName, newPool);\n      } else {\n        this.pools.delete(poolName);\n      }\n\n      var hasHandlers = false;\n      this.pools.forEach(function (pool) {\n        return hasHandlers = hasHandlers || pool.hasHandlers(eventType);\n      });\n\n      if (!hasHandlers) {\n        this.removeTargetHandler(eventType);\n      }\n    }\n  }, {\n    key: \"addTargetHandler\",\n    value: function addTargetHandler(eventType) {\n      var handler = this.createEmitter(eventType);\n      this.handlers.set(eventType, handler);\n      this.target.addEventListener(eventType, handler, true);\n    }\n  }, {\n    key: \"removeTargetHandler\",\n    value: function removeTargetHandler(eventType) {\n      if (this.handlers.has(eventType)) {\n        this.target.removeEventListener(eventType, this.handlers.get(eventType), true);\n        this.handlers.delete(eventType);\n      }\n    }\n  }]);\n\n  return EventTarget;\n}();\n\nvar EventStack =\n/*#__PURE__*/\nfunction () {\n  function EventStack() {\n    var _this = this;\n\n    _classCallCheck(this, EventStack);\n\n    _defineProperty(this, \"targets\", new Map());\n\n    _defineProperty(this, \"getTarget\", function (target) {\n      var autoCreate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n      var normalized = normalizeTarget(target);\n\n      if (_this.targets.has(normalized)) {\n        return _this.targets.get(normalized);\n      }\n\n      if (!autoCreate) return null;\n      var eventTarget = new EventTarget(normalized);\n\n      _this.targets.set(normalized, eventTarget);\n\n      return eventTarget;\n    });\n\n    _defineProperty(this, \"removeTarget\", function (target) {\n      _this.targets.delete(normalizeTarget(target));\n    });\n  }\n\n  _createClass(EventStack, [{\n    key: \"sub\",\n    value: function sub(eventName, eventHandlers) {\n      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n      if (!env.canUseDOM) return;\n      var _options$target = options.target,\n          target = _options$target === void 0 ? document : _options$target,\n          _options$pool = options.pool,\n          pool = _options$pool === void 0 ? 'default' : _options$pool;\n      var eventTarget = this.getTarget(target);\n      eventTarget.addHandlers(pool, eventName, normalizeHandlers(eventHandlers));\n    }\n  }, {\n    key: \"unsub\",\n    value: function unsub(eventName, eventHandlers) {\n      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n      if (!env.canUseDOM) return;\n      var _options$target2 = options.target,\n          target = _options$target2 === void 0 ? document : _options$target2,\n          _options$pool2 = options.pool,\n          pool = _options$pool2 === void 0 ? 'default' : _options$pool2;\n      var eventTarget = this.getTarget(target, false);\n\n      if (eventTarget) {\n        eventTarget.removeHandlers(pool, eventName, normalizeHandlers(eventHandlers));\n        if (!eventTarget.hasHandlers()) this.removeTarget(target);\n      }\n    }\n  }]);\n\n  return EventStack;\n}();\n\nvar instance = new EventStack();\n\n/**\n * This component exposes the EventStack API as public and provides a declarative way to manage it.\n */\nvar EventStack$1 =\n/*#__PURE__*/\nfunction (_React$PureComponent) {\n  _inherits(EventStack, _React$PureComponent);\n\n  function EventStack() {\n    _classCallCheck(this, EventStack);\n\n    return _possibleConstructorReturn(this, _getPrototypeOf(EventStack).apply(this, arguments));\n  }\n\n  _createClass(EventStack, [{\n    key: \"componentDidMount\",\n    value: function componentDidMount() {\n      this.subscribe(this.props);\n    }\n  }, {\n    key: \"componentDidUpdate\",\n    value: function componentDidUpdate(prevProps) {\n      this.unsubscribe(prevProps);\n      this.subscribe(this.props);\n    }\n  }, {\n    key: \"componentWillUnmount\",\n    value: function componentWillUnmount() {\n      this.unsubscribe(this.props);\n    }\n  }, {\n    key: \"subscribe\",\n    value: function subscribe(props) {\n      var name = props.name,\n          on = props.on,\n          pool = props.pool,\n          target = props.target;\n      instance.sub(name, on, {\n        pool: pool,\n        target: target\n      });\n    }\n  }, {\n    key: \"unsubscribe\",\n    value: function unsubscribe(props) {\n      var name = props.name,\n          on = props.on,\n          pool = props.pool,\n          target = props.target;\n      instance.unsub(name, on, {\n        pool: pool,\n        target: target\n      });\n    }\n  }, {\n    key: \"render\",\n    value: function render() {\n      return null;\n    }\n  }]);\n\n  return EventStack;\n}(React.PureComponent);\n\n_defineProperty(EventStack$1, \"defaultProps\", {\n  pool: 'default',\n  target: 'document'\n});\nEventStack$1.propTypes = {\n  /** An event name on which we will subscribe. */\n  name: PropTypes.string.isRequired,\n\n  /** An event handler or array of event handlers. */\n  on: PropTypes.oneOfType([PropTypes.func, PropTypes.arrayOf(PropTypes.func)]).isRequired,\n\n  /** A name of pool. */\n  pool: PropTypes.string,\n\n  /** A DOM element on which we will subscribe. */\n  target: PropTypes.oneOfType([PropTypes.oneOf(['document', 'window']), // Heads up!\n  // This condition for SSR safety.\n  PropTypes.instanceOf(env.canUseDOM ? HTMLElement : Object), PropTypes.shape({\n    current: PropTypes.object\n  })])\n};\n\nexports.instance = instance;\nexports.default = EventStack$1;\n","\n'use strict';\n\nvar stack;\n\nif (process.env.NODE_ENV === 'production') {\n  stack = require('./cjs/event-stack.production.js');\n} else {\n  stack = require('./cjs/event-stack.development.js');\n}\n\nmodule.exports = stack.default;\nmodule.exports.instance = stack.instance;\n","import * as PropTypes from 'prop-types';\nimport useEventListener from './useEventListener';\n\nfunction EventListener(props) {\n  useEventListener(props);\n  return null;\n}\n\nEventListener.displayName = 'EventListener'; // TODO: use Babel plugin for this\n\nEventListener.propTypes = process.env.NODE_ENV !== 'production' ? {\n  capture: PropTypes.bool,\n  listener: PropTypes.func.isRequired,\n  targetRef: PropTypes.shape({\n    current: PropTypes.object\n  }).isRequired,\n  type: PropTypes.string.isRequired\n} : {};\nEventListener.defaultProps = {\n  capture: false\n};\nexport default EventListener;","export var documentRef = {\n  current: typeof document === 'undefined' ? null : document\n};\nexport var windowRef = {\n  current: typeof window === 'undefined' ? null : window\n};\nexport { default as EventListener } from './EventListener';\nexport * from './types';\nexport { default as useEventListener } from './useEventListener';","import * as React from 'react';\n\nvar isActionSupported = function isActionSupported(targetRef, method) {\n  return targetRef && !!targetRef.current && !!targetRef.current[method];\n};\n\nvar useEventListener = function useEventListener(options) {\n  var capture = options.capture,\n      listener = options.listener,\n      type = options.type,\n      targetRef = options.targetRef;\n  var latestListener = React.useRef(listener);\n  latestListener.current = listener;\n  var eventHandler = React.useCallback(function (event) {\n    return latestListener.current(event);\n  }, []);\n  React.useEffect(function () {\n    if (isActionSupported(targetRef, 'addEventListener')) {\n      ;\n      targetRef.current.addEventListener(type, eventHandler, capture);\n    } else if (process.env.NODE_ENV !== 'production') {\n      throw new Error('@stardust-ui/react-component-event-listener: Passed `targetRef` is not valid or does not support `addEventListener()` method.');\n    }\n\n    return function () {\n      if (isActionSupported(targetRef, 'removeEventListener')) {\n        ;\n        targetRef.current.removeEventListener(type, eventHandler, capture);\n      } else if (process.env.NODE_ENV !== 'production') {\n        throw new Error('@stardust-ui/react-component-event-listener: Passed `targetRef` is not valid or does not support `removeEventListener()` method.');\n      }\n    };\n  }, [capture, targetRef, type]);\n};\n\nexport default useEventListener;","import * as PropTypes from 'prop-types';\nimport * as React from 'react';\nimport * as ReactIs from 'react-is';\nimport RefFindNode from './RefFindNode';\nimport RefForward from './RefForward';\nimport { refPropType } from './types';\n\nvar Ref = function Ref(props) {\n  var children = props.children,\n      innerRef = props.innerRef;\n  var child = React.Children.only(children);\n  var ElementType = ReactIs.isForwardRef(child) ? RefForward : RefFindNode;\n  return React.createElement(ElementType, {\n    innerRef: innerRef\n  }, child);\n};\n\nRef.displayName = 'Ref'; // TODO: use Babel plugin for this\n\nif (process.env.NODE_ENV !== 'production') {\n  Ref.propTypes = {\n    children: PropTypes.element.isRequired,\n    innerRef: refPropType.isRequired\n  };\n}\n\nexport default Ref;","import _classCallCheck from \"@babel/runtime/helpers/esm/classCallCheck\";\nimport _createClass from \"@babel/runtime/helpers/esm/createClass\";\nimport _possibleConstructorReturn from \"@babel/runtime/helpers/esm/possibleConstructorReturn\";\nimport _getPrototypeOf from \"@babel/runtime/helpers/esm/getPrototypeOf\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/esm/assertThisInitialized\";\nimport _inherits from \"@babel/runtime/helpers/esm/inherits\";\nimport _defineProperty from \"@babel/runtime/helpers/esm/defineProperty\";\nimport * as PropTypes from 'prop-types';\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport handleRef from './handleRef';\nimport { refPropType } from './types';\n\nvar RefFindNode =\n/*#__PURE__*/\nfunction (_React$Component) {\n  _inherits(RefFindNode, _React$Component);\n\n  function RefFindNode() {\n    var _getPrototypeOf2;\n\n    var _this;\n\n    _classCallCheck(this, RefFindNode);\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(RefFindNode)).call.apply(_getPrototypeOf2, [this].concat(args)));\n\n    _defineProperty(_assertThisInitialized(_this), \"prevNode\", null);\n\n    return _this;\n  }\n\n  _createClass(RefFindNode, [{\n    key: \"componentDidMount\",\n    value: function componentDidMount() {\n      this.prevNode = ReactDOM.findDOMNode(this);\n      handleRef(this.props.innerRef, this.prevNode);\n    }\n  }, {\n    key: \"componentDidUpdate\",\n    value: function componentDidUpdate(prevProps) {\n      var currentNode = ReactDOM.findDOMNode(this);\n\n      if (this.prevNode !== currentNode) {\n        this.prevNode = currentNode;\n        handleRef(this.props.innerRef, currentNode);\n      }\n\n      if (prevProps.innerRef !== this.props.innerRef) {\n        handleRef(this.props.innerRef, currentNode);\n      }\n    }\n  }, {\n    key: \"componentWillUnmount\",\n    value: function componentWillUnmount() {\n      handleRef(this.props.innerRef, null);\n    }\n  }, {\n    key: \"render\",\n    value: function render() {\n      var children = this.props.children;\n      return children;\n    }\n  }]);\n\n  return RefFindNode;\n}(React.Component);\n\n_defineProperty(RefFindNode, \"displayName\", 'RefFindNode');\n\n_defineProperty(RefFindNode, \"propTypes\", process.env.NODE_ENV !== 'production' ? {\n  children: PropTypes.element.isRequired,\n  innerRef: refPropType.isRequired\n} : {});\n\nexport { RefFindNode as default };","import _classCallCheck from \"@babel/runtime/helpers/esm/classCallCheck\";\nimport _createClass from \"@babel/runtime/helpers/esm/createClass\";\nimport _possibleConstructorReturn from \"@babel/runtime/helpers/esm/possibleConstructorReturn\";\nimport _getPrototypeOf from \"@babel/runtime/helpers/esm/getPrototypeOf\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/esm/assertThisInitialized\";\nimport _inherits from \"@babel/runtime/helpers/esm/inherits\";\nimport _defineProperty from \"@babel/runtime/helpers/esm/defineProperty\";\nimport * as PropTypes from 'prop-types';\nimport * as React from 'react';\nimport handleRef from './handleRef';\nimport { refPropType } from './types';\n\nvar RefForward =\n/*#__PURE__*/\nfunction (_React$Component) {\n  _inherits(RefForward, _React$Component);\n\n  function RefForward() {\n    var _getPrototypeOf2;\n\n    var _this;\n\n    _classCallCheck(this, RefForward);\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(RefForward)).call.apply(_getPrototypeOf2, [this].concat(args)));\n\n    _defineProperty(_assertThisInitialized(_this), \"handleRefOverride\", function (node) {\n      var _this$props = _this.props,\n          children = _this$props.children,\n          innerRef = _this$props.innerRef;\n      handleRef(children.ref, node);\n      handleRef(innerRef, node);\n    });\n\n    return _this;\n  }\n\n  _createClass(RefForward, [{\n    key: \"render\",\n    value: function render() {\n      var children = this.props.children;\n      return React.cloneElement(children, {\n        ref: this.handleRefOverride\n      });\n    }\n  }]);\n\n  return RefForward;\n}(React.Component);\n\n_defineProperty(RefForward, \"displayName\", 'RefForward');\n\n_defineProperty(RefForward, \"propTypes\", process.env.NODE_ENV !== 'production' ? {\n  children: PropTypes.element.isRequired,\n  innerRef: refPropType.isRequired\n} : {});\n\nexport { RefForward as default };","import _typeof from \"@babel/runtime/helpers/esm/typeof\";\n\n/**\n * The function that correctly handles passing refs.\n *\n * @param ref An ref object or function\n * @param node A node that should be passed by ref\n */\nvar handleRef = function handleRef(ref, node) {\n  if (process.env.NODE_ENV !== 'production') {\n    if (typeof ref === 'string') {\n      throw new Error('We do not support refs as string, this is a legacy API and will be likely to be removed in one of the future releases of React.');\n    }\n  }\n\n  if (typeof ref === 'function') {\n    ref(node);\n    return;\n  }\n\n  if (ref !== null && _typeof(ref) === 'object') {\n    // The `current` property is defined as readonly, however it's a valid way because\n    // `ref` is a mutable object\n    ;\n    ref.current = node;\n  }\n};\n\nexport default handleRef;","export { default as handleRef } from './handleRef';\nexport { default as isRefObject } from './isRefObject';\nexport { default as toRefObject } from './toRefObject';\nexport { default as Ref } from './Ref';\nexport { default as RefFindNode } from './RefFindNode';\nexport { default as RefForward } from './RefForward';\nexport * from './types';","import _typeof from \"@babel/runtime/helpers/esm/typeof\";\n\n/** Checks that the passed object is a valid React ref object. */\nvar isRefObject = function isRefObject(ref) {\n  return (// https://github.com/facebook/react/blob/v16.8.2/packages/react-reconciler/src/ReactFiberCommitWork.js#L665\n    ref !== null && _typeof(ref) === 'object' && ref.hasOwnProperty('current')\n  );\n};\n\nexport default isRefObject;","var nullRefObject = {\n  current: null // A map of created ref objects to provide memoization.\n\n};\nvar refObjects = new WeakMap();\n/** Creates a React ref object from existing DOM node. */\n\nvar toRefObject = function toRefObject(node) {\n  // A \"null\" is not valid key for a WeakMap\n  if (node === null) {\n    return nullRefObject;\n  }\n\n  if (refObjects.has(node)) {\n    return refObjects.get(node);\n  }\n\n  var refObject = {\n    current: node\n  };\n  refObjects.set(node, refObject);\n  return refObject;\n};\n\nexport default toRefObject;","import * as PropTypes from 'prop-types';\n\n/** A checker that matches the React.Ref type. */\nexport var refPropType = PropTypes.oneOfType([PropTypes.func, PropTypes.object]);","/*!\n  Copyright (c) 2017 Jed Watson.\n  Licensed under the MIT License (MIT), see\n  http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg) && arg.length) {\n\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\tif (inner) {\n\t\t\t\t\tclasses.push(inner);\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","function toVal(mix) {\n\tvar k, y, str='';\n\n\tif (typeof mix === 'string' || typeof mix === 'number') {\n\t\tstr += mix;\n\t} else if (typeof mix === 'object') {\n\t\tif (Array.isArray(mix)) {\n\t\t\tfor (k=0; k < mix.length; k++) {\n\t\t\t\tif (mix[k]) {\n\t\t\t\t\tif (y = toVal(mix[k])) {\n\t\t\t\t\t\tstr && (str += ' ');\n\t\t\t\t\t\tstr += y;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (k in mix) {\n\t\t\t\tif (mix[k]) {\n\t\t\t\t\tstr && (str += ' ');\n\t\t\t\t\tstr += k;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn str;\n}\n\nexport default function () {\n\tvar i=0, tmp, x, str='';\n\twhile (i < arguments.length) {\n\t\tif (tmp = arguments[i++]) {\n\t\t\tif (x = toVal(tmp)) {\n\t\t\t\tstr && (str += ' ');\n\t\t\t\tstr += x\n\t\t\t}\n\t\t}\n\t}\n\treturn str;\n}\n","'use strict';\n\nexports.__esModule = true;\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = require('prop-types');\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _gud = require('gud');\n\nvar _gud2 = _interopRequireDefault(_gud);\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar MAX_SIGNED_31_BIT_INT = 1073741823;\n\n// Inlined Object.is polyfill.\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\nfunction objectIs(x, y) {\n  if (x === y) {\n    return x !== 0 || 1 / x === 1 / y;\n  } else {\n    return x !== x && y !== y;\n  }\n}\n\nfunction createEventEmitter(value) {\n  var handlers = [];\n  return {\n    on: function on(handler) {\n      handlers.push(handler);\n    },\n    off: function off(handler) {\n      handlers = handlers.filter(function (h) {\n        return h !== handler;\n      });\n    },\n    get: function get() {\n      return value;\n    },\n    set: function set(newValue, changedBits) {\n      value = newValue;\n      handlers.forEach(function (handler) {\n        return handler(value, changedBits);\n      });\n    }\n  };\n}\n\nfunction onlyChild(children) {\n  return Array.isArray(children) ? children[0] : children;\n}\n\nfunction createReactContext(defaultValue, calculateChangedBits) {\n  var _Provider$childContex, _Consumer$contextType;\n\n  var contextProp = '__create-react-context-' + (0, _gud2.default)() + '__';\n\n  var Provider = function (_Component) {\n    _inherits(Provider, _Component);\n\n    function Provider() {\n      var _temp, _this, _ret;\n\n      _classCallCheck(this, Provider);\n\n      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n        args[_key] = arguments[_key];\n      }\n\n      return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.emitter = createEventEmitter(_this.props.value), _temp), _possibleConstructorReturn(_this, _ret);\n    }\n\n    Provider.prototype.getChildContext = function getChildContext() {\n      var _ref;\n\n      return _ref = {}, _ref[contextProp] = this.emitter, _ref;\n    };\n\n    Provider.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {\n      if (this.props.value !== nextProps.value) {\n        var oldValue = this.props.value;\n        var newValue = nextProps.value;\n        var changedBits = void 0;\n\n        if (objectIs(oldValue, newValue)) {\n          changedBits = 0; // No change\n        } else {\n          changedBits = typeof calculateChangedBits === 'function' ? calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;\n          if (process.env.NODE_ENV !== 'production') {\n            (0, _warning2.default)((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);\n          }\n\n          changedBits |= 0;\n\n          if (changedBits !== 0) {\n            this.emitter.set(nextProps.value, changedBits);\n          }\n        }\n      }\n    };\n\n    Provider.prototype.render = function render() {\n      return this.props.children;\n    };\n\n    return Provider;\n  }(_react.Component);\n\n  Provider.childContextTypes = (_Provider$childContex = {}, _Provider$childContex[contextProp] = _propTypes2.default.object.isRequired, _Provider$childContex);\n\n  var Consumer = function (_Component2) {\n    _inherits(Consumer, _Component2);\n\n    function Consumer() {\n      var _temp2, _this2, _ret2;\n\n      _classCallCheck(this, Consumer);\n\n      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n        args[_key2] = arguments[_key2];\n      }\n\n      return _ret2 = (_temp2 = (_this2 = _possibleConstructorReturn(this, _Component2.call.apply(_Component2, [this].concat(args))), _this2), _this2.state = {\n        value: _this2.getValue()\n      }, _this2.onUpdate = function (newValue, changedBits) {\n        var observedBits = _this2.observedBits | 0;\n        if ((observedBits & changedBits) !== 0) {\n          _this2.setState({ value: _this2.getValue() });\n        }\n      }, _temp2), _possibleConstructorReturn(_this2, _ret2);\n    }\n\n    Consumer.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {\n      var observedBits = nextProps.observedBits;\n\n      this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default\n      : observedBits;\n    };\n\n    Consumer.prototype.componentDidMount = function componentDidMount() {\n      if (this.context[contextProp]) {\n        this.context[contextProp].on(this.onUpdate);\n      }\n      var observedBits = this.props.observedBits;\n\n      this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default\n      : observedBits;\n    };\n\n    Consumer.prototype.componentWillUnmount = function componentWillUnmount() {\n      if (this.context[contextProp]) {\n        this.context[contextProp].off(this.onUpdate);\n      }\n    };\n\n    Consumer.prototype.getValue = function getValue() {\n      if (this.context[contextProp]) {\n        return this.context[contextProp].get();\n      } else {\n        return defaultValue;\n      }\n    };\n\n    Consumer.prototype.render = function render() {\n      return onlyChild(this.props.children)(this.state.value);\n    };\n\n    return Consumer;\n  }(_react.Component);\n\n  Consumer.contextTypes = (_Consumer$contextType = {}, _Consumer$contextType[contextProp] = _propTypes2.default.object, _Consumer$contextType);\n\n\n  return {\n    Provider: Provider,\n    Consumer: Consumer\n  };\n}\n\nexports.default = createReactContext;\nmodule.exports = exports['default'];","'use strict';\n\nexports.__esModule = true;\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _implementation = require('./implementation');\n\nvar _implementation2 = _interopRequireDefault(_implementation);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = _react2.default.createContext || _implementation2.default;\nmodule.exports = exports['default'];","// Imports\nimport ___CSS_LOADER_API_IMPORT___ from \"../../css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(true);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".clndr-calendars-segment{text-align:center;margin-bottom:.25rem!important;margin-top:.25rem!important}.clndr-calendars-segment.clndr-floating{position:absolute!important;z-index:2000}.clndr-calendars-wrapper{display:grid;grid-gap:1em;grid-template-columns:repeat(var(--n,1),1fr)}.clndr-control{display:grid;grid-template-columns:repeat(3,1fr);margin-bottom:10px;align-items:center}.clndr-days{text-align:center;display:grid;grid-gap:1px;grid-template-columns:repeat(7,2.2rem);background-color:rgba(0,0,0,.1);border:1px solid rgba(0,0,0,.1);border-radius:.28571429rem;overflow:hidden}.clndr-left{left:0}.clndr-right{right:0}.clndr-top{bottom:100%}.clndr-bottom{top:100%}.clndr-calendars-segment.clndr-top{box-shadow:0 -1px 2px 0 rgba(34,36,38,.15)!important;margin-bottom:.25rem!important}\\n.clndr-cell{background-color:#fff;transition:all .2s;padding:5px 0;height:30px;cursor:pointer}.clndr-cell:hover{background-color:#cacbcd;color:inherit}.clndr-cell-today{background-color:#e0e1e2}.clndr-cell-inrange{background-color:#cacbcd;color:inherit}.clndr-cell-disabled{cursor:default;opacity:.45}.clndr-cell-disabled:hover{background-color:#fff}.clndr-cell-selected{background-color:#4f4f4f;color:#f2f2f2}.clndr-cell-other-month{color:#d9d9d9}\", \"\",{\"version\":3,\"sources\":[\"react-semantic-ui-datepickers.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB,iBAAiB,CAAC,8BAA8B,CAAC,2BAA2B,CAAC,wCAAwC,2BAA2B,CAAC,YAAY,CAAC,yBAAyB,YAAY,CAAC,YAAY,CAAC,4CAA4C,CAAC,eAAe,YAAY,CAAC,mCAAmC,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,YAAY,iBAAiB,CAAC,YAAY,CAAC,YAAY,CAAC,sCAAsC,CAAC,+BAA+B,CAAC,+BAA+B,CAAC,0BAA0B,CAAC,eAAe,CAAC,YAAY,MAAM,CAAC,aAAa,OAAO,CAAC,WAAW,WAAW,CAAC,cAAc,QAAQ,CAAC,mCAAmC,oDAAoD,CAAC,8BAA8B;AACnxB,YAAY,qBAAqB,CAAC,kBAAkB,CAAC,aAAa,CAAC,WAAW,CAAC,cAAc,CAAC,kBAAkB,wBAAwB,CAAC,aAAa,CAAC,kBAAkB,wBAAwB,CAAC,oBAAoB,wBAAwB,CAAC,aAAa,CAAC,qBAAqB,cAAc,CAAC,WAAW,CAAC,2BAA2B,qBAAqB,CAAC,qBAAqB,wBAAwB,CAAC,aAAa,CAAC,wBAAwB,aAAa\",\"file\":\"react-semantic-ui-datepickers.css\",\"sourcesContent\":[\".clndr-calendars-segment{text-align:center;margin-bottom:.25rem!important;margin-top:.25rem!important}.clndr-calendars-segment.clndr-floating{position:absolute!important;z-index:2000}.clndr-calendars-wrapper{display:grid;grid-gap:1em;grid-template-columns:repeat(var(--n,1),1fr)}.clndr-control{display:grid;grid-template-columns:repeat(3,1fr);margin-bottom:10px;align-items:center}.clndr-days{text-align:center;display:grid;grid-gap:1px;grid-template-columns:repeat(7,2.2rem);background-color:rgba(0,0,0,.1);border:1px solid rgba(0,0,0,.1);border-radius:.28571429rem;overflow:hidden}.clndr-left{left:0}.clndr-right{right:0}.clndr-top{bottom:100%}.clndr-bottom{top:100%}.clndr-calendars-segment.clndr-top{box-shadow:0 -1px 2px 0 rgba(34,36,38,.15)!important;margin-bottom:.25rem!important}\\n.clndr-cell{background-color:#fff;transition:all .2s;padding:5px 0;height:30px;cursor:pointer}.clndr-cell:hover{background-color:#cacbcd;color:inherit}.clndr-cell-today{background-color:#e0e1e2}.clndr-cell-inrange{background-color:#cacbcd;color:inherit}.clndr-cell-disabled{cursor:default;opacity:.45}.clndr-cell-disabled:hover{background-color:#fff}.clndr-cell-selected{background-color:#4f4f4f;color:#f2f2f2}.clndr-cell-other-month{color:#d9d9d9}\"]}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_IMPORT___ from \"../css-loader/dist/runtime/api.js\";\nimport ___CSS_LOADER_GET_URL_IMPORT___ from \"../css-loader/dist/runtime/getUrl.js\";\nimport ___CSS_LOADER_URL_IMPORT_0___ from \"./themes/default/assets/images/flags.png\";\nimport ___CSS_LOADER_URL_IMPORT_1___ from \"./themes/default/assets/fonts/icons.eot\";\nimport ___CSS_LOADER_URL_IMPORT_2___ from \"./themes/default/assets/fonts/icons.woff2\";\nimport ___CSS_LOADER_URL_IMPORT_3___ from \"./themes/default/assets/fonts/icons.woff\";\nimport ___CSS_LOADER_URL_IMPORT_4___ from \"./themes/default/assets/fonts/icons.ttf\";\nimport ___CSS_LOADER_URL_IMPORT_5___ from \"./themes/default/assets/fonts/icons.svg\";\nimport ___CSS_LOADER_URL_IMPORT_6___ from \"./themes/default/assets/fonts/outline-icons.eot\";\nimport ___CSS_LOADER_URL_IMPORT_7___ from \"./themes/default/assets/fonts/outline-icons.woff2\";\nimport ___CSS_LOADER_URL_IMPORT_8___ from \"./themes/default/assets/fonts/outline-icons.woff\";\nimport ___CSS_LOADER_URL_IMPORT_9___ from \"./themes/default/assets/fonts/outline-icons.ttf\";\nimport ___CSS_LOADER_URL_IMPORT_10___ from \"./themes/default/assets/fonts/outline-icons.svg\";\nimport ___CSS_LOADER_URL_IMPORT_11___ from \"./themes/default/assets/fonts/brand-icons.eot\";\nimport ___CSS_LOADER_URL_IMPORT_12___ from \"./themes/default/assets/fonts/brand-icons.woff2\";\nimport ___CSS_LOADER_URL_IMPORT_13___ from \"./themes/default/assets/fonts/brand-icons.woff\";\nimport ___CSS_LOADER_URL_IMPORT_14___ from \"./themes/default/assets/fonts/brand-icons.ttf\";\nimport ___CSS_LOADER_URL_IMPORT_15___ from \"./themes/default/assets/fonts/brand-icons.svg\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(true);\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin);\"]);\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);\nvar ___CSS_LOADER_URL_REPLACEMENT_1___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_1___);\nvar ___CSS_LOADER_URL_REPLACEMENT_2___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_1___, { hash: \"?#iefix\" });\nvar ___CSS_LOADER_URL_REPLACEMENT_3___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_2___);\nvar ___CSS_LOADER_URL_REPLACEMENT_4___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_3___);\nvar ___CSS_LOADER_URL_REPLACEMENT_5___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_4___);\nvar ___CSS_LOADER_URL_REPLACEMENT_6___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_5___, { hash: \"#icons\" });\nvar ___CSS_LOADER_URL_REPLACEMENT_7___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_6___);\nvar ___CSS_LOADER_URL_REPLACEMENT_8___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_6___, { hash: \"?#iefix\" });\nvar ___CSS_LOADER_URL_REPLACEMENT_9___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_7___);\nvar ___CSS_LOADER_URL_REPLACEMENT_10___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_8___);\nvar ___CSS_LOADER_URL_REPLACEMENT_11___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_9___);\nvar ___CSS_LOADER_URL_REPLACEMENT_12___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_10___, { hash: \"#icons\" });\nvar ___CSS_LOADER_URL_REPLACEMENT_13___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_11___);\nvar ___CSS_LOADER_URL_REPLACEMENT_14___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_11___, { hash: \"?#iefix\" });\nvar ___CSS_LOADER_URL_REPLACEMENT_15___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_12___);\nvar ___CSS_LOADER_URL_REPLACEMENT_16___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_13___);\nvar ___CSS_LOADER_URL_REPLACEMENT_17___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_14___);\nvar ___CSS_LOADER_URL_REPLACEMENT_18___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_15___, { hash: \"#icons\" });\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \" /*\\n * # Semantic UI - 2.4.0\\n * https://github.com/Semantic-Org/Semantic-UI\\n * http://www.semantic-ui.com/\\n *\\n * Copyright 2014 Contributors\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n *//*!\\n * # Semantic UI 2.4.0 - Reset\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}html{-webkit-box-sizing:border-box;box-sizing:border-box}input[type=email],input[type=password],input[type=search],input[type=text]{-webkit-appearance:none;-moz-appearance:none}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*!\\n * # Semantic UI 2.4.0 - Site\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */body,html{height:100%}html{font-size:14px}body{margin:0;padding:0;overflow-x:hidden;min-width:320px;background:#fff;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:14px;line-height:1.4285em;color:rgba(0,0,0,.87);font-smoothing:antialiased}h1,h2,h3,h4,h5{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;line-height:1.28571429em;margin:calc(2rem - .14285714em) 0 1rem;font-weight:700;padding:0}h1{min-height:1rem;font-size:2rem}h2{font-size:1.71428571rem}h3{font-size:1.28571429rem}h4{font-size:1.07142857rem}h5{font-size:1rem}h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child{margin-top:0}h1:last-child,h2:last-child,h3:last-child,h4:last-child,h5:last-child{margin-bottom:0}p{margin:0 0 1em;line-height:1.4285em}p:first-child{margin-top:0}p:last-child{margin-bottom:0}a{color:#4183c4;text-decoration:none}a:hover{color:#1e70bf;text-decoration:none}::-webkit-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::-moz-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}input::-webkit-selection,textarea::-webkit-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::-moz-selection,textarea::-moz-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::selection,textarea::selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}body ::-webkit-scrollbar{-webkit-appearance:none;width:10px;height:10px}body ::-webkit-scrollbar-track{background:rgba(0,0,0,.1);border-radius:0}body ::-webkit-scrollbar-thumb{cursor:pointer;border-radius:5px;background:rgba(0,0,0,.25);-webkit-transition:color .2s ease;transition:color .2s ease}body ::-webkit-scrollbar-thumb:window-inactive{background:rgba(0,0,0,.15)}body ::-webkit-scrollbar-thumb:hover{background:rgba(128,135,139,.8)}body .ui.inverted::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}body .ui.inverted::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}body .ui.inverted::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}body .ui.inverted::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}/*!\\n * # Semantic UI 2.4.0 - Button\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.button{cursor:pointer;display:inline-block;min-height:1em;outline:0;border:none;vertical-align:baseline;background:#e0e1e2 none;color:rgba(0,0,0,.6);font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;margin:0 .25em 0 0;padding:.78571429em 1.5em .78571429em;text-transform:none;text-shadow:none;font-weight:700;line-height:1em;font-style:normal;text-align:center;text-decoration:none;border-radius:.28571429rem;-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;will-change:'';-webkit-tap-highlight-color:transparent}.ui.button:hover{background-color:#cacbcd;background-image:none;-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;color:rgba(0,0,0,.8)}.ui.button:hover .icon{opacity:.85}.ui.button:focus{background-color:#cacbcd;color:rgba(0,0,0,.8);background-image:''!important;-webkit-box-shadow:''!important;box-shadow:''!important}.ui.button:focus .icon{opacity:.85}.ui.active.button:active,.ui.button:active{background-color:#babbbc;background-image:'';color:rgba(0,0,0,.9);-webkit-box-shadow:0 0 0 1px transparent inset,none;box-shadow:0 0 0 1px transparent inset,none}.ui.active.button{background-color:#c0c1c2;background-image:none;-webkit-box-shadow:0 0 0 1px transparent inset;box-shadow:0 0 0 1px transparent inset;color:rgba(0,0,0,.95)}.ui.active.button:hover{background-color:#c0c1c2;background-image:none;color:rgba(0,0,0,.95)}.ui.active.button:active{background-color:#c0c1c2;background-image:none}.ui.loading.loading.loading.loading.loading.loading.button{position:relative;cursor:default;text-shadow:none!important;color:transparent!important;opacity:1;pointer-events:auto;-webkit-transition:all 0s linear,opacity .1s ease;transition:all 0s linear,opacity .1s ease}.ui.loading.button:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.15)}.ui.loading.button:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#fff transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.labeled.icon.loading.button .icon{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}@-webkit-keyframes button-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes button-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.basic.loading.button:not(.inverted):before{border-color:rgba(0,0,0,.1)}.ui.basic.loading.button:not(.inverted):after{border-top-color:#767676}.ui.button:disabled,.ui.buttons .disabled.button,.ui.disabled.active.button,.ui.disabled.button,.ui.disabled.button:hover{cursor:default;opacity:.45!important;background-image:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;pointer-events:none!important}.ui.basic.buttons .ui.disabled.button{border-color:rgba(34,36,38,.5)}.ui.animated.button{position:relative;overflow:hidden;padding-right:0!important;vertical-align:middle;z-index:1}.ui.animated.button .content{will-change:transform,opacity}.ui.animated.button .visible.content{position:relative;margin-right:1.5em}.ui.animated.button .hidden.content{position:absolute;width:100%}.ui.animated.button .hidden.content,.ui.animated.button .visible.content{-webkit-transition:right .3s ease 0s;transition:right .3s ease 0s}.ui.animated.button .visible.content{left:auto;right:0}.ui.animated.button .hidden.content{top:50%;left:auto;right:-100%;margin-top:-.5em}.ui.animated.button:focus .visible.content,.ui.animated.button:hover .visible.content{left:auto;right:200%}.ui.animated.button:focus .hidden.content,.ui.animated.button:hover .hidden.content{left:auto;right:0}.ui.vertical.animated.button .hidden.content,.ui.vertical.animated.button .visible.content{-webkit-transition:top .3s ease,-webkit-transform .3s ease;transition:top .3s ease,-webkit-transform .3s ease;transition:top .3s ease,transform .3s ease;transition:top .3s ease,transform .3s ease,-webkit-transform .3s ease}.ui.vertical.animated.button .visible.content{-webkit-transform:translateY(0);transform:translateY(0);right:auto}.ui.vertical.animated.button .hidden.content{top:-50%;left:0;right:auto}.ui.vertical.animated.button:focus .visible.content,.ui.vertical.animated.button:hover .visible.content{-webkit-transform:translateY(200%);transform:translateY(200%);right:auto}.ui.vertical.animated.button:focus .hidden.content,.ui.vertical.animated.button:hover .hidden.content{top:50%;right:auto}.ui.fade.animated.button .hidden.content,.ui.fade.animated.button .visible.content{-webkit-transition:opacity .3s ease,-webkit-transform .3s ease;transition:opacity .3s ease,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease;transition:opacity .3s ease,transform .3s ease,-webkit-transform .3s ease}.ui.fade.animated.button .visible.content{left:auto;right:auto;opacity:1;-webkit-transform:scale(1);transform:scale(1)}.ui.fade.animated.button .hidden.content{opacity:0;left:0;right:auto;-webkit-transform:scale(1.5);transform:scale(1.5)}.ui.fade.animated.button:focus .visible.content,.ui.fade.animated.button:hover .visible.content{left:auto;right:auto;opacity:0;-webkit-transform:scale(.75);transform:scale(.75)}.ui.fade.animated.button:focus .hidden.content,.ui.fade.animated.button:hover .hidden.content{left:0;right:auto;opacity:1;-webkit-transform:scale(1);transform:scale(1)}.ui.inverted.button{-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;background:transparent none;color:#fff;text-shadow:none!important}.ui.inverted.buttons .button{margin:0 0 0 -2px}.ui.inverted.buttons .button:first-child{margin-left:0}.ui.inverted.vertical.buttons .button{margin:0 0 -2px 0}.ui.inverted.vertical.buttons .button:first-child{margin-top:0}.ui.inverted.button:hover{background:#fff;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;color:rgba(0,0,0,.8)}.ui.inverted.button.active,.ui.inverted.button:focus{background:#fff;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;color:rgba(0,0,0,.8)}.ui.inverted.button.active:focus{background:#dcddde;-webkit-box-shadow:0 0 0 2px #dcddde inset!important;box-shadow:0 0 0 2px #dcddde inset!important;color:rgba(0,0,0,.8)}.ui.labeled.button:not(.icon){display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;background:0 0!important;padding:0!important;border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.labeled.button>.button{margin:0}.ui.labeled.button>.label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 0 0 -1px!important;padding:'';font-size:1em;border-color:rgba(34,36,38,.15)}.ui.labeled.button>.tag.label:before{width:1.85em;height:1.85em}.ui.labeled.button:not([class*=\\\"left labeled\\\"])>.button{border-top-right-radius:0;border-bottom-right-radius:0}.ui.labeled.button:not([class*=\\\"left labeled\\\"])>.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"left labeled\\\"].button>.button{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"left labeled\\\"].button>.label{border-top-right-radius:0;border-bottom-right-radius:0}.ui.facebook.button{background-color:#3b5998;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.facebook.button:hover{background-color:#304d8a;color:#fff;text-shadow:none}.ui.facebook.button:active{background-color:#2d4373;color:#fff;text-shadow:none}.ui.twitter.button{background-color:#55acee;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.twitter.button:hover{background-color:#35a2f4;color:#fff;text-shadow:none}.ui.twitter.button:active{background-color:#2795e9;color:#fff;text-shadow:none}.ui.google.plus.button{background-color:#dd4b39;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.google.plus.button:hover{background-color:#e0321c;color:#fff;text-shadow:none}.ui.google.plus.button:active{background-color:#c23321;color:#fff;text-shadow:none}.ui.linkedin.button{background-color:#1f88be;color:#fff;text-shadow:none}.ui.linkedin.button:hover{background-color:#147baf;color:#fff;text-shadow:none}.ui.linkedin.button:active{background-color:#186992;color:#fff;text-shadow:none}.ui.youtube.button{background-color:red;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.youtube.button:hover{background-color:#e60000;color:#fff;text-shadow:none}.ui.youtube.button:active{background-color:#c00;color:#fff;text-shadow:none}.ui.instagram.button{background-color:#49769c;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.instagram.button:hover{background-color:#3d698e;color:#fff;text-shadow:none}.ui.instagram.button:active{background-color:#395c79;color:#fff;text-shadow:none}.ui.pinterest.button{background-color:#bd081c;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pinterest.button:hover{background-color:#ac0013;color:#fff;text-shadow:none}.ui.pinterest.button:active{background-color:#8c0615;color:#fff;text-shadow:none}.ui.vk.button{background-color:#4d7198;color:#fff;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.vk.button:hover{background-color:#41648a;color:#fff}.ui.vk.button:active{background-color:#3c5876;color:#fff}.ui.button>.icon:not(.button){height:.85714286em;opacity:.8;margin:0 .42857143em 0 -.21428571em;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;vertical-align:'';color:''}.ui.button:not(.icon)>.icon:not(.button):not(.dropdown){margin:0 .42857143em 0 -.21428571em}.ui.button:not(.icon)>.right.icon:not(.button):not(.dropdown){margin:0 -.21428571em 0 .42857143em}.ui[class*=\\\"left floated\\\"].button,.ui[class*=\\\"left floated\\\"].buttons{float:left;margin-left:0;margin-right:.25em}.ui[class*=\\\"right floated\\\"].button,.ui[class*=\\\"right floated\\\"].buttons{float:right;margin-right:0;margin-left:.25em}.ui.compact.button,.ui.compact.buttons .button{padding:.58928571em 1.125em .58928571em}.ui.compact.icon.button,.ui.compact.icon.buttons .button{padding:.58928571em .58928571em .58928571em}.ui.compact.labeled.icon.button,.ui.compact.labeled.icon.buttons .button{padding:.58928571em 3.69642857em .58928571em}.ui.mini.button,.ui.mini.buttons .button,.ui.mini.buttons .or{font-size:.78571429rem}.ui.tiny.button,.ui.tiny.buttons .button,.ui.tiny.buttons .or{font-size:.85714286rem}.ui.small.button,.ui.small.buttons .button,.ui.small.buttons .or{font-size:.92857143rem}.ui.button,.ui.buttons .button,.ui.buttons .or{font-size:1rem}.ui.large.button,.ui.large.buttons .button,.ui.large.buttons .or{font-size:1.14285714rem}.ui.big.button,.ui.big.buttons .button,.ui.big.buttons .or{font-size:1.28571429rem}.ui.huge.button,.ui.huge.buttons .button,.ui.huge.buttons .or{font-size:1.42857143rem}.ui.massive.button,.ui.massive.buttons .button,.ui.massive.buttons .or{font-size:1.71428571rem}.ui.icon.button,.ui.icon.buttons .button{padding:.78571429em .78571429em .78571429em}.ui.icon.button>.icon,.ui.icon.buttons .button>.icon{opacity:.9;margin:0!important;vertical-align:top}.ui.basic.button,.ui.basic.buttons .button{background:transparent none!important;color:rgba(0,0,0,.6)!important;font-weight:400;border-radius:.28571429rem;text-transform:none;text-shadow:none!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.basic.buttons{-webkit-box-shadow:none;box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem}.ui.basic.buttons .button{border-radius:0}.ui.basic.button:hover,.ui.basic.buttons .button:hover{background:#fff!important;color:rgba(0,0,0,.8)!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:focus,.ui.basic.buttons .button:focus{background:#fff!important;color:rgba(0,0,0,.8)!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:active,.ui.basic.buttons .button:active{background:#f8f8f8!important;color:rgba(0,0,0,.9)!important;-webkit-box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset}.ui.basic.active.button,.ui.basic.buttons .active.button{background:rgba(0,0,0,.05)!important;-webkit-box-shadow:''!important;box-shadow:''!important;color:rgba(0,0,0,.95)!important}.ui.basic.active.button:hover,.ui.basic.buttons .active.button:hover{background-color:rgba(0,0,0,.05)}.ui.basic.buttons .button:hover{-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset inset}.ui.basic.buttons .button:active{-webkit-box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset inset;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset inset}.ui.basic.buttons .active.button{-webkit-box-shadow:''!important;box-shadow:''!important}.ui.basic.inverted.button,.ui.basic.inverted.buttons .button{background-color:transparent!important;color:#f9fafb!important;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important}.ui.basic.inverted.button:hover,.ui.basic.inverted.buttons .button:hover{color:#fff!important;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.inverted.button:focus,.ui.basic.inverted.buttons .button:focus{color:#fff!important;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.inverted.button:active,.ui.basic.inverted.buttons .button:active{background-color:rgba(255,255,255,.08)!important;color:#fff!important;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.9) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.9) inset!important}.ui.basic.inverted.active.button,.ui.basic.inverted.buttons .active.button{background-color:rgba(255,255,255,.08);color:#fff;text-shadow:none;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.7) inset;box-shadow:0 0 0 2px rgba(255,255,255,.7) inset}.ui.basic.inverted.active.button:hover,.ui.basic.inverted.buttons .active.button:hover{background-color:rgba(255,255,255,.15);-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.buttons .button{border-left:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.vertical.buttons .button{border-left:none}.ui.basic.vertical.buttons .button{border-left-width:0;border-top:1px solid rgba(34,36,38,.15)}.ui.basic.vertical.buttons .button:first-child{border-top-width:0}.ui.labeled.icon.button,.ui.labeled.icon.buttons .button{position:relative;padding-left:4.07142857em!important;padding-right:1.5em!important}.ui.labeled.icon.button>.icon,.ui.labeled.icon.buttons>.button>.icon{position:absolute;height:100%;line-height:1;border-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit;text-align:center;margin:0;width:2.57142857em;background-color:rgba(0,0,0,.05);color:'';-webkit-box-shadow:-1px 0 0 0 transparent inset;box-shadow:-1px 0 0 0 transparent inset}.ui.labeled.icon.button>.icon,.ui.labeled.icon.buttons>.button>.icon{top:0;left:0}.ui[class*=\\\"right labeled\\\"].icon.button{padding-right:4.07142857em!important;padding-left:1.5em!important}.ui[class*=\\\"right labeled\\\"].icon.button>.icon{left:auto;right:0;border-radius:0;border-top-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-box-shadow:1px 0 0 0 transparent inset;box-shadow:1px 0 0 0 transparent inset}.ui.labeled.icon.button>.icon:after,.ui.labeled.icon.button>.icon:before,.ui.labeled.icon.buttons>.button>.icon:after,.ui.labeled.icon.buttons>.button>.icon:before{display:block;position:absolute;width:100%;top:50%;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ui.labeled.icon.buttons .button>.icon{border-radius:0}.ui.labeled.icon.buttons .button:first-child>.icon{border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.labeled.icon.buttons .button:last-child>.icon{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:first-child>.icon{border-radius:0;border-top-left-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:last-child>.icon{border-radius:0;border-bottom-left-radius:.28571429rem}.ui.fluid[class*=\\\"left labeled\\\"].icon.button,.ui.fluid[class*=\\\"right labeled\\\"].icon.button{padding-left:1.5em!important;padding-right:1.5em!important}.ui.button.toggle.active,.ui.buttons .button.toggle.active,.ui.toggle.buttons .active.button{background-color:#21ba45!important;-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none;color:#fff!important}.ui.button.toggle.active:hover{background-color:#16ab39!important;text-shadow:none;color:#fff!important}.ui.circular.button{border-radius:10em}.ui.circular.button>.icon{width:1em;vertical-align:baseline}.ui.buttons .or{position:relative;width:.3em;height:2.57142857em;z-index:3}.ui.buttons .or:before{position:absolute;text-align:center;border-radius:500rem;content:'or';top:50%;left:50%;background-color:#fff;text-shadow:none;margin-top:-.89285714em;margin-left:-.89285714em;width:1.78571429em;height:1.78571429em;line-height:1.78571429em;color:rgba(0,0,0,.4);font-style:normal;font-weight:700;-webkit-box-shadow:0 0 0 1px transparent inset;box-shadow:0 0 0 1px transparent inset}.ui.buttons .or[data-text]:before{content:attr(data-text)}.ui.fluid.buttons .or{width:0!important}.ui.fluid.buttons .or:after{display:none}.ui.attached.button{position:relative;display:block;margin:0;border-radius:0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15)!important}.ui.attached.top.button{border-radius:.28571429rem .28571429rem 0 0}.ui.attached.bottom.button{border-radius:0 0 .28571429rem .28571429rem}.ui.left.attached.button{display:inline-block;border-left:none;text-align:right;padding-right:.75em;border-radius:.28571429rem 0 0 .28571429rem}.ui.right.attached.button{display:inline-block;text-align:left;padding-left:.75em;border-radius:0 .28571429rem .28571429rem 0}.ui.attached.buttons{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:0;width:auto!important;z-index:2;margin-left:-1px;margin-right:-1px}.ui.attached.buttons .button{margin:0}.ui.attached.buttons .button:first-child{border-radius:0}.ui.attached.buttons .button:last-child{border-radius:0}.ui[class*=\\\"top attached\\\"].buttons{margin-bottom:-1px;border-radius:.28571429rem .28571429rem 0 0}.ui[class*=\\\"top attached\\\"].buttons .button:first-child{border-radius:.28571429rem 0 0 0}.ui[class*=\\\"top attached\\\"].buttons .button:last-child{border-radius:0 .28571429rem 0 0}.ui[class*=\\\"bottom attached\\\"].buttons{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].buttons .button:first-child{border-radius:0 0 0 .28571429rem}.ui[class*=\\\"bottom attached\\\"].buttons .button:last-child{border-radius:0 0 .28571429rem 0}.ui[class*=\\\"left attached\\\"].buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:0;margin-left:-1px;border-radius:0 .28571429rem .28571429rem 0}.ui[class*=\\\"left attached\\\"].buttons .button:first-child{margin-left:-1px;border-radius:0 .28571429rem 0 0}.ui[class*=\\\"left attached\\\"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 .28571429rem 0}.ui[class*=\\\"right attached\\\"].buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-left:0;margin-right:-1px;border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"right attached\\\"].buttons .button:first-child{margin-left:-1px;border-radius:.28571429rem 0 0 0}.ui[class*=\\\"right attached\\\"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 0 .28571429rem}.ui.fluid.button,.ui.fluid.buttons{width:100%}.ui.fluid.button{display:block}.ui.two.buttons{width:100%}.ui.two.buttons>.button{width:50%}.ui.three.buttons{width:100%}.ui.three.buttons>.button{width:33.333%}.ui.four.buttons{width:100%}.ui.four.buttons>.button{width:25%}.ui.five.buttons{width:100%}.ui.five.buttons>.button{width:20%}.ui.six.buttons{width:100%}.ui.six.buttons>.button{width:16.666%}.ui.seven.buttons{width:100%}.ui.seven.buttons>.button{width:14.285%}.ui.eight.buttons{width:100%}.ui.eight.buttons>.button{width:12.5%}.ui.nine.buttons{width:100%}.ui.nine.buttons>.button{width:11.11%}.ui.ten.buttons{width:100%}.ui.ten.buttons>.button{width:10%}.ui.eleven.buttons{width:100%}.ui.eleven.buttons>.button{width:9.09%}.ui.twelve.buttons{width:100%}.ui.twelve.buttons>.button{width:8.3333%}.ui.fluid.vertical.buttons,.ui.fluid.vertical.buttons>.button{display:-webkit-box;display:-ms-flexbox;display:flex;width:auto}.ui.two.vertical.buttons>.button{height:50%}.ui.three.vertical.buttons>.button{height:33.333%}.ui.four.vertical.buttons>.button{height:25%}.ui.five.vertical.buttons>.button{height:20%}.ui.six.vertical.buttons>.button{height:16.666%}.ui.seven.vertical.buttons>.button{height:14.285%}.ui.eight.vertical.buttons>.button{height:12.5%}.ui.nine.vertical.buttons>.button{height:11.11%}.ui.ten.vertical.buttons>.button{height:10%}.ui.eleven.vertical.buttons>.button{height:9.09%}.ui.twelve.vertical.buttons>.button{height:8.3333%}.ui.black.button,.ui.black.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.black.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.black.button:hover,.ui.black.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.black.button:focus,.ui.black.buttons .button:focus{background-color:#2f3032;color:#fff;text-shadow:none}.ui.black.button:active,.ui.black.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.black.active.button,.ui.black.button .active.button:active,.ui.black.buttons .active.button,.ui.black.buttons .active.button:active{background-color:#0f0f10;color:#fff;text-shadow:none}.ui.basic.black.button,.ui.basic.black.buttons .button{-webkit-box-shadow:0 0 0 1px #1b1c1d inset!important;box-shadow:0 0 0 1px #1b1c1d inset!important;color:#1b1c1d!important}.ui.basic.black.button:hover,.ui.basic.black.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#27292a!important}.ui.basic.black.button:focus,.ui.basic.black.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #2f3032 inset!important;box-shadow:0 0 0 1px #2f3032 inset!important;color:#27292a!important}.ui.basic.black.active.button,.ui.basic.black.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0f0f10 inset!important;box-shadow:0 0 0 1px #0f0f10 inset!important;color:#343637!important}.ui.basic.black.button:active,.ui.basic.black.buttons .button:active{-webkit-box-shadow:0 0 0 1px #343637 inset!important;box-shadow:0 0 0 1px #343637 inset!important;color:#343637!important}.ui.buttons:not(.vertical)>.basic.black.button:not(:first-child){margin-left:-1px}.ui.inverted.black.button,.ui.inverted.black.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d4d4d5 inset!important;box-shadow:0 0 0 2px #d4d4d5 inset!important;color:#fff}.ui.inverted.black.button.active,.ui.inverted.black.button:active,.ui.inverted.black.button:focus,.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button.active,.ui.inverted.black.buttons .button:active,.ui.inverted.black.buttons .button:focus,.ui.inverted.black.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button:hover{background-color:#000}.ui.inverted.black.button:focus,.ui.inverted.black.buttons .button:focus{background-color:#000}.ui.inverted.black.active.button,.ui.inverted.black.buttons .active.button{background-color:#000}.ui.inverted.black.button:active,.ui.inverted.black.buttons .button:active{background-color:#000}.ui.inverted.black.basic.button,.ui.inverted.black.basic.buttons .button,.ui.inverted.black.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.black.basic.button:hover,.ui.inverted.black.basic.buttons .button:hover,.ui.inverted.black.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.inverted.black.basic.button:focus,.ui.inverted.black.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#545454!important}.ui.inverted.black.basic.active.button,.ui.inverted.black.basic.buttons .active.button,.ui.inverted.black.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.inverted.black.basic.button:active,.ui.inverted.black.basic.buttons .button:active,.ui.inverted.black.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.grey.button,.ui.grey.buttons .button{background-color:#767676;color:#fff;text-shadow:none;background-image:none}.ui.grey.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.grey.button:hover,.ui.grey.buttons .button:hover{background-color:#838383;color:#fff;text-shadow:none}.ui.grey.button:focus,.ui.grey.buttons .button:focus{background-color:#8a8a8a;color:#fff;text-shadow:none}.ui.grey.button:active,.ui.grey.buttons .button:active{background-color:#909090;color:#fff;text-shadow:none}.ui.grey.active.button,.ui.grey.button .active.button:active,.ui.grey.buttons .active.button,.ui.grey.buttons .active.button:active{background-color:#696969;color:#fff;text-shadow:none}.ui.basic.grey.button,.ui.basic.grey.buttons .button{-webkit-box-shadow:0 0 0 1px #767676 inset!important;box-shadow:0 0 0 1px #767676 inset!important;color:#767676!important}.ui.basic.grey.button:hover,.ui.basic.grey.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #838383 inset!important;box-shadow:0 0 0 1px #838383 inset!important;color:#838383!important}.ui.basic.grey.button:focus,.ui.basic.grey.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #8a8a8a inset!important;box-shadow:0 0 0 1px #8a8a8a inset!important;color:#838383!important}.ui.basic.grey.active.button,.ui.basic.grey.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #696969 inset!important;box-shadow:0 0 0 1px #696969 inset!important;color:#909090!important}.ui.basic.grey.button:active,.ui.basic.grey.buttons .button:active{-webkit-box-shadow:0 0 0 1px #909090 inset!important;box-shadow:0 0 0 1px #909090 inset!important;color:#909090!important}.ui.buttons:not(.vertical)>.basic.grey.button:not(:first-child){margin-left:-1px}.ui.inverted.grey.button,.ui.inverted.grey.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d4d4d5 inset!important;box-shadow:0 0 0 2px #d4d4d5 inset!important;color:#fff}.ui.inverted.grey.button.active,.ui.inverted.grey.button:active,.ui.inverted.grey.button:focus,.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button.active,.ui.inverted.grey.buttons .button:active,.ui.inverted.grey.buttons .button:focus,.ui.inverted.grey.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button:hover{background-color:#cfd0d2}.ui.inverted.grey.button:focus,.ui.inverted.grey.buttons .button:focus{background-color:#c7c9cb}.ui.inverted.grey.active.button,.ui.inverted.grey.buttons .active.button{background-color:#cfd0d2}.ui.inverted.grey.button:active,.ui.inverted.grey.buttons .button:active{background-color:#c2c4c5}.ui.inverted.grey.basic.button,.ui.inverted.grey.basic.buttons .button,.ui.inverted.grey.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.grey.basic.button:hover,.ui.inverted.grey.basic.buttons .button:hover,.ui.inverted.grey.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #cfd0d2 inset!important;box-shadow:0 0 0 2px #cfd0d2 inset!important;color:#fff!important}.ui.inverted.grey.basic.button:focus,.ui.inverted.grey.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #c7c9cb inset!important;box-shadow:0 0 0 2px #c7c9cb inset!important;color:#dcddde!important}.ui.inverted.grey.basic.active.button,.ui.inverted.grey.basic.buttons .active.button,.ui.inverted.grey.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #cfd0d2 inset!important;box-shadow:0 0 0 2px #cfd0d2 inset!important;color:#fff!important}.ui.inverted.grey.basic.button:active,.ui.inverted.grey.basic.buttons .button:active,.ui.inverted.grey.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #c2c4c5 inset!important;box-shadow:0 0 0 2px #c2c4c5 inset!important;color:#fff!important}.ui.brown.button,.ui.brown.buttons .button{background-color:#a5673f;color:#fff;text-shadow:none;background-image:none}.ui.brown.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.brown.button:hover,.ui.brown.buttons .button:hover{background-color:#975b33;color:#fff;text-shadow:none}.ui.brown.button:focus,.ui.brown.buttons .button:focus{background-color:#90532b;color:#fff;text-shadow:none}.ui.brown.button:active,.ui.brown.buttons .button:active{background-color:#805031;color:#fff;text-shadow:none}.ui.brown.active.button,.ui.brown.button .active.button:active,.ui.brown.buttons .active.button,.ui.brown.buttons .active.button:active{background-color:#995a31;color:#fff;text-shadow:none}.ui.basic.brown.button,.ui.basic.brown.buttons .button{-webkit-box-shadow:0 0 0 1px #a5673f inset!important;box-shadow:0 0 0 1px #a5673f inset!important;color:#a5673f!important}.ui.basic.brown.button:hover,.ui.basic.brown.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #975b33 inset!important;box-shadow:0 0 0 1px #975b33 inset!important;color:#975b33!important}.ui.basic.brown.button:focus,.ui.basic.brown.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #90532b inset!important;box-shadow:0 0 0 1px #90532b inset!important;color:#975b33!important}.ui.basic.brown.active.button,.ui.basic.brown.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #995a31 inset!important;box-shadow:0 0 0 1px #995a31 inset!important;color:#805031!important}.ui.basic.brown.button:active,.ui.basic.brown.buttons .button:active{-webkit-box-shadow:0 0 0 1px #805031 inset!important;box-shadow:0 0 0 1px #805031 inset!important;color:#805031!important}.ui.buttons:not(.vertical)>.basic.brown.button:not(:first-child){margin-left:-1px}.ui.inverted.brown.button,.ui.inverted.brown.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d67c1c inset!important;box-shadow:0 0 0 2px #d67c1c inset!important;color:#d67c1c}.ui.inverted.brown.button.active,.ui.inverted.brown.button:active,.ui.inverted.brown.button:focus,.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button.active,.ui.inverted.brown.buttons .button:active,.ui.inverted.brown.buttons .button:focus,.ui.inverted.brown.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button:hover{background-color:#c86f11}.ui.inverted.brown.button:focus,.ui.inverted.brown.buttons .button:focus{background-color:#c16808}.ui.inverted.brown.active.button,.ui.inverted.brown.buttons .active.button{background-color:#cc6f0d}.ui.inverted.brown.button:active,.ui.inverted.brown.buttons .button:active{background-color:#a96216}.ui.inverted.brown.basic.button,.ui.inverted.brown.basic.buttons .button,.ui.inverted.brown.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.brown.basic.button:hover,.ui.inverted.brown.basic.buttons .button:hover,.ui.inverted.brown.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #c86f11 inset!important;box-shadow:0 0 0 2px #c86f11 inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.button:focus,.ui.inverted.brown.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #c16808 inset!important;box-shadow:0 0 0 2px #c16808 inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.active.button,.ui.inverted.brown.basic.buttons .active.button,.ui.inverted.brown.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #cc6f0d inset!important;box-shadow:0 0 0 2px #cc6f0d inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.button:active,.ui.inverted.brown.basic.buttons .button:active,.ui.inverted.brown.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #a96216 inset!important;box-shadow:0 0 0 2px #a96216 inset!important;color:#d67c1c!important}.ui.blue.button,.ui.blue.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.blue.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.blue.button:hover,.ui.blue.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.blue.button:focus,.ui.blue.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.blue.button:active,.ui.blue.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.blue.active.button,.ui.blue.button .active.button:active,.ui.blue.buttons .active.button,.ui.blue.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.blue.button,.ui.basic.blue.buttons .button{-webkit-box-shadow:0 0 0 1px #2185d0 inset!important;box-shadow:0 0 0 1px #2185d0 inset!important;color:#2185d0!important}.ui.basic.blue.button:hover,.ui.basic.blue.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1678c2 inset!important;box-shadow:0 0 0 1px #1678c2 inset!important;color:#1678c2!important}.ui.basic.blue.button:focus,.ui.basic.blue.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0d71bb inset!important;box-shadow:0 0 0 1px #0d71bb inset!important;color:#1678c2!important}.ui.basic.blue.active.button,.ui.basic.blue.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1279c6 inset!important;box-shadow:0 0 0 1px #1279c6 inset!important;color:#1a69a4!important}.ui.basic.blue.button:active,.ui.basic.blue.buttons .button:active{-webkit-box-shadow:0 0 0 1px #1a69a4 inset!important;box-shadow:0 0 0 1px #1a69a4 inset!important;color:#1a69a4!important}.ui.buttons:not(.vertical)>.basic.blue.button:not(:first-child){margin-left:-1px}.ui.inverted.blue.button,.ui.inverted.blue.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #54c8ff inset!important;box-shadow:0 0 0 2px #54c8ff inset!important;color:#54c8ff}.ui.inverted.blue.button.active,.ui.inverted.blue.button:active,.ui.inverted.blue.button:focus,.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button.active,.ui.inverted.blue.buttons .button:active,.ui.inverted.blue.buttons .button:focus,.ui.inverted.blue.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button:hover{background-color:#3ac0ff}.ui.inverted.blue.button:focus,.ui.inverted.blue.buttons .button:focus{background-color:#2bbbff}.ui.inverted.blue.active.button,.ui.inverted.blue.buttons .active.button{background-color:#3ac0ff}.ui.inverted.blue.button:active,.ui.inverted.blue.buttons .button:active{background-color:#21b8ff}.ui.inverted.blue.basic.button,.ui.inverted.blue.basic.buttons .button,.ui.inverted.blue.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.blue.basic.button:hover,.ui.inverted.blue.basic.buttons .button:hover,.ui.inverted.blue.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.button:focus,.ui.inverted.blue.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #2bbbff inset!important;box-shadow:0 0 0 2px #2bbbff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.active.button,.ui.inverted.blue.basic.buttons .active.button,.ui.inverted.blue.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.button:active,.ui.inverted.blue.basic.buttons .button:active,.ui.inverted.blue.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #21b8ff inset!important;box-shadow:0 0 0 2px #21b8ff inset!important;color:#54c8ff!important}.ui.green.button,.ui.green.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.green.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.green.button:hover,.ui.green.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.green.button:focus,.ui.green.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.green.button:active,.ui.green.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.green.active.button,.ui.green.button .active.button:active,.ui.green.buttons .active.button,.ui.green.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.green.button,.ui.basic.green.buttons .button{-webkit-box-shadow:0 0 0 1px #21ba45 inset!important;box-shadow:0 0 0 1px #21ba45 inset!important;color:#21ba45!important}.ui.basic.green.button:hover,.ui.basic.green.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #16ab39 inset!important;box-shadow:0 0 0 1px #16ab39 inset!important;color:#16ab39!important}.ui.basic.green.button:focus,.ui.basic.green.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0ea432 inset!important;box-shadow:0 0 0 1px #0ea432 inset!important;color:#16ab39!important}.ui.basic.green.active.button,.ui.basic.green.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #13ae38 inset!important;box-shadow:0 0 0 1px #13ae38 inset!important;color:#198f35!important}.ui.basic.green.button:active,.ui.basic.green.buttons .button:active{-webkit-box-shadow:0 0 0 1px #198f35 inset!important;box-shadow:0 0 0 1px #198f35 inset!important;color:#198f35!important}.ui.buttons:not(.vertical)>.basic.green.button:not(:first-child){margin-left:-1px}.ui.inverted.green.button,.ui.inverted.green.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #2ecc40 inset!important;box-shadow:0 0 0 2px #2ecc40 inset!important;color:#2ecc40}.ui.inverted.green.button.active,.ui.inverted.green.button:active,.ui.inverted.green.button:focus,.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button.active,.ui.inverted.green.buttons .button:active,.ui.inverted.green.buttons .button:focus,.ui.inverted.green.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button:hover{background-color:#22be34}.ui.inverted.green.button:focus,.ui.inverted.green.buttons .button:focus{background-color:#19b82b}.ui.inverted.green.active.button,.ui.inverted.green.buttons .active.button{background-color:#1fc231}.ui.inverted.green.button:active,.ui.inverted.green.buttons .button:active{background-color:#25a233}.ui.inverted.green.basic.button,.ui.inverted.green.basic.buttons .button,.ui.inverted.green.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.green.basic.button:hover,.ui.inverted.green.basic.buttons .button:hover,.ui.inverted.green.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #22be34 inset!important;box-shadow:0 0 0 2px #22be34 inset!important;color:#2ecc40!important}.ui.inverted.green.basic.button:focus,.ui.inverted.green.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #19b82b inset!important;box-shadow:0 0 0 2px #19b82b inset!important;color:#2ecc40!important}.ui.inverted.green.basic.active.button,.ui.inverted.green.basic.buttons .active.button,.ui.inverted.green.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #1fc231 inset!important;box-shadow:0 0 0 2px #1fc231 inset!important;color:#2ecc40!important}.ui.inverted.green.basic.button:active,.ui.inverted.green.basic.buttons .button:active,.ui.inverted.green.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #25a233 inset!important;box-shadow:0 0 0 2px #25a233 inset!important;color:#2ecc40!important}.ui.orange.button,.ui.orange.buttons .button{background-color:#f2711c;color:#fff;text-shadow:none;background-image:none}.ui.orange.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.orange.button:hover,.ui.orange.buttons .button:hover{background-color:#f26202;color:#fff;text-shadow:none}.ui.orange.button:focus,.ui.orange.buttons .button:focus{background-color:#e55b00;color:#fff;text-shadow:none}.ui.orange.button:active,.ui.orange.buttons .button:active{background-color:#cf590c;color:#fff;text-shadow:none}.ui.orange.active.button,.ui.orange.button .active.button:active,.ui.orange.buttons .active.button,.ui.orange.buttons .active.button:active{background-color:#f56100;color:#fff;text-shadow:none}.ui.basic.orange.button,.ui.basic.orange.buttons .button{-webkit-box-shadow:0 0 0 1px #f2711c inset!important;box-shadow:0 0 0 1px #f2711c inset!important;color:#f2711c!important}.ui.basic.orange.button:hover,.ui.basic.orange.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #f26202 inset!important;box-shadow:0 0 0 1px #f26202 inset!important;color:#f26202!important}.ui.basic.orange.button:focus,.ui.basic.orange.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e55b00 inset!important;box-shadow:0 0 0 1px #e55b00 inset!important;color:#f26202!important}.ui.basic.orange.active.button,.ui.basic.orange.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #f56100 inset!important;box-shadow:0 0 0 1px #f56100 inset!important;color:#cf590c!important}.ui.basic.orange.button:active,.ui.basic.orange.buttons .button:active{-webkit-box-shadow:0 0 0 1px #cf590c inset!important;box-shadow:0 0 0 1px #cf590c inset!important;color:#cf590c!important}.ui.buttons:not(.vertical)>.basic.orange.button:not(:first-child){margin-left:-1px}.ui.inverted.orange.button,.ui.inverted.orange.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff851b inset!important;box-shadow:0 0 0 2px #ff851b inset!important;color:#ff851b}.ui.inverted.orange.button.active,.ui.inverted.orange.button:active,.ui.inverted.orange.button:focus,.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button.active,.ui.inverted.orange.buttons .button:active,.ui.inverted.orange.buttons .button:focus,.ui.inverted.orange.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button:hover{background-color:#ff7701}.ui.inverted.orange.button:focus,.ui.inverted.orange.buttons .button:focus{background-color:#f17000}.ui.inverted.orange.active.button,.ui.inverted.orange.buttons .active.button{background-color:#ff7701}.ui.inverted.orange.button:active,.ui.inverted.orange.buttons .button:active{background-color:#e76b00}.ui.inverted.orange.basic.button,.ui.inverted.orange.basic.buttons .button,.ui.inverted.orange.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.orange.basic.button:hover,.ui.inverted.orange.basic.buttons .button:hover,.ui.inverted.orange.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff7701 inset!important;box-shadow:0 0 0 2px #ff7701 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.button:focus,.ui.inverted.orange.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #f17000 inset!important;box-shadow:0 0 0 2px #f17000 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.active.button,.ui.inverted.orange.basic.buttons .active.button,.ui.inverted.orange.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff7701 inset!important;box-shadow:0 0 0 2px #ff7701 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.button:active,.ui.inverted.orange.basic.buttons .button:active,.ui.inverted.orange.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #e76b00 inset!important;box-shadow:0 0 0 2px #e76b00 inset!important;color:#ff851b!important}.ui.pink.button,.ui.pink.buttons .button{background-color:#e03997;color:#fff;text-shadow:none;background-image:none}.ui.pink.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pink.button:hover,.ui.pink.buttons .button:hover{background-color:#e61a8d;color:#fff;text-shadow:none}.ui.pink.button:focus,.ui.pink.buttons .button:focus{background-color:#e10f85;color:#fff;text-shadow:none}.ui.pink.button:active,.ui.pink.buttons .button:active{background-color:#c71f7e;color:#fff;text-shadow:none}.ui.pink.active.button,.ui.pink.button .active.button:active,.ui.pink.buttons .active.button,.ui.pink.buttons .active.button:active{background-color:#ea158d;color:#fff;text-shadow:none}.ui.basic.pink.button,.ui.basic.pink.buttons .button{-webkit-box-shadow:0 0 0 1px #e03997 inset!important;box-shadow:0 0 0 1px #e03997 inset!important;color:#e03997!important}.ui.basic.pink.button:hover,.ui.basic.pink.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e61a8d inset!important;box-shadow:0 0 0 1px #e61a8d inset!important;color:#e61a8d!important}.ui.basic.pink.button:focus,.ui.basic.pink.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e10f85 inset!important;box-shadow:0 0 0 1px #e10f85 inset!important;color:#e61a8d!important}.ui.basic.pink.active.button,.ui.basic.pink.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ea158d inset!important;box-shadow:0 0 0 1px #ea158d inset!important;color:#c71f7e!important}.ui.basic.pink.button:active,.ui.basic.pink.buttons .button:active{-webkit-box-shadow:0 0 0 1px #c71f7e inset!important;box-shadow:0 0 0 1px #c71f7e inset!important;color:#c71f7e!important}.ui.buttons:not(.vertical)>.basic.pink.button:not(:first-child){margin-left:-1px}.ui.inverted.pink.button,.ui.inverted.pink.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff8edf inset!important;box-shadow:0 0 0 2px #ff8edf inset!important;color:#ff8edf}.ui.inverted.pink.button.active,.ui.inverted.pink.button:active,.ui.inverted.pink.button:focus,.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button.active,.ui.inverted.pink.buttons .button:active,.ui.inverted.pink.buttons .button:focus,.ui.inverted.pink.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button:hover{background-color:#ff74d8}.ui.inverted.pink.button:focus,.ui.inverted.pink.buttons .button:focus{background-color:#ff65d3}.ui.inverted.pink.active.button,.ui.inverted.pink.buttons .active.button{background-color:#ff74d8}.ui.inverted.pink.button:active,.ui.inverted.pink.buttons .button:active{background-color:#ff5bd1}.ui.inverted.pink.basic.button,.ui.inverted.pink.basic.buttons .button,.ui.inverted.pink.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.pink.basic.button:hover,.ui.inverted.pink.basic.buttons .button:hover,.ui.inverted.pink.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff74d8 inset!important;box-shadow:0 0 0 2px #ff74d8 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.button:focus,.ui.inverted.pink.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #ff65d3 inset!important;box-shadow:0 0 0 2px #ff65d3 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.active.button,.ui.inverted.pink.basic.buttons .active.button,.ui.inverted.pink.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff74d8 inset!important;box-shadow:0 0 0 2px #ff74d8 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.button:active,.ui.inverted.pink.basic.buttons .button:active,.ui.inverted.pink.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ff5bd1 inset!important;box-shadow:0 0 0 2px #ff5bd1 inset!important;color:#ff8edf!important}.ui.violet.button,.ui.violet.buttons .button{background-color:#6435c9;color:#fff;text-shadow:none;background-image:none}.ui.violet.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.violet.button:hover,.ui.violet.buttons .button:hover{background-color:#5829bb;color:#fff;text-shadow:none}.ui.violet.button:focus,.ui.violet.buttons .button:focus{background-color:#4f20b5;color:#fff;text-shadow:none}.ui.violet.button:active,.ui.violet.buttons .button:active{background-color:#502aa1;color:#fff;text-shadow:none}.ui.violet.active.button,.ui.violet.button .active.button:active,.ui.violet.buttons .active.button,.ui.violet.buttons .active.button:active{background-color:#5626bf;color:#fff;text-shadow:none}.ui.basic.violet.button,.ui.basic.violet.buttons .button{-webkit-box-shadow:0 0 0 1px #6435c9 inset!important;box-shadow:0 0 0 1px #6435c9 inset!important;color:#6435c9!important}.ui.basic.violet.button:hover,.ui.basic.violet.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #5829bb inset!important;box-shadow:0 0 0 1px #5829bb inset!important;color:#5829bb!important}.ui.basic.violet.button:focus,.ui.basic.violet.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #4f20b5 inset!important;box-shadow:0 0 0 1px #4f20b5 inset!important;color:#5829bb!important}.ui.basic.violet.active.button,.ui.basic.violet.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #5626bf inset!important;box-shadow:0 0 0 1px #5626bf inset!important;color:#502aa1!important}.ui.basic.violet.button:active,.ui.basic.violet.buttons .button:active{-webkit-box-shadow:0 0 0 1px #502aa1 inset!important;box-shadow:0 0 0 1px #502aa1 inset!important;color:#502aa1!important}.ui.buttons:not(.vertical)>.basic.violet.button:not(:first-child){margin-left:-1px}.ui.inverted.violet.button,.ui.inverted.violet.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #a291fb inset!important;box-shadow:0 0 0 2px #a291fb inset!important;color:#a291fb}.ui.inverted.violet.button.active,.ui.inverted.violet.button:active,.ui.inverted.violet.button:focus,.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button.active,.ui.inverted.violet.buttons .button:active,.ui.inverted.violet.buttons .button:focus,.ui.inverted.violet.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button:hover{background-color:#8a73ff}.ui.inverted.violet.button:focus,.ui.inverted.violet.buttons .button:focus{background-color:#7d64ff}.ui.inverted.violet.active.button,.ui.inverted.violet.buttons .active.button{background-color:#8a73ff}.ui.inverted.violet.button:active,.ui.inverted.violet.buttons .button:active{background-color:#7860f9}.ui.inverted.violet.basic.button,.ui.inverted.violet.basic.buttons .button,.ui.inverted.violet.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.violet.basic.button:hover,.ui.inverted.violet.basic.buttons .button:hover,.ui.inverted.violet.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #8a73ff inset!important;box-shadow:0 0 0 2px #8a73ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.button:focus,.ui.inverted.violet.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #7d64ff inset!important;box-shadow:0 0 0 2px #7d64ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.active.button,.ui.inverted.violet.basic.buttons .active.button,.ui.inverted.violet.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #8a73ff inset!important;box-shadow:0 0 0 2px #8a73ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.button:active,.ui.inverted.violet.basic.buttons .button:active,.ui.inverted.violet.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #7860f9 inset!important;box-shadow:0 0 0 2px #7860f9 inset!important;color:#a291fb!important}.ui.purple.button,.ui.purple.buttons .button{background-color:#a333c8;color:#fff;text-shadow:none;background-image:none}.ui.purple.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.purple.button:hover,.ui.purple.buttons .button:hover{background-color:#9627ba;color:#fff;text-shadow:none}.ui.purple.button:focus,.ui.purple.buttons .button:focus{background-color:#8f1eb4;color:#fff;text-shadow:none}.ui.purple.button:active,.ui.purple.buttons .button:active{background-color:#82299f;color:#fff;text-shadow:none}.ui.purple.active.button,.ui.purple.button .active.button:active,.ui.purple.buttons .active.button,.ui.purple.buttons .active.button:active{background-color:#9724be;color:#fff;text-shadow:none}.ui.basic.purple.button,.ui.basic.purple.buttons .button{-webkit-box-shadow:0 0 0 1px #a333c8 inset!important;box-shadow:0 0 0 1px #a333c8 inset!important;color:#a333c8!important}.ui.basic.purple.button:hover,.ui.basic.purple.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #9627ba inset!important;box-shadow:0 0 0 1px #9627ba inset!important;color:#9627ba!important}.ui.basic.purple.button:focus,.ui.basic.purple.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #8f1eb4 inset!important;box-shadow:0 0 0 1px #8f1eb4 inset!important;color:#9627ba!important}.ui.basic.purple.active.button,.ui.basic.purple.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #9724be inset!important;box-shadow:0 0 0 1px #9724be inset!important;color:#82299f!important}.ui.basic.purple.button:active,.ui.basic.purple.buttons .button:active{-webkit-box-shadow:0 0 0 1px #82299f inset!important;box-shadow:0 0 0 1px #82299f inset!important;color:#82299f!important}.ui.buttons:not(.vertical)>.basic.purple.button:not(:first-child){margin-left:-1px}.ui.inverted.purple.button,.ui.inverted.purple.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #dc73ff inset!important;box-shadow:0 0 0 2px #dc73ff inset!important;color:#dc73ff}.ui.inverted.purple.button.active,.ui.inverted.purple.button:active,.ui.inverted.purple.button:focus,.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button.active,.ui.inverted.purple.buttons .button:active,.ui.inverted.purple.buttons .button:focus,.ui.inverted.purple.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button:hover{background-color:#d65aff}.ui.inverted.purple.button:focus,.ui.inverted.purple.buttons .button:focus{background-color:#d24aff}.ui.inverted.purple.active.button,.ui.inverted.purple.buttons .active.button{background-color:#d65aff}.ui.inverted.purple.button:active,.ui.inverted.purple.buttons .button:active{background-color:#cf40ff}.ui.inverted.purple.basic.button,.ui.inverted.purple.basic.buttons .button,.ui.inverted.purple.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.purple.basic.button:hover,.ui.inverted.purple.basic.buttons .button:hover,.ui.inverted.purple.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #d65aff inset!important;box-shadow:0 0 0 2px #d65aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.button:focus,.ui.inverted.purple.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #d24aff inset!important;box-shadow:0 0 0 2px #d24aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.active.button,.ui.inverted.purple.basic.buttons .active.button,.ui.inverted.purple.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #d65aff inset!important;box-shadow:0 0 0 2px #d65aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.button:active,.ui.inverted.purple.basic.buttons .button:active,.ui.inverted.purple.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #cf40ff inset!important;box-shadow:0 0 0 2px #cf40ff inset!important;color:#dc73ff!important}.ui.red.button,.ui.red.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.red.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.red.button:hover,.ui.red.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.red.button:focus,.ui.red.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.red.button:active,.ui.red.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.red.active.button,.ui.red.button .active.button:active,.ui.red.buttons .active.button,.ui.red.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.red.button,.ui.basic.red.buttons .button{-webkit-box-shadow:0 0 0 1px #db2828 inset!important;box-shadow:0 0 0 1px #db2828 inset!important;color:#db2828!important}.ui.basic.red.button:hover,.ui.basic.red.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d01919 inset!important;box-shadow:0 0 0 1px #d01919 inset!important;color:#d01919!important}.ui.basic.red.button:focus,.ui.basic.red.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ca1010 inset!important;box-shadow:0 0 0 1px #ca1010 inset!important;color:#d01919!important}.ui.basic.red.active.button,.ui.basic.red.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d41515 inset!important;box-shadow:0 0 0 1px #d41515 inset!important;color:#b21e1e!important}.ui.basic.red.button:active,.ui.basic.red.buttons .button:active{-webkit-box-shadow:0 0 0 1px #b21e1e inset!important;box-shadow:0 0 0 1px #b21e1e inset!important;color:#b21e1e!important}.ui.buttons:not(.vertical)>.basic.red.button:not(:first-child){margin-left:-1px}.ui.inverted.red.button,.ui.inverted.red.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff695e inset!important;box-shadow:0 0 0 2px #ff695e inset!important;color:#ff695e}.ui.inverted.red.button.active,.ui.inverted.red.button:active,.ui.inverted.red.button:focus,.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button.active,.ui.inverted.red.buttons .button:active,.ui.inverted.red.buttons .button:focus,.ui.inverted.red.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button:hover{background-color:#ff5144}.ui.inverted.red.button:focus,.ui.inverted.red.buttons .button:focus{background-color:#ff4335}.ui.inverted.red.active.button,.ui.inverted.red.buttons .active.button{background-color:#ff5144}.ui.inverted.red.button:active,.ui.inverted.red.buttons .button:active{background-color:#ff392b}.ui.inverted.red.basic.button,.ui.inverted.red.basic.buttons .button,.ui.inverted.red.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.red.basic.button:hover,.ui.inverted.red.basic.buttons .button:hover,.ui.inverted.red.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff5144 inset!important;box-shadow:0 0 0 2px #ff5144 inset!important;color:#ff695e!important}.ui.inverted.red.basic.button:focus,.ui.inverted.red.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #ff4335 inset!important;box-shadow:0 0 0 2px #ff4335 inset!important;color:#ff695e!important}.ui.inverted.red.basic.active.button,.ui.inverted.red.basic.buttons .active.button,.ui.inverted.red.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff5144 inset!important;box-shadow:0 0 0 2px #ff5144 inset!important;color:#ff695e!important}.ui.inverted.red.basic.button:active,.ui.inverted.red.basic.buttons .button:active,.ui.inverted.red.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ff392b inset!important;box-shadow:0 0 0 2px #ff392b inset!important;color:#ff695e!important}.ui.teal.button,.ui.teal.buttons .button{background-color:#00b5ad;color:#fff;text-shadow:none;background-image:none}.ui.teal.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.teal.button:hover,.ui.teal.buttons .button:hover{background-color:#009c95;color:#fff;text-shadow:none}.ui.teal.button:focus,.ui.teal.buttons .button:focus{background-color:#008c86;color:#fff;text-shadow:none}.ui.teal.button:active,.ui.teal.buttons .button:active{background-color:#00827c;color:#fff;text-shadow:none}.ui.teal.active.button,.ui.teal.button .active.button:active,.ui.teal.buttons .active.button,.ui.teal.buttons .active.button:active{background-color:#009c95;color:#fff;text-shadow:none}.ui.basic.teal.button,.ui.basic.teal.buttons .button{-webkit-box-shadow:0 0 0 1px #00b5ad inset!important;box-shadow:0 0 0 1px #00b5ad inset!important;color:#00b5ad!important}.ui.basic.teal.button:hover,.ui.basic.teal.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #009c95 inset!important;box-shadow:0 0 0 1px #009c95 inset!important;color:#009c95!important}.ui.basic.teal.button:focus,.ui.basic.teal.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #008c86 inset!important;box-shadow:0 0 0 1px #008c86 inset!important;color:#009c95!important}.ui.basic.teal.active.button,.ui.basic.teal.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #009c95 inset!important;box-shadow:0 0 0 1px #009c95 inset!important;color:#00827c!important}.ui.basic.teal.button:active,.ui.basic.teal.buttons .button:active{-webkit-box-shadow:0 0 0 1px #00827c inset!important;box-shadow:0 0 0 1px #00827c inset!important;color:#00827c!important}.ui.buttons:not(.vertical)>.basic.teal.button:not(:first-child){margin-left:-1px}.ui.inverted.teal.button,.ui.inverted.teal.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #6dffff inset!important;box-shadow:0 0 0 2px #6dffff inset!important;color:#6dffff}.ui.inverted.teal.button.active,.ui.inverted.teal.button:active,.ui.inverted.teal.button:focus,.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button.active,.ui.inverted.teal.buttons .button:active,.ui.inverted.teal.buttons .button:focus,.ui.inverted.teal.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button:hover{background-color:#54ffff}.ui.inverted.teal.button:focus,.ui.inverted.teal.buttons .button:focus{background-color:#4ff}.ui.inverted.teal.active.button,.ui.inverted.teal.buttons .active.button{background-color:#54ffff}.ui.inverted.teal.button:active,.ui.inverted.teal.buttons .button:active{background-color:#3affff}.ui.inverted.teal.basic.button,.ui.inverted.teal.basic.buttons .button,.ui.inverted.teal.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.teal.basic.button:hover,.ui.inverted.teal.basic.buttons .button:hover,.ui.inverted.teal.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #54ffff inset!important;box-shadow:0 0 0 2px #54ffff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.button:focus,.ui.inverted.teal.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #4ff inset!important;box-shadow:0 0 0 2px #4ff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.active.button,.ui.inverted.teal.basic.buttons .active.button,.ui.inverted.teal.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #54ffff inset!important;box-shadow:0 0 0 2px #54ffff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.button:active,.ui.inverted.teal.basic.buttons .button:active,.ui.inverted.teal.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #3affff inset!important;box-shadow:0 0 0 2px #3affff inset!important;color:#6dffff!important}.ui.olive.button,.ui.olive.buttons .button{background-color:#b5cc18;color:#fff;text-shadow:none;background-image:none}.ui.olive.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.olive.button:hover,.ui.olive.buttons .button:hover{background-color:#a7bd0d;color:#fff;text-shadow:none}.ui.olive.button:focus,.ui.olive.buttons .button:focus{background-color:#a0b605;color:#fff;text-shadow:none}.ui.olive.button:active,.ui.olive.buttons .button:active{background-color:#8d9e13;color:#fff;text-shadow:none}.ui.olive.active.button,.ui.olive.button .active.button:active,.ui.olive.buttons .active.button,.ui.olive.buttons .active.button:active{background-color:#aac109;color:#fff;text-shadow:none}.ui.basic.olive.button,.ui.basic.olive.buttons .button{-webkit-box-shadow:0 0 0 1px #b5cc18 inset!important;box-shadow:0 0 0 1px #b5cc18 inset!important;color:#b5cc18!important}.ui.basic.olive.button:hover,.ui.basic.olive.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #a7bd0d inset!important;box-shadow:0 0 0 1px #a7bd0d inset!important;color:#a7bd0d!important}.ui.basic.olive.button:focus,.ui.basic.olive.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #a0b605 inset!important;box-shadow:0 0 0 1px #a0b605 inset!important;color:#a7bd0d!important}.ui.basic.olive.active.button,.ui.basic.olive.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #aac109 inset!important;box-shadow:0 0 0 1px #aac109 inset!important;color:#8d9e13!important}.ui.basic.olive.button:active,.ui.basic.olive.buttons .button:active{-webkit-box-shadow:0 0 0 1px #8d9e13 inset!important;box-shadow:0 0 0 1px #8d9e13 inset!important;color:#8d9e13!important}.ui.buttons:not(.vertical)>.basic.olive.button:not(:first-child){margin-left:-1px}.ui.inverted.olive.button,.ui.inverted.olive.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d9e778 inset!important;box-shadow:0 0 0 2px #d9e778 inset!important;color:#d9e778}.ui.inverted.olive.button.active,.ui.inverted.olive.button:active,.ui.inverted.olive.button:focus,.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button.active,.ui.inverted.olive.buttons .button:active,.ui.inverted.olive.buttons .button:focus,.ui.inverted.olive.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button:hover{background-color:#d8ea5c}.ui.inverted.olive.button:focus,.ui.inverted.olive.buttons .button:focus{background-color:#daef47}.ui.inverted.olive.active.button,.ui.inverted.olive.buttons .active.button{background-color:#daed59}.ui.inverted.olive.button:active,.ui.inverted.olive.buttons .button:active{background-color:#cddf4d}.ui.inverted.olive.basic.button,.ui.inverted.olive.basic.buttons .button,.ui.inverted.olive.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.olive.basic.button:hover,.ui.inverted.olive.basic.buttons .button:hover,.ui.inverted.olive.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #d8ea5c inset!important;box-shadow:0 0 0 2px #d8ea5c inset!important;color:#d9e778!important}.ui.inverted.olive.basic.button:focus,.ui.inverted.olive.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #daef47 inset!important;box-shadow:0 0 0 2px #daef47 inset!important;color:#d9e778!important}.ui.inverted.olive.basic.active.button,.ui.inverted.olive.basic.buttons .active.button,.ui.inverted.olive.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #daed59 inset!important;box-shadow:0 0 0 2px #daed59 inset!important;color:#d9e778!important}.ui.inverted.olive.basic.button:active,.ui.inverted.olive.basic.buttons .button:active,.ui.inverted.olive.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #cddf4d inset!important;box-shadow:0 0 0 2px #cddf4d inset!important;color:#d9e778!important}.ui.yellow.button,.ui.yellow.buttons .button{background-color:#fbbd08;color:#fff;text-shadow:none;background-image:none}.ui.yellow.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.yellow.button:hover,.ui.yellow.buttons .button:hover{background-color:#eaae00;color:#fff;text-shadow:none}.ui.yellow.button:focus,.ui.yellow.buttons .button:focus{background-color:#daa300;color:#fff;text-shadow:none}.ui.yellow.button:active,.ui.yellow.buttons .button:active{background-color:#cd9903;color:#fff;text-shadow:none}.ui.yellow.active.button,.ui.yellow.button .active.button:active,.ui.yellow.buttons .active.button,.ui.yellow.buttons .active.button:active{background-color:#eaae00;color:#fff;text-shadow:none}.ui.basic.yellow.button,.ui.basic.yellow.buttons .button{-webkit-box-shadow:0 0 0 1px #fbbd08 inset!important;box-shadow:0 0 0 1px #fbbd08 inset!important;color:#fbbd08!important}.ui.basic.yellow.button:hover,.ui.basic.yellow.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #eaae00 inset!important;box-shadow:0 0 0 1px #eaae00 inset!important;color:#eaae00!important}.ui.basic.yellow.button:focus,.ui.basic.yellow.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #daa300 inset!important;box-shadow:0 0 0 1px #daa300 inset!important;color:#eaae00!important}.ui.basic.yellow.active.button,.ui.basic.yellow.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #eaae00 inset!important;box-shadow:0 0 0 1px #eaae00 inset!important;color:#cd9903!important}.ui.basic.yellow.button:active,.ui.basic.yellow.buttons .button:active{-webkit-box-shadow:0 0 0 1px #cd9903 inset!important;box-shadow:0 0 0 1px #cd9903 inset!important;color:#cd9903!important}.ui.buttons:not(.vertical)>.basic.yellow.button:not(:first-child){margin-left:-1px}.ui.inverted.yellow.button,.ui.inverted.yellow.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ffe21f inset!important;box-shadow:0 0 0 2px #ffe21f inset!important;color:#ffe21f}.ui.inverted.yellow.button.active,.ui.inverted.yellow.button:active,.ui.inverted.yellow.button:focus,.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button.active,.ui.inverted.yellow.buttons .button:active,.ui.inverted.yellow.buttons .button:focus,.ui.inverted.yellow.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button:hover{background-color:#ffdf05}.ui.inverted.yellow.button:focus,.ui.inverted.yellow.buttons .button:focus{background-color:#f5d500}.ui.inverted.yellow.active.button,.ui.inverted.yellow.buttons .active.button{background-color:#ffdf05}.ui.inverted.yellow.button:active,.ui.inverted.yellow.buttons .button:active{background-color:#ebcd00}.ui.inverted.yellow.basic.button,.ui.inverted.yellow.basic.buttons .button,.ui.inverted.yellow.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.yellow.basic.button:hover,.ui.inverted.yellow.basic.buttons .button:hover,.ui.inverted.yellow.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ffdf05 inset!important;box-shadow:0 0 0 2px #ffdf05 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.button:focus,.ui.inverted.yellow.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #f5d500 inset!important;box-shadow:0 0 0 2px #f5d500 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.active.button,.ui.inverted.yellow.basic.buttons .active.button,.ui.inverted.yellow.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ffdf05 inset!important;box-shadow:0 0 0 2px #ffdf05 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.button:active,.ui.inverted.yellow.basic.buttons .button:active,.ui.inverted.yellow.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ebcd00 inset!important;box-shadow:0 0 0 2px #ebcd00 inset!important;color:#ffe21f!important}.ui.primary.button,.ui.primary.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.primary.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.primary.button:hover,.ui.primary.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.primary.button:focus,.ui.primary.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.primary.button:active,.ui.primary.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.primary.active.button,.ui.primary.button .active.button:active,.ui.primary.buttons .active.button,.ui.primary.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.primary.button,.ui.basic.primary.buttons .button{-webkit-box-shadow:0 0 0 1px #2185d0 inset!important;box-shadow:0 0 0 1px #2185d0 inset!important;color:#2185d0!important}.ui.basic.primary.button:hover,.ui.basic.primary.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1678c2 inset!important;box-shadow:0 0 0 1px #1678c2 inset!important;color:#1678c2!important}.ui.basic.primary.button:focus,.ui.basic.primary.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0d71bb inset!important;box-shadow:0 0 0 1px #0d71bb inset!important;color:#1678c2!important}.ui.basic.primary.active.button,.ui.basic.primary.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1279c6 inset!important;box-shadow:0 0 0 1px #1279c6 inset!important;color:#1a69a4!important}.ui.basic.primary.button:active,.ui.basic.primary.buttons .button:active{-webkit-box-shadow:0 0 0 1px #1a69a4 inset!important;box-shadow:0 0 0 1px #1a69a4 inset!important;color:#1a69a4!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.inverted.primary.button,.ui.inverted.primary.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #54c8ff inset!important;box-shadow:0 0 0 2px #54c8ff inset!important;color:#54c8ff}.ui.inverted.primary.button.active,.ui.inverted.primary.button:active,.ui.inverted.primary.button:focus,.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button.active,.ui.inverted.primary.buttons .button:active,.ui.inverted.primary.buttons .button:focus,.ui.inverted.primary.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button:hover{background-color:#3ac0ff}.ui.inverted.primary.button:focus,.ui.inverted.primary.buttons .button:focus{background-color:#2bbbff}.ui.inverted.primary.active.button,.ui.inverted.primary.buttons .active.button{background-color:#3ac0ff}.ui.inverted.primary.button:active,.ui.inverted.primary.buttons .button:active{background-color:#21b8ff}.ui.inverted.primary.basic.button,.ui.inverted.primary.basic.buttons .button,.ui.inverted.primary.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.primary.basic.button:hover,.ui.inverted.primary.basic.buttons .button:hover,.ui.inverted.primary.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.button:focus,.ui.inverted.primary.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #2bbbff inset!important;box-shadow:0 0 0 2px #2bbbff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.active.button,.ui.inverted.primary.basic.buttons .active.button,.ui.inverted.primary.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.button:active,.ui.inverted.primary.basic.buttons .button:active,.ui.inverted.primary.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #21b8ff inset!important;box-shadow:0 0 0 2px #21b8ff inset!important;color:#54c8ff!important}.ui.secondary.button,.ui.secondary.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.secondary.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.secondary.button:hover,.ui.secondary.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.secondary.button:focus,.ui.secondary.buttons .button:focus{background-color:#2e3032;color:#fff;text-shadow:none}.ui.secondary.button:active,.ui.secondary.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.secondary.active.button,.ui.secondary.button .active.button:active,.ui.secondary.buttons .active.button,.ui.secondary.buttons .active.button:active{background-color:#27292a;color:#fff;text-shadow:none}.ui.basic.secondary.button,.ui.basic.secondary.buttons .button{-webkit-box-shadow:0 0 0 1px #1b1c1d inset!important;box-shadow:0 0 0 1px #1b1c1d inset!important;color:#1b1c1d!important}.ui.basic.secondary.button:hover,.ui.basic.secondary.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#27292a!important}.ui.basic.secondary.button:focus,.ui.basic.secondary.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #2e3032 inset!important;box-shadow:0 0 0 1px #2e3032 inset!important;color:#27292a!important}.ui.basic.secondary.active.button,.ui.basic.secondary.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#343637!important}.ui.basic.secondary.button:active,.ui.basic.secondary.buttons .button:active{-webkit-box-shadow:0 0 0 1px #343637 inset!important;box-shadow:0 0 0 1px #343637 inset!important;color:#343637!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.inverted.secondary.button,.ui.inverted.secondary.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #545454 inset!important;box-shadow:0 0 0 2px #545454 inset!important;color:#545454}.ui.inverted.secondary.button.active,.ui.inverted.secondary.button:active,.ui.inverted.secondary.button:focus,.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button.active,.ui.inverted.secondary.buttons .button:active,.ui.inverted.secondary.buttons .button:focus,.ui.inverted.secondary.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button:hover{background-color:#616161}.ui.inverted.secondary.button:focus,.ui.inverted.secondary.buttons .button:focus{background-color:#686868}.ui.inverted.secondary.active.button,.ui.inverted.secondary.buttons .active.button{background-color:#616161}.ui.inverted.secondary.button:active,.ui.inverted.secondary.buttons .button:active{background-color:#6e6e6e}.ui.inverted.secondary.basic.button,.ui.inverted.secondary.basic.buttons .button,.ui.inverted.secondary.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.secondary.basic.button:hover,.ui.inverted.secondary.basic.buttons .button:hover,.ui.inverted.secondary.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #616161 inset!important;box-shadow:0 0 0 2px #616161 inset!important;color:#545454!important}.ui.inverted.secondary.basic.button:focus,.ui.inverted.secondary.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #686868 inset!important;box-shadow:0 0 0 2px #686868 inset!important;color:#545454!important}.ui.inverted.secondary.basic.active.button,.ui.inverted.secondary.basic.buttons .active.button,.ui.inverted.secondary.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #616161 inset!important;box-shadow:0 0 0 2px #616161 inset!important;color:#545454!important}.ui.inverted.secondary.basic.button:active,.ui.inverted.secondary.basic.buttons .button:active,.ui.inverted.secondary.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #6e6e6e inset!important;box-shadow:0 0 0 2px #6e6e6e inset!important;color:#545454!important}.ui.positive.button,.ui.positive.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.positive.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.positive.button:hover,.ui.positive.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.positive.button:focus,.ui.positive.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.positive.button:active,.ui.positive.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.positive.active.button,.ui.positive.button .active.button:active,.ui.positive.buttons .active.button,.ui.positive.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.positive.button,.ui.basic.positive.buttons .button{-webkit-box-shadow:0 0 0 1px #21ba45 inset!important;box-shadow:0 0 0 1px #21ba45 inset!important;color:#21ba45!important}.ui.basic.positive.button:hover,.ui.basic.positive.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #16ab39 inset!important;box-shadow:0 0 0 1px #16ab39 inset!important;color:#16ab39!important}.ui.basic.positive.button:focus,.ui.basic.positive.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0ea432 inset!important;box-shadow:0 0 0 1px #0ea432 inset!important;color:#16ab39!important}.ui.basic.positive.active.button,.ui.basic.positive.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #13ae38 inset!important;box-shadow:0 0 0 1px #13ae38 inset!important;color:#198f35!important}.ui.basic.positive.button:active,.ui.basic.positive.buttons .button:active{-webkit-box-shadow:0 0 0 1px #198f35 inset!important;box-shadow:0 0 0 1px #198f35 inset!important;color:#198f35!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.negative.button,.ui.negative.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.negative.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.negative.button:hover,.ui.negative.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.negative.button:focus,.ui.negative.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.negative.button:active,.ui.negative.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.negative.active.button,.ui.negative.button .active.button:active,.ui.negative.buttons .active.button,.ui.negative.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.negative.button,.ui.basic.negative.buttons .button{-webkit-box-shadow:0 0 0 1px #db2828 inset!important;box-shadow:0 0 0 1px #db2828 inset!important;color:#db2828!important}.ui.basic.negative.button:hover,.ui.basic.negative.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d01919 inset!important;box-shadow:0 0 0 1px #d01919 inset!important;color:#d01919!important}.ui.basic.negative.button:focus,.ui.basic.negative.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ca1010 inset!important;box-shadow:0 0 0 1px #ca1010 inset!important;color:#d01919!important}.ui.basic.negative.active.button,.ui.basic.negative.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d41515 inset!important;box-shadow:0 0 0 1px #d41515 inset!important;color:#b21e1e!important}.ui.basic.negative.button:active,.ui.basic.negative.buttons .button:active{-webkit-box-shadow:0 0 0 1px #b21e1e inset!important;box-shadow:0 0 0 1px #b21e1e inset!important;color:#b21e1e!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;font-size:0;vertical-align:baseline;margin:0 .25em 0 0}.ui.buttons:not(.basic):not(.inverted){-webkit-box-shadow:none;box-shadow:none}.ui.buttons:after{content:\\\".\\\";display:block;height:0;clear:both;visibility:hidden}.ui.buttons .button{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;margin:0;border-radius:0;margin:0}.ui.buttons:not(.basic):not(.inverted)>.button,.ui.buttons>.ui.button:not(.basic):not(.inverted){-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.buttons .button:first-child{border-left:none;margin-left:0;border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.buttons .button:last-child{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.vertical.buttons .button{display:block;float:none;width:100%;margin:0;-webkit-box-shadow:none;box-shadow:none;border-radius:0}.ui.vertical.buttons .button:first-child{border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.vertical.buttons .button:last-child{margin-bottom:0;border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons .button:only-child{border-radius:.28571429rem}/*!\\n * # Semantic UI 2.4.0 - Container\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.container{display:block;max-width:100%!important}@media only screen and (max-width:767px){.ui.container{width:auto!important;margin-left:1em!important;margin-right:1em!important}.ui.grid.container{width:auto!important}.ui.relaxed.grid.container{width:auto!important}.ui.very.relaxed.grid.container{width:auto!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.container{width:723px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(723px + 2rem)!important}.ui.relaxed.grid.container{width:calc(723px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(723px + 5rem)!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.container{width:933px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(933px + 2rem)!important}.ui.relaxed.grid.container{width:calc(933px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(933px + 5rem)!important}}@media only screen and (min-width:1200px){.ui.container{width:1127px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(1127px + 2rem)!important}.ui.relaxed.grid.container{width:calc(1127px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(1127px + 5rem)!important}}.ui.text.container{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;max-width:700px!important;line-height:1.5}.ui.text.container{font-size:1.14285714rem}.ui.fluid.container{width:100%}.ui[class*=\\\"left aligned\\\"].container{text-align:left}.ui[class*=\\\"center aligned\\\"].container{text-align:center}.ui[class*=\\\"right aligned\\\"].container{text-align:right}.ui.justified.container{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}/*!\\n * # Semantic UI 2.4.0 - Divider\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.divider{margin:1rem 0;line-height:1;height:0;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:rgba(0,0,0,.85);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ui.divider:not(.vertical):not(.horizontal){border-top:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(255,255,255,.1)}.ui.grid>.column+.divider,.ui.grid>.row>.column+.divider{left:auto}.ui.horizontal.divider{display:table;white-space:nowrap;height:auto;margin:'';line-height:1;text-align:center}.ui.horizontal.divider:after,.ui.horizontal.divider:before{content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.horizontal.divider:before{background-position:right 1em top 50%}.ui.horizontal.divider:after{background-position:left 1em top 50%}.ui.vertical.divider{position:absolute;z-index:2;top:50%;left:50%;margin:0;padding:0;width:auto;height:50%;line-height:0;text-align:center;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ui.vertical.divider:after,.ui.vertical.divider:before{position:absolute;left:50%;content:'';z-index:3;border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(255,255,255,.1);width:0%;height:calc(100% - 1rem)}.ui.vertical.divider:before{top:-100%}.ui.vertical.divider:after{top:auto;bottom:0}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider,.ui.stackable.grid .ui.vertical.divider{display:table;white-space:nowrap;height:auto;margin:'';overflow:hidden;line-height:1;text-align:center;position:static;top:0;left:0;-webkit-transform:none;transform:none}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{position:static;left:0;border-left:none;border-right:none;content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:before{background-position:right 1em top 50%}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:after{background-position:left 1em top 50%}}.ui.divider>.icon{margin:0;font-size:1rem;height:1em;vertical-align:middle}.ui.hidden.divider{border-color:transparent!important}.ui.hidden.divider:after,.ui.hidden.divider:before{display:none}.ui.divider.inverted,.ui.horizontal.inverted.divider,.ui.vertical.inverted.divider{color:#fff}.ui.divider.inverted,.ui.divider.inverted:after,.ui.divider.inverted:before{border-top-color:rgba(34,36,38,.15)!important;border-left-color:rgba(34,36,38,.15)!important;border-bottom-color:rgba(255,255,255,.15)!important;border-right-color:rgba(255,255,255,.15)!important}.ui.fitted.divider{margin:0}.ui.clearing.divider{clear:both}.ui.section.divider{margin-top:2rem;margin-bottom:2rem}.ui.divider{font-size:1rem}.ui.horizontal.divider:after,.ui.horizontal.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}}/*!\\n * # Semantic UI 2.4.0 - Flag\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */i.flag:not(.icon){display:inline-block;width:16px;height:11px;line-height:11px;vertical-align:baseline;margin:0 .5em 0 0;text-decoration:inherit;speak:none;font-smoothing:antialiased;-webkit-backface-visibility:hidden;backface-visibility:hidden}i.flag:not(.icon):before{display:inline-block;content:'';background:url(\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \") no-repeat -108px -1976px;width:16px;height:11px}i.flag.ad:before,i.flag.andorra:before{background-position:0 0}i.flag.ae:before,i.flag.uae:before,i.flag.united.arab.emirates:before{background-position:0 -26px}i.flag.af:before,i.flag.afghanistan:before{background-position:0 -52px}i.flag.ag:before,i.flag.antigua:before{background-position:0 -78px}i.flag.ai:before,i.flag.anguilla:before{background-position:0 -104px}i.flag.al:before,i.flag.albania:before{background-position:0 -130px}i.flag.am:before,i.flag.armenia:before{background-position:0 -156px}i.flag.an:before,i.flag.netherlands.antilles:before{background-position:0 -182px}i.flag.angola:before,i.flag.ao:before{background-position:0 -208px}i.flag.ar:before,i.flag.argentina:before{background-position:0 -234px}i.flag.american.samoa:before,i.flag.as:before{background-position:0 -260px}i.flag.at:before,i.flag.austria:before{background-position:0 -286px}i.flag.au:before,i.flag.australia:before{background-position:0 -312px}i.flag.aruba:before,i.flag.aw:before{background-position:0 -338px}i.flag.aland.islands:before,i.flag.ax:before{background-position:0 -364px}i.flag.az:before,i.flag.azerbaijan:before{background-position:0 -390px}i.flag.ba:before,i.flag.bosnia:before{background-position:0 -416px}i.flag.barbados:before,i.flag.bb:before{background-position:0 -442px}i.flag.bangladesh:before,i.flag.bd:before{background-position:0 -468px}i.flag.be:before,i.flag.belgium:before{background-position:0 -494px}i.flag.bf:before,i.flag.burkina.faso:before{background-position:0 -520px}i.flag.bg:before,i.flag.bulgaria:before{background-position:0 -546px}i.flag.bahrain:before,i.flag.bh:before{background-position:0 -572px}i.flag.bi:before,i.flag.burundi:before{background-position:0 -598px}i.flag.benin:before,i.flag.bj:before{background-position:0 -624px}i.flag.bermuda:before,i.flag.bm:before{background-position:0 -650px}i.flag.bn:before,i.flag.brunei:before{background-position:0 -676px}i.flag.bo:before,i.flag.bolivia:before{background-position:0 -702px}i.flag.br:before,i.flag.brazil:before{background-position:0 -728px}i.flag.bahamas:before,i.flag.bs:before{background-position:0 -754px}i.flag.bhutan:before,i.flag.bt:before{background-position:0 -780px}i.flag.bouvet.island:before,i.flag.bv:before{background-position:0 -806px}i.flag.botswana:before,i.flag.bw:before{background-position:0 -832px}i.flag.belarus:before,i.flag.by:before{background-position:0 -858px}i.flag.belize:before,i.flag.bz:before{background-position:0 -884px}i.flag.ca:before,i.flag.canada:before{background-position:0 -910px}i.flag.cc:before,i.flag.cocos.islands:before{background-position:0 -962px}i.flag.cd:before,i.flag.congo:before{background-position:0 -988px}i.flag.central.african.republic:before,i.flag.cf:before{background-position:0 -1014px}i.flag.cg:before,i.flag.congo.brazzaville:before{background-position:0 -1040px}i.flag.ch:before,i.flag.switzerland:before{background-position:0 -1066px}i.flag.ci:before,i.flag.cote.divoire:before{background-position:0 -1092px}i.flag.ck:before,i.flag.cook.islands:before{background-position:0 -1118px}i.flag.chile:before,i.flag.cl:before{background-position:0 -1144px}i.flag.cameroon:before,i.flag.cm:before{background-position:0 -1170px}i.flag.china:before,i.flag.cn:before{background-position:0 -1196px}i.flag.co:before,i.flag.colombia:before{background-position:0 -1222px}i.flag.costa.rica:before,i.flag.cr:before{background-position:0 -1248px}i.flag.cs:before,i.flag.serbia:before{background-position:0 -1274px}i.flag.cu:before,i.flag.cuba:before{background-position:0 -1300px}i.flag.cape.verde:before,i.flag.cv:before{background-position:0 -1326px}i.flag.christmas.island:before,i.flag.cx:before{background-position:0 -1352px}i.flag.cy:before,i.flag.cyprus:before{background-position:0 -1378px}i.flag.cz:before,i.flag.czech.republic:before{background-position:0 -1404px}i.flag.de:before,i.flag.germany:before{background-position:0 -1430px}i.flag.dj:before,i.flag.djibouti:before{background-position:0 -1456px}i.flag.denmark:before,i.flag.dk:before{background-position:0 -1482px}i.flag.dm:before,i.flag.dominica:before{background-position:0 -1508px}i.flag.do:before,i.flag.dominican.republic:before{background-position:0 -1534px}i.flag.algeria:before,i.flag.dz:before{background-position:0 -1560px}i.flag.ec:before,i.flag.ecuador:before{background-position:0 -1586px}i.flag.ee:before,i.flag.estonia:before{background-position:0 -1612px}i.flag.eg:before,i.flag.egypt:before{background-position:0 -1638px}i.flag.eh:before,i.flag.western.sahara:before{background-position:0 -1664px}i.flag.england:before,i.flag.gb.eng:before{background-position:0 -1690px}i.flag.er:before,i.flag.eritrea:before{background-position:0 -1716px}i.flag.es:before,i.flag.spain:before{background-position:0 -1742px}i.flag.et:before,i.flag.ethiopia:before{background-position:0 -1768px}i.flag.eu:before,i.flag.european.union:before{background-position:0 -1794px}i.flag.fi:before,i.flag.finland:before{background-position:0 -1846px}i.flag.fiji:before,i.flag.fj:before{background-position:0 -1872px}i.flag.falkland.islands:before,i.flag.fk:before{background-position:0 -1898px}i.flag.fm:before,i.flag.micronesia:before{background-position:0 -1924px}i.flag.faroe.islands:before,i.flag.fo:before{background-position:0 -1950px}i.flag.fr:before,i.flag.france:before{background-position:0 -1976px}i.flag.ga:before,i.flag.gabon:before{background-position:-36px 0}i.flag.gb:before,i.flag.uk:before,i.flag.united.kingdom:before{background-position:-36px -26px}i.flag.gd:before,i.flag.grenada:before{background-position:-36px -52px}i.flag.ge:before,i.flag.georgia:before{background-position:-36px -78px}i.flag.french.guiana:before,i.flag.gf:before{background-position:-36px -104px}i.flag.gh:before,i.flag.ghana:before{background-position:-36px -130px}i.flag.gi:before,i.flag.gibraltar:before{background-position:-36px -156px}i.flag.gl:before,i.flag.greenland:before{background-position:-36px -182px}i.flag.gambia:before,i.flag.gm:before{background-position:-36px -208px}i.flag.gn:before,i.flag.guinea:before{background-position:-36px -234px}i.flag.gp:before,i.flag.guadeloupe:before{background-position:-36px -260px}i.flag.equatorial.guinea:before,i.flag.gq:before{background-position:-36px -286px}i.flag.gr:before,i.flag.greece:before{background-position:-36px -312px}i.flag.gs:before,i.flag.sandwich.islands:before{background-position:-36px -338px}i.flag.gt:before,i.flag.guatemala:before{background-position:-36px -364px}i.flag.gu:before,i.flag.guam:before{background-position:-36px -390px}i.flag.guinea-bissau:before,i.flag.gw:before{background-position:-36px -416px}i.flag.guyana:before,i.flag.gy:before{background-position:-36px -442px}i.flag.hk:before,i.flag.hong.kong:before{background-position:-36px -468px}i.flag.heard.island:before,i.flag.hm:before{background-position:-36px -494px}i.flag.hn:before,i.flag.honduras:before{background-position:-36px -520px}i.flag.croatia:before,i.flag.hr:before{background-position:-36px -546px}i.flag.haiti:before,i.flag.ht:before{background-position:-36px -572px}i.flag.hu:before,i.flag.hungary:before{background-position:-36px -598px}i.flag.id:before,i.flag.indonesia:before{background-position:-36px -624px}i.flag.ie:before,i.flag.ireland:before{background-position:-36px -650px}i.flag.il:before,i.flag.israel:before{background-position:-36px -676px}i.flag.in:before,i.flag.india:before{background-position:-36px -702px}i.flag.indian.ocean.territory:before,i.flag.io:before{background-position:-36px -728px}i.flag.iq:before,i.flag.iraq:before{background-position:-36px -754px}i.flag.ir:before,i.flag.iran:before{background-position:-36px -780px}i.flag.iceland:before,i.flag.is:before{background-position:-36px -806px}i.flag.it:before,i.flag.italy:before{background-position:-36px -832px}i.flag.jamaica:before,i.flag.jm:before{background-position:-36px -858px}i.flag.jo:before,i.flag.jordan:before{background-position:-36px -884px}i.flag.japan:before,i.flag.jp:before{background-position:-36px -910px}i.flag.ke:before,i.flag.kenya:before{background-position:-36px -936px}i.flag.kg:before,i.flag.kyrgyzstan:before{background-position:-36px -962px}i.flag.cambodia:before,i.flag.kh:before{background-position:-36px -988px}i.flag.ki:before,i.flag.kiribati:before{background-position:-36px -1014px}i.flag.comoros:before,i.flag.km:before{background-position:-36px -1040px}i.flag.kn:before,i.flag.saint.kitts.and.nevis:before{background-position:-36px -1066px}i.flag.kp:before,i.flag.north.korea:before{background-position:-36px -1092px}i.flag.kr:before,i.flag.south.korea:before{background-position:-36px -1118px}i.flag.kuwait:before,i.flag.kw:before{background-position:-36px -1144px}i.flag.cayman.islands:before,i.flag.ky:before{background-position:-36px -1170px}i.flag.kazakhstan:before,i.flag.kz:before{background-position:-36px -1196px}i.flag.la:before,i.flag.laos:before{background-position:-36px -1222px}i.flag.lb:before,i.flag.lebanon:before{background-position:-36px -1248px}i.flag.lc:before,i.flag.saint.lucia:before{background-position:-36px -1274px}i.flag.li:before,i.flag.liechtenstein:before{background-position:-36px -1300px}i.flag.lk:before,i.flag.sri.lanka:before{background-position:-36px -1326px}i.flag.liberia:before,i.flag.lr:before{background-position:-36px -1352px}i.flag.lesotho:before,i.flag.ls:before{background-position:-36px -1378px}i.flag.lithuania:before,i.flag.lt:before{background-position:-36px -1404px}i.flag.lu:before,i.flag.luxembourg:before{background-position:-36px -1430px}i.flag.latvia:before,i.flag.lv:before{background-position:-36px -1456px}i.flag.libya:before,i.flag.ly:before{background-position:-36px -1482px}i.flag.ma:before,i.flag.morocco:before{background-position:-36px -1508px}i.flag.mc:before,i.flag.monaco:before{background-position:-36px -1534px}i.flag.md:before,i.flag.moldova:before{background-position:-36px -1560px}i.flag.me:before,i.flag.montenegro:before{background-position:-36px -1586px}i.flag.madagascar:before,i.flag.mg:before{background-position:-36px -1613px}i.flag.marshall.islands:before,i.flag.mh:before{background-position:-36px -1639px}i.flag.macedonia:before,i.flag.mk:before{background-position:-36px -1665px}i.flag.mali:before,i.flag.ml:before{background-position:-36px -1691px}i.flag.burma:before,i.flag.mm:before,i.flag.myanmar:before{background-position:-73px -1821px}i.flag.mn:before,i.flag.mongolia:before{background-position:-36px -1743px}i.flag.macau:before,i.flag.mo:before{background-position:-36px -1769px}i.flag.mp:before,i.flag.northern.mariana.islands:before{background-position:-36px -1795px}i.flag.martinique:before,i.flag.mq:before{background-position:-36px -1821px}i.flag.mauritania:before,i.flag.mr:before{background-position:-36px -1847px}i.flag.montserrat:before,i.flag.ms:before{background-position:-36px -1873px}i.flag.malta:before,i.flag.mt:before{background-position:-36px -1899px}i.flag.mauritius:before,i.flag.mu:before{background-position:-36px -1925px}i.flag.maldives:before,i.flag.mv:before{background-position:-36px -1951px}i.flag.malawi:before,i.flag.mw:before{background-position:-36px -1977px}i.flag.mexico:before,i.flag.mx:before{background-position:-72px 0}i.flag.malaysia:before,i.flag.my:before{background-position:-72px -26px}i.flag.mozambique:before,i.flag.mz:before{background-position:-72px -52px}i.flag.na:before,i.flag.namibia:before{background-position:-72px -78px}i.flag.nc:before,i.flag.new.caledonia:before{background-position:-72px -104px}i.flag.ne:before,i.flag.niger:before{background-position:-72px -130px}i.flag.nf:before,i.flag.norfolk.island:before{background-position:-72px -156px}i.flag.ng:before,i.flag.nigeria:before{background-position:-72px -182px}i.flag.ni:before,i.flag.nicaragua:before{background-position:-72px -208px}i.flag.netherlands:before,i.flag.nl:before{background-position:-72px -234px}i.flag.no:before,i.flag.norway:before{background-position:-72px -260px}i.flag.nepal:before,i.flag.np:before{background-position:-72px -286px}i.flag.nauru:before,i.flag.nr:before{background-position:-72px -312px}i.flag.niue:before,i.flag.nu:before{background-position:-72px -338px}i.flag.new.zealand:before,i.flag.nz:before{background-position:-72px -364px}i.flag.om:before,i.flag.oman:before{background-position:-72px -390px}i.flag.pa:before,i.flag.panama:before{background-position:-72px -416px}i.flag.pe:before,i.flag.peru:before{background-position:-72px -442px}i.flag.french.polynesia:before,i.flag.pf:before{background-position:-72px -468px}i.flag.new.guinea:before,i.flag.pg:before{background-position:-72px -494px}i.flag.ph:before,i.flag.philippines:before{background-position:-72px -520px}i.flag.pakistan:before,i.flag.pk:before{background-position:-72px -546px}i.flag.pl:before,i.flag.poland:before{background-position:-72px -572px}i.flag.pm:before,i.flag.saint.pierre:before{background-position:-72px -598px}i.flag.pitcairn.islands:before,i.flag.pn:before{background-position:-72px -624px}i.flag.pr:before,i.flag.puerto.rico:before{background-position:-72px -650px}i.flag.palestine:before,i.flag.ps:before{background-position:-72px -676px}i.flag.portugal:before,i.flag.pt:before{background-position:-72px -702px}i.flag.palau:before,i.flag.pw:before{background-position:-72px -728px}i.flag.paraguay:before,i.flag.py:before{background-position:-72px -754px}i.flag.qa:before,i.flag.qatar:before{background-position:-72px -780px}i.flag.re:before,i.flag.reunion:before{background-position:-72px -806px}i.flag.ro:before,i.flag.romania:before{background-position:-72px -832px}i.flag.rs:before,i.flag.serbia:before{background-position:-72px -858px}i.flag.ru:before,i.flag.russia:before{background-position:-72px -884px}i.flag.rw:before,i.flag.rwanda:before{background-position:-72px -910px}i.flag.sa:before,i.flag.saudi.arabia:before{background-position:-72px -936px}i.flag.sb:before,i.flag.solomon.islands:before{background-position:-72px -962px}i.flag.sc:before,i.flag.seychelles:before{background-position:-72px -988px}i.flag.gb.sct:before,i.flag.scotland:before{background-position:-72px -1014px}i.flag.sd:before,i.flag.sudan:before{background-position:-72px -1040px}i.flag.se:before,i.flag.sweden:before{background-position:-72px -1066px}i.flag.sg:before,i.flag.singapore:before{background-position:-72px -1092px}i.flag.saint.helena:before,i.flag.sh:before{background-position:-72px -1118px}i.flag.si:before,i.flag.slovenia:before{background-position:-72px -1144px}i.flag.jan.mayen:before,i.flag.sj:before,i.flag.svalbard:before{background-position:-72px -1170px}i.flag.sk:before,i.flag.slovakia:before{background-position:-72px -1196px}i.flag.sierra.leone:before,i.flag.sl:before{background-position:-72px -1222px}i.flag.san.marino:before,i.flag.sm:before{background-position:-72px -1248px}i.flag.senegal:before,i.flag.sn:before{background-position:-72px -1274px}i.flag.so:before,i.flag.somalia:before{background-position:-72px -1300px}i.flag.sr:before,i.flag.suriname:before{background-position:-72px -1326px}i.flag.sao.tome:before,i.flag.st:before{background-position:-72px -1352px}i.flag.el.salvador:before,i.flag.sv:before{background-position:-72px -1378px}i.flag.sy:before,i.flag.syria:before{background-position:-72px -1404px}i.flag.swaziland:before,i.flag.sz:before{background-position:-72px -1430px}i.flag.caicos.islands:before,i.flag.tc:before{background-position:-72px -1456px}i.flag.chad:before,i.flag.td:before{background-position:-72px -1482px}i.flag.french.territories:before,i.flag.tf:before{background-position:-72px -1508px}i.flag.tg:before,i.flag.togo:before{background-position:-72px -1534px}i.flag.th:before,i.flag.thailand:before{background-position:-72px -1560px}i.flag.tajikistan:before,i.flag.tj:before{background-position:-72px -1586px}i.flag.tk:before,i.flag.tokelau:before{background-position:-72px -1612px}i.flag.timorleste:before,i.flag.tl:before{background-position:-72px -1638px}i.flag.tm:before,i.flag.turkmenistan:before{background-position:-72px -1664px}i.flag.tn:before,i.flag.tunisia:before{background-position:-72px -1690px}i.flag.to:before,i.flag.tonga:before{background-position:-72px -1716px}i.flag.tr:before,i.flag.turkey:before{background-position:-72px -1742px}i.flag.trinidad:before,i.flag.tt:before{background-position:-72px -1768px}i.flag.tuvalu:before,i.flag.tv:before{background-position:-72px -1794px}i.flag.taiwan:before,i.flag.tw:before{background-position:-72px -1820px}i.flag.tanzania:before,i.flag.tz:before{background-position:-72px -1846px}i.flag.ua:before,i.flag.ukraine:before{background-position:-72px -1872px}i.flag.ug:before,i.flag.uganda:before{background-position:-72px -1898px}i.flag.um:before,i.flag.us.minor.islands:before{background-position:-72px -1924px}i.flag.america:before,i.flag.united.states:before,i.flag.us:before{background-position:-72px -1950px}i.flag.uruguay:before,i.flag.uy:before{background-position:-72px -1976px}i.flag.uz:before,i.flag.uzbekistan:before{background-position:-108px 0}i.flag.va:before,i.flag.vatican.city:before{background-position:-108px -26px}i.flag.saint.vincent:before,i.flag.vc:before{background-position:-108px -52px}i.flag.ve:before,i.flag.venezuela:before{background-position:-108px -78px}i.flag.british.virgin.islands:before,i.flag.vg:before{background-position:-108px -104px}i.flag.us.virgin.islands:before,i.flag.vi:before{background-position:-108px -130px}i.flag.vietnam:before,i.flag.vn:before{background-position:-108px -156px}i.flag.vanuatu:before,i.flag.vu:before{background-position:-108px -182px}i.flag.gb.wls:before,i.flag.wales:before{background-position:-108px -208px}i.flag.wallis.and.futuna:before,i.flag.wf:before{background-position:-108px -234px}i.flag.samoa:before,i.flag.ws:before{background-position:-108px -260px}i.flag.ye:before,i.flag.yemen:before{background-position:-108px -286px}i.flag.mayotte:before,i.flag.yt:before{background-position:-108px -312px}i.flag.south.africa:before,i.flag.za:before{background-position:-108px -338px}i.flag.zambia:before,i.flag.zm:before{background-position:-108px -364px}i.flag.zimbabwe:before,i.flag.zw:before{background-position:-108px -390px}/*!\\n * # Semantic UI 2.4.0 - Header\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.header{border:none;margin:calc(2rem - .14285714em) 0 1rem;padding:0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;line-height:1.28571429em;text-transform:none;color:rgba(0,0,0,.87)}.ui.header:first-child{margin-top:-.14285714em}.ui.header:last-child{margin-bottom:0}.ui.header .sub.header{display:block;font-weight:400;padding:0;margin:0;font-size:1rem;line-height:1.2em;color:rgba(0,0,0,.6)}.ui.header>.icon{display:table-cell;opacity:1;font-size:1.5em;padding-top:0;vertical-align:middle}.ui.header .icon:only-child{display:inline-block;padding:0;margin-right:.75rem}.ui.header>.image:not(.icon),.ui.header>img{display:inline-block;margin-top:.14285714em;width:2.5em;height:auto;vertical-align:middle}.ui.header>.image:not(.icon):only-child,.ui.header>img:only-child{margin-right:.75rem}.ui.header .content{display:inline-block;vertical-align:top}.ui.header>.image+.content,.ui.header>img+.content{padding-left:.75rem;vertical-align:middle}.ui.header>.icon+.content{padding-left:.75rem;display:table-cell;vertical-align:middle}.ui.header .ui.label{font-size:'';margin-left:.5rem;vertical-align:middle}.ui.header+p{margin-top:0}h1.ui.header{font-size:2rem}h2.ui.header{font-size:1.71428571rem}h3.ui.header{font-size:1.28571429rem}h4.ui.header{font-size:1.07142857rem}h5.ui.header{font-size:1rem}h1.ui.header .sub.header{font-size:1.14285714rem}h2.ui.header .sub.header{font-size:1.14285714rem}h3.ui.header .sub.header{font-size:1rem}h4.ui.header .sub.header{font-size:1rem}h5.ui.header .sub.header{font-size:.92857143rem}.ui.huge.header{min-height:1em;font-size:2em}.ui.large.header{font-size:1.71428571em}.ui.medium.header{font-size:1.28571429em}.ui.small.header{font-size:1.07142857em}.ui.tiny.header{font-size:1em}.ui.huge.header .sub.header{font-size:1.14285714rem}.ui.large.header .sub.header{font-size:1.14285714rem}.ui.header .sub.header{font-size:1rem}.ui.small.header .sub.header{font-size:1rem}.ui.tiny.header .sub.header{font-size:.92857143rem}.ui.sub.header{padding:0;margin-bottom:.14285714rem;font-weight:700;font-size:.85714286em;text-transform:uppercase;color:''}.ui.small.sub.header{font-size:.78571429em}.ui.sub.header{font-size:.85714286em}.ui.large.sub.header{font-size:.92857143em}.ui.huge.sub.header{font-size:1em}.ui.icon.header{display:inline-block;text-align:center;margin:2rem 0 1rem}.ui.icon.header:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.icon.header:first-child{margin-top:0}.ui.icon.header .icon{float:none;display:block;width:auto;height:auto;line-height:1;padding:0;font-size:3em;margin:0 auto .5rem;opacity:1}.ui.icon.header .content{display:block;padding:0}.ui.icon.header .circular.icon{font-size:2em}.ui.icon.header .square.icon{font-size:2em}.ui.block.icon.header .icon{margin-bottom:0}.ui.icon.header.aligned{margin-left:auto;margin-right:auto;display:block}.ui.disabled.header{opacity:.45}.ui.inverted.header{color:#fff}.ui.inverted.header .sub.header{color:rgba(255,255,255,.8)}.ui.inverted.attached.header{background:#545454 -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#545454 -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#545454 linear-gradient(transparent,rgba(0,0,0,.05));-webkit-box-shadow:none;box-shadow:none;border-color:transparent}.ui.inverted.block.header{background:#545454 -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#545454 -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#545454 linear-gradient(transparent,rgba(0,0,0,.05));-webkit-box-shadow:none;box-shadow:none}.ui.inverted.block.header{border-bottom:none}.ui.red.header{color:#db2828!important}a.ui.red.header:hover{color:#d01919!important}.ui.red.dividing.header{border-bottom:2px solid #db2828}.ui.inverted.red.header{color:#ff695e!important}a.ui.inverted.red.header:hover{color:#ff5144!important}.ui.orange.header{color:#f2711c!important}a.ui.orange.header:hover{color:#f26202!important}.ui.orange.dividing.header{border-bottom:2px solid #f2711c}.ui.inverted.orange.header{color:#ff851b!important}a.ui.inverted.orange.header:hover{color:#ff7701!important}.ui.olive.header{color:#b5cc18!important}a.ui.olive.header:hover{color:#a7bd0d!important}.ui.olive.dividing.header{border-bottom:2px solid #b5cc18}.ui.inverted.olive.header{color:#d9e778!important}a.ui.inverted.olive.header:hover{color:#d8ea5c!important}.ui.yellow.header{color:#fbbd08!important}a.ui.yellow.header:hover{color:#eaae00!important}.ui.yellow.dividing.header{border-bottom:2px solid #fbbd08}.ui.inverted.yellow.header{color:#ffe21f!important}a.ui.inverted.yellow.header:hover{color:#ffdf05!important}.ui.green.header{color:#21ba45!important}a.ui.green.header:hover{color:#16ab39!important}.ui.green.dividing.header{border-bottom:2px solid #21ba45}.ui.inverted.green.header{color:#2ecc40!important}a.ui.inverted.green.header:hover{color:#22be34!important}.ui.teal.header{color:#00b5ad!important}a.ui.teal.header:hover{color:#009c95!important}.ui.teal.dividing.header{border-bottom:2px solid #00b5ad}.ui.inverted.teal.header{color:#6dffff!important}a.ui.inverted.teal.header:hover{color:#54ffff!important}.ui.blue.header{color:#2185d0!important}a.ui.blue.header:hover{color:#1678c2!important}.ui.blue.dividing.header{border-bottom:2px solid #2185d0}.ui.inverted.blue.header{color:#54c8ff!important}a.ui.inverted.blue.header:hover{color:#3ac0ff!important}.ui.violet.header{color:#6435c9!important}a.ui.violet.header:hover{color:#5829bb!important}.ui.violet.dividing.header{border-bottom:2px solid #6435c9}.ui.inverted.violet.header{color:#a291fb!important}a.ui.inverted.violet.header:hover{color:#8a73ff!important}.ui.purple.header{color:#a333c8!important}a.ui.purple.header:hover{color:#9627ba!important}.ui.purple.dividing.header{border-bottom:2px solid #a333c8}.ui.inverted.purple.header{color:#dc73ff!important}a.ui.inverted.purple.header:hover{color:#d65aff!important}.ui.pink.header{color:#e03997!important}a.ui.pink.header:hover{color:#e61a8d!important}.ui.pink.dividing.header{border-bottom:2px solid #e03997}.ui.inverted.pink.header{color:#ff8edf!important}a.ui.inverted.pink.header:hover{color:#ff74d8!important}.ui.brown.header{color:#a5673f!important}a.ui.brown.header:hover{color:#975b33!important}.ui.brown.dividing.header{border-bottom:2px solid #a5673f}.ui.inverted.brown.header{color:#d67c1c!important}a.ui.inverted.brown.header:hover{color:#c86f11!important}.ui.grey.header{color:#767676!important}a.ui.grey.header:hover{color:#838383!important}.ui.grey.dividing.header{border-bottom:2px solid #767676}.ui.inverted.grey.header{color:#dcddde!important}a.ui.inverted.grey.header:hover{color:#cfd0d2!important}.ui.left.aligned.header{text-align:left}.ui.right.aligned.header{text-align:right}.ui.center.aligned.header,.ui.centered.header{text-align:center}.ui.justified.header{text-align:justify}.ui.justified.header:after{display:inline-block;content:'';width:100%}.ui.floated.header,.ui[class*=\\\"left floated\\\"].header{float:left;margin-top:0;margin-right:.5em}.ui[class*=\\\"right floated\\\"].header{float:right;margin-top:0;margin-left:.5em}.ui.fitted.header{padding:0}.ui.dividing.header{padding-bottom:.21428571rem;border-bottom:1px solid rgba(34,36,38,.15)}.ui.dividing.header .sub.header{padding-bottom:.21428571rem}.ui.dividing.header .icon{margin-bottom:0}.ui.inverted.dividing.header{border-bottom-color:rgba(255,255,255,.1)}.ui.block.header{background:#f3f4f5;padding:.78571429rem 1rem;-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5;border-radius:.28571429rem}.ui.tiny.block.header{font-size:.85714286rem}.ui.small.block.header{font-size:.92857143rem}.ui.block.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1rem}.ui.large.block.header{font-size:1.14285714rem}.ui.huge.block.header{font-size:1.42857143rem}.ui.attached.header{background:#fff;padding:.78571429rem 1rem;margin-left:-1px;margin-right:-1px;-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached.block.header{background:#f3f4f5}.ui.attached:not(.top):not(.bottom).header{margin-top:0;margin-bottom:0;border-top:none;border-radius:0}.ui.top.attached.header{margin-bottom:0;border-radius:.28571429rem .28571429rem 0 0}.ui.bottom.attached.header{margin-top:0;border-top:none;border-radius:0 0 .28571429rem .28571429rem}.ui.tiny.attached.header{font-size:.85714286em}.ui.small.attached.header{font-size:.92857143em}.ui.attached.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1em}.ui.large.attached.header{font-size:1.14285714em}.ui.huge.attached.header{font-size:1.42857143em}.ui.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1.28571429em}/*!\\n * # Semantic UI 2.4.0 - Icon\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */@font-face{font-family:Icons;src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_1___ + \");src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_2___ + \") format('embedded-opentype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_3___ + \") format('woff2'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_4___ + \") format('woff'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_5___ + \") format('truetype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_6___ + \") format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon{display:inline-block;opacity:1;margin:0 .25rem 0 0;width:1.18em;height:1em;font-family:Icons;font-style:normal;font-weight:400;text-decoration:inherit;text-align:center;speak:none;font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-backface-visibility:hidden;backface-visibility:hidden}i.icon:before{background:0 0!important}i.icon.loading{height:1em;line-height:1;-webkit-animation:icon-loading 2s linear infinite;animation:icon-loading 2s linear infinite}@-webkit-keyframes icon-loading{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes icon-loading{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}i.icon.hover{opacity:1!important}i.icon.active{opacity:1!important}i.emphasized.icon{opacity:1!important}i.disabled.icon{opacity:.45!important}i.fitted.icon{width:auto;margin:0!important}i.link.icon,i.link.icons{cursor:pointer;opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}i.link.icon:hover,i.link.icons:hover{opacity:1!important}i.circular.icon{border-radius:500em!important;line-height:1!important;padding:.5em 0!important;-webkit-box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;width:2em!important;height:2em!important}i.circular.inverted.icon{border:none;-webkit-box-shadow:none;box-shadow:none}i.flipped.icon,i.horizontally.flipped.icon{-webkit-transform:scale(-1,1);transform:scale(-1,1)}i.vertically.flipped.icon{-webkit-transform:scale(1,-1);transform:scale(1,-1)}i.clockwise.rotated.icon,i.right.rotated.icon,i.rotated.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}i.counterclockwise.rotated.icon,i.left.rotated.icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}i.bordered.icon{line-height:1;vertical-align:baseline;width:2em;height:2em;padding:.5em 0!important;-webkit-box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset}i.bordered.inverted.icon{border:none;-webkit-box-shadow:none;box-shadow:none}i.inverted.bordered.icon,i.inverted.circular.icon{background-color:#1b1c1d!important;color:#fff!important}i.inverted.icon{color:#fff}i.red.icon{color:#db2828!important}i.inverted.red.icon{color:#ff695e!important}i.inverted.bordered.red.icon,i.inverted.circular.red.icon{background-color:#db2828!important;color:#fff!important}i.orange.icon{color:#f2711c!important}i.inverted.orange.icon{color:#ff851b!important}i.inverted.bordered.orange.icon,i.inverted.circular.orange.icon{background-color:#f2711c!important;color:#fff!important}i.yellow.icon{color:#fbbd08!important}i.inverted.yellow.icon{color:#ffe21f!important}i.inverted.bordered.yellow.icon,i.inverted.circular.yellow.icon{background-color:#fbbd08!important;color:#fff!important}i.olive.icon{color:#b5cc18!important}i.inverted.olive.icon{color:#d9e778!important}i.inverted.bordered.olive.icon,i.inverted.circular.olive.icon{background-color:#b5cc18!important;color:#fff!important}i.green.icon{color:#21ba45!important}i.inverted.green.icon{color:#2ecc40!important}i.inverted.bordered.green.icon,i.inverted.circular.green.icon{background-color:#21ba45!important;color:#fff!important}i.teal.icon{color:#00b5ad!important}i.inverted.teal.icon{color:#6dffff!important}i.inverted.bordered.teal.icon,i.inverted.circular.teal.icon{background-color:#00b5ad!important;color:#fff!important}i.blue.icon{color:#2185d0!important}i.inverted.blue.icon{color:#54c8ff!important}i.inverted.bordered.blue.icon,i.inverted.circular.blue.icon{background-color:#2185d0!important;color:#fff!important}i.violet.icon{color:#6435c9!important}i.inverted.violet.icon{color:#a291fb!important}i.inverted.bordered.violet.icon,i.inverted.circular.violet.icon{background-color:#6435c9!important;color:#fff!important}i.purple.icon{color:#a333c8!important}i.inverted.purple.icon{color:#dc73ff!important}i.inverted.bordered.purple.icon,i.inverted.circular.purple.icon{background-color:#a333c8!important;color:#fff!important}i.pink.icon{color:#e03997!important}i.inverted.pink.icon{color:#ff8edf!important}i.inverted.bordered.pink.icon,i.inverted.circular.pink.icon{background-color:#e03997!important;color:#fff!important}i.brown.icon{color:#a5673f!important}i.inverted.brown.icon{color:#d67c1c!important}i.inverted.bordered.brown.icon,i.inverted.circular.brown.icon{background-color:#a5673f!important;color:#fff!important}i.grey.icon{color:#767676!important}i.inverted.grey.icon{color:#dcddde!important}i.inverted.bordered.grey.icon,i.inverted.circular.grey.icon{background-color:#767676!important;color:#fff!important}i.black.icon{color:#1b1c1d!important}i.inverted.black.icon{color:#545454!important}i.inverted.bordered.black.icon,i.inverted.circular.black.icon{background-color:#1b1c1d!important;color:#fff!important}i.mini.icon,i.mini.icons{line-height:1;font-size:.4em}i.tiny.icon,i.tiny.icons{line-height:1;font-size:.5em}i.small.icon,i.small.icons{line-height:1;font-size:.75em}i.icon,i.icons{font-size:1em}i.large.icon,i.large.icons{line-height:1;vertical-align:middle;font-size:1.5em}i.big.icon,i.big.icons{line-height:1;vertical-align:middle;font-size:2em}i.huge.icon,i.huge.icons{line-height:1;vertical-align:middle;font-size:4em}i.massive.icon,i.massive.icons{line-height:1;vertical-align:middle;font-size:8em}i.icons{display:inline-block;position:relative;line-height:1}i.icons .icon{position:absolute;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);margin:0;margin:0}i.icons .icon:first-child{position:static;width:auto;height:auto;vertical-align:top;-webkit-transform:none;transform:none;margin-right:.25rem}i.icons .corner.icon{top:auto;left:auto;right:0;bottom:0;-webkit-transform:none;transform:none;font-size:.45em;text-shadow:-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff,1px 1px 0 #fff}i.icons .top.right.corner.icon{top:0;left:auto;right:0;bottom:auto}i.icons .top.left.corner.icon{top:0;left:0;right:auto;bottom:auto}i.icons .bottom.left.corner.icon{top:auto;left:0;right:auto;bottom:0}i.icons .bottom.right.corner.icon{top:auto;left:auto;right:0;bottom:0}i.icons .inverted.corner.icon{text-shadow:-1px -1px 0 #1b1c1d,1px -1px 0 #1b1c1d,-1px 1px 0 #1b1c1d,1px 1px 0 #1b1c1d}i.icon.linkedin.in:before{content:\\\"\\\\f0e1\\\"}i.icon.zoom.in:before{content:\\\"\\\\f00e\\\"}i.icon.zoom.out:before{content:\\\"\\\\f010\\\"}i.icon.sign.in:before{content:\\\"\\\\f2f6\\\"}i.icon.in.cart:before{content:\\\"\\\\f218\\\"}i.icon.log.out:before{content:\\\"\\\\f2f5\\\"}i.icon.sign.out:before{content:\\\"\\\\f2f5\\\"}i.icon.\\\\35 00px:before{content:\\\"\\\\f26e\\\"}i.icon.accessible.icon:before{content:\\\"\\\\f368\\\"}i.icon.accusoft:before{content:\\\"\\\\f369\\\"}i.icon.address.book:before{content:\\\"\\\\f2b9\\\"}i.icon.address.card:before{content:\\\"\\\\f2bb\\\"}i.icon.adjust:before{content:\\\"\\\\f042\\\"}i.icon.adn:before{content:\\\"\\\\f170\\\"}i.icon.adversal:before{content:\\\"\\\\f36a\\\"}i.icon.affiliatetheme:before{content:\\\"\\\\f36b\\\"}i.icon.algolia:before{content:\\\"\\\\f36c\\\"}i.icon.align.center:before{content:\\\"\\\\f037\\\"}i.icon.align.justify:before{content:\\\"\\\\f039\\\"}i.icon.align.left:before{content:\\\"\\\\f036\\\"}i.icon.align.right:before{content:\\\"\\\\f038\\\"}i.icon.amazon:before{content:\\\"\\\\f270\\\"}i.icon.amazon.pay:before{content:\\\"\\\\f42c\\\"}i.icon.ambulance:before{content:\\\"\\\\f0f9\\\"}i.icon.american.sign.language.interpreting:before{content:\\\"\\\\f2a3\\\"}i.icon.amilia:before{content:\\\"\\\\f36d\\\"}i.icon.anchor:before{content:\\\"\\\\f13d\\\"}i.icon.android:before{content:\\\"\\\\f17b\\\"}i.icon.angellist:before{content:\\\"\\\\f209\\\"}i.icon.angle.double.down:before{content:\\\"\\\\f103\\\"}i.icon.angle.double.left:before{content:\\\"\\\\f100\\\"}i.icon.angle.double.right:before{content:\\\"\\\\f101\\\"}i.icon.angle.double.up:before{content:\\\"\\\\f102\\\"}i.icon.angle.down:before{content:\\\"\\\\f107\\\"}i.icon.angle.left:before{content:\\\"\\\\f104\\\"}i.icon.angle.right:before{content:\\\"\\\\f105\\\"}i.icon.angle.up:before{content:\\\"\\\\f106\\\"}i.icon.angrycreative:before{content:\\\"\\\\f36e\\\"}i.icon.angular:before{content:\\\"\\\\f420\\\"}i.icon.app.store:before{content:\\\"\\\\f36f\\\"}i.icon.app.store.ios:before{content:\\\"\\\\f370\\\"}i.icon.apper:before{content:\\\"\\\\f371\\\"}i.icon.apple:before{content:\\\"\\\\f179\\\"}i.icon.apple.pay:before{content:\\\"\\\\f415\\\"}i.icon.archive:before{content:\\\"\\\\f187\\\"}i.icon.arrow.alternate.circle.down:before{content:\\\"\\\\f358\\\"}i.icon.arrow.alternate.circle.left:before{content:\\\"\\\\f359\\\"}i.icon.arrow.alternate.circle.right:before{content:\\\"\\\\f35a\\\"}i.icon.arrow.alternate.circle.up:before{content:\\\"\\\\f35b\\\"}i.icon.arrow.circle.down:before{content:\\\"\\\\f0ab\\\"}i.icon.arrow.circle.left:before{content:\\\"\\\\f0a8\\\"}i.icon.arrow.circle.right:before{content:\\\"\\\\f0a9\\\"}i.icon.arrow.circle.up:before{content:\\\"\\\\f0aa\\\"}i.icon.arrow.down:before{content:\\\"\\\\f063\\\"}i.icon.arrow.left:before{content:\\\"\\\\f060\\\"}i.icon.arrow.right:before{content:\\\"\\\\f061\\\"}i.icon.arrow.up:before{content:\\\"\\\\f062\\\"}i.icon.arrows.alternate:before{content:\\\"\\\\f0b2\\\"}i.icon.arrows.alternate.horizontal:before{content:\\\"\\\\f337\\\"}i.icon.arrows.alternate.vertical:before{content:\\\"\\\\f338\\\"}i.icon.assistive.listening.systems:before{content:\\\"\\\\f2a2\\\"}i.icon.asterisk:before{content:\\\"\\\\f069\\\"}i.icon.asymmetrik:before{content:\\\"\\\\f372\\\"}i.icon.at:before{content:\\\"\\\\f1fa\\\"}i.icon.audible:before{content:\\\"\\\\f373\\\"}i.icon.audio.description:before{content:\\\"\\\\f29e\\\"}i.icon.autoprefixer:before{content:\\\"\\\\f41c\\\"}i.icon.avianex:before{content:\\\"\\\\f374\\\"}i.icon.aviato:before{content:\\\"\\\\f421\\\"}i.icon.aws:before{content:\\\"\\\\f375\\\"}i.icon.backward:before{content:\\\"\\\\f04a\\\"}i.icon.balance.scale:before{content:\\\"\\\\f24e\\\"}i.icon.ban:before{content:\\\"\\\\f05e\\\"}i.icon.band.aid:before{content:\\\"\\\\f462\\\"}i.icon.bandcamp:before{content:\\\"\\\\f2d5\\\"}i.icon.barcode:before{content:\\\"\\\\f02a\\\"}i.icon.bars:before{content:\\\"\\\\f0c9\\\"}i.icon.baseball.ball:before{content:\\\"\\\\f433\\\"}i.icon.basketball.ball:before{content:\\\"\\\\f434\\\"}i.icon.bath:before{content:\\\"\\\\f2cd\\\"}i.icon.battery.empty:before{content:\\\"\\\\f244\\\"}i.icon.battery.full:before{content:\\\"\\\\f240\\\"}i.icon.battery.half:before{content:\\\"\\\\f242\\\"}i.icon.battery.quarter:before{content:\\\"\\\\f243\\\"}i.icon.battery.three.quarters:before{content:\\\"\\\\f241\\\"}i.icon.bed:before{content:\\\"\\\\f236\\\"}i.icon.beer:before{content:\\\"\\\\f0fc\\\"}i.icon.behance:before{content:\\\"\\\\f1b4\\\"}i.icon.behance.square:before{content:\\\"\\\\f1b5\\\"}i.icon.bell:before{content:\\\"\\\\f0f3\\\"}i.icon.bell.slash:before{content:\\\"\\\\f1f6\\\"}i.icon.bicycle:before{content:\\\"\\\\f206\\\"}i.icon.bimobject:before{content:\\\"\\\\f378\\\"}i.icon.binoculars:before{content:\\\"\\\\f1e5\\\"}i.icon.birthday.cake:before{content:\\\"\\\\f1fd\\\"}i.icon.bitbucket:before{content:\\\"\\\\f171\\\"}i.icon.bitcoin:before{content:\\\"\\\\f379\\\"}i.icon.bity:before{content:\\\"\\\\f37a\\\"}i.icon.black.tie:before{content:\\\"\\\\f27e\\\"}i.icon.blackberry:before{content:\\\"\\\\f37b\\\"}i.icon.blind:before{content:\\\"\\\\f29d\\\"}i.icon.blogger:before{content:\\\"\\\\f37c\\\"}i.icon.blogger.b:before{content:\\\"\\\\f37d\\\"}i.icon.bluetooth:before{content:\\\"\\\\f293\\\"}i.icon.bluetooth.b:before{content:\\\"\\\\f294\\\"}i.icon.bold:before{content:\\\"\\\\f032\\\"}i.icon.bolt:before{content:\\\"\\\\f0e7\\\"}i.icon.bomb:before{content:\\\"\\\\f1e2\\\"}i.icon.book:before{content:\\\"\\\\f02d\\\"}i.icon.bookmark:before{content:\\\"\\\\f02e\\\"}i.icon.bowling.ball:before{content:\\\"\\\\f436\\\"}i.icon.box:before{content:\\\"\\\\f466\\\"}i.icon.boxes:before{content:\\\"\\\\f468\\\"}i.icon.braille:before{content:\\\"\\\\f2a1\\\"}i.icon.briefcase:before{content:\\\"\\\\f0b1\\\"}i.icon.btc:before{content:\\\"\\\\f15a\\\"}i.icon.bug:before{content:\\\"\\\\f188\\\"}i.icon.building:before{content:\\\"\\\\f1ad\\\"}i.icon.bullhorn:before{content:\\\"\\\\f0a1\\\"}i.icon.bullseye:before{content:\\\"\\\\f140\\\"}i.icon.buromobelexperte:before{content:\\\"\\\\f37f\\\"}i.icon.bus:before{content:\\\"\\\\f207\\\"}i.icon.buysellads:before{content:\\\"\\\\f20d\\\"}i.icon.calculator:before{content:\\\"\\\\f1ec\\\"}i.icon.calendar:before{content:\\\"\\\\f133\\\"}i.icon.calendar.alternate:before{content:\\\"\\\\f073\\\"}i.icon.calendar.check:before{content:\\\"\\\\f274\\\"}i.icon.calendar.minus:before{content:\\\"\\\\f272\\\"}i.icon.calendar.plus:before{content:\\\"\\\\f271\\\"}i.icon.calendar.times:before{content:\\\"\\\\f273\\\"}i.icon.camera:before{content:\\\"\\\\f030\\\"}i.icon.camera.retro:before{content:\\\"\\\\f083\\\"}i.icon.car:before{content:\\\"\\\\f1b9\\\"}i.icon.caret.down:before{content:\\\"\\\\f0d7\\\"}i.icon.caret.left:before{content:\\\"\\\\f0d9\\\"}i.icon.caret.right:before{content:\\\"\\\\f0da\\\"}i.icon.caret.square.down:before{content:\\\"\\\\f150\\\"}i.icon.caret.square.left:before{content:\\\"\\\\f191\\\"}i.icon.caret.square.right:before{content:\\\"\\\\f152\\\"}i.icon.caret.square.up:before{content:\\\"\\\\f151\\\"}i.icon.caret.up:before{content:\\\"\\\\f0d8\\\"}i.icon.cart.arrow.down:before{content:\\\"\\\\f218\\\"}i.icon.cart.plus:before{content:\\\"\\\\f217\\\"}i.icon.cc.amazon.pay:before{content:\\\"\\\\f42d\\\"}i.icon.cc.amex:before{content:\\\"\\\\f1f3\\\"}i.icon.cc.apple.pay:before{content:\\\"\\\\f416\\\"}i.icon.cc.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.cc.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.cc.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.cc.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.cc.paypal:before{content:\\\"\\\\f1f4\\\"}i.icon.cc.stripe:before{content:\\\"\\\\f1f5\\\"}i.icon.cc.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.centercode:before{content:\\\"\\\\f380\\\"}i.icon.certificate:before{content:\\\"\\\\f0a3\\\"}i.icon.chart.area:before{content:\\\"\\\\f1fe\\\"}i.icon.chart.bar:before{content:\\\"\\\\f080\\\"}i.icon.chart.line:before{content:\\\"\\\\f201\\\"}i.icon.chart.pie:before{content:\\\"\\\\f200\\\"}i.icon.check:before{content:\\\"\\\\f00c\\\"}i.icon.check.circle:before{content:\\\"\\\\f058\\\"}i.icon.check.square:before{content:\\\"\\\\f14a\\\"}i.icon.chess:before{content:\\\"\\\\f439\\\"}i.icon.chess.bishop:before{content:\\\"\\\\f43a\\\"}i.icon.chess.board:before{content:\\\"\\\\f43c\\\"}i.icon.chess.king:before{content:\\\"\\\\f43f\\\"}i.icon.chess.knight:before{content:\\\"\\\\f441\\\"}i.icon.chess.pawn:before{content:\\\"\\\\f443\\\"}i.icon.chess.queen:before{content:\\\"\\\\f445\\\"}i.icon.chess.rook:before{content:\\\"\\\\f447\\\"}i.icon.chevron.circle.down:before{content:\\\"\\\\f13a\\\"}i.icon.chevron.circle.left:before{content:\\\"\\\\f137\\\"}i.icon.chevron.circle.right:before{content:\\\"\\\\f138\\\"}i.icon.chevron.circle.up:before{content:\\\"\\\\f139\\\"}i.icon.chevron.down:before{content:\\\"\\\\f078\\\"}i.icon.chevron.left:before{content:\\\"\\\\f053\\\"}i.icon.chevron.right:before{content:\\\"\\\\f054\\\"}i.icon.chevron.up:before{content:\\\"\\\\f077\\\"}i.icon.child:before{content:\\\"\\\\f1ae\\\"}i.icon.chrome:before{content:\\\"\\\\f268\\\"}i.icon.circle:before{content:\\\"\\\\f111\\\"}i.icon.circle.notch:before{content:\\\"\\\\f1ce\\\"}i.icon.clipboard:before{content:\\\"\\\\f328\\\"}i.icon.clipboard.check:before{content:\\\"\\\\f46c\\\"}i.icon.clipboard.list:before{content:\\\"\\\\f46d\\\"}i.icon.clock:before{content:\\\"\\\\f017\\\"}i.icon.clone:before{content:\\\"\\\\f24d\\\"}i.icon.closed.captioning:before{content:\\\"\\\\f20a\\\"}i.icon.cloud:before{content:\\\"\\\\f0c2\\\"}i.icon.cloudscale:before{content:\\\"\\\\f383\\\"}i.icon.cloudsmith:before{content:\\\"\\\\f384\\\"}i.icon.cloudversify:before{content:\\\"\\\\f385\\\"}i.icon.code:before{content:\\\"\\\\f121\\\"}i.icon.code.branch:before{content:\\\"\\\\f126\\\"}i.icon.codepen:before{content:\\\"\\\\f1cb\\\"}i.icon.codiepie:before{content:\\\"\\\\f284\\\"}i.icon.coffee:before{content:\\\"\\\\f0f4\\\"}i.icon.cog:before{content:\\\"\\\\f013\\\"}i.icon.cogs:before{content:\\\"\\\\f085\\\"}i.icon.columns:before{content:\\\"\\\\f0db\\\"}i.icon.comment:before{content:\\\"\\\\f075\\\"}i.icon.comment.alternate:before{content:\\\"\\\\f27a\\\"}i.icon.comments:before{content:\\\"\\\\f086\\\"}i.icon.compass:before{content:\\\"\\\\f14e\\\"}i.icon.compress:before{content:\\\"\\\\f066\\\"}i.icon.connectdevelop:before{content:\\\"\\\\f20e\\\"}i.icon.contao:before{content:\\\"\\\\f26d\\\"}i.icon.copy:before{content:\\\"\\\\f0c5\\\"}i.icon.copyright:before{content:\\\"\\\\f1f9\\\"}i.icon.cpanel:before{content:\\\"\\\\f388\\\"}i.icon.creative.commons:before{content:\\\"\\\\f25e\\\"}i.icon.credit.card:before{content:\\\"\\\\f09d\\\"}i.icon.crop:before{content:\\\"\\\\f125\\\"}i.icon.crosshairs:before{content:\\\"\\\\f05b\\\"}i.icon.css3:before{content:\\\"\\\\f13c\\\"}i.icon.css3.alternate:before{content:\\\"\\\\f38b\\\"}i.icon.cube:before{content:\\\"\\\\f1b2\\\"}i.icon.cubes:before{content:\\\"\\\\f1b3\\\"}i.icon.cut:before{content:\\\"\\\\f0c4\\\"}i.icon.cuttlefish:before{content:\\\"\\\\f38c\\\"}i.icon.d.and.d:before{content:\\\"\\\\f38d\\\"}i.icon.dashcube:before{content:\\\"\\\\f210\\\"}i.icon.database:before{content:\\\"\\\\f1c0\\\"}i.icon.deaf:before{content:\\\"\\\\f2a4\\\"}i.icon.delicious:before{content:\\\"\\\\f1a5\\\"}i.icon.deploydog:before{content:\\\"\\\\f38e\\\"}i.icon.deskpro:before{content:\\\"\\\\f38f\\\"}i.icon.desktop:before{content:\\\"\\\\f108\\\"}i.icon.deviantart:before{content:\\\"\\\\f1bd\\\"}i.icon.digg:before{content:\\\"\\\\f1a6\\\"}i.icon.digital.ocean:before{content:\\\"\\\\f391\\\"}i.icon.discord:before{content:\\\"\\\\f392\\\"}i.icon.discourse:before{content:\\\"\\\\f393\\\"}i.icon.dna:before{content:\\\"\\\\f471\\\"}i.icon.dochub:before{content:\\\"\\\\f394\\\"}i.icon.docker:before{content:\\\"\\\\f395\\\"}i.icon.dollar.sign:before{content:\\\"\\\\f155\\\"}i.icon.dolly:before{content:\\\"\\\\f472\\\"}i.icon.dolly.flatbed:before{content:\\\"\\\\f474\\\"}i.icon.dot.circle:before{content:\\\"\\\\f192\\\"}i.icon.download:before{content:\\\"\\\\f019\\\"}i.icon.draft2digital:before{content:\\\"\\\\f396\\\"}i.icon.dribbble:before{content:\\\"\\\\f17d\\\"}i.icon.dribbble.square:before{content:\\\"\\\\f397\\\"}i.icon.dropbox:before{content:\\\"\\\\f16b\\\"}i.icon.drupal:before{content:\\\"\\\\f1a9\\\"}i.icon.dyalog:before{content:\\\"\\\\f399\\\"}i.icon.earlybirds:before{content:\\\"\\\\f39a\\\"}i.icon.edge:before{content:\\\"\\\\f282\\\"}i.icon.edit:before{content:\\\"\\\\f044\\\"}i.icon.eject:before{content:\\\"\\\\f052\\\"}i.icon.elementor:before{content:\\\"\\\\f430\\\"}i.icon.ellipsis.horizontal:before{content:\\\"\\\\f141\\\"}i.icon.ellipsis.vertical:before{content:\\\"\\\\f142\\\"}i.icon.ember:before{content:\\\"\\\\f423\\\"}i.icon.empire:before{content:\\\"\\\\f1d1\\\"}i.icon.envelope:before{content:\\\"\\\\f0e0\\\"}i.icon.envelope.open:before{content:\\\"\\\\f2b6\\\"}i.icon.envelope.square:before{content:\\\"\\\\f199\\\"}i.icon.envira:before{content:\\\"\\\\f299\\\"}i.icon.eraser:before{content:\\\"\\\\f12d\\\"}i.icon.erlang:before{content:\\\"\\\\f39d\\\"}i.icon.ethereum:before{content:\\\"\\\\f42e\\\"}i.icon.etsy:before{content:\\\"\\\\f2d7\\\"}i.icon.euro.sign:before{content:\\\"\\\\f153\\\"}i.icon.exchange.alternate:before{content:\\\"\\\\f362\\\"}i.icon.exclamation:before{content:\\\"\\\\f12a\\\"}i.icon.exclamation.circle:before{content:\\\"\\\\f06a\\\"}i.icon.exclamation.triangle:before{content:\\\"\\\\f071\\\"}i.icon.expand:before{content:\\\"\\\\f065\\\"}i.icon.expand.arrows.alternate:before{content:\\\"\\\\f31e\\\"}i.icon.expeditedssl:before{content:\\\"\\\\f23e\\\"}i.icon.external.alternate:before{content:\\\"\\\\f35d\\\"}i.icon.external.square.alternate:before{content:\\\"\\\\f360\\\"}i.icon.eye:before{content:\\\"\\\\f06e\\\"}i.icon.eye.dropper:before{content:\\\"\\\\f1fb\\\"}i.icon.eye.slash:before{content:\\\"\\\\f070\\\"}i.icon.facebook:before{content:\\\"\\\\f09a\\\"}i.icon.facebook.f:before{content:\\\"\\\\f39e\\\"}i.icon.facebook.messenger:before{content:\\\"\\\\f39f\\\"}i.icon.facebook.square:before{content:\\\"\\\\f082\\\"}i.icon.fast.backward:before{content:\\\"\\\\f049\\\"}i.icon.fast.forward:before{content:\\\"\\\\f050\\\"}i.icon.fax:before{content:\\\"\\\\f1ac\\\"}i.icon.female:before{content:\\\"\\\\f182\\\"}i.icon.fighter.jet:before{content:\\\"\\\\f0fb\\\"}i.icon.file:before{content:\\\"\\\\f15b\\\"}i.icon.file.alternate:before{content:\\\"\\\\f15c\\\"}i.icon.file.archive:before{content:\\\"\\\\f1c6\\\"}i.icon.file.audio:before{content:\\\"\\\\f1c7\\\"}i.icon.file.code:before{content:\\\"\\\\f1c9\\\"}i.icon.file.excel:before{content:\\\"\\\\f1c3\\\"}i.icon.file.image:before{content:\\\"\\\\f1c5\\\"}i.icon.file.pdf:before{content:\\\"\\\\f1c1\\\"}i.icon.file.powerpoint:before{content:\\\"\\\\f1c4\\\"}i.icon.file.video:before{content:\\\"\\\\f1c8\\\"}i.icon.file.word:before{content:\\\"\\\\f1c2\\\"}i.icon.film:before{content:\\\"\\\\f008\\\"}i.icon.filter:before{content:\\\"\\\\f0b0\\\"}i.icon.fire:before{content:\\\"\\\\f06d\\\"}i.icon.fire.extinguisher:before{content:\\\"\\\\f134\\\"}i.icon.firefox:before{content:\\\"\\\\f269\\\"}i.icon.first.aid:before{content:\\\"\\\\f479\\\"}i.icon.first.order:before{content:\\\"\\\\f2b0\\\"}i.icon.firstdraft:before{content:\\\"\\\\f3a1\\\"}i.icon.flag:before{content:\\\"\\\\f024\\\"}i.icon.flag.checkered:before{content:\\\"\\\\f11e\\\"}i.icon.flask:before{content:\\\"\\\\f0c3\\\"}i.icon.flickr:before{content:\\\"\\\\f16e\\\"}i.icon.flipboard:before{content:\\\"\\\\f44d\\\"}i.icon.fly:before{content:\\\"\\\\f417\\\"}i.icon.folder:before{content:\\\"\\\\f07b\\\"}i.icon.folder.open:before{content:\\\"\\\\f07c\\\"}i.icon.font:before{content:\\\"\\\\f031\\\"}i.icon.font.awesome:before{content:\\\"\\\\f2b4\\\"}i.icon.font.awesome.alternate:before{content:\\\"\\\\f35c\\\"}i.icon.font.awesome.flag:before{content:\\\"\\\\f425\\\"}i.icon.fonticons:before{content:\\\"\\\\f280\\\"}i.icon.fonticons.fi:before{content:\\\"\\\\f3a2\\\"}i.icon.football.ball:before{content:\\\"\\\\f44e\\\"}i.icon.fort.awesome:before{content:\\\"\\\\f286\\\"}i.icon.fort.awesome.alternate:before{content:\\\"\\\\f3a3\\\"}i.icon.forumbee:before{content:\\\"\\\\f211\\\"}i.icon.forward:before{content:\\\"\\\\f04e\\\"}i.icon.foursquare:before{content:\\\"\\\\f180\\\"}i.icon.free.code.camp:before{content:\\\"\\\\f2c5\\\"}i.icon.freebsd:before{content:\\\"\\\\f3a4\\\"}i.icon.frown:before{content:\\\"\\\\f119\\\"}i.icon.futbol:before{content:\\\"\\\\f1e3\\\"}i.icon.gamepad:before{content:\\\"\\\\f11b\\\"}i.icon.gavel:before{content:\\\"\\\\f0e3\\\"}i.icon.gem:before{content:\\\"\\\\f3a5\\\"}i.icon.genderless:before{content:\\\"\\\\f22d\\\"}i.icon.get.pocket:before{content:\\\"\\\\f265\\\"}i.icon.gg:before{content:\\\"\\\\f260\\\"}i.icon.gg.circle:before{content:\\\"\\\\f261\\\"}i.icon.gift:before{content:\\\"\\\\f06b\\\"}i.icon.git:before{content:\\\"\\\\f1d3\\\"}i.icon.git.square:before{content:\\\"\\\\f1d2\\\"}i.icon.github:before{content:\\\"\\\\f09b\\\"}i.icon.github.alternate:before{content:\\\"\\\\f113\\\"}i.icon.github.square:before{content:\\\"\\\\f092\\\"}i.icon.gitkraken:before{content:\\\"\\\\f3a6\\\"}i.icon.gitlab:before{content:\\\"\\\\f296\\\"}i.icon.gitter:before{content:\\\"\\\\f426\\\"}i.icon.glass.martini:before{content:\\\"\\\\f000\\\"}i.icon.glide:before{content:\\\"\\\\f2a5\\\"}i.icon.glide.g:before{content:\\\"\\\\f2a6\\\"}i.icon.globe:before{content:\\\"\\\\f0ac\\\"}i.icon.gofore:before{content:\\\"\\\\f3a7\\\"}i.icon.golf.ball:before{content:\\\"\\\\f450\\\"}i.icon.goodreads:before{content:\\\"\\\\f3a8\\\"}i.icon.goodreads.g:before{content:\\\"\\\\f3a9\\\"}i.icon.google:before{content:\\\"\\\\f1a0\\\"}i.icon.google.drive:before{content:\\\"\\\\f3aa\\\"}i.icon.google.play:before{content:\\\"\\\\f3ab\\\"}i.icon.google.plus:before{content:\\\"\\\\f2b3\\\"}i.icon.google.plus.g:before{content:\\\"\\\\f0d5\\\"}i.icon.google.plus.square:before{content:\\\"\\\\f0d4\\\"}i.icon.google.wallet:before{content:\\\"\\\\f1ee\\\"}i.icon.graduation.cap:before{content:\\\"\\\\f19d\\\"}i.icon.gratipay:before{content:\\\"\\\\f184\\\"}i.icon.grav:before{content:\\\"\\\\f2d6\\\"}i.icon.gripfire:before{content:\\\"\\\\f3ac\\\"}i.icon.grunt:before{content:\\\"\\\\f3ad\\\"}i.icon.gulp:before{content:\\\"\\\\f3ae\\\"}i.icon.h.square:before{content:\\\"\\\\f0fd\\\"}i.icon.hacker.news:before{content:\\\"\\\\f1d4\\\"}i.icon.hacker.news.square:before{content:\\\"\\\\f3af\\\"}i.icon.hand.lizard:before{content:\\\"\\\\f258\\\"}i.icon.hand.paper:before{content:\\\"\\\\f256\\\"}i.icon.hand.peace:before{content:\\\"\\\\f25b\\\"}i.icon.hand.point.down:before{content:\\\"\\\\f0a7\\\"}i.icon.hand.point.left:before{content:\\\"\\\\f0a5\\\"}i.icon.hand.point.right:before{content:\\\"\\\\f0a4\\\"}i.icon.hand.point.up:before{content:\\\"\\\\f0a6\\\"}i.icon.hand.pointer:before{content:\\\"\\\\f25a\\\"}i.icon.hand.rock:before{content:\\\"\\\\f255\\\"}i.icon.hand.scissors:before{content:\\\"\\\\f257\\\"}i.icon.hand.spock:before{content:\\\"\\\\f259\\\"}i.icon.handshake:before{content:\\\"\\\\f2b5\\\"}i.icon.hashtag:before{content:\\\"\\\\f292\\\"}i.icon.hdd:before{content:\\\"\\\\f0a0\\\"}i.icon.heading:before{content:\\\"\\\\f1dc\\\"}i.icon.headphones:before{content:\\\"\\\\f025\\\"}i.icon.heart:before{content:\\\"\\\\f004\\\"}i.icon.heartbeat:before{content:\\\"\\\\f21e\\\"}i.icon.hips:before{content:\\\"\\\\f452\\\"}i.icon.hire.a.helper:before{content:\\\"\\\\f3b0\\\"}i.icon.history:before{content:\\\"\\\\f1da\\\"}i.icon.hockey.puck:before{content:\\\"\\\\f453\\\"}i.icon.home:before{content:\\\"\\\\f015\\\"}i.icon.hooli:before{content:\\\"\\\\f427\\\"}i.icon.hospital:before{content:\\\"\\\\f0f8\\\"}i.icon.hospital.symbol:before{content:\\\"\\\\f47e\\\"}i.icon.hotjar:before{content:\\\"\\\\f3b1\\\"}i.icon.hourglass:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.end:before{content:\\\"\\\\f253\\\"}i.icon.hourglass.half:before{content:\\\"\\\\f252\\\"}i.icon.hourglass.start:before{content:\\\"\\\\f251\\\"}i.icon.houzz:before{content:\\\"\\\\f27c\\\"}i.icon.html5:before{content:\\\"\\\\f13b\\\"}i.icon.hubspot:before{content:\\\"\\\\f3b2\\\"}i.icon.i.cursor:before{content:\\\"\\\\f246\\\"}i.icon.id.badge:before{content:\\\"\\\\f2c1\\\"}i.icon.id.card:before{content:\\\"\\\\f2c2\\\"}i.icon.image:before{content:\\\"\\\\f03e\\\"}i.icon.images:before{content:\\\"\\\\f302\\\"}i.icon.imdb:before{content:\\\"\\\\f2d8\\\"}i.icon.inbox:before{content:\\\"\\\\f01c\\\"}i.icon.indent:before{content:\\\"\\\\f03c\\\"}i.icon.industry:before{content:\\\"\\\\f275\\\"}i.icon.info:before{content:\\\"\\\\f129\\\"}i.icon.info.circle:before{content:\\\"\\\\f05a\\\"}i.icon.instagram:before{content:\\\"\\\\f16d\\\"}i.icon.internet.explorer:before{content:\\\"\\\\f26b\\\"}i.icon.ioxhost:before{content:\\\"\\\\f208\\\"}i.icon.italic:before{content:\\\"\\\\f033\\\"}i.icon.itunes:before{content:\\\"\\\\f3b4\\\"}i.icon.itunes.note:before{content:\\\"\\\\f3b5\\\"}i.icon.jenkins:before{content:\\\"\\\\f3b6\\\"}i.icon.joget:before{content:\\\"\\\\f3b7\\\"}i.icon.joomla:before{content:\\\"\\\\f1aa\\\"}i.icon.js:before{content:\\\"\\\\f3b8\\\"}i.icon.js.square:before{content:\\\"\\\\f3b9\\\"}i.icon.jsfiddle:before{content:\\\"\\\\f1cc\\\"}i.icon.key:before{content:\\\"\\\\f084\\\"}i.icon.keyboard:before{content:\\\"\\\\f11c\\\"}i.icon.keycdn:before{content:\\\"\\\\f3ba\\\"}i.icon.kickstarter:before{content:\\\"\\\\f3bb\\\"}i.icon.kickstarter.k:before{content:\\\"\\\\f3bc\\\"}i.icon.korvue:before{content:\\\"\\\\f42f\\\"}i.icon.language:before{content:\\\"\\\\f1ab\\\"}i.icon.laptop:before{content:\\\"\\\\f109\\\"}i.icon.laravel:before{content:\\\"\\\\f3bd\\\"}i.icon.lastfm:before{content:\\\"\\\\f202\\\"}i.icon.lastfm.square:before{content:\\\"\\\\f203\\\"}i.icon.leaf:before{content:\\\"\\\\f06c\\\"}i.icon.leanpub:before{content:\\\"\\\\f212\\\"}i.icon.lemon:before{content:\\\"\\\\f094\\\"}i.icon.less:before{content:\\\"\\\\f41d\\\"}i.icon.level.down.alternate:before{content:\\\"\\\\f3be\\\"}i.icon.level.up.alternate:before{content:\\\"\\\\f3bf\\\"}i.icon.life.ring:before{content:\\\"\\\\f1cd\\\"}i.icon.lightbulb:before{content:\\\"\\\\f0eb\\\"}i.icon.linechat:before{content:\\\"\\\\f3c0\\\"}i.icon.linkify:before{content:\\\"\\\\f0c1\\\"}i.icon.linkedin:before{content:\\\"\\\\f08c\\\"}i.icon.linkedin.alt:before{content:\\\"\\\\f0e1\\\"}i.icon.linode:before{content:\\\"\\\\f2b8\\\"}i.icon.linux:before{content:\\\"\\\\f17c\\\"}i.icon.lira.sign:before{content:\\\"\\\\f195\\\"}i.icon.list:before{content:\\\"\\\\f03a\\\"}i.icon.list.alternate:before{content:\\\"\\\\f022\\\"}i.icon.list.ol:before{content:\\\"\\\\f0cb\\\"}i.icon.list.ul:before{content:\\\"\\\\f0ca\\\"}i.icon.location.arrow:before{content:\\\"\\\\f124\\\"}i.icon.lock:before{content:\\\"\\\\f023\\\"}i.icon.lock.open:before{content:\\\"\\\\f3c1\\\"}i.icon.long.arrow.alternate.down:before{content:\\\"\\\\f309\\\"}i.icon.long.arrow.alternate.left:before{content:\\\"\\\\f30a\\\"}i.icon.long.arrow.alternate.right:before{content:\\\"\\\\f30b\\\"}i.icon.long.arrow.alternate.up:before{content:\\\"\\\\f30c\\\"}i.icon.low.vision:before{content:\\\"\\\\f2a8\\\"}i.icon.lyft:before{content:\\\"\\\\f3c3\\\"}i.icon.magento:before{content:\\\"\\\\f3c4\\\"}i.icon.magic:before{content:\\\"\\\\f0d0\\\"}i.icon.magnet:before{content:\\\"\\\\f076\\\"}i.icon.male:before{content:\\\"\\\\f183\\\"}i.icon.map:before{content:\\\"\\\\f279\\\"}i.icon.map.marker:before{content:\\\"\\\\f041\\\"}i.icon.map.marker.alternate:before{content:\\\"\\\\f3c5\\\"}i.icon.map.pin:before{content:\\\"\\\\f276\\\"}i.icon.map.signs:before{content:\\\"\\\\f277\\\"}i.icon.mars:before{content:\\\"\\\\f222\\\"}i.icon.mars.double:before{content:\\\"\\\\f227\\\"}i.icon.mars.stroke:before{content:\\\"\\\\f229\\\"}i.icon.mars.stroke.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.mars.stroke.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.maxcdn:before{content:\\\"\\\\f136\\\"}i.icon.medapps:before{content:\\\"\\\\f3c6\\\"}i.icon.medium:before{content:\\\"\\\\f23a\\\"}i.icon.medium.m:before{content:\\\"\\\\f3c7\\\"}i.icon.medkit:before{content:\\\"\\\\f0fa\\\"}i.icon.medrt:before{content:\\\"\\\\f3c8\\\"}i.icon.meetup:before{content:\\\"\\\\f2e0\\\"}i.icon.meh:before{content:\\\"\\\\f11a\\\"}i.icon.mercury:before{content:\\\"\\\\f223\\\"}i.icon.microchip:before{content:\\\"\\\\f2db\\\"}i.icon.microphone:before{content:\\\"\\\\f130\\\"}i.icon.microphone.slash:before{content:\\\"\\\\f131\\\"}i.icon.microsoft:before{content:\\\"\\\\f3ca\\\"}i.icon.minus:before{content:\\\"\\\\f068\\\"}i.icon.minus.circle:before{content:\\\"\\\\f056\\\"}i.icon.minus.square:before{content:\\\"\\\\f146\\\"}i.icon.mix:before{content:\\\"\\\\f3cb\\\"}i.icon.mixcloud:before{content:\\\"\\\\f289\\\"}i.icon.mizuni:before{content:\\\"\\\\f3cc\\\"}i.icon.mobile:before{content:\\\"\\\\f10b\\\"}i.icon.mobile.alternate:before{content:\\\"\\\\f3cd\\\"}i.icon.modx:before{content:\\\"\\\\f285\\\"}i.icon.monero:before{content:\\\"\\\\f3d0\\\"}i.icon.money.bill.alternate:before{content:\\\"\\\\f3d1\\\"}i.icon.moon:before{content:\\\"\\\\f186\\\"}i.icon.motorcycle:before{content:\\\"\\\\f21c\\\"}i.icon.mouse.pointer:before{content:\\\"\\\\f245\\\"}i.icon.music:before{content:\\\"\\\\f001\\\"}i.icon.napster:before{content:\\\"\\\\f3d2\\\"}i.icon.neuter:before{content:\\\"\\\\f22c\\\"}i.icon.newspaper:before{content:\\\"\\\\f1ea\\\"}i.icon.nintendo.switch:before{content:\\\"\\\\f418\\\"}i.icon.node:before{content:\\\"\\\\f419\\\"}i.icon.node.js:before{content:\\\"\\\\f3d3\\\"}i.icon.npm:before{content:\\\"\\\\f3d4\\\"}i.icon.ns8:before{content:\\\"\\\\f3d5\\\"}i.icon.nutritionix:before{content:\\\"\\\\f3d6\\\"}i.icon.object.group:before{content:\\\"\\\\f247\\\"}i.icon.object.ungroup:before{content:\\\"\\\\f248\\\"}i.icon.odnoklassniki:before{content:\\\"\\\\f263\\\"}i.icon.odnoklassniki.square:before{content:\\\"\\\\f264\\\"}i.icon.opencart:before{content:\\\"\\\\f23d\\\"}i.icon.openid:before{content:\\\"\\\\f19b\\\"}i.icon.opera:before{content:\\\"\\\\f26a\\\"}i.icon.optin.monster:before{content:\\\"\\\\f23c\\\"}i.icon.osi:before{content:\\\"\\\\f41a\\\"}i.icon.outdent:before{content:\\\"\\\\f03b\\\"}i.icon.page4:before{content:\\\"\\\\f3d7\\\"}i.icon.pagelines:before{content:\\\"\\\\f18c\\\"}i.icon.paint.brush:before{content:\\\"\\\\f1fc\\\"}i.icon.palfed:before{content:\\\"\\\\f3d8\\\"}i.icon.pallet:before{content:\\\"\\\\f482\\\"}i.icon.paper.plane:before{content:\\\"\\\\f1d8\\\"}i.icon.paperclip:before{content:\\\"\\\\f0c6\\\"}i.icon.paragraph:before{content:\\\"\\\\f1dd\\\"}i.icon.paste:before{content:\\\"\\\\f0ea\\\"}i.icon.patreon:before{content:\\\"\\\\f3d9\\\"}i.icon.pause:before{content:\\\"\\\\f04c\\\"}i.icon.pause.circle:before{content:\\\"\\\\f28b\\\"}i.icon.paw:before{content:\\\"\\\\f1b0\\\"}i.icon.paypal:before{content:\\\"\\\\f1ed\\\"}i.icon.pen.square:before{content:\\\"\\\\f14b\\\"}i.icon.pencil.alternate:before{content:\\\"\\\\f303\\\"}i.icon.percent:before{content:\\\"\\\\f295\\\"}i.icon.periscope:before{content:\\\"\\\\f3da\\\"}i.icon.phabricator:before{content:\\\"\\\\f3db\\\"}i.icon.phoenix.framework:before{content:\\\"\\\\f3dc\\\"}i.icon.phone:before{content:\\\"\\\\f095\\\"}i.icon.phone.square:before{content:\\\"\\\\f098\\\"}i.icon.phone.volume:before{content:\\\"\\\\f2a0\\\"}i.icon.php:before{content:\\\"\\\\f457\\\"}i.icon.pied.piper:before{content:\\\"\\\\f2ae\\\"}i.icon.pied.piper.alternate:before{content:\\\"\\\\f1a8\\\"}i.icon.pied.piper.pp:before{content:\\\"\\\\f1a7\\\"}i.icon.pills:before{content:\\\"\\\\f484\\\"}i.icon.pinterest:before{content:\\\"\\\\f0d2\\\"}i.icon.pinterest.p:before{content:\\\"\\\\f231\\\"}i.icon.pinterest.square:before{content:\\\"\\\\f0d3\\\"}i.icon.plane:before{content:\\\"\\\\f072\\\"}i.icon.play:before{content:\\\"\\\\f04b\\\"}i.icon.play.circle:before{content:\\\"\\\\f144\\\"}i.icon.playstation:before{content:\\\"\\\\f3df\\\"}i.icon.plug:before{content:\\\"\\\\f1e6\\\"}i.icon.plus:before{content:\\\"\\\\f067\\\"}i.icon.plus.circle:before{content:\\\"\\\\f055\\\"}i.icon.plus.square:before{content:\\\"\\\\f0fe\\\"}i.icon.podcast:before{content:\\\"\\\\f2ce\\\"}i.icon.pound.sign:before{content:\\\"\\\\f154\\\"}i.icon.power.off:before{content:\\\"\\\\f011\\\"}i.icon.print:before{content:\\\"\\\\f02f\\\"}i.icon.product.hunt:before{content:\\\"\\\\f288\\\"}i.icon.pushed:before{content:\\\"\\\\f3e1\\\"}i.icon.puzzle.piece:before{content:\\\"\\\\f12e\\\"}i.icon.python:before{content:\\\"\\\\f3e2\\\"}i.icon.qq:before{content:\\\"\\\\f1d6\\\"}i.icon.qrcode:before{content:\\\"\\\\f029\\\"}i.icon.question:before{content:\\\"\\\\f128\\\"}i.icon.question.circle:before{content:\\\"\\\\f059\\\"}i.icon.quidditch:before{content:\\\"\\\\f458\\\"}i.icon.quinscape:before{content:\\\"\\\\f459\\\"}i.icon.quora:before{content:\\\"\\\\f2c4\\\"}i.icon.quote.left:before{content:\\\"\\\\f10d\\\"}i.icon.quote.right:before{content:\\\"\\\\f10e\\\"}i.icon.random:before{content:\\\"\\\\f074\\\"}i.icon.ravelry:before{content:\\\"\\\\f2d9\\\"}i.icon.react:before{content:\\\"\\\\f41b\\\"}i.icon.rebel:before{content:\\\"\\\\f1d0\\\"}i.icon.recycle:before{content:\\\"\\\\f1b8\\\"}i.icon.redriver:before{content:\\\"\\\\f3e3\\\"}i.icon.reddit:before{content:\\\"\\\\f1a1\\\"}i.icon.reddit.alien:before{content:\\\"\\\\f281\\\"}i.icon.reddit.square:before{content:\\\"\\\\f1a2\\\"}i.icon.redo:before{content:\\\"\\\\f01e\\\"}i.icon.redo.alternate:before{content:\\\"\\\\f2f9\\\"}i.icon.registered:before{content:\\\"\\\\f25d\\\"}i.icon.rendact:before{content:\\\"\\\\f3e4\\\"}i.icon.renren:before{content:\\\"\\\\f18b\\\"}i.icon.reply:before{content:\\\"\\\\f3e5\\\"}i.icon.reply.all:before{content:\\\"\\\\f122\\\"}i.icon.replyd:before{content:\\\"\\\\f3e6\\\"}i.icon.resolving:before{content:\\\"\\\\f3e7\\\"}i.icon.retweet:before{content:\\\"\\\\f079\\\"}i.icon.road:before{content:\\\"\\\\f018\\\"}i.icon.rocket:before{content:\\\"\\\\f135\\\"}i.icon.rocketchat:before{content:\\\"\\\\f3e8\\\"}i.icon.rockrms:before{content:\\\"\\\\f3e9\\\"}i.icon.rss:before{content:\\\"\\\\f09e\\\"}i.icon.rss.square:before{content:\\\"\\\\f143\\\"}i.icon.ruble.sign:before{content:\\\"\\\\f158\\\"}i.icon.rupee.sign:before{content:\\\"\\\\f156\\\"}i.icon.safari:before{content:\\\"\\\\f267\\\"}i.icon.sass:before{content:\\\"\\\\f41e\\\"}i.icon.save:before{content:\\\"\\\\f0c7\\\"}i.icon.schlix:before{content:\\\"\\\\f3ea\\\"}i.icon.scribd:before{content:\\\"\\\\f28a\\\"}i.icon.search:before{content:\\\"\\\\f002\\\"}i.icon.search.minus:before{content:\\\"\\\\f010\\\"}i.icon.search.plus:before{content:\\\"\\\\f00e\\\"}i.icon.searchengin:before{content:\\\"\\\\f3eb\\\"}i.icon.sellcast:before{content:\\\"\\\\f2da\\\"}i.icon.sellsy:before{content:\\\"\\\\f213\\\"}i.icon.server:before{content:\\\"\\\\f233\\\"}i.icon.servicestack:before{content:\\\"\\\\f3ec\\\"}i.icon.share:before{content:\\\"\\\\f064\\\"}i.icon.share.alternate:before{content:\\\"\\\\f1e0\\\"}i.icon.share.alternate.square:before{content:\\\"\\\\f1e1\\\"}i.icon.share.square:before{content:\\\"\\\\f14d\\\"}i.icon.shekel.sign:before{content:\\\"\\\\f20b\\\"}i.icon.shield.alternate:before{content:\\\"\\\\f3ed\\\"}i.icon.ship:before{content:\\\"\\\\f21a\\\"}i.icon.shipping.fast:before{content:\\\"\\\\f48b\\\"}i.icon.shirtsinbulk:before{content:\\\"\\\\f214\\\"}i.icon.shopping.bag:before{content:\\\"\\\\f290\\\"}i.icon.shopping.basket:before{content:\\\"\\\\f291\\\"}i.icon.shopping.cart:before{content:\\\"\\\\f07a\\\"}i.icon.shower:before{content:\\\"\\\\f2cc\\\"}i.icon.sign.language:before{content:\\\"\\\\f2a7\\\"}i.icon.signal:before{content:\\\"\\\\f012\\\"}i.icon.simplybuilt:before{content:\\\"\\\\f215\\\"}i.icon.sistrix:before{content:\\\"\\\\f3ee\\\"}i.icon.sitemap:before{content:\\\"\\\\f0e8\\\"}i.icon.skyatlas:before{content:\\\"\\\\f216\\\"}i.icon.skype:before{content:\\\"\\\\f17e\\\"}i.icon.slack:before{content:\\\"\\\\f198\\\"}i.icon.slack.hash:before{content:\\\"\\\\f3ef\\\"}i.icon.sliders.horizontal:before{content:\\\"\\\\f1de\\\"}i.icon.slideshare:before{content:\\\"\\\\f1e7\\\"}i.icon.smile:before{content:\\\"\\\\f118\\\"}i.icon.snapchat:before{content:\\\"\\\\f2ab\\\"}i.icon.snapchat.ghost:before{content:\\\"\\\\f2ac\\\"}i.icon.snapchat.square:before{content:\\\"\\\\f2ad\\\"}i.icon.snowflake:before{content:\\\"\\\\f2dc\\\"}i.icon.sort:before{content:\\\"\\\\f0dc\\\"}i.icon.sort.alphabet.down:before{content:\\\"\\\\f15d\\\"}i.icon.sort.alphabet.up:before{content:\\\"\\\\f15e\\\"}i.icon.sort.amount.down:before{content:\\\"\\\\f160\\\"}i.icon.sort.amount.up:before{content:\\\"\\\\f161\\\"}i.icon.sort.down:before{content:\\\"\\\\f0dd\\\"}i.icon.sort.numeric.down:before{content:\\\"\\\\f162\\\"}i.icon.sort.numeric.up:before{content:\\\"\\\\f163\\\"}i.icon.sort.up:before{content:\\\"\\\\f0de\\\"}i.icon.soundcloud:before{content:\\\"\\\\f1be\\\"}i.icon.space.shuttle:before{content:\\\"\\\\f197\\\"}i.icon.speakap:before{content:\\\"\\\\f3f3\\\"}i.icon.spinner:before{content:\\\"\\\\f110\\\"}i.icon.spotify:before{content:\\\"\\\\f1bc\\\"}i.icon.square:before{content:\\\"\\\\f0c8\\\"}i.icon.square.full:before{content:\\\"\\\\f45c\\\"}i.icon.stack.exchange:before{content:\\\"\\\\f18d\\\"}i.icon.stack.overflow:before{content:\\\"\\\\f16c\\\"}i.icon.star:before{content:\\\"\\\\f005\\\"}i.icon.star.half:before{content:\\\"\\\\f089\\\"}i.icon.staylinked:before{content:\\\"\\\\f3f5\\\"}i.icon.steam:before{content:\\\"\\\\f1b6\\\"}i.icon.steam.square:before{content:\\\"\\\\f1b7\\\"}i.icon.steam.symbol:before{content:\\\"\\\\f3f6\\\"}i.icon.step.backward:before{content:\\\"\\\\f048\\\"}i.icon.step.forward:before{content:\\\"\\\\f051\\\"}i.icon.stethoscope:before{content:\\\"\\\\f0f1\\\"}i.icon.sticker.mule:before{content:\\\"\\\\f3f7\\\"}i.icon.sticky.note:before{content:\\\"\\\\f249\\\"}i.icon.stop:before{content:\\\"\\\\f04d\\\"}i.icon.stop.circle:before{content:\\\"\\\\f28d\\\"}i.icon.stopwatch:before{content:\\\"\\\\f2f2\\\"}i.icon.strava:before{content:\\\"\\\\f428\\\"}i.icon.street.view:before{content:\\\"\\\\f21d\\\"}i.icon.strikethrough:before{content:\\\"\\\\f0cc\\\"}i.icon.stripe:before{content:\\\"\\\\f429\\\"}i.icon.stripe.s:before{content:\\\"\\\\f42a\\\"}i.icon.studiovinari:before{content:\\\"\\\\f3f8\\\"}i.icon.stumbleupon:before{content:\\\"\\\\f1a4\\\"}i.icon.stumbleupon.circle:before{content:\\\"\\\\f1a3\\\"}i.icon.subscript:before{content:\\\"\\\\f12c\\\"}i.icon.subway:before{content:\\\"\\\\f239\\\"}i.icon.suitcase:before{content:\\\"\\\\f0f2\\\"}i.icon.sun:before{content:\\\"\\\\f185\\\"}i.icon.superpowers:before{content:\\\"\\\\f2dd\\\"}i.icon.superscript:before{content:\\\"\\\\f12b\\\"}i.icon.supple:before{content:\\\"\\\\f3f9\\\"}i.icon.sync:before{content:\\\"\\\\f021\\\"}i.icon.sync.alternate:before{content:\\\"\\\\f2f1\\\"}i.icon.syringe:before{content:\\\"\\\\f48e\\\"}i.icon.table:before{content:\\\"\\\\f0ce\\\"}i.icon.table.tennis:before{content:\\\"\\\\f45d\\\"}i.icon.tablet:before{content:\\\"\\\\f10a\\\"}i.icon.tablet.alternate:before{content:\\\"\\\\f3fa\\\"}i.icon.tachometer.alternate:before{content:\\\"\\\\f3fd\\\"}i.icon.tag:before{content:\\\"\\\\f02b\\\"}i.icon.tags:before{content:\\\"\\\\f02c\\\"}i.icon.tasks:before{content:\\\"\\\\f0ae\\\"}i.icon.taxi:before{content:\\\"\\\\f1ba\\\"}i.icon.telegram:before{content:\\\"\\\\f2c6\\\"}i.icon.telegram.plane:before{content:\\\"\\\\f3fe\\\"}i.icon.tencent.weibo:before{content:\\\"\\\\f1d5\\\"}i.icon.terminal:before{content:\\\"\\\\f120\\\"}i.icon.text.height:before{content:\\\"\\\\f034\\\"}i.icon.text.width:before{content:\\\"\\\\f035\\\"}i.icon.th:before{content:\\\"\\\\f00a\\\"}i.icon.th.large:before{content:\\\"\\\\f009\\\"}i.icon.th.list:before{content:\\\"\\\\f00b\\\"}i.icon.themeisle:before{content:\\\"\\\\f2b2\\\"}i.icon.thermometer:before{content:\\\"\\\\f491\\\"}i.icon.thermometer.empty:before{content:\\\"\\\\f2cb\\\"}i.icon.thermometer.full:before{content:\\\"\\\\f2c7\\\"}i.icon.thermometer.half:before{content:\\\"\\\\f2c9\\\"}i.icon.thermometer.quarter:before{content:\\\"\\\\f2ca\\\"}i.icon.thermometer.three.quarters:before{content:\\\"\\\\f2c8\\\"}i.icon.thumbs.down:before{content:\\\"\\\\f165\\\"}i.icon.thumbs.up:before{content:\\\"\\\\f164\\\"}i.icon.thumbtack:before{content:\\\"\\\\f08d\\\"}i.icon.ticket.alternate:before{content:\\\"\\\\f3ff\\\"}i.icon.times:before{content:\\\"\\\\f00d\\\"}i.icon.times.circle:before{content:\\\"\\\\f057\\\"}i.icon.tint:before{content:\\\"\\\\f043\\\"}i.icon.toggle.off:before{content:\\\"\\\\f204\\\"}i.icon.toggle.on:before{content:\\\"\\\\f205\\\"}i.icon.trademark:before{content:\\\"\\\\f25c\\\"}i.icon.train:before{content:\\\"\\\\f238\\\"}i.icon.transgender:before{content:\\\"\\\\f224\\\"}i.icon.transgender.alternate:before{content:\\\"\\\\f225\\\"}i.icon.trash:before{content:\\\"\\\\f1f8\\\"}i.icon.trash.alternate:before{content:\\\"\\\\f2ed\\\"}i.icon.tree:before{content:\\\"\\\\f1bb\\\"}i.icon.trello:before{content:\\\"\\\\f181\\\"}i.icon.tripadvisor:before{content:\\\"\\\\f262\\\"}i.icon.trophy:before{content:\\\"\\\\f091\\\"}i.icon.truck:before{content:\\\"\\\\f0d1\\\"}i.icon.tty:before{content:\\\"\\\\f1e4\\\"}i.icon.tumblr:before{content:\\\"\\\\f173\\\"}i.icon.tumblr.square:before{content:\\\"\\\\f174\\\"}i.icon.tv:before{content:\\\"\\\\f26c\\\"}i.icon.twitch:before{content:\\\"\\\\f1e8\\\"}i.icon.twitter:before{content:\\\"\\\\f099\\\"}i.icon.twitter.square:before{content:\\\"\\\\f081\\\"}i.icon.typo3:before{content:\\\"\\\\f42b\\\"}i.icon.uber:before{content:\\\"\\\\f402\\\"}i.icon.uikit:before{content:\\\"\\\\f403\\\"}i.icon.umbrella:before{content:\\\"\\\\f0e9\\\"}i.icon.underline:before{content:\\\"\\\\f0cd\\\"}i.icon.undo:before{content:\\\"\\\\f0e2\\\"}i.icon.undo.alternate:before{content:\\\"\\\\f2ea\\\"}i.icon.uniregistry:before{content:\\\"\\\\f404\\\"}i.icon.universal.access:before{content:\\\"\\\\f29a\\\"}i.icon.university:before{content:\\\"\\\\f19c\\\"}i.icon.unlink:before{content:\\\"\\\\f127\\\"}i.icon.unlock:before{content:\\\"\\\\f09c\\\"}i.icon.unlock.alternate:before{content:\\\"\\\\f13e\\\"}i.icon.untappd:before{content:\\\"\\\\f405\\\"}i.icon.upload:before{content:\\\"\\\\f093\\\"}i.icon.usb:before{content:\\\"\\\\f287\\\"}i.icon.user:before{content:\\\"\\\\f007\\\"}i.icon.user.circle:before{content:\\\"\\\\f2bd\\\"}i.icon.user.md:before{content:\\\"\\\\f0f0\\\"}i.icon.user.plus:before{content:\\\"\\\\f234\\\"}i.icon.user.secret:before{content:\\\"\\\\f21b\\\"}i.icon.user.times:before{content:\\\"\\\\f235\\\"}i.icon.users:before{content:\\\"\\\\f0c0\\\"}i.icon.ussunnah:before{content:\\\"\\\\f407\\\"}i.icon.utensil.spoon:before{content:\\\"\\\\f2e5\\\"}i.icon.utensils:before{content:\\\"\\\\f2e7\\\"}i.icon.vaadin:before{content:\\\"\\\\f408\\\"}i.icon.venus:before{content:\\\"\\\\f221\\\"}i.icon.venus.double:before{content:\\\"\\\\f226\\\"}i.icon.venus.mars:before{content:\\\"\\\\f228\\\"}i.icon.viacoin:before{content:\\\"\\\\f237\\\"}i.icon.viadeo:before{content:\\\"\\\\f2a9\\\"}i.icon.viadeo.square:before{content:\\\"\\\\f2aa\\\"}i.icon.viber:before{content:\\\"\\\\f409\\\"}i.icon.video:before{content:\\\"\\\\f03d\\\"}i.icon.vimeo:before{content:\\\"\\\\f40a\\\"}i.icon.vimeo.square:before{content:\\\"\\\\f194\\\"}i.icon.vimeo.v:before{content:\\\"\\\\f27d\\\"}i.icon.vine:before{content:\\\"\\\\f1ca\\\"}i.icon.vk:before{content:\\\"\\\\f189\\\"}i.icon.vnv:before{content:\\\"\\\\f40b\\\"}i.icon.volleyball.ball:before{content:\\\"\\\\f45f\\\"}i.icon.volume.down:before{content:\\\"\\\\f027\\\"}i.icon.volume.off:before{content:\\\"\\\\f026\\\"}i.icon.volume.up:before{content:\\\"\\\\f028\\\"}i.icon.vuejs:before{content:\\\"\\\\f41f\\\"}i.icon.warehouse:before{content:\\\"\\\\f494\\\"}i.icon.weibo:before{content:\\\"\\\\f18a\\\"}i.icon.weight:before{content:\\\"\\\\f496\\\"}i.icon.weixin:before{content:\\\"\\\\f1d7\\\"}i.icon.whatsapp:before{content:\\\"\\\\f232\\\"}i.icon.whatsapp.square:before{content:\\\"\\\\f40c\\\"}i.icon.wheelchair:before{content:\\\"\\\\f193\\\"}i.icon.whmcs:before{content:\\\"\\\\f40d\\\"}i.icon.wifi:before{content:\\\"\\\\f1eb\\\"}i.icon.wikipedia.w:before{content:\\\"\\\\f266\\\"}i.icon.window.close:before{content:\\\"\\\\f410\\\"}i.icon.window.maximize:before{content:\\\"\\\\f2d0\\\"}i.icon.window.minimize:before{content:\\\"\\\\f2d1\\\"}i.icon.window.restore:before{content:\\\"\\\\f2d2\\\"}i.icon.windows:before{content:\\\"\\\\f17a\\\"}i.icon.won.sign:before{content:\\\"\\\\f159\\\"}i.icon.wordpress:before{content:\\\"\\\\f19a\\\"}i.icon.wordpress.simple:before{content:\\\"\\\\f411\\\"}i.icon.wpbeginner:before{content:\\\"\\\\f297\\\"}i.icon.wpexplorer:before{content:\\\"\\\\f2de\\\"}i.icon.wpforms:before{content:\\\"\\\\f298\\\"}i.icon.wrench:before{content:\\\"\\\\f0ad\\\"}i.icon.xbox:before{content:\\\"\\\\f412\\\"}i.icon.xing:before{content:\\\"\\\\f168\\\"}i.icon.xing.square:before{content:\\\"\\\\f169\\\"}i.icon.y.combinator:before{content:\\\"\\\\f23b\\\"}i.icon.yahoo:before{content:\\\"\\\\f19e\\\"}i.icon.yandex:before{content:\\\"\\\\f413\\\"}i.icon.yandex.international:before{content:\\\"\\\\f414\\\"}i.icon.yelp:before{content:\\\"\\\\f1e9\\\"}i.icon.yen.sign:before{content:\\\"\\\\f157\\\"}i.icon.yoast:before{content:\\\"\\\\f2b1\\\"}i.icon.youtube:before{content:\\\"\\\\f167\\\"}i.icon.youtube.square:before{content:\\\"\\\\f431\\\"}i.icon.chess.rock:before{content:\\\"\\\\f447\\\"}i.icon.ordered.list:before{content:\\\"\\\\f0cb\\\"}i.icon.unordered.list:before{content:\\\"\\\\f0ca\\\"}i.icon.user.doctor:before{content:\\\"\\\\f0f0\\\"}i.icon.shield:before{content:\\\"\\\\f3ed\\\"}i.icon.puzzle:before{content:\\\"\\\\f12e\\\"}i.icon.credit.card.amazon.pay:before{content:\\\"\\\\f42d\\\"}i.icon.credit.card.american.express:before{content:\\\"\\\\f1f3\\\"}i.icon.credit.card.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.credit.card.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.credit.card.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.credit.card.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.credit.card.paypal:before{content:\\\"\\\\f1f4\\\"}i.icon.credit.card.stripe:before{content:\\\"\\\\f1f5\\\"}i.icon.credit.card.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.add.circle:before{content:\\\"\\\\f055\\\"}i.icon.add.square:before{content:\\\"\\\\f0fe\\\"}i.icon.add.to.calendar:before{content:\\\"\\\\f271\\\"}i.icon.add.to.cart:before{content:\\\"\\\\f217\\\"}i.icon.add.user:before{content:\\\"\\\\f234\\\"}i.icon.add:before{content:\\\"\\\\f067\\\"}i.icon.alarm.mute:before{content:\\\"\\\\f1f6\\\"}i.icon.alarm:before{content:\\\"\\\\f0f3\\\"}i.icon.ald:before{content:\\\"\\\\f2a2\\\"}i.icon.als:before{content:\\\"\\\\f2a2\\\"}i.icon.american.express.card:before{content:\\\"\\\\f1f3\\\"}i.icon.american.express:before{content:\\\"\\\\f1f3\\\"}i.icon.amex:before{content:\\\"\\\\f1f3\\\"}i.icon.announcement:before{content:\\\"\\\\f0a1\\\"}i.icon.area.chart:before{content:\\\"\\\\f1fe\\\"}i.icon.area.graph:before{content:\\\"\\\\f1fe\\\"}i.icon.arrow.down.cart:before{content:\\\"\\\\f218\\\"}i.icon.asexual:before{content:\\\"\\\\f22d\\\"}i.icon.asl.interpreting:before{content:\\\"\\\\f2a3\\\"}i.icon.asl:before{content:\\\"\\\\f2a3\\\"}i.icon.assistive.listening.devices:before{content:\\\"\\\\f2a2\\\"}i.icon.attach:before{content:\\\"\\\\f0c6\\\"}i.icon.attention:before{content:\\\"\\\\f06a\\\"}i.icon.balance:before{content:\\\"\\\\f24e\\\"}i.icon.bar:before{content:\\\"\\\\f0fc\\\"}i.icon.bathtub:before{content:\\\"\\\\f2cd\\\"}i.icon.battery.four:before{content:\\\"\\\\f240\\\"}i.icon.battery.high:before{content:\\\"\\\\f241\\\"}i.icon.battery.low:before{content:\\\"\\\\f243\\\"}i.icon.battery.medium:before{content:\\\"\\\\f242\\\"}i.icon.battery.one:before{content:\\\"\\\\f243\\\"}i.icon.battery.three:before{content:\\\"\\\\f241\\\"}i.icon.battery.two:before{content:\\\"\\\\f242\\\"}i.icon.battery.zero:before{content:\\\"\\\\f244\\\"}i.icon.birthday:before{content:\\\"\\\\f1fd\\\"}i.icon.block.layout:before{content:\\\"\\\\f009\\\"}i.icon.bluetooth.alternative:before{content:\\\"\\\\f294\\\"}i.icon.broken.chain:before{content:\\\"\\\\f127\\\"}i.icon.browser:before{content:\\\"\\\\f022\\\"}i.icon.call.square:before{content:\\\"\\\\f098\\\"}i.icon.call:before{content:\\\"\\\\f095\\\"}i.icon.cancel:before{content:\\\"\\\\f00d\\\"}i.icon.cart:before{content:\\\"\\\\f07a\\\"}i.icon.cc:before{content:\\\"\\\\f20a\\\"}i.icon.chain:before{content:\\\"\\\\f0c1\\\"}i.icon.chat:before{content:\\\"\\\\f075\\\"}i.icon.checked.calendar:before{content:\\\"\\\\f274\\\"}i.icon.checkmark:before{content:\\\"\\\\f00c\\\"}i.icon.circle.notched:before{content:\\\"\\\\f1ce\\\"}i.icon.close:before{content:\\\"\\\\f00d\\\"}i.icon.cny:before{content:\\\"\\\\f157\\\"}i.icon.cocktail:before{content:\\\"\\\\f000\\\"}i.icon.commenting:before{content:\\\"\\\\f27a\\\"}i.icon.computer:before{content:\\\"\\\\f108\\\"}i.icon.configure:before{content:\\\"\\\\f0ad\\\"}i.icon.content:before{content:\\\"\\\\f0c9\\\"}i.icon.deafness:before{content:\\\"\\\\f2a4\\\"}i.icon.delete.calendar:before{content:\\\"\\\\f273\\\"}i.icon.delete:before{content:\\\"\\\\f00d\\\"}i.icon.detective:before{content:\\\"\\\\f21b\\\"}i.icon.diners.club.card:before{content:\\\"\\\\f24c\\\"}i.icon.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.discover.card:before{content:\\\"\\\\f1f2\\\"}i.icon.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.discussions:before{content:\\\"\\\\f086\\\"}i.icon.doctor:before{content:\\\"\\\\f0f0\\\"}i.icon.dollar:before{content:\\\"\\\\f155\\\"}i.icon.dont:before{content:\\\"\\\\f05e\\\"}i.icon.dribble:before{content:\\\"\\\\f17d\\\"}i.icon.drivers.license:before{content:\\\"\\\\f2c2\\\"}i.icon.dropdown:before{content:\\\"\\\\f0d7\\\"}i.icon.eercast:before{content:\\\"\\\\f2da\\\"}i.icon.emergency:before{content:\\\"\\\\f0f9\\\"}i.icon.envira.gallery:before{content:\\\"\\\\f299\\\"}i.icon.erase:before{content:\\\"\\\\f12d\\\"}i.icon.eur:before{content:\\\"\\\\f153\\\"}i.icon.euro:before{content:\\\"\\\\f153\\\"}i.icon.eyedropper:before{content:\\\"\\\\f1fb\\\"}i.icon.fa:before{content:\\\"\\\\f2b4\\\"}i.icon.factory:before{content:\\\"\\\\f275\\\"}i.icon.favorite:before{content:\\\"\\\\f005\\\"}i.icon.feed:before{content:\\\"\\\\f09e\\\"}i.icon.female.homosexual:before{content:\\\"\\\\f226\\\"}i.icon.file.text:before{content:\\\"\\\\f15c\\\"}i.icon.find:before{content:\\\"\\\\f1e5\\\"}i.icon.first.aid:before{content:\\\"\\\\f0fa\\\"}i.icon.five.hundred.pixels:before{content:\\\"\\\\f26e\\\"}i.icon.fork:before{content:\\\"\\\\f126\\\"}i.icon.game:before{content:\\\"\\\\f11b\\\"}i.icon.gay:before{content:\\\"\\\\f227\\\"}i.icon.gbp:before{content:\\\"\\\\f154\\\"}i.icon.gittip:before{content:\\\"\\\\f184\\\"}i.icon.google.plus.circle:before{content:\\\"\\\\f2b3\\\"}i.icon.google.plus.official:before{content:\\\"\\\\f2b3\\\"}i.icon.grab:before{content:\\\"\\\\f255\\\"}i.icon.graduation:before{content:\\\"\\\\f19d\\\"}i.icon.grid.layout:before{content:\\\"\\\\f00a\\\"}i.icon.group:before{content:\\\"\\\\f0c0\\\"}i.icon.h:before{content:\\\"\\\\f0fd\\\"}i.icon.hand.victory:before{content:\\\"\\\\f25b\\\"}i.icon.handicap:before{content:\\\"\\\\f193\\\"}i.icon.hard.of.hearing:before{content:\\\"\\\\f2a4\\\"}i.icon.header:before{content:\\\"\\\\f1dc\\\"}i.icon.help.circle:before{content:\\\"\\\\f059\\\"}i.icon.help:before{content:\\\"\\\\f128\\\"}i.icon.heterosexual:before{content:\\\"\\\\f228\\\"}i.icon.hide:before{content:\\\"\\\\f070\\\"}i.icon.hotel:before{content:\\\"\\\\f236\\\"}i.icon.hourglass.four:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.full:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.one:before{content:\\\"\\\\f251\\\"}i.icon.hourglass.three:before{content:\\\"\\\\f253\\\"}i.icon.hourglass.two:before{content:\\\"\\\\f252\\\"}i.icon.idea:before{content:\\\"\\\\f0eb\\\"}i.icon.ils:before{content:\\\"\\\\f20b\\\"}i.icon.in-cart:before{content:\\\"\\\\f218\\\"}i.icon.inr:before{content:\\\"\\\\f156\\\"}i.icon.intergender:before{content:\\\"\\\\f224\\\"}i.icon.intersex:before{content:\\\"\\\\f224\\\"}i.icon.japan.credit.bureau.card:before{content:\\\"\\\\f24b\\\"}i.icon.japan.credit.bureau:before{content:\\\"\\\\f24b\\\"}i.icon.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.jpy:before{content:\\\"\\\\f157\\\"}i.icon.krw:before{content:\\\"\\\\f159\\\"}i.icon.lab:before{content:\\\"\\\\f0c3\\\"}i.icon.law:before{content:\\\"\\\\f24e\\\"}i.icon.legal:before{content:\\\"\\\\f0e3\\\"}i.icon.lesbian:before{content:\\\"\\\\f226\\\"}i.icon.lightning:before{content:\\\"\\\\f0e7\\\"}i.icon.like:before{content:\\\"\\\\f004\\\"}i.icon.line.graph:before{content:\\\"\\\\f201\\\"}i.icon.linkedin.square:before{content:\\\"\\\\f08c\\\"}i.icon.linkify:before{content:\\\"\\\\f0c1\\\"}i.icon.lira:before{content:\\\"\\\\f195\\\"}i.icon.list.layout:before{content:\\\"\\\\f00b\\\"}i.icon.magnify:before{content:\\\"\\\\f00e\\\"}i.icon.mail.forward:before{content:\\\"\\\\f064\\\"}i.icon.mail.square:before{content:\\\"\\\\f199\\\"}i.icon.mail:before{content:\\\"\\\\f0e0\\\"}i.icon.male.homosexual:before{content:\\\"\\\\f227\\\"}i.icon.man:before{content:\\\"\\\\f222\\\"}i.icon.marker:before{content:\\\"\\\\f041\\\"}i.icon.mars.alternate:before{content:\\\"\\\\f229\\\"}i.icon.mars.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.mars.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.mastercard.card:before{content:\\\"\\\\f1f1\\\"}i.icon.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.microsoft.edge:before{content:\\\"\\\\f282\\\"}i.icon.military:before{content:\\\"\\\\f0fb\\\"}i.icon.ms.edge:before{content:\\\"\\\\f282\\\"}i.icon.mute:before{content:\\\"\\\\f131\\\"}i.icon.new.pied.piper:before{content:\\\"\\\\f2ae\\\"}i.icon.non.binary.transgender:before{content:\\\"\\\\f223\\\"}i.icon.numbered.list:before{content:\\\"\\\\f0cb\\\"}i.icon.optinmonster:before{content:\\\"\\\\f23c\\\"}i.icon.options:before{content:\\\"\\\\f1de\\\"}i.icon.other.gender.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.other.gender.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.other.gender:before{content:\\\"\\\\f229\\\"}i.icon.payment:before{content:\\\"\\\\f09d\\\"}i.icon.paypal.card:before{content:\\\"\\\\f1f4\\\"}i.icon.pencil.square:before{content:\\\"\\\\f14b\\\"}i.icon.photo:before{content:\\\"\\\\f030\\\"}i.icon.picture:before{content:\\\"\\\\f03e\\\"}i.icon.pie.chart:before{content:\\\"\\\\f200\\\"}i.icon.pie.graph:before{content:\\\"\\\\f200\\\"}i.icon.pied.piper.hat:before{content:\\\"\\\\f2ae\\\"}i.icon.pin:before{content:\\\"\\\\f08d\\\"}i.icon.plus.cart:before{content:\\\"\\\\f217\\\"}i.icon.pocket:before{content:\\\"\\\\f265\\\"}i.icon.point:before{content:\\\"\\\\f041\\\"}i.icon.pointing.down:before{content:\\\"\\\\f0a7\\\"}i.icon.pointing.left:before{content:\\\"\\\\f0a5\\\"}i.icon.pointing.right:before{content:\\\"\\\\f0a4\\\"}i.icon.pointing.up:before{content:\\\"\\\\f0a6\\\"}i.icon.pound:before{content:\\\"\\\\f154\\\"}i.icon.power.cord:before{content:\\\"\\\\f1e6\\\"}i.icon.power:before{content:\\\"\\\\f011\\\"}i.icon.privacy:before{content:\\\"\\\\f084\\\"}i.icon.r.circle:before{content:\\\"\\\\f25d\\\"}i.icon.rain:before{content:\\\"\\\\f0e9\\\"}i.icon.record:before{content:\\\"\\\\f03d\\\"}i.icon.refresh:before{content:\\\"\\\\f021\\\"}i.icon.remove.circle:before{content:\\\"\\\\f057\\\"}i.icon.remove.from.calendar:before{content:\\\"\\\\f272\\\"}i.icon.remove.user:before{content:\\\"\\\\f235\\\"}i.icon.remove:before{content:\\\"\\\\f00d\\\"}i.icon.repeat:before{content:\\\"\\\\f01e\\\"}i.icon.rmb:before{content:\\\"\\\\f157\\\"}i.icon.rouble:before{content:\\\"\\\\f158\\\"}i.icon.rub:before{content:\\\"\\\\f158\\\"}i.icon.ruble:before{content:\\\"\\\\f158\\\"}i.icon.rupee:before{content:\\\"\\\\f156\\\"}i.icon.s15:before{content:\\\"\\\\f2cd\\\"}i.icon.selected.radio:before{content:\\\"\\\\f192\\\"}i.icon.send:before{content:\\\"\\\\f1d8\\\"}i.icon.setting:before{content:\\\"\\\\f013\\\"}i.icon.settings:before{content:\\\"\\\\f085\\\"}i.icon.shekel:before{content:\\\"\\\\f20b\\\"}i.icon.sheqel:before{content:\\\"\\\\f20b\\\"}i.icon.shipping:before{content:\\\"\\\\f0d1\\\"}i.icon.shop:before{content:\\\"\\\\f07a\\\"}i.icon.shuffle:before{content:\\\"\\\\f074\\\"}i.icon.shutdown:before{content:\\\"\\\\f011\\\"}i.icon.sidebar:before{content:\\\"\\\\f0c9\\\"}i.icon.signing:before{content:\\\"\\\\f2a7\\\"}i.icon.signup:before{content:\\\"\\\\f044\\\"}i.icon.sliders:before{content:\\\"\\\\f1de\\\"}i.icon.soccer:before{content:\\\"\\\\f1e3\\\"}i.icon.sort.alphabet.ascending:before{content:\\\"\\\\f15d\\\"}i.icon.sort.alphabet.descending:before{content:\\\"\\\\f15e\\\"}i.icon.sort.ascending:before{content:\\\"\\\\f0de\\\"}i.icon.sort.content.ascending:before{content:\\\"\\\\f160\\\"}i.icon.sort.content.descending:before{content:\\\"\\\\f161\\\"}i.icon.sort.descending:before{content:\\\"\\\\f0dd\\\"}i.icon.sort.numeric.ascending:before{content:\\\"\\\\f162\\\"}i.icon.sort.numeric.descending:before{content:\\\"\\\\f163\\\"}i.icon.sound:before{content:\\\"\\\\f025\\\"}i.icon.spy:before{content:\\\"\\\\f21b\\\"}i.icon.stripe.card:before{content:\\\"\\\\f1f5\\\"}i.icon.student:before{content:\\\"\\\\f19d\\\"}i.icon.talk:before{content:\\\"\\\\f27a\\\"}i.icon.target:before{content:\\\"\\\\f140\\\"}i.icon.teletype:before{content:\\\"\\\\f1e4\\\"}i.icon.television:before{content:\\\"\\\\f26c\\\"}i.icon.text.cursor:before{content:\\\"\\\\f246\\\"}i.icon.text.telephone:before{content:\\\"\\\\f1e4\\\"}i.icon.theme.isle:before{content:\\\"\\\\f2b2\\\"}i.icon.theme:before{content:\\\"\\\\f043\\\"}i.icon.thermometer:before{content:\\\"\\\\f2c7\\\"}i.icon.thumb.tack:before{content:\\\"\\\\f08d\\\"}i.icon.time:before{content:\\\"\\\\f017\\\"}i.icon.tm:before{content:\\\"\\\\f25c\\\"}i.icon.toggle.down:before{content:\\\"\\\\f150\\\"}i.icon.toggle.left:before{content:\\\"\\\\f191\\\"}i.icon.toggle.right:before{content:\\\"\\\\f152\\\"}i.icon.toggle.up:before{content:\\\"\\\\f151\\\"}i.icon.translate:before{content:\\\"\\\\f1ab\\\"}i.icon.travel:before{content:\\\"\\\\f0b1\\\"}i.icon.treatment:before{content:\\\"\\\\f0f1\\\"}i.icon.triangle.down:before{content:\\\"\\\\f0d7\\\"}i.icon.triangle.left:before{content:\\\"\\\\f0d9\\\"}i.icon.triangle.right:before{content:\\\"\\\\f0da\\\"}i.icon.triangle.up:before{content:\\\"\\\\f0d8\\\"}i.icon.try:before{content:\\\"\\\\f195\\\"}i.icon.unhide:before{content:\\\"\\\\f06e\\\"}i.icon.unlinkify:before{content:\\\"\\\\f127\\\"}i.icon.unmute:before{content:\\\"\\\\f130\\\"}i.icon.usd:before{content:\\\"\\\\f155\\\"}i.icon.user.cancel:before{content:\\\"\\\\f235\\\"}i.icon.user.close:before{content:\\\"\\\\f235\\\"}i.icon.user.delete:before{content:\\\"\\\\f235\\\"}i.icon.user.x:before{content:\\\"\\\\f235\\\"}i.icon.vcard:before{content:\\\"\\\\f2bb\\\"}i.icon.video.camera:before{content:\\\"\\\\f03d\\\"}i.icon.video.play:before{content:\\\"\\\\f144\\\"}i.icon.visa.card:before{content:\\\"\\\\f1f0\\\"}i.icon.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.volume.control.phone:before{content:\\\"\\\\f2a0\\\"}i.icon.wait:before{content:\\\"\\\\f017\\\"}i.icon.warning.circle:before{content:\\\"\\\\f06a\\\"}i.icon.warning.sign:before{content:\\\"\\\\f071\\\"}i.icon.warning:before{content:\\\"\\\\f12a\\\"}i.icon.wechat:before{content:\\\"\\\\f1d7\\\"}i.icon.wi-fi:before{content:\\\"\\\\f1eb\\\"}i.icon.wikipedia:before{content:\\\"\\\\f266\\\"}i.icon.winner:before{content:\\\"\\\\f091\\\"}i.icon.wizard:before{content:\\\"\\\\f0d0\\\"}i.icon.woman:before{content:\\\"\\\\f221\\\"}i.icon.won:before{content:\\\"\\\\f159\\\"}i.icon.wordpress.beginner:before{content:\\\"\\\\f297\\\"}i.icon.wordpress.forms:before{content:\\\"\\\\f298\\\"}i.icon.world:before{content:\\\"\\\\f0ac\\\"}i.icon.write.square:before{content:\\\"\\\\f14b\\\"}i.icon.x:before{content:\\\"\\\\f00d\\\"}i.icon.yc:before{content:\\\"\\\\f23b\\\"}i.icon.ycombinator:before{content:\\\"\\\\f23b\\\"}i.icon.yen:before{content:\\\"\\\\f157\\\"}i.icon.zip:before{content:\\\"\\\\f187\\\"}i.icon.zoom-in:before{content:\\\"\\\\f00e\\\"}i.icon.zoom-out:before{content:\\\"\\\\f010\\\"}i.icon.zoom:before{content:\\\"\\\\f00e\\\"}i.icon.bitbucket.square:before{content:\\\"\\\\f171\\\"}i.icon.checkmark.box:before{content:\\\"\\\\f14a\\\"}i.icon.circle.thin:before{content:\\\"\\\\f111\\\"}i.icon.cloud.download:before{content:\\\"\\\\f381\\\"}i.icon.cloud.upload:before{content:\\\"\\\\f382\\\"}i.icon.compose:before{content:\\\"\\\\f303\\\"}i.icon.conversation:before{content:\\\"\\\\f086\\\"}i.icon.credit.card.alternative:before{content:\\\"\\\\f09d\\\"}i.icon.currency:before{content:\\\"\\\\f3d1\\\"}i.icon.dashboard:before{content:\\\"\\\\f3fd\\\"}i.icon.diamond:before{content:\\\"\\\\f3a5\\\"}i.icon.disk:before{content:\\\"\\\\f0a0\\\"}i.icon.exchange:before{content:\\\"\\\\f362\\\"}i.icon.external.share:before{content:\\\"\\\\f14d\\\"}i.icon.external.square:before{content:\\\"\\\\f360\\\"}i.icon.external:before{content:\\\"\\\\f35d\\\"}i.icon.facebook.official:before{content:\\\"\\\\f082\\\"}i.icon.food:before{content:\\\"\\\\f2e7\\\"}i.icon.hourglass.zero:before{content:\\\"\\\\f253\\\"}i.icon.level.down:before{content:\\\"\\\\f3be\\\"}i.icon.level.up:before{content:\\\"\\\\f3bf\\\"}i.icon.logout:before{content:\\\"\\\\f2f5\\\"}i.icon.meanpath:before{content:\\\"\\\\f0c8\\\"}i.icon.money:before{content:\\\"\\\\f3d1\\\"}i.icon.move:before{content:\\\"\\\\f0b2\\\"}i.icon.pencil:before{content:\\\"\\\\f303\\\"}i.icon.protect:before{content:\\\"\\\\f023\\\"}i.icon.radio:before{content:\\\"\\\\f192\\\"}i.icon.remove.bookmark:before{content:\\\"\\\\f02e\\\"}i.icon.resize.horizontal:before{content:\\\"\\\\f337\\\"}i.icon.resize.vertical:before{content:\\\"\\\\f338\\\"}i.icon.sign-in:before{content:\\\"\\\\f2f6\\\"}i.icon.sign-out:before{content:\\\"\\\\f2f5\\\"}i.icon.spoon:before{content:\\\"\\\\f2e5\\\"}i.icon.star.half.empty:before{content:\\\"\\\\f089\\\"}i.icon.star.half.full:before{content:\\\"\\\\f089\\\"}i.icon.ticket:before{content:\\\"\\\\f3ff\\\"}i.icon.times.rectangle:before{content:\\\"\\\\f410\\\"}i.icon.write:before{content:\\\"\\\\f303\\\"}i.icon.youtube.play:before{content:\\\"\\\\f167\\\"}@font-face{font-family:outline-icons;src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_7___ + \");src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_8___ + \") format('embedded-opentype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_9___ + \") format('woff2'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_10___ + \") format('woff'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_11___ + \") format('truetype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_12___ + \") format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon.outline{font-family:outline-icons}i.icon.address.book.outline:before{content:\\\"\\\\f2b9\\\"}i.icon.address.card.outline:before{content:\\\"\\\\f2bb\\\"}i.icon.arrow.alternate.circle.down.outline:before{content:\\\"\\\\f358\\\"}i.icon.arrow.alternate.circle.left.outline:before{content:\\\"\\\\f359\\\"}i.icon.arrow.alternate.circle.right.outline:before{content:\\\"\\\\f35a\\\"}i.icon.arrow.alternate.circle.up.outline:before{content:\\\"\\\\f35b\\\"}i.icon.bell.outline:before{content:\\\"\\\\f0f3\\\"}i.icon.bell.slash.outline:before{content:\\\"\\\\f1f6\\\"}i.icon.bookmark.outline:before{content:\\\"\\\\f02e\\\"}i.icon.building.outline:before{content:\\\"\\\\f1ad\\\"}i.icon.calendar.outline:before{content:\\\"\\\\f133\\\"}i.icon.calendar.alternate.outline:before{content:\\\"\\\\f073\\\"}i.icon.calendar.check.outline:before{content:\\\"\\\\f274\\\"}i.icon.calendar.minus.outline:before{content:\\\"\\\\f272\\\"}i.icon.calendar.plus.outline:before{content:\\\"\\\\f271\\\"}i.icon.calendar.times.outline:before{content:\\\"\\\\f273\\\"}i.icon.caret.square.down.outline:before{content:\\\"\\\\f150\\\"}i.icon.caret.square.left.outline:before{content:\\\"\\\\f191\\\"}i.icon.caret.square.right.outline:before{content:\\\"\\\\f152\\\"}i.icon.caret.square.up.outline:before{content:\\\"\\\\f151\\\"}i.icon.chart.bar.outline:before{content:\\\"\\\\f080\\\"}i.icon.check.circle.outline:before{content:\\\"\\\\f058\\\"}i.icon.check.square.outline:before{content:\\\"\\\\f14a\\\"}i.icon.circle.outline:before{content:\\\"\\\\f111\\\"}i.icon.clipboard.outline:before{content:\\\"\\\\f328\\\"}i.icon.clock.outline:before{content:\\\"\\\\f017\\\"}i.icon.clone.outline:before{content:\\\"\\\\f24d\\\"}i.icon.closed.captioning.outline:before{content:\\\"\\\\f20a\\\"}i.icon.comment.outline:before{content:\\\"\\\\f075\\\"}i.icon.comment.alternate.outline:before{content:\\\"\\\\f27a\\\"}i.icon.comments.outline:before{content:\\\"\\\\f086\\\"}i.icon.compass.outline:before{content:\\\"\\\\f14e\\\"}i.icon.copy.outline:before{content:\\\"\\\\f0c5\\\"}i.icon.copyright.outline:before{content:\\\"\\\\f1f9\\\"}i.icon.credit.card.outline:before{content:\\\"\\\\f09d\\\"}i.icon.dot.circle.outline:before{content:\\\"\\\\f192\\\"}i.icon.edit.outline:before{content:\\\"\\\\f044\\\"}i.icon.envelope.outline:before{content:\\\"\\\\f0e0\\\"}i.icon.envelope.open.outline:before{content:\\\"\\\\f2b6\\\"}i.icon.eye.slash.outline:before{content:\\\"\\\\f070\\\"}i.icon.file.outline:before{content:\\\"\\\\f15b\\\"}i.icon.file.alternate.outline:before{content:\\\"\\\\f15c\\\"}i.icon.file.archive.outline:before{content:\\\"\\\\f1c6\\\"}i.icon.file.audio.outline:before{content:\\\"\\\\f1c7\\\"}i.icon.file.code.outline:before{content:\\\"\\\\f1c9\\\"}i.icon.file.excel.outline:before{content:\\\"\\\\f1c3\\\"}i.icon.file.image.outline:before{content:\\\"\\\\f1c5\\\"}i.icon.file.pdf.outline:before{content:\\\"\\\\f1c1\\\"}i.icon.file.powerpoint.outline:before{content:\\\"\\\\f1c4\\\"}i.icon.file.video.outline:before{content:\\\"\\\\f1c8\\\"}i.icon.file.word.outline:before{content:\\\"\\\\f1c2\\\"}i.icon.flag.outline:before{content:\\\"\\\\f024\\\"}i.icon.folder.outline:before{content:\\\"\\\\f07b\\\"}i.icon.folder.open.outline:before{content:\\\"\\\\f07c\\\"}i.icon.frown.outline:before{content:\\\"\\\\f119\\\"}i.icon.futbol.outline:before{content:\\\"\\\\f1e3\\\"}i.icon.gem.outline:before{content:\\\"\\\\f3a5\\\"}i.icon.hand.lizard.outline:before{content:\\\"\\\\f258\\\"}i.icon.hand.paper.outline:before{content:\\\"\\\\f256\\\"}i.icon.hand.peace.outline:before{content:\\\"\\\\f25b\\\"}i.icon.hand.point.down.outline:before{content:\\\"\\\\f0a7\\\"}i.icon.hand.point.left.outline:before{content:\\\"\\\\f0a5\\\"}i.icon.hand.point.right.outline:before{content:\\\"\\\\f0a4\\\"}i.icon.hand.point.up.outline:before{content:\\\"\\\\f0a6\\\"}i.icon.hand.pointer.outline:before{content:\\\"\\\\f25a\\\"}i.icon.hand.rock.outline:before{content:\\\"\\\\f255\\\"}i.icon.hand.scissors.outline:before{content:\\\"\\\\f257\\\"}i.icon.hand.spock.outline:before{content:\\\"\\\\f259\\\"}i.icon.handshake.outline:before{content:\\\"\\\\f2b5\\\"}i.icon.hdd.outline:before{content:\\\"\\\\f0a0\\\"}i.icon.heart.outline:before{content:\\\"\\\\f004\\\"}i.icon.hospital.outline:before{content:\\\"\\\\f0f8\\\"}i.icon.hourglass.outline:before{content:\\\"\\\\f254\\\"}i.icon.id.badge.outline:before{content:\\\"\\\\f2c1\\\"}i.icon.id.card.outline:before{content:\\\"\\\\f2c2\\\"}i.icon.image.outline:before{content:\\\"\\\\f03e\\\"}i.icon.images.outline:before{content:\\\"\\\\f302\\\"}i.icon.keyboard.outline:before{content:\\\"\\\\f11c\\\"}i.icon.lemon.outline:before{content:\\\"\\\\f094\\\"}i.icon.life.ring.outline:before{content:\\\"\\\\f1cd\\\"}i.icon.lightbulb.outline:before{content:\\\"\\\\f0eb\\\"}i.icon.list.alternate.outline:before{content:\\\"\\\\f022\\\"}i.icon.map.outline:before{content:\\\"\\\\f279\\\"}i.icon.meh.outline:before{content:\\\"\\\\f11a\\\"}i.icon.minus.square.outline:before{content:\\\"\\\\f146\\\"}i.icon.money.bill.alternate.outline:before{content:\\\"\\\\f3d1\\\"}i.icon.moon.outline:before{content:\\\"\\\\f186\\\"}i.icon.newspaper.outline:before{content:\\\"\\\\f1ea\\\"}i.icon.object.group.outline:before{content:\\\"\\\\f247\\\"}i.icon.object.ungroup.outline:before{content:\\\"\\\\f248\\\"}i.icon.paper.plane.outline:before{content:\\\"\\\\f1d8\\\"}i.icon.pause.circle.outline:before{content:\\\"\\\\f28b\\\"}i.icon.play.circle.outline:before{content:\\\"\\\\f144\\\"}i.icon.plus.square.outline:before{content:\\\"\\\\f0fe\\\"}i.icon.question.circle.outline:before{content:\\\"\\\\f059\\\"}i.icon.registered.outline:before{content:\\\"\\\\f25d\\\"}i.icon.save.outline:before{content:\\\"\\\\f0c7\\\"}i.icon.share.square.outline:before{content:\\\"\\\\f14d\\\"}i.icon.smile.outline:before{content:\\\"\\\\f118\\\"}i.icon.snowflake.outline:before{content:\\\"\\\\f2dc\\\"}i.icon.square.outline:before{content:\\\"\\\\f0c8\\\"}i.icon.star.outline:before{content:\\\"\\\\f005\\\"}i.icon.star.half.outline:before{content:\\\"\\\\f089\\\"}i.icon.sticky.note.outline:before{content:\\\"\\\\f249\\\"}i.icon.stop.circle.outline:before{content:\\\"\\\\f28d\\\"}i.icon.sun.outline:before{content:\\\"\\\\f185\\\"}i.icon.thumbs.down.outline:before{content:\\\"\\\\f165\\\"}i.icon.thumbs.up.outline:before{content:\\\"\\\\f164\\\"}i.icon.times.circle.outline:before{content:\\\"\\\\f057\\\"}i.icon.trash.alternate.outline:before{content:\\\"\\\\f2ed\\\"}i.icon.user.outline:before{content:\\\"\\\\f007\\\"}i.icon.user.circle.outline:before{content:\\\"\\\\f2bd\\\"}i.icon.window.close.outline:before{content:\\\"\\\\f410\\\"}i.icon.window.maximize.outline:before{content:\\\"\\\\f2d0\\\"}i.icon.window.minimize.outline:before{content:\\\"\\\\f2d1\\\"}i.icon.window.restore.outline:before{content:\\\"\\\\f2d2\\\"}i.icon.disk.outline:before{content:\\\"\\\\f0a0\\\"}i.icon.heart.empty,i.icon.star.empty{font-family:outline-icons}i.icon.heart.empty:before{content:\\\"\\\\f004\\\"}i.icon.star.empty:before{content:\\\"\\\\f089\\\"}@font-face{font-family:brand-icons;src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_13___ + \");src:url(\" + ___CSS_LOADER_URL_REPLACEMENT_14___ + \") format('embedded-opentype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_15___ + \") format('woff2'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_16___ + \") format('woff'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_17___ + \") format('truetype'),url(\" + ___CSS_LOADER_URL_REPLACEMENT_18___ + \") format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon.\\\\35 00px,i.icon.accessible.icon,i.icon.accusoft,i.icon.adn,i.icon.adversal,i.icon.affiliatetheme,i.icon.algolia,i.icon.amazon,i.icon.amazon.pay,i.icon.amilia,i.icon.android,i.icon.angellist,i.icon.angrycreative,i.icon.angular,i.icon.app.store,i.icon.app.store.ios,i.icon.apper,i.icon.apple,i.icon.apple.pay,i.icon.asymmetrik,i.icon.audible,i.icon.autoprefixer,i.icon.avianex,i.icon.aviato,i.icon.aws,i.icon.bandcamp,i.icon.behance,i.icon.behance.square,i.icon.bimobject,i.icon.bitbucket,i.icon.bitcoin,i.icon.bity,i.icon.black.tie,i.icon.blackberry,i.icon.blogger,i.icon.blogger.b,i.icon.bluetooth,i.icon.bluetooth.b,i.icon.btc,i.icon.buromobelexperte,i.icon.buysellads,i.icon.cc.amazon.pay,i.icon.cc.amex,i.icon.cc.apple.pay,i.icon.cc.diners.club,i.icon.cc.discover,i.icon.cc.jcb,i.icon.cc.mastercard,i.icon.cc.paypal,i.icon.cc.stripe,i.icon.cc.visa,i.icon.centercode,i.icon.chrome,i.icon.cloudscale,i.icon.cloudsmith,i.icon.cloudversify,i.icon.codepen,i.icon.codiepie,i.icon.connectdevelop,i.icon.contao,i.icon.cpanel,i.icon.creative.commons,i.icon.css3,i.icon.css3.alternate,i.icon.cuttlefish,i.icon.d.and.d,i.icon.dashcube,i.icon.delicious,i.icon.deploydog,i.icon.deskpro,i.icon.deviantart,i.icon.digg,i.icon.digital.ocean,i.icon.discord,i.icon.discourse,i.icon.dochub,i.icon.docker,i.icon.draft2digital,i.icon.dribbble,i.icon.dribbble.square,i.icon.dropbox,i.icon.drupal,i.icon.dyalog,i.icon.earlybirds,i.icon.edge,i.icon.elementor,i.icon.ember,i.icon.empire,i.icon.envira,i.icon.erlang,i.icon.ethereum,i.icon.etsy,i.icon.expeditedssl,i.icon.facebook,i.icon.facebook.f,i.icon.facebook.messenger,i.icon.facebook.square,i.icon.firefox,i.icon.first.order,i.icon.firstdraft,i.icon.flickr,i.icon.flipboard,i.icon.fly,i.icon.font.awesome,i.icon.font.awesome.alternate,i.icon.font.awesome.flag,i.icon.fonticons,i.icon.fonticons.fi,i.icon.fort.awesome,i.icon.fort.awesome.alternate,i.icon.forumbee,i.icon.foursquare,i.icon.free.code.camp,i.icon.freebsd,i.icon.get.pocket,i.icon.gg,i.icon.gg.circle,i.icon.git,i.icon.git.square,i.icon.github,i.icon.github.alternate,i.icon.github.square,i.icon.gitkraken,i.icon.gitlab,i.icon.gitter,i.icon.glide,i.icon.glide.g,i.icon.gofore,i.icon.goodreads,i.icon.goodreads.g,i.icon.google,i.icon.google.drive,i.icon.google.play,i.icon.google.plus,i.icon.google.plus.g,i.icon.google.plus.square,i.icon.google.wallet,i.icon.gratipay,i.icon.grav,i.icon.gripfire,i.icon.grunt,i.icon.gulp,i.icon.hacker.news,i.icon.hacker.news.square,i.icon.hips,i.icon.hire.a.helper,i.icon.hooli,i.icon.hotjar,i.icon.houzz,i.icon.html5,i.icon.hubspot,i.icon.imdb,i.icon.instagram,i.icon.internet.explorer,i.icon.ioxhost,i.icon.itunes,i.icon.itunes.note,i.icon.jenkins,i.icon.joget,i.icon.joomla,i.icon.js,i.icon.js.square,i.icon.jsfiddle,i.icon.keycdn,i.icon.kickstarter,i.icon.kickstarter.k,i.icon.korvue,i.icon.laravel,i.icon.lastfm,i.icon.lastfm.square,i.icon.leanpub,i.icon.less,i.icon.linechat,i.icon.linkedin,i.icon.linkedin.alternate,i.icon.linkedin.in,i.icon.linode,i.icon.linux,i.icon.lyft,i.icon.magento,i.icon.maxcdn,i.icon.medapps,i.icon.medium,i.icon.medium.m,i.icon.medrt,i.icon.meetup,i.icon.microsoft,i.icon.mix,i.icon.mixcloud,i.icon.mizuni,i.icon.modx,i.icon.monero,i.icon.napster,i.icon.nintendo.switch,i.icon.node,i.icon.node.js,i.icon.npm,i.icon.ns8,i.icon.nutritionix,i.icon.odnoklassniki,i.icon.odnoklassniki.square,i.icon.opencart,i.icon.openid,i.icon.opera,i.icon.optin.monster,i.icon.osi,i.icon.page4,i.icon.pagelines,i.icon.palfed,i.icon.patreon,i.icon.paypal,i.icon.periscope,i.icon.phabricator,i.icon.phoenix.framework,i.icon.php,i.icon.pied.piper,i.icon.pied.piper.alternate,i.icon.pied.piper.pp,i.icon.pinterest,i.icon.pinterest.p,i.icon.pinterest.square,i.icon.playstation,i.icon.product.hunt,i.icon.pushed,i.icon.python,i.icon.qq,i.icon.quinscape,i.icon.quora,i.icon.ravelry,i.icon.react,i.icon.rebel,i.icon.reddit,i.icon.reddit.alien,i.icon.reddit.square,i.icon.redriver,i.icon.rendact,i.icon.renren,i.icon.replyd,i.icon.resolving,i.icon.rocketchat,i.icon.rockrms,i.icon.safari,i.icon.sass,i.icon.schlix,i.icon.scribd,i.icon.searchengin,i.icon.sellcast,i.icon.sellsy,i.icon.servicestack,i.icon.shirtsinbulk,i.icon.simplybuilt,i.icon.sistrix,i.icon.skyatlas,i.icon.skype,i.icon.slack,i.icon.slack.hash,i.icon.slideshare,i.icon.snapchat,i.icon.snapchat.ghost,i.icon.snapchat.square,i.icon.soundcloud,i.icon.speakap,i.icon.spotify,i.icon.stack.exchange,i.icon.stack.overflow,i.icon.staylinked,i.icon.steam,i.icon.steam.square,i.icon.steam.symbol,i.icon.sticker.mule,i.icon.strava,i.icon.stripe,i.icon.stripe.s,i.icon.studiovinari,i.icon.stumbleupon,i.icon.stumbleupon.circle,i.icon.superpowers,i.icon.supple,i.icon.telegram,i.icon.telegram.plane,i.icon.tencent.weibo,i.icon.themeisle,i.icon.trello,i.icon.tripadvisor,i.icon.tumblr,i.icon.tumblr.square,i.icon.twitch,i.icon.twitter,i.icon.twitter.square,i.icon.typo3,i.icon.uber,i.icon.uikit,i.icon.uniregistry,i.icon.untappd,i.icon.usb,i.icon.ussunnah,i.icon.vaadin,i.icon.viacoin,i.icon.viadeo,i.icon.viadeo.square,i.icon.viber,i.icon.vimeo,i.icon.vimeo.square,i.icon.vimeo.v,i.icon.vine,i.icon.vk,i.icon.vnv,i.icon.vuejs,i.icon.wechat,i.icon.weibo,i.icon.weixin,i.icon.whatsapp,i.icon.whatsapp.square,i.icon.whmcs,i.icon.wikipedia.w,i.icon.windows,i.icon.wordpress,i.icon.wordpress.simple,i.icon.wpbeginner,i.icon.wpexplorer,i.icon.wpforms,i.icon.xbox,i.icon.xing,i.icon.xing.square,i.icon.y.combinator,i.icon.yahoo,i.icon.yandex,i.icon.yandex.international,i.icon.yelp,i.icon.yoast,i.icon.youtube,i.icon.youtube.square{font-family:brand-icons}/*!\\n * # Semantic UI 2.4.0 - Image\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.image{position:relative;display:inline-block;vertical-align:middle;max-width:100%;background-color:transparent}img.ui.image{display:block}.ui.image img,.ui.image svg{display:block;max-width:100%;height:auto}.ui.hidden.image,.ui.hidden.images{display:none}.ui.hidden.transition.image,.ui.hidden.transition.images{display:block;visibility:hidden}.ui.images>.hidden.transition{display:inline-block;visibility:hidden}.ui.disabled.image,.ui.disabled.images{cursor:default;opacity:.45}.ui.inline.image,.ui.inline.image img,.ui.inline.image svg{display:inline-block}.ui.top.aligned.image,.ui.top.aligned.image img,.ui.top.aligned.image svg,.ui.top.aligned.images .image{display:inline-block;vertical-align:top}.ui.middle.aligned.image,.ui.middle.aligned.image img,.ui.middle.aligned.image svg,.ui.middle.aligned.images .image{display:inline-block;vertical-align:middle}.ui.bottom.aligned.image,.ui.bottom.aligned.image img,.ui.bottom.aligned.image svg,.ui.bottom.aligned.images .image{display:inline-block;vertical-align:bottom}.ui.rounded.image,.ui.rounded.image>*,.ui.rounded.images .image,.ui.rounded.images .image>*{border-radius:.3125em}.ui.bordered.image img,.ui.bordered.image svg,.ui.bordered.images .image,.ui.bordered.images img,.ui.bordered.images svg,img.ui.bordered.image{border:1px solid rgba(0,0,0,.1)}.ui.circular.image,.ui.circular.images{overflow:hidden}.ui.circular.image,.ui.circular.image>*,.ui.circular.images .image,.ui.circular.images .image>*{border-radius:500rem}.ui.fluid.image,.ui.fluid.image img,.ui.fluid.image svg,.ui.fluid.images,.ui.fluid.images img,.ui.fluid.images svg{display:block;width:100%;height:auto}.ui.avatar.image,.ui.avatar.image img,.ui.avatar.image svg,.ui.avatar.images .image,.ui.avatar.images img,.ui.avatar.images svg{margin-right:.25em;display:inline-block;width:2em;height:2em;border-radius:500rem}.ui.spaced.image{display:inline-block!important;margin-left:.5em;margin-right:.5em}.ui[class*=\\\"left spaced\\\"].image{margin-left:.5em;margin-right:0}.ui[class*=\\\"right spaced\\\"].image{margin-left:0;margin-right:.5em}.ui.floated.image,.ui.floated.images{float:left;margin-right:1em;margin-bottom:1em}.ui.right.floated.image,.ui.right.floated.images{float:right;margin-right:0;margin-bottom:1em;margin-left:1em}.ui.floated.image:last-child,.ui.floated.images:last-child{margin-bottom:0}.ui.centered.image,.ui.centered.images{margin-left:auto;margin-right:auto}.ui.mini.image,.ui.mini.images .image,.ui.mini.images img,.ui.mini.images svg{width:35px;height:auto;font-size:.78571429rem}.ui.tiny.image,.ui.tiny.images .image,.ui.tiny.images img,.ui.tiny.images svg{width:80px;height:auto;font-size:.85714286rem}.ui.small.image,.ui.small.images .image,.ui.small.images img,.ui.small.images svg{width:150px;height:auto;font-size:.92857143rem}.ui.medium.image,.ui.medium.images .image,.ui.medium.images img,.ui.medium.images svg{width:300px;height:auto;font-size:1rem}.ui.large.image,.ui.large.images .image,.ui.large.images img,.ui.large.images svg{width:450px;height:auto;font-size:1.14285714rem}.ui.big.image,.ui.big.images .image,.ui.big.images img,.ui.big.images svg{width:600px;height:auto;font-size:1.28571429rem}.ui.huge.image,.ui.huge.images .image,.ui.huge.images img,.ui.huge.images svg{width:800px;height:auto;font-size:1.42857143rem}.ui.massive.image,.ui.massive.images .image,.ui.massive.images img,.ui.massive.images svg{width:960px;height:auto;font-size:1.71428571rem}.ui.images{font-size:0;margin:0 -.25rem 0}.ui.images .image,.ui.images>img,.ui.images>svg{display:inline-block;margin:0 .25rem .5rem}/*!\\n * # Semantic UI 2.4.0 - Input\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.input{position:relative;font-weight:400;font-style:normal;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;color:rgba(0,0,0,.87)}.ui.input>input{margin:0;max-width:100%;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);text-align:left;line-height:1.21428571em;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;padding:.67857143em 1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-transition:border-color .1s ease,-webkit-box-shadow .1s ease;transition:border-color .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,border-color .1s ease;transition:box-shadow .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;-webkit-box-shadow:none;box-shadow:none}.ui.input>input::-webkit-input-placeholder{color:rgba(191,191,191,.87)}.ui.input>input::-moz-placeholder{color:rgba(191,191,191,.87)}.ui.input>input:-ms-input-placeholder{color:rgba(191,191,191,.87)}.ui.disabled.input,.ui.input:not(.disabled) input[disabled]{opacity:.45}.ui.disabled.input>input,.ui.input:not(.disabled) input[disabled]{pointer-events:none}.ui.input.down input,.ui.input>input:active{border-color:rgba(0,0,0,.3);background:#fafafa;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}.ui.loading.loading.input>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.loading.input>i.icon:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.input.focus>input,.ui.input>input:focus{border-color:#85b7d9;background:#fff;color:rgba(0,0,0,.8);-webkit-box-shadow:none;box-shadow:none}.ui.input.focus>input::-webkit-input-placeholder,.ui.input>input:focus::-webkit-input-placeholder{color:rgba(115,115,115,.87)}.ui.input.focus>input::-moz-placeholder,.ui.input>input:focus::-moz-placeholder{color:rgba(115,115,115,.87)}.ui.input.focus>input:-ms-input-placeholder,.ui.input>input:focus:-ms-input-placeholder{color:rgba(115,115,115,.87)}.ui.input.error>input{background-color:#fff6f6;border-color:#e0b4b4;color:#9f3a38;-webkit-box-shadow:none;box-shadow:none}.ui.input.error>input::-webkit-input-placeholder{color:#e7bdbc}.ui.input.error>input::-moz-placeholder{color:#e7bdbc}.ui.input.error>input:-ms-input-placeholder{color:#e7bdbc!important}.ui.input.error>input:focus::-webkit-input-placeholder{color:#da9796}.ui.input.error>input:focus::-moz-placeholder{color:#da9796}.ui.input.error>input:focus:-ms-input-placeholder{color:#da9796!important}.ui.transparent.input>input{border-color:transparent!important;background-color:transparent!important;padding:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;border-radius:0!important}.ui.transparent.icon.input>i.icon{width:1.1em}.ui.transparent.icon.input>input{padding-left:0!important;padding-right:2em!important}.ui.transparent[class*=\\\"left icon\\\"].input>input{padding-left:2em!important;padding-right:0!important}.ui.transparent.inverted.input{color:#fff}.ui.transparent.inverted.input>input{color:inherit}.ui.transparent.inverted.input>input::-webkit-input-placeholder{color:rgba(255,255,255,.5)}.ui.transparent.inverted.input>input::-moz-placeholder{color:rgba(255,255,255,.5)}.ui.transparent.inverted.input>input:-ms-input-placeholder{color:rgba(255,255,255,.5)}.ui.icon.input>i.icon{cursor:default;position:absolute;line-height:1;text-align:center;top:0;right:0;margin:0;height:100%;width:2.67142857em;opacity:.5;border-radius:0 .28571429rem .28571429rem 0;-webkit-transition:opacity .3s ease;transition:opacity .3s ease}.ui.icon.input>i.icon:not(.link){pointer-events:none}.ui.icon.input>input{padding-right:2.67142857em!important}.ui.icon.input>i.icon:after,.ui.icon.input>i.icon:before{left:0;position:absolute;text-align:center;top:50%;width:100%;margin-top:-.5em}.ui.icon.input>i.link.icon{cursor:pointer}.ui.icon.input>i.circular.icon{top:.35em;right:.5em}.ui[class*=\\\"left icon\\\"].input>i.icon{right:auto;left:1px;border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"left icon\\\"].input>i.circular.icon{right:auto;left:.5em}.ui[class*=\\\"left icon\\\"].input>input{padding-left:2.67142857em!important;padding-right:1em!important}.ui.icon.input>input:focus~i.icon{opacity:1}.ui.labeled.input>.label{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;margin:0;font-size:1em}.ui.labeled.input>.label:not(.corner){padding-top:.78571429em;padding-bottom:.78571429em}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child+input{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:transparent}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child+input:focus{border-left-color:#85b7d9}.ui[class*=\\\"right labeled\\\"].input>input{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right-color:transparent!important}.ui[class*=\\\"right labeled\\\"].input>input+.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"right labeled\\\"].input>input:focus{border-right-color:#85b7d9!important}.ui.labeled.input .corner.label{top:1px;right:1px;font-size:.64285714em;border-radius:0 .28571429rem 0 0}.ui[class*=\\\"corner labeled\\\"]:not([class*=\\\"left corner labeled\\\"]).labeled.input>input{padding-right:2.5em!important}.ui[class*=\\\"corner labeled\\\"].icon.input:not([class*=\\\"left corner labeled\\\"])>input{padding-right:3.25em!important}.ui[class*=\\\"corner labeled\\\"].icon.input:not([class*=\\\"left corner labeled\\\"])>.icon{margin-right:1.25em}.ui[class*=\\\"left corner labeled\\\"].labeled.input>input{padding-left:2.5em!important}.ui[class*=\\\"left corner labeled\\\"].icon.input>input{padding-left:3.25em!important}.ui[class*=\\\"left corner labeled\\\"].icon.input>.icon{margin-left:1.25em}.ui.input>.ui.corner.label{top:1px;right:1px}.ui.input>.ui.left.corner.label{right:auto;left:1px}.ui.action.input>.button,.ui.action.input>.buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto}.ui.action.input>.button,.ui.action.input>.buttons>.button{padding-top:.78571429em;padding-bottom:.78571429em;margin:0}.ui.action.input:not([class*=\\\"left action\\\"])>input{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right-color:transparent!important}.ui.action.input:not([class*=\\\"left action\\\"])>.button:not(:first-child),.ui.action.input:not([class*=\\\"left action\\\"])>.buttons:not(:first-child)>.button,.ui.action.input:not([class*=\\\"left action\\\"])>.dropdown:not(:first-child){border-radius:0}.ui.action.input:not([class*=\\\"left action\\\"])>.button:last-child,.ui.action.input:not([class*=\\\"left action\\\"])>.buttons:last-child>.button,.ui.action.input:not([class*=\\\"left action\\\"])>.dropdown:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.action.input:not([class*=\\\"left action\\\"])>input:focus{border-right-color:#85b7d9!important}.ui[class*=\\\"left action\\\"].input>input{border-top-left-radius:0!important;border-bottom-left-radius:0!important;border-left-color:transparent!important}.ui[class*=\\\"left action\\\"].input>.button,.ui[class*=\\\"left action\\\"].input>.buttons>.button,.ui[class*=\\\"left action\\\"].input>.dropdown{border-radius:0}.ui[class*=\\\"left action\\\"].input>.button:first-child,.ui[class*=\\\"left action\\\"].input>.buttons:first-child>.button,.ui[class*=\\\"left action\\\"].input>.dropdown:first-child{border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"left action\\\"].input>input:focus{border-left-color:#85b7d9!important}.ui.inverted.input>input{border:none}.ui.fluid.input{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.fluid.input>input{width:0!important}.ui.mini.input{font-size:.78571429em}.ui.small.input{font-size:.92857143em}.ui.input{font-size:1em}.ui.large.input{font-size:1.14285714em}.ui.big.input{font-size:1.28571429em}.ui.huge.input{font-size:1.42857143em}.ui.massive.input{font-size:1.71428571em}/*!\\n * # Semantic UI 2.4.0 - Label\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.label{display:inline-block;line-height:1;vertical-align:baseline;margin:0 .14285714em;background-color:#e8e8e8;background-image:none;padding:.5833em .833em;color:rgba(0,0,0,.6);text-transform:none;font-weight:700;border:0 solid transparent;border-radius:.28571429rem;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.label:first-child{margin-left:0}.ui.label:last-child{margin-right:0}a.ui.label{cursor:pointer}.ui.label>a{cursor:pointer;color:inherit;opacity:.5;-webkit-transition:.1s opacity ease;transition:.1s opacity ease}.ui.label>a:hover{opacity:1}.ui.label>img{width:auto!important;vertical-align:middle;height:2.1666em!important}.ui.label>.icon{width:auto;margin:0 .75em 0 0}.ui.label>.detail{display:inline-block;vertical-align:top;font-weight:700;margin-left:1em;opacity:.8}.ui.label>.detail .icon{margin:0 .25em 0 0}.ui.label>.close.icon,.ui.label>.delete.icon{cursor:pointer;margin-right:0;margin-left:.5em;font-size:.92857143em;opacity:.5;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.label>.delete.icon:hover{opacity:1}.ui.labels>.label{margin:0 .5em .5em 0}.ui.header>.ui.label{margin-top:-.29165em}.ui.attached.segment>.ui.top.left.attached.label,.ui.bottom.attached.segment>.ui.top.left.attached.label{border-top-left-radius:0}.ui.attached.segment>.ui.top.right.attached.label,.ui.bottom.attached.segment>.ui.top.right.attached.label{border-top-right-radius:0}.ui.top.attached.segment>.ui.bottom.left.attached.label{border-bottom-left-radius:0}.ui.top.attached.segment>.ui.bottom.right.attached.label{border-bottom-right-radius:0}.ui.top.attached.label+[class*=\\\"right floated\\\"]+*,.ui.top.attached.label:first-child+:not(.attached){margin-top:2rem!important}.ui.bottom.attached.label:first-child~:last-child:not(.attached){margin-top:0;margin-bottom:2rem!important}.ui.image.label{width:auto!important;margin-top:0;margin-bottom:0;max-width:9999px;vertical-align:baseline;text-transform:none;background:#e8e8e8;padding:.5833em .833em .5833em .5em;border-radius:.28571429rem;-webkit-box-shadow:none;box-shadow:none}.ui.image.label img{display:inline-block;vertical-align:top;height:2.1666em;margin:-.5833em .5em -.5833em -.5em;border-radius:.28571429rem 0 0 .28571429rem}.ui.image.label .detail{background:rgba(0,0,0,.1);margin:-.5833em -.833em -.5833em .5em;padding:.5833em .833em;border-radius:0 .28571429rem .28571429rem 0}.ui.tag.label,.ui.tag.labels .label{margin-left:1em;position:relative;padding-left:1.5em;padding-right:1.5em;border-radius:0 .28571429rem .28571429rem 0;-webkit-transition:none;transition:none}.ui.tag.label:before,.ui.tag.labels .label:before{position:absolute;-webkit-transform:translateY(-50%) translateX(50%) rotate(-45deg);transform:translateY(-50%) translateX(50%) rotate(-45deg);top:50%;right:100%;content:'';background-color:inherit;background-image:none;width:1.56em;height:1.56em;-webkit-transition:none;transition:none}.ui.tag.label:after,.ui.tag.labels .label:after{position:absolute;content:'';top:50%;left:-.25em;margin-top:-.25em;background-color:#fff!important;width:.5em;height:.5em;-webkit-box-shadow:0 -1px 1px 0 rgba(0,0,0,.3);box-shadow:0 -1px 1px 0 rgba(0,0,0,.3);border-radius:500rem}.ui.corner.label{position:absolute;top:0;right:0;margin:0;padding:0;text-align:center;border-color:#e8e8e8;width:4em;height:4em;z-index:1;-webkit-transition:border-color .1s ease;transition:border-color .1s ease}.ui.corner.label{background-color:transparent!important}.ui.corner.label:after{position:absolute;content:\\\"\\\";right:0;top:0;z-index:-1;width:0;height:0;background-color:transparent!important;border-top:0 solid transparent;border-right:4em solid transparent;border-bottom:4em solid transparent;border-left:0 solid transparent;border-right-color:inherit;-webkit-transition:border-color .1s ease;transition:border-color .1s ease}.ui.corner.label .icon{cursor:default;position:relative;top:.64285714em;left:.78571429em;font-size:1.14285714em;margin:0}.ui.left.corner.label,.ui.left.corner.label:after{right:auto;left:0}.ui.left.corner.label:after{border-top:4em solid transparent;border-right:4em solid transparent;border-bottom:0 solid transparent;border-left:0 solid transparent;border-top-color:inherit}.ui.left.corner.label .icon{left:-.78571429em}.ui.segment>.ui.corner.label{top:-1px;right:-1px}.ui.segment>.ui.left.corner.label{right:auto;left:-1px}.ui.ribbon.label{position:relative;margin:0;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;border-radius:0 .28571429rem .28571429rem 0;border-color:rgba(0,0,0,.15)}.ui.ribbon.label:after{position:absolute;content:'';top:100%;left:0;background-color:transparent!important;border-style:solid;border-width:0 1.2em 1.2em 0;border-color:transparent;border-right-color:inherit;width:0;height:0}.ui.ribbon.label{left:calc(-1rem - 1.2em);margin-right:-1.2em;padding-left:calc(1rem + 1.2em);padding-right:1.2em}.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + 1rem + 1.2em);padding-left:1.2em;padding-right:calc(1rem + 1.2em)}.ui[class*=\\\"right ribbon\\\"].label{text-align:left;-webkit-transform:translateX(-100%);transform:translateX(-100%);border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"right ribbon\\\"].label:after{left:auto;right:0;border-style:solid;border-width:1.2em 1.2em 0 0;border-color:transparent;border-top-color:inherit}.ui.card .image>.ribbon.label,.ui.image>.ribbon.label{position:absolute;top:1rem}.ui.card .image>.ui.ribbon.label,.ui.image>.ui.ribbon.label{left:calc(.05rem - 1.2em)}.ui.card .image>.ui[class*=\\\"right ribbon\\\"].label,.ui.image>.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + -.05rem + 1.2em);padding-left:.833em}.ui.table td>.ui.ribbon.label{left:calc(-.78571429em - 1.2em)}.ui.table td>.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + .78571429em + 1.2em);padding-left:.833em}.ui.attached.label,.ui[class*=\\\"top attached\\\"].label{width:100%;position:absolute;margin:0;top:0;left:0;padding:.75em 1em;border-radius:.21428571rem .21428571rem 0 0}.ui[class*=\\\"bottom attached\\\"].label{top:auto;bottom:0;border-radius:0 0 .21428571rem .21428571rem}.ui[class*=\\\"top left attached\\\"].label{width:auto;margin-top:0!important;border-radius:.21428571rem 0 .28571429rem 0}.ui[class*=\\\"top right attached\\\"].label{width:auto;left:auto;right:0;border-radius:0 .21428571rem 0 .28571429rem}.ui[class*=\\\"bottom left attached\\\"].label{width:auto;top:auto;bottom:0;border-radius:0 .28571429rem 0 .21428571rem}.ui[class*=\\\"bottom right attached\\\"].label{top:auto;bottom:0;left:auto;right:0;width:auto;border-radius:.28571429rem 0 .21428571rem 0}.ui.label.disabled{opacity:.5}a.ui.label:hover,a.ui.labels .label:hover{background-color:#e0e0e0;border-color:#e0e0e0;background-image:none;color:rgba(0,0,0,.8)}.ui.labels a.label:hover:before,a.ui.label:hover:before{color:rgba(0,0,0,.8)}.ui.active.label{background-color:#d0d0d0;border-color:#d0d0d0;background-image:none;color:rgba(0,0,0,.95)}.ui.active.label:before{background-color:#d0d0d0;background-image:none;color:rgba(0,0,0,.95)}a.ui.active.label:hover,a.ui.labels .active.label:hover{background-color:#c8c8c8;border-color:#c8c8c8;background-image:none;color:rgba(0,0,0,.95)}.ui.labels a.active.label:ActiveHover:before,a.ui.active.label:ActiveHover:before{background-color:#c8c8c8;background-image:none;color:rgba(0,0,0,.95)}.ui.label.visible:not(.dropdown),.ui.labels.visible .label{display:inline-block!important}.ui.label.hidden,.ui.labels.hidden .label{display:none!important}.ui.red.label,.ui.red.labels .label{background-color:#db2828!important;border-color:#db2828!important;color:#fff!important}.ui.red.labels .label:hover,a.ui.red.label:hover{background-color:#d01919!important;border-color:#d01919!important;color:#fff!important}.ui.red.corner.label,.ui.red.corner.label:hover{background-color:transparent!important}.ui.red.ribbon.label{border-color:#b21e1e!important}.ui.basic.red.label{background:none #fff!important;color:#db2828!important;border-color:#db2828!important}.ui.basic.red.labels a.label:hover,a.ui.basic.red.label:hover{background-color:#fff!important;color:#d01919!important;border-color:#d01919!important}.ui.orange.label,.ui.orange.labels .label{background-color:#f2711c!important;border-color:#f2711c!important;color:#fff!important}.ui.orange.labels .label:hover,a.ui.orange.label:hover{background-color:#f26202!important;border-color:#f26202!important;color:#fff!important}.ui.orange.corner.label,.ui.orange.corner.label:hover{background-color:transparent!important}.ui.orange.ribbon.label{border-color:#cf590c!important}.ui.basic.orange.label{background:none #fff!important;color:#f2711c!important;border-color:#f2711c!important}.ui.basic.orange.labels a.label:hover,a.ui.basic.orange.label:hover{background-color:#fff!important;color:#f26202!important;border-color:#f26202!important}.ui.yellow.label,.ui.yellow.labels .label{background-color:#fbbd08!important;border-color:#fbbd08!important;color:#fff!important}.ui.yellow.labels .label:hover,a.ui.yellow.label:hover{background-color:#eaae00!important;border-color:#eaae00!important;color:#fff!important}.ui.yellow.corner.label,.ui.yellow.corner.label:hover{background-color:transparent!important}.ui.yellow.ribbon.label{border-color:#cd9903!important}.ui.basic.yellow.label{background:none #fff!important;color:#fbbd08!important;border-color:#fbbd08!important}.ui.basic.yellow.labels a.label:hover,a.ui.basic.yellow.label:hover{background-color:#fff!important;color:#eaae00!important;border-color:#eaae00!important}.ui.olive.label,.ui.olive.labels .label{background-color:#b5cc18!important;border-color:#b5cc18!important;color:#fff!important}.ui.olive.labels .label:hover,a.ui.olive.label:hover{background-color:#a7bd0d!important;border-color:#a7bd0d!important;color:#fff!important}.ui.olive.corner.label,.ui.olive.corner.label:hover{background-color:transparent!important}.ui.olive.ribbon.label{border-color:#198f35!important}.ui.basic.olive.label{background:none #fff!important;color:#b5cc18!important;border-color:#b5cc18!important}.ui.basic.olive.labels a.label:hover,a.ui.basic.olive.label:hover{background-color:#fff!important;color:#a7bd0d!important;border-color:#a7bd0d!important}.ui.green.label,.ui.green.labels .label{background-color:#21ba45!important;border-color:#21ba45!important;color:#fff!important}.ui.green.labels .label:hover,a.ui.green.label:hover{background-color:#16ab39!important;border-color:#16ab39!important;color:#fff!important}.ui.green.corner.label,.ui.green.corner.label:hover{background-color:transparent!important}.ui.green.ribbon.label{border-color:#198f35!important}.ui.basic.green.label{background:none #fff!important;color:#21ba45!important;border-color:#21ba45!important}.ui.basic.green.labels a.label:hover,a.ui.basic.green.label:hover{background-color:#fff!important;color:#16ab39!important;border-color:#16ab39!important}.ui.teal.label,.ui.teal.labels .label{background-color:#00b5ad!important;border-color:#00b5ad!important;color:#fff!important}.ui.teal.labels .label:hover,a.ui.teal.label:hover{background-color:#009c95!important;border-color:#009c95!important;color:#fff!important}.ui.teal.corner.label,.ui.teal.corner.label:hover{background-color:transparent!important}.ui.teal.ribbon.label{border-color:#00827c!important}.ui.basic.teal.label{background:none #fff!important;color:#00b5ad!important;border-color:#00b5ad!important}.ui.basic.teal.labels a.label:hover,a.ui.basic.teal.label:hover{background-color:#fff!important;color:#009c95!important;border-color:#009c95!important}.ui.blue.label,.ui.blue.labels .label{background-color:#2185d0!important;border-color:#2185d0!important;color:#fff!important}.ui.blue.labels .label:hover,a.ui.blue.label:hover{background-color:#1678c2!important;border-color:#1678c2!important;color:#fff!important}.ui.blue.corner.label,.ui.blue.corner.label:hover{background-color:transparent!important}.ui.blue.ribbon.label{border-color:#1a69a4!important}.ui.basic.blue.label{background:none #fff!important;color:#2185d0!important;border-color:#2185d0!important}.ui.basic.blue.labels a.label:hover,a.ui.basic.blue.label:hover{background-color:#fff!important;color:#1678c2!important;border-color:#1678c2!important}.ui.violet.label,.ui.violet.labels .label{background-color:#6435c9!important;border-color:#6435c9!important;color:#fff!important}.ui.violet.labels .label:hover,a.ui.violet.label:hover{background-color:#5829bb!important;border-color:#5829bb!important;color:#fff!important}.ui.violet.corner.label,.ui.violet.corner.label:hover{background-color:transparent!important}.ui.violet.ribbon.label{border-color:#502aa1!important}.ui.basic.violet.label{background:none #fff!important;color:#6435c9!important;border-color:#6435c9!important}.ui.basic.violet.labels a.label:hover,a.ui.basic.violet.label:hover{background-color:#fff!important;color:#5829bb!important;border-color:#5829bb!important}.ui.purple.label,.ui.purple.labels .label{background-color:#a333c8!important;border-color:#a333c8!important;color:#fff!important}.ui.purple.labels .label:hover,a.ui.purple.label:hover{background-color:#9627ba!important;border-color:#9627ba!important;color:#fff!important}.ui.purple.corner.label,.ui.purple.corner.label:hover{background-color:transparent!important}.ui.purple.ribbon.label{border-color:#82299f!important}.ui.basic.purple.label{background:none #fff!important;color:#a333c8!important;border-color:#a333c8!important}.ui.basic.purple.labels a.label:hover,a.ui.basic.purple.label:hover{background-color:#fff!important;color:#9627ba!important;border-color:#9627ba!important}.ui.pink.label,.ui.pink.labels .label{background-color:#e03997!important;border-color:#e03997!important;color:#fff!important}.ui.pink.labels .label:hover,a.ui.pink.label:hover{background-color:#e61a8d!important;border-color:#e61a8d!important;color:#fff!important}.ui.pink.corner.label,.ui.pink.corner.label:hover{background-color:transparent!important}.ui.pink.ribbon.label{border-color:#c71f7e!important}.ui.basic.pink.label{background:none #fff!important;color:#e03997!important;border-color:#e03997!important}.ui.basic.pink.labels a.label:hover,a.ui.basic.pink.label:hover{background-color:#fff!important;color:#e61a8d!important;border-color:#e61a8d!important}.ui.brown.label,.ui.brown.labels .label{background-color:#a5673f!important;border-color:#a5673f!important;color:#fff!important}.ui.brown.labels .label:hover,a.ui.brown.label:hover{background-color:#975b33!important;border-color:#975b33!important;color:#fff!important}.ui.brown.corner.label,.ui.brown.corner.label:hover{background-color:transparent!important}.ui.brown.ribbon.label{border-color:#805031!important}.ui.basic.brown.label{background:none #fff!important;color:#a5673f!important;border-color:#a5673f!important}.ui.basic.brown.labels a.label:hover,a.ui.basic.brown.label:hover{background-color:#fff!important;color:#975b33!important;border-color:#975b33!important}.ui.grey.label,.ui.grey.labels .label{background-color:#767676!important;border-color:#767676!important;color:#fff!important}.ui.grey.labels .label:hover,a.ui.grey.label:hover{background-color:#838383!important;border-color:#838383!important;color:#fff!important}.ui.grey.corner.label,.ui.grey.corner.label:hover{background-color:transparent!important}.ui.grey.ribbon.label{border-color:#805031!important}.ui.basic.grey.label{background:none #fff!important;color:#767676!important;border-color:#767676!important}.ui.basic.grey.labels a.label:hover,a.ui.basic.grey.label:hover{background-color:#fff!important;color:#838383!important;border-color:#838383!important}.ui.black.label,.ui.black.labels .label{background-color:#1b1c1d!important;border-color:#1b1c1d!important;color:#fff!important}.ui.black.labels .label:hover,a.ui.black.label:hover{background-color:#27292a!important;border-color:#27292a!important;color:#fff!important}.ui.black.corner.label,.ui.black.corner.label:hover{background-color:transparent!important}.ui.black.ribbon.label{border-color:#805031!important}.ui.basic.black.label{background:none #fff!important;color:#1b1c1d!important;border-color:#1b1c1d!important}.ui.basic.black.labels a.label:hover,a.ui.basic.black.label:hover{background-color:#fff!important;color:#27292a!important;border-color:#27292a!important}.ui.basic.label{background:none #fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}a.ui.basic.label:hover{text-decoration:none;background:none #fff;color:#1e70bf;-webkit-box-shadow:1px solid rgba(34,36,38,.15);box-shadow:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.pointing.label:before{border-color:inherit}.ui.fluid.labels>.label,.ui.label.fluid{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.ui.inverted.label,.ui.inverted.labels .label{color:rgba(255,255,255,.9)!important}.ui.horizontal.label,.ui.horizontal.labels .label{margin:0 .5em 0 0;padding:.4em .833em;min-width:3em;text-align:center}.ui.circular.label,.ui.circular.labels .label{min-width:2em;min-height:2em;padding:.5em!important;line-height:1em;text-align:center;border-radius:500rem}.ui.empty.circular.label,.ui.empty.circular.labels .label{min-width:0;min-height:0;overflow:hidden;width:.5em;height:.5em;vertical-align:baseline}.ui.pointing.label{position:relative}.ui.attached.pointing.label{position:absolute}.ui.pointing.label:before{background-color:inherit;background-image:inherit;border-width:none;border-style:solid;border-color:inherit}.ui.pointing.label:before{position:absolute;content:'';-webkit-transform:rotate(45deg);transform:rotate(45deg);background-image:none;z-index:2;width:.6666em;height:.6666em;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.pointing.label,.ui[class*=\\\"pointing above\\\"].label{margin-top:1em}.ui.pointing.label:before,.ui[class*=\\\"pointing above\\\"].label:before{border-width:1px 0 0 1px;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);top:0;left:50%}.ui[class*=\\\"bottom pointing\\\"].label,.ui[class*=\\\"pointing below\\\"].label{margin-top:0;margin-bottom:1em}.ui[class*=\\\"bottom pointing\\\"].label:before,.ui[class*=\\\"pointing below\\\"].label:before{border-width:0 1px 1px 0;top:auto;right:auto;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);top:100%;left:50%}.ui[class*=\\\"left pointing\\\"].label{margin-top:0;margin-left:.6666em}.ui[class*=\\\"left pointing\\\"].label:before{border-width:0 0 1px 1px;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);bottom:auto;right:auto;top:50%;left:0}.ui[class*=\\\"right pointing\\\"].label{margin-top:0;margin-right:.6666em}.ui[class*=\\\"right pointing\\\"].label:before{border-width:1px 1px 0 0;-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg);top:50%;right:0;bottom:auto;left:auto}.ui.basic.pointing.label:before,.ui.basic[class*=\\\"pointing above\\\"].label:before{margin-top:-1px}.ui.basic[class*=\\\"bottom pointing\\\"].label:before,.ui.basic[class*=\\\"pointing below\\\"].label:before{bottom:auto;top:100%;margin-top:1px}.ui.basic[class*=\\\"left pointing\\\"].label:before{top:50%;left:-1px}.ui.basic[class*=\\\"right pointing\\\"].label:before{top:50%;right:-1px}.ui.floating.label{position:absolute;z-index:100;top:-1em;left:100%;margin:0 0 0 -1.5em!important}.ui.mini.label,.ui.mini.labels .label{font-size:.64285714rem}.ui.tiny.label,.ui.tiny.labels .label{font-size:.71428571rem}.ui.small.label,.ui.small.labels .label{font-size:.78571429rem}.ui.label,.ui.labels .label{font-size:.85714286rem}.ui.large.label,.ui.large.labels .label{font-size:1rem}.ui.big.label,.ui.big.labels .label{font-size:1.28571429rem}.ui.huge.label,.ui.huge.labels .label{font-size:1.42857143rem}.ui.massive.label,.ui.massive.labels .label{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - List\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.list,ol.ui.list,ul.ui.list{list-style-type:none;margin:1em 0;padding:0 0}.ui.list:first-child,ol.ui.list:first-child,ul.ui.list:first-child{margin-top:0;padding-top:0}.ui.list:last-child,ol.ui.list:last-child,ul.ui.list:last-child{margin-bottom:0;padding-bottom:0}.ui.list .list>.item,.ui.list>.item,ol.ui.list li,ul.ui.list li{display:list-item;table-layout:fixed;list-style-type:none;list-style-position:outside;padding:.21428571em 0;line-height:1.14285714em}.ui.list>.item:after,.ui.list>.list>.item,ol.ui.list>li:first-child:after,ul.ui.list>li:first-child:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.list .list>.item:first-child,.ui.list>.item:first-child,ol.ui.list li:first-child,ul.ui.list li:first-child{padding-top:0}.ui.list .list>.item:last-child,.ui.list>.item:last-child,ol.ui.list li:last-child,ul.ui.list li:last-child{padding-bottom:0}.ui.list .list,ol.ui.list ol,ul.ui.list ul{clear:both;margin:0;padding:.75em 0 .25em .5em}.ui.list .list>.item,ol.ui.list ol li,ul.ui.list ul li{padding:.14285714em 0;line-height:inherit}.ui.list .list>.item>i.icon,.ui.list>.item>i.icon{display:table-cell;margin:0;padding-top:0;padding-right:.28571429em;vertical-align:top;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.list .list>.item>i.icon:only-child,.ui.list>.item>i.icon:only-child{display:inline-block;vertical-align:top}.ui.list .list>.item>.image,.ui.list>.item>.image{display:table-cell;background-color:transparent;margin:0;vertical-align:top}.ui.list .list>.item>.image:not(:only-child):not(img),.ui.list>.item>.image:not(:only-child):not(img){padding-right:.5em}.ui.list .list>.item>.image img,.ui.list>.item>.image img{vertical-align:top}.ui.list .list>.item>.image:only-child,.ui.list .list>.item>img.image,.ui.list>.item>.image:only-child,.ui.list>.item>img.image{display:inline-block}.ui.list .list>.item>.content,.ui.list>.item>.content{line-height:1.14285714em}.ui.list .list>.item>.icon+.content,.ui.list .list>.item>.image+.content,.ui.list>.item>.icon+.content,.ui.list>.item>.image+.content{display:table-cell;width:100%;padding:0 0 0 .5em;vertical-align:top}.ui.list .list>.item>img.image+.content,.ui.list>.item>img.image+.content{display:inline-block;width:auto}.ui.list .list>.item>.content>.list,.ui.list>.item>.content>.list{margin-left:0;padding-left:0}.ui.list .list>.item .header,.ui.list>.item .header{display:block;margin:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;color:rgba(0,0,0,.87)}.ui.list .list>.item .description,.ui.list>.item .description{display:block;color:rgba(0,0,0,.7)}.ui.list .list>.item a,.ui.list>.item a{cursor:pointer}.ui.list .list>a.item,.ui.list>a.item{cursor:pointer;color:#4183c4}.ui.list .list>a.item:hover,.ui.list>a.item:hover{color:#1e70bf}.ui.list .list>a.item i.icon,.ui.list>a.item i.icon{color:rgba(0,0,0,.4)}.ui.list .list>.item a.header,.ui.list>.item a.header{cursor:pointer;color:#4183c4!important}.ui.list .list>.item a.header:hover,.ui.list>.item a.header:hover{color:#1e70bf!important}.ui[class*=\\\"left floated\\\"].list{float:left}.ui[class*=\\\"right floated\\\"].list{float:right}.ui.list .list>.item [class*=\\\"left floated\\\"],.ui.list>.item [class*=\\\"left floated\\\"]{float:left;margin:0 1em 0 0}.ui.list .list>.item [class*=\\\"right floated\\\"],.ui.list>.item [class*=\\\"right floated\\\"]{float:right;margin:0 0 0 1em}.ui.menu .ui.list .list>.item,.ui.menu .ui.list>.item{display:list-item;table-layout:fixed;background-color:transparent;list-style-type:none;list-style-position:outside;padding:.21428571em 0;line-height:1.14285714em}.ui.menu .ui.list .list>.item:before,.ui.menu .ui.list>.item:before{border:none;background:0 0}.ui.menu .ui.list .list>.item:first-child,.ui.menu .ui.list>.item:first-child{padding-top:0}.ui.menu .ui.list .list>.item:last-child,.ui.menu .ui.list>.item:last-child{padding-bottom:0}.ui.horizontal.list{display:inline-block;font-size:0}.ui.horizontal.list>.item{display:inline-block;margin-left:1em;font-size:1rem}.ui.horizontal.list:not(.celled)>.item:first-child{margin-left:0!important;padding-left:0!important}.ui.horizontal.list .list{padding-left:0;padding-bottom:0}.ui.horizontal.list .list>.item>.content,.ui.horizontal.list .list>.item>.icon,.ui.horizontal.list .list>.item>.image,.ui.horizontal.list>.item>.content,.ui.horizontal.list>.item>.icon,.ui.horizontal.list>.item>.image{vertical-align:middle}.ui.horizontal.list>.item:first-child,.ui.horizontal.list>.item:last-child{padding-top:.21428571em;padding-bottom:.21428571em}.ui.horizontal.list>.item>i.icon{margin:0;padding:0 .25em 0 0}.ui.horizontal.list>.item>.icon,.ui.horizontal.list>.item>.icon+.content{float:none;display:inline-block}.ui.list .list>.disabled.item,.ui.list>.disabled.item{pointer-events:none;color:rgba(40,40,40,.3)!important}.ui.inverted.list .list>.disabled.item,.ui.inverted.list>.disabled.item{color:rgba(225,225,225,.3)!important}.ui.list .list>a.item:hover .icon,.ui.list>a.item:hover .icon{color:rgba(0,0,0,.87)}.ui.inverted.list .list>a.item>.icon,.ui.inverted.list>a.item>.icon{color:rgba(255,255,255,.7)}.ui.inverted.list .list>.item .header,.ui.inverted.list>.item .header{color:rgba(255,255,255,.9)}.ui.inverted.list .list>.item .description,.ui.inverted.list>.item .description{color:rgba(255,255,255,.7)}.ui.inverted.list .list>a.item,.ui.inverted.list>a.item{cursor:pointer;color:rgba(255,255,255,.9)}.ui.inverted.list .list>a.item:hover,.ui.inverted.list>a.item:hover{color:#1e70bf}.ui.inverted.list .item a:not(.ui){color:rgba(255,255,255,.9)!important}.ui.inverted.list .item a:not(.ui):hover{color:#1e70bf!important}.ui.list [class*=\\\"top aligned\\\"],.ui.list[class*=\\\"top aligned\\\"] .content,.ui.list[class*=\\\"top aligned\\\"] .image{vertical-align:top!important}.ui.list [class*=\\\"middle aligned\\\"],.ui.list[class*=\\\"middle aligned\\\"] .content,.ui.list[class*=\\\"middle aligned\\\"] .image{vertical-align:middle!important}.ui.list [class*=\\\"bottom aligned\\\"],.ui.list[class*=\\\"bottom aligned\\\"] .content,.ui.list[class*=\\\"bottom aligned\\\"] .image{vertical-align:bottom!important}.ui.link.list .item,.ui.link.list .item a:not(.ui),.ui.link.list a.item{color:rgba(0,0,0,.4);-webkit-transition:.1s color ease;transition:.1s color ease}.ui.link.list.list .item a:not(.ui):hover,.ui.link.list.list a.item:hover{color:rgba(0,0,0,.8)}.ui.link.list.list .item a:not(.ui):active,.ui.link.list.list a.item:active{color:rgba(0,0,0,.9)}.ui.link.list.list .active.item,.ui.link.list.list .active.item a:not(.ui){color:rgba(0,0,0,.95)}.ui.inverted.link.list .item,.ui.inverted.link.list .item a:not(.ui),.ui.inverted.link.list a.item{color:rgba(255,255,255,.5)}.ui.inverted.link.list.list .item a:not(.ui):hover,.ui.inverted.link.list.list a.item:hover{color:#fff}.ui.inverted.link.list.list .item a:not(.ui):active,.ui.inverted.link.list.list a.item:active{color:#fff}.ui.inverted.link.list.list .active.item a:not(.ui),.ui.inverted.link.list.list a.active.item{color:#fff}.ui.selection.list .list>.item,.ui.selection.list>.item{cursor:pointer;background:0 0;padding:.5em .5em;margin:0;color:rgba(0,0,0,.4);border-radius:.5em;-webkit-transition:.1s color ease,.1s padding-left ease,.1s background-color ease;transition:.1s color ease,.1s padding-left ease,.1s background-color ease}.ui.selection.list .list>.item:last-child,.ui.selection.list>.item:last-child{margin-bottom:0}.ui.selection.list.list>.item:hover,.ui.selection.list>.item:hover{background:rgba(0,0,0,.03);color:rgba(0,0,0,.8)}.ui.selection.list .list>.item:active,.ui.selection.list>.item:active{background:rgba(0,0,0,.05);color:rgba(0,0,0,.9)}.ui.selection.list .list>.item.active,.ui.selection.list>.item.active{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.inverted.selection.list>.item{background:0 0;color:rgba(255,255,255,.5)}.ui.inverted.selection.list>.item:hover{background:rgba(255,255,255,.02);color:#fff}.ui.inverted.selection.list>.item:active{background:rgba(255,255,255,.08);color:#fff}.ui.inverted.selection.list>.item.active{background:rgba(255,255,255,.08);color:#fff}.ui.celled.selection.list .list>.item,.ui.celled.selection.list>.item,.ui.divided.selection.list .list>.item,.ui.divided.selection.list>.item{border-radius:0}.ui.animated.list>.item{-webkit-transition:.25s color ease .1s,.25s padding-left ease .1s,.25s background-color ease .1s;transition:.25s color ease .1s,.25s padding-left ease .1s,.25s background-color ease .1s}.ui.animated.list:not(.horizontal)>.item:hover{padding-left:1em}.ui.fitted.list:not(.selection) .list>.item,.ui.fitted.list:not(.selection)>.item{padding-left:0;padding-right:0}.ui.fitted.selection.list .list>.item,.ui.fitted.selection.list>.item{margin-left:-.5em;margin-right:-.5em}.ui.bulleted.list,ul.ui.list{margin-left:1.25rem}.ui.bulleted.list .list>.item,.ui.bulleted.list>.item,ul.ui.list li{position:relative}.ui.bulleted.list .list>.item:before,.ui.bulleted.list>.item:before,ul.ui.list li:before{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;position:absolute;top:auto;left:auto;font-weight:400;margin-left:-1.25rem;content:'•';opacity:1;color:inherit;vertical-align:top}.ui.bulleted.list .list>a.item:before,.ui.bulleted.list>a.item:before,ul.ui.list li:before{color:rgba(0,0,0,.87)}.ui.bulleted.list .list,ul.ui.list ul{padding-left:1.25rem}.ui.horizontal.bulleted.list,ul.ui.horizontal.bulleted.list{margin-left:0}.ui.horizontal.bulleted.list>.item,ul.ui.horizontal.bulleted.list li{margin-left:1.75rem}.ui.horizontal.bulleted.list>.item:first-child,ul.ui.horizontal.bulleted.list li:first-child{margin-left:0}.ui.horizontal.bulleted.list>.item::before,ul.ui.horizontal.bulleted.list li::before{color:rgba(0,0,0,.87)}.ui.horizontal.bulleted.list>.item:first-child::before,ul.ui.horizontal.bulleted.list li:first-child::before{display:none}.ui.ordered.list,.ui.ordered.list .list,ol.ui.list,ol.ui.list ol{counter-reset:ordered;margin-left:1.25rem;list-style-type:none}.ui.ordered.list .list>.item,.ui.ordered.list>.item,ol.ui.list li{list-style-type:none;position:relative}.ui.ordered.list .list>.item:before,.ui.ordered.list>.item:before,ol.ui.list li:before{position:absolute;top:auto;left:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;margin-left:-1.25rem;counter-increment:ordered;content:counters(ordered, \\\".\\\") \\\" \\\";text-align:right;color:rgba(0,0,0,.87);vertical-align:middle;opacity:.8}.ui.ordered.inverted.list .list>.item:before,.ui.ordered.inverted.list>.item:before,ol.ui.inverted.list li:before{color:rgba(255,255,255,.7)}.ui.ordered.list>.item[data-value],.ui.ordered.list>.list>.item[data-value]{content:attr(data-value)}ol.ui.list li[value]:before{content:attr(value)}.ui.ordered.list .list,ol.ui.list ol{margin-left:1em}.ui.ordered.list .list>.item:before,ol.ui.list ol li:before{margin-left:-2em}.ui.ordered.horizontal.list,ol.ui.horizontal.list{margin-left:0}.ui.ordered.horizontal.list .list>.item:before,.ui.ordered.horizontal.list>.item:before,ol.ui.horizontal.list li:before{position:static;margin:0 .5em 0 0}.ui.divided.list>.item{border-top:1px solid rgba(34,36,38,.15)}.ui.divided.list .list>.item{border-top:none}.ui.divided.list .item .list>.item{border-top:none}.ui.divided.list .list>.item:first-child,.ui.divided.list>.item:first-child{border-top:none}.ui.divided.list:not(.horizontal) .list>.item:first-child{border-top-width:1px}.ui.divided.bulleted.list .list,.ui.divided.bulleted.list:not(.horizontal){margin-left:0;padding-left:0}.ui.divided.bulleted.list>.item:not(.horizontal){padding-left:1.25rem}.ui.divided.ordered.list{margin-left:0}.ui.divided.ordered.list .list>.item,.ui.divided.ordered.list>.item{padding-left:1.25rem}.ui.divided.ordered.list .item .list{margin-left:0;margin-right:0;padding-bottom:.21428571em}.ui.divided.ordered.list .item .list>.item{padding-left:1em}.ui.divided.selection.list .list>.item,.ui.divided.selection.list>.item{margin:0;border-radius:0}.ui.divided.horizontal.list{margin-left:0}.ui.divided.horizontal.list>.item:not(:first-child){padding-left:.5em}.ui.divided.horizontal.list>.item:not(:last-child){padding-right:.5em}.ui.divided.horizontal.list>.item{border-top:none;border-left:1px solid rgba(34,36,38,.15);margin:0;line-height:.6}.ui.horizontal.divided.list>.item:first-child{border-left:none}.ui.divided.inverted.horizontal.list>.item,.ui.divided.inverted.list>.item,.ui.divided.inverted.list>.list{border-color:rgba(255,255,255,.1)}.ui.celled.list>.item,.ui.celled.list>.list{border-top:1px solid rgba(34,36,38,.15);padding-left:.5em;padding-right:.5em}.ui.celled.list>.item:last-child{border-bottom:1px solid rgba(34,36,38,.15)}.ui.celled.list>.item:first-child,.ui.celled.list>.item:last-child{padding-top:.21428571em;padding-bottom:.21428571em}.ui.celled.list .item .list>.item{border-width:0}.ui.celled.list .list>.item:first-child{border-top-width:0}.ui.celled.bulleted.list{margin-left:0}.ui.celled.bulleted.list .list>.item,.ui.celled.bulleted.list>.item{padding-left:1.25rem}.ui.celled.bulleted.list .item .list{margin-left:-1.25rem;margin-right:-1.25rem;padding-bottom:.21428571em}.ui.celled.ordered.list{margin-left:0}.ui.celled.ordered.list .list>.item,.ui.celled.ordered.list>.item{padding-left:1.25rem}.ui.celled.ordered.list .item .list{margin-left:0;margin-right:0;padding-bottom:.21428571em}.ui.celled.ordered.list .list>.item{padding-left:1em}.ui.horizontal.celled.list{margin-left:0}.ui.horizontal.celled.list .list>.item,.ui.horizontal.celled.list>.item{border-top:none;border-left:1px solid rgba(34,36,38,.15);margin:0;padding-left:.5em;padding-right:.5em;line-height:.6}.ui.horizontal.celled.list .list>.item:last-child,.ui.horizontal.celled.list>.item:last-child{border-bottom:none;border-right:1px solid rgba(34,36,38,.15)}.ui.celled.inverted.list>.item,.ui.celled.inverted.list>.list{border-color:1px solid rgba(255,255,255,.1)}.ui.celled.inverted.horizontal.list .list>.item,.ui.celled.inverted.horizontal.list>.item{border-color:1px solid rgba(255,255,255,.1)}.ui.relaxed.list:not(.horizontal)>.item:not(:first-child){padding-top:.42857143em}.ui.relaxed.list:not(.horizontal)>.item:not(:last-child){padding-bottom:.42857143em}.ui.horizontal.relaxed.list .list>.item:not(:first-child),.ui.horizontal.relaxed.list>.item:not(:first-child){padding-left:1rem}.ui.horizontal.relaxed.list .list>.item:not(:last-child),.ui.horizontal.relaxed.list>.item:not(:last-child){padding-right:1rem}.ui[class*=\\\"very relaxed\\\"].list:not(.horizontal)>.item:not(:first-child){padding-top:.85714286em}.ui[class*=\\\"very relaxed\\\"].list:not(.horizontal)>.item:not(:last-child){padding-bottom:.85714286em}.ui.horizontal[class*=\\\"very relaxed\\\"].list .list>.item:not(:first-child),.ui.horizontal[class*=\\\"very relaxed\\\"].list>.item:not(:first-child){padding-left:1.5rem}.ui.horizontal[class*=\\\"very relaxed\\\"].list .list>.item:not(:last-child),.ui.horizontal[class*=\\\"very relaxed\\\"].list>.item:not(:last-child){padding-right:1.5rem}.ui.mini.list{font-size:.78571429em}.ui.tiny.list{font-size:.85714286em}.ui.small.list{font-size:.92857143em}.ui.list{font-size:1em}.ui.large.list{font-size:1.14285714em}.ui.big.list{font-size:1.28571429em}.ui.huge.list{font-size:1.42857143em}.ui.massive.list{font-size:1.71428571em}.ui.mini.horizontal.list .list>.item,.ui.mini.horizontal.list>.item{font-size:.78571429rem}.ui.tiny.horizontal.list .list>.item,.ui.tiny.horizontal.list>.item{font-size:.85714286rem}.ui.small.horizontal.list .list>.item,.ui.small.horizontal.list>.item{font-size:.92857143rem}.ui.horizontal.list .list>.item,.ui.horizontal.list>.item{font-size:1rem}.ui.large.horizontal.list .list>.item,.ui.large.horizontal.list>.item{font-size:1.14285714rem}.ui.big.horizontal.list .list>.item,.ui.big.horizontal.list>.item{font-size:1.28571429rem}.ui.huge.horizontal.list .list>.item,.ui.huge.horizontal.list>.item{font-size:1.42857143rem}.ui.massive.horizontal.list .list>.item,.ui.massive.horizontal.list>.item{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Loader\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.loader{display:none;position:absolute;top:50%;left:50%;margin:0;text-align:center;z-index:1000;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.ui.loader:before{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loader:after{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;-webkit-animation:loader .6s linear;animation:loader .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}@-webkit-keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.mini.loader:after,.ui.mini.loader:before{width:1rem;height:1rem;margin:0 0 0 -.5rem}.ui.tiny.loader:after,.ui.tiny.loader:before{width:1.14285714rem;height:1.14285714rem;margin:0 0 0 -.57142857rem}.ui.small.loader:after,.ui.small.loader:before{width:1.71428571rem;height:1.71428571rem;margin:0 0 0 -.85714286rem}.ui.loader:after,.ui.loader:before{width:2.28571429rem;height:2.28571429rem;margin:0 0 0 -1.14285714rem}.ui.large.loader:after,.ui.large.loader:before{width:3.42857143rem;height:3.42857143rem;margin:0 0 0 -1.71428571rem}.ui.big.loader:after,.ui.big.loader:before{width:3.71428571rem;height:3.71428571rem;margin:0 0 0 -1.85714286rem}.ui.huge.loader:after,.ui.huge.loader:before{width:4.14285714rem;height:4.14285714rem;margin:0 0 0 -2.07142857rem}.ui.massive.loader:after,.ui.massive.loader:before{width:4.57142857rem;height:4.57142857rem;margin:0 0 0 -2.28571429rem}.ui.dimmer .loader{display:block}.ui.dimmer .ui.loader{color:rgba(255,255,255,.9)}.ui.dimmer .ui.loader:before{border-color:rgba(255,255,255,.15)}.ui.dimmer .ui.loader:after{border-color:#fff transparent transparent}.ui.inverted.dimmer .ui.loader{color:rgba(0,0,0,.87)}.ui.inverted.dimmer .ui.loader:before{border-color:rgba(0,0,0,.1)}.ui.inverted.dimmer .ui.loader:after{border-color:#767676 transparent transparent}.ui.text.loader{width:auto!important;height:auto!important;text-align:center;font-style:normal}.ui.indeterminate.loader:after{animation-direction:reverse;-webkit-animation-duration:1.2s;animation-duration:1.2s}.ui.loader.active,.ui.loader.visible{display:block}.ui.loader.disabled,.ui.loader.hidden{display:none}.ui.inverted.dimmer .ui.mini.loader,.ui.mini.loader{width:1rem;height:1rem;font-size:.78571429em}.ui.inverted.dimmer .ui.tiny.loader,.ui.tiny.loader{width:1.14285714rem;height:1.14285714rem;font-size:.85714286em}.ui.inverted.dimmer .ui.small.loader,.ui.small.loader{width:1.71428571rem;height:1.71428571rem;font-size:.92857143em}.ui.inverted.dimmer .ui.loader,.ui.loader{width:2.28571429rem;height:2.28571429rem;font-size:1em}.ui.inverted.dimmer .ui.large.loader,.ui.large.loader{width:3.42857143rem;height:3.42857143rem;font-size:1.14285714em}.ui.big.loader,.ui.inverted.dimmer .ui.big.loader{width:3.71428571rem;height:3.71428571rem;font-size:1.28571429em}.ui.huge.loader,.ui.inverted.dimmer .ui.huge.loader{width:4.14285714rem;height:4.14285714rem;font-size:1.42857143em}.ui.inverted.dimmer .ui.massive.loader,.ui.massive.loader{width:4.57142857rem;height:4.57142857rem;font-size:1.71428571em}.ui.mini.text.loader{min-width:1rem;padding-top:1.78571429rem}.ui.tiny.text.loader{min-width:1.14285714rem;padding-top:1.92857143rem}.ui.small.text.loader{min-width:1.71428571rem;padding-top:2.5rem}.ui.text.loader{min-width:2.28571429rem;padding-top:3.07142857rem}.ui.large.text.loader{min-width:3.42857143rem;padding-top:4.21428571rem}.ui.big.text.loader{min-width:3.71428571rem;padding-top:4.5rem}.ui.huge.text.loader{min-width:4.14285714rem;padding-top:4.92857143rem}.ui.massive.text.loader{min-width:4.57142857rem;padding-top:5.35714286rem}.ui.inverted.loader{color:rgba(255,255,255,.9)}.ui.inverted.loader:before{border-color:rgba(255,255,255,.15)}.ui.inverted.loader:after{border-top-color:#fff}.ui.inline.loader{position:relative;vertical-align:middle;margin:0;left:0;top:0;-webkit-transform:none;transform:none}.ui.inline.loader.active,.ui.inline.loader.visible{display:inline-block}.ui.centered.inline.loader.active,.ui.centered.inline.loader.visible{display:block;margin-left:auto;margin-right:auto}/*!\\n * # Semantic UI 2.4.0 - Loader\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.placeholder{position:static;overflow:hidden;-webkit-animation:placeholderShimmer 2s linear;animation:placeholderShimmer 2s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;background-color:#fff;background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.08)),color-stop(15%,rgba(0,0,0,.15)),color-stop(30%,rgba(0,0,0,.08)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.08) 0,rgba(0,0,0,.15) 15%,rgba(0,0,0,.08) 30%);background-image:linear-gradient(to right,rgba(0,0,0,.08) 0,rgba(0,0,0,.15) 15%,rgba(0,0,0,.08) 30%);background-size:1200px 100%;max-width:30rem}@-webkit-keyframes placeholderShimmer{0%{background-position:-1200px 0}100%{background-position:1200px 0}}@keyframes placeholderShimmer{0%{background-position:-1200px 0}100%{background-position:1200px 0}}.ui.placeholder+.ui.placeholder{margin-top:2rem}.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.15s;animation-delay:.15s}.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.3s;animation-delay:.3s}.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.45s;animation-delay:.45s}.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.6s;animation-delay:.6s}.ui.placeholder,.ui.placeholder .image.header:after,.ui.placeholder .line,.ui.placeholder .line:after,.ui.placeholder>:before{background-color:#fff}.ui.placeholder .image:not(.header):not(.ui){height:100px}.ui.placeholder .square.image:not(.header){height:0;overflow:hidden;padding-top:100%}.ui.placeholder .rectangular.image:not(.header){height:0;overflow:hidden;padding-top:75%}.ui.placeholder .line{position:relative;height:.85714286em}.ui.placeholder .line:after,.ui.placeholder .line:before{top:100%;position:absolute;content:'';background-color:inherit}.ui.placeholder .line:before{left:0}.ui.placeholder .line:after{right:0}.ui.placeholder .line{margin-bottom:.5em}.ui.placeholder .line:after,.ui.placeholder .line:before{height:.5em}.ui.placeholder .line:not(:first-child){margin-top:.5em}.ui.placeholder .header{position:relative;overflow:hidden}.ui.placeholder .line:nth-child(1):after{width:0%}.ui.placeholder .line:nth-child(2):after{width:50%}.ui.placeholder .line:nth-child(3):after{width:10%}.ui.placeholder .line:nth-child(4):after{width:35%}.ui.placeholder .line:nth-child(5):after{width:65%}.ui.placeholder .header .line{margin-bottom:.64285714em}.ui.placeholder .header .line:after,.ui.placeholder .header .line:before{height:.64285714em}.ui.placeholder .header .line:not(:first-child){margin-top:.64285714em}.ui.placeholder .header .line:after{width:20%}.ui.placeholder .header .line:nth-child(2):after{width:60%}.ui.placeholder .image.header .line{margin-left:3em}.ui.placeholder .image.header .line:before{width:.71428571rem}.ui.placeholder .image.header:after{display:block;height:.85714286em;content:'';margin-left:3em}.ui.placeholder .header .line:first-child,.ui.placeholder .image .line:first-child,.ui.placeholder .paragraph .line:first-child{height:.01px}.ui.placeholder .header:not(:first-child):before,.ui.placeholder .image:not(:first-child):before,.ui.placeholder .paragraph:not(:first-child):before{height:1.42857143em;content:'';display:block}.ui.inverted.placeholder{background-image:-webkit-gradient(linear,left top,right top,from(rgba(255,255,255,.08)),color-stop(15%,rgba(255,255,255,.14)),color-stop(30%,rgba(255,255,255,.08)));background-image:-webkit-linear-gradient(left,rgba(255,255,255,.08) 0,rgba(255,255,255,.14) 15%,rgba(255,255,255,.08) 30%);background-image:linear-gradient(to right,rgba(255,255,255,.08) 0,rgba(255,255,255,.14) 15%,rgba(255,255,255,.08) 30%)}.ui.inverted.placeholder,.ui.inverted.placeholder .image.header:after,.ui.inverted.placeholder .line,.ui.inverted.placeholder .line:after,.ui.inverted.placeholder>:before{background-color:#1b1c1d}.ui.placeholder .full.line.line.line:after{width:0%}.ui.placeholder .very.long.line.line.line:after{width:10%}.ui.placeholder .long.line.line.line:after{width:35%}.ui.placeholder .medium.line.line.line:after{width:50%}.ui.placeholder .short.line.line.line:after{width:65%}.ui.placeholder .very.short.line.line.line:after{width:80%}.ui.fluid.placeholder{max-width:none}/*!\\n * # Semantic UI 2.4.0 - Rail\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.rail{position:absolute;top:0;width:300px;height:100%}.ui.left.rail{left:auto;right:100%;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.right.rail{left:100%;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.left.internal.rail{left:0;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.right.internal.rail{left:auto;right:0;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.dividing.rail{width:302.5px}.ui.left.dividing.rail{padding:0 2.5rem 0 0;margin:0 2.5rem 0 0;border-right:1px solid rgba(34,36,38,.15)}.ui.right.dividing.rail{border-left:1px solid rgba(34,36,38,.15);padding:0 0 0 2.5rem;margin:0 0 0 2.5rem}.ui.close.rail{width:calc(300px + 1em)}.ui.close.left.rail{padding:0 1em 0 0;margin:0 1em 0 0}.ui.close.right.rail{padding:0 0 0 1em;margin:0 0 0 1em}.ui.very.close.rail{width:calc(300px + .5em)}.ui.very.close.left.rail{padding:0 .5em 0 0;margin:0 .5em 0 0}.ui.very.close.right.rail{padding:0 0 0 .5em;margin:0 0 0 .5em}.ui.attached.left.rail,.ui.attached.right.rail{padding:0;margin:0}.ui.mini.rail{font-size:.78571429rem}.ui.tiny.rail{font-size:.85714286rem}.ui.small.rail{font-size:.92857143rem}.ui.rail{font-size:1rem}.ui.large.rail{font-size:1.14285714rem}.ui.big.rail{font-size:1.28571429rem}.ui.huge.rail{font-size:1.42857143rem}.ui.massive.rail{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Reveal\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.reveal{display:inherit;position:relative!important;font-size:0!important}.ui.reveal>.visible.content{position:absolute!important;top:0!important;left:0!important;z-index:3!important;-webkit-transition:all .5s ease .1s;transition:all .5s ease .1s}.ui.reveal>.hidden.content{position:relative!important;z-index:2!important}.ui.active.reveal .visible.content,.ui.reveal:hover .visible.content{z-index:4!important}.ui.slide.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.slide.reveal>.content{display:block;width:100%;white-space:normal;float:left;margin:0;-webkit-transition:-webkit-transform .5s ease .1s;transition:-webkit-transform .5s ease .1s;transition:transform .5s ease .1s;transition:transform .5s ease .1s,-webkit-transform .5s ease .1s}.ui.slide.reveal>.visible.content{position:relative!important}.ui.slide.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important;-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.active.reveal>.visible.content,.ui.slide.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.active.reveal>.hidden.content,.ui.slide.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.visible.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.hidden.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.right.active.reveal>.visible.content,.ui.slide.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.right.active.reveal>.hidden.content,.ui.slide.right.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.up.reveal>.hidden.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.up.active.reveal>.visible.content,.ui.slide.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.up.active.reveal>.hidden.content,.ui.slide.up.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.slide.down.reveal>.hidden.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.down.active.reveal>.visible.content,.ui.slide.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.down.active.reveal>.hidden.content,.ui.slide.down.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.fade.reveal>.visible.content{opacity:1}.ui.fade.active.reveal>.visible.content,.ui.fade.reveal:hover>.visible.content{opacity:0}.ui.move.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.move.reveal>.content{display:block;float:left;white-space:normal;margin:0;-webkit-transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s,-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s}.ui.move.reveal>.visible.content{position:relative!important}.ui.move.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important}.ui.move.active.reveal>.visible.content,.ui.move.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.move.right.active.reveal>.visible.content,.ui.move.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.move.up.active.reveal>.visible.content,.ui.move.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.move.down.active.reveal>.visible.content,.ui.move.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.rotate.reveal>.visible.content{-webkit-transition-duration:.5s;transition-duration:.5s;-webkit-transform:rotate(0);transform:rotate(0)}.ui.rotate.reveal>.visible.content,.ui.rotate.right.reveal>.visible.content{-webkit-transform-origin:bottom right;transform-origin:bottom right}.ui.rotate.active.reveal>.visible.content,.ui.rotate.reveal:hover>.visible.content,.ui.rotate.right.active.reveal>.visible.content,.ui.rotate.right.reveal:hover>.visible.content{-webkit-transform:rotate(110deg);transform:rotate(110deg)}.ui.rotate.left.reveal>.visible.content{-webkit-transform-origin:bottom left;transform-origin:bottom left}.ui.rotate.left.active.reveal>.visible.content,.ui.rotate.left.reveal:hover>.visible.content{-webkit-transform:rotate(-110deg);transform:rotate(-110deg)}.ui.disabled.reveal:hover>.visible.visible.content{position:static!important;display:block!important;opacity:1!important;top:0!important;left:0!important;right:auto!important;bottom:auto!important;-webkit-transform:none!important;transform:none!important}.ui.disabled.reveal:hover>.hidden.hidden.content{display:none!important}.ui.reveal>.ui.ribbon.label{z-index:5}.ui.visible.reveal{overflow:visible}.ui.instant.reveal>.content{-webkit-transition-delay:0s!important;transition-delay:0s!important}.ui.reveal>.content{font-size:1rem!important}/*!\\n * # Semantic UI 2.4.0 - Segment\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.segment{position:relative;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);margin:1rem 0;padding:1em 1em;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.segment:first-child{margin-top:0}.ui.segment:last-child{margin-bottom:0}.ui.vertical.segment{margin:0;padding-left:0;padding-right:0;background:none transparent;border-radius:0;-webkit-box-shadow:none;box-shadow:none;border:none;border-bottom:1px solid rgba(34,36,38,.15)}.ui.vertical.segment:last-child{border-bottom:none}.ui.inverted.segment>.ui.header{color:#fff}.ui[class*=\\\"bottom attached\\\"].segment>[class*=\\\"top attached\\\"].label{border-top-left-radius:0;border-top-right-radius:0}.ui[class*=\\\"top attached\\\"].segment>[class*=\\\"bottom attached\\\"].label{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.attached.segment:not(.top):not(.bottom)>[class*=\\\"top attached\\\"].label{border-top-left-radius:0;border-top-right-radius:0}.ui.attached.segment:not(.top):not(.bottom)>[class*=\\\"bottom attached\\\"].label{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.grid>.row>.ui.segment.column,.ui.grid>.ui.segment.column,.ui.page.grid.segment{padding-top:2em;padding-bottom:2em}.ui.grid.segment{margin:1rem 0;border-radius:.28571429rem}.ui.basic.table.segment{background:#fff;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15)}.ui[class*=\\\"very basic\\\"].table.segment{padding:1em 1em}.ui.placeholder.segment{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;max-width:initial;-webkit-animation:none;animation:none;overflow:visible;padding:1em 1em;min-height:18rem;background:#f9fafb;border-color:rgba(34,36,38,.15);-webkit-box-shadow:0 2px 25px 0 rgba(34,36,38,.05) inset;box-shadow:0 2px 25px 0 rgba(34,36,38,.05) inset}.ui.placeholder.segment .button,.ui.placeholder.segment textarea{display:block}.ui.placeholder.segment .button,.ui.placeholder.segment .field,.ui.placeholder.segment textarea,.ui.placeholder.segment>.ui.input{max-width:15rem;margin-left:auto;margin-right:auto}.ui.placeholder.segment .column .button,.ui.placeholder.segment .column .field,.ui.placeholder.segment .column textarea,.ui.placeholder.segment .column>.ui.input{max-width:15rem;margin-left:auto;margin-right:auto}.ui.placeholder.segment>.inline{-ms-flex-item-align:center;align-self:center}.ui.placeholder.segment>.inline>.button{display:inline-block;width:auto;margin:0 .35714286rem 0 0}.ui.placeholder.segment>.inline>.button:last-child{margin-right:0}.ui.piled.segment,.ui.piled.segments{margin:3em 0;-webkit-box-shadow:'';box-shadow:'';z-index:auto}.ui.piled.segment:first-child{margin-top:0}.ui.piled.segment:last-child{margin-bottom:0}.ui.piled.segment:after,.ui.piled.segment:before,.ui.piled.segments:after,.ui.piled.segments:before{background-color:#fff;visibility:visible;content:'';display:block;height:100%;left:0;position:absolute;width:100%;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:'';box-shadow:''}.ui.piled.segment:before,.ui.piled.segments:before{-webkit-transform:rotate(-1.2deg);transform:rotate(-1.2deg);top:0;z-index:-2}.ui.piled.segment:after,.ui.piled.segments:after{-webkit-transform:rotate(1.2deg);transform:rotate(1.2deg);top:0;z-index:-1}.ui[class*=\\\"top attached\\\"].piled.segment{margin-top:3em;margin-bottom:0}.ui.piled.segment[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui.piled.segment[class*=\\\"bottom attached\\\"]{margin-top:0;margin-bottom:3em}.ui.piled.segment[class*=\\\"bottom attached\\\"]:last-child{margin-bottom:0}.ui.stacked.segment{padding-bottom:1.4em}.ui.stacked.segment:after,.ui.stacked.segment:before,.ui.stacked.segments:after,.ui.stacked.segments:before{content:'';position:absolute;bottom:-3px;left:0;border-top:1px solid rgba(34,36,38,.15);background:rgba(0,0,0,.03);width:100%;height:6px;visibility:visible}.ui.stacked.segment:before,.ui.stacked.segments:before{display:none}.ui.tall.stacked.segment:before,.ui.tall.stacked.segments:before{display:block;bottom:0}.ui.stacked.inverted.segment:after,.ui.stacked.inverted.segment:before,.ui.stacked.inverted.segments:after,.ui.stacked.inverted.segments:before{background-color:rgba(0,0,0,.03);border-top:1px solid rgba(34,36,38,.35)}.ui.padded.segment{padding:1.5em}.ui[class*=\\\"very padded\\\"].segment{padding:3em}.ui.padded.segment.vertical.segment,.ui[class*=\\\"very padded\\\"].vertical.segment{padding-left:0;padding-right:0}.ui.compact.segment{display:table}.ui.compact.segments{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.ui.compact.segments .segment,.ui.segments .compact.segment{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.ui.circular.segment{display:table-cell;padding:2em;text-align:center;vertical-align:middle;border-radius:500em}.ui.raised.segment,.ui.raised.segments{-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.segments{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:relative;margin:1rem 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);border-radius:.28571429rem}.ui.segments:first-child{margin-top:0}.ui.segments:last-child{margin-bottom:0}.ui.segments>.segment{top:0;bottom:0;border-radius:0;margin:0;width:auto;-webkit-box-shadow:none;box-shadow:none;border:none;border-top:1px solid rgba(34,36,38,.15)}.ui.segments:not(.horizontal)>.segment:first-child{border-top:none;margin-top:0;bottom:0;margin-bottom:0;top:0;border-radius:.28571429rem .28571429rem 0 0}.ui.segments:not(.horizontal)>.segment:last-child{top:0;bottom:0;margin-top:0;margin-bottom:0;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui.segments:not(.horizontal)>.segment:only-child{border-radius:.28571429rem}.ui.segments>.ui.segments{border-top:1px solid rgba(34,36,38,.15);margin:1rem 1rem}.ui.segments>.segments:first-child{border-top:none}.ui.segments>.segment+.segments:not(.horizontal){margin-top:0}.ui.horizontal.segments{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;background-color:transparent;border-radius:0;padding:0;background-color:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);margin:1rem 0;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.segments>.horizontal.segments{margin:0;background-color:transparent;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none;border-top:1px solid rgba(34,36,38,.15)}.ui.horizontal.segments>.segment{-webkit-box-flex:1;flex:1 1 auto;-ms-flex:1 1 0px;margin:0;min-width:0;background-color:transparent;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none;border-left:1px solid rgba(34,36,38,.15)}.ui.segments>.horizontal.segments:first-child{border-top:none}.ui.horizontal.segments>.segment:first-child{border-left:none}.ui.disabled.segment{opacity:.45;color:rgba(40,40,40,.3)}.ui.loading.segment{position:relative;cursor:default;pointer-events:none;text-shadow:none!important;color:transparent!important;-webkit-transition:all 0s linear;transition:all 0s linear}.ui.loading.segment:before{position:absolute;content:'';top:0;left:0;background:rgba(255,255,255,.8);width:100%;height:100%;border-radius:.28571429rem;z-index:100}.ui.loading.segment:after{position:absolute;content:'';top:50%;left:50%;margin:-1.5em 0 0 -1.5em;width:3em;height:3em;-webkit-animation:segment-spin .6s linear;animation:segment-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.1);border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;visibility:visible;z-index:101}@-webkit-keyframes segment-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes segment-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.basic.segment{background:none transparent;-webkit-box-shadow:none;box-shadow:none;border:none;border-radius:0}.ui.clearing.segment:after{content:\\\".\\\";display:block;height:0;clear:both;visibility:hidden}.ui.red.segment:not(.inverted){border-top:2px solid #db2828!important}.ui.inverted.red.segment{background-color:#db2828!important;color:#fff!important}.ui.orange.segment:not(.inverted){border-top:2px solid #f2711c!important}.ui.inverted.orange.segment{background-color:#f2711c!important;color:#fff!important}.ui.yellow.segment:not(.inverted){border-top:2px solid #fbbd08!important}.ui.inverted.yellow.segment{background-color:#fbbd08!important;color:#fff!important}.ui.olive.segment:not(.inverted){border-top:2px solid #b5cc18!important}.ui.inverted.olive.segment{background-color:#b5cc18!important;color:#fff!important}.ui.green.segment:not(.inverted){border-top:2px solid #21ba45!important}.ui.inverted.green.segment{background-color:#21ba45!important;color:#fff!important}.ui.teal.segment:not(.inverted){border-top:2px solid #00b5ad!important}.ui.inverted.teal.segment{background-color:#00b5ad!important;color:#fff!important}.ui.blue.segment:not(.inverted){border-top:2px solid #2185d0!important}.ui.inverted.blue.segment{background-color:#2185d0!important;color:#fff!important}.ui.violet.segment:not(.inverted){border-top:2px solid #6435c9!important}.ui.inverted.violet.segment{background-color:#6435c9!important;color:#fff!important}.ui.purple.segment:not(.inverted){border-top:2px solid #a333c8!important}.ui.inverted.purple.segment{background-color:#a333c8!important;color:#fff!important}.ui.pink.segment:not(.inverted){border-top:2px solid #e03997!important}.ui.inverted.pink.segment{background-color:#e03997!important;color:#fff!important}.ui.brown.segment:not(.inverted){border-top:2px solid #a5673f!important}.ui.inverted.brown.segment{background-color:#a5673f!important;color:#fff!important}.ui.grey.segment:not(.inverted){border-top:2px solid #767676!important}.ui.inverted.grey.segment{background-color:#767676!important;color:#fff!important}.ui.black.segment:not(.inverted){border-top:2px solid #1b1c1d!important}.ui.inverted.black.segment{background-color:#1b1c1d!important;color:#fff!important}.ui[class*=\\\"left aligned\\\"].segment{text-align:left}.ui[class*=\\\"right aligned\\\"].segment{text-align:right}.ui[class*=\\\"center aligned\\\"].segment{text-align:center}.ui.floated.segment,.ui[class*=\\\"left floated\\\"].segment{float:left;margin-right:1em}.ui[class*=\\\"right floated\\\"].segment{float:right;margin-left:1em}.ui.inverted.segment{border:none;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.segment,.ui.primary.inverted.segment{background:#1b1c1d;color:rgba(255,255,255,.9)}.ui.inverted.segment .segment{color:rgba(0,0,0,.87)}.ui.inverted.segment .inverted.segment{color:rgba(255,255,255,.9)}.ui.inverted.attached.segment{border-color:#555}.ui.secondary.segment{background:#f3f4f5;color:rgba(0,0,0,.6)}.ui.secondary.inverted.segment{background:#4c4f52 -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,.2)),to(rgba(255,255,255,.2)));background:#4c4f52 -webkit-linear-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.2) 100%);background:#4c4f52 linear-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.2) 100%);color:rgba(255,255,255,.8)}.ui.tertiary.segment{background:#dcddde;color:rgba(0,0,0,.6)}.ui.tertiary.inverted.segment{background:#717579 -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,.35)),to(rgba(255,255,255,.35)));background:#717579 -webkit-linear-gradient(rgba(255,255,255,.35) 0,rgba(255,255,255,.35) 100%);background:#717579 linear-gradient(rgba(255,255,255,.35) 0,rgba(255,255,255,.35) 100%);color:rgba(255,255,255,.8)}.ui.attached.segment{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached:not(.message)+.ui.attached.segment:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].segment{bottom:0;margin-bottom:0;top:0;margin-top:1rem;border-radius:.28571429rem .28571429rem 0 0}.ui.segment[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui.segment[class*=\\\"bottom attached\\\"]{bottom:0;margin-top:0;top:0;margin-bottom:1rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui.segment[class*=\\\"bottom attached\\\"]:last-child{margin-bottom:0}.ui.mini.segment,.ui.mini.segments .segment{font-size:.78571429rem}.ui.tiny.segment,.ui.tiny.segments .segment{font-size:.85714286rem}.ui.small.segment,.ui.small.segments .segment{font-size:.92857143rem}.ui.segment,.ui.segments .segment{font-size:1rem}.ui.large.segment,.ui.large.segments .segment{font-size:1.14285714rem}.ui.big.segment,.ui.big.segments .segment{font-size:1.28571429rem}.ui.huge.segment,.ui.huge.segments .segment{font-size:1.42857143rem}.ui.massive.segment,.ui.massive.segments .segment{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Step\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;margin:1em 0;background:'';-webkit-box-shadow:none;box-shadow:none;line-height:1.14285714em;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.steps:first-child{margin-top:0}.ui.steps:last-child{margin-bottom:0}.ui.steps .step{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;vertical-align:middle;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:0 0;padding:1.14285714em 2em;background:#fff;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none;border-radius:0;border:none;border-right:1px solid rgba(34,36,38,.15);-webkit-transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease}.ui.steps .step:after{display:none;position:absolute;z-index:2;content:'';top:50%;right:0;border:medium none;background-color:#fff;width:1.14285714em;height:1.14285714em;border-style:solid;border-color:rgba(34,36,38,.15);border-width:0 1px 1px 0;-webkit-transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease;-webkit-transform:translateY(-50%) translateX(50%) rotate(-45deg);transform:translateY(-50%) translateX(50%) rotate(-45deg)}.ui.steps .step:first-child{padding-left:2em;border-radius:.28571429rem 0 0 .28571429rem}.ui.steps .step:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.steps .step:last-child{border-right:none;margin-right:0}.ui.steps .step:only-child{border-radius:.28571429rem}.ui.steps .step .title{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.14285714em;font-weight:700}.ui.steps .step>.title{width:100%}.ui.steps .step .description{font-weight:400;font-size:.92857143em;color:rgba(0,0,0,.87)}.ui.steps .step>.description{width:100%}.ui.steps .step .title~.description{margin-top:.25em}.ui.steps .step>.icon{line-height:1;font-size:2.5em;margin:0 1rem 0 0}.ui.steps .step>.icon,.ui.steps .step>.icon~.content{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-ms-flex-item-align:middle;align-self:middle}.ui.steps .step>.icon~.content{-webkit-box-flex:1 0 auto;-ms-flex-positive:1 0 auto;flex-grow:1 0 auto}.ui.steps:not(.vertical) .step>.icon{width:auto}.ui.steps .link.step,.ui.steps a.step{cursor:pointer}.ui.ordered.steps{counter-reset:ordered}.ui.ordered.steps .step:before{display:block;position:static;text-align:center;content:counters(ordered, \\\".\\\");-ms-flex-item-align:middle;align-self:middle;margin-right:1rem;font-size:2.5em;counter-increment:ordered;font-family:inherit;font-weight:700}.ui.ordered.steps .step>*{display:block;-ms-flex-item-align:middle;align-self:middle}.ui.vertical.steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:visible}.ui.vertical.steps .step{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;border-radius:0;padding:1.14285714em 2em;border-right:none;border-bottom:1px solid rgba(34,36,38,.15)}.ui.vertical.steps .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.steps .step:last-child{border-bottom:none;border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.steps .step:only-child{border-radius:.28571429rem}.ui.vertical.steps .step:after{display:none}.ui.vertical.steps .step:after{top:50%;right:0;border-width:0 1px 1px 0}.ui.vertical.steps .step:after{display:none}.ui.vertical.steps .active.step:after{display:block}.ui.vertical.steps .step:last-child:after{display:none}.ui.vertical.steps .active.step:last-child:after{display:block}@media only screen and (max-width:767px){.ui.steps:not(.unstackable){display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;overflow:visible;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.steps:not(.unstackable) .step{width:100%!important;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-radius:0;padding:1.14285714em 2em}.ui.steps:not(.unstackable) .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui.steps:not(.unstackable) .step:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.steps:not(.unstackable) .step:after{display:none!important}.ui.steps:not(.unstackable) .step .content{text-align:center}.ui.ordered.steps:not(.unstackable) .step:before,.ui.steps:not(.unstackable) .step>.icon{margin:0 0 1rem 0}}.ui.steps .link.step:hover,.ui.steps .link.step:hover::after,.ui.steps a.step:hover,.ui.steps a.step:hover::after{background:#f9fafb;color:rgba(0,0,0,.8)}.ui.steps .link.step:active,.ui.steps .link.step:active::after,.ui.steps a.step:active,.ui.steps a.step:active::after{background:#f3f4f5;color:rgba(0,0,0,.9)}.ui.steps .step.active{cursor:auto;background:#f3f4f5}.ui.steps .step.active:after{background:#f3f4f5}.ui.steps .step.active .title{color:#4183c4}.ui.ordered.steps .step.active:before,.ui.steps .active.step .icon{color:rgba(0,0,0,.85)}.ui.steps .step:after{display:block}.ui.steps .active.step:after{display:block}.ui.steps .step:last-child:after{display:none}.ui.steps .active.step:last-child:after{display:none}.ui.steps .link.active.step:hover,.ui.steps .link.active.step:hover::after,.ui.steps a.active.step:hover,.ui.steps a.active.step:hover::after{cursor:pointer;background:#dcddde;color:rgba(0,0,0,.87)}.ui.ordered.steps .step.completed:before,.ui.steps .step.completed>.icon:before{color:#21ba45}.ui.steps .disabled.step{cursor:auto;background:#fff;pointer-events:none}.ui.steps .disabled.step,.ui.steps .disabled.step .description,.ui.steps .disabled.step .title{color:rgba(40,40,40,.3)}.ui.steps .disabled.step:after{background:#fff}@media only screen and (max-width:991px){.ui[class*=\\\"tablet stackable\\\"].steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;overflow:visible;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui[class*=\\\"tablet stackable\\\"].steps .step{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-radius:0;padding:1.14285714em 2em}.ui[class*=\\\"tablet stackable\\\"].steps .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui[class*=\\\"tablet stackable\\\"].steps .step:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"tablet stackable\\\"].steps .step:after{display:none!important}.ui[class*=\\\"tablet stackable\\\"].steps .step .content{text-align:center}.ui[class*=\\\"tablet stackable\\\"].ordered.steps .step:before,.ui[class*=\\\"tablet stackable\\\"].steps .step>.icon{margin:0 0 1rem 0}}.ui.fluid.steps{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%}.ui.attached.steps{width:calc(100% + 2px)!important;margin:0 -1px 0;max-width:calc(100% + 2px);border-radius:.28571429rem .28571429rem 0 0}.ui.attached.steps .step:first-child{border-radius:.28571429rem 0 0 0}.ui.attached.steps .step:last-child{border-radius:0 .28571429rem 0 0}.ui.bottom.attached.steps{margin:0 -1px 0;border-radius:0 0 .28571429rem .28571429rem}.ui.bottom.attached.steps .step:first-child{border-radius:0 0 0 .28571429rem}.ui.bottom.attached.steps .step:last-child{border-radius:0 0 .28571429rem 0}.ui.eight.steps,.ui.five.steps,.ui.four.steps,.ui.one.steps,.ui.seven.steps,.ui.six.steps,.ui.three.steps,.ui.two.steps{width:100%}.ui.eight.steps>.step,.ui.five.steps>.step,.ui.four.steps>.step,.ui.one.steps>.step,.ui.seven.steps>.step,.ui.six.steps>.step,.ui.three.steps>.step,.ui.two.steps>.step{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.ui.one.steps>.step{width:100%}.ui.two.steps>.step{width:50%}.ui.three.steps>.step{width:33.333%}.ui.four.steps>.step{width:25%}.ui.five.steps>.step{width:20%}.ui.six.steps>.step{width:16.666%}.ui.seven.steps>.step{width:14.285%}.ui.eight.steps>.step{width:12.5%}.ui.mini.step,.ui.mini.steps .step{font-size:.78571429rem}.ui.tiny.step,.ui.tiny.steps .step{font-size:.85714286rem}.ui.small.step,.ui.small.steps .step{font-size:.92857143rem}.ui.step,.ui.steps .step{font-size:1rem}.ui.large.step,.ui.large.steps .step{font-size:1.14285714rem}.ui.big.step,.ui.big.steps .step{font-size:1.28571429rem}.ui.huge.step,.ui.huge.steps .step{font-size:1.42857143rem}.ui.massive.step,.ui.massive.steps .step{font-size:1.71428571rem}@font-face{font-family:Step;src:url(data:application/x-font-ttf;charset=utf-8;;base64,AAEAAAAOAIAAAwBgT1MvMj3hSQEAAADsAAAAVmNtYXDQEhm3AAABRAAAAUpjdnQgBkn/lAAABuwAAAAcZnBnbYoKeDsAAAcIAAAJkWdhc3AAAAAQAAAG5AAAAAhnbHlm32cEdgAAApAAAAC2aGVhZAErPHsAAANIAAAANmhoZWEHUwNNAAADgAAAACRobXR4CykAAAAAA6QAAAAMbG9jYQA4AFsAAAOwAAAACG1heHAApgm8AAADuAAAACBuYW1lzJ0aHAAAA9gAAALNcG9zdK69QJgAAAaoAAAAO3ByZXCSoZr/AAAQnAAAAFYAAQO4AZAABQAIAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6ADoAQNS/2oAWgMLAE8AAAABAAAAAAAAAAAAAwAAAAMAAAAcAAEAAAAAAEQAAwABAAAAHAAEACgAAAAGAAQAAQACAADoAf//AAAAAOgA//8AABgBAAEAAAAAAAAAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAADpAKYABUAHEAZDwEAAQFCAAIBAmoAAQABagAAAGEUFxQDEisBFAcBBiInASY0PwE2Mh8BATYyHwEWA6QP/iAQLBD+6g8PTBAsEKQBbhAsEEwPAhYWEP4gDw8BFhAsEEwQEKUBbxAQTBAAAAH//f+xA18DCwAMABJADwABAQpDAAAACwBEFRMCESsBFA4BIi4CPgEyHgEDWXLG6MhuBnq89Lp+AV51xHR0xOrEdHTEAAAAAAEAAAABAADDeRpdXw889QALA+gAAAAAzzWYjQAAAADPNWBN//3/sQOkAwsAAAAIAAIAAAAAAAAAAQAAA1L/agBaA+gAAP/3A6QAAQAAAAAAAAAAAAAAAAAAAAMD6AAAA+gAAANZAAAAAAAAADgAWwABAAAAAwAWAAEAAAAAAAIABgATAG4AAAAtCZEAAAAAAAAAEgDeAAEAAAAAAAAANQAAAAEAAAAAAAEACAA1AAEAAAAAAAIABwA9AAEAAAAAAAMACABEAAEAAAAAAAQACABMAAEAAAAAAAUACwBUAAEAAAAAAAYACABfAAEAAAAAAAoAKwBnAAEAAAAAAAsAEwCSAAMAAQQJAAAAagClAAMAAQQJAAEAEAEPAAMAAQQJAAIADgEfAAMAAQQJAAMAEAEtAAMAAQQJAAQAEAE9AAMAAQQJAAUAFgFNAAMAAQQJAAYAEAFjAAMAAQQJAAoAVgFzAAMAAQQJAAsAJgHJQ29weXJpZ2h0IChDKSAyMDE0IGJ5IG9yaWdpbmFsIGF1dGhvcnMgQCBmb250ZWxsby5jb21mb250ZWxsb1JlZ3VsYXJmb250ZWxsb2ZvbnRlbGxvVmVyc2lvbiAxLjBmb250ZWxsb0dlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMQA0ACAAYgB5ACAAbwByAGkAZwBpAG4AYQBsACAAYQB1AHQAaABvAHIAcwAgAEAAIABmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQBmAG8AbgB0AGUAbABsAG8AUgBlAGcAdQBsAGEAcgBmAG8AbgB0AGUAbABsAG8AZgBvAG4AdABlAGwAbABvAFYAZQByAHMAaQBvAG4AIAAxAC4AMABmAG8AbgB0AGUAbABsAG8ARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAQIBAwljaGVja21hcmsGY2lyY2xlAAAAAAEAAf//AA8AAAAAAAAAAAAAAAAAAAAAADIAMgML/7EDC/+xsAAssCBgZi2wASwgZCCwwFCwBCZasARFW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCwCkVhZLAoUFghsApFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwACtZWSOwAFBYZVlZLbACLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbADLCMhIyEgZLEFYkIgsAYjQrIKAAIqISCwBkMgiiCKsAArsTAFJYpRWGBQG2FSWVgjWSEgsEBTWLAAKxshsEBZI7AAUFhlWS2wBCywB0MrsgACAENgQi2wBSywByNCIyCwACNCYbCAYrABYLAEKi2wBiwgIEUgsAJFY7ABRWJgRLABYC2wBywgIEUgsAArI7ECBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAgssQUFRbABYUQtsAkssAFgICCwCUNKsABQWCCwCSNCWbAKQ0qwAFJYILAKI0JZLbAKLCC4BABiILgEAGOKI2GwC0NgIIpgILALI0IjLbALLEtUWLEHAURZJLANZSN4LbAMLEtRWEtTWLEHAURZGyFZJLATZSN4LbANLLEADENVWLEMDEOwAWFCsAorWbAAQ7ACJUKxCQIlQrEKAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAJKiEjsAFhIIojYbAJKiEbsQEAQ2CwAiVCsAIlYbAJKiFZsAlDR7AKQ0dgsIBiILACRWOwAUViYLEAABMjRLABQ7AAPrIBAQFDYEItsA4ssQAFRVRYALAMI0IgYLABYbUNDQEACwBCQopgsQ0FK7BtKxsiWS2wDyyxAA4rLbAQLLEBDistsBEssQIOKy2wEiyxAw4rLbATLLEEDistsBQssQUOKy2wFSyxBg4rLbAWLLEHDistsBcssQgOKy2wGCyxCQ4rLbAZLLAIK7EABUVUWACwDCNCIGCwAWG1DQ0BAAsAQkKKYLENBSuwbSsbIlktsBossQAZKy2wGyyxARkrLbAcLLECGSstsB0ssQMZKy2wHiyxBBkrLbAfLLEFGSstsCAssQYZKy2wISyxBxkrLbAiLLEIGSstsCMssQkZKy2wJCwgPLABYC2wJSwgYLANYCBDI7ABYEOwAiVhsAFgsCQqIS2wJiywJSuwJSotsCcsICBHICCwAkVjsAFFYmAjYTgjIIpVWCBHICCwAkVjsAFFYmAjYTgbIVktsCgssQAFRVRYALABFrAnKrABFTAbIlktsCkssAgrsQAFRVRYALABFrAnKrABFTAbIlktsCosIDWwAWAtsCssALADRWOwAUVisAArsAJFY7ABRWKwACuwABa0AAAAAABEPiM4sSoBFSotsCwsIDwgRyCwAkVjsAFFYmCwAENhOC2wLSwuFzwtsC4sIDwgRyCwAkVjsAFFYmCwAENhsAFDYzgtsC8ssQIAFiUgLiBHsAAjQrACJUmKikcjRyNhIFhiGyFZsAEjQrIuAQEVFCotsDAssAAWsAQlsAQlRyNHI2GwBkUrZYouIyAgPIo4LbAxLLAAFrAEJbAEJSAuRyNHI2EgsAQjQrAGRSsgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjILAIQyCKI0cjRyNhI0ZgsARDsIBiYCCwACsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsIBiYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsIBiYCMgsAArI7AEQ2CwACuwBSVhsAUlsIBisAQmYSCwBCVgZCOwAyVgZFBYIRsjIVkjICCwBCYjRmE4WS2wMiywABYgICCwBSYgLkcjRyNhIzw4LbAzLLAAFiCwCCNCICAgRiNHsAArI2E4LbA0LLAAFrADJbACJUcjRyNhsABUWC4gPCMhG7ACJbACJUcjRyNhILAFJbAEJUcjRyNhsAYlsAUlSbACJWGwAUVjIyBYYhshWWOwAUViYCMuIyAgPIo4IyFZLbA1LLAAFiCwCEMgLkcjRyNhIGCwIGBmsIBiIyAgPIo4LbA2LCMgLkawAiVGUlggPFkusSYBFCstsDcsIyAuRrACJUZQWCA8WS6xJgEUKy2wOCwjIC5GsAIlRlJYIDxZIyAuRrACJUZQWCA8WS6xJgEUKy2wOSywMCsjIC5GsAIlRlJYIDxZLrEmARQrLbA6LLAxK4ogIDywBCNCijgjIC5GsAIlRlJYIDxZLrEmARQrsARDLrAmKy2wOyywABawBCWwBCYgLkcjRyNhsAZFKyMgPCAuIzixJgEUKy2wPCyxCAQlQrAAFrAEJbAEJSAuRyNHI2EgsAQjQrAGRSsgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjIEewBEOwgGJgILAAKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwgGJhsAIlRmE4IyA8IzgbISAgRiNHsAArI2E4IVmxJgEUKy2wPSywMCsusSYBFCstsD4ssDErISMgIDywBCNCIzixJgEUK7AEQy6wJistsD8ssAAVIEewACNCsgABARUUEy6wLCotsEAssAAVIEewACNCsgABARUUEy6wLCotsEEssQABFBOwLSotsEIssC8qLbBDLLAAFkUjIC4gRoojYTixJgEUKy2wRCywCCNCsEMrLbBFLLIAADwrLbBGLLIAATwrLbBHLLIBADwrLbBILLIBATwrLbBJLLIAAD0rLbBKLLIAAT0rLbBLLLIBAD0rLbBMLLIBAT0rLbBNLLIAADkrLbBOLLIAATkrLbBPLLIBADkrLbBQLLIBATkrLbBRLLIAADsrLbBSLLIAATsrLbBTLLIBADsrLbBULLIBATsrLbBVLLIAAD4rLbBWLLIAAT4rLbBXLLIBAD4rLbBYLLIBAT4rLbBZLLIAADorLbBaLLIAATorLbBbLLIBADorLbBcLLIBATorLbBdLLAyKy6xJgEUKy2wXiywMiuwNistsF8ssDIrsDcrLbBgLLAAFrAyK7A4Ky2wYSywMysusSYBFCstsGIssDMrsDYrLbBjLLAzK7A3Ky2wZCywMyuwOCstsGUssDQrLrEmARQrLbBmLLA0K7A2Ky2wZyywNCuwNystsGgssDQrsDgrLbBpLLA1Ky6xJgEUKy2waiywNSuwNistsGsssDUrsDcrLbBsLLA1K7A4Ky2wbSwrsAhlsAMkUHiwARUwLQAAAEu4AMhSWLEBAY5ZuQgACABjILABI0SwAyNwsgQoCUVSRLIKAgcqsQYBRLEkAYhRWLBAiFixBgNEsSYBiFFYuAQAiFixBgFEWVlZWbgB/4WwBI2xBQBEAAA=) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,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) format('woff')}.ui.ordered.steps .step.completed:before,.ui.steps .step.completed>.icon:before{font-family:Step;content:'\\\\e800'}/*!\\n * # Semantic UI 2.4.0 - Breadcrumb\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.breadcrumb{line-height:1;display:inline-block;margin:0 0;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.7;margin:0 .21428571rem 0;font-size:.92857143em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#4183c4}.ui.breadcrumb a:hover{color:#1e70bf}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.78571429em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.78571429rem}.ui.tiny.breadcrumb{font-size:.85714286rem}.ui.small.breadcrumb{font-size:.92857143rem}.ui.breadcrumb{font-size:1rem}.ui.large.breadcrumb{font-size:1.14285714rem}.ui.big.breadcrumb{font-size:1.28571429rem}.ui.huge.breadcrumb{font-size:1.42857143rem}.ui.massive.breadcrumb{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Form\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.form{position:relative;max-width:100%}.ui.form>p{margin:1em 0}.ui.form .field{clear:both;margin:0 0 1em}.ui.form .field:last-child,.ui.form .fields:last-child .field{margin-bottom:0}.ui.form .fields .field{clear:both;margin:0}.ui.form .field>label{display:block;margin:0 0 .28571429rem 0;color:rgba(0,0,0,.87);font-size:.92857143em;font-weight:700;text-transform:none}.ui.form input:not([type]),.ui.form input[type=date],.ui.form input[type=datetime-local],.ui.form input[type=email],.ui.form input[type=file],.ui.form input[type=number],.ui.form input[type=password],.ui.form input[type=search],.ui.form input[type=tel],.ui.form input[type=text],.ui.form input[type=time],.ui.form input[type=url],.ui.form textarea{width:100%;vertical-align:top}.ui.form ::-webkit-datetime-edit,.ui.form ::-webkit-inner-spin-button{height:1.21428571em}.ui.form input:not([type]),.ui.form input[type=date],.ui.form input[type=datetime-local],.ui.form input[type=email],.ui.form input[type=file],.ui.form input[type=number],.ui.form input[type=password],.ui.form input[type=search],.ui.form input[type=tel],.ui.form input[type=text],.ui.form input[type=time],.ui.form input[type=url]{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;margin:0;outline:0;-webkit-appearance:none;tap-highlight-color:rgba(255,255,255,0);line-height:1.21428571em;padding:.67857143em 1em;font-size:1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease}.ui.form textarea{margin:0;-webkit-appearance:none;tap-highlight-color:rgba(255,255,255,0);padding:.78571429em 1em;background:#fff;border:1px solid rgba(34,36,38,.15);outline:0;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease;font-size:1em;line-height:1.2857;resize:vertical}.ui.form textarea:not([rows]){height:12em;min-height:8em;max-height:24em}.ui.form input[type=checkbox],.ui.form textarea{vertical-align:top}.ui.form input.attached{width:auto}.ui.form select{display:block;height:auto;width:100%;background:#fff;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;padding:.62em 1em;color:rgba(0,0,0,.87);-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease}.ui.form .field>.selection.dropdown{width:100%}.ui.form .field>.selection.dropdown>.dropdown.icon{float:right}.ui.form .inline.field>.selection.dropdown,.ui.form .inline.fields .field>.selection.dropdown{width:auto}.ui.form .inline.field>.selection.dropdown>.dropdown.icon,.ui.form .inline.fields .field>.selection.dropdown>.dropdown.icon{float:none}.ui.form .field .ui.input,.ui.form .fields .field .ui.input,.ui.form .wide.field .ui.input{width:100%}.ui.form .inline.field:not(.wide) .ui.input,.ui.form .inline.fields .field:not(.wide) .ui.input{width:auto;vertical-align:middle}.ui.form .field .ui.input input,.ui.form .fields .field .ui.input input{width:auto}.ui.form .eight.fields .ui.input input,.ui.form .five.fields .ui.input input,.ui.form .four.fields .ui.input input,.ui.form .nine.fields .ui.input input,.ui.form .seven.fields .ui.input input,.ui.form .six.fields .ui.input input,.ui.form .ten.fields .ui.input input,.ui.form .three.fields .ui.input input,.ui.form .two.fields .ui.input input,.ui.form .wide.field .ui.input input{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;width:0}.ui.form .error.message,.ui.form .success.message,.ui.form .warning.message{display:none}.ui.form .message:first-child{margin-top:0}.ui.form .field .prompt.label{white-space:normal;background:#fff!important;border:1px solid #e0b4b4!important;color:#9f3a38!important}.ui.form .inline.field .prompt,.ui.form .inline.fields .field .prompt{vertical-align:top;margin:-.25em 0 -.5em .5em}.ui.form .inline.field .prompt:before,.ui.form .inline.fields .field .prompt:before{border-width:0 0 1px 1px;bottom:auto;right:auto;top:50%;left:0}.ui.form .field.field input:-webkit-autofill{-webkit-box-shadow:0 0 0 100px ivory inset!important;box-shadow:0 0 0 100px ivory inset!important;border-color:#e5dfa1!important}.ui.form .field.field input:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 100px ivory inset!important;box-shadow:0 0 0 100px ivory inset!important;border-color:#d5c315!important}.ui.form .error.error input:-webkit-autofill{-webkit-box-shadow:0 0 0 100px #fffaf0 inset!important;box-shadow:0 0 0 100px #fffaf0 inset!important;border-color:#e0b4b4!important}.ui.form ::-webkit-input-placeholder{color:rgba(191,191,191,.87)}.ui.form :-ms-input-placeholder{color:rgba(191,191,191,.87)!important}.ui.form ::-moz-placeholder{color:rgba(191,191,191,.87)}.ui.form :focus::-webkit-input-placeholder{color:rgba(115,115,115,.87)}.ui.form :focus:-ms-input-placeholder{color:rgba(115,115,115,.87)!important}.ui.form :focus::-moz-placeholder{color:rgba(115,115,115,.87)}.ui.form .error ::-webkit-input-placeholder{color:#e7bdbc}.ui.form .error :-ms-input-placeholder{color:#e7bdbc!important}.ui.form .error ::-moz-placeholder{color:#e7bdbc}.ui.form .error :focus::-webkit-input-placeholder{color:#da9796}.ui.form .error :focus:-ms-input-placeholder{color:#da9796!important}.ui.form .error :focus::-moz-placeholder{color:#da9796}.ui.form input:not([type]):focus,.ui.form input[type=date]:focus,.ui.form input[type=datetime-local]:focus,.ui.form input[type=email]:focus,.ui.form input[type=file]:focus,.ui.form input[type=number]:focus,.ui.form input[type=password]:focus,.ui.form input[type=search]:focus,.ui.form input[type=tel]:focus,.ui.form input[type=text]:focus,.ui.form input[type=time]:focus,.ui.form input[type=url]:focus{color:rgba(0,0,0,.95);border-color:#85b7d9;border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;box-shadow:0 0 0 0 rgba(34,36,38,.35) inset}.ui.form textarea:focus{color:rgba(0,0,0,.95);border-color:#85b7d9;border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;-webkit-appearance:none}.ui.form.success .success.message:not(:empty){display:block}.ui.form.success .compact.success.message:not(:empty){display:inline-block}.ui.form.success .icon.success.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form.warning .warning.message:not(:empty){display:block}.ui.form.warning .compact.warning.message:not(:empty){display:inline-block}.ui.form.warning .icon.warning.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form.error .error.message:not(:empty){display:block}.ui.form.error .compact.error.message:not(:empty){display:inline-block}.ui.form.error .icon.error.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form .field.error .input,.ui.form .field.error label,.ui.form .fields.error .field .input,.ui.form .fields.error .field label{color:#9f3a38}.ui.form .field.error .corner.label,.ui.form .fields.error .field .corner.label{border-color:#9f3a38;color:#fff}.ui.form .field.error input:not([type]),.ui.form .field.error input[type=date],.ui.form .field.error input[type=datetime-local],.ui.form .field.error input[type=email],.ui.form .field.error input[type=file],.ui.form .field.error input[type=number],.ui.form .field.error input[type=password],.ui.form .field.error input[type=search],.ui.form .field.error input[type=tel],.ui.form .field.error input[type=text],.ui.form .field.error input[type=time],.ui.form .field.error input[type=url],.ui.form .field.error select,.ui.form .field.error textarea,.ui.form .fields.error .field input:not([type]),.ui.form .fields.error .field input[type=date],.ui.form .fields.error .field input[type=datetime-local],.ui.form .fields.error .field input[type=email],.ui.form .fields.error .field input[type=file],.ui.form .fields.error .field input[type=number],.ui.form .fields.error .field input[type=password],.ui.form .fields.error .field input[type=search],.ui.form .fields.error .field input[type=tel],.ui.form .fields.error .field input[type=text],.ui.form .fields.error .field input[type=time],.ui.form .fields.error .field input[type=url],.ui.form .fields.error .field select,.ui.form .fields.error .field textarea{background:#fff6f6;border-color:#e0b4b4;color:#9f3a38;border-radius:'';-webkit-box-shadow:none;box-shadow:none}.ui.form .field.error input:not([type]):focus,.ui.form .field.error input[type=date]:focus,.ui.form .field.error input[type=datetime-local]:focus,.ui.form .field.error input[type=email]:focus,.ui.form .field.error input[type=file]:focus,.ui.form .field.error input[type=number]:focus,.ui.form .field.error input[type=password]:focus,.ui.form .field.error input[type=search]:focus,.ui.form .field.error input[type=tel]:focus,.ui.form .field.error input[type=text]:focus,.ui.form .field.error input[type=time]:focus,.ui.form .field.error input[type=url]:focus,.ui.form .field.error select:focus,.ui.form .field.error textarea:focus{background:#fff6f6;border-color:#e0b4b4;color:#9f3a38;-webkit-appearance:none;-webkit-box-shadow:none;box-shadow:none}.ui.form .field.error select{-webkit-appearance:menulist-button}.ui.form .field.error .ui.dropdown,.ui.form .field.error .ui.dropdown .item,.ui.form .field.error .ui.dropdown .text,.ui.form .fields.error .field .ui.dropdown,.ui.form .fields.error .field .ui.dropdown .item{background:#fff6f6;color:#9f3a38}.ui.form .field.error .ui.dropdown,.ui.form .fields.error .field .ui.dropdown{border-color:#e0b4b4!important}.ui.form .field.error .ui.dropdown:hover,.ui.form .fields.error .field .ui.dropdown:hover{border-color:#e0b4b4!important}.ui.form .field.error .ui.dropdown:hover .menu,.ui.form .fields.error .field .ui.dropdown:hover .menu{border-color:#e0b4b4}.ui.form .field.error .ui.multiple.selection.dropdown>.label,.ui.form .fields.error .field .ui.multiple.selection.dropdown>.label{background-color:#eacbcb;color:#9f3a38}.ui.form .field.error .ui.dropdown .menu .item:hover,.ui.form .fields.error .field .ui.dropdown .menu .item:hover{background-color:#fbe7e7}.ui.form .field.error .ui.dropdown .menu .selected.item,.ui.form .fields.error .field .ui.dropdown .menu .selected.item{background-color:#fbe7e7}.ui.form .field.error .ui.dropdown .menu .active.item,.ui.form .fields.error .field .ui.dropdown .menu .active.item{background-color:#fdcfcf!important}.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box,.ui.form .field.error .checkbox:not(.toggle):not(.slider) label,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) label{color:#9f3a38}.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box:before,.ui.form .field.error .checkbox:not(.toggle):not(.slider) label:before,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box:before,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) label:before{background:#fff6f6;border-color:#e0b4b4}.ui.form .field.error .checkbox .box:after,.ui.form .field.error .checkbox label:after,.ui.form .fields.error .field .checkbox .box:after,.ui.form .fields.error .field .checkbox label:after{color:#9f3a38}.ui.form .disabled.field,.ui.form .disabled.fields .field,.ui.form .field :disabled{pointer-events:none;opacity:.45}.ui.form .field.disabled>label,.ui.form .fields.disabled>label{opacity:.45}.ui.form .field.disabled :disabled{opacity:1}.ui.loading.form{position:relative;cursor:default;pointer-events:none}.ui.loading.form:before{position:absolute;content:'';top:0;left:0;background:rgba(255,255,255,.8);width:100%;height:100%;z-index:100}.ui.loading.form:after{position:absolute;content:'';top:50%;left:50%;margin:-1.5em 0 0 -1.5em;width:3em;height:3em;-webkit-animation:form-spin .6s linear;animation:form-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.1);border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;visibility:visible;z-index:101}@-webkit-keyframes form-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes form-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.form .required.field>.checkbox:after,.ui.form .required.field>label:after,.ui.form .required.fields.grouped>label:after,.ui.form .required.fields:not(.grouped)>.field>.checkbox:after,.ui.form .required.fields:not(.grouped)>.field>label:after{margin:-.2em 0 0 .2em;content:'*';color:#db2828}.ui.form .required.field>label:after,.ui.form .required.fields.grouped>label:after,.ui.form .required.fields:not(.grouped)>.field>label:after{display:inline-block;vertical-align:top}.ui.form .required.field>.checkbox:after,.ui.form .required.fields:not(.grouped)>.field>.checkbox:after{position:absolute;top:0;left:100%}.ui.form .inverted.segment .ui.checkbox .box,.ui.form .inverted.segment .ui.checkbox label,.ui.form .inverted.segment label,.ui.inverted.form .inline.field>label,.ui.inverted.form .inline.field>p,.ui.inverted.form .inline.fields .field>label,.ui.inverted.form .inline.fields .field>p,.ui.inverted.form .inline.fields>label,.ui.inverted.form .ui.checkbox .box,.ui.inverted.form .ui.checkbox label,.ui.inverted.form label{color:rgba(255,255,255,.9)}.ui.inverted.form input:not([type]),.ui.inverted.form input[type=date],.ui.inverted.form input[type=datetime-local],.ui.inverted.form input[type=email],.ui.inverted.form input[type=file],.ui.inverted.form input[type=number],.ui.inverted.form input[type=password],.ui.inverted.form input[type=search],.ui.inverted.form input[type=tel],.ui.inverted.form input[type=text],.ui.inverted.form input[type=time],.ui.inverted.form input[type=url]{background:#fff;border-color:rgba(255,255,255,.1);color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}.ui.form .grouped.fields{display:block;margin:0 0 1em}.ui.form .grouped.fields:last-child{margin-bottom:0}.ui.form .grouped.fields>label{margin:0 0 .28571429rem 0;color:rgba(0,0,0,.87);font-size:.92857143em;font-weight:700;text-transform:none}.ui.form .grouped.fields .field,.ui.form .grouped.inline.fields .field{display:block;margin:.5em 0;padding:0}.ui.form .fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin:0 -.5em 1em}.ui.form .fields>.field{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;padding-left:.5em;padding-right:.5em}.ui.form .fields>.field:first-child{border-left:none;-webkit-box-shadow:none;box-shadow:none}.ui.form .two.fields>.field,.ui.form .two.fields>.fields{width:50%}.ui.form .three.fields>.field,.ui.form .three.fields>.fields{width:33.33333333%}.ui.form .four.fields>.field,.ui.form .four.fields>.fields{width:25%}.ui.form .five.fields>.field,.ui.form .five.fields>.fields{width:20%}.ui.form .six.fields>.field,.ui.form .six.fields>.fields{width:16.66666667%}.ui.form .seven.fields>.field,.ui.form .seven.fields>.fields{width:14.28571429%}.ui.form .eight.fields>.field,.ui.form .eight.fields>.fields{width:12.5%}.ui.form .nine.fields>.field,.ui.form .nine.fields>.fields{width:11.11111111%}.ui.form .ten.fields>.field,.ui.form .ten.fields>.fields{width:10%}@media only screen and (max-width:767px){.ui.form .fields{-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.form:not(.unstackable) .eight.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .eight.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .nine.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .nine.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .seven.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .seven.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .six.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .six.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .ten.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .ten.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) [class*=\\\"equal width\\\"].fields:not(.unstackable)>.field,.ui[class*=\\\"equal width\\\"].form:not(.unstackable) .fields>.field{width:100%!important;margin:0 0 1em}}.ui.form .fields .wide.field{width:6.25%;padding-left:.5em;padding-right:.5em}.ui.form .one.wide.field{width:6.25%!important}.ui.form .two.wide.field{width:12.5%!important}.ui.form .three.wide.field{width:18.75%!important}.ui.form .four.wide.field{width:25%!important}.ui.form .five.wide.field{width:31.25%!important}.ui.form .six.wide.field{width:37.5%!important}.ui.form .seven.wide.field{width:43.75%!important}.ui.form .eight.wide.field{width:50%!important}.ui.form .nine.wide.field{width:56.25%!important}.ui.form .ten.wide.field{width:62.5%!important}.ui.form .eleven.wide.field{width:68.75%!important}.ui.form .twelve.wide.field{width:75%!important}.ui.form .thirteen.wide.field{width:81.25%!important}.ui.form .fourteen.wide.field{width:87.5%!important}.ui.form .fifteen.wide.field{width:93.75%!important}.ui.form .sixteen.wide.field{width:100%!important}@media only screen and (max-width:767px){.ui.form:not(.unstackable) .fields:not(.unstackable)>.eight.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.eleven.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.fifteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.five.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.four.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.fourteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.nine.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.seven.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.six.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.sixteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.ten.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.thirteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.three.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.twelve.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.two.wide.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.fields{width:100%!important}.ui.form .fields{margin-bottom:0}}.ui.form [class*=\\\"equal width\\\"].fields>.field,.ui[class*=\\\"equal width\\\"].form .fields>.field{width:100%;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.ui.form .inline.fields{margin:0 0 1em;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.form .inline.fields .field{margin:0;padding:0 1em 0 0}.ui.form .inline.field>label,.ui.form .inline.field>p,.ui.form .inline.fields .field>label,.ui.form .inline.fields .field>p,.ui.form .inline.fields>label{display:inline-block;width:auto;margin-top:0;margin-bottom:0;vertical-align:baseline;font-size:.92857143em;font-weight:700;color:rgba(0,0,0,.87);text-transform:none}.ui.form .inline.fields>label{margin:.035714em 1em 0 0}.ui.form .inline.field>input,.ui.form .inline.field>select,.ui.form .inline.fields .field>input,.ui.form .inline.fields .field>select{display:inline-block;width:auto;margin-top:0;margin-bottom:0;vertical-align:middle;font-size:1em}.ui.form .inline.field>:first-child,.ui.form .inline.fields .field>:first-child{margin:0 .85714286em 0 0}.ui.form .inline.field>:only-child,.ui.form .inline.fields .field>:only-child{margin:0}.ui.form .inline.fields .wide.field{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.form .inline.fields .wide.field>input,.ui.form .inline.fields .wide.field>select{width:100%}.ui.mini.form{font-size:.78571429rem}.ui.tiny.form{font-size:.85714286rem}.ui.small.form{font-size:.92857143rem}.ui.form{font-size:1rem}.ui.large.form{font-size:1.14285714rem}.ui.big.form{font-size:1.28571429rem}.ui.huge.form{font-size:1.42857143rem}.ui.massive.form{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Grid\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.grid{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;padding:0}.ui.grid{margin-top:-1rem;margin-bottom:-1rem;margin-left:-1rem;margin-right:-1rem}.ui.relaxed.grid{margin-left:-1.5rem;margin-right:-1.5rem}.ui[class*=\\\"very relaxed\\\"].grid{margin-left:-2.5rem;margin-right:-2.5rem}.ui.grid+.grid{margin-top:1rem}.ui.grid>.column:not(.row),.ui.grid>.row>.column{position:relative;display:inline-block;width:6.25%;padding-left:1rem;padding-right:1rem;vertical-align:top}.ui.grid>*{padding-left:1rem;padding-right:1rem}.ui.grid>.row{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:inherit;-ms-flex-pack:inherit;justify-content:inherit;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%!important;padding:0;padding-top:1rem;padding-bottom:1rem}.ui.grid>.column:not(.row){padding-top:1rem;padding-bottom:1rem}.ui.grid>.row>.column{margin-top:0;margin-bottom:0}.ui.grid>.row>.column>img,.ui.grid>.row>img{max-width:100%}.ui.grid>.ui.grid:first-child{margin-top:0}.ui.grid>.ui.grid:last-child{margin-bottom:0}.ui.aligned.grid .column>.segment:not(.compact):not(.attached),.ui.grid .aligned.row>.column>.segment:not(.compact):not(.attached){width:100%}.ui.grid .row+.ui.divider{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;margin:1rem 1rem}.ui.grid .column+.ui.vertical.divider{height:calc(50% - 1rem)}.ui.grid>.column:last-child>.horizontal.segment,.ui.grid>.row>.column:last-child>.horizontal.segment{-webkit-box-shadow:none;box-shadow:none}@media only screen and (max-width:767px){.ui.page.grid{width:auto;padding-left:0;padding-right:0;margin-left:0;margin-right:0}}@media only screen and (min-width:768px) and (max-width:991px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:2em;padding-right:2em}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:3%;padding-right:3%}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:15%;padding-right:15%}}@media only screen and (min-width:1920px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:23%;padding-right:23%}}.ui.grid>.column:only-child,.ui.grid>.row>.column:only-child{width:100%}.ui[class*=\\\"one column\\\"].grid>.column:not(.row),.ui[class*=\\\"one column\\\"].grid>.row>.column{width:100%}.ui[class*=\\\"two column\\\"].grid>.column:not(.row),.ui[class*=\\\"two column\\\"].grid>.row>.column{width:50%}.ui[class*=\\\"three column\\\"].grid>.column:not(.row),.ui[class*=\\\"three column\\\"].grid>.row>.column{width:33.33333333%}.ui[class*=\\\"four column\\\"].grid>.column:not(.row),.ui[class*=\\\"four column\\\"].grid>.row>.column{width:25%}.ui[class*=\\\"five column\\\"].grid>.column:not(.row),.ui[class*=\\\"five column\\\"].grid>.row>.column{width:20%}.ui[class*=\\\"six column\\\"].grid>.column:not(.row),.ui[class*=\\\"six column\\\"].grid>.row>.column{width:16.66666667%}.ui[class*=\\\"seven column\\\"].grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].grid>.row>.column{width:14.28571429%}.ui[class*=\\\"eight column\\\"].grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].grid>.row>.column{width:12.5%}.ui[class*=\\\"nine column\\\"].grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].grid>.row>.column{width:11.11111111%}.ui[class*=\\\"ten column\\\"].grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].grid>.row>.column{width:10%}.ui[class*=\\\"eleven column\\\"].grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].grid>.row>.column{width:9.09090909%}.ui[class*=\\\"twelve column\\\"].grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].grid>.row>.column{width:8.33333333%}.ui[class*=\\\"thirteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].grid>.row>.column{width:7.69230769%}.ui[class*=\\\"fourteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].grid>.row>.column{width:7.14285714%}.ui[class*=\\\"fifteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].grid>.row>.column{width:6.66666667%}.ui[class*=\\\"sixteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].grid>.row>.column{width:6.25%}.ui.grid>[class*=\\\"one column\\\"].row>.column{width:100%!important}.ui.grid>[class*=\\\"two column\\\"].row>.column{width:50%!important}.ui.grid>[class*=\\\"three column\\\"].row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"four column\\\"].row>.column{width:25%!important}.ui.grid>[class*=\\\"five column\\\"].row>.column{width:20%!important}.ui.grid>[class*=\\\"six column\\\"].row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"seven column\\\"].row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"eight column\\\"].row>.column{width:12.5%!important}.ui.grid>[class*=\\\"nine column\\\"].row>.column{width:11.11111111%!important}.ui.grid>[class*=\\\"ten column\\\"].row>.column{width:10%!important}.ui.grid>[class*=\\\"eleven column\\\"].row>.column{width:9.09090909%!important}.ui.grid>[class*=\\\"twelve column\\\"].row>.column{width:8.33333333%!important}.ui.grid>[class*=\\\"thirteen column\\\"].row>.column{width:7.69230769%!important}.ui.grid>[class*=\\\"fourteen column\\\"].row>.column{width:7.14285714%!important}.ui.grid>[class*=\\\"fifteen column\\\"].row>.column{width:6.66666667%!important}.ui.grid>[class*=\\\"sixteen column\\\"].row>.column{width:6.25%!important}.ui.celled.page.grid{-webkit-box-shadow:none;box-shadow:none}.ui.column.grid>[class*=\\\"one wide\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide\\\"].column,.ui.grid>.row>[class*=\\\"one wide\\\"].column,.ui.grid>[class*=\\\"one wide\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide\\\"].column,.ui.grid>.row>[class*=\\\"two wide\\\"].column,.ui.grid>[class*=\\\"two wide\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide\\\"].column,.ui.grid>.row>[class*=\\\"three wide\\\"].column,.ui.grid>[class*=\\\"three wide\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide\\\"].column,.ui.grid>.row>[class*=\\\"four wide\\\"].column,.ui.grid>[class*=\\\"four wide\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide\\\"].column,.ui.grid>.row>[class*=\\\"five wide\\\"].column,.ui.grid>[class*=\\\"five wide\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide\\\"].column,.ui.grid>.row>[class*=\\\"six wide\\\"].column,.ui.grid>[class*=\\\"six wide\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide\\\"].column,.ui.grid>.row>[class*=\\\"seven wide\\\"].column,.ui.grid>[class*=\\\"seven wide\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide\\\"].column,.ui.grid>.row>[class*=\\\"eight wide\\\"].column,.ui.grid>[class*=\\\"eight wide\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide\\\"].column,.ui.grid>.row>[class*=\\\"nine wide\\\"].column,.ui.grid>[class*=\\\"nine wide\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide\\\"].column,.ui.grid>.row>[class*=\\\"ten wide\\\"].column,.ui.grid>[class*=\\\"ten wide\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide\\\"].column,.ui.grid>[class*=\\\"eleven wide\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide\\\"].column,.ui.grid>[class*=\\\"twelve wide\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide\\\"].column,.ui.grid>[class*=\\\"thirteen wide\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide\\\"].column,.ui.grid>[class*=\\\"fourteen wide\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide\\\"].column,.ui.grid>[class*=\\\"fifteen wide\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide\\\"].column,.ui.grid>[class*=\\\"sixteen wide\\\"].column{width:100%!important}@media only screen and (min-width:320px) and (max-width:767px){.ui.column.grid>[class*=\\\"one wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"one wide mobile\\\"].column,.ui.grid>[class*=\\\"one wide mobile\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"two wide mobile\\\"].column,.ui.grid>[class*=\\\"two wide mobile\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"three wide mobile\\\"].column,.ui.grid>[class*=\\\"three wide mobile\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"four wide mobile\\\"].column,.ui.grid>[class*=\\\"four wide mobile\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"five wide mobile\\\"].column,.ui.grid>[class*=\\\"five wide mobile\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"six wide mobile\\\"].column,.ui.grid>[class*=\\\"six wide mobile\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>[class*=\\\"seven wide mobile\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>[class*=\\\"eight wide mobile\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>[class*=\\\"nine wide mobile\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>[class*=\\\"ten wide mobile\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>[class*=\\\"eleven wide mobile\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>[class*=\\\"twelve wide mobile\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>[class*=\\\"thirteen wide mobile\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>[class*=\\\"fourteen wide mobile\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>[class*=\\\"fifteen wide mobile\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>[class*=\\\"sixteen wide mobile\\\"].column{width:100%!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.column.grid>[class*=\\\"one wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"one wide tablet\\\"].column,.ui.grid>[class*=\\\"one wide tablet\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"two wide tablet\\\"].column,.ui.grid>[class*=\\\"two wide tablet\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"three wide tablet\\\"].column,.ui.grid>[class*=\\\"three wide tablet\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"four wide tablet\\\"].column,.ui.grid>[class*=\\\"four wide tablet\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"five wide tablet\\\"].column,.ui.grid>[class*=\\\"five wide tablet\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"six wide tablet\\\"].column,.ui.grid>[class*=\\\"six wide tablet\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>[class*=\\\"seven wide tablet\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>[class*=\\\"eight wide tablet\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>[class*=\\\"nine wide tablet\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>[class*=\\\"ten wide tablet\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>[class*=\\\"eleven wide tablet\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>[class*=\\\"twelve wide tablet\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>[class*=\\\"thirteen wide tablet\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>[class*=\\\"fourteen wide tablet\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>[class*=\\\"fifteen wide tablet\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>[class*=\\\"sixteen wide tablet\\\"].column{width:100%!important}}@media only screen and (min-width:992px){.ui.column.grid>[class*=\\\"one wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide computer\\\"].column,.ui.grid>.row>[class*=\\\"one wide computer\\\"].column,.ui.grid>[class*=\\\"one wide computer\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide computer\\\"].column,.ui.grid>.row>[class*=\\\"two wide computer\\\"].column,.ui.grid>[class*=\\\"two wide computer\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide computer\\\"].column,.ui.grid>.row>[class*=\\\"three wide computer\\\"].column,.ui.grid>[class*=\\\"three wide computer\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide computer\\\"].column,.ui.grid>.row>[class*=\\\"four wide computer\\\"].column,.ui.grid>[class*=\\\"four wide computer\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide computer\\\"].column,.ui.grid>.row>[class*=\\\"five wide computer\\\"].column,.ui.grid>[class*=\\\"five wide computer\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide computer\\\"].column,.ui.grid>.row>[class*=\\\"six wide computer\\\"].column,.ui.grid>[class*=\\\"six wide computer\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide computer\\\"].column,.ui.grid>.row>[class*=\\\"seven wide computer\\\"].column,.ui.grid>[class*=\\\"seven wide computer\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide computer\\\"].column,.ui.grid>.row>[class*=\\\"eight wide computer\\\"].column,.ui.grid>[class*=\\\"eight wide computer\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide computer\\\"].column,.ui.grid>.row>[class*=\\\"nine wide computer\\\"].column,.ui.grid>[class*=\\\"nine wide computer\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide computer\\\"].column,.ui.grid>.row>[class*=\\\"ten wide computer\\\"].column,.ui.grid>[class*=\\\"ten wide computer\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>[class*=\\\"eleven wide computer\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>[class*=\\\"twelve wide computer\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>[class*=\\\"thirteen wide computer\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>[class*=\\\"fourteen wide computer\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>[class*=\\\"fifteen wide computer\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>[class*=\\\"sixteen wide computer\\\"].column{width:100%!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.column.grid>[class*=\\\"one wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"one wide large screen\\\"].column,.ui.grid>[class*=\\\"one wide large screen\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"two wide large screen\\\"].column,.ui.grid>[class*=\\\"two wide large screen\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"three wide large screen\\\"].column,.ui.grid>[class*=\\\"three wide large screen\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"four wide large screen\\\"].column,.ui.grid>[class*=\\\"four wide large screen\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"five wide large screen\\\"].column,.ui.grid>[class*=\\\"five wide large screen\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"six wide large screen\\\"].column,.ui.grid>[class*=\\\"six wide large screen\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>[class*=\\\"seven wide large screen\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>[class*=\\\"eight wide large screen\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>[class*=\\\"nine wide large screen\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>[class*=\\\"ten wide large screen\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>[class*=\\\"eleven wide large screen\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>[class*=\\\"twelve wide large screen\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>[class*=\\\"thirteen wide large screen\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>[class*=\\\"fourteen wide large screen\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>[class*=\\\"fifteen wide large screen\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>[class*=\\\"sixteen wide large screen\\\"].column{width:100%!important}}@media only screen and (min-width:1920px){.ui.column.grid>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>[class*=\\\"one wide widescreen\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>[class*=\\\"two wide widescreen\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>[class*=\\\"three wide widescreen\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>[class*=\\\"four wide widescreen\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>[class*=\\\"five wide widescreen\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>[class*=\\\"six wide widescreen\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>[class*=\\\"seven wide widescreen\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>[class*=\\\"eight wide widescreen\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>[class*=\\\"nine wide widescreen\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>[class*=\\\"ten wide widescreen\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>[class*=\\\"eleven wide widescreen\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>[class*=\\\"twelve wide widescreen\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"thirteen wide widescreen\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"fourteen wide widescreen\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"fifteen wide widescreen\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"sixteen wide widescreen\\\"].column{width:100%!important}}.ui.centered.grid,.ui.centered.grid>.row,.ui.grid>.centered.row{text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.centered.grid>.column:not(.aligned):not(.justified):not(.row),.ui.centered.grid>.row>.column:not(.aligned):not(.justified),.ui.grid .centered.row>.column:not(.aligned):not(.justified){text-align:left}.ui.grid>.centered.column,.ui.grid>.row>.centered.column{display:block;margin-left:auto;margin-right:auto}.ui.grid>.relaxed.row>.column,.ui.relaxed.grid>.column:not(.row),.ui.relaxed.grid>.row>.column{padding-left:1.5rem;padding-right:1.5rem}.ui.grid>[class*=\\\"very relaxed\\\"].row>.column,.ui[class*=\\\"very relaxed\\\"].grid>.column:not(.row),.ui[class*=\\\"very relaxed\\\"].grid>.row>.column{padding-left:2.5rem;padding-right:2.5rem}.ui.grid .relaxed.row+.ui.divider,.ui.relaxed.grid .row+.ui.divider{margin-left:1.5rem;margin-right:1.5rem}.ui.grid [class*=\\\"very relaxed\\\"].row+.ui.divider,.ui[class*=\\\"very relaxed\\\"].grid .row+.ui.divider{margin-left:2.5rem;margin-right:2.5rem}.ui.padded.grid:not(.vertically):not(.horizontally){margin:0!important}[class*=\\\"horizontally padded\\\"].ui.grid{margin-left:0!important;margin-right:0!important}[class*=\\\"vertically padded\\\"].ui.grid{margin-top:0!important;margin-bottom:0!important}.ui.grid [class*=\\\"left floated\\\"].column{margin-right:auto}.ui.grid [class*=\\\"right floated\\\"].column{margin-left:auto}.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row),.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"vertically divided\\\"].grid>.column:not(.row),.ui[class*=\\\"vertically divided\\\"].grid>.row>.column{margin-top:1rem;margin-bottom:1rem;padding-top:0;padding-bottom:0}.ui[class*=\\\"vertically divided\\\"].grid>.row{margin-top:0;margin-bottom:0}.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"vertically divided\\\"].grid>.row:first-child>.column{margin-top:0}.ui.grid>.divided.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui.grid>.divided.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"vertically divided\\\"].grid>.row{position:relative}.ui[class*=\\\"vertically divided\\\"].grid>.row:before{position:absolute;content:\\\"\\\";top:0;left:0;width:calc(100% - 2rem);height:1px;margin:0 1rem;-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.padded.divided.grid:not(.vertically):not(.horizontally),[class*=\\\"horizontally padded\\\"].ui.divided.grid{width:100%}.ui[class*=\\\"vertically divided\\\"].grid>.row:first-child:before{-webkit-box-shadow:none;box-shadow:none}.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row),.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(255,255,255,.1);box-shadow:-1px 0 0 0 rgba(255,255,255,.1)}.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row):first-child,.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.inverted[class*=\\\"vertically divided\\\"].grid>.row:before{-webkit-box-shadow:0 -1px 0 0 rgba(255,255,255,.1);box-shadow:0 -1px 0 0 rgba(255,255,255,.1)}.ui.relaxed[class*=\\\"vertically divided\\\"].grid>.row:before{margin-left:1.5rem;margin-right:1.5rem;width:calc(100% - 3rem)}.ui[class*=\\\"very relaxed\\\"][class*=\\\"vertically divided\\\"].grid>.row:before{margin-left:5rem;margin-right:5rem;width:calc(100% - 5rem)}.ui.celled.grid{width:100%;margin:1em 0;-webkit-box-shadow:0 0 0 1px #d4d4d5;box-shadow:0 0 0 1px #d4d4d5}.ui.celled.grid>.row{width:100%!important;margin:0;padding:0;-webkit-box-shadow:0 -1px 0 0 #d4d4d5;box-shadow:0 -1px 0 0 #d4d4d5}.ui.celled.grid>.column:not(.row),.ui.celled.grid>.row>.column{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui.celled.grid>.column:first-child,.ui.celled.grid>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.celled.grid>.column:not(.row),.ui.celled.grid>.row>.column{padding:1em}.ui.relaxed.celled.grid>.column:not(.row),.ui.relaxed.celled.grid>.row>.column{padding:1.5em}.ui[class*=\\\"very relaxed\\\"].celled.grid>.column:not(.row),.ui[class*=\\\"very relaxed\\\"].celled.grid>.row>.column{padding:2em}.ui[class*=\\\"internally celled\\\"].grid{-webkit-box-shadow:none;box-shadow:none;margin:0}.ui[class*=\\\"internally celled\\\"].grid>.row:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"internally celled\\\"].grid>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid>.row>[class*=\\\"top aligned\\\"].column,.ui.grid>[class*=\\\"top aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"top aligned\\\"].row>.column,.ui[class*=\\\"top aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"top aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:top;-ms-flex-item-align:start!important;align-self:flex-start!important}.ui.grid>.row>[class*=\\\"middle aligned\\\"].column,.ui.grid>[class*=\\\"middle aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"middle aligned\\\"].row>.column,.ui[class*=\\\"middle aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"middle aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:middle;-ms-flex-item-align:center!important;align-self:center!important}.ui.grid>.row>[class*=\\\"bottom aligned\\\"].column,.ui.grid>[class*=\\\"bottom aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"bottom aligned\\\"].row>.column,.ui[class*=\\\"bottom aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"bottom aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:bottom;-ms-flex-item-align:end!important;align-self:flex-end!important}.ui.grid>.row>.stretched.column,.ui.grid>.stretched.column:not(.row),.ui.grid>.stretched.row>.column,.ui.stretched.grid>.column,.ui.stretched.grid>.row>.column{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important;-ms-flex-item-align:stretch;align-self:stretch;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.grid>.row>.stretched.column>*,.ui.grid>.stretched.column:not(.row)>*,.ui.grid>.stretched.row>.column>*,.ui.stretched.grid>.column>*,.ui.stretched.grid>.row>.column>*{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.ui.grid>.row>[class*=\\\"left aligned\\\"].column.column,.ui.grid>[class*=\\\"left aligned\\\"].column.column,.ui.grid>[class*=\\\"left aligned\\\"].row>.column,.ui[class*=\\\"left aligned\\\"].grid>.column,.ui[class*=\\\"left aligned\\\"].grid>.row>.column{text-align:left;-ms-flex-item-align:inherit;align-self:inherit}.ui.grid>.row>[class*=\\\"center aligned\\\"].column.column,.ui.grid>[class*=\\\"center aligned\\\"].column.column,.ui.grid>[class*=\\\"center aligned\\\"].row>.column,.ui[class*=\\\"center aligned\\\"].grid>.column,.ui[class*=\\\"center aligned\\\"].grid>.row>.column{text-align:center;-ms-flex-item-align:inherit;align-self:inherit}.ui[class*=\\\"center aligned\\\"].grid{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.grid>.row>[class*=\\\"right aligned\\\"].column.column,.ui.grid>[class*=\\\"right aligned\\\"].column.column,.ui.grid>[class*=\\\"right aligned\\\"].row>.column,.ui[class*=\\\"right aligned\\\"].grid>.column,.ui[class*=\\\"right aligned\\\"].grid>.row>.column{text-align:right;-ms-flex-item-align:inherit;align-self:inherit}.ui.grid>.justified.column.column,.ui.grid>.justified.row>.column,.ui.grid>.row>.justified.column.column,.ui.justified.grid>.column,.ui.justified.grid>.row>.column{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.ui.grid>.row>.black.column,.ui.grid>.row>.blue.column,.ui.grid>.row>.brown.column,.ui.grid>.row>.green.column,.ui.grid>.row>.grey.column,.ui.grid>.row>.olive.column,.ui.grid>.row>.orange.column,.ui.grid>.row>.pink.column,.ui.grid>.row>.purple.column,.ui.grid>.row>.red.column,.ui.grid>.row>.teal.column,.ui.grid>.row>.violet.column,.ui.grid>.row>.yellow.column{margin-top:-1rem;margin-bottom:-1rem;padding-top:1rem;padding-bottom:1rem}.ui.grid>.red.column,.ui.grid>.red.row,.ui.grid>.row>.red.column{background-color:#db2828!important;color:#fff}.ui.grid>.orange.column,.ui.grid>.orange.row,.ui.grid>.row>.orange.column{background-color:#f2711c!important;color:#fff}.ui.grid>.row>.yellow.column,.ui.grid>.yellow.column,.ui.grid>.yellow.row{background-color:#fbbd08!important;color:#fff}.ui.grid>.olive.column,.ui.grid>.olive.row,.ui.grid>.row>.olive.column{background-color:#b5cc18!important;color:#fff}.ui.grid>.green.column,.ui.grid>.green.row,.ui.grid>.row>.green.column{background-color:#21ba45!important;color:#fff}.ui.grid>.row>.teal.column,.ui.grid>.teal.column,.ui.grid>.teal.row{background-color:#00b5ad!important;color:#fff}.ui.grid>.blue.column,.ui.grid>.blue.row,.ui.grid>.row>.blue.column{background-color:#2185d0!important;color:#fff}.ui.grid>.row>.violet.column,.ui.grid>.violet.column,.ui.grid>.violet.row{background-color:#6435c9!important;color:#fff}.ui.grid>.purple.column,.ui.grid>.purple.row,.ui.grid>.row>.purple.column{background-color:#a333c8!important;color:#fff}.ui.grid>.pink.column,.ui.grid>.pink.row,.ui.grid>.row>.pink.column{background-color:#e03997!important;color:#fff}.ui.grid>.brown.column,.ui.grid>.brown.row,.ui.grid>.row>.brown.column{background-color:#a5673f!important;color:#fff}.ui.grid>.grey.column,.ui.grid>.grey.row,.ui.grid>.row>.grey.column{background-color:#767676!important;color:#fff}.ui.grid>.black.column,.ui.grid>.black.row,.ui.grid>.row>.black.column{background-color:#1b1c1d!important;color:#fff}.ui.grid>[class*=\\\"equal width\\\"].row>.column,.ui[class*=\\\"equal width\\\"].grid>.column:not(.row),.ui[class*=\\\"equal width\\\"].grid>.row>.column{display:inline-block;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.ui.grid>[class*=\\\"equal width\\\"].row>.wide.column,.ui[class*=\\\"equal width\\\"].grid>.row>.wide.column,.ui[class*=\\\"equal width\\\"].grid>.wide.column{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}@media only screen and (max-width:767px){.ui.grid>[class*=\\\"mobile reversed\\\"].row,.ui[class*=\\\"mobile reversed\\\"].grid,.ui[class*=\\\"mobile reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui.stackable[class*=\\\"mobile reversed\\\"],.ui[class*=\\\"mobile vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"mobile vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"mobile vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"mobile reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"mobile reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:768px) and (max-width:991px){.ui.grid>[class*=\\\"tablet reversed\\\"].row,.ui[class*=\\\"tablet reversed\\\"].grid,.ui[class*=\\\"tablet reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui[class*=\\\"tablet vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"tablet vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"tablet vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"tablet reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"tablet reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:992px){.ui.grid>[class*=\\\"computer reversed\\\"].row,.ui[class*=\\\"computer reversed\\\"].grid,.ui[class*=\\\"computer reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui[class*=\\\"computer vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"computer vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"computer vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"computer reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"computer reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:768px) and (max-width:991px){.ui.doubling.grid{width:auto}.ui.doubling.grid>.row,.ui.grid>.doubling.row{margin:0!important;padding:0!important}.ui.doubling.grid>.row>.column,.ui.grid>.doubling.row>.column{display:inline-block!important;padding-top:1rem!important;padding-bottom:1rem!important;-webkit-box-shadow:none!important;box-shadow:none!important;margin:0}.ui.grid>[class*=\\\"two column\\\"].doubling.row.row>.column,.ui[class*=\\\"two column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"two column\\\"].doubling.grid>.row>.column{width:100%!important}.ui.grid>[class*=\\\"three column\\\"].doubling.row.row>.column,.ui[class*=\\\"three column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"three column\\\"].doubling.grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"four column\\\"].doubling.row.row>.column,.ui[class*=\\\"four column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"four column\\\"].doubling.grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"five column\\\"].doubling.row.row>.column,.ui[class*=\\\"five column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"five column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"six column\\\"].doubling.row.row>.column,.ui[class*=\\\"six column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"six column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"seven column\\\"].doubling.row.row>.column,.ui[class*=\\\"seven column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"eight column\\\"].doubling.row.row>.column,.ui[class*=\\\"eight column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].doubling.grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"nine column\\\"].doubling.row.row>.column,.ui[class*=\\\"nine column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].doubling.grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"ten column\\\"].doubling.row.row>.column,.ui[class*=\\\"ten column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].doubling.grid>.row>.column{width:20%!important}.ui.grid>[class*=\\\"eleven column\\\"].doubling.row.row>.column,.ui[class*=\\\"eleven column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].doubling.grid>.row>.column{width:20%!important}.ui.grid>[class*=\\\"twelve column\\\"].doubling.row.row>.column,.ui[class*=\\\"twelve column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].doubling.grid>.row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"thirteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"thirteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].doubling.grid>.row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"fourteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"fourteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].doubling.grid>.row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"fifteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"fifteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].doubling.grid>.row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"sixteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"sixteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].doubling.grid>.row>.column{width:12.5%!important}}@media only screen and (max-width:767px){.ui.doubling.grid>.row,.ui.grid>.doubling.row{margin:0!important;padding:0!important}.ui.doubling.grid>.row>.column,.ui.grid>.doubling.row>.column{padding-top:1rem!important;padding-bottom:1rem!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.grid>[class*=\\\"two column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"two column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"two column\\\"].doubling:not(.stackable).grid>.row>.column{width:100%!important}.ui.grid>[class*=\\\"three column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"three column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"three column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"four column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"four column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"four column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"five column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"five column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"five column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"six column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"six column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"six column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"seven column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"seven column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"eight column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"eight column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"nine column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"nine column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"ten column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"ten column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"eleven column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"eleven column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"twelve column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"twelve column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"thirteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"thirteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"fourteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"fourteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"fifteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"fifteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"sixteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"sixteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}}@media only screen and (max-width:767px){.ui.stackable.grid{width:auto;margin-left:0!important;margin-right:0!important}.ui.grid>.stackable.stackable.row>.column,.ui.stackable.grid>.column.grid>.column,.ui.stackable.grid>.column.row>.column,.ui.stackable.grid>.column:not(.row),.ui.stackable.grid>.row>.column,.ui.stackable.grid>.row>.wide.column,.ui.stackable.grid>.wide.column{width:100%!important;margin:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important;padding:1rem 1rem!important}.ui.stackable.grid:not(.vertically)>.row{margin:0;padding:0}.ui.container>.ui.stackable.grid>.column,.ui.container>.ui.stackable.grid>.row>.column{padding-left:0!important;padding-right:0!important}.ui.grid .ui.stackable.grid,.ui.segment:not(.vertical) .ui.stackable.page.grid{margin-left:-1rem!important;margin-right:-1rem!important}.ui.stackable.celled.grid>.column:not(.row):first-child,.ui.stackable.celled.grid>.row:first-child>.column:first-child,.ui.stackable.divided.grid>.column:not(.row):first-child,.ui.stackable.divided.grid>.row:first-child>.column:first-child{border-top:none!important}.ui.inverted.stackable.celled.grid>.column:not(.row),.ui.inverted.stackable.celled.grid>.row>.column,.ui.inverted.stackable.divided.grid>.column:not(.row),.ui.inverted.stackable.divided.grid>.row>.column{border-top:1px solid rgba(255,255,255,.1)}.ui.stackable.celled.grid>.column:not(.row),.ui.stackable.celled.grid>.row>.column,.ui.stackable.divided:not(.vertically).grid>.column:not(.row),.ui.stackable.divided:not(.vertically).grid>.row>.column{border-top:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none!important;box-shadow:none!important;padding-top:2rem!important;padding-bottom:2rem!important}.ui.stackable.celled.grid>.row{-webkit-box-shadow:none!important;box-shadow:none!important}.ui.stackable.divided:not(.vertically).grid>.column:not(.row),.ui.stackable.divided:not(.vertically).grid>.row>.column{padding-left:0!important;padding-right:0!important}}@media only screen and (max-width:767px){.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.mobile),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"computer only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].row:not(.mobile),.ui[class*=\\\"computer only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.tablet),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.tablet){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"computer only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].row:not(.tablet),.ui[class*=\\\"computer only\\\"].grid.grid.grid:not(.tablet){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:1920px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}}.ui.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1rem 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;background:#fff;font-weight:400;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);border-radius:.28571429rem;min-height:2.85714286em}.ui.menu:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.menu:first-child{margin-top:0}.ui.menu:last-child{margin-bottom:0}.ui.menu .menu{margin:0}.ui.menu:not(.vertical)>.menu{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.menu:not(.vertical) .item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.menu .item{position:relative;vertical-align:middle;line-height:1;text-decoration:none;-webkit-tap-highlight-color:transparent;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:0 0;padding:.92857143em 1.14285714em;text-transform:none;color:rgba(0,0,0,.87);font-weight:400;-webkit-transition:background .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background .1s ease,box-shadow .1s ease,color .1s ease;transition:background .1s ease,box-shadow .1s ease,color .1s ease,-webkit-box-shadow .1s ease}.ui.menu>.item:first-child{border-radius:.28571429rem 0 0 .28571429rem}.ui.menu .item:before{position:absolute;content:'';top:0;right:0;height:100%;width:1px;background:rgba(34,36,38,.1)}.ui.menu .item>a:not(.ui),.ui.menu .item>p:only-child,.ui.menu .text.item>*{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;line-height:1.3}.ui.menu .item>p:first-child{margin-top:0}.ui.menu .item>p:last-child{margin-bottom:0}.ui.menu .item>i.icon{opacity:.9;float:none;margin:0 .35714286em 0 0}.ui.menu:not(.vertical) .item>.button{position:relative;top:0;margin:-.5em 0;padding-bottom:.78571429em;padding-top:.78571429em;font-size:1em}.ui.menu>.container,.ui.menu>.grid{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:inherit;-ms-flex-align:inherit;align-items:inherit;-webkit-box-orient:inherit;-webkit-box-direction:inherit;-ms-flex-direction:inherit;flex-direction:inherit}.ui.menu .item>.input{width:100%}.ui.menu:not(.vertical) .item>.input{position:relative;top:0;margin:-.5em 0}.ui.menu .item>.input input{font-size:1em;padding-top:.57142857em;padding-bottom:.57142857em}.ui.menu .header.item,.ui.vertical.menu .header.item{margin:0;background:'';text-transform:normal;font-weight:700}.ui.vertical.menu .item>.header:not(.ui){margin:0 0 .5em;font-size:1em;font-weight:700}.ui.menu .item>i.dropdown.icon{padding:0;float:right;margin:0 0 0 1em}.ui.menu .dropdown.item .menu{min-width:calc(100% - 1px);border-radius:0 0 .28571429rem .28571429rem;background:#fff;margin:0 0 0;-webkit-box-shadow:0 1px 3px 0 rgba(0,0,0,.08);box-shadow:0 1px 3px 0 rgba(0,0,0,.08);-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.ui.menu .ui.dropdown .menu>.item{margin:0;text-align:left;font-size:1em!important;padding:.78571429em 1.14285714em!important;background:0 0!important;color:rgba(0,0,0,.87)!important;text-transform:none!important;font-weight:400!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-transition:none!important;transition:none!important}.ui.menu .ui.dropdown .menu>.item:hover{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown .menu>.selected.item{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown .menu>.active.item{background:rgba(0,0,0,.03)!important;font-weight:700!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown.item .menu .item:not(.filtered){display:block}.ui.menu .ui.dropdown .menu>.item .icon:not(.dropdown){display:inline-block;font-size:1em!important;float:none;margin:0 .75em 0 0!important}.ui.secondary.menu .dropdown.item>.menu,.ui.text.menu .dropdown.item>.menu{border-radius:.28571429rem;margin-top:.35714286em}.ui.menu .pointing.dropdown.item .menu{margin-top:.75em}.ui.inverted.menu .search.dropdown.item>.search,.ui.inverted.menu .search.dropdown.item>.text{color:rgba(255,255,255,.9)}.ui.vertical.menu .dropdown.item>.icon{float:right;content:\\\"\\\\f0da\\\";margin-left:1em}.ui.vertical.menu .dropdown.item .menu{left:100%;min-width:0;margin:0;-webkit-box-shadow:0 1px 3px 0 rgba(0,0,0,.08);box-shadow:0 1px 3px 0 rgba(0,0,0,.08);border-radius:0 .28571429rem .28571429rem .28571429rem}.ui.vertical.menu .dropdown.item.upward .menu{bottom:0}.ui.vertical.menu .dropdown.item:not(.upward) .menu{top:0}.ui.vertical.menu .active.dropdown.item{border-top-right-radius:0;border-bottom-right-radius:0}.ui.vertical.menu .dropdown.active.item{-webkit-box-shadow:none;box-shadow:none}.ui.item.menu .dropdown .menu .item{width:100%}.ui.menu .item>.label{background:#999;color:#fff;margin-left:1em;padding:.3em .78571429em}.ui.vertical.menu .item>.label{background:#999;color:#fff;margin-top:-.15em;margin-bottom:-.15em;padding:.3em .78571429em}.ui.menu .item>.floating.label{padding:.3em .78571429em}.ui.menu .item>img:not(.ui){display:inline-block;vertical-align:middle;margin:-.3em 0;width:2.5em}.ui.vertical.menu .item>img:not(.ui):only-child{display:block;max-width:100%;width:auto}.ui.menu .list .item:before{background:0 0!important}.ui.vertical.sidebar.menu>.item:first-child:before{display:block!important}.ui.vertical.sidebar.menu>.item::before{top:auto;bottom:0}@media only screen and (max-width:767px){.ui.menu>.ui.container{width:100%!important;margin-left:0!important;margin-right:0!important}}@media only screen and (min-width:768px){.ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless)>.container>.item:not(.right):not(.borderless):first-child{border-left:1px solid rgba(34,36,38,.1)}}.ui.link.menu .item:hover,.ui.menu .dropdown.item:hover,.ui.menu .link.item:hover,.ui.menu a.item:hover{cursor:pointer;background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.link.menu .item:active,.ui.menu .link.item:active,.ui.menu a.item:active{background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.menu .active.item{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);font-weight:400;-webkit-box-shadow:none;box-shadow:none}.ui.menu .active.item>i.icon{opacity:1}.ui.menu .active.item:hover,.ui.vertical.menu .active.item:hover{background-color:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.menu .item.disabled,.ui.menu .item.disabled:hover{cursor:default!important;background-color:transparent!important;color:rgba(40,40,40,.3)!important}.ui.menu:not(.vertical) .left.item,.ui.menu:not(.vertical) :not(.dropdown)>.left.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin-right:auto!important}.ui.menu:not(.vertical) .right.item,.ui.menu:not(.vertical) .right.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin-left:auto!important}.ui.menu .right.item::before,.ui.menu .right.menu>.item::before{right:auto;left:0}.ui.vertical.menu{display:block;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15)}.ui.vertical.menu .item{display:block;background:0 0;border-top:none;border-right:none}.ui.vertical.menu>.item:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.menu>.item:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.menu .item>.label{float:right;text-align:center}.ui.vertical.menu .item>i.icon{width:1.18em;float:right;margin:0 0 0 .5em}.ui.vertical.menu .item>.label+i.icon{float:none;margin:0 .5em 0 0}.ui.vertical.menu .item:before{position:absolute;content:'';top:0;left:0;width:100%;height:1px;background:rgba(34,36,38,.1)}.ui.vertical.menu .item:first-child:before{display:none!important}.ui.vertical.menu .item>.menu{margin:.5em -1.14285714em 0}.ui.vertical.menu .menu .item{background:0 0;padding:.5em 1.33333333em;font-size:.85714286em;color:rgba(0,0,0,.5)}.ui.vertical.menu .item .menu .link.item:hover,.ui.vertical.menu .item .menu a.item:hover{color:rgba(0,0,0,.85)}.ui.vertical.menu .menu .item:before{display:none}.ui.vertical.menu .active.item{background:rgba(0,0,0,.05);border-radius:0;-webkit-box-shadow:none;box-shadow:none}.ui.vertical.menu>.active.item:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.menu>.active.item:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.menu>.active.item:only-child{border-radius:.28571429rem}.ui.vertical.menu .active.item .menu .active.item{border-left:none}.ui.vertical.menu .item .menu .active.item{background-color:transparent;font-weight:700;color:rgba(0,0,0,.95)}.ui.tabular.menu{border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border:none;background:none transparent;border-bottom:1px solid #d4d4d5}.ui.tabular.fluid.menu{width:calc(100% + 2px)!important}.ui.tabular.menu .item{background:0 0;border-bottom:none;border-left:1px solid transparent;border-right:1px solid transparent;border-top:2px solid transparent;padding:.92857143em 1.42857143em;color:rgba(0,0,0,.87)}.ui.tabular.menu .item:before{display:none}.ui.tabular.menu .item:hover{background-color:transparent;color:rgba(0,0,0,.8)}.ui.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-top-width:1px;border-color:#d4d4d5;font-weight:700;margin-bottom:-1px;-webkit-box-shadow:none;box-shadow:none;border-radius:.28571429rem .28571429rem 0 0!important}.ui.tabular.menu+.attached:not(.top).segment,.ui.tabular.menu+.attached:not(.top).segment+.attached:not(.top).segment{border-top:none;margin-left:0;margin-top:0;margin-right:0;width:100%}.top.attached.segment+.ui.bottom.tabular.menu{position:relative;width:calc(100% + 2px);left:-1px}.ui.bottom.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-top:1px solid #d4d4d5}.ui.bottom.tabular.menu .item{background:0 0;border-left:1px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-top:none}.ui.bottom.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:-1px 0 0 0;border-radius:0 0 .28571429rem .28571429rem!important}.ui.vertical.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-right:1px solid #d4d4d5}.ui.vertical.tabular.menu .item{background:0 0;border-left:1px solid transparent;border-bottom:1px solid transparent;border-top:1px solid transparent;border-right:none}.ui.vertical.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:0 -1px 0 0;border-radius:.28571429rem 0 0 .28571429rem!important}.ui.vertical.right.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-right:none;border-left:1px solid #d4d4d5}.ui.vertical.right.tabular.menu .item{background:0 0;border-right:1px solid transparent;border-bottom:1px solid transparent;border-top:1px solid transparent;border-left:none}.ui.vertical.right.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:0 0 0 -1px;border-radius:0 .28571429rem .28571429rem 0!important}.ui.tabular.menu .active.dropdown.item{margin-bottom:0;border-left:1px solid transparent;border-right:1px solid transparent;border-top:2px solid transparent;border-bottom:none}.ui.pagination.menu{margin:0;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.ui.pagination.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.compact.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.pagination.menu .item:last-child:before{display:none}.ui.pagination.menu .item{min-width:3em;text-align:center}.ui.pagination.menu .icon.item i.icon{vertical-align:top}.ui.pagination.menu .active.item{border-top:none;padding-top:.92857143em;background-color:rgba(0,0,0,.05);color:rgba(0,0,0,.95);-webkit-box-shadow:none;box-shadow:none}.ui.secondary.menu{background:0 0;margin-left:-.35714286em;margin-right:-.35714286em;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none}.ui.secondary.menu .item{-ms-flex-item-align:center;align-self:center;-webkit-box-shadow:none;box-shadow:none;border:none;padding:.78571429em .92857143em;margin:0 .35714286em;background:0 0;-webkit-transition:color .1s ease;transition:color .1s ease;border-radius:.28571429rem}.ui.secondary.menu .item:before{display:none!important}.ui.secondary.menu .header.item{border-radius:0;border-right:none;background:none transparent}.ui.secondary.menu .item>img:not(.ui){margin:0}.ui.secondary.menu .dropdown.item:hover,.ui.secondary.menu .link.item:hover,.ui.secondary.menu a.item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.secondary.menu .active.item{-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);border-radius:.28571429rem}.ui.secondary.menu .active.item:hover{-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.secondary.inverted.menu .link.item,.ui.secondary.inverted.menu a.item{color:rgba(255,255,255,.7)!important}.ui.secondary.inverted.menu .dropdown.item:hover,.ui.secondary.inverted.menu .link.item:hover,.ui.secondary.inverted.menu a.item:hover{background:rgba(255,255,255,.08);color:#fff!important}.ui.secondary.inverted.menu .active.item{background:rgba(255,255,255,.15);color:#fff!important}.ui.secondary.item.menu{margin-left:0;margin-right:0}.ui.secondary.item.menu .item:last-child{margin-right:0}.ui.secondary.attached.menu{-webkit-box-shadow:none;box-shadow:none}.ui.vertical.secondary.menu .item:not(.dropdown)>.menu{margin:0 -.92857143em}.ui.vertical.secondary.menu .item:not(.dropdown)>.menu>.item{margin:0;padding:.5em 1.33333333em}.ui.secondary.vertical.menu>.item{border:none;margin:0 0 .35714286em;border-radius:.28571429rem!important}.ui.secondary.vertical.menu>.header.item{border-radius:0}.ui.vertical.secondary.menu .item>.menu .item{background-color:transparent}.ui.secondary.inverted.menu{background-color:transparent}.ui.secondary.pointing.menu{margin-left:0;margin-right:0;border-bottom:2px solid rgba(34,36,38,.15)}.ui.secondary.pointing.menu .item{border-bottom-color:transparent;border-bottom-style:solid;border-radius:0;-ms-flex-item-align:end;align-self:flex-end;margin:0 0 -2px;padding:.85714286em 1.14285714em;border-bottom-width:2px;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.secondary.pointing.menu .header.item{color:rgba(0,0,0,.85)!important}.ui.secondary.pointing.menu .text.item{-webkit-box-shadow:none!important;box-shadow:none!important}.ui.secondary.pointing.menu .item:after{display:none}.ui.secondary.pointing.menu .dropdown.item:hover,.ui.secondary.pointing.menu .link.item:hover,.ui.secondary.pointing.menu a.item:hover{background-color:transparent;color:rgba(0,0,0,.87)}.ui.secondary.pointing.menu .dropdown.item:active,.ui.secondary.pointing.menu .link.item:active,.ui.secondary.pointing.menu a.item:active{background-color:transparent;border-color:rgba(34,36,38,.15)}.ui.secondary.pointing.menu .active.item{background-color:transparent;-webkit-box-shadow:none;box-shadow:none;border-color:#1b1c1d;font-weight:700;color:rgba(0,0,0,.95)}.ui.secondary.pointing.menu .active.item:hover{border-color:#1b1c1d;color:rgba(0,0,0,.95)}.ui.secondary.pointing.menu .active.dropdown.item{border-color:transparent}.ui.secondary.vertical.pointing.menu{border-bottom-width:0;border-right-width:2px;border-right-style:solid;border-right-color:rgba(34,36,38,.15)}.ui.secondary.vertical.pointing.menu .item{border-bottom:none;border-right-style:solid;border-right-color:transparent;border-radius:0!important;margin:0 -2px 0 0;border-right-width:2px}.ui.secondary.vertical.pointing.menu .active.item{border-color:#1b1c1d}.ui.secondary.inverted.pointing.menu{border-color:rgba(255,255,255,.1)}.ui.secondary.inverted.pointing.menu{border-width:2px;border-color:rgba(34,36,38,.15)}.ui.secondary.inverted.pointing.menu .item{color:rgba(255,255,255,.9)}.ui.secondary.inverted.pointing.menu .header.item{color:#fff!important}.ui.secondary.inverted.pointing.menu .link.item:hover,.ui.secondary.inverted.pointing.menu a.item:hover{color:rgba(0,0,0,.95)}.ui.secondary.inverted.pointing.menu .active.item{border-color:#fff;color:#fff}.ui.text.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none;box-shadow:none;border:none;margin:1em -.5em}.ui.text.menu .item{border-radius:0;-webkit-box-shadow:none;box-shadow:none;-ms-flex-item-align:center;align-self:center;margin:0 0;padding:.35714286em .5em;font-weight:400;color:rgba(0,0,0,.6);-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.text.menu .item:before,.ui.text.menu .menu .item:before{display:none!important}.ui.text.menu .header.item{background-color:transparent;opacity:1;color:rgba(0,0,0,.85);font-size:.92857143em;text-transform:uppercase;font-weight:700}.ui.text.menu .item>img:not(.ui){margin:0}.ui.text.item.menu .item{margin:0}.ui.vertical.text.menu{margin:1em 0}.ui.vertical.text.menu:first-child{margin-top:0}.ui.vertical.text.menu:last-child{margin-bottom:0}.ui.vertical.text.menu .item{margin:.57142857em 0;padding-left:0;padding-right:0}.ui.vertical.text.menu .item>i.icon{float:none;margin:0 .35714286em 0 0}.ui.vertical.text.menu .header.item{margin:.57142857em 0 .71428571em}.ui.vertical.text.menu .item:not(.dropdown)>.menu{margin:0}.ui.vertical.text.menu .item:not(.dropdown)>.menu>.item{margin:0;padding:.5em 0}.ui.text.menu .item:hover{opacity:1;background-color:transparent}.ui.text.menu .active.item{background-color:transparent;border:none;-webkit-box-shadow:none;box-shadow:none;font-weight:400;color:rgba(0,0,0,.95)}.ui.text.menu .active.item:hover{background-color:transparent}.ui.text.pointing.menu .active.item:after{-webkit-box-shadow:none;box-shadow:none}.ui.text.attached.menu{-webkit-box-shadow:none;box-shadow:none}.ui.inverted.text.menu,.ui.inverted.text.menu .active.item,.ui.inverted.text.menu .item,.ui.inverted.text.menu .item:hover{background-color:transparent!important}.ui.fluid.text.menu{margin-left:0;margin-right:0}.ui.vertical.icon.menu{display:inline-block;width:auto}.ui.icon.menu .item{height:auto;text-align:center;color:#1b1c1d}.ui.icon.menu .item>.icon:not(.dropdown){margin:0;opacity:1}.ui.icon.menu .icon:before{opacity:1}.ui.menu .icon.item>.icon{width:auto;margin:0 auto}.ui.vertical.icon.menu .item>.icon:not(.dropdown){display:block;opacity:1;margin:0 auto;float:none}.ui.inverted.icon.menu .item{color:#fff}.ui.labeled.icon.menu{text-align:center}.ui.labeled.icon.menu .item{min-width:6em;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.labeled.icon.menu .item>.icon:not(.dropdown){height:1em;display:block;font-size:1.71428571em!important;margin:0 auto .5rem!important}.ui.fluid.labeled.icon.menu>.item{min-width:0}@media only screen and (max-width:767px){.ui.stackable.menu{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.stackable.menu .item{width:100%!important}.ui.stackable.menu .item:before{position:absolute;content:'';top:auto;bottom:0;left:0;width:100%;height:1px;background:rgba(34,36,38,.1)}.ui.stackable.menu .left.item,.ui.stackable.menu .left.menu{margin-right:0!important}.ui.stackable.menu .right.item,.ui.stackable.menu .right.menu{margin-left:0!important}.ui.stackable.menu .left.menu,.ui.stackable.menu .right.menu{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.ui.menu .red.active.item,.ui.red.menu .active.item{border-color:#db2828!important;color:#db2828!important}.ui.menu .orange.active.item,.ui.orange.menu .active.item{border-color:#f2711c!important;color:#f2711c!important}.ui.menu .yellow.active.item,.ui.yellow.menu .active.item{border-color:#fbbd08!important;color:#fbbd08!important}.ui.menu .olive.active.item,.ui.olive.menu .active.item{border-color:#b5cc18!important;color:#b5cc18!important}.ui.green.menu .active.item,.ui.menu .green.active.item{border-color:#21ba45!important;color:#21ba45!important}.ui.menu .teal.active.item,.ui.teal.menu .active.item{border-color:#00b5ad!important;color:#00b5ad!important}.ui.blue.menu .active.item,.ui.menu .blue.active.item{border-color:#2185d0!important;color:#2185d0!important}.ui.menu .violet.active.item,.ui.violet.menu .active.item{border-color:#6435c9!important;color:#6435c9!important}.ui.menu .purple.active.item,.ui.purple.menu .active.item{border-color:#a333c8!important;color:#a333c8!important}.ui.menu .pink.active.item,.ui.pink.menu .active.item{border-color:#e03997!important;color:#e03997!important}.ui.brown.menu .active.item,.ui.menu .brown.active.item{border-color:#a5673f!important;color:#a5673f!important}.ui.grey.menu .active.item,.ui.menu .grey.active.item{border-color:#767676!important;color:#767676!important}.ui.inverted.menu{border:0 solid transparent;background:#1b1c1d;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.menu .item,.ui.inverted.menu .item>a:not(.ui){background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.menu .item.menu{background:0 0}.ui.inverted.menu .item:before{background:rgba(255,255,255,.08)}.ui.vertical.inverted.menu .item:before{background:rgba(255,255,255,.08)}.ui.vertical.inverted.menu .menu .item,.ui.vertical.inverted.menu .menu .item a:not(.ui){color:rgba(255,255,255,.5)}.ui.inverted.menu .header.item{margin:0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.menu .item.disabled,.ui.inverted.menu .item.disabled:hover{color:rgba(225,225,225,.3)}.ui.inverted.menu .dropdown.item:hover,.ui.inverted.menu .link.item:hover,.ui.inverted.menu a.item:hover,.ui.link.inverted.menu .item:hover{background:rgba(255,255,255,.08);color:#fff}.ui.vertical.inverted.menu .item .menu .link.item:hover,.ui.vertical.inverted.menu .item .menu a.item:hover{background:0 0;color:#fff}.ui.inverted.menu .link.item:active,.ui.inverted.menu a.item:active{background:rgba(255,255,255,.08);color:#fff}.ui.inverted.menu .active.item{background:rgba(255,255,255,.15);color:#fff!important}.ui.inverted.vertical.menu .item .menu .active.item{background:0 0;color:#fff}.ui.inverted.pointing.menu .active.item:after{background:#3d3e3f!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;border:none!important}.ui.inverted.menu .active.item:hover{background:rgba(255,255,255,.15);color:#fff!important}.ui.inverted.pointing.menu .active.item:hover:after{background:#3d3e3f!important}.ui.floated.menu{float:left;margin:0 .5rem 0 0}.ui.floated.menu .item:last-child:before{display:none}.ui.right.floated.menu{float:right;margin:0 0 0 .5rem}.ui.inverted.menu .red.active.item,.ui.inverted.red.menu{background-color:#db2828}.ui.inverted.red.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.red.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .orange.active.item,.ui.inverted.orange.menu{background-color:#f2711c}.ui.inverted.orange.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.orange.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .yellow.active.item,.ui.inverted.yellow.menu{background-color:#fbbd08}.ui.inverted.yellow.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.yellow.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .olive.active.item,.ui.inverted.olive.menu{background-color:#b5cc18}.ui.inverted.olive.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.olive.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.green.menu,.ui.inverted.menu .green.active.item{background-color:#21ba45}.ui.inverted.green.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.green.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .teal.active.item,.ui.inverted.teal.menu{background-color:#00b5ad}.ui.inverted.teal.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.teal.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.blue.menu,.ui.inverted.menu .blue.active.item{background-color:#2185d0}.ui.inverted.blue.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.blue.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .violet.active.item,.ui.inverted.violet.menu{background-color:#6435c9}.ui.inverted.violet.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.violet.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .purple.active.item,.ui.inverted.purple.menu{background-color:#a333c8}.ui.inverted.purple.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.purple.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .pink.active.item,.ui.inverted.pink.menu{background-color:#e03997}.ui.inverted.pink.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.pink.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.brown.menu,.ui.inverted.menu .brown.active.item{background-color:#a5673f}.ui.inverted.brown.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.brown.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.grey.menu,.ui.inverted.menu .grey.active.item{background-color:#767676}.ui.inverted.grey.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.grey.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.fitted.menu .item,.ui.fitted.menu .item .menu .item,.ui.menu .fitted.item{padding:0}.ui.horizontally.fitted.menu .item,.ui.horizontally.fitted.menu .item .menu .item,.ui.menu .horizontally.fitted.item{padding-top:.92857143em;padding-bottom:.92857143em}.ui.menu .vertically.fitted.item,.ui.vertically.fitted.menu .item,.ui.vertically.fitted.menu .item .menu .item{padding-left:1.14285714em;padding-right:1.14285714em}.ui.borderless.menu .item .menu .item:before,.ui.borderless.menu .item:before,.ui.menu .borderless.item:before{background:0 0!important}.ui.compact.menu{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin:0;vertical-align:middle}.ui.compact.vertical.menu{display:inline-block}.ui.compact.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.compact.menu .item:last-child:before{display:none}.ui.compact.vertical.menu{width:auto!important}.ui.compact.vertical.menu .item:last-child::before{display:block}.ui.menu.fluid,.ui.vertical.menu.fluid{width:100%!important}.ui.item.menu,.ui.item.menu .item{width:100%;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important;text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.attached.item.menu{margin:0 -1px!important}.ui.item.menu .item:last-child:before{display:none}.ui.menu.two.item .item{width:50%}.ui.menu.three.item .item{width:33.333%}.ui.menu.four.item .item{width:25%}.ui.menu.five.item .item{width:20%}.ui.menu.six.item .item{width:16.666%}.ui.menu.seven.item .item{width:14.285%}.ui.menu.eight.item .item{width:12.5%}.ui.menu.nine.item .item{width:11.11%}.ui.menu.ten.item .item{width:10%}.ui.menu.eleven.item .item{width:9.09%}.ui.menu.twelve.item .item{width:8.333%}.ui.menu.fixed{position:fixed;z-index:101;margin:0;width:100%}.ui.menu.fixed,.ui.menu.fixed .item:first-child,.ui.menu.fixed .item:last-child{border-radius:0!important}.ui.fixed.menu,.ui[class*=\\\"top fixed\\\"].menu{top:0;left:0;right:auto;bottom:auto}.ui[class*=\\\"top fixed\\\"].menu{border-top:none;border-left:none;border-right:none}.ui[class*=\\\"right fixed\\\"].menu{border-top:none;border-bottom:none;border-right:none;top:0;right:0;left:auto;bottom:auto;width:auto;height:100%}.ui[class*=\\\"bottom fixed\\\"].menu{border-bottom:none;border-left:none;border-right:none;bottom:0;left:0;top:auto;right:auto}.ui[class*=\\\"left fixed\\\"].menu{border-top:none;border-bottom:none;border-left:none;top:0;left:0;right:auto;bottom:auto;width:auto;height:100%}.ui.fixed.menu+.ui.grid{padding-top:2.75rem}.ui.pointing.menu .item:after{visibility:hidden;position:absolute;content:'';top:100%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);background:0 0;margin:.5px 0 0;width:.57142857em;height:.57142857em;border:none;border-bottom:1px solid #d4d4d5;border-right:1px solid #d4d4d5;z-index:2;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.vertical.pointing.menu .item:after{position:absolute;top:50%;right:0;bottom:auto;left:auto;-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg);margin:0 -.5px 0 0;border:none;border-top:1px solid #d4d4d5;border-right:1px solid #d4d4d5}.ui.pointing.menu .active.item:after{visibility:visible}.ui.pointing.menu .active.dropdown.item:after{visibility:hidden}.ui.pointing.menu .active.item .menu .active.item:after,.ui.pointing.menu .dropdown.active.item:after{display:none}.ui.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.pointing.menu .active.item:after{background-color:#f2f2f2}.ui.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .active.item:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .menu .active.item:after{background-color:#fff}.ui.attached.menu{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none}.ui.attached+.ui.attached.menu:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].menu{bottom:0;margin-bottom:0;top:0;margin-top:1rem;border-radius:.28571429rem .28571429rem 0 0}.ui.menu[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui[class*=\\\"bottom attached\\\"].menu{bottom:0;margin-top:0;top:0;margin-bottom:1rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].menu:last-child{margin-bottom:0}.ui.top.attached.menu>.item:first-child{border-radius:.28571429rem 0 0 0}.ui.bottom.attached.menu>.item:first-child{border-radius:0 0 0 .28571429rem}.ui.attached.menu:not(.tabular){border:1px solid #d4d4d5}.ui.attached.inverted.menu{border:none}.ui.attached.tabular.menu{margin-left:0;margin-right:0;width:100%}.ui.mini.menu{font-size:.78571429rem}.ui.mini.vertical.menu{width:9rem}.ui.tiny.menu{font-size:.85714286rem}.ui.tiny.vertical.menu{width:11rem}.ui.small.menu{font-size:.92857143rem}.ui.small.vertical.menu{width:13rem}.ui.menu{font-size:1rem}.ui.vertical.menu{width:15rem}.ui.large.menu{font-size:1.07142857rem}.ui.large.vertical.menu{width:18rem}.ui.huge.menu{font-size:1.21428571rem}.ui.huge.vertical.menu{width:22rem}.ui.big.menu{font-size:1.14285714rem}.ui.big.vertical.menu{width:20rem}.ui.massive.menu{font-size:1.28571429rem}.ui.massive.vertical.menu{width:25rem}/*!\\n * # Semantic UI 2.4.0 - Message\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.message{position:relative;min-height:1em;margin:1em 0;background:#f8f8f9;padding:1em 1.5em;line-height:1.4285em;color:rgba(0,0,0,.87);-webkit-transition:opacity .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease;border-radius:.28571429rem;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 0 0 0 transparent;box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 0 0 0 transparent}.ui.message:first-child{margin-top:0}.ui.message:last-child{margin-bottom:0}.ui.message .header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;margin:-.14285714em 0 0 0}.ui.message .header:not(.ui){font-size:1.14285714em}.ui.message p{opacity:.85;margin:.75em 0}.ui.message p:first-child{margin-top:0}.ui.message p:last-child{margin-bottom:0}.ui.message .header+p{margin-top:.25em}.ui.message .list:not(.ui){text-align:left;padding:0;opacity:.85;list-style-position:inside;margin:.5em 0 0}.ui.message .list:not(.ui):first-child{margin-top:0}.ui.message .list:not(.ui):last-child{margin-bottom:0}.ui.message .list:not(.ui) li{position:relative;list-style-type:none;margin:0 0 .3em 1em;padding:0}.ui.message .list:not(.ui) li:before{position:absolute;content:'•';left:-1em;height:100%;vertical-align:baseline}.ui.message .list:not(.ui) li:last-child{margin-bottom:0}.ui.message>.icon{margin-right:.6em}.ui.message>.close.icon{cursor:pointer;position:absolute;margin:0;top:.78575em;right:.5em;opacity:.7;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.message>.close.icon:hover{opacity:1}.ui.message>:first-child{margin-top:0}.ui.message>:last-child{margin-bottom:0}.ui.dropdown .menu>.message{margin:0 -1px}.ui.visible.visible.visible.visible.message{display:block}.ui.icon.visible.visible.visible.visible.message{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.hidden.hidden.hidden.hidden.message{display:none}.ui.compact.message{display:inline-block}.ui.compact.icon.message{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.ui.attached.message{margin-bottom:-1px;border-radius:.28571429rem .28571429rem 0 0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;margin-left:-1px;margin-right:-1px}.ui.attached+.ui.attached.message:not(.top):not(.bottom){margin-top:-1px;border-radius:0}.ui.bottom.attached.message{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset,0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px rgba(34,36,38,.15) inset,0 1px 2px 0 rgba(34,36,38,.15)}.ui.bottom.attached.message:not(:last-child){margin-bottom:1em}.ui.attached.icon.message{width:auto}.ui.icon.message{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.icon.message>.icon:not(.close){display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;line-height:1;vertical-align:middle;font-size:3em;opacity:.8}.ui.icon.message>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;vertical-align:middle}.ui.icon.message .icon:not(.close)+.content{padding-left:0}.ui.icon.message .circular.icon{width:1em}.ui.floating.message{-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.black.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.positive.message{background-color:#fcfff5;color:#2c662d}.ui.attached.positive.message,.ui.positive.message{-webkit-box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.positive.message .header{color:#1a531b}.ui.negative.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.negative.message,.ui.negative.message{-webkit-box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.negative.message .header{color:#912d2b}.ui.info.message{background-color:#f8ffff;color:#276f86}.ui.attached.info.message,.ui.info.message{-webkit-box-shadow:0 0 0 1px #a9d5de inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a9d5de inset,0 0 0 0 transparent}.ui.info.message .header{color:#0e566c}.ui.warning.message{background-color:#fffaf3;color:#573a08}.ui.attached.warning.message,.ui.warning.message{-webkit-box-shadow:0 0 0 1px #c9ba9b inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #c9ba9b inset,0 0 0 0 transparent}.ui.warning.message .header{color:#794b02}.ui.error.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.error.message,.ui.error.message{-webkit-box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.error.message .header{color:#912d2b}.ui.success.message{background-color:#fcfff5;color:#2c662d}.ui.attached.success.message,.ui.success.message{-webkit-box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.success.message .header{color:#1a531b}.ui.black.message,.ui.inverted.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.red.message{background-color:#ffe8e6;color:#db2828;-webkit-box-shadow:0 0 0 1px #db2828 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #db2828 inset,0 0 0 0 transparent}.ui.red.message .header{color:#c82121}.ui.orange.message{background-color:#ffedde;color:#f2711c;-webkit-box-shadow:0 0 0 1px #f2711c inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #f2711c inset,0 0 0 0 transparent}.ui.orange.message .header{color:#e7640d}.ui.yellow.message{background-color:#fff8db;color:#b58105;-webkit-box-shadow:0 0 0 1px #b58105 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #b58105 inset,0 0 0 0 transparent}.ui.yellow.message .header{color:#9c6f04}.ui.olive.message{background-color:#fbfdef;color:#8abc1e;-webkit-box-shadow:0 0 0 1px #8abc1e inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #8abc1e inset,0 0 0 0 transparent}.ui.olive.message .header{color:#7aa61a}.ui.green.message{background-color:#e5f9e7;color:#1ebc30;-webkit-box-shadow:0 0 0 1px #1ebc30 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #1ebc30 inset,0 0 0 0 transparent}.ui.green.message .header{color:#1aa62a}.ui.teal.message{background-color:#e1f7f7;color:#10a3a3;-webkit-box-shadow:0 0 0 1px #10a3a3 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #10a3a3 inset,0 0 0 0 transparent}.ui.teal.message .header{color:#0e8c8c}.ui.blue.message{background-color:#dff0ff;color:#2185d0;-webkit-box-shadow:0 0 0 1px #2185d0 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #2185d0 inset,0 0 0 0 transparent}.ui.blue.message .header{color:#1e77ba}.ui.violet.message{background-color:#eae7ff;color:#6435c9;-webkit-box-shadow:0 0 0 1px #6435c9 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #6435c9 inset,0 0 0 0 transparent}.ui.violet.message .header{color:#5a30b5}.ui.purple.message{background-color:#f6e7ff;color:#a333c8;-webkit-box-shadow:0 0 0 1px #a333c8 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a333c8 inset,0 0 0 0 transparent}.ui.purple.message .header{color:#922eb4}.ui.pink.message{background-color:#ffe3fb;color:#e03997;-webkit-box-shadow:0 0 0 1px #e03997 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e03997 inset,0 0 0 0 transparent}.ui.pink.message .header{color:#dd238b}.ui.brown.message{background-color:#f1e2d3;color:#a5673f;-webkit-box-shadow:0 0 0 1px #a5673f inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a5673f inset,0 0 0 0 transparent}.ui.brown.message .header{color:#935b38}.ui.mini.message{font-size:.78571429em}.ui.tiny.message{font-size:.85714286em}.ui.small.message{font-size:.92857143em}.ui.message{font-size:1em}.ui.large.message{font-size:1.14285714em}.ui.big.message{font-size:1.28571429em}.ui.huge.message{font-size:1.42857143em}.ui.massive.message{font-size:1.71428571em}/*!\\n * # Semantic UI 2.4.0 - Table\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.table{width:100%;background:#fff;margin:1em 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none;border-radius:.28571429rem;text-align:left;color:rgba(0,0,0,.87);border-collapse:separate;border-spacing:0}.ui.table:first-child{margin-top:0}.ui.table:last-child{margin-bottom:0}.ui.table td,.ui.table th{-webkit-transition:background .1s ease,color .1s ease;transition:background .1s ease,color .1s ease}.ui.table thead{-webkit-box-shadow:none;box-shadow:none}.ui.table thead th{cursor:auto;background:#f9fafb;text-align:inherit;color:rgba(0,0,0,.87);padding:.92857143em .78571429em;vertical-align:inherit;font-style:none;font-weight:700;text-transform:none;border-bottom:1px solid rgba(34,36,38,.1);border-left:none}.ui.table thead tr>th:first-child{border-left:none}.ui.table thead tr:first-child>th:first-child{border-radius:.28571429rem 0 0 0}.ui.table thead tr:first-child>th:last-child{border-radius:0 .28571429rem 0 0}.ui.table thead tr:first-child>th:only-child{border-radius:.28571429rem .28571429rem 0 0}.ui.table tfoot{-webkit-box-shadow:none;box-shadow:none}.ui.table tfoot th{cursor:auto;border-top:1px solid rgba(34,36,38,.15);background:#f9fafb;text-align:inherit;color:rgba(0,0,0,.87);padding:.78571429em .78571429em;vertical-align:middle;font-style:normal;font-weight:400;text-transform:none}.ui.table tfoot tr>th:first-child{border-left:none}.ui.table tfoot tr:first-child>th:first-child{border-radius:0 0 0 .28571429rem}.ui.table tfoot tr:first-child>th:last-child{border-radius:0 0 .28571429rem 0}.ui.table tfoot tr:first-child>th:only-child{border-radius:0 0 .28571429rem .28571429rem}.ui.table tr td{border-top:1px solid rgba(34,36,38,.1)}.ui.table tr:first-child td{border-top:none}.ui.table tbody+tbody tr:first-child td{border-top:1px solid rgba(34,36,38,.1)}.ui.table td{padding:.78571429em .78571429em;text-align:inherit}.ui.table>.icon{vertical-align:baseline}.ui.table>.icon:only-child{margin:0}.ui.table.segment{padding:0}.ui.table.segment:after{display:none}.ui.table.segment.stacked:after{display:block}@media only screen and (max-width:767px){.ui.table:not(.unstackable){width:100%}.ui.table:not(.unstackable) tbody,.ui.table:not(.unstackable) tr,.ui.table:not(.unstackable) tr>td,.ui.table:not(.unstackable) tr>th{width:auto!important;display:block!important}.ui.table:not(.unstackable){padding:0}.ui.table:not(.unstackable) thead{display:block}.ui.table:not(.unstackable) tfoot{display:block}.ui.table:not(.unstackable) tr{padding-top:1em;padding-bottom:1em;-webkit-box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important;box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important}.ui.table:not(.unstackable) tr>td,.ui.table:not(.unstackable) tr>th{background:0 0;border:none!important;padding:.25em .75em!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.table:not(.unstackable) td:first-child,.ui.table:not(.unstackable) th:first-child{font-weight:700}.ui.definition.table:not(.unstackable) thead th:first-child{-webkit-box-shadow:none!important;box-shadow:none!important}}.ui.table td .image,.ui.table td .image img,.ui.table th .image,.ui.table th .image img{max-width:none}.ui.structured.table{border-collapse:collapse}.ui.structured.table thead th{border-left:none;border-right:none}.ui.structured.sortable.table thead th{border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(34,36,38,.15)}.ui.structured.basic.table th{border-left:none;border-right:none}.ui.structured.celled.table tr td,.ui.structured.celled.table tr th{border-left:1px solid rgba(34,36,38,.1);border-right:1px solid rgba(34,36,38,.1)}.ui.definition.table thead:not(.full-width) th:first-child{pointer-events:none;background:0 0;font-weight:400;color:rgba(0,0,0,.4);-webkit-box-shadow:-1px -1px 0 1px #fff;box-shadow:-1px -1px 0 1px #fff}.ui.definition.table tfoot:not(.full-width) th:first-child{pointer-events:none;background:0 0;font-weight:rgba(0,0,0,.4);color:normal;-webkit-box-shadow:1px 1px 0 1px #fff;box-shadow:1px 1px 0 1px #fff}.ui.celled.definition.table thead:not(.full-width) th:first-child{-webkit-box-shadow:0 -1px 0 1px #fff;box-shadow:0 -1px 0 1px #fff}.ui.celled.definition.table tfoot:not(.full-width) th:first-child{-webkit-box-shadow:0 1px 0 1px #fff;box-shadow:0 1px 0 1px #fff}.ui.definition.table tr td.definition,.ui.definition.table tr td:first-child:not(.ignored){background:rgba(0,0,0,.03);font-weight:700;color:rgba(0,0,0,.95);text-transform:'';-webkit-box-shadow:'';box-shadow:'';text-align:'';font-size:1em;padding-left:'';padding-right:''}.ui.definition.table thead:not(.full-width) th:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.definition.table tfoot:not(.full-width) th:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.definition.table td:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.table td.positive,.ui.table tr.positive{-webkit-box-shadow:0 0 0 #a3c293 inset;box-shadow:0 0 0 #a3c293 inset}.ui.table td.positive,.ui.table tr.positive{background:#fcfff5!important;color:#2c662d!important}.ui.table td.negative,.ui.table tr.negative{-webkit-box-shadow:0 0 0 #e0b4b4 inset;box-shadow:0 0 0 #e0b4b4 inset}.ui.table td.negative,.ui.table tr.negative{background:#fff6f6!important;color:#9f3a38!important}.ui.table td.error,.ui.table tr.error{-webkit-box-shadow:0 0 0 #e0b4b4 inset;box-shadow:0 0 0 #e0b4b4 inset}.ui.table td.error,.ui.table tr.error{background:#fff6f6!important;color:#9f3a38!important}.ui.table td.warning,.ui.table tr.warning{-webkit-box-shadow:0 0 0 #c9ba9b inset;box-shadow:0 0 0 #c9ba9b inset}.ui.table td.warning,.ui.table tr.warning{background:#fffaf3!important;color:#573a08!important}.ui.table td.active,.ui.table tr.active{-webkit-box-shadow:0 0 0 rgba(0,0,0,.87) inset;box-shadow:0 0 0 rgba(0,0,0,.87) inset}.ui.table td.active,.ui.table tr.active{background:#e0e0e0!important;color:rgba(0,0,0,.87)!important}.ui.table tr td.disabled,.ui.table tr.disabled td,.ui.table tr.disabled:hover,.ui.table tr:hover td.disabled{pointer-events:none;color:rgba(40,40,40,.3)}@media only screen and (max-width:991px){.ui[class*=\\\"tablet stackable\\\"].table,.ui[class*=\\\"tablet stackable\\\"].table tbody,.ui[class*=\\\"tablet stackable\\\"].table tr,.ui[class*=\\\"tablet stackable\\\"].table tr>td,.ui[class*=\\\"tablet stackable\\\"].table tr>th{width:100%!important;display:block!important}.ui[class*=\\\"tablet stackable\\\"].table{padding:0}.ui[class*=\\\"tablet stackable\\\"].table thead{display:block}.ui[class*=\\\"tablet stackable\\\"].table tfoot{display:block}.ui[class*=\\\"tablet stackable\\\"].table tr{padding-top:1em;padding-bottom:1em;-webkit-box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important;box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important}.ui[class*=\\\"tablet stackable\\\"].table tr>td,.ui[class*=\\\"tablet stackable\\\"].table tr>th{background:0 0;border:none!important;padding:.25em .75em;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.definition[class*=\\\"tablet stackable\\\"].table thead th:first-child{-webkit-box-shadow:none!important;box-shadow:none!important}}.ui.table [class*=\\\"left aligned\\\"],.ui.table[class*=\\\"left aligned\\\"]{text-align:left}.ui.table [class*=\\\"center aligned\\\"],.ui.table[class*=\\\"center aligned\\\"]{text-align:center}.ui.table [class*=\\\"right aligned\\\"],.ui.table[class*=\\\"right aligned\\\"]{text-align:right}.ui.table [class*=\\\"top aligned\\\"],.ui.table[class*=\\\"top aligned\\\"]{vertical-align:top}.ui.table [class*=\\\"middle aligned\\\"],.ui.table[class*=\\\"middle aligned\\\"]{vertical-align:middle}.ui.table [class*=\\\"bottom aligned\\\"],.ui.table[class*=\\\"bottom aligned\\\"]{vertical-align:bottom}.ui.table td.collapsing,.ui.table th.collapsing{width:1px;white-space:nowrap}.ui.fixed.table{table-layout:fixed}.ui.fixed.table td,.ui.fixed.table th{overflow:hidden;text-overflow:ellipsis}.ui.selectable.table tbody tr:hover,.ui.table tbody tr td.selectable:hover{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.inverted.table tbody tr td.selectable:hover,.ui.selectable.inverted.table tbody tr:hover{background:rgba(255,255,255,.08)!important;color:#fff!important}.ui.table tbody tr td.selectable{padding:0}.ui.table tbody tr td.selectable>a:not(.ui){display:block;color:inherit;padding:.78571429em .78571429em}.ui.selectable.table tr.error:hover,.ui.selectable.table tr:hover td.error,.ui.table tr td.selectable.error:hover{background:#ffe7e7!important;color:#943634!important}.ui.selectable.table tr.warning:hover,.ui.selectable.table tr:hover td.warning,.ui.table tr td.selectable.warning:hover{background:#fff4e4!important;color:#493107!important}.ui.selectable.table tr.active:hover,.ui.selectable.table tr:hover td.active,.ui.table tr td.selectable.active:hover{background:#e0e0e0!important;color:rgba(0,0,0,.87)!important}.ui.selectable.table tr.positive:hover,.ui.selectable.table tr:hover td.positive,.ui.table tr td.selectable.positive:hover{background:#f7ffe6!important;color:#275b28!important}.ui.selectable.table tr.negative:hover,.ui.selectable.table tr:hover td.negative,.ui.table tr td.selectable.negative:hover{background:#ffe7e7!important;color:#943634!important}.ui.attached.table{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached+.ui.attached.table:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].table{bottom:0;margin-bottom:0;top:0;margin-top:1em;border-radius:.28571429rem .28571429rem 0 0}.ui.table[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui[class*=\\\"bottom attached\\\"].table{bottom:0;margin-top:0;top:0;margin-bottom:1em;-webkit-box-shadow:none,none;box-shadow:none,none;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].table:last-child{margin-bottom:0}.ui.striped.table tbody tr:nth-child(2n),.ui.striped.table>tr:nth-child(2n){background-color:rgba(0,0,50,.02)}.ui.inverted.striped.table tbody tr:nth-child(2n),.ui.inverted.striped.table>tr:nth-child(2n){background-color:rgba(255,255,255,.05)}.ui.striped.selectable.selectable.selectable.table tbody tr.active:hover{background:#efefef!important;color:rgba(0,0,0,.95)!important}.ui.table [class*=\\\"single line\\\"],.ui.table[class*=\\\"single line\\\"]{white-space:nowrap}.ui.table [class*=\\\"single line\\\"],.ui.table[class*=\\\"single line\\\"]{white-space:nowrap}.ui.red.table{border-top:.2em solid #db2828}.ui.inverted.red.table{background-color:#db2828!important;color:#fff!important}.ui.orange.table{border-top:.2em solid #f2711c}.ui.inverted.orange.table{background-color:#f2711c!important;color:#fff!important}.ui.yellow.table{border-top:.2em solid #fbbd08}.ui.inverted.yellow.table{background-color:#fbbd08!important;color:#fff!important}.ui.olive.table{border-top:.2em solid #b5cc18}.ui.inverted.olive.table{background-color:#b5cc18!important;color:#fff!important}.ui.green.table{border-top:.2em solid #21ba45}.ui.inverted.green.table{background-color:#21ba45!important;color:#fff!important}.ui.teal.table{border-top:.2em solid #00b5ad}.ui.inverted.teal.table{background-color:#00b5ad!important;color:#fff!important}.ui.blue.table{border-top:.2em solid #2185d0}.ui.inverted.blue.table{background-color:#2185d0!important;color:#fff!important}.ui.violet.table{border-top:.2em solid #6435c9}.ui.inverted.violet.table{background-color:#6435c9!important;color:#fff!important}.ui.purple.table{border-top:.2em solid #a333c8}.ui.inverted.purple.table{background-color:#a333c8!important;color:#fff!important}.ui.pink.table{border-top:.2em solid #e03997}.ui.inverted.pink.table{background-color:#e03997!important;color:#fff!important}.ui.brown.table{border-top:.2em solid #a5673f}.ui.inverted.brown.table{background-color:#a5673f!important;color:#fff!important}.ui.grey.table{border-top:.2em solid #767676}.ui.inverted.grey.table{background-color:#767676!important;color:#fff!important}.ui.black.table{border-top:.2em solid #1b1c1d}.ui.inverted.black.table{background-color:#1b1c1d!important;color:#fff!important}.ui.one.column.table td{width:100%}.ui.two.column.table td{width:50%}.ui.three.column.table td{width:33.33333333%}.ui.four.column.table td{width:25%}.ui.five.column.table td{width:20%}.ui.six.column.table td{width:16.66666667%}.ui.seven.column.table td{width:14.28571429%}.ui.eight.column.table td{width:12.5%}.ui.nine.column.table td{width:11.11111111%}.ui.ten.column.table td{width:10%}.ui.eleven.column.table td{width:9.09090909%}.ui.twelve.column.table td{width:8.33333333%}.ui.thirteen.column.table td{width:7.69230769%}.ui.fourteen.column.table td{width:7.14285714%}.ui.fifteen.column.table td{width:6.66666667%}.ui.sixteen.column.table td{width:6.25%}.ui.table td.one.wide,.ui.table th.one.wide{width:6.25%}.ui.table td.two.wide,.ui.table th.two.wide{width:12.5%}.ui.table td.three.wide,.ui.table th.three.wide{width:18.75%}.ui.table td.four.wide,.ui.table th.four.wide{width:25%}.ui.table td.five.wide,.ui.table th.five.wide{width:31.25%}.ui.table td.six.wide,.ui.table th.six.wide{width:37.5%}.ui.table td.seven.wide,.ui.table th.seven.wide{width:43.75%}.ui.table td.eight.wide,.ui.table th.eight.wide{width:50%}.ui.table td.nine.wide,.ui.table th.nine.wide{width:56.25%}.ui.table td.ten.wide,.ui.table th.ten.wide{width:62.5%}.ui.table td.eleven.wide,.ui.table th.eleven.wide{width:68.75%}.ui.table td.twelve.wide,.ui.table th.twelve.wide{width:75%}.ui.table td.thirteen.wide,.ui.table th.thirteen.wide{width:81.25%}.ui.table td.fourteen.wide,.ui.table th.fourteen.wide{width:87.5%}.ui.table td.fifteen.wide,.ui.table th.fifteen.wide{width:93.75%}.ui.table td.sixteen.wide,.ui.table th.sixteen.wide{width:100%}.ui.sortable.table thead th{cursor:pointer;white-space:nowrap;border-left:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87)}.ui.sortable.table thead th:first-child{border-left:none}.ui.sortable.table thead th.sorted,.ui.sortable.table thead th.sorted:hover{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui.sortable.table thead th:after{display:none;font-style:normal;font-weight:400;text-decoration:inherit;content:'';height:1em;width:auto;opacity:.8;margin:0 0 0 .5em;font-family:Icons}.ui.sortable.table thead th.ascending:after{content:'\\\\f0d8'}.ui.sortable.table thead th.descending:after{content:'\\\\f0d7'}.ui.sortable.table th.disabled:hover{cursor:auto;color:rgba(40,40,40,.3)}.ui.sortable.table thead th:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.8)}.ui.sortable.table thead th.sorted{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.sortable.table thead th.sorted:after{display:inline-block}.ui.sortable.table thead th.sorted:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.inverted.sortable.table thead th.sorted{background:rgba(255,255,255,.15) -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:rgba(255,255,255,.15) -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:rgba(255,255,255,.15) linear-gradient(transparent,rgba(0,0,0,.05));color:#fff}.ui.inverted.sortable.table thead th:hover{background:rgba(255,255,255,.08) -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:rgba(255,255,255,.08) -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:rgba(255,255,255,.08) linear-gradient(transparent,rgba(0,0,0,.05));color:#fff}.ui.inverted.sortable.table thead th{border-left-color:transparent;border-right-color:transparent}.ui.inverted.table{background:#333;color:rgba(255,255,255,.9);border:none}.ui.inverted.table th{background-color:rgba(0,0,0,.15);border-color:rgba(255,255,255,.1)!important;color:rgba(255,255,255,.9)!important}.ui.inverted.table tr td{border-color:rgba(255,255,255,.1)!important}.ui.inverted.table tr td.disabled,.ui.inverted.table tr.disabled td,.ui.inverted.table tr.disabled:hover td,.ui.inverted.table tr:hover td.disabled{pointer-events:none;color:rgba(225,225,225,.3)}.ui.inverted.definition.table tfoot:not(.full-width) th:first-child,.ui.inverted.definition.table thead:not(.full-width) th:first-child{background:#fff}.ui.inverted.definition.table tr td:first-child{background:rgba(255,255,255,.02);color:#fff}.ui.collapsing.table{width:auto}.ui.basic.table{background:0 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.table tfoot,.ui.basic.table thead{-webkit-box-shadow:none;box-shadow:none}.ui.basic.table th{background:0 0;border-left:none}.ui.basic.table tbody tr{border-bottom:1px solid rgba(0,0,0,.1)}.ui.basic.table td{background:0 0}.ui.basic.striped.table tbody tr:nth-child(2n){background-color:rgba(0,0,0,.05)!important}.ui[class*=\\\"very basic\\\"].table{border:none}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th{padding:''}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td:first-child,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th:first-child{padding-left:0}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td:last-child,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th:last-child{padding-right:0}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) thead tr:first-child th{padding-top:0}.ui.celled.table tr td,.ui.celled.table tr th{border-left:1px solid rgba(34,36,38,.1)}.ui.celled.table tr td:first-child,.ui.celled.table tr th:first-child{border-left:none}.ui.padded.table th{padding-left:1em;padding-right:1em}.ui.padded.table td,.ui.padded.table th{padding:1em 1em}.ui[class*=\\\"very padded\\\"].table th{padding-left:1.5em;padding-right:1.5em}.ui[class*=\\\"very padded\\\"].table td{padding:1.5em 1.5em}.ui.compact.table th{padding-left:.7em;padding-right:.7em}.ui.compact.table td{padding:.5em .7em}.ui[class*=\\\"very compact\\\"].table th{padding-left:.6em;padding-right:.6em}.ui[class*=\\\"very compact\\\"].table td{padding:.4em .6em}.ui.small.table{font-size:.9em}.ui.table{font-size:1em}.ui.large.table{font-size:1.1em}/*!\\n * # Semantic UI 2.4.0 - Ad\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Copyright 2013 Contributors\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child{margin:0}.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*=\\\"medium rectangle\\\"].ad{width:300px;height:250px}.ui[class*=\\\"large rectangle\\\"].ad{width:336px;height:280px}.ui[class*=\\\"half page\\\"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*=\\\"small square\\\"].ad{width:200px;height:200px}.ui[class*=\\\"small rectangle\\\"].ad{width:180px;height:150px}.ui[class*=\\\"vertical rectangle\\\"].ad{width:240px;height:400px}.ui.button.ad{width:120px;height:90px}.ui[class*=\\\"square button\\\"].ad{width:125px;height:125px}.ui[class*=\\\"small button\\\"].ad{width:120px;height:60px}.ui.skyscraper.ad{width:120px;height:600px}.ui[class*=\\\"wide skyscraper\\\"].ad{width:160px}.ui.banner.ad{width:468px;height:60px}.ui[class*=\\\"vertical banner\\\"].ad{width:120px;height:240px}.ui[class*=\\\"top banner\\\"].ad{width:930px;height:180px}.ui[class*=\\\"half banner\\\"].ad{width:234px;height:60px}.ui[class*=\\\"large leaderboard\\\"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:120px}.ui.netboard.ad{width:580px;height:400px}.ui[class*=\\\"large mobile banner\\\"].ad{width:320px;height:100px}.ui[class*=\\\"mobile leaderboard\\\"].ad{width:320px;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#545454}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714286em}.ui.test.ad[data-text]:after{content:attr(data-text)}/*!\\n * # Semantic UI 2.4.0 - Item\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.card,.ui.cards>.card{max-width:100%;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:290px;min-height:0;background:#fff;padding:0;border:none;border-radius:.28571429rem;-webkit-box-shadow:0 1px 3px 0 #d4d4d5,0 0 0 1px #d4d4d5;box-shadow:0 1px 3px 0 #d4d4d5,0 0 0 1px #d4d4d5;-webkit-transition:-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:box-shadow .1s ease,transform .1s ease;transition:box-shadow .1s ease,transform .1s ease,-webkit-box-shadow .1s ease,-webkit-transform .1s ease;z-index:''}.ui.card{margin:1em 0}.ui.card a,.ui.cards>.card a{cursor:pointer}.ui.card:first-child{margin-top:0}.ui.card:last-child{margin-bottom:0}.ui.cards{display:-webkit-box;display:-ms-flexbox;display:flex;margin:-.875em -.5em;-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.cards>.card{display:-webkit-box;display:-ms-flexbox;display:flex;margin:.875em .5em;float:none}.ui.card:after,.ui.cards:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.cards~.ui.cards{margin-top:.875em}.ui.card>:first-child,.ui.cards>.card>:first-child{border-radius:.28571429rem .28571429rem 0 0!important;border-top:none!important}.ui.card>:last-child,.ui.cards>.card>:last-child{border-radius:0 0 .28571429rem .28571429rem!important}.ui.card>:only-child,.ui.cards>.card>:only-child{border-radius:.28571429rem!important}.ui.card>.image,.ui.cards>.card>.image{position:relative;display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding:0;background:rgba(0,0,0,.05)}.ui.card>.image>img,.ui.cards>.card>.image>img{display:block;width:100%;height:auto;border-radius:inherit}.ui.card>.image:not(.ui)>img,.ui.cards>.card>.image:not(.ui)>img{border:none}.ui.card>.content,.ui.cards>.card>.content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;border:none;border-top:1px solid rgba(34,36,38,.1);background:0 0;margin:0;padding:1em 1em;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border-radius:0}.ui.card>.content:after,.ui.cards>.card>.content:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.card>.content>.header,.ui.cards>.card>.content>.header{display:block;margin:'';font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;color:rgba(0,0,0,.85)}.ui.card>.content>.header:not(.ui),.ui.cards>.card>.content>.header:not(.ui){font-weight:700;font-size:1.28571429em;margin-top:-.21425em;line-height:1.28571429em}.ui.card>.content>.header+.description,.ui.card>.content>.meta+.description,.ui.cards>.card>.content>.header+.description,.ui.cards>.card>.content>.meta+.description{margin-top:.5em}.ui.card [class*=\\\"left floated\\\"],.ui.cards>.card [class*=\\\"left floated\\\"]{float:left}.ui.card [class*=\\\"right floated\\\"],.ui.cards>.card [class*=\\\"right floated\\\"]{float:right}.ui.card [class*=\\\"left aligned\\\"],.ui.cards>.card [class*=\\\"left aligned\\\"]{text-align:left}.ui.card [class*=\\\"center aligned\\\"],.ui.cards>.card [class*=\\\"center aligned\\\"]{text-align:center}.ui.card [class*=\\\"right aligned\\\"],.ui.cards>.card [class*=\\\"right aligned\\\"]{text-align:right}.ui.card .content img,.ui.cards>.card .content img{display:inline-block;vertical-align:middle;width:''}.ui.card .avatar img,.ui.card img.avatar,.ui.cards>.card .avatar img,.ui.cards>.card img.avatar{width:2em;height:2em;border-radius:500rem}.ui.card>.content>.description,.ui.cards>.card>.content>.description{clear:both;color:rgba(0,0,0,.68)}.ui.card>.content p,.ui.cards>.card>.content p{margin:0 0 .5em}.ui.card>.content p:last-child,.ui.cards>.card>.content p:last-child{margin-bottom:0}.ui.card .meta,.ui.cards>.card .meta{font-size:1em;color:rgba(0,0,0,.4)}.ui.card .meta *,.ui.cards>.card .meta *{margin-right:.3em}.ui.card .meta :last-child,.ui.cards>.card .meta :last-child{margin-right:0}.ui.card .meta [class*=\\\"right floated\\\"],.ui.cards>.card .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.card>.content a:not(.ui),.ui.cards>.card>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content a:not(.ui):hover,.ui.cards>.card>.content a:not(.ui):hover{color:''}.ui.card>.content>a.header,.ui.cards>.card>.content>a.header{color:rgba(0,0,0,.85)}.ui.card>.content>a.header:hover,.ui.cards>.card>.content>a.header:hover{color:#1e70bf}.ui.card .meta>a:not(.ui),.ui.cards>.card .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.card .meta>a:not(.ui):hover,.ui.cards>.card .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.card>.button,.ui.card>.buttons,.ui.cards>.card>.button,.ui.cards>.card>.buttons{margin:0 -1px;width:calc(100% + 2px)}.ui.card .dimmer,.ui.cards>.card .dimmer{background-color:'';z-index:10}.ui.card>.content .star.icon,.ui.cards>.card>.content .star.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content .star.icon:hover,.ui.cards>.card>.content .star.icon:hover{opacity:1;color:#ffb70a}.ui.card>.content .active.star.icon,.ui.cards>.card>.content .active.star.icon{color:#ffe623}.ui.card>.content .like.icon,.ui.cards>.card>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content .like.icon:hover,.ui.cards>.card>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.card>.content .active.like.icon,.ui.cards>.card>.content .active.like.icon{color:#ff2733}.ui.card>.extra,.ui.cards>.card>.extra{max-width:100%;min-height:0!important;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;border-top:1px solid rgba(0,0,0,.05)!important;position:static;background:0 0;width:auto;margin:0 0;padding:.75em 1em;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.extra a:not(.ui),.ui.cards>.card>.extra a:not(.ui){color:rgba(0,0,0,.4)}.ui.card>.extra a:not(.ui):hover,.ui.cards>.card>.extra a:not(.ui):hover{color:#1e70bf}.ui.raised.card,.ui.raised.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.link.cards .raised.card:hover,.ui.link.raised.card:hover,.ui.raised.cards a.card:hover,a.ui.raised.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25)}.ui.raised.card,.ui.raised.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.centered.cards{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.centered.card{margin-left:auto;margin-right:auto}.ui.fluid.card{width:100%;max-width:9999px}.ui.cards a.card,.ui.link.card,.ui.link.cards .card,a.ui.card{-webkit-transform:none;transform:none}.ui.cards a.card:hover,.ui.link.card:hover,.ui.link.cards .card:hover,a.ui.card:hover{cursor:pointer;z-index:5;background:#fff;border:none;-webkit-box-shadow:0 1px 3px 0 #bcbdbd,0 0 0 1px #d4d4d5;box-shadow:0 1px 3px 0 #bcbdbd,0 0 0 1px #d4d4d5;-webkit-transform:translateY(-3px);transform:translateY(-3px)}.ui.cards>.red.card,.ui.red.card,.ui.red.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #db2828,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #db2828,0 1px 3px 0 #d4d4d5}.ui.cards>.red.card:hover,.ui.red.card:hover,.ui.red.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #d01919,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #d01919,0 1px 3px 0 #bcbdbd}.ui.cards>.orange.card,.ui.orange.card,.ui.orange.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f2711c,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f2711c,0 1px 3px 0 #d4d4d5}.ui.cards>.orange.card:hover,.ui.orange.card:hover,.ui.orange.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f26202,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f26202,0 1px 3px 0 #bcbdbd}.ui.cards>.yellow.card,.ui.yellow.card,.ui.yellow.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #fbbd08,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #fbbd08,0 1px 3px 0 #d4d4d5}.ui.cards>.yellow.card:hover,.ui.yellow.card:hover,.ui.yellow.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #eaae00,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #eaae00,0 1px 3px 0 #bcbdbd}.ui.cards>.olive.card,.ui.olive.card,.ui.olive.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #b5cc18,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #b5cc18,0 1px 3px 0 #d4d4d5}.ui.cards>.olive.card:hover,.ui.olive.card:hover,.ui.olive.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a7bd0d,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a7bd0d,0 1px 3px 0 #bcbdbd}.ui.cards>.green.card,.ui.green.card,.ui.green.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #21ba45,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #21ba45,0 1px 3px 0 #d4d4d5}.ui.cards>.green.card:hover,.ui.green.card:hover,.ui.green.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #16ab39,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #16ab39,0 1px 3px 0 #bcbdbd}.ui.cards>.teal.card,.ui.teal.card,.ui.teal.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #00b5ad,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #00b5ad,0 1px 3px 0 #d4d4d5}.ui.cards>.teal.card:hover,.ui.teal.card:hover,.ui.teal.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #009c95,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #009c95,0 1px 3px 0 #bcbdbd}.ui.blue.card,.ui.blue.cards>.card,.ui.cards>.blue.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5}.ui.blue.card:hover,.ui.blue.cards>.card:hover,.ui.cards>.blue.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd}.ui.cards>.violet.card,.ui.violet.card,.ui.violet.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #6435c9,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #6435c9,0 1px 3px 0 #d4d4d5}.ui.cards>.violet.card:hover,.ui.violet.card:hover,.ui.violet.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #5829bb,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #5829bb,0 1px 3px 0 #bcbdbd}.ui.cards>.purple.card,.ui.purple.card,.ui.purple.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a333c8,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a333c8,0 1px 3px 0 #d4d4d5}.ui.cards>.purple.card:hover,.ui.purple.card:hover,.ui.purple.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #9627ba,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #9627ba,0 1px 3px 0 #bcbdbd}.ui.cards>.pink.card,.ui.pink.card,.ui.pink.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e03997,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e03997,0 1px 3px 0 #d4d4d5}.ui.cards>.pink.card:hover,.ui.pink.card:hover,.ui.pink.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e61a8d,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e61a8d,0 1px 3px 0 #bcbdbd}.ui.brown.card,.ui.brown.cards>.card,.ui.cards>.brown.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a5673f,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a5673f,0 1px 3px 0 #d4d4d5}.ui.brown.card:hover,.ui.brown.cards>.card:hover,.ui.cards>.brown.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #975b33,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #975b33,0 1px 3px 0 #bcbdbd}.ui.cards>.grey.card,.ui.grey.card,.ui.grey.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #767676,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #767676,0 1px 3px 0 #d4d4d5}.ui.cards>.grey.card:hover,.ui.grey.card:hover,.ui.grey.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #838383,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #838383,0 1px 3px 0 #bcbdbd}.ui.black.card,.ui.black.cards>.card,.ui.cards>.black.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5}.ui.black.card:hover,.ui.black.cards>.card:hover,.ui.cards>.black.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd}.ui.one.cards{margin-left:0;margin-right:0}.ui.one.cards>.card{width:100%}.ui.two.cards{margin-left:-1em;margin-right:-1em}.ui.two.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.three.cards{margin-left:-1em;margin-right:-1em}.ui.three.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.four.cards{margin-left:-.75em;margin-right:-.75em}.ui.four.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.five.cards{margin-left:-.75em;margin-right:-.75em}.ui.five.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.six.cards{margin-left:-.75em;margin-right:-.75em}.ui.six.cards>.card{width:calc(16.66666667% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.seven.cards{margin-left:-.5em;margin-right:-.5em}.ui.seven.cards>.card{width:calc(14.28571429% - 1em);margin-left:.5em;margin-right:.5em}.ui.eight.cards{margin-left:-.5em;margin-right:-.5em}.ui.eight.cards>.card{width:calc(12.5% - 1em);margin-left:.5em;margin-right:.5em;font-size:11px}.ui.nine.cards{margin-left:-.5em;margin-right:-.5em}.ui.nine.cards>.card{width:calc(11.11111111% - 1em);margin-left:.5em;margin-right:.5em;font-size:10px}.ui.ten.cards{margin-left:-.5em;margin-right:-.5em}.ui.ten.cards>.card{width:calc(10% - 1em);margin-left:.5em;margin-right:.5em}@media only screen and (max-width:767px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.seven.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.seven.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.nine.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.nine.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.ten.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.ten.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}}@media only screen and (min-width:768px) and (max-width:991px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.eight.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.nine.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.nine.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.ten.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.ten.doubling.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}}@media only screen and (max-width:767px){.ui.stackable.cards{display:block!important}.ui.stackable.cards .card:first-child{margin-top:0!important}.ui.stackable.cards>.card{display:block!important;height:auto!important;margin:1em 1em;padding:0!important;width:calc(100% - 2em)!important}}.ui.cards>.card{font-size:1em}/*!\\n * # Semantic UI 2.4.0 - Comment\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.comments{margin:1.5em 0;max-width:650px}.ui.comments:first-child{margin-top:0}.ui.comments:last-child{margin-bottom:0}.ui.comments .comment{position:relative;background:0 0;margin:.5em 0 0;padding:.5em 0 0;border:none;border-top:none;line-height:1.2}.ui.comments .comment:first-child{margin-top:0;padding-top:0}.ui.comments .comment .comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment .comments:before{position:absolute;top:0;left:0}.ui.comments .comment .comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.87);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#1e70bf}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.87);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment .comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;-webkit-box-shadow:-1px 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 rgba(34,36,38,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;-webkit-transition-delay:.1s;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.mini.comments{font-size:.78571429rem}.ui.tiny.comments{font-size:.85714286rem}.ui.small.comments{font-size:.92857143rem}.ui.comments{font-size:1rem}.ui.large.comments{font-size:1.14285714rem}.ui.big.comments{font-size:1.28571429rem}.ui.huge.comments{font-size:1.42857143rem}.ui.massive.comments{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Feed\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.feed{margin:1em 0}.ui.feed:first-child{margin-top:0}.ui.feed:last-child{margin-bottom:0}.ui.feed>.event{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;width:100%;padding:.21428571rem 0;margin:0;background:0 0;border-top:none}.ui.feed>.event:first-child{border-top:0;padding-top:0}.ui.feed>.event:last-child{padding-bottom:0}.ui.feed>.event>.label{display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:2.5em;height:auto;-ms-flex-item-align:stretch;align-self:stretch;text-align:left}.ui.feed>.event>.label .icon{opacity:1;font-size:1.5em;width:100%;padding:.25em;background:0 0;border:none;border-radius:none;color:rgba(0,0,0,.6)}.ui.feed>.event>.label img{width:100%;height:auto;border-radius:500rem}.ui.feed>.event>.label+.content{margin:.5em 0 .35714286em 1.14285714em}.ui.feed>.event>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-item-align:stretch;align-self:stretch;text-align:left;word-wrap:break-word}.ui.feed>.event:last-child>.content{padding-bottom:0}.ui.feed>.event>.content a{cursor:pointer}.ui.feed>.event>.content .date{margin:-.5rem 0 0;padding:0;font-weight:400;font-size:1em;font-style:normal;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .summary{margin:0;font-size:1em;font-weight:700;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .summary img{display:inline-block;width:auto;height:10em;margin:-.25em .25em 0 0;border-radius:.25em;vertical-align:middle}.ui.feed>.event>.content .user{display:inline-block;font-weight:700;margin-right:0;vertical-align:baseline}.ui.feed>.event>.content .user img{margin:-.25em .25em 0 0;width:auto;height:10em;vertical-align:middle}.ui.feed>.event>.content .summary>.date{display:inline-block;float:none;font-weight:400;font-size:.85714286em;font-style:normal;margin:0 0 0 .5em;padding:0;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .extra{margin:.5em 0 0;background:0 0;padding:0;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .extra.images img{display:inline-block;margin:0 .25em 0 0;width:6em}.ui.feed>.event>.content .extra.text{padding:0;border-left:none;font-size:1em;max-width:500px;line-height:1.4285em}.ui.feed>.event>.content .meta{display:inline-block;font-size:.85714286em;margin:.5em 0 0;background:0 0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;padding:0;color:rgba(0,0,0,.6)}.ui.feed>.event>.content .meta>*{position:relative;margin-left:.75em}.ui.feed>.event>.content .meta>:after{content:'';color:rgba(0,0,0,.2);top:0;left:-1em;opacity:1;position:absolute;vertical-align:top}.ui.feed>.event>.content .meta .like{color:'';-webkit-transition:.2s color ease;transition:.2s color ease}.ui.feed>.event>.content .meta .like:hover .icon{color:#ff2733}.ui.feed>.event>.content .meta .active.like .icon{color:#ef404a}.ui.feed>.event>.content .meta>:first-child{margin-left:0}.ui.feed>.event>.content .meta>:first-child::after{display:none}.ui.feed>.event>.content .meta a,.ui.feed>.event>.content .meta>.icon{cursor:pointer;opacity:1;color:rgba(0,0,0,.5);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.feed>.event>.content .meta a:hover,.ui.feed>.event>.content .meta a:hover .icon,.ui.feed>.event>.content .meta>.icon:hover{color:rgba(0,0,0,.95)}.ui.small.feed{font-size:.92857143rem}.ui.feed{font-size:1rem}.ui.large.feed{font-size:1.14285714rem}/*!\\n * # Semantic UI 2.4.0 - Item\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:top;align-self:top}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:top;align-self:top;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:middle;align-self:middle;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}@media only screen and (max-width:767px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}/*!\\n * # Semantic UI 2.4.0 - Statistic\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.statistic{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:1em 0;max-width:auto}.ui.statistic+.ui.statistic{margin:0 0 0 1.5em}.ui.statistic:first-child{margin-top:0}.ui.statistic:last-child{margin-bottom:0}.ui.statistics{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.statistics>.statistic{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 1.5em 1em;max-width:auto}.ui.statistics{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em -1.5em -1em}.ui.statistics:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.statistics:first-child{margin-top:0}.ui.statistic>.value,.ui.statistics .statistic>.value{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:4rem;font-weight:400;line-height:1em;color:#1b1c1d;text-transform:uppercase;text-align:center}.ui.statistic>.label,.ui.statistics .statistic>.label{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;font-weight:700;color:rgba(0,0,0,.87);text-transform:uppercase;text-align:center}.ui.statistic>.label~.value,.ui.statistics .statistic>.label~.value{margin-top:0}.ui.statistic>.value~.label,.ui.statistics .statistic>.value~.label{margin-top:0}.ui.statistic>.value .icon,.ui.statistics .statistic>.value .icon{opacity:1;width:auto;margin:0}.ui.statistic>.text.value,.ui.statistics .statistic>.text.value{line-height:1em;min-height:2em;font-weight:700;text-align:center}.ui.statistic>.text.value+.label,.ui.statistics .statistic>.text.value+.label{text-align:center}.ui.statistic>.value img,.ui.statistics .statistic>.value img{max-height:3rem;vertical-align:baseline}.ui.ten.statistics{margin:0 0 -1em}.ui.ten.statistics .statistic{min-width:10%;margin:0 0 1em}.ui.nine.statistics{margin:0 0 -1em}.ui.nine.statistics .statistic{min-width:11.11111111%;margin:0 0 1em}.ui.eight.statistics{margin:0 0 -1em}.ui.eight.statistics .statistic{min-width:12.5%;margin:0 0 1em}.ui.seven.statistics{margin:0 0 -1em}.ui.seven.statistics .statistic{min-width:14.28571429%;margin:0 0 1em}.ui.six.statistics{margin:0 0 -1em}.ui.six.statistics .statistic{min-width:16.66666667%;margin:0 0 1em}.ui.five.statistics{margin:0 0 -1em}.ui.five.statistics .statistic{min-width:20%;margin:0 0 1em}.ui.four.statistics{margin:0 0 -1em}.ui.four.statistics .statistic{min-width:25%;margin:0 0 1em}.ui.three.statistics{margin:0 0 -1em}.ui.three.statistics .statistic{min-width:33.33333333%;margin:0 0 1em}.ui.two.statistics{margin:0 0 -1em}.ui.two.statistics .statistic{min-width:50%;margin:0 0 1em}.ui.one.statistics{margin:0 0 -1em}.ui.one.statistics .statistic{min-width:100%;margin:0 0 1em}.ui.horizontal.statistic{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.horizontal.statistics{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0;max-width:none}.ui.horizontal.statistics .statistic{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:none;margin:1em 0}.ui.horizontal.statistic>.text.value,.ui.horizontal.statistics>.statistic>.text.value{min-height:0!important}.ui.horizontal.statistic>.value .icon,.ui.horizontal.statistics .statistic>.value .icon{width:1.18em}.ui.horizontal.statistic>.value,.ui.horizontal.statistics .statistic>.value{display:inline-block;vertical-align:middle}.ui.horizontal.statistic>.label,.ui.horizontal.statistics .statistic>.label{display:inline-block;vertical-align:middle;margin:0 0 0 .75em}.ui.red.statistic>.value,.ui.red.statistics .statistic>.value,.ui.statistics .red.statistic>.value{color:#db2828}.ui.orange.statistic>.value,.ui.orange.statistics .statistic>.value,.ui.statistics .orange.statistic>.value{color:#f2711c}.ui.statistics .yellow.statistic>.value,.ui.yellow.statistic>.value,.ui.yellow.statistics .statistic>.value{color:#fbbd08}.ui.olive.statistic>.value,.ui.olive.statistics .statistic>.value,.ui.statistics .olive.statistic>.value{color:#b5cc18}.ui.green.statistic>.value,.ui.green.statistics .statistic>.value,.ui.statistics .green.statistic>.value{color:#21ba45}.ui.statistics .teal.statistic>.value,.ui.teal.statistic>.value,.ui.teal.statistics .statistic>.value{color:#00b5ad}.ui.blue.statistic>.value,.ui.blue.statistics .statistic>.value,.ui.statistics .blue.statistic>.value{color:#2185d0}.ui.statistics .violet.statistic>.value,.ui.violet.statistic>.value,.ui.violet.statistics .statistic>.value{color:#6435c9}.ui.purple.statistic>.value,.ui.purple.statistics .statistic>.value,.ui.statistics .purple.statistic>.value{color:#a333c8}.ui.pink.statistic>.value,.ui.pink.statistics .statistic>.value,.ui.statistics .pink.statistic>.value{color:#e03997}.ui.brown.statistic>.value,.ui.brown.statistics .statistic>.value,.ui.statistics .brown.statistic>.value{color:#a5673f}.ui.grey.statistic>.value,.ui.grey.statistics .statistic>.value,.ui.statistics .grey.statistic>.value{color:#767676}.ui.inverted.statistic .value,.ui.inverted.statistics .statistic>.value{color:#fff}.ui.inverted.statistic .label,.ui.inverted.statistics .statistic>.label{color:rgba(255,255,255,.9)}.ui.inverted.red.statistic>.value,.ui.inverted.red.statistics .statistic>.value,.ui.statistics .inverted.red.statistic>.value{color:#ff695e}.ui.inverted.orange.statistic>.value,.ui.inverted.orange.statistics .statistic>.value,.ui.statistics .inverted.orange.statistic>.value{color:#ff851b}.ui.inverted.yellow.statistic>.value,.ui.inverted.yellow.statistics .statistic>.value,.ui.statistics .inverted.yellow.statistic>.value{color:#ffe21f}.ui.inverted.olive.statistic>.value,.ui.inverted.olive.statistics .statistic>.value,.ui.statistics .inverted.olive.statistic>.value{color:#d9e778}.ui.inverted.green.statistic>.value,.ui.inverted.green.statistics .statistic>.value,.ui.statistics .inverted.green.statistic>.value{color:#2ecc40}.ui.inverted.teal.statistic>.value,.ui.inverted.teal.statistics .statistic>.value,.ui.statistics .inverted.teal.statistic>.value{color:#6dffff}.ui.inverted.blue.statistic>.value,.ui.inverted.blue.statistics .statistic>.value,.ui.statistics .inverted.blue.statistic>.value{color:#54c8ff}.ui.inverted.violet.statistic>.value,.ui.inverted.violet.statistics .statistic>.value,.ui.statistics .inverted.violet.statistic>.value{color:#a291fb}.ui.inverted.purple.statistic>.value,.ui.inverted.purple.statistics .statistic>.value,.ui.statistics .inverted.purple.statistic>.value{color:#dc73ff}.ui.inverted.pink.statistic>.value,.ui.inverted.pink.statistics .statistic>.value,.ui.statistics .inverted.pink.statistic>.value{color:#ff8edf}.ui.inverted.brown.statistic>.value,.ui.inverted.brown.statistics .statistic>.value,.ui.statistics .inverted.brown.statistic>.value{color:#d67c1c}.ui.inverted.grey.statistic>.value,.ui.inverted.grey.statistics .statistic>.value,.ui.statistics .inverted.grey.statistic>.value{color:#dcddde}.ui[class*=\\\"left floated\\\"].statistic{float:left;margin:0 2em 1em 0}.ui[class*=\\\"right floated\\\"].statistic{float:right;margin:0 0 1em 2em}.ui.floated.statistic:last-child{margin-bottom:0}.ui.mini.statistic>.value,.ui.mini.statistics .statistic>.value{font-size:1.5rem!important}.ui.mini.horizontal.statistic>.value,.ui.mini.horizontal.statistics .statistic>.value{font-size:1.5rem!important}.ui.mini.statistic>.text.value,.ui.mini.statistics .statistic>.text.value{font-size:1rem!important}.ui.tiny.statistic>.value,.ui.tiny.statistics .statistic>.value{font-size:2rem!important}.ui.tiny.horizontal.statistic>.value,.ui.tiny.horizontal.statistics .statistic>.value{font-size:2rem!important}.ui.tiny.statistic>.text.value,.ui.tiny.statistics .statistic>.text.value{font-size:1rem!important}.ui.small.statistic>.value,.ui.small.statistics .statistic>.value{font-size:3rem!important}.ui.small.horizontal.statistic>.value,.ui.small.horizontal.statistics .statistic>.value{font-size:2rem!important}.ui.small.statistic>.text.value,.ui.small.statistics .statistic>.text.value{font-size:1rem!important}.ui.statistic>.value,.ui.statistics .statistic>.value{font-size:4rem!important}.ui.horizontal.statistic>.value,.ui.horizontal.statistics .statistic>.value{font-size:3rem!important}.ui.statistic>.text.value,.ui.statistics .statistic>.text.value{font-size:2rem!important}.ui.large.statistic>.value,.ui.large.statistics .statistic>.value{font-size:5rem!important}.ui.large.horizontal.statistic>.value,.ui.large.horizontal.statistics .statistic>.value{font-size:4rem!important}.ui.large.statistic>.text.value,.ui.large.statistics .statistic>.text.value{font-size:2.5rem!important}.ui.huge.statistic>.value,.ui.huge.statistics .statistic>.value{font-size:6rem!important}.ui.huge.horizontal.statistic>.value,.ui.huge.horizontal.statistics .statistic>.value{font-size:5rem!important}.ui.huge.statistic>.text.value,.ui.huge.statistics .statistic>.text.value{font-size:2.5rem!important}/*!\\n * # Semantic UI 2.4.0 - Accordion\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.accordion,.ui.accordion .accordion{max-width:100%}.ui.accordion .accordion{margin:1em 0 0;padding:0}.ui.accordion .accordion .title,.ui.accordion .title{cursor:pointer}.ui.accordion .title:not(.ui){padding:.5em 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;color:rgba(0,0,0,.87)}.ui.accordion .accordion .title~.content,.ui.accordion .title~.content{display:none}.ui.accordion:not(.styled) .accordion .title~.content:not(.ui),.ui.accordion:not(.styled) .title~.content:not(.ui){margin:'';padding:.5em 0 1em}.ui.accordion:not(.styled) .title~.content:not(.ui):last-child{padding-bottom:0}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{display:inline-block;float:none;opacity:1;width:1.25em;height:1em;margin:0 .25rem 0 0;padding:0;font-size:1em;-webkit-transition:opacity .1s ease,-webkit-transform .1s ease;transition:opacity .1s ease,-webkit-transform .1s ease;transition:transform .1s ease,opacity .1s ease;transition:transform .1s ease,opacity .1s ease,-webkit-transform .1s ease;vertical-align:baseline;-webkit-transform:none;transform:none}.ui.accordion.menu .item .title{display:block;padding:0}.ui.accordion.menu .item .title>.dropdown.icon{float:right;margin:.21425em 0 0 1em;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.ui.accordion .ui.header .dropdown.icon{font-size:1em;margin:0 .25rem 0 0}.ui.accordion .accordion .active.title .dropdown.icon,.ui.accordion .active.title .dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.accordion.menu .item .active.title>.dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.styled.accordion{width:600px}.ui.styled.accordion,.ui.styled.accordion .accordion{border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15)}.ui.styled.accordion .accordion .title,.ui.styled.accordion .title{margin:0;padding:.75em 1em;color:rgba(0,0,0,.4);font-weight:700;border-top:1px solid rgba(34,36,38,.15);-webkit-transition:background .1s ease,color .1s ease;transition:background .1s ease,color .1s ease}.ui.styled.accordion .accordion .title:first-child,.ui.styled.accordion>.title:first-child{border-top:none}.ui.styled.accordion .accordion .content,.ui.styled.accordion .content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .content{padding:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover,.ui.styled.accordion .active.title,.ui.styled.accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.styled.accordion .accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.accordion .accordion .active.content,.ui.accordion .active.content{display:block}.ui.fluid.accordion,.ui.fluid.accordion .accordion{width:100%}.ui.inverted.accordion .title:not(.ui){color:rgba(255,255,255,.9)}@font-face{font-family:Accordion;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggjB5AAAAC8AAAAYGNtYXAPfOIKAAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5Zryj6HgAAAFwAAAAyGhlYWT/0IhHAAACOAAAADZoaGVhApkB5wAAAnAAAAAkaG10eAJuABIAAAKUAAAAGGxvY2EAjABWAAACrAAAAA5tYXhwAAgAFgAAArwAAAAgbmFtZfC1n04AAALcAAABPHBvc3QAAwAAAAAEGAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQASAEkAtwFuABMAADc0PwE2FzYXFh0BFAcGJwYvASY1EgaABQgHBQYGBQcIBYAG2wcGfwcBAQcECf8IBAcBAQd/BgYAAAAAAQAAAEkApQFuABMAADcRNDc2MzIfARYVFA8BBiMiJyY1AAUGBwgFgAYGgAUIBwYFWwEACAUGBoAFCAcFgAYGBQcAAAABAAAAAQAAqWYls18PPPUACwIAAAAAAM/9o+4AAAAAz/2j7gAAAAAAtwFuAAAACAACAAAAAAAAAAEAAAHg/+AAAAIAAAAAAAC3AAEAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAQAAAAC3ABIAtwAAAAAAAAAKABQAHgBCAGQAAAABAAAABgAUAAEAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AAASwAAoAAAAABGgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAAS0AAAEtFpovuE9TLzIAAAIkAAAAYAAAAGAIIweQY21hcAAAAoQAAABMAAAATA984gpnYXNwAAAC0AAAAAgAAAAIAAAAEGhlYWQAAALYAAAANgAAADb/0IhHaGhlYQAAAxAAAAAkAAAAJAKZAedobXR4AAADNAAAABgAAAAYAm4AEm1heHAAAANMAAAABgAAAAYABlAAbmFtZQAAA1QAAAE8AAABPPC1n05wb3N0AAAEkAAAACAAAAAgAAMAAAEABAQAAQEBB3JhdGluZwABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeLa/iU+HQFHQAAAHkPHQAAAH4RHQAAAAkdAAABJBIABwEBBw0PERQZHnJhdGluZ3JhdGluZ3UwdTF1MjB1RjBEOXVGMERBAAACAYkABAAGAQEEBwoNVp38lA78lA78lA77lA773Z33bxWLkI2Qj44I9xT3FAWOj5CNkIuQi4+JjoePiI2Gi4YIi/uUBYuGiYeHiIiHh4mGi4aLho2Ijwj7FPcUBYeOiY+LkAgO+92L5hWL95QFi5CNkI6Oj4+PjZCLkIuQiY6HCPcU+xQFj4iNhouGi4aJh4eICPsU+xQFiIeGiYaLhouHjYePiI6Jj4uQCA74lBT4lBWLDAoAAAAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAEAADfYOJZfDzz1AAsCAAAAAADP/aPuAAAAAM/9o+4AAAAAALcBbgAAAAgAAgAAAAAAAAABAAAB4P/gAAACAAAAAAAAtwABAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAEAAAAAtwASALcAAAAAUAAABgAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('woff');font-weight:400;font-style:normal}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{font-family:Accordion;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.accordion .accordion .title .dropdown.icon:before,.ui.accordion .title .dropdown.icon:before{content:'\\\\f0da'}/*!\\n * # Semantic UI 2.4.0 - Checkbox\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.checkbox{position:relative;display:inline-block;-webkit-backface-visibility:hidden;backface-visibility:hidden;outline:0;vertical-align:baseline;font-style:normal;min-height:17px;font-size:1rem;line-height:17px;min-width:17px}.ui.checkbox input[type=checkbox],.ui.checkbox input[type=radio]{cursor:pointer;position:absolute;top:0;left:0;opacity:0!important;outline:0;z-index:3;width:17px;height:17px}.ui.checkbox .box,.ui.checkbox label{cursor:auto;position:relative;display:block;padding-left:1.85714em;outline:0;font-size:1em}.ui.checkbox .box:before,.ui.checkbox label:before{position:absolute;top:0;left:0;width:17px;height:17px;content:'';background:#fff;border-radius:.21428571rem;-webkit-transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;border:1px solid #d4d4d5}.ui.checkbox .box:after,.ui.checkbox label:after{position:absolute;font-size:14px;top:0;left:0;width:17px;height:17px;text-align:center;opacity:0;color:rgba(0,0,0,.87);-webkit-transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease}.ui.checkbox label,.ui.checkbox+label{color:rgba(0,0,0,.87);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.checkbox+label{vertical-align:middle}.ui.checkbox .box:hover::before,.ui.checkbox label:hover::before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox label:hover,.ui.checkbox+label:hover{color:rgba(0,0,0,.8)}.ui.checkbox .box:active::before,.ui.checkbox label:active::before{background:#f9fafb;border-color:rgba(34,36,38,.35)}.ui.checkbox .box:active::after,.ui.checkbox label:active::after{color:rgba(0,0,0,.95)}.ui.checkbox input:active~label{color:rgba(0,0,0,.95)}.ui.checkbox input:focus~.box:before,.ui.checkbox input:focus~label:before{background:#fff;border-color:#96c8da}.ui.checkbox input:focus~.box:after,.ui.checkbox input:focus~label:after{color:rgba(0,0,0,.95)}.ui.checkbox input:focus~label{color:rgba(0,0,0,.95)}.ui.checkbox input:checked~.box:before,.ui.checkbox input:checked~label:before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:checked~.box:after,.ui.checkbox input:checked~label:after{opacity:1;color:rgba(0,0,0,.95)}.ui.checkbox input:not([type=radio]):indeterminate~.box:before,.ui.checkbox input:not([type=radio]):indeterminate~label:before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:not([type=radio]):indeterminate~.box:after,.ui.checkbox input:not([type=radio]):indeterminate~label:after{opacity:1;color:rgba(0,0,0,.95)}.ui.checkbox input:checked:focus~.box:before,.ui.checkbox input:checked:focus~label:before,.ui.checkbox input:not([type=radio]):indeterminate:focus~.box:before,.ui.checkbox input:not([type=radio]):indeterminate:focus~label:before{background:#fff;border-color:#96c8da}.ui.checkbox input:checked:focus~.box:after,.ui.checkbox input:checked:focus~label:after,.ui.checkbox input:not([type=radio]):indeterminate:focus~.box:after,.ui.checkbox input:not([type=radio]):indeterminate:focus~label:after{color:rgba(0,0,0,.95)}.ui.read-only.checkbox,.ui.read-only.checkbox label{cursor:default}.ui.checkbox input[disabled]~.box:after,.ui.checkbox input[disabled]~label,.ui.disabled.checkbox .box:after,.ui.disabled.checkbox label{cursor:default!important;opacity:.5;color:#000}.ui.checkbox input.hidden{z-index:-1}.ui.checkbox input.hidden+label{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui.radio.checkbox{min-height:15px}.ui.radio.checkbox .box,.ui.radio.checkbox label{padding-left:1.85714em}.ui.radio.checkbox .box:before,.ui.radio.checkbox label:before{content:'';-webkit-transform:none;transform:none;width:15px;height:15px;border-radius:500rem;top:1px;left:0}.ui.radio.checkbox .box:after,.ui.radio.checkbox label:after{border:none;content:''!important;width:15px;height:15px;line-height:15px}.ui.radio.checkbox .box:after,.ui.radio.checkbox label:after{top:1px;left:0;width:15px;height:15px;border-radius:500rem;-webkit-transform:scale(.46666667);transform:scale(.46666667);background-color:rgba(0,0,0,.87)}.ui.radio.checkbox input:focus~.box:before,.ui.radio.checkbox input:focus~label:before{background-color:#fff}.ui.radio.checkbox input:focus~.box:after,.ui.radio.checkbox input:focus~label:after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:indeterminate~.box:after,.ui.radio.checkbox input:indeterminate~label:after{opacity:0}.ui.radio.checkbox input:checked~.box:before,.ui.radio.checkbox input:checked~label:before{background-color:#fff}.ui.radio.checkbox input:checked~.box:after,.ui.radio.checkbox input:checked~label:after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:focus:checked~.box:before,.ui.radio.checkbox input:focus:checked~label:before{background-color:#fff}.ui.radio.checkbox input:focus:checked~.box:after,.ui.radio.checkbox input:focus:checked~label:after{background-color:rgba(0,0,0,.95)}.ui.slider.checkbox{min-height:1.25rem}.ui.slider.checkbox input{width:3.5rem;height:1.25rem}.ui.slider.checkbox .box,.ui.slider.checkbox label{padding-left:4.5rem;line-height:1rem;color:rgba(0,0,0,.4)}.ui.slider.checkbox .box:before,.ui.slider.checkbox label:before{display:block;position:absolute;content:'';border:none!important;left:0;z-index:1;top:.4rem;background-color:rgba(0,0,0,.05);width:3.5rem;height:.21428571rem;-webkit-transform:none;transform:none;border-radius:500rem;-webkit-transition:background .3s ease;transition:background .3s ease}.ui.slider.checkbox .box:after,.ui.slider.checkbox label:after{background:#fff -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#fff -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:''!important;opacity:1;z-index:2;border:none;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:-.25rem;left:0;-webkit-transform:none;transform:none;border-radius:500rem;-webkit-transition:left .3s ease;transition:left .3s ease}.ui.slider.checkbox input:focus~.box:before,.ui.slider.checkbox input:focus~label:before{background-color:rgba(0,0,0,.15);border:none}.ui.slider.checkbox .box:hover,.ui.slider.checkbox label:hover{color:rgba(0,0,0,.8)}.ui.slider.checkbox .box:hover::before,.ui.slider.checkbox label:hover::before{background:rgba(0,0,0,.15)}.ui.slider.checkbox input:checked~.box,.ui.slider.checkbox input:checked~label{color:rgba(0,0,0,.95)!important}.ui.slider.checkbox input:checked~.box:before,.ui.slider.checkbox input:checked~label:before{background-color:#545454!important}.ui.slider.checkbox input:checked~.box:after,.ui.slider.checkbox input:checked~label:after{left:2rem}.ui.slider.checkbox input:focus:checked~.box,.ui.slider.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)!important}.ui.slider.checkbox input:focus:checked~.box:before,.ui.slider.checkbox input:focus:checked~label:before{background-color:#000!important}.ui.toggle.checkbox{min-height:1.5rem}.ui.toggle.checkbox input{width:3.5rem;height:1.5rem}.ui.toggle.checkbox .box,.ui.toggle.checkbox label{min-height:1.5rem;padding-left:4.5rem;color:rgba(0,0,0,.87)}.ui.toggle.checkbox label{padding-top:.15em}.ui.toggle.checkbox .box:before,.ui.toggle.checkbox label:before{display:block;position:absolute;content:'';z-index:1;-webkit-transform:none;transform:none;border:none;top:0;background:rgba(0,0,0,.05);-webkit-box-shadow:none;box-shadow:none;width:3.5rem;height:1.5rem;border-radius:500rem}.ui.toggle.checkbox .box:after,.ui.toggle.checkbox label:after{background:#fff -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#fff -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:''!important;opacity:1;z-index:2;border:none;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:0;left:0;border-radius:500rem;-webkit-transition:background .3s ease,left .3s ease;transition:background .3s ease,left .3s ease}.ui.toggle.checkbox input~.box:after,.ui.toggle.checkbox input~label:after{left:-.05rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus~.box:before,.ui.toggle.checkbox input:focus~label:before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox .box:hover::before,.ui.toggle.checkbox label:hover::before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox input:checked~.box,.ui.toggle.checkbox input:checked~label{color:rgba(0,0,0,.95)!important}.ui.toggle.checkbox input:checked~.box:before,.ui.toggle.checkbox input:checked~label:before{background-color:#2185d0!important}.ui.toggle.checkbox input:checked~.box:after,.ui.toggle.checkbox input:checked~label:after{left:2.15rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus:checked~.box,.ui.toggle.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)!important}.ui.toggle.checkbox input:focus:checked~.box:before,.ui.toggle.checkbox input:focus:checked~label:before{background-color:#0d71bb!important}.ui.fitted.checkbox .box,.ui.fitted.checkbox label{padding-left:0!important}.ui.fitted.toggle.checkbox{width:3.5rem}.ui.fitted.slider.checkbox{width:3.5rem}@font-face{font-family:Checkbox;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBD8AAAC8AAAAYGNtYXAYVtCJAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zn4huwUAAAF4AAABYGhlYWQGPe1ZAAAC2AAAADZoaGVhB30DyAAAAxAAAAAkaG10eBBKAEUAAAM0AAAAHGxvY2EAmgESAAADUAAAABBtYXhwAAkALwAAA2AAAAAgbmFtZSC8IugAAAOAAAABknBvc3QAAwAAAAAFFAAAACAAAwMTAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADoAgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6AL//f//AAAAAAAg6AD//f//AAH/4xgEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAEUAUQO7AvgAGgAAARQHAQYjIicBJjU0PwE2MzIfAQE2MzIfARYVA7sQ/hQQFhcQ/uMQEE4QFxcQqAF2EBcXEE4QAnMWEP4UEBABHRAXFhBOEBCoAXcQEE4QFwAAAAABAAABbgMlAkkAFAAAARUUBwYjISInJj0BNDc2MyEyFxYVAyUQEBf9SRcQEBAQFwK3FxAQAhJtFxAQEBAXbRcQEBAQFwAAAAABAAAASQMlA24ALAAAARUUBwYrARUUBwYrASInJj0BIyInJj0BNDc2OwE1NDc2OwEyFxYdATMyFxYVAyUQEBfuEBAXbhYQEO4XEBAQEBfuEBAWbhcQEO4XEBACEm0XEBDuFxAQEBAX7hAQF20XEBDuFxAQEBAX7hAQFwAAAQAAAAIAAHRSzT9fDzz1AAsEAAAAAADRsdR3AAAAANGx1HcAAAAAA7sDbgAAAAgAAgAAAAAAAAABAAADwP/AAAAEAAAAAAADuwABAAAAAAAAAAAAAAAAAAAABwQAAAAAAAAAAAAAAAIAAAAEAABFAyUAAAMlAAAAAAAAAAoAFAAeAE4AcgCwAAEAAAAHAC0AAQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAIAAAAAQAAAAAAAgAHAGkAAQAAAAAAAwAIADkAAQAAAAAABAAIAH4AAQAAAAAABQALABgAAQAAAAAABgAIAFEAAQAAAAAACgAaAJYAAwABBAkAAQAQAAgAAwABBAkAAgAOAHAAAwABBAkAAwAQAEEAAwABBAkABAAQAIYAAwABBAkABQAWACMAAwABBAkABgAQAFkAAwABBAkACgA0ALBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhWZXJzaW9uIDIuMABWAGUAcgBzAGkAbwBuACAAMgAuADBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhDaGVja2JveABDAGgAZQBjAGsAYgBvAHhSZWd1bGFyAFIAZQBnAHUAbABhAHJDaGVja2JveABDAGgAZQBjAGsAYgBvAHhGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype')}.ui.checkbox .box:after,.ui.checkbox label:after{font-family:Checkbox}.ui.checkbox input:checked~.box:after,.ui.checkbox input:checked~label:after{content:'\\\\e800'}.ui.checkbox input:indeterminate~.box:after,.ui.checkbox input:indeterminate~label:after{font-size:12px;content:'\\\\e801'}/*!\\n * # Semantic UI 2.4.0 - Dimmer\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.dimmable:not(body){position:relative}.ui.dimmer{display:none;position:absolute;top:0!important;left:0!important;width:100%;height:100%;text-align:center;vertical-align:middle;padding:1em;background-color:rgba(0,0,0,.85);opacity:0;line-height:1;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-transition:background-color .5s linear;transition:background-color .5s linear;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;color:#fff}.ui.segment>.ui.dimmer{border-radius:inherit!important}.ui.dimmer:not(.inverted)::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.dimmed.dimmable>.ui.animating.legacy.dimmer,.dimmed.dimmable>.ui.visible.legacy.dimmer,.ui.active.legacy.dimmer{display:block}.ui[class*=\\\"top aligned\\\"].dimmer{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.ui[class*=\\\"bottom aligned\\\"].dimmer{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.ui.page.dimmer{position:fixed;-webkit-transform-style:'';transform-style:'';-webkit-perspective:2000px;perspective:2000px;-webkit-transform-origin:center center;transform-origin:center center}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}.blurring.dimmable>:not(.dimmer){-webkit-filter:blur(0) grayscale(0);filter:blur(0) grayscale(0);-webkit-transition:.8s -webkit-filter ease;transition:.8s -webkit-filter ease;transition:.8s filter ease;transition:.8s filter ease,.8s -webkit-filter ease}.blurring.dimmed.dimmable>:not(.dimmer){-webkit-filter:blur(5px) grayscale(.7);filter:blur(5px) grayscale(.7)}.blurring.dimmable>.dimmer{background-color:rgba(0,0,0,.6)}.blurring.dimmable>.inverted.dimmer{background-color:rgba(255,255,255,.6)}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.ui.inverted.dimmer{background-color:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content>*{color:#fff}.ui.simple.dimmer{display:block;overflow:hidden;opacity:1;width:0%;height:0%;z-index:-100;background-color:rgba(0,0,0,0)}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background-color:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,.85)}/*!\\n * # Semantic UI 2.4.0 - Dropdown\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.dropdown{cursor:pointer;position:relative;display:inline-block;outline:0;text-align:left;-webkit-transition:width .1s ease,-webkit-box-shadow .1s ease;transition:width .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,width .1s ease;transition:box-shadow .1s ease,width .1s ease,-webkit-box-shadow .1s ease;-webkit-tap-highlight-color:transparent}.ui.dropdown .menu{cursor:auto;position:absolute;display:none;outline:0;top:100%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;margin:0;padding:0 0;background:#fff;font-size:1em;text-shadow:none;text-align:left;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15);border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;z-index:11;will-change:transform,opacity}.ui.dropdown .menu>*{white-space:nowrap}.ui.dropdown>input:not(.search):first-child,.ui.dropdown>select{display:none!important}.ui.dropdown>.dropdown.icon{position:relative;width:auto;font-size:.85714286em;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon{width:auto;float:right;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon+.text{margin-right:1em}.ui.dropdown>.text{display:inline-block;-webkit-transition:none;transition:none}.ui.dropdown .menu>.item{position:relative;cursor:pointer;display:block;border:none;height:auto;text-align:left;border-top:none;line-height:1em;color:rgba(0,0,0,.87);padding:.78571429rem 1.14285714rem!important;font-size:1rem;text-transform:none;font-weight:400;-webkit-box-shadow:none;box-shadow:none;-webkit-touch-callout:none}.ui.dropdown .menu>.item:first-child{border-top-width:0}.ui.dropdown .menu .item>[class*=\\\"right floated\\\"],.ui.dropdown>.text>[class*=\\\"right floated\\\"]{float:right!important;margin-right:0!important;margin-left:1em!important}.ui.dropdown .menu .item>[class*=\\\"left floated\\\"],.ui.dropdown>.text>[class*=\\\"left floated\\\"]{float:left!important;margin-left:0!important;margin-right:1em!important}.ui.dropdown .menu .item>.flag.floated,.ui.dropdown .menu .item>.icon.floated,.ui.dropdown .menu .item>.image.floated,.ui.dropdown .menu .item>img.floated{margin-top:0}.ui.dropdown .menu>.header{margin:1rem 0 .75rem;padding:0 1.14285714rem;color:rgba(0,0,0,.85);font-size:.78571429em;font-weight:700;text-transform:uppercase}.ui.dropdown .menu>.divider{border-top:1px solid rgba(34,36,38,.1);height:0;margin:.5em 0}.ui.dropdown.dropdown .menu>.input{width:auto;display:-webkit-box;display:-ms-flexbox;display:flex;margin:1.14285714rem .78571429rem;min-width:10rem}.ui.dropdown .menu>.header+.input{margin-top:0}.ui.dropdown .menu>.input:not(.transparent) input{padding:.5em 1em}.ui.dropdown .menu>.input:not(.transparent) .button,.ui.dropdown .menu>.input:not(.transparent) .icon,.ui.dropdown .menu>.input:not(.transparent) .label{padding-top:.5em;padding-bottom:.5em}.ui.dropdown .menu>.item>.description,.ui.dropdown>.text>.description{float:right;margin:0 0 0 1em;color:rgba(0,0,0,.4)}.ui.dropdown .menu>.message{padding:.78571429rem 1.14285714rem;font-weight:400}.ui.dropdown .menu>.message:not(.ui){color:rgba(0,0,0,.4)}.ui.dropdown .menu .menu{top:0!important;left:100%;right:auto;margin:0 0 0 -.5em!important;border-radius:.28571429rem!important;z-index:21!important}.ui.dropdown .menu .menu:after{display:none}.ui.dropdown>.text>.flag,.ui.dropdown>.text>.icon,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.icon,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.icon,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.flag,.ui.dropdown>.text>.icon,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>img{margin-left:0;float:none;margin-right:.78571429rem}.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.image,.ui.dropdown>.text>img{display:inline-block;vertical-align:top;width:auto;margin-top:-.5em;margin-bottom:-.5em;max-height:2em}.ui.dropdown .ui.menu>.item:before,.ui.menu .ui.dropdown .menu>.item:before{display:none}.ui.menu .ui.dropdown .menu .active.item{border-left:none}.ui.buttons>.ui.dropdown:last-child .menu,.ui.menu .right.dropdown.item .menu,.ui.menu .right.menu .dropdown:last-child .menu{left:auto;right:0}.ui.label.dropdown .menu{min-width:100%}.ui.dropdown.icon.button>.dropdown.icon{margin:0}.ui.button.dropdown .menu{min-width:100%}.ui.selection.dropdown{cursor:pointer;word-wrap:break-word;line-height:1em;white-space:normal;outline:0;-webkit-transform:rotateZ(0);transform:rotateZ(0);min-width:14em;min-height:2.71428571em;background:#fff;display:inline-block;padding:.78571429em 2.1em .78571429em 1em;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-transition:width .1s ease,-webkit-box-shadow .1s ease;transition:width .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,width .1s ease;transition:box-shadow .1s ease,width .1s ease,-webkit-box-shadow .1s ease}.ui.selection.dropdown.active,.ui.selection.dropdown.visible{z-index:10}select.ui.dropdown{height:38px;padding:.5em;border:1px solid rgba(34,36,38,.15);visibility:visible}.ui.selection.dropdown>.delete.icon,.ui.selection.dropdown>.dropdown.icon,.ui.selection.dropdown>.search.icon{cursor:pointer;position:absolute;width:auto;height:auto;line-height:1.21428571em;top:.78571429em;right:1em;z-index:3;margin:-.78571429em;padding:.91666667em;opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.compact.selection.dropdown{min-width:0}.ui.selection.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch;border-top-width:0!important;width:auto;outline:0;margin:0 -1px;min-width:calc(100% + 2px);width:calc(100% + 2px);border-radius:0 0 .28571429rem .28571429rem;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15);-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.selection.dropdown .menu:after,.ui.selection.dropdown .menu:before{display:none}.ui.selection.dropdown .menu>.message{padding:.78571429rem 1.14285714rem}@media only screen and (max-width:767px){.ui.selection.dropdown .menu{max-height:8.01428571rem}}@media only screen and (min-width:768px){.ui.selection.dropdown .menu{max-height:10.68571429rem}}@media only screen and (min-width:992px){.ui.selection.dropdown .menu{max-height:16.02857143rem}}@media only screen and (min-width:1920px){.ui.selection.dropdown .menu{max-height:21.37142857rem}}.ui.selection.dropdown .menu>.item{border-top:1px solid #fafafa;padding:.78571429rem 1.14285714rem!important;white-space:normal;word-wrap:normal}.ui.selection.dropdown .menu>.hidden.addition.item{display:none}.ui.selection.dropdown:hover{border-color:rgba(34,36,38,.35);-webkit-box-shadow:none;box-shadow:none}.ui.selection.active.dropdown{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.dropdown:focus{border-color:#96c8da;-webkit-box-shadow:none;box-shadow:none}.ui.selection.dropdown:focus .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.visible.dropdown>.text:not(.default){font-weight:400;color:rgba(0,0,0,.8)}.ui.selection.active.dropdown:hover{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown:hover .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.active.selection.dropdown>.dropdown.icon,.ui.visible.selection.dropdown>.dropdown.icon{opacity:'';z-index:3}.ui.active.selection.dropdown{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.ui.active.empty.selection.dropdown{border-radius:.28571429rem!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.active.empty.selection.dropdown .menu{border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.search.dropdown{min-width:''}.ui.search.dropdown>input.search{background:none transparent!important;border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;cursor:text;top:0;left:1px;width:100%;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);padding:inherit}.ui.search.dropdown>input.search{position:absolute;z-index:2}.ui.search.dropdown>.text{cursor:text;position:relative;left:1px;z-index:3}.ui.search.selection.dropdown>input.search{line-height:1.21428571em;padding:.67857143em 2.1em .67857143em 1em}.ui.search.selection.dropdown>span.sizer{line-height:1.21428571em;padding:.67857143em 2.1em .67857143em 1em;display:none;white-space:pre}.ui.search.dropdown.active>input.search,.ui.search.dropdown.visible>input.search{cursor:auto}.ui.search.dropdown.active>.text,.ui.search.dropdown.visible>.text{pointer-events:none}.ui.active.search.dropdown input.search:focus+.text .flag,.ui.active.search.dropdown input.search:focus+.text .icon{opacity:.45}.ui.active.search.dropdown input.search:focus+.text{color:rgba(115,115,115,.87)!important}.ui.search.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch}@media only screen and (max-width:767px){.ui.search.dropdown .menu{max-height:8.01428571rem}}@media only screen and (min-width:768px){.ui.search.dropdown .menu{max-height:10.68571429rem}}@media only screen and (min-width:992px){.ui.search.dropdown .menu{max-height:16.02857143rem}}@media only screen and (min-width:1920px){.ui.search.dropdown .menu{max-height:21.37142857rem}}.ui.multiple.dropdown{padding:.22619048em 2.1em .22619048em .35714286em}.ui.multiple.dropdown .menu{cursor:auto}.ui.multiple.search.dropdown,.ui.multiple.search.dropdown>input.search{cursor:text}.ui.multiple.dropdown>.label{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:inline-block;vertical-align:top;white-space:normal;font-size:1em;padding:.35714286em .78571429em;margin:.14285714rem .28571429rem .14285714rem 0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.multiple.dropdown .dropdown.icon{margin:'';padding:''}.ui.multiple.dropdown>.text{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.dropdown>.label~input.search{margin-left:.14285714em!important}.ui.multiple.dropdown>.label~.text{display:none}.ui.multiple.search.dropdown>.text{display:inline-block;position:absolute;top:0;left:0;padding:inherit;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.search.dropdown>.label~.text{display:none}.ui.multiple.search.dropdown>input.search{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;width:2.2em;line-height:1.21428571em}.ui.inline.dropdown{cursor:pointer;display:inline-block;color:inherit}.ui.inline.dropdown .dropdown.icon{margin:0 .21428571em 0 .21428571em;vertical-align:baseline}.ui.inline.dropdown>.text{font-weight:700}.ui.inline.dropdown .menu{cursor:auto;margin-top:.21428571em;border-radius:.28571429rem}.ui.dropdown .menu .active.item{background:0 0;font-weight:700;color:rgba(0,0,0,.95);-webkit-box-shadow:none;box-shadow:none;z-index:12}.ui.dropdown .menu>.item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);z-index:13}.ui.loading.dropdown>i.icon{height:1em!important}.ui.loading.selection.dropdown>i.icon{padding:1.5em 1.28571429em!important}.ui.loading.dropdown>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.dropdown>i.icon:after{position:absolute;content:'';top:50%;left:50%;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:dropdown-spin .6s linear;animation:dropdown-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em}.ui.loading.dropdown.button>i.icon:after,.ui.loading.dropdown.button>i.icon:before{display:none}@-webkit-keyframes dropdown-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dropdown-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.default.dropdown:not(.button)>.text,.ui.dropdown:not(.button)>.default.text{color:rgba(191,191,191,.87)}.ui.default.dropdown:not(.button)>input:focus~.text,.ui.dropdown:not(.button)>input:focus~.default.text{color:rgba(115,115,115,.87)}.ui.loading.dropdown>.text{-webkit-transition:none;transition:none}.ui.dropdown .loading.menu{display:block;visibility:hidden;z-index:-1}.ui.dropdown>.loading.menu{left:0!important;right:auto!important}.ui.dropdown>.menu .loading.menu{left:100%!important;right:auto!important}.ui.dropdown .menu .selected.item,.ui.dropdown.selected{background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.dropdown>.filtered.text{visibility:hidden}.ui.dropdown .filtered.item{display:none!important}.ui.dropdown.error,.ui.dropdown.error>.default.text,.ui.dropdown.error>.text{color:#9f3a38}.ui.selection.dropdown.error{background:#fff6f6;border-color:#e0b4b4}.ui.selection.dropdown.error:hover{border-color:#e0b4b4}.ui.dropdown.error>.menu,.ui.dropdown.error>.menu .menu{border-color:#e0b4b4}.ui.dropdown.error>.menu>.item{color:#9f3a38}.ui.multiple.selection.error.dropdown>.label{border-color:#e0b4b4}.ui.dropdown.error>.menu>.item:hover{background-color:#fff2f2}.ui.dropdown.error>.menu .active.item{background-color:#fdcfcf}.ui.dropdown>.clear.dropdown.icon{opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.dropdown>.clear.dropdown.icon:hover{opacity:1}.ui.disabled.dropdown,.ui.dropdown .menu>.disabled.item{cursor:default;pointer-events:none;opacity:.45}.ui.dropdown .menu{left:0}.ui.dropdown .menu .right.menu,.ui.dropdown .right.menu>.menu{left:100%!important;right:auto!important;border-radius:.28571429rem!important}.ui.dropdown>.left.menu{left:auto!important;right:0!important}.ui.dropdown .menu .left.menu,.ui.dropdown>.left.menu .menu{left:auto;right:100%;margin:0 -.5em 0 0!important;border-radius:.28571429rem!important}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon+.text,.ui.dropdown .left.menu .item .dropdown.icon+.text{margin-left:1em;margin-right:0}.ui.upward.dropdown>.menu{top:auto;bottom:100%;-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.08);box-shadow:0 0 3px 0 rgba(0,0,0,.08);border-radius:.28571429rem .28571429rem 0 0}.ui.dropdown .upward.menu{top:auto!important;bottom:0!important}.ui.simple.upward.active.dropdown,.ui.simple.upward.dropdown:hover{border-radius:.28571429rem .28571429rem 0 0!important}.ui.upward.dropdown.button:not(.pointing):not(.floating).active{border-radius:.28571429rem .28571429rem 0 0}.ui.upward.selection.dropdown .menu{border-top-width:1px!important;border-bottom-width:0!important;-webkit-box-shadow:0 -2px 3px 0 rgba(0,0,0,.08);box-shadow:0 -2px 3px 0 rgba(0,0,0,.08)}.ui.upward.selection.dropdown:hover{-webkit-box-shadow:0 0 2px 0 rgba(0,0,0,.05);box-shadow:0 0 2px 0 rgba(0,0,0,.05)}.ui.active.upward.selection.dropdown{border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.selection.dropdown.visible{-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.08);box-shadow:0 0 3px 0 rgba(0,0,0,.08);border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.active.selection.dropdown:hover{-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.05);box-shadow:0 0 3px 0 rgba(0,0,0,.05)}.ui.upward.active.selection.dropdown:hover .menu{-webkit-box-shadow:0 -2px 3px 0 rgba(0,0,0,.08);box-shadow:0 -2px 3px 0 rgba(0,0,0,.08)}.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{overflow-x:hidden;overflow-y:auto}.ui.scrolling.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch;min-width:100%!important;width:auto!important}.ui.dropdown .scrolling.menu{position:static;overflow-y:auto;border:none;-webkit-box-shadow:none!important;box-shadow:none!important;border-radius:0!important;margin:0!important;min-width:100%!important;width:auto!important;border-top:1px solid rgba(34,36,38,.15)}.ui.dropdown .scrolling.menu>.item.item.item,.ui.scrolling.dropdown .menu .item.item.item{border-top:none}.ui.dropdown .scrolling.menu .item:first-child,.ui.scrolling.dropdown .menu .item:first-child{border-top:none}.ui.dropdown>.animating.menu .scrolling.menu,.ui.dropdown>.visible.menu .scrolling.menu{display:block}@media all and (-ms-high-contrast:none){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{min-width:calc(100% - 17px)}}@media only screen and (max-width:767px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:10.28571429rem}}@media only screen and (min-width:768px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:15.42857143rem}}@media only screen and (min-width:992px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}}@media only screen and (min-width:1920px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}}.ui.simple.dropdown .menu:after,.ui.simple.dropdown .menu:before{display:none}.ui.simple.dropdown .menu{position:absolute;display:block;overflow:hidden;top:-9999px!important;opacity:0;width:0;height:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.simple.active.dropdown,.ui.simple.dropdown:hover{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.ui.simple.active.dropdown>.menu,.ui.simple.dropdown:hover>.menu{overflow:visible;width:auto;height:auto;top:100%!important;opacity:1}.ui.simple.dropdown:hover>.menu>.item:hover>.menu,.ui.simple.dropdown>.menu>.item:active>.menu{overflow:visible;width:auto;height:auto;top:0!important;left:100%!important;opacity:1}.ui.simple.disabled.dropdown:hover .menu{display:none;height:0;width:0;overflow:hidden}.ui.simple.visible.dropdown>.menu{display:block}.ui.fluid.dropdown{display:block;width:100%;min-width:0}.ui.fluid.dropdown>.dropdown.icon{float:right}.ui.floating.dropdown .menu{left:0;right:auto;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)!important;box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)!important;border-radius:.28571429rem!important}.ui.floating.dropdown>.menu{margin-top:.5em!important;border-radius:.28571429rem!important}.ui.pointing.dropdown>.menu{top:100%;margin-top:.78571429rem;border-radius:.28571429rem}.ui.pointing.dropdown>.menu:after{display:block;position:absolute;pointer-events:none;content:'';visibility:visible;-webkit-transform:rotate(45deg);transform:rotate(45deg);width:.5em;height:.5em;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);background:#fff;z-index:2}.ui.pointing.dropdown>.menu:after{top:-.25em;left:50%;margin:0 0 0 -.25em}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu:after{top:-.25em;left:1em;right:auto;margin:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ui.top.right.pointing.dropdown>.menu{top:100%;bottom:auto;right:0;left:auto;margin:1em 0 0}.ui.top.pointing.dropdown>.left.menu:after,.ui.top.right.pointing.dropdown>.menu:after{top:-.25em;left:auto!important;right:1em!important;margin:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ui.left.pointing.dropdown>.menu{top:0;left:100%;right:auto;margin:0 0 0 1em}.ui.left.pointing.dropdown>.menu:after{top:1em;left:-.25em;margin:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu{left:auto!important;right:100%!important;margin:0 1em 0 0}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu:after{top:1em;left:auto;right:-.25em;margin:0;-webkit-transform:rotate(135deg);transform:rotate(135deg)}.ui.right.pointing.dropdown>.menu{top:0;left:auto;right:100%;margin:0 1em 0 0}.ui.right.pointing.dropdown>.menu:after{top:1em;left:auto;right:-.25em;margin:0;-webkit-transform:rotate(135deg);transform:rotate(135deg)}.ui.bottom.pointing.dropdown>.menu{top:auto;bottom:100%;left:0;right:auto;margin:0 0 1em}.ui.bottom.pointing.dropdown>.menu:after{top:auto;bottom:-.25em;right:auto;margin:0;-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.ui.bottom.pointing.dropdown>.menu .menu{top:auto!important;bottom:0!important}.ui.bottom.left.pointing.dropdown>.menu{left:0;right:auto}.ui.bottom.left.pointing.dropdown>.menu:after{left:1em;right:auto}.ui.bottom.right.pointing.dropdown>.menu{right:0;left:auto}.ui.bottom.right.pointing.dropdown>.menu:after{left:auto;right:1em}.ui.pointing.upward.dropdown .menu,.ui.top.pointing.upward.dropdown .menu{top:auto!important;bottom:100%!important;margin:0 0 .78571429rem;border-radius:.28571429rem}.ui.pointing.upward.dropdown .menu:after,.ui.top.pointing.upward.dropdown .menu:after{top:100%!important;bottom:auto!important;-webkit-box-shadow:1px 1px 0 0 rgba(34,36,38,.15);box-shadow:1px 1px 0 0 rgba(34,36,38,.15);margin:-.25em 0 0}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 1em 0 0}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after{top:auto!important;bottom:0!important;margin:0 0 1em 0;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 0 0 1em}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after{top:auto!important;bottom:0!important;margin:0 0 1em 0;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}@font-face{font-family:Dropdown;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAVgAA8AAAAACFAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABWAAAABwAAAAchGgaq0dERUYAAAF0AAAAHAAAAB4AJwAPT1MvMgAAAZAAAABDAAAAVnW4TJdjbWFwAAAB1AAAAEsAAAFS8CcaqmN2dCAAAAIgAAAABAAAAAQAEQFEZ2FzcAAAAiQAAAAIAAAACP//AANnbHlmAAACLAAAAQoAAAGkrRHP9WhlYWQAAAM4AAAAMAAAADYPK8YyaGhlYQAAA2gAAAAdAAAAJANCAb1obXR4AAADiAAAACIAAAAiCBkAOGxvY2EAAAOsAAAAFAAAABQBnAIybWF4cAAAA8AAAAAfAAAAIAEVAF5uYW1lAAAD4AAAATAAAAKMFGlj5HBvc3QAAAUQAAAARgAAAHJoedjqd2ViZgAABVgAAAAGAAAABrO7W5UAAAABAAAAANXulPUAAAAA1r4hgAAAAADXu2Q1eNpjYGRgYOABYjEgZmJgBEIOIGYB8xgAA/YAN3jaY2BktGOcwMDKwMI4jTGNgYHBHUp/ZZBkaGFgYGJgZWbACgLSXFMYHFT/fLjFeOD/AQY9xjMMbkBhRpAcAN48DQYAeNpjYGBgZoBgGQZGBhDwAfIYwXwWBgMgzQGETAwMqn8+8H649f8/lHX9//9b7Pzf+fWgusCAkY0BzmUE6gHpQwGMDMMeAACbxg7SAAARAUQAAAAB//8AAnjadZBPSsNAGMXfS+yMqYgOhpSuSlKadmUhiVEhEMQzFF22m17BbbvzCh5BXCUn6EG8gjeQ4DepwYo4i+/ffL95j4EDA+CFC7jQuKyIeVHrI3wkleq9F7XrSInKteOeHdda8bOoaeepSc00NWPz/LRec9G8GabyGtEdF7h19z033GAMTK7zbM42xNEZpzYof0RtQ5CUHAQJ73OtVyutc+3b7Ou//b8XNlsPx3jgjUifABdhEohKJJL5iM5p39uqc7X1+sRQSqmGrUVhlsJ4lpmEUVwyT8SUYtg0P9DyNzPADDs+tjrGV6KRCRfsui3eHcL4/p8ZXvfMlcnEU+CLv7hDykOP+AKTPTxbAAB42mNgZGBgAGKuf5KP4vltvjLIMzGAwLV9ig0g+vruFFMQzdjACOJzMIClARh0CTJ42mNgZGBgPPD/AJD8wgAEjA0MjAyogAMAbOQEAQAAAAC7ABEAAAAAAKoAAAH0AAABgAAAAUAACAFAAAgAwAAXAAAAAAAAACoAKgAqADIAbACGAKAAugDSeNpjYGRgYOBkUGFgYgABEMkFhAwM/xn0QAIADdUBdAB42qWQvUoDQRSFv3GjaISUQaymSmGxJoGAsRC0iPYLsU50Y6IxrvlRtPCJJKUPIBb+PIHv4EN4djKuKAqCDHfmu+feOdwZoMCUAJNbAlYUMzaUlM14jjxbngOq7HnOia89z1Pk1vMCa9x7ztPkzfMyJbPj+ZGi6Xp+omxuPD+zaD7meaFg7mb8GrBqHmhwxoAxlm0uiRkpP9X5m26pKRoMxTGR1D49Dv/Yb/91o6l8qL6eu5n2hZQzn68utR9m3FU2cB4t9cdSLG2utI+44Eh/P9bqKO+oJ/WxmXssj77YkrjasZQD6SFddythk3Wtzrf+UF2p076Udla1VNzsERP3kkjVRKel7mp1udXYcHtZSlV7RfmJe1GiFWveluaeKD5/MuJcSk8Tpm/vvwPIbmJleNpjYGKAAFYG7ICTgYGRiZGZkYWRlZGNkZ2Rg5GTLT2nsiDDEEIZsZfmZRqZujmDaDcDAxcI7WIOpS2gtCWUdgQAZkcSmQAAAAFblbO6AAA=) format('woff');font-weight:400;font-style:normal}.ui.dropdown>.dropdown.icon{font-family:Dropdown;line-height:1;height:1em;width:1.23em;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.dropdown>.dropdown.icon{width:auto}.ui.dropdown>.dropdown.icon:before{content:'\\\\f0d7'}.ui.dropdown .menu .item .dropdown.icon:before{content:'\\\\f0da'}.ui.dropdown .item .left.dropdown.icon:before,.ui.dropdown .left.menu .item .dropdown.icon:before{content:\\\"\\\\f0d9\\\"}.ui.vertical.menu .dropdown.item>.dropdown.icon:before{content:\\\"\\\\f0da\\\"}.ui.dropdown>.clear.icon:before{content:\\\"\\\\f00d\\\"}/*!\\n * # Semantic UI 2.4.0 - Video\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.embed{position:relative;max-width:100%;height:0;overflow:hidden;background:#dcddde;padding-bottom:56.25%}.ui.embed embed,.ui.embed iframe,.ui.embed object{position:absolute;border:none;width:100%;height:100%;top:0;left:0;margin:0;padding:0}.ui.embed>.embed{display:none}.ui.embed>.placeholder{position:absolute;cursor:pointer;top:0;left:0;display:block;width:100%;height:100%;background-color:radial-gradient(transparent 45%,rgba(0,0,0,.3))}.ui.embed>.icon{cursor:pointer;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.ui.embed>.icon:after{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;content:'';background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:.5;-webkit-transition:opacity .5s ease;transition:opacity .5s ease}.ui.embed>.icon:before{position:absolute;top:50%;left:50%;z-index:4;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);color:#fff;font-size:6rem;text-shadow:0 2px 10px rgba(34,36,38,.2);-webkit-transition:opacity .5s ease,color .5s ease;transition:opacity .5s ease,color .5s ease;z-index:10}.ui.embed .icon:hover:after{background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:1}.ui.embed .icon:hover:before{color:#fff}.ui.active.embed>.icon,.ui.active.embed>.placeholder{display:none}.ui.active.embed>.embed{display:block}.ui.square.embed{padding-bottom:100%}.ui[class*=\\\"4:3\\\"].embed{padding-bottom:75%}.ui[class*=\\\"16:9\\\"].embed{padding-bottom:56.25%}.ui[class*=\\\"21:9\\\"].embed{padding-bottom:42.85714286%}/*!\\n * # Semantic UI 2.4.0 - Modal\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.modal{position:absolute;display:none;z-index:1001;text-align:left;background:#fff;border:none;-webkit-box-shadow:1px 3px 3px 0 rgba(0,0,0,.2),1px 3px 15px 2px rgba(0,0,0,.2);box-shadow:1px 3px 3px 0 rgba(0,0,0,.2),1px 3px 15px 2px rgba(0,0,0,.2);-webkit-transform-origin:50% 25%;transform-origin:50% 25%;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;border-radius:.28571429rem;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;will-change:top,left,margin,transform,opacity}.ui.modal>.icon:first-child+*,.ui.modal>:first-child:not(.icon){border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.modal>:last-child{border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.modal>.close{cursor:pointer;position:absolute;top:-2.5rem;right:-2.5rem;z-index:1;opacity:.8;font-size:1.25em;color:#fff;width:2.25rem;height:2.25rem;padding:.625rem 0 0 0}.ui.modal>.close:hover{opacity:1}.ui.modal>.header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;background:#fff;margin:0;padding:1.25rem 1.5rem;-webkit-box-shadow:none;box-shadow:none;color:rgba(0,0,0,.85);border-bottom:1px solid rgba(34,36,38,.15)}.ui.modal>.header:not(.ui){font-size:1.42857143rem;line-height:1.28571429em;font-weight:700}.ui.modal>.content{display:block;width:100%;font-size:1em;line-height:1.4;padding:1.5rem;background:#fff}.ui.modal>.image.content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.ui.modal>.content>.image{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:'';-ms-flex-item-align:top;align-self:top}.ui.modal>[class*=\\\"top aligned\\\"]{-ms-flex-item-align:top;align-self:top}.ui.modal>[class*=\\\"middle aligned\\\"]{-ms-flex-item-align:middle;align-self:middle}.ui.modal>[class*=stretched]{-ms-flex-item-align:stretch;align-self:stretch}.ui.modal>.content>.description{display:block;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;min-width:0;-ms-flex-item-align:top;align-self:top}.ui.modal>.content>.icon+.description,.ui.modal>.content>.image+.description{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;min-width:'';width:auto;padding-left:2em}.ui.modal>.content>.image>i.icon{margin:0;opacity:1;width:auto;line-height:1;font-size:8rem}.ui.modal>.actions{background:#f9fafb;padding:1rem 1rem;border-top:1px solid rgba(34,36,38,.15);text-align:right}.ui.modal .actions>.button{margin-left:.75em}@media only screen and (max-width:767px){.ui.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.modal{width:88%;margin:0}}@media only screen and (min-width:992px){.ui.modal{width:850px;margin:0}}@media only screen and (min-width:1200px){.ui.modal{width:900px;margin:0}}@media only screen and (min-width:1920px){.ui.modal{width:950px;margin:0}}@media only screen and (max-width:991px){.ui.modal>.header{padding-right:2.25rem}.ui.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}}@media only screen and (max-width:767px){.ui.modal>.header{padding:.75rem 1rem!important;padding-right:2.25rem!important}.ui.modal>.content{display:block;padding:1rem!important}.ui.modal>.close{top:.5rem!important;right:.5rem!important}.ui.modal .image.content{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.modal .content>.image{display:block;max-width:100%;margin:0 auto!important;text-align:center;padding:0 0 1rem!important}.ui.modal>.content>.image>i.icon{font-size:5rem;text-align:center}.ui.modal .content>.description{display:block;width:100%!important;margin:0!important;padding:1rem 0!important;-webkit-box-shadow:none;box-shadow:none}.ui.modal>.actions{padding:1rem 1rem 0!important}.ui.modal .actions>.button,.ui.modal .actions>.buttons{margin-bottom:1rem}}.ui.inverted.dimmer>.ui.modal{-webkit-box-shadow:1px 3px 10px 2px rgba(0,0,0,.2);box-shadow:1px 3px 10px 2px rgba(0,0,0,.2)}.ui.basic.modal{background-color:transparent;border:none;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.basic.modal>.actions,.ui.basic.modal>.content,.ui.basic.modal>.header{background-color:transparent}.ui.basic.modal>.header{color:#fff}.ui.basic.modal>.close{top:1rem;right:1.5rem}.ui.inverted.dimmer>.basic.modal{color:rgba(0,0,0,.87)}.ui.inverted.dimmer>.ui.basic.modal>.header{color:rgba(0,0,0,.85)}.ui.legacy.modal,.ui.legacy.page.dimmer>.ui.modal{top:50%;left:50%}.ui.legacy.page.dimmer>.ui.scrolling.modal,.ui.page.dimmer>.ui.scrolling.legacy.modal,.ui.top.aligned.dimmer>.ui.legacy.modal,.ui.top.aligned.legacy.page.dimmer>.ui.modal{top:auto}@media only screen and (max-width:991px){.ui.basic.modal>.close{color:#fff}}.ui.loading.modal{display:block;visibility:hidden;z-index:-1}.ui.active.modal{display:block}.modals.dimmer[class*=\\\"top aligned\\\"] .modal{margin:5vh auto}@media only screen and (max-width:767px){.modals.dimmer[class*=\\\"top aligned\\\"] .modal{margin:1rem auto}}.legacy.modals.dimmer[class*=\\\"top aligned\\\"]{padding-top:5vh}@media only screen and (max-width:767px){.legacy.modals.dimmer[class*=\\\"top aligned\\\"]{padding-top:1rem}}.scrolling.dimmable.dimmed{overflow:hidden}.scrolling.dimmable>.dimmer{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.scrolling.dimmable.dimmed>.dimmer{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.dimmable>.dimmer{position:fixed}.modals.dimmer .ui.scrolling.modal{margin:1rem auto}.scrolling.undetached.dimmable.dimmed{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.undetached.dimmable.dimmed>.dimmer{overflow:hidden}.scrolling.undetached.dimmable .ui.scrolling.modal{position:absolute;left:50%;margin-top:1rem!important}.ui.modal .scrolling.content{max-height:calc(70vh);overflow:auto}.ui.fullscreen.modal{width:95%!important;left:0!important;margin:1em auto}.ui.fullscreen.scrolling.modal{left:0!important}.ui.fullscreen.modal>.header{padding-right:2.25rem}.ui.fullscreen.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}.ui.modal{font-size:1rem}.ui.mini.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.mini.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.mini.modal{width:35.2%;margin:0}}@media only screen and (min-width:992px){.ui.mini.modal{width:340px;margin:0}}@media only screen and (min-width:1200px){.ui.mini.modal{width:360px;margin:0}}@media only screen and (min-width:1920px){.ui.mini.modal{width:380px;margin:0}}.ui.small.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.tiny.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.tiny.modal{width:52.8%;margin:0}}@media only screen and (min-width:992px){.ui.tiny.modal{width:510px;margin:0}}@media only screen and (min-width:1200px){.ui.tiny.modal{width:540px;margin:0}}@media only screen and (min-width:1920px){.ui.tiny.modal{width:570px;margin:0}}.ui.small.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.small.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.small.modal{width:70.4%;margin:0}}@media only screen and (min-width:992px){.ui.small.modal{width:680px;margin:0}}@media only screen and (min-width:1200px){.ui.small.modal{width:720px;margin:0}}@media only screen and (min-width:1920px){.ui.small.modal{width:760px;margin:0}}.ui.large.modal>.header{font-size:1.6em}@media only screen and (max-width:767px){.ui.large.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.large.modal{width:88%;margin:0}}@media only screen and (min-width:992px){.ui.large.modal{width:1020px;margin:0}}@media only screen and (min-width:1200px){.ui.large.modal{width:1080px;margin:0}}@media only screen and (min-width:1920px){.ui.large.modal{width:1140px;margin:0}}/*!\\n * # Semantic UI 2.4.0 - Nag\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.nag{display:none;opacity:.95;position:relative;top:0;left:0;z-index:999;min-height:0;width:100%;margin:0;padding:.75em 1em;background:#555;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.2);box-shadow:0 1px 2px 0 rgba(0,0,0,.2);font-size:1rem;text-align:center;color:rgba(0,0,0,.87);border-radius:0 0 .28571429rem .28571429rem;-webkit-transition:.2s background ease;transition:.2s background ease}a.ui.nag{cursor:pointer}.ui.nag>.title{display:inline-block;margin:0 .5em;color:#fff}.ui.nag>.close.icon{cursor:pointer;opacity:.4;position:absolute;top:50%;right:1em;font-size:1em;margin:-.5em 0 0;color:#fff;-webkit-transition:opacity .2s ease;transition:opacity .2s ease}.ui.nag:hover{background:#555;opacity:1}.ui.nag .close:hover{opacity:1}.ui.overlay.nag{position:absolute;display:block}.ui.fixed.nag{position:fixed}.ui.bottom.nag,.ui.bottom.nags{border-radius:.28571429rem .28571429rem 0 0;top:auto;bottom:0}.ui.inverted.nag,.ui.inverted.nags .nag{background-color:#f3f4f5;color:rgba(0,0,0,.85)}.ui.inverted.nag .close,.ui.inverted.nag .title,.ui.inverted.nags .nag .close,.ui.inverted.nags .nag .title{color:rgba(0,0,0,.4)}.ui.nags .nag{border-radius:0!important}.ui.nags .nag:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.bottom.nags .nag:last-child{border-radius:.28571429rem .28571429rem 0 0}/*!\\n * # Semantic UI 2.4.0 - Popup\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-webkit-min-content;min-width:-moz-min-content;min-width:min-content;z-index:1900;border:1px solid #d4d4d5;line-height:1.4285em;max-width:250px;background:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.popup>.header{padding:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.14285714em;line-height:1.2;font-weight:700}.ui.popup>.header+.content{padding-top:.5em}.ui.popup:before{position:absolute;content:'';width:.71428571em;height:.71428571em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg);z-index:2;-webkit-box-shadow:1px 1px 0 0 #bababc;box-shadow:1px 1px 0 0 #bababc}[data-tooltip]{position:relative}[data-tooltip]:before{pointer-events:none;position:absolute;content:'';font-size:1rem;width:.71428571em;height:.71428571em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg);z-index:2;-webkit-box-shadow:1px 1px 0 0 #bababc;box-shadow:1px 1px 0 0 #bababc}[data-tooltip]:after{pointer-events:none;content:attr(data-tooltip);position:absolute;text-transform:none;text-align:left;white-space:nowrap;font-size:1rem;border:1px solid #d4d4d5;line-height:1.4285em;max-width:none;background:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);z-index:1}[data-tooltip]:not([data-position]):before{top:auto;right:auto;bottom:100%;left:50%;background:#fff;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-tooltip]:not([data-position]):after{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:100%;margin-bottom:.5em}[data-tooltip]:after,[data-tooltip]:before{pointer-events:none;visibility:hidden}[data-tooltip]:before{opacity:0;-webkit-transform:rotate(45deg) scale(0)!important;transform:rotate(45deg) scale(0)!important;-webkit-transform-origin:center top;transform-origin:center top;-webkit-transition:all .1s ease;transition:all .1s ease}[data-tooltip]:after{opacity:1;-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-transition:all .1s ease;transition:all .1s ease}[data-tooltip]:hover:after,[data-tooltip]:hover:before{visibility:visible;pointer-events:auto}[data-tooltip]:hover:before{-webkit-transform:rotate(45deg) scale(1)!important;transform:rotate(45deg) scale(1)!important;opacity:1}[data-tooltip]:after,[data-tooltip][data-position=\\\"bottom center\\\"]:after,[data-tooltip][data-position=\\\"top center\\\"]:after{-webkit-transform:translateX(-50%) scale(0)!important;transform:translateX(-50%) scale(0)!important}[data-tooltip]:hover:after,[data-tooltip][data-position=\\\"bottom center\\\"]:hover:after{-webkit-transform:translateX(-50%) scale(1)!important;transform:translateX(-50%) scale(1)!important}[data-tooltip][data-position=\\\"left center\\\"]:after,[data-tooltip][data-position=\\\"right center\\\"]:after{-webkit-transform:translateY(-50%) scale(0)!important;transform:translateY(-50%) scale(0)!important}[data-tooltip][data-position=\\\"left center\\\"]:hover:after,[data-tooltip][data-position=\\\"right center\\\"]:hover:after{-webkit-transform:translateY(-50%) scale(1)!important;transform:translateY(-50%) scale(1)!important}[data-tooltip][data-position=\\\"bottom left\\\"]:after,[data-tooltip][data-position=\\\"bottom right\\\"]:after,[data-tooltip][data-position=\\\"top left\\\"]:after,[data-tooltip][data-position=\\\"top right\\\"]:after{-webkit-transform:scale(0)!important;transform:scale(0)!important}[data-tooltip][data-position=\\\"bottom left\\\"]:hover:after,[data-tooltip][data-position=\\\"bottom right\\\"]:hover:after,[data-tooltip][data-position=\\\"top left\\\"]:hover:after,[data-tooltip][data-position=\\\"top right\\\"]:hover:after{-webkit-transform:scale(1)!important;transform:scale(1)!important}[data-tooltip][data-inverted]:before{-webkit-box-shadow:none!important;box-shadow:none!important}[data-tooltip][data-inverted]:before{background:#1b1c1d}[data-tooltip][data-inverted]:after{background:#1b1c1d;color:#fff;border:none;-webkit-box-shadow:none;box-shadow:none}[data-tooltip][data-inverted]:after .header{background-color:none;color:#fff}[data-position=\\\"top center\\\"][data-tooltip]:after{top:auto;right:auto;left:50%;bottom:100%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin-bottom:.5em}[data-position=\\\"top center\\\"][data-tooltip]:before{top:auto;right:auto;bottom:100%;left:50%;background:#fff;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"top left\\\"][data-tooltip]:after{top:auto;right:auto;left:0;bottom:100%;margin-bottom:.5em}[data-position=\\\"top left\\\"][data-tooltip]:before{top:auto;right:auto;bottom:100%;left:1em;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"top right\\\"][data-tooltip]:after{top:auto;left:auto;right:0;bottom:100%;margin-bottom:.5em}[data-position=\\\"top right\\\"][data-tooltip]:before{top:auto;left:auto;bottom:100%;right:1em;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"bottom center\\\"][data-tooltip]:after{bottom:auto;right:auto;left:50%;top:100%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin-top:.5em}[data-position=\\\"bottom center\\\"][data-tooltip]:before{bottom:auto;right:auto;top:100%;left:50%;margin-left:-.07142857rem;margin-top:.14285714rem}[data-position=\\\"bottom left\\\"][data-tooltip]:after{left:0;top:100%;margin-top:.5em}[data-position=\\\"bottom left\\\"][data-tooltip]:before{bottom:auto;right:auto;top:100%;left:1em;margin-left:-.07142857rem;margin-top:.14285714rem}[data-position=\\\"bottom right\\\"][data-tooltip]:after{right:0;top:100%;margin-top:.5em}[data-position=\\\"bottom right\\\"][data-tooltip]:before{bottom:auto;left:auto;top:100%;right:1em;margin-left:-.14285714rem;margin-top:.07142857rem}[data-position=\\\"left center\\\"][data-tooltip]:after{right:100%;top:50%;margin-right:.5em;-webkit-transform:translateY(-50%);transform:translateY(-50%)}[data-position=\\\"left center\\\"][data-tooltip]:before{right:100%;top:50%;margin-top:-.14285714rem;margin-right:-.07142857rem}[data-position=\\\"right center\\\"][data-tooltip]:after{left:100%;top:50%;margin-left:.5em;-webkit-transform:translateY(-50%);transform:translateY(-50%)}[data-position=\\\"right center\\\"][data-tooltip]:before{left:100%;top:50%;margin-top:-.07142857rem;margin-left:.14285714rem}[data-position~=bottom][data-tooltip]:before{background:#fff;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}[data-position=\\\"left center\\\"][data-tooltip]:before{background:#fff;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}[data-position=\\\"right center\\\"][data-tooltip]:before{background:#fff;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}[data-position~=top][data-tooltip]:before{background:#fff}[data-inverted][data-position~=bottom][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}[data-inverted][data-position=\\\"left center\\\"][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}[data-inverted][data-position=\\\"right center\\\"][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}[data-inverted][data-position~=top][data-tooltip]:before{background:#1b1c1d}[data-position~=bottom][data-tooltip]:before{-webkit-transform-origin:center bottom;transform-origin:center bottom}[data-position~=bottom][data-tooltip]:after{-webkit-transform-origin:center top;transform-origin:center top}[data-position=\\\"left center\\\"][data-tooltip]:before{-webkit-transform-origin:top center;transform-origin:top center}[data-position=\\\"left center\\\"][data-tooltip]:after{-webkit-transform-origin:right center;transform-origin:right center}[data-position=\\\"right center\\\"][data-tooltip]:before{-webkit-transform-origin:right center;transform-origin:right center}[data-position=\\\"right center\\\"][data-tooltip]:after{-webkit-transform-origin:left center;transform-origin:left center}.ui.popup{margin:0}.ui.top.popup{margin:0 0 .71428571em}.ui.top.left.popup{-webkit-transform-origin:left bottom;transform-origin:left bottom}.ui.top.center.popup{-webkit-transform-origin:center bottom;transform-origin:center bottom}.ui.top.right.popup{-webkit-transform-origin:right bottom;transform-origin:right bottom}.ui.left.center.popup{margin:0 .71428571em 0 0;-webkit-transform-origin:right 50%;transform-origin:right 50%}.ui.right.center.popup{margin:0 0 0 .71428571em;-webkit-transform-origin:left 50%;transform-origin:left 50%}.ui.bottom.popup{margin:.71428571em 0 0}.ui.bottom.left.popup{-webkit-transform-origin:left top;transform-origin:left top}.ui.bottom.center.popup{-webkit-transform-origin:center top;transform-origin:center top}.ui.bottom.right.popup{-webkit-transform-origin:right top;transform-origin:right top}.ui.bottom.center.popup:before{margin-left:-.30714286em;top:-.30714286em;left:50%;right:auto;bottom:auto;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.left.popup{margin-left:0}.ui.bottom.left.popup:before{top:-.30714286em;left:1em;right:auto;bottom:auto;margin-left:0;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.right.popup{margin-right:0}.ui.bottom.right.popup:before{top:-.30714286em;right:1em;bottom:auto;left:auto;margin-left:0;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.top.center.popup:before{top:auto;right:auto;bottom:-.30714286em;left:50%;margin-left:-.30714286em}.ui.top.left.popup{margin-left:0}.ui.top.left.popup:before{bottom:-.30714286em;left:1em;top:auto;right:auto;margin-left:0}.ui.top.right.popup{margin-right:0}.ui.top.right.popup:before{bottom:-.30714286em;right:1em;top:auto;left:auto;margin-left:0}.ui.left.center.popup:before{top:50%;right:-.30714286em;bottom:auto;left:auto;margin-top:-.30714286em;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}.ui.right.center.popup:before{top:50%;left:-.30714286em;bottom:auto;right:auto;margin-top:-.30714286em;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}.ui.bottom.popup:before{background:#fff}.ui.left.center.popup:before,.ui.right.center.popup:before{background:#fff}.ui.top.popup:before{background:#fff}.ui.inverted.bottom.popup:before{background:#1b1c1d}.ui.inverted.left.center.popup:before,.ui.inverted.right.center.popup:before{background:#1b1c1d}.ui.inverted.top.popup:before{background:#1b1c1d}.ui.popup>.ui.grid:not(.padded){width:calc(100% + 1.75rem);margin:-.7rem -.875rem}.ui.loading.popup{display:block;visibility:hidden;z-index:-1}.ui.animating.popup,.ui.visible.popup{display:block}.ui.visible.popup{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.basic.popup:before{display:none}.ui.wide.popup{max-width:350px}.ui[class*=\\\"very wide\\\"].popup{max-width:550px}@media only screen and (max-width:767px){.ui.wide.popup,.ui[class*=\\\"very wide\\\"].popup{max-width:250px}}.ui.fluid.popup{width:100%;max-width:none}.ui.inverted.popup{background:#1b1c1d;color:#fff;border:none;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.popup .header{background-color:none;color:#fff}.ui.inverted.popup:before{background-color:#1b1c1d;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.flowing.popup{max-width:none}.ui.mini.popup{font-size:.78571429rem}.ui.tiny.popup{font-size:.85714286rem}.ui.small.popup{font-size:.92857143rem}.ui.popup{font-size:1rem}.ui.large.popup{font-size:1.14285714rem}.ui.huge.popup{font-size:1.42857143rem}/*!\\n * # Semantic UI 2.4.0 - Progress Bar\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.progress{position:relative;display:block;max-width:100%;border:none;margin:1em 0 2.5em;-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.1);padding:0;border-radius:.28571429rem}.ui.progress:first-child{margin:0 0 2.5em}.ui.progress:last-child{margin:0 0 1.5em}.ui.progress .bar{display:block;line-height:1;position:relative;width:0%;min-width:2em;background:#888;border-radius:.28571429rem;-webkit-transition:width .1s ease,background-color .1s ease;transition:width .1s ease,background-color .1s ease}.ui.progress .bar>.progress{white-space:nowrap;position:absolute;width:auto;font-size:.92857143em;top:50%;right:.5em;left:auto;bottom:auto;color:rgba(255,255,255,.7);text-shadow:none;margin-top:-.5em;font-weight:700;text-align:left}.ui.progress>.label{position:absolute;width:100%;font-size:1em;top:100%;right:auto;left:0;bottom:auto;color:rgba(0,0,0,.87);font-weight:700;text-shadow:none;margin-top:.2em;text-align:center;-webkit-transition:color .4s ease;transition:color .4s ease}.ui.indicating.progress[data-percent^=\\\"1\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"2\\\"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent^=\\\"3\\\"] .bar{background-color:#efbc72}.ui.indicating.progress[data-percent^=\\\"4\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"5\\\"] .bar{background-color:#e6bb48}.ui.indicating.progress[data-percent^=\\\"6\\\"] .bar{background-color:#ddc928}.ui.indicating.progress[data-percent^=\\\"7\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"8\\\"] .bar{background-color:#b4d95c}.ui.indicating.progress[data-percent^=\\\"100\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"9\\\"] .bar{background-color:#66da81}.ui.indicating.progress[data-percent^=\\\"1\\\"] .label,.ui.indicating.progress[data-percent^=\\\"2\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"3\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"4\\\"] .label,.ui.indicating.progress[data-percent^=\\\"5\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"6\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"7\\\"] .label,.ui.indicating.progress[data-percent^=\\\"8\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"100\\\"] .label,.ui.indicating.progress[data-percent^=\\\"9\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent=\\\"1\\\"] .bar,.ui.indicating.progress[data-percent=\\\"2\\\"] .bar,.ui.indicating.progress[data-percent=\\\"3\\\"] .bar,.ui.indicating.progress[data-percent=\\\"4\\\"] .bar,.ui.indicating.progress[data-percent=\\\"5\\\"] .bar,.ui.indicating.progress[data-percent=\\\"6\\\"] .bar,.ui.indicating.progress[data-percent=\\\"7\\\"] .bar,.ui.indicating.progress[data-percent=\\\"8\\\"] .bar,.ui.indicating.progress[data-percent=\\\"9\\\"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent=\\\"1\\\"] .label,.ui.indicating.progress[data-percent=\\\"2\\\"] .label,.ui.indicating.progress[data-percent=\\\"3\\\"] .label,.ui.indicating.progress[data-percent=\\\"4\\\"] .label,.ui.indicating.progress[data-percent=\\\"5\\\"] .label,.ui.indicating.progress[data-percent=\\\"6\\\"] .label,.ui.indicating.progress[data-percent=\\\"7\\\"] .label,.ui.indicating.progress[data-percent=\\\"8\\\"] .label,.ui.indicating.progress[data-percent=\\\"9\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress.success .label{color:#1a531b}.ui.progress.success .bar{background-color:#21ba45!important}.ui.progress.success .bar,.ui.progress.success .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.success>.label{color:#1a531b}.ui.progress.warning .bar{background-color:#f2c037!important}.ui.progress.warning .bar,.ui.progress.warning .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.warning>.label{color:#794b02}.ui.progress.error .bar{background-color:#db2828!important}.ui.progress.error .bar,.ui.progress.error .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.error>.label{color:#912d2b}.ui.active.progress .bar{position:relative;min-width:2em}.ui.active.progress .bar::after{content:'';opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff;border-radius:.28571429rem;-webkit-animation:progress-active 2s ease infinite;animation:progress-active 2s ease infinite}@-webkit-keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}@keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}.ui.disabled.progress{opacity:.35}.ui.disabled.progress .bar,.ui.disabled.progress .bar::after{-webkit-animation:none!important;animation:none!important}.ui.inverted.progress{background:rgba(255,255,255,.08);border:none}.ui.inverted.progress .bar{background:#888}.ui.inverted.progress .bar>.progress{color:#f9fafb}.ui.inverted.progress>.label{color:#fff}.ui.inverted.progress.success>.label{color:#21ba45}.ui.inverted.progress.warning>.label{color:#f2c037}.ui.inverted.progress.error>.label{color:#db2828}.ui.progress.attached{background:0 0;position:relative;border:none;margin:0}.ui.progress.attached,.ui.progress.attached .bar{display:block;height:.2rem;padding:0;overflow:hidden;border-radius:0 0 .28571429rem .28571429rem}.ui.progress.attached .bar{border-radius:0}.ui.progress.top.attached,.ui.progress.top.attached .bar{top:0;border-radius:.28571429rem .28571429rem 0 0}.ui.progress.top.attached .bar{border-radius:0}.ui.card>.ui.attached.progress,.ui.segment>.ui.attached.progress{position:absolute;top:auto;left:0;bottom:100%;width:100%}.ui.card>.ui.bottom.attached.progress,.ui.segment>.ui.bottom.attached.progress{top:100%;bottom:auto}.ui.red.progress .bar{background-color:#db2828}.ui.red.inverted.progress .bar{background-color:#ff695e}.ui.orange.progress .bar{background-color:#f2711c}.ui.orange.inverted.progress .bar{background-color:#ff851b}.ui.yellow.progress .bar{background-color:#fbbd08}.ui.yellow.inverted.progress .bar{background-color:#ffe21f}.ui.olive.progress .bar{background-color:#b5cc18}.ui.olive.inverted.progress .bar{background-color:#d9e778}.ui.green.progress .bar{background-color:#21ba45}.ui.green.inverted.progress .bar{background-color:#2ecc40}.ui.teal.progress .bar{background-color:#00b5ad}.ui.teal.inverted.progress .bar{background-color:#6dffff}.ui.blue.progress .bar{background-color:#2185d0}.ui.blue.inverted.progress .bar{background-color:#54c8ff}.ui.violet.progress .bar{background-color:#6435c9}.ui.violet.inverted.progress .bar{background-color:#a291fb}.ui.purple.progress .bar{background-color:#a333c8}.ui.purple.inverted.progress .bar{background-color:#dc73ff}.ui.pink.progress .bar{background-color:#e03997}.ui.pink.inverted.progress .bar{background-color:#ff8edf}.ui.brown.progress .bar{background-color:#a5673f}.ui.brown.inverted.progress .bar{background-color:#d67c1c}.ui.grey.progress .bar{background-color:#767676}.ui.grey.inverted.progress .bar{background-color:#dcddde}.ui.black.progress .bar{background-color:#1b1c1d}.ui.black.inverted.progress .bar{background-color:#545454}.ui.tiny.progress{font-size:.85714286rem}.ui.tiny.progress .bar{height:.5em}.ui.small.progress{font-size:.92857143rem}.ui.small.progress .bar{height:1em}.ui.progress{font-size:1rem}.ui.progress .bar{height:1.75em}.ui.large.progress{font-size:1.14285714rem}.ui.large.progress .bar{height:2.5em}.ui.big.progress{font-size:1.28571429rem}.ui.big.progress .bar{height:3.5em}/*!\\n * # Semantic UI 2.4.0 - Rating\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.rating{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;white-space:nowrap;vertical-align:baseline}.ui.rating:last-child{margin-right:0}.ui.rating .icon{padding:0;margin:0;text-align:center;font-weight:400;font-style:normal;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;cursor:pointer;width:1.25em;height:auto;-webkit-transition:opacity .1s ease,background .1s ease,text-shadow .1s ease,color .1s ease;transition:opacity .1s ease,background .1s ease,text-shadow .1s ease,color .1s ease}.ui.rating .icon{background:0 0;color:rgba(0,0,0,.15)}.ui.rating .active.icon{background:0 0;color:rgba(0,0,0,.85)}.ui.rating .icon.selected,.ui.rating .icon.selected.active{background:0 0;color:rgba(0,0,0,.87)}.ui.star.rating .icon{width:1.25em;height:auto;background:0 0;color:rgba(0,0,0,.15);text-shadow:none}.ui.star.rating .active.icon{background:0 0!important;color:#ffe623!important;text-shadow:0 -1px 0 #ddc507,-1px 0 0 #ddc507,0 1px 0 #ddc507,1px 0 0 #ddc507!important}.ui.star.rating .icon.selected,.ui.star.rating .icon.selected.active{background:0 0!important;color:#fc0!important;text-shadow:0 -1px 0 #e6a200,-1px 0 0 #e6a200,0 1px 0 #e6a200,1px 0 0 #e6a200!important}.ui.heart.rating .icon{width:1.4em;height:auto;background:0 0;color:rgba(0,0,0,.15);text-shadow:none!important}.ui.heart.rating .active.icon{background:0 0!important;color:#ff6d75!important;text-shadow:0 -1px 0 #cd0707,-1px 0 0 #cd0707,0 1px 0 #cd0707,1px 0 0 #cd0707!important}.ui.heart.rating .icon.selected,.ui.heart.rating .icon.selected.active{background:0 0!important;color:#ff3000!important;text-shadow:0 -1px 0 #aa0101,-1px 0 0 #aa0101,0 1px 0 #aa0101,1px 0 0 #aa0101!important}.ui.disabled.rating .icon{cursor:default}.ui.rating.selected .active.icon{opacity:1}.ui.rating .icon.selected,.ui.rating.selected .icon.selected{opacity:1}.ui.mini.rating{font-size:.78571429rem}.ui.tiny.rating{font-size:.85714286rem}.ui.small.rating{font-size:.92857143rem}.ui.rating{font-size:1rem}.ui.large.rating{font-size:1.14285714rem}.ui.huge.rating{font-size:1.42857143rem}.ui.massive.rating{font-size:2rem}@font-face{font-family:Rating;src:url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,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kIiRi5MI5vdUFfcni4vCBYufhJx8mn2ZepJ3i3aLeoR9fX18g3qLdwiLVAUO+yaLshWL+AQFi5GNkY+RjpCQj5KNj42PjI+LCPfAiwWPi4+Kj4mRiZCHj4aPhY2Fi4UIi/wEBYuEiYWHhoeGhoeFiIiKhoqHi4GLhI6EkQj7EvcN+xL7DQWEhYOIgouHi4eLh42EjoaPiJCHkImRi5IIDov3XRWLko2Rj5Kltq+vuKW4pbuZvYu9i7t9uHG4ca9npWCPhI2Fi4SLhYmEh4RxYGdoXnAIXnFbflmLWYtbmF6lXqZnrnG2h5KJkouRCLCLFaRkq2yxdLF0tH+4i7iLtJexorGiq6qksm64Z61goZZ3kXaLdItnfm1ycnJybX9oiwhoi22XcqRypH6pi6+LopGglp9gdWdpbl4I9xiwFYuHjIiOiI6IjoqPi4+LjoyOjo2OjY6Lj4ubkJmXl5eWmZGbi4+LjoyOjo2OjY6LjwiLj4mOiY6IjYiNh4tzi3eCenp6eoJ3i3MIDov3XRWLko2Sj5GouK+utqW3pbqYvouci5yJnIgIm6cFjY6NjI+LjIuNi42JjYqOio+JjomOiY6KjomOiY6JjoqNioyKjomMiYuHi4qLiouLCHdnbVVjQ2NDbVV3Zwh9cgWJiIiJiIuJi36SdJiIjYmOi46LjY+UlJlvl3KcdJ90oHeie6WHkYmSi5IIsIsVqlq0Z711CKGzBXqXfpqCnoKdhp6LoIuikaCWn2B1Z2luXgj3GLAVi4eMiI6IjoiOio+Lj4uOjI6OjY6NjouPi5uQmZeXl5aZkZuLj4uOjI6OjY6NjouPCIuPiY6JjoiNiI2Hi3OLd4J6enp6gneLcwji+10VoLAFtI+wmK2hrqKnqKKvdq1wp2uhCJ2rBZ1/nHycepx6mHqWeY+EjYWLhIuEiYWHhIR/gH1+fG9qaXJmeWV5Y4Jhiwi53BXb9yQFjIKMg4uEi3CDc3x1fHV3fHOBCA6L1BWL90sFi5WPlJKSkpKTj5aLCNmLBZKPmJqepJaZlZeVlY+Qj5ONl42WjpeOmI+YkZWTk5OSk46Vi5uLmYiYhZiFlIGSfgiSfo55i3WLeYd5gXgIvosFn4uchJl8mn2Seot3i3qGfIJ9jYSLhYuEi3yIfoR+i4eLh4uHi3eGen99i3CDdnt8CHt8dYNwiwhmiwV5i3mNeY95kHeRc5N1k36Ph4sIOYsFgIuDjoSShJKHlIuVCLCdFYuGjIePiI+Hj4mQi5CLj42Pj46OjY+LkIuQiZCIjoePh42Gi4aLh4mHh4eIioaLhgjUeRWUiwWNi46Lj4qOi4+KjYqOi4+Kj4mQio6KjYqNio+Kj4mQio6KjIqzfquEpIsIrosFr4uemouri5CKkYqQkY6QkI6SjpKNkouSi5KJkoiRlZWQlouYi5CKkImRiZGJj4iOCJGMkI+PlI+UjZKLkouViJODk4SSgo+CiwgmiwWLlpCalJ6UnpCbi5aLnoiYhJSFlH+QeYuGhoeDiYCJf4h/h3+IfoWBg4KHh4SCgH4Ii4qIiYiGh4aIh4mIiIiIh4eGh4aHh4eHiIiHiIeHiIiHiIeKh4mIioiLCIKLi/tLBQ6L90sVi/dLBYuVj5OSk5KSk46WiwjdiwWPi5iPoZOkk6CRnZCdj56Nn4sIq4sFpougg5x8m3yTd4txCIuJBZd8kHuLd4uHi4eLh5J+jn6LfIuEi4SJhZR9kHyLeot3hHp8fH19eoR3iwhYiwWVeI95i3mLdIh6hH6EfoKBfoV+hX2He4uBi4OPg5KFkYaTh5SHlYiTipOKk4qTiJMIiZSIkYiPgZSBl4CaeKR+moSPCD2LBYCLg4+EkoSSh5SLlQiw9zgVi4aMh4+Ij4ePiZCLkIuPjY+Pjo6Nj4uQi5CJkIiOh4+HjYaLhouHiYeHh4iKhouGCNT7OBWUiwWOi46Kj4mPio+IjoiPh4+IjoePiI+Hj4aPho6HjoiNiI6Hj4aOho6Ii4qWfpKDj4YIk4ORgY5+j36OgI1/jYCPg5CGnYuXj5GUkpSOmYuei5aGmoKfgp6GmouWCPCLBZSLlI+SkpOTjpOLlYuSiZKHlIeUho+Fi46PjY+NkY2RjJCLkIuYhpaBlY6RjZKLkgiLkomSiJKIkoaQhY6MkIyRi5CLm4aXgpOBkn6Pe4sIZosFcotrhGN9iouIioaJh4qHiomKiYqIioaKh4mHioiKiYuHioiLh4qIi4mLCIKLi/tLBQ77lIv3txWLkpCPlo0I9yOgzPcWBY6SkI+RiwiL/BL7FUcFh4mHioiLh4uIjImOiY6KjouPi4yLjYyOCKP3IyPwBYaQiZCLjwgOi/fFFYu1l6yjoqOjrZe2i5aLl4mYh5eHloWWhJaElIWShZOE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) format('woff');font-weight:400;font-style:normal}.ui.rating .icon{font-family:Rating;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.rating .icon:before{content:'\\\\f005'}.ui.rating .active.icon:before{content:'\\\\f005'}.ui.star.rating .icon:before{content:'\\\\f005'}.ui.star.rating .active.icon:before{content:'\\\\f005'}.ui.star.rating .partial.icon:before{content:'\\\\f006'}.ui.star.rating .partial.icon{content:'\\\\f005'}.ui.heart.rating .icon:before{content:'\\\\f004'}.ui.heart.rating .active.icon:before{content:'\\\\f004'}/*!\\n * # Semantic UI 2.4.0 - Search\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.search{position:relative}.ui.search>.prompt{margin:0;outline:0;-webkit-appearance:none;-webkit-tap-highlight-color:rgba(255,255,255,0);text-shadow:none;font-style:normal;font-weight:400;line-height:1.21428571em;padding:.67857143em 1em;font-size:1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:background-color .1s ease,color .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,color .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease;transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease}.ui.search .prompt{border-radius:500rem}.ui.search .prompt~.search.icon{cursor:pointer}.ui.search>.results{display:none;position:absolute;top:100%;left:0;-webkit-transform-origin:center top;transform-origin:center top;white-space:normal;text-align:left;text-transform:none;background:#fff;margin-top:.5em;width:18em;border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);border:1px solid #d4d4d5;z-index:998}.ui.search>.results>:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.search>.results>:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.search>.results .result{cursor:pointer;display:block;overflow:hidden;font-size:1em;padding:.85714286em 1.14285714em;color:rgba(0,0,0,.87);line-height:1.33;border-bottom:1px solid rgba(34,36,38,.1)}.ui.search>.results .result:last-child{border-bottom:none!important}.ui.search>.results .result .image{float:right;overflow:hidden;background:0 0;width:5em;height:3em;border-radius:.25em}.ui.search>.results .result .image img{display:block;width:auto;height:100%}.ui.search>.results .result .image+.content{margin:0 6em 0 0}.ui.search>.results .result .title{margin:-.14285714em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;font-size:1em;color:rgba(0,0,0,.85)}.ui.search>.results .result .description{margin-top:0;font-size:.92857143em;color:rgba(0,0,0,.4)}.ui.search>.results .result .price{float:right;color:#21ba45}.ui.search>.results>.message{padding:1em 1em}.ui.search>.results>.message .header{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1rem;font-weight:700;color:rgba(0,0,0,.87)}.ui.search>.results>.message .description{margin-top:.25rem;font-size:1em;color:rgba(0,0,0,.87)}.ui.search>.results>.action{display:block;border-top:none;background:#f3f4f5;padding:.92857143em 1em;color:rgba(0,0,0,.87);font-weight:700;text-align:center}.ui.search>.prompt:focus{border-color:rgba(34,36,38,.35);background:#fff;color:rgba(0,0,0,.95)}.ui.loading.search .input>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.search .input>i.icon:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.category.search>.results .category .result:hover,.ui.search>.results .result:hover{background:#f9fafb}.ui.search .action:hover{background:#e0e0e0}.ui.category.search>.results .category.active{background:#f3f4f5}.ui.category.search>.results .category.active>.name{color:rgba(0,0,0,.87)}.ui.category.search>.results .category .result.active,.ui.search>.results .result.active{position:relative;border-left-color:rgba(34,36,38,.1);background:#f3f4f5;-webkit-box-shadow:none;box-shadow:none}.ui.search>.results .result.active .title{color:rgba(0,0,0,.85)}.ui.search>.results .result.active .description{color:rgba(0,0,0,.85)}.ui.disabled.search{cursor:default;pointer-events:none;opacity:.45}.ui.search.selection .prompt{border-radius:.28571429rem}.ui.search.selection>.icon.input>.remove.icon{pointer-events:none;position:absolute;left:auto;opacity:0;color:'';top:0;right:0;-webkit-transition:color .1s ease,opacity .1s ease;transition:color .1s ease,opacity .1s ease}.ui.search.selection>.icon.input>.active.remove.icon{cursor:pointer;opacity:.8;pointer-events:auto}.ui.search.selection>.icon.input:not([class*=\\\"left icon\\\"])>.icon~.remove.icon{right:1.85714em}.ui.search.selection>.icon.input>.remove.icon:hover{opacity:1;color:#db2828}.ui.category.search .results{width:28em}.ui.category.search .results.animating,.ui.category.search .results.visible{display:table}.ui.category.search>.results .category{display:table-row;background:#f3f4f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease}.ui.category.search>.results .category:last-child{border-bottom:none}.ui.category.search>.results .category:first-child .name+.result{border-radius:0 .28571429rem 0 0}.ui.category.search>.results .category:last-child .result:last-child{border-radius:0 0 .28571429rem 0}.ui.category.search>.results .category>.name{display:table-cell;text-overflow:ellipsis;width:100px;white-space:nowrap;background:0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;padding:.4em 1em;font-weight:700;color:rgba(0,0,0,.4);border-bottom:1px solid rgba(34,36,38,.1)}.ui.category.search>.results .category .results{display:table-cell;background:#fff;border-left:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(34,36,38,.1)}.ui.category.search>.results .category .result{border-bottom:1px solid rgba(34,36,38,.1);-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease;padding:.85714286em 1.14285714em}.ui[class*=\\\"left aligned\\\"].search>.results{right:auto;left:0}.ui[class*=\\\"right aligned\\\"].search>.results{right:0;left:auto}.ui.fluid.search .results{width:100%}.ui.mini.search{font-size:.78571429em}.ui.small.search{font-size:.92857143em}.ui.search{font-size:1em}.ui.large.search{font-size:1.14285714em}.ui.big.search{font-size:1.28571429em}.ui.huge.search{font-size:1.42857143em}.ui.massive.search{font-size:1.71428571em}@media only screen and (max-width:767px){.ui.search .results{max-width:calc(100vw - 2rem)}}/*!\\n * # Semantic UI 2.4.0 - Shape\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.shape{position:relative;vertical-align:top;display:inline-block;-webkit-perspective:2000px;perspective:2000px;-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape .sides{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.ui.shape .side{opacity:1;width:100%;margin:0!important;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.shape .side{display:none}.ui.shape .side *{-webkit-backface-visibility:visible!important;backface-visibility:visible!important}.ui.cube.shape .side{min-width:15em;height:15em;padding:2em;background-color:#e6e6e6;color:rgba(0,0,0,.87);-webkit-box-shadow:0 0 2px rgba(0,0,0,.3);box-shadow:0 0 2px rgba(0,0,0,.3)}.ui.cube.shape .side>.content{width:100%;height:100%;display:table;text-align:center;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.cube.shape .side>.content>div{display:table-cell;vertical-align:middle;font-size:2em}.ui.text.shape.animating .sides{position:static}.ui.text.shape .side{white-space:nowrap}.ui.text.shape .side>*{white-space:normal}.ui.loading.shape{position:absolute;top:-9999px;left:-9999px}.ui.shape .animating.side{position:absolute;top:0;left:0;display:block;z-index:100}.ui.shape .hidden.side{opacity:.6}.ui.shape.animating .sides{position:absolute}.ui.shape.animating .sides{-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape.animating .side{-webkit-transition:opacity .6s ease-in-out;transition:opacity .6s ease-in-out}.ui.shape .active.side{display:block}/*!\\n * # Semantic UI 2.4.0 - Sidebar\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.sidebar{position:fixed;top:0;left:0;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:none;transition:none;will-change:transform;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);visibility:hidden;-webkit-overflow-scrolling:touch;height:100%!important;max-height:100%;border-radius:0!important;margin:0!important;overflow-y:auto!important;z-index:102}.ui.sidebar>*{-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.left.sidebar{right:auto;left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.sidebar{right:0!important;left:auto!important;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.bottom.sidebar,.ui.top.sidebar{width:100%!important;height:auto!important}.ui.top.sidebar{top:0!important;bottom:auto!important;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.sidebar{top:auto!important;bottom:0!important;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.pushable{height:100%;overflow-x:hidden;padding:0!important}body.pushable{background:#545454!important}.pushable:not(body){-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pushable:not(body)>.fixed,.pushable:not(body)>.pusher:after,.pushable:not(body)>.ui.sidebar{position:absolute}.pushable>.fixed{position:fixed;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;will-change:transform;z-index:101}.pushable>.pusher{position:relative;-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;min-height:100%;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:2}body.pushable>.pusher{background:#fff}.pushable>.pusher{background:inherit}.pushable>.pusher:after{position:fixed;top:0;right:0;content:'';background-color:rgba(0,0,0,.4);overflow:hidden;opacity:0;-webkit-transition:opacity .5s;transition:opacity .5s;will-change:opacity;z-index:1000}.ui.sidebar.menu .item{border-radius:0!important}.pushable>.pusher.dimmed:after{width:100%!important;height:100%!important;opacity:1!important}.ui.animating.sidebar{visibility:visible}.ui.visible.sidebar{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.left.visible.sidebar,.ui.right.visible.sidebar{-webkit-box-shadow:0 0 20px rgba(34,36,38,.15);box-shadow:0 0 20px rgba(34,36,38,.15)}.ui.bottom.visible.sidebar,.ui.top.visible.sidebar{-webkit-box-shadow:0 0 20px rgba(34,36,38,.15);box-shadow:0 0 20px rgba(34,36,38,.15)}.ui.visible.left.sidebar~.fixed,.ui.visible.left.sidebar~.pusher{-webkit-transform:translate3d(260px,0,0);transform:translate3d(260px,0,0)}.ui.visible.right.sidebar~.fixed,.ui.visible.right.sidebar~.pusher{-webkit-transform:translate3d(-260px,0,0);transform:translate3d(-260px,0,0)}.ui.visible.top.sidebar~.fixed,.ui.visible.top.sidebar~.pusher{-webkit-transform:translate3d(0,36px,0);transform:translate3d(0,36px,0)}.ui.visible.bottom.sidebar~.fixed,.ui.visible.bottom.sidebar~.pusher{-webkit-transform:translate3d(0,-36px,0);transform:translate3d(0,-36px,0)}.ui.visible.left.sidebar~.ui.visible.right.sidebar~.fixed,.ui.visible.left.sidebar~.ui.visible.right.sidebar~.pusher,.ui.visible.right.sidebar~.ui.visible.left.sidebar~.fixed,.ui.visible.right.sidebar~.ui.visible.left.sidebar~.pusher{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.thin.left.sidebar,.ui.thin.right.sidebar{width:150px}.ui[class*=\\\"very thin\\\"].left.sidebar,.ui[class*=\\\"very thin\\\"].right.sidebar{width:60px}.ui.left.sidebar,.ui.right.sidebar{width:260px}.ui.wide.left.sidebar,.ui.wide.right.sidebar{width:350px}.ui[class*=\\\"very wide\\\"].left.sidebar,.ui[class*=\\\"very wide\\\"].right.sidebar{width:475px}.ui.visible.thin.left.sidebar~.fixed,.ui.visible.thin.left.sidebar~.pusher{-webkit-transform:translate3d(150px,0,0);transform:translate3d(150px,0,0)}.ui.visible[class*=\\\"very thin\\\"].left.sidebar~.fixed,.ui.visible[class*=\\\"very thin\\\"].left.sidebar~.pusher{-webkit-transform:translate3d(60px,0,0);transform:translate3d(60px,0,0)}.ui.visible.wide.left.sidebar~.fixed,.ui.visible.wide.left.sidebar~.pusher{-webkit-transform:translate3d(350px,0,0);transform:translate3d(350px,0,0)}.ui.visible[class*=\\\"very wide\\\"].left.sidebar~.fixed,.ui.visible[class*=\\\"very wide\\\"].left.sidebar~.pusher{-webkit-transform:translate3d(475px,0,0);transform:translate3d(475px,0,0)}.ui.visible.thin.right.sidebar~.fixed,.ui.visible.thin.right.sidebar~.pusher{-webkit-transform:translate3d(-150px,0,0);transform:translate3d(-150px,0,0)}.ui.visible[class*=\\\"very thin\\\"].right.sidebar~.fixed,.ui.visible[class*=\\\"very thin\\\"].right.sidebar~.pusher{-webkit-transform:translate3d(-60px,0,0);transform:translate3d(-60px,0,0)}.ui.visible.wide.right.sidebar~.fixed,.ui.visible.wide.right.sidebar~.pusher{-webkit-transform:translate3d(-350px,0,0);transform:translate3d(-350px,0,0)}.ui.visible[class*=\\\"very wide\\\"].right.sidebar~.fixed,.ui.visible[class*=\\\"very wide\\\"].right.sidebar~.pusher{-webkit-transform:translate3d(-475px,0,0);transform:translate3d(-475px,0,0)}.ui.overlay.sidebar{z-index:102}.ui.left.overlay.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.overlay.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.overlay.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.overlay.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.animating.ui.overlay.sidebar,.ui.visible.overlay.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.left.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.right.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.top.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.bottom.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.overlay.sidebar~.fixed,.ui.visible.overlay.sidebar~.pusher{-webkit-transform:none!important;transform:none!important}.ui.push.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:102}.ui.left.push.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.push.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.push.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.push.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.ui.visible.push.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.uncover.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:1}.ui.visible.uncover.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.slide.along.sidebar{z-index:1}.ui.left.slide.along.sidebar{-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui.right.slide.along.sidebar{-webkit-transform:translate3d(50%,0,0);transform:translate3d(50%,0,0)}.ui.top.slide.along.sidebar{-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.ui.bottom.slide.along.sidebar{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.ui.animating.slide.along.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.slide.along.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.slide.out.sidebar{z-index:1}.ui.left.slide.out.sidebar{-webkit-transform:translate3d(50%,0,0);transform:translate3d(50%,0,0)}.ui.right.slide.out.sidebar{-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui.top.slide.out.sidebar{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.ui.bottom.slide.out.sidebar{-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.ui.animating.slide.out.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.slide.out.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.scale.down.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:102}.ui.left.scale.down.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.scale.down.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.scale.down.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.scale.down.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.ui.scale.down.left.sidebar~.pusher{-webkit-transform-origin:75% 50%;transform-origin:75% 50%}.ui.scale.down.right.sidebar~.pusher{-webkit-transform-origin:25% 50%;transform-origin:25% 50%}.ui.scale.down.top.sidebar~.pusher{-webkit-transform-origin:50% 75%;transform-origin:50% 75%}.ui.scale.down.bottom.sidebar~.pusher{-webkit-transform-origin:50% 25%;transform-origin:50% 25%}.ui.animating.scale.down>.visible.ui.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.animating.scale.down.sidebar~.pusher,.ui.visible.scale.down.sidebar~.pusher{display:block!important;width:100%;height:100%;overflow:hidden!important}.ui.visible.scale.down.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.scale.down.sidebar~.pusher{-webkit-transform:scale(.75);transform:scale(.75)}/*!\\n * # Semantic UI 2.4.0 - Sticky\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.sticky{position:static;-webkit-transition:none;transition:none;z-index:800}.ui.sticky.bound{position:absolute;left:auto;right:auto}.ui.sticky.fixed{position:fixed;left:auto;right:auto}.ui.sticky.bound.top,.ui.sticky.fixed.top{top:0;bottom:auto}.ui.sticky.bound.bottom,.ui.sticky.fixed.bottom{top:auto;bottom:0}.ui.native.sticky{position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;position:sticky}/*!\\n * # Semantic UI 2.4.0 - Tab\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.tab{display:none}.ui.tab.active,.ui.tab.open{display:block}.ui.tab.loading{position:relative;overflow:hidden;display:block;min-height:250px}.ui.tab.loading *{position:relative!important;left:-10000px!important}.ui.tab.loading.segment:before,.ui.tab.loading:before{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.tab.loading.segment:after,.ui.tab.loading:after{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}/*!\\n * # Semantic UI 2.4.0 - Transition\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.transition{-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animating.transition{-webkit-backface-visibility:hidden;backface-visibility:hidden;visibility:visible!important}.loading.transition{position:absolute;top:-99999px;left:-99999px}.hidden.transition{display:none;visibility:hidden}.visible.transition{display:block!important;visibility:visible!important}.disabled.transition{-webkit-animation-play-state:paused;animation-play-state:paused}.looping.transition{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.transition.browse{-webkit-animation-duration:.5s;animation-duration:.5s}.transition.browse.in{-webkit-animation-name:browseIn;animation-name:browseIn}.transition.browse.left.out,.transition.browse.out{-webkit-animation-name:browseOutLeft;animation-name:browseOutLeft}.transition.browse.right.out{-webkit-animation-name:browseOutRight;animation-name:browseOutRight}@-webkit-keyframes browseIn{0%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1}10%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1;opacity:.7}80%{-webkit-transform:scale(1.05) translateZ(0);transform:scale(1.05) translateZ(0);opacity:1;z-index:999}100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);z-index:999}}@keyframes browseIn{0%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1}10%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1;opacity:.7}80%{-webkit-transform:scale(1.05) translateZ(0);transform:scale(1.05) translateZ(0);opacity:1;z-index:999}100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);z-index:999}}@-webkit-keyframes browseOutLeft{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:-1;-webkit-transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:-1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@keyframes browseOutLeft{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:-1;-webkit-transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:-1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@-webkit-keyframes browseOutRight{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:1;-webkit-transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@keyframes browseOutRight{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:1;-webkit-transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}.drop.transition{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:cubic-bezier(.34,1.61,.7,1);animation-timing-function:cubic-bezier(.34,1.61,.7,1)}.drop.transition.in{-webkit-animation-name:dropIn;animation-name:dropIn}.drop.transition.out{-webkit-animation-name:dropOut;animation-name:dropOut}@-webkit-keyframes dropIn{0%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes dropIn{0%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes dropOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}@keyframes dropOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}.transition.fade.in{-webkit-animation-name:fadeIn;animation-name:fadeIn}.transition[class*=\\\"fade up\\\"].in{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}.transition[class*=\\\"fade down\\\"].in{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}.transition[class*=\\\"fade left\\\"].in{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}.transition[class*=\\\"fade right\\\"].in{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}.transition.fade.out{-webkit-animation-name:fadeOut;animation-name:fadeOut}.transition[class*=\\\"fade up\\\"].out{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}.transition[class*=\\\"fade down\\\"].out{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}.transition[class*=\\\"fade left\\\"].out{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}.transition[class*=\\\"fade right\\\"].out{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(5%);transform:translateY(5%)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(5%);transform:translateY(5%)}}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-5%);transform:translateY(-5%)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-5%);transform:translateY(-5%)}}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(5%);transform:translateX(5%)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(5%);transform:translateX(5%)}}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-5%);transform:translateX(-5%)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-5%);transform:translateX(-5%)}}.flip.transition.in,.flip.transition.out{-webkit-animation-duration:.6s;animation-duration:.6s}.horizontal.flip.transition.in{-webkit-animation-name:horizontalFlipIn;animation-name:horizontalFlipIn}.horizontal.flip.transition.out{-webkit-animation-name:horizontalFlipOut;animation-name:horizontalFlipOut}.vertical.flip.transition.in{-webkit-animation-name:verticalFlipIn;animation-name:verticalFlipIn}.vertical.flip.transition.out{-webkit-animation-name:verticalFlipOut;animation-name:verticalFlipOut}@-webkit-keyframes horizontalFlipIn{0%{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}}@keyframes horizontalFlipIn{0%{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}}@-webkit-keyframes verticalFlipIn{0%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}}@keyframes verticalFlipIn{0%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}}@-webkit-keyframes horizontalFlipOut{0%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);opacity:0}}@keyframes horizontalFlipOut{0%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);opacity:0}}@-webkit-keyframes verticalFlipOut{0%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}}@keyframes verticalFlipOut{0%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}}.scale.transition.in{-webkit-animation-name:scaleIn;animation-name:scaleIn}.scale.transition.out{-webkit-animation-name:scaleOut;animation-name:scaleOut}@-webkit-keyframes scaleIn{0%{opacity:0;-webkit-transform:scale(.8);transform:scale(.8)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes scaleIn{0%{opacity:0;-webkit-transform:scale(.8);transform:scale(.8)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes scaleOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(.9);transform:scale(.9)}}@keyframes scaleOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(.9);transform:scale(.9)}}.transition.fly{-webkit-animation-duration:.6s;animation-duration:.6s;-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}.transition.fly.in{-webkit-animation-name:flyIn;animation-name:flyIn}.transition[class*=\\\"fly up\\\"].in{-webkit-animation-name:flyInUp;animation-name:flyInUp}.transition[class*=\\\"fly down\\\"].in{-webkit-animation-name:flyInDown;animation-name:flyInDown}.transition[class*=\\\"fly left\\\"].in{-webkit-animation-name:flyInLeft;animation-name:flyInLeft}.transition[class*=\\\"fly right\\\"].in{-webkit-animation-name:flyInRight;animation-name:flyInRight}.transition.fly.out{-webkit-animation-name:flyOut;animation-name:flyOut}.transition[class*=\\\"fly up\\\"].out{-webkit-animation-name:flyOutUp;animation-name:flyOutUp}.transition[class*=\\\"fly down\\\"].out{-webkit-animation-name:flyOutDown;animation-name:flyOutDown}.transition[class*=\\\"fly left\\\"].out{-webkit-animation-name:flyOutLeft;animation-name:flyOutLeft}.transition[class*=\\\"fly right\\\"].out{-webkit-animation-name:flyOutRight;animation-name:flyOutRight}@-webkit-keyframes flyIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes flyIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@-webkit-keyframes flyInUp{0%{opacity:0;-webkit-transform:translate3d(0,1500px,0);transform:translate3d(0,1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes flyInUp{0%{opacity:0;-webkit-transform:translate3d(0,1500px,0);transform:translate3d(0,1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes flyInDown{0%{opacity:0;-webkit-transform:translate3d(0,-1500px,0);transform:translate3d(0,-1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInDown{0%{opacity:0;-webkit-transform:translate3d(0,-1500px,0);transform:translate3d(0,-1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyInLeft{0%{opacity:0;-webkit-transform:translate3d(1500px,0,0);transform:translate3d(1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInLeft{0%{opacity:0;-webkit-transform:translate3d(1500px,0,0);transform:translate3d(1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyInRight{0%{opacity:0;-webkit-transform:translate3d(-1500px,0,0);transform:translate3d(-1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInRight{0%{opacity:0;-webkit-transform:translate3d(-1500px,0,0);transform:translate3d(-1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes flyOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@-webkit-keyframes flyOutUp{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes flyOutUp{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@-webkit-keyframes flyOutDown{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes flyOutDown{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@-webkit-keyframes flyOutRight{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes flyOutRight{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@-webkit-keyframes flyOutLeft{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes flyOutLeft{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.transition.slide.in,.transition[class*=\\\"slide down\\\"].in{-webkit-animation-name:slideInY;animation-name:slideInY;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"slide up\\\"].in{-webkit-animation-name:slideInY;animation-name:slideInY;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"slide left\\\"].in{-webkit-animation-name:slideInX;animation-name:slideInX;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"slide right\\\"].in{-webkit-animation-name:slideInX;animation-name:slideInX;-webkit-transform-origin:center left;transform-origin:center left}.transition.slide.out,.transition[class*=\\\"slide down\\\"].out{-webkit-animation-name:slideOutY;animation-name:slideOutY;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"slide up\\\"].out{-webkit-animation-name:slideOutY;animation-name:slideOutY;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"slide left\\\"].out{-webkit-animation-name:slideOutX;animation-name:slideOutX;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"slide right\\\"].out{-webkit-animation-name:slideOutX;animation-name:slideOutX;-webkit-transform-origin:center left;transform-origin:center left}@-webkit-keyframes slideInY{0%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}100%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@keyframes slideInY{0%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}100%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@-webkit-keyframes slideInX{0%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}100%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes slideInX{0%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}100%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@-webkit-keyframes slideOutY{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}100%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@keyframes slideOutY{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}100%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@-webkit-keyframes slideOutX{0%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}100%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}}@keyframes slideOutX{0%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}100%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}}.transition.swing{-webkit-animation-duration:.8s;animation-duration:.8s}.transition[class*=\\\"swing down\\\"].in{-webkit-animation-name:swingInX;animation-name:swingInX;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"swing up\\\"].in{-webkit-animation-name:swingInX;animation-name:swingInX;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"swing left\\\"].in{-webkit-animation-name:swingInY;animation-name:swingInY;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"swing right\\\"].in{-webkit-animation-name:swingInY;animation-name:swingInY;-webkit-transform-origin:center left;transform-origin:center left}.transition.swing.out,.transition[class*=\\\"swing down\\\"].out{-webkit-animation-name:swingOutX;animation-name:swingOutX;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"swing up\\\"].out{-webkit-animation-name:swingOutX;animation-name:swingOutX;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"swing left\\\"].out{-webkit-animation-name:swingOutY;animation-name:swingOutY;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"swing right\\\"].out{-webkit-animation-name:swingOutY;animation-name:swingOutY;-webkit-transform-origin:center left;transform-origin:center left}@-webkit-keyframes swingInX{0%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateX(15deg);transform:perspective(1000px) rotateX(15deg)}80%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}100%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}}@keyframes swingInX{0%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateX(15deg);transform:perspective(1000px) rotateX(15deg)}80%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}100%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}}@-webkit-keyframes swingInY{0%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateY(-17.5deg);transform:perspective(1000px) rotateY(-17.5deg)}80%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}100%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}}@keyframes swingInY{0%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateY(-17.5deg);transform:perspective(1000px) rotateY(-17.5deg)}80%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}100%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}}@-webkit-keyframes swingOutX{0%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}40%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}60%{-webkit-transform:perspective(1000px) rotateX(17.5deg);transform:perspective(1000px) rotateX(17.5deg)}80%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}}@keyframes swingOutX{0%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}40%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}60%{-webkit-transform:perspective(1000px) rotateX(17.5deg);transform:perspective(1000px) rotateX(17.5deg)}80%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}}@-webkit-keyframes swingOutY{0%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}40%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}60%{-webkit-transform:perspective(1000px) rotateY(-10deg);transform:perspective(1000px) rotateY(-10deg)}80%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}}@keyframes swingOutY{0%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}40%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}60%{-webkit-transform:perspective(1000px) rotateY(-10deg);transform:perspective(1000px) rotateY(-10deg)}80%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}}.transition.zoom.in{-webkit-animation-name:zoomIn;animation-name:zoomIn}.transition.zoom.out{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomIn{0%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes zoomIn{0%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes zoomOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}}@keyframes zoomOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}}.flash.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:flash;animation-name:flash}.shake.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:shake;animation-name:shake}.bounce.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:bounce;animation-name:bounce}.tada.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:tada;animation-name:tada}.pulse.transition{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-name:pulse;animation-name:pulse}.jiggle.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:jiggle;animation-name:jiggle}.transition.glow{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:cubic-bezier(.19,1,.22,1);animation-timing-function:cubic-bezier(.19,1,.22,1)}.transition.glow{-webkit-animation-name:glow;animation-name:glow}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@-webkit-keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@-webkit-keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9) rotate(-3deg);transform:scale(.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}@keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9) rotate(-3deg);transform:scale(.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.9);transform:scale(.9);opacity:.7}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.9);transform:scale(.9);opacity:.7}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes jiggle{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes jiggle{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@-webkit-keyframes glow{0%{background-color:#fcfcfd}30%{background-color:#fff6cd}100%{background-color:#fcfcfd}}@keyframes glow{0%{background-color:#fcfcfd}30%{background-color:#fff6cd}100%{background-color:#fcfcfd}}\", \"\",{\"version\":3,\"sources\":[\"semantic.min.css\"],\"names\":[],\"mappings\":\"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\",\"file\":\"semantic.min.css\",\"sourcesContent\":[\" /*\\n * # Semantic UI - 2.4.0\\n * https://github.com/Semantic-Org/Semantic-UI\\n * http://www.semantic-ui.com/\\n *\\n * Copyright 2014 Contributors\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */\\n@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin);/*!\\n * # Semantic UI 2.4.0 - Reset\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}html{-webkit-box-sizing:border-box;box-sizing:border-box}input[type=email],input[type=password],input[type=search],input[type=text]{-webkit-appearance:none;-moz-appearance:none}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*!\\n * # Semantic UI 2.4.0 - Site\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */body,html{height:100%}html{font-size:14px}body{margin:0;padding:0;overflow-x:hidden;min-width:320px;background:#fff;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:14px;line-height:1.4285em;color:rgba(0,0,0,.87);font-smoothing:antialiased}h1,h2,h3,h4,h5{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;line-height:1.28571429em;margin:calc(2rem - .14285714em) 0 1rem;font-weight:700;padding:0}h1{min-height:1rem;font-size:2rem}h2{font-size:1.71428571rem}h3{font-size:1.28571429rem}h4{font-size:1.07142857rem}h5{font-size:1rem}h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child{margin-top:0}h1:last-child,h2:last-child,h3:last-child,h4:last-child,h5:last-child{margin-bottom:0}p{margin:0 0 1em;line-height:1.4285em}p:first-child{margin-top:0}p:last-child{margin-bottom:0}a{color:#4183c4;text-decoration:none}a:hover{color:#1e70bf;text-decoration:none}::-webkit-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::-moz-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}input::-webkit-selection,textarea::-webkit-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::-moz-selection,textarea::-moz-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::selection,textarea::selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}body ::-webkit-scrollbar{-webkit-appearance:none;width:10px;height:10px}body ::-webkit-scrollbar-track{background:rgba(0,0,0,.1);border-radius:0}body ::-webkit-scrollbar-thumb{cursor:pointer;border-radius:5px;background:rgba(0,0,0,.25);-webkit-transition:color .2s ease;transition:color .2s ease}body ::-webkit-scrollbar-thumb:window-inactive{background:rgba(0,0,0,.15)}body ::-webkit-scrollbar-thumb:hover{background:rgba(128,135,139,.8)}body .ui.inverted::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}body .ui.inverted::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}body .ui.inverted::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}body .ui.inverted::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}/*!\\n * # Semantic UI 2.4.0 - Button\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.button{cursor:pointer;display:inline-block;min-height:1em;outline:0;border:none;vertical-align:baseline;background:#e0e1e2 none;color:rgba(0,0,0,.6);font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;margin:0 .25em 0 0;padding:.78571429em 1.5em .78571429em;text-transform:none;text-shadow:none;font-weight:700;line-height:1em;font-style:normal;text-align:center;text-decoration:none;border-radius:.28571429rem;-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;transition:opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;will-change:'';-webkit-tap-highlight-color:transparent}.ui.button:hover{background-color:#cacbcd;background-image:none;-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;color:rgba(0,0,0,.8)}.ui.button:hover .icon{opacity:.85}.ui.button:focus{background-color:#cacbcd;color:rgba(0,0,0,.8);background-image:''!important;-webkit-box-shadow:''!important;box-shadow:''!important}.ui.button:focus .icon{opacity:.85}.ui.active.button:active,.ui.button:active{background-color:#babbbc;background-image:'';color:rgba(0,0,0,.9);-webkit-box-shadow:0 0 0 1px transparent inset,none;box-shadow:0 0 0 1px transparent inset,none}.ui.active.button{background-color:#c0c1c2;background-image:none;-webkit-box-shadow:0 0 0 1px transparent inset;box-shadow:0 0 0 1px transparent inset;color:rgba(0,0,0,.95)}.ui.active.button:hover{background-color:#c0c1c2;background-image:none;color:rgba(0,0,0,.95)}.ui.active.button:active{background-color:#c0c1c2;background-image:none}.ui.loading.loading.loading.loading.loading.loading.button{position:relative;cursor:default;text-shadow:none!important;color:transparent!important;opacity:1;pointer-events:auto;-webkit-transition:all 0s linear,opacity .1s ease;transition:all 0s linear,opacity .1s ease}.ui.loading.button:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.15)}.ui.loading.button:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#fff transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.labeled.icon.loading.button .icon{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}@-webkit-keyframes button-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes button-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.basic.loading.button:not(.inverted):before{border-color:rgba(0,0,0,.1)}.ui.basic.loading.button:not(.inverted):after{border-top-color:#767676}.ui.button:disabled,.ui.buttons .disabled.button,.ui.disabled.active.button,.ui.disabled.button,.ui.disabled.button:hover{cursor:default;opacity:.45!important;background-image:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;pointer-events:none!important}.ui.basic.buttons .ui.disabled.button{border-color:rgba(34,36,38,.5)}.ui.animated.button{position:relative;overflow:hidden;padding-right:0!important;vertical-align:middle;z-index:1}.ui.animated.button .content{will-change:transform,opacity}.ui.animated.button .visible.content{position:relative;margin-right:1.5em}.ui.animated.button .hidden.content{position:absolute;width:100%}.ui.animated.button .hidden.content,.ui.animated.button .visible.content{-webkit-transition:right .3s ease 0s;transition:right .3s ease 0s}.ui.animated.button .visible.content{left:auto;right:0}.ui.animated.button .hidden.content{top:50%;left:auto;right:-100%;margin-top:-.5em}.ui.animated.button:focus .visible.content,.ui.animated.button:hover .visible.content{left:auto;right:200%}.ui.animated.button:focus .hidden.content,.ui.animated.button:hover .hidden.content{left:auto;right:0}.ui.vertical.animated.button .hidden.content,.ui.vertical.animated.button .visible.content{-webkit-transition:top .3s ease,-webkit-transform .3s ease;transition:top .3s ease,-webkit-transform .3s ease;transition:top .3s ease,transform .3s ease;transition:top .3s ease,transform .3s ease,-webkit-transform .3s ease}.ui.vertical.animated.button .visible.content{-webkit-transform:translateY(0);transform:translateY(0);right:auto}.ui.vertical.animated.button .hidden.content{top:-50%;left:0;right:auto}.ui.vertical.animated.button:focus .visible.content,.ui.vertical.animated.button:hover .visible.content{-webkit-transform:translateY(200%);transform:translateY(200%);right:auto}.ui.vertical.animated.button:focus .hidden.content,.ui.vertical.animated.button:hover .hidden.content{top:50%;right:auto}.ui.fade.animated.button .hidden.content,.ui.fade.animated.button .visible.content{-webkit-transition:opacity .3s ease,-webkit-transform .3s ease;transition:opacity .3s ease,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease;transition:opacity .3s ease,transform .3s ease,-webkit-transform .3s ease}.ui.fade.animated.button .visible.content{left:auto;right:auto;opacity:1;-webkit-transform:scale(1);transform:scale(1)}.ui.fade.animated.button .hidden.content{opacity:0;left:0;right:auto;-webkit-transform:scale(1.5);transform:scale(1.5)}.ui.fade.animated.button:focus .visible.content,.ui.fade.animated.button:hover .visible.content{left:auto;right:auto;opacity:0;-webkit-transform:scale(.75);transform:scale(.75)}.ui.fade.animated.button:focus .hidden.content,.ui.fade.animated.button:hover .hidden.content{left:0;right:auto;opacity:1;-webkit-transform:scale(1);transform:scale(1)}.ui.inverted.button{-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;background:transparent none;color:#fff;text-shadow:none!important}.ui.inverted.buttons .button{margin:0 0 0 -2px}.ui.inverted.buttons .button:first-child{margin-left:0}.ui.inverted.vertical.buttons .button{margin:0 0 -2px 0}.ui.inverted.vertical.buttons .button:first-child{margin-top:0}.ui.inverted.button:hover{background:#fff;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;color:rgba(0,0,0,.8)}.ui.inverted.button.active,.ui.inverted.button:focus{background:#fff;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important;color:rgba(0,0,0,.8)}.ui.inverted.button.active:focus{background:#dcddde;-webkit-box-shadow:0 0 0 2px #dcddde inset!important;box-shadow:0 0 0 2px #dcddde inset!important;color:rgba(0,0,0,.8)}.ui.labeled.button:not(.icon){display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;background:0 0!important;padding:0!important;border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.labeled.button>.button{margin:0}.ui.labeled.button>.label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 0 0 -1px!important;padding:'';font-size:1em;border-color:rgba(34,36,38,.15)}.ui.labeled.button>.tag.label:before{width:1.85em;height:1.85em}.ui.labeled.button:not([class*=\\\"left labeled\\\"])>.button{border-top-right-radius:0;border-bottom-right-radius:0}.ui.labeled.button:not([class*=\\\"left labeled\\\"])>.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"left labeled\\\"].button>.button{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"left labeled\\\"].button>.label{border-top-right-radius:0;border-bottom-right-radius:0}.ui.facebook.button{background-color:#3b5998;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.facebook.button:hover{background-color:#304d8a;color:#fff;text-shadow:none}.ui.facebook.button:active{background-color:#2d4373;color:#fff;text-shadow:none}.ui.twitter.button{background-color:#55acee;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.twitter.button:hover{background-color:#35a2f4;color:#fff;text-shadow:none}.ui.twitter.button:active{background-color:#2795e9;color:#fff;text-shadow:none}.ui.google.plus.button{background-color:#dd4b39;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.google.plus.button:hover{background-color:#e0321c;color:#fff;text-shadow:none}.ui.google.plus.button:active{background-color:#c23321;color:#fff;text-shadow:none}.ui.linkedin.button{background-color:#1f88be;color:#fff;text-shadow:none}.ui.linkedin.button:hover{background-color:#147baf;color:#fff;text-shadow:none}.ui.linkedin.button:active{background-color:#186992;color:#fff;text-shadow:none}.ui.youtube.button{background-color:red;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.youtube.button:hover{background-color:#e60000;color:#fff;text-shadow:none}.ui.youtube.button:active{background-color:#c00;color:#fff;text-shadow:none}.ui.instagram.button{background-color:#49769c;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.instagram.button:hover{background-color:#3d698e;color:#fff;text-shadow:none}.ui.instagram.button:active{background-color:#395c79;color:#fff;text-shadow:none}.ui.pinterest.button{background-color:#bd081c;color:#fff;text-shadow:none;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pinterest.button:hover{background-color:#ac0013;color:#fff;text-shadow:none}.ui.pinterest.button:active{background-color:#8c0615;color:#fff;text-shadow:none}.ui.vk.button{background-color:#4d7198;color:#fff;background-image:none;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.vk.button:hover{background-color:#41648a;color:#fff}.ui.vk.button:active{background-color:#3c5876;color:#fff}.ui.button>.icon:not(.button){height:.85714286em;opacity:.8;margin:0 .42857143em 0 -.21428571em;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;vertical-align:'';color:''}.ui.button:not(.icon)>.icon:not(.button):not(.dropdown){margin:0 .42857143em 0 -.21428571em}.ui.button:not(.icon)>.right.icon:not(.button):not(.dropdown){margin:0 -.21428571em 0 .42857143em}.ui[class*=\\\"left floated\\\"].button,.ui[class*=\\\"left floated\\\"].buttons{float:left;margin-left:0;margin-right:.25em}.ui[class*=\\\"right floated\\\"].button,.ui[class*=\\\"right floated\\\"].buttons{float:right;margin-right:0;margin-left:.25em}.ui.compact.button,.ui.compact.buttons .button{padding:.58928571em 1.125em .58928571em}.ui.compact.icon.button,.ui.compact.icon.buttons .button{padding:.58928571em .58928571em .58928571em}.ui.compact.labeled.icon.button,.ui.compact.labeled.icon.buttons .button{padding:.58928571em 3.69642857em .58928571em}.ui.mini.button,.ui.mini.buttons .button,.ui.mini.buttons .or{font-size:.78571429rem}.ui.tiny.button,.ui.tiny.buttons .button,.ui.tiny.buttons .or{font-size:.85714286rem}.ui.small.button,.ui.small.buttons .button,.ui.small.buttons .or{font-size:.92857143rem}.ui.button,.ui.buttons .button,.ui.buttons .or{font-size:1rem}.ui.large.button,.ui.large.buttons .button,.ui.large.buttons .or{font-size:1.14285714rem}.ui.big.button,.ui.big.buttons .button,.ui.big.buttons .or{font-size:1.28571429rem}.ui.huge.button,.ui.huge.buttons .button,.ui.huge.buttons .or{font-size:1.42857143rem}.ui.massive.button,.ui.massive.buttons .button,.ui.massive.buttons .or{font-size:1.71428571rem}.ui.icon.button,.ui.icon.buttons .button{padding:.78571429em .78571429em .78571429em}.ui.icon.button>.icon,.ui.icon.buttons .button>.icon{opacity:.9;margin:0!important;vertical-align:top}.ui.basic.button,.ui.basic.buttons .button{background:transparent none!important;color:rgba(0,0,0,.6)!important;font-weight:400;border-radius:.28571429rem;text-transform:none;text-shadow:none!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.basic.buttons{-webkit-box-shadow:none;box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem}.ui.basic.buttons .button{border-radius:0}.ui.basic.button:hover,.ui.basic.buttons .button:hover{background:#fff!important;color:rgba(0,0,0,.8)!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:focus,.ui.basic.buttons .button:focus{background:#fff!important;color:rgba(0,0,0,.8)!important;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:active,.ui.basic.buttons .button:active{background:#f8f8f8!important;color:rgba(0,0,0,.9)!important;-webkit-box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset}.ui.basic.active.button,.ui.basic.buttons .active.button{background:rgba(0,0,0,.05)!important;-webkit-box-shadow:''!important;box-shadow:''!important;color:rgba(0,0,0,.95)!important}.ui.basic.active.button:hover,.ui.basic.buttons .active.button:hover{background-color:rgba(0,0,0,.05)}.ui.basic.buttons .button:hover{-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset inset;box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset inset}.ui.basic.buttons .button:active{-webkit-box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset inset;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset inset}.ui.basic.buttons .active.button{-webkit-box-shadow:''!important;box-shadow:''!important}.ui.basic.inverted.button,.ui.basic.inverted.buttons .button{background-color:transparent!important;color:#f9fafb!important;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important}.ui.basic.inverted.button:hover,.ui.basic.inverted.buttons .button:hover{color:#fff!important;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.inverted.button:focus,.ui.basic.inverted.buttons .button:focus{color:#fff!important;-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.inverted.button:active,.ui.basic.inverted.buttons .button:active{background-color:rgba(255,255,255,.08)!important;color:#fff!important;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.9) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.9) inset!important}.ui.basic.inverted.active.button,.ui.basic.inverted.buttons .active.button{background-color:rgba(255,255,255,.08);color:#fff;text-shadow:none;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.7) inset;box-shadow:0 0 0 2px rgba(255,255,255,.7) inset}.ui.basic.inverted.active.button:hover,.ui.basic.inverted.buttons .active.button:hover{background-color:rgba(255,255,255,.15);-webkit-box-shadow:0 0 0 2px #fff inset!important;box-shadow:0 0 0 2px #fff inset!important}.ui.basic.buttons .button{border-left:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.vertical.buttons .button{border-left:none}.ui.basic.vertical.buttons .button{border-left-width:0;border-top:1px solid rgba(34,36,38,.15)}.ui.basic.vertical.buttons .button:first-child{border-top-width:0}.ui.labeled.icon.button,.ui.labeled.icon.buttons .button{position:relative;padding-left:4.07142857em!important;padding-right:1.5em!important}.ui.labeled.icon.button>.icon,.ui.labeled.icon.buttons>.button>.icon{position:absolute;height:100%;line-height:1;border-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit;text-align:center;margin:0;width:2.57142857em;background-color:rgba(0,0,0,.05);color:'';-webkit-box-shadow:-1px 0 0 0 transparent inset;box-shadow:-1px 0 0 0 transparent inset}.ui.labeled.icon.button>.icon,.ui.labeled.icon.buttons>.button>.icon{top:0;left:0}.ui[class*=\\\"right labeled\\\"].icon.button{padding-right:4.07142857em!important;padding-left:1.5em!important}.ui[class*=\\\"right labeled\\\"].icon.button>.icon{left:auto;right:0;border-radius:0;border-top-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-box-shadow:1px 0 0 0 transparent inset;box-shadow:1px 0 0 0 transparent inset}.ui.labeled.icon.button>.icon:after,.ui.labeled.icon.button>.icon:before,.ui.labeled.icon.buttons>.button>.icon:after,.ui.labeled.icon.buttons>.button>.icon:before{display:block;position:absolute;width:100%;top:50%;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ui.labeled.icon.buttons .button>.icon{border-radius:0}.ui.labeled.icon.buttons .button:first-child>.icon{border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.labeled.icon.buttons .button:last-child>.icon{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:first-child>.icon{border-radius:0;border-top-left-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:last-child>.icon{border-radius:0;border-bottom-left-radius:.28571429rem}.ui.fluid[class*=\\\"left labeled\\\"].icon.button,.ui.fluid[class*=\\\"right labeled\\\"].icon.button{padding-left:1.5em!important;padding-right:1.5em!important}.ui.button.toggle.active,.ui.buttons .button.toggle.active,.ui.toggle.buttons .active.button{background-color:#21ba45!important;-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none;color:#fff!important}.ui.button.toggle.active:hover{background-color:#16ab39!important;text-shadow:none;color:#fff!important}.ui.circular.button{border-radius:10em}.ui.circular.button>.icon{width:1em;vertical-align:baseline}.ui.buttons .or{position:relative;width:.3em;height:2.57142857em;z-index:3}.ui.buttons .or:before{position:absolute;text-align:center;border-radius:500rem;content:'or';top:50%;left:50%;background-color:#fff;text-shadow:none;margin-top:-.89285714em;margin-left:-.89285714em;width:1.78571429em;height:1.78571429em;line-height:1.78571429em;color:rgba(0,0,0,.4);font-style:normal;font-weight:700;-webkit-box-shadow:0 0 0 1px transparent inset;box-shadow:0 0 0 1px transparent inset}.ui.buttons .or[data-text]:before{content:attr(data-text)}.ui.fluid.buttons .or{width:0!important}.ui.fluid.buttons .or:after{display:none}.ui.attached.button{position:relative;display:block;margin:0;border-radius:0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15)!important}.ui.attached.top.button{border-radius:.28571429rem .28571429rem 0 0}.ui.attached.bottom.button{border-radius:0 0 .28571429rem .28571429rem}.ui.left.attached.button{display:inline-block;border-left:none;text-align:right;padding-right:.75em;border-radius:.28571429rem 0 0 .28571429rem}.ui.right.attached.button{display:inline-block;text-align:left;padding-left:.75em;border-radius:0 .28571429rem .28571429rem 0}.ui.attached.buttons{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:0;width:auto!important;z-index:2;margin-left:-1px;margin-right:-1px}.ui.attached.buttons .button{margin:0}.ui.attached.buttons .button:first-child{border-radius:0}.ui.attached.buttons .button:last-child{border-radius:0}.ui[class*=\\\"top attached\\\"].buttons{margin-bottom:-1px;border-radius:.28571429rem .28571429rem 0 0}.ui[class*=\\\"top attached\\\"].buttons .button:first-child{border-radius:.28571429rem 0 0 0}.ui[class*=\\\"top attached\\\"].buttons .button:last-child{border-radius:0 .28571429rem 0 0}.ui[class*=\\\"bottom attached\\\"].buttons{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].buttons .button:first-child{border-radius:0 0 0 .28571429rem}.ui[class*=\\\"bottom attached\\\"].buttons .button:last-child{border-radius:0 0 .28571429rem 0}.ui[class*=\\\"left attached\\\"].buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:0;margin-left:-1px;border-radius:0 .28571429rem .28571429rem 0}.ui[class*=\\\"left attached\\\"].buttons .button:first-child{margin-left:-1px;border-radius:0 .28571429rem 0 0}.ui[class*=\\\"left attached\\\"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 .28571429rem 0}.ui[class*=\\\"right attached\\\"].buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-left:0;margin-right:-1px;border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"right attached\\\"].buttons .button:first-child{margin-left:-1px;border-radius:.28571429rem 0 0 0}.ui[class*=\\\"right attached\\\"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 0 .28571429rem}.ui.fluid.button,.ui.fluid.buttons{width:100%}.ui.fluid.button{display:block}.ui.two.buttons{width:100%}.ui.two.buttons>.button{width:50%}.ui.three.buttons{width:100%}.ui.three.buttons>.button{width:33.333%}.ui.four.buttons{width:100%}.ui.four.buttons>.button{width:25%}.ui.five.buttons{width:100%}.ui.five.buttons>.button{width:20%}.ui.six.buttons{width:100%}.ui.six.buttons>.button{width:16.666%}.ui.seven.buttons{width:100%}.ui.seven.buttons>.button{width:14.285%}.ui.eight.buttons{width:100%}.ui.eight.buttons>.button{width:12.5%}.ui.nine.buttons{width:100%}.ui.nine.buttons>.button{width:11.11%}.ui.ten.buttons{width:100%}.ui.ten.buttons>.button{width:10%}.ui.eleven.buttons{width:100%}.ui.eleven.buttons>.button{width:9.09%}.ui.twelve.buttons{width:100%}.ui.twelve.buttons>.button{width:8.3333%}.ui.fluid.vertical.buttons,.ui.fluid.vertical.buttons>.button{display:-webkit-box;display:-ms-flexbox;display:flex;width:auto}.ui.two.vertical.buttons>.button{height:50%}.ui.three.vertical.buttons>.button{height:33.333%}.ui.four.vertical.buttons>.button{height:25%}.ui.five.vertical.buttons>.button{height:20%}.ui.six.vertical.buttons>.button{height:16.666%}.ui.seven.vertical.buttons>.button{height:14.285%}.ui.eight.vertical.buttons>.button{height:12.5%}.ui.nine.vertical.buttons>.button{height:11.11%}.ui.ten.vertical.buttons>.button{height:10%}.ui.eleven.vertical.buttons>.button{height:9.09%}.ui.twelve.vertical.buttons>.button{height:8.3333%}.ui.black.button,.ui.black.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.black.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.black.button:hover,.ui.black.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.black.button:focus,.ui.black.buttons .button:focus{background-color:#2f3032;color:#fff;text-shadow:none}.ui.black.button:active,.ui.black.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.black.active.button,.ui.black.button .active.button:active,.ui.black.buttons .active.button,.ui.black.buttons .active.button:active{background-color:#0f0f10;color:#fff;text-shadow:none}.ui.basic.black.button,.ui.basic.black.buttons .button{-webkit-box-shadow:0 0 0 1px #1b1c1d inset!important;box-shadow:0 0 0 1px #1b1c1d inset!important;color:#1b1c1d!important}.ui.basic.black.button:hover,.ui.basic.black.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#27292a!important}.ui.basic.black.button:focus,.ui.basic.black.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #2f3032 inset!important;box-shadow:0 0 0 1px #2f3032 inset!important;color:#27292a!important}.ui.basic.black.active.button,.ui.basic.black.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0f0f10 inset!important;box-shadow:0 0 0 1px #0f0f10 inset!important;color:#343637!important}.ui.basic.black.button:active,.ui.basic.black.buttons .button:active{-webkit-box-shadow:0 0 0 1px #343637 inset!important;box-shadow:0 0 0 1px #343637 inset!important;color:#343637!important}.ui.buttons:not(.vertical)>.basic.black.button:not(:first-child){margin-left:-1px}.ui.inverted.black.button,.ui.inverted.black.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d4d4d5 inset!important;box-shadow:0 0 0 2px #d4d4d5 inset!important;color:#fff}.ui.inverted.black.button.active,.ui.inverted.black.button:active,.ui.inverted.black.button:focus,.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button.active,.ui.inverted.black.buttons .button:active,.ui.inverted.black.buttons .button:focus,.ui.inverted.black.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button:hover{background-color:#000}.ui.inverted.black.button:focus,.ui.inverted.black.buttons .button:focus{background-color:#000}.ui.inverted.black.active.button,.ui.inverted.black.buttons .active.button{background-color:#000}.ui.inverted.black.button:active,.ui.inverted.black.buttons .button:active{background-color:#000}.ui.inverted.black.basic.button,.ui.inverted.black.basic.buttons .button,.ui.inverted.black.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.black.basic.button:hover,.ui.inverted.black.basic.buttons .button:hover,.ui.inverted.black.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.inverted.black.basic.button:focus,.ui.inverted.black.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#545454!important}.ui.inverted.black.basic.active.button,.ui.inverted.black.basic.buttons .active.button,.ui.inverted.black.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.inverted.black.basic.button:active,.ui.inverted.black.basic.buttons .button:active,.ui.inverted.black.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #000 inset!important;box-shadow:0 0 0 2px #000 inset!important;color:#fff!important}.ui.grey.button,.ui.grey.buttons .button{background-color:#767676;color:#fff;text-shadow:none;background-image:none}.ui.grey.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.grey.button:hover,.ui.grey.buttons .button:hover{background-color:#838383;color:#fff;text-shadow:none}.ui.grey.button:focus,.ui.grey.buttons .button:focus{background-color:#8a8a8a;color:#fff;text-shadow:none}.ui.grey.button:active,.ui.grey.buttons .button:active{background-color:#909090;color:#fff;text-shadow:none}.ui.grey.active.button,.ui.grey.button .active.button:active,.ui.grey.buttons .active.button,.ui.grey.buttons .active.button:active{background-color:#696969;color:#fff;text-shadow:none}.ui.basic.grey.button,.ui.basic.grey.buttons .button{-webkit-box-shadow:0 0 0 1px #767676 inset!important;box-shadow:0 0 0 1px #767676 inset!important;color:#767676!important}.ui.basic.grey.button:hover,.ui.basic.grey.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #838383 inset!important;box-shadow:0 0 0 1px #838383 inset!important;color:#838383!important}.ui.basic.grey.button:focus,.ui.basic.grey.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #8a8a8a inset!important;box-shadow:0 0 0 1px #8a8a8a inset!important;color:#838383!important}.ui.basic.grey.active.button,.ui.basic.grey.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #696969 inset!important;box-shadow:0 0 0 1px #696969 inset!important;color:#909090!important}.ui.basic.grey.button:active,.ui.basic.grey.buttons .button:active{-webkit-box-shadow:0 0 0 1px #909090 inset!important;box-shadow:0 0 0 1px #909090 inset!important;color:#909090!important}.ui.buttons:not(.vertical)>.basic.grey.button:not(:first-child){margin-left:-1px}.ui.inverted.grey.button,.ui.inverted.grey.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d4d4d5 inset!important;box-shadow:0 0 0 2px #d4d4d5 inset!important;color:#fff}.ui.inverted.grey.button.active,.ui.inverted.grey.button:active,.ui.inverted.grey.button:focus,.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button.active,.ui.inverted.grey.buttons .button:active,.ui.inverted.grey.buttons .button:focus,.ui.inverted.grey.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button:hover{background-color:#cfd0d2}.ui.inverted.grey.button:focus,.ui.inverted.grey.buttons .button:focus{background-color:#c7c9cb}.ui.inverted.grey.active.button,.ui.inverted.grey.buttons .active.button{background-color:#cfd0d2}.ui.inverted.grey.button:active,.ui.inverted.grey.buttons .button:active{background-color:#c2c4c5}.ui.inverted.grey.basic.button,.ui.inverted.grey.basic.buttons .button,.ui.inverted.grey.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.grey.basic.button:hover,.ui.inverted.grey.basic.buttons .button:hover,.ui.inverted.grey.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #cfd0d2 inset!important;box-shadow:0 0 0 2px #cfd0d2 inset!important;color:#fff!important}.ui.inverted.grey.basic.button:focus,.ui.inverted.grey.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #c7c9cb inset!important;box-shadow:0 0 0 2px #c7c9cb inset!important;color:#dcddde!important}.ui.inverted.grey.basic.active.button,.ui.inverted.grey.basic.buttons .active.button,.ui.inverted.grey.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #cfd0d2 inset!important;box-shadow:0 0 0 2px #cfd0d2 inset!important;color:#fff!important}.ui.inverted.grey.basic.button:active,.ui.inverted.grey.basic.buttons .button:active,.ui.inverted.grey.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #c2c4c5 inset!important;box-shadow:0 0 0 2px #c2c4c5 inset!important;color:#fff!important}.ui.brown.button,.ui.brown.buttons .button{background-color:#a5673f;color:#fff;text-shadow:none;background-image:none}.ui.brown.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.brown.button:hover,.ui.brown.buttons .button:hover{background-color:#975b33;color:#fff;text-shadow:none}.ui.brown.button:focus,.ui.brown.buttons .button:focus{background-color:#90532b;color:#fff;text-shadow:none}.ui.brown.button:active,.ui.brown.buttons .button:active{background-color:#805031;color:#fff;text-shadow:none}.ui.brown.active.button,.ui.brown.button .active.button:active,.ui.brown.buttons .active.button,.ui.brown.buttons .active.button:active{background-color:#995a31;color:#fff;text-shadow:none}.ui.basic.brown.button,.ui.basic.brown.buttons .button{-webkit-box-shadow:0 0 0 1px #a5673f inset!important;box-shadow:0 0 0 1px #a5673f inset!important;color:#a5673f!important}.ui.basic.brown.button:hover,.ui.basic.brown.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #975b33 inset!important;box-shadow:0 0 0 1px #975b33 inset!important;color:#975b33!important}.ui.basic.brown.button:focus,.ui.basic.brown.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #90532b inset!important;box-shadow:0 0 0 1px #90532b inset!important;color:#975b33!important}.ui.basic.brown.active.button,.ui.basic.brown.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #995a31 inset!important;box-shadow:0 0 0 1px #995a31 inset!important;color:#805031!important}.ui.basic.brown.button:active,.ui.basic.brown.buttons .button:active{-webkit-box-shadow:0 0 0 1px #805031 inset!important;box-shadow:0 0 0 1px #805031 inset!important;color:#805031!important}.ui.buttons:not(.vertical)>.basic.brown.button:not(:first-child){margin-left:-1px}.ui.inverted.brown.button,.ui.inverted.brown.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d67c1c inset!important;box-shadow:0 0 0 2px #d67c1c inset!important;color:#d67c1c}.ui.inverted.brown.button.active,.ui.inverted.brown.button:active,.ui.inverted.brown.button:focus,.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button.active,.ui.inverted.brown.buttons .button:active,.ui.inverted.brown.buttons .button:focus,.ui.inverted.brown.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button:hover{background-color:#c86f11}.ui.inverted.brown.button:focus,.ui.inverted.brown.buttons .button:focus{background-color:#c16808}.ui.inverted.brown.active.button,.ui.inverted.brown.buttons .active.button{background-color:#cc6f0d}.ui.inverted.brown.button:active,.ui.inverted.brown.buttons .button:active{background-color:#a96216}.ui.inverted.brown.basic.button,.ui.inverted.brown.basic.buttons .button,.ui.inverted.brown.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.brown.basic.button:hover,.ui.inverted.brown.basic.buttons .button:hover,.ui.inverted.brown.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #c86f11 inset!important;box-shadow:0 0 0 2px #c86f11 inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.button:focus,.ui.inverted.brown.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #c16808 inset!important;box-shadow:0 0 0 2px #c16808 inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.active.button,.ui.inverted.brown.basic.buttons .active.button,.ui.inverted.brown.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #cc6f0d inset!important;box-shadow:0 0 0 2px #cc6f0d inset!important;color:#d67c1c!important}.ui.inverted.brown.basic.button:active,.ui.inverted.brown.basic.buttons .button:active,.ui.inverted.brown.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #a96216 inset!important;box-shadow:0 0 0 2px #a96216 inset!important;color:#d67c1c!important}.ui.blue.button,.ui.blue.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.blue.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.blue.button:hover,.ui.blue.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.blue.button:focus,.ui.blue.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.blue.button:active,.ui.blue.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.blue.active.button,.ui.blue.button .active.button:active,.ui.blue.buttons .active.button,.ui.blue.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.blue.button,.ui.basic.blue.buttons .button{-webkit-box-shadow:0 0 0 1px #2185d0 inset!important;box-shadow:0 0 0 1px #2185d0 inset!important;color:#2185d0!important}.ui.basic.blue.button:hover,.ui.basic.blue.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1678c2 inset!important;box-shadow:0 0 0 1px #1678c2 inset!important;color:#1678c2!important}.ui.basic.blue.button:focus,.ui.basic.blue.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0d71bb inset!important;box-shadow:0 0 0 1px #0d71bb inset!important;color:#1678c2!important}.ui.basic.blue.active.button,.ui.basic.blue.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1279c6 inset!important;box-shadow:0 0 0 1px #1279c6 inset!important;color:#1a69a4!important}.ui.basic.blue.button:active,.ui.basic.blue.buttons .button:active{-webkit-box-shadow:0 0 0 1px #1a69a4 inset!important;box-shadow:0 0 0 1px #1a69a4 inset!important;color:#1a69a4!important}.ui.buttons:not(.vertical)>.basic.blue.button:not(:first-child){margin-left:-1px}.ui.inverted.blue.button,.ui.inverted.blue.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #54c8ff inset!important;box-shadow:0 0 0 2px #54c8ff inset!important;color:#54c8ff}.ui.inverted.blue.button.active,.ui.inverted.blue.button:active,.ui.inverted.blue.button:focus,.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button.active,.ui.inverted.blue.buttons .button:active,.ui.inverted.blue.buttons .button:focus,.ui.inverted.blue.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button:hover{background-color:#3ac0ff}.ui.inverted.blue.button:focus,.ui.inverted.blue.buttons .button:focus{background-color:#2bbbff}.ui.inverted.blue.active.button,.ui.inverted.blue.buttons .active.button{background-color:#3ac0ff}.ui.inverted.blue.button:active,.ui.inverted.blue.buttons .button:active{background-color:#21b8ff}.ui.inverted.blue.basic.button,.ui.inverted.blue.basic.buttons .button,.ui.inverted.blue.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.blue.basic.button:hover,.ui.inverted.blue.basic.buttons .button:hover,.ui.inverted.blue.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.button:focus,.ui.inverted.blue.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #2bbbff inset!important;box-shadow:0 0 0 2px #2bbbff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.active.button,.ui.inverted.blue.basic.buttons .active.button,.ui.inverted.blue.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.blue.basic.button:active,.ui.inverted.blue.basic.buttons .button:active,.ui.inverted.blue.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #21b8ff inset!important;box-shadow:0 0 0 2px #21b8ff inset!important;color:#54c8ff!important}.ui.green.button,.ui.green.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.green.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.green.button:hover,.ui.green.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.green.button:focus,.ui.green.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.green.button:active,.ui.green.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.green.active.button,.ui.green.button .active.button:active,.ui.green.buttons .active.button,.ui.green.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.green.button,.ui.basic.green.buttons .button{-webkit-box-shadow:0 0 0 1px #21ba45 inset!important;box-shadow:0 0 0 1px #21ba45 inset!important;color:#21ba45!important}.ui.basic.green.button:hover,.ui.basic.green.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #16ab39 inset!important;box-shadow:0 0 0 1px #16ab39 inset!important;color:#16ab39!important}.ui.basic.green.button:focus,.ui.basic.green.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0ea432 inset!important;box-shadow:0 0 0 1px #0ea432 inset!important;color:#16ab39!important}.ui.basic.green.active.button,.ui.basic.green.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #13ae38 inset!important;box-shadow:0 0 0 1px #13ae38 inset!important;color:#198f35!important}.ui.basic.green.button:active,.ui.basic.green.buttons .button:active{-webkit-box-shadow:0 0 0 1px #198f35 inset!important;box-shadow:0 0 0 1px #198f35 inset!important;color:#198f35!important}.ui.buttons:not(.vertical)>.basic.green.button:not(:first-child){margin-left:-1px}.ui.inverted.green.button,.ui.inverted.green.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #2ecc40 inset!important;box-shadow:0 0 0 2px #2ecc40 inset!important;color:#2ecc40}.ui.inverted.green.button.active,.ui.inverted.green.button:active,.ui.inverted.green.button:focus,.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button.active,.ui.inverted.green.buttons .button:active,.ui.inverted.green.buttons .button:focus,.ui.inverted.green.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button:hover{background-color:#22be34}.ui.inverted.green.button:focus,.ui.inverted.green.buttons .button:focus{background-color:#19b82b}.ui.inverted.green.active.button,.ui.inverted.green.buttons .active.button{background-color:#1fc231}.ui.inverted.green.button:active,.ui.inverted.green.buttons .button:active{background-color:#25a233}.ui.inverted.green.basic.button,.ui.inverted.green.basic.buttons .button,.ui.inverted.green.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.green.basic.button:hover,.ui.inverted.green.basic.buttons .button:hover,.ui.inverted.green.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #22be34 inset!important;box-shadow:0 0 0 2px #22be34 inset!important;color:#2ecc40!important}.ui.inverted.green.basic.button:focus,.ui.inverted.green.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #19b82b inset!important;box-shadow:0 0 0 2px #19b82b inset!important;color:#2ecc40!important}.ui.inverted.green.basic.active.button,.ui.inverted.green.basic.buttons .active.button,.ui.inverted.green.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #1fc231 inset!important;box-shadow:0 0 0 2px #1fc231 inset!important;color:#2ecc40!important}.ui.inverted.green.basic.button:active,.ui.inverted.green.basic.buttons .button:active,.ui.inverted.green.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #25a233 inset!important;box-shadow:0 0 0 2px #25a233 inset!important;color:#2ecc40!important}.ui.orange.button,.ui.orange.buttons .button{background-color:#f2711c;color:#fff;text-shadow:none;background-image:none}.ui.orange.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.orange.button:hover,.ui.orange.buttons .button:hover{background-color:#f26202;color:#fff;text-shadow:none}.ui.orange.button:focus,.ui.orange.buttons .button:focus{background-color:#e55b00;color:#fff;text-shadow:none}.ui.orange.button:active,.ui.orange.buttons .button:active{background-color:#cf590c;color:#fff;text-shadow:none}.ui.orange.active.button,.ui.orange.button .active.button:active,.ui.orange.buttons .active.button,.ui.orange.buttons .active.button:active{background-color:#f56100;color:#fff;text-shadow:none}.ui.basic.orange.button,.ui.basic.orange.buttons .button{-webkit-box-shadow:0 0 0 1px #f2711c inset!important;box-shadow:0 0 0 1px #f2711c inset!important;color:#f2711c!important}.ui.basic.orange.button:hover,.ui.basic.orange.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #f26202 inset!important;box-shadow:0 0 0 1px #f26202 inset!important;color:#f26202!important}.ui.basic.orange.button:focus,.ui.basic.orange.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e55b00 inset!important;box-shadow:0 0 0 1px #e55b00 inset!important;color:#f26202!important}.ui.basic.orange.active.button,.ui.basic.orange.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #f56100 inset!important;box-shadow:0 0 0 1px #f56100 inset!important;color:#cf590c!important}.ui.basic.orange.button:active,.ui.basic.orange.buttons .button:active{-webkit-box-shadow:0 0 0 1px #cf590c inset!important;box-shadow:0 0 0 1px #cf590c inset!important;color:#cf590c!important}.ui.buttons:not(.vertical)>.basic.orange.button:not(:first-child){margin-left:-1px}.ui.inverted.orange.button,.ui.inverted.orange.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff851b inset!important;box-shadow:0 0 0 2px #ff851b inset!important;color:#ff851b}.ui.inverted.orange.button.active,.ui.inverted.orange.button:active,.ui.inverted.orange.button:focus,.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button.active,.ui.inverted.orange.buttons .button:active,.ui.inverted.orange.buttons .button:focus,.ui.inverted.orange.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button:hover{background-color:#ff7701}.ui.inverted.orange.button:focus,.ui.inverted.orange.buttons .button:focus{background-color:#f17000}.ui.inverted.orange.active.button,.ui.inverted.orange.buttons .active.button{background-color:#ff7701}.ui.inverted.orange.button:active,.ui.inverted.orange.buttons .button:active{background-color:#e76b00}.ui.inverted.orange.basic.button,.ui.inverted.orange.basic.buttons .button,.ui.inverted.orange.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.orange.basic.button:hover,.ui.inverted.orange.basic.buttons .button:hover,.ui.inverted.orange.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff7701 inset!important;box-shadow:0 0 0 2px #ff7701 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.button:focus,.ui.inverted.orange.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #f17000 inset!important;box-shadow:0 0 0 2px #f17000 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.active.button,.ui.inverted.orange.basic.buttons .active.button,.ui.inverted.orange.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff7701 inset!important;box-shadow:0 0 0 2px #ff7701 inset!important;color:#ff851b!important}.ui.inverted.orange.basic.button:active,.ui.inverted.orange.basic.buttons .button:active,.ui.inverted.orange.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #e76b00 inset!important;box-shadow:0 0 0 2px #e76b00 inset!important;color:#ff851b!important}.ui.pink.button,.ui.pink.buttons .button{background-color:#e03997;color:#fff;text-shadow:none;background-image:none}.ui.pink.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pink.button:hover,.ui.pink.buttons .button:hover{background-color:#e61a8d;color:#fff;text-shadow:none}.ui.pink.button:focus,.ui.pink.buttons .button:focus{background-color:#e10f85;color:#fff;text-shadow:none}.ui.pink.button:active,.ui.pink.buttons .button:active{background-color:#c71f7e;color:#fff;text-shadow:none}.ui.pink.active.button,.ui.pink.button .active.button:active,.ui.pink.buttons .active.button,.ui.pink.buttons .active.button:active{background-color:#ea158d;color:#fff;text-shadow:none}.ui.basic.pink.button,.ui.basic.pink.buttons .button{-webkit-box-shadow:0 0 0 1px #e03997 inset!important;box-shadow:0 0 0 1px #e03997 inset!important;color:#e03997!important}.ui.basic.pink.button:hover,.ui.basic.pink.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e61a8d inset!important;box-shadow:0 0 0 1px #e61a8d inset!important;color:#e61a8d!important}.ui.basic.pink.button:focus,.ui.basic.pink.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #e10f85 inset!important;box-shadow:0 0 0 1px #e10f85 inset!important;color:#e61a8d!important}.ui.basic.pink.active.button,.ui.basic.pink.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ea158d inset!important;box-shadow:0 0 0 1px #ea158d inset!important;color:#c71f7e!important}.ui.basic.pink.button:active,.ui.basic.pink.buttons .button:active{-webkit-box-shadow:0 0 0 1px #c71f7e inset!important;box-shadow:0 0 0 1px #c71f7e inset!important;color:#c71f7e!important}.ui.buttons:not(.vertical)>.basic.pink.button:not(:first-child){margin-left:-1px}.ui.inverted.pink.button,.ui.inverted.pink.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff8edf inset!important;box-shadow:0 0 0 2px #ff8edf inset!important;color:#ff8edf}.ui.inverted.pink.button.active,.ui.inverted.pink.button:active,.ui.inverted.pink.button:focus,.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button.active,.ui.inverted.pink.buttons .button:active,.ui.inverted.pink.buttons .button:focus,.ui.inverted.pink.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button:hover{background-color:#ff74d8}.ui.inverted.pink.button:focus,.ui.inverted.pink.buttons .button:focus{background-color:#ff65d3}.ui.inverted.pink.active.button,.ui.inverted.pink.buttons .active.button{background-color:#ff74d8}.ui.inverted.pink.button:active,.ui.inverted.pink.buttons .button:active{background-color:#ff5bd1}.ui.inverted.pink.basic.button,.ui.inverted.pink.basic.buttons .button,.ui.inverted.pink.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.pink.basic.button:hover,.ui.inverted.pink.basic.buttons .button:hover,.ui.inverted.pink.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff74d8 inset!important;box-shadow:0 0 0 2px #ff74d8 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.button:focus,.ui.inverted.pink.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #ff65d3 inset!important;box-shadow:0 0 0 2px #ff65d3 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.active.button,.ui.inverted.pink.basic.buttons .active.button,.ui.inverted.pink.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff74d8 inset!important;box-shadow:0 0 0 2px #ff74d8 inset!important;color:#ff8edf!important}.ui.inverted.pink.basic.button:active,.ui.inverted.pink.basic.buttons .button:active,.ui.inverted.pink.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ff5bd1 inset!important;box-shadow:0 0 0 2px #ff5bd1 inset!important;color:#ff8edf!important}.ui.violet.button,.ui.violet.buttons .button{background-color:#6435c9;color:#fff;text-shadow:none;background-image:none}.ui.violet.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.violet.button:hover,.ui.violet.buttons .button:hover{background-color:#5829bb;color:#fff;text-shadow:none}.ui.violet.button:focus,.ui.violet.buttons .button:focus{background-color:#4f20b5;color:#fff;text-shadow:none}.ui.violet.button:active,.ui.violet.buttons .button:active{background-color:#502aa1;color:#fff;text-shadow:none}.ui.violet.active.button,.ui.violet.button .active.button:active,.ui.violet.buttons .active.button,.ui.violet.buttons .active.button:active{background-color:#5626bf;color:#fff;text-shadow:none}.ui.basic.violet.button,.ui.basic.violet.buttons .button{-webkit-box-shadow:0 0 0 1px #6435c9 inset!important;box-shadow:0 0 0 1px #6435c9 inset!important;color:#6435c9!important}.ui.basic.violet.button:hover,.ui.basic.violet.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #5829bb inset!important;box-shadow:0 0 0 1px #5829bb inset!important;color:#5829bb!important}.ui.basic.violet.button:focus,.ui.basic.violet.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #4f20b5 inset!important;box-shadow:0 0 0 1px #4f20b5 inset!important;color:#5829bb!important}.ui.basic.violet.active.button,.ui.basic.violet.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #5626bf inset!important;box-shadow:0 0 0 1px #5626bf inset!important;color:#502aa1!important}.ui.basic.violet.button:active,.ui.basic.violet.buttons .button:active{-webkit-box-shadow:0 0 0 1px #502aa1 inset!important;box-shadow:0 0 0 1px #502aa1 inset!important;color:#502aa1!important}.ui.buttons:not(.vertical)>.basic.violet.button:not(:first-child){margin-left:-1px}.ui.inverted.violet.button,.ui.inverted.violet.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #a291fb inset!important;box-shadow:0 0 0 2px #a291fb inset!important;color:#a291fb}.ui.inverted.violet.button.active,.ui.inverted.violet.button:active,.ui.inverted.violet.button:focus,.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button.active,.ui.inverted.violet.buttons .button:active,.ui.inverted.violet.buttons .button:focus,.ui.inverted.violet.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button:hover{background-color:#8a73ff}.ui.inverted.violet.button:focus,.ui.inverted.violet.buttons .button:focus{background-color:#7d64ff}.ui.inverted.violet.active.button,.ui.inverted.violet.buttons .active.button{background-color:#8a73ff}.ui.inverted.violet.button:active,.ui.inverted.violet.buttons .button:active{background-color:#7860f9}.ui.inverted.violet.basic.button,.ui.inverted.violet.basic.buttons .button,.ui.inverted.violet.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.violet.basic.button:hover,.ui.inverted.violet.basic.buttons .button:hover,.ui.inverted.violet.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #8a73ff inset!important;box-shadow:0 0 0 2px #8a73ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.button:focus,.ui.inverted.violet.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #7d64ff inset!important;box-shadow:0 0 0 2px #7d64ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.active.button,.ui.inverted.violet.basic.buttons .active.button,.ui.inverted.violet.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #8a73ff inset!important;box-shadow:0 0 0 2px #8a73ff inset!important;color:#a291fb!important}.ui.inverted.violet.basic.button:active,.ui.inverted.violet.basic.buttons .button:active,.ui.inverted.violet.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #7860f9 inset!important;box-shadow:0 0 0 2px #7860f9 inset!important;color:#a291fb!important}.ui.purple.button,.ui.purple.buttons .button{background-color:#a333c8;color:#fff;text-shadow:none;background-image:none}.ui.purple.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.purple.button:hover,.ui.purple.buttons .button:hover{background-color:#9627ba;color:#fff;text-shadow:none}.ui.purple.button:focus,.ui.purple.buttons .button:focus{background-color:#8f1eb4;color:#fff;text-shadow:none}.ui.purple.button:active,.ui.purple.buttons .button:active{background-color:#82299f;color:#fff;text-shadow:none}.ui.purple.active.button,.ui.purple.button .active.button:active,.ui.purple.buttons .active.button,.ui.purple.buttons .active.button:active{background-color:#9724be;color:#fff;text-shadow:none}.ui.basic.purple.button,.ui.basic.purple.buttons .button{-webkit-box-shadow:0 0 0 1px #a333c8 inset!important;box-shadow:0 0 0 1px #a333c8 inset!important;color:#a333c8!important}.ui.basic.purple.button:hover,.ui.basic.purple.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #9627ba inset!important;box-shadow:0 0 0 1px #9627ba inset!important;color:#9627ba!important}.ui.basic.purple.button:focus,.ui.basic.purple.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #8f1eb4 inset!important;box-shadow:0 0 0 1px #8f1eb4 inset!important;color:#9627ba!important}.ui.basic.purple.active.button,.ui.basic.purple.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #9724be inset!important;box-shadow:0 0 0 1px #9724be inset!important;color:#82299f!important}.ui.basic.purple.button:active,.ui.basic.purple.buttons .button:active{-webkit-box-shadow:0 0 0 1px #82299f inset!important;box-shadow:0 0 0 1px #82299f inset!important;color:#82299f!important}.ui.buttons:not(.vertical)>.basic.purple.button:not(:first-child){margin-left:-1px}.ui.inverted.purple.button,.ui.inverted.purple.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #dc73ff inset!important;box-shadow:0 0 0 2px #dc73ff inset!important;color:#dc73ff}.ui.inverted.purple.button.active,.ui.inverted.purple.button:active,.ui.inverted.purple.button:focus,.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button.active,.ui.inverted.purple.buttons .button:active,.ui.inverted.purple.buttons .button:focus,.ui.inverted.purple.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button:hover{background-color:#d65aff}.ui.inverted.purple.button:focus,.ui.inverted.purple.buttons .button:focus{background-color:#d24aff}.ui.inverted.purple.active.button,.ui.inverted.purple.buttons .active.button{background-color:#d65aff}.ui.inverted.purple.button:active,.ui.inverted.purple.buttons .button:active{background-color:#cf40ff}.ui.inverted.purple.basic.button,.ui.inverted.purple.basic.buttons .button,.ui.inverted.purple.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.purple.basic.button:hover,.ui.inverted.purple.basic.buttons .button:hover,.ui.inverted.purple.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #d65aff inset!important;box-shadow:0 0 0 2px #d65aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.button:focus,.ui.inverted.purple.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #d24aff inset!important;box-shadow:0 0 0 2px #d24aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.active.button,.ui.inverted.purple.basic.buttons .active.button,.ui.inverted.purple.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #d65aff inset!important;box-shadow:0 0 0 2px #d65aff inset!important;color:#dc73ff!important}.ui.inverted.purple.basic.button:active,.ui.inverted.purple.basic.buttons .button:active,.ui.inverted.purple.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #cf40ff inset!important;box-shadow:0 0 0 2px #cf40ff inset!important;color:#dc73ff!important}.ui.red.button,.ui.red.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.red.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.red.button:hover,.ui.red.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.red.button:focus,.ui.red.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.red.button:active,.ui.red.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.red.active.button,.ui.red.button .active.button:active,.ui.red.buttons .active.button,.ui.red.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.red.button,.ui.basic.red.buttons .button{-webkit-box-shadow:0 0 0 1px #db2828 inset!important;box-shadow:0 0 0 1px #db2828 inset!important;color:#db2828!important}.ui.basic.red.button:hover,.ui.basic.red.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d01919 inset!important;box-shadow:0 0 0 1px #d01919 inset!important;color:#d01919!important}.ui.basic.red.button:focus,.ui.basic.red.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ca1010 inset!important;box-shadow:0 0 0 1px #ca1010 inset!important;color:#d01919!important}.ui.basic.red.active.button,.ui.basic.red.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d41515 inset!important;box-shadow:0 0 0 1px #d41515 inset!important;color:#b21e1e!important}.ui.basic.red.button:active,.ui.basic.red.buttons .button:active{-webkit-box-shadow:0 0 0 1px #b21e1e inset!important;box-shadow:0 0 0 1px #b21e1e inset!important;color:#b21e1e!important}.ui.buttons:not(.vertical)>.basic.red.button:not(:first-child){margin-left:-1px}.ui.inverted.red.button,.ui.inverted.red.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ff695e inset!important;box-shadow:0 0 0 2px #ff695e inset!important;color:#ff695e}.ui.inverted.red.button.active,.ui.inverted.red.button:active,.ui.inverted.red.button:focus,.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button.active,.ui.inverted.red.buttons .button:active,.ui.inverted.red.buttons .button:focus,.ui.inverted.red.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button:hover{background-color:#ff5144}.ui.inverted.red.button:focus,.ui.inverted.red.buttons .button:focus{background-color:#ff4335}.ui.inverted.red.active.button,.ui.inverted.red.buttons .active.button{background-color:#ff5144}.ui.inverted.red.button:active,.ui.inverted.red.buttons .button:active{background-color:#ff392b}.ui.inverted.red.basic.button,.ui.inverted.red.basic.buttons .button,.ui.inverted.red.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.red.basic.button:hover,.ui.inverted.red.basic.buttons .button:hover,.ui.inverted.red.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ff5144 inset!important;box-shadow:0 0 0 2px #ff5144 inset!important;color:#ff695e!important}.ui.inverted.red.basic.button:focus,.ui.inverted.red.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #ff4335 inset!important;box-shadow:0 0 0 2px #ff4335 inset!important;color:#ff695e!important}.ui.inverted.red.basic.active.button,.ui.inverted.red.basic.buttons .active.button,.ui.inverted.red.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ff5144 inset!important;box-shadow:0 0 0 2px #ff5144 inset!important;color:#ff695e!important}.ui.inverted.red.basic.button:active,.ui.inverted.red.basic.buttons .button:active,.ui.inverted.red.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ff392b inset!important;box-shadow:0 0 0 2px #ff392b inset!important;color:#ff695e!important}.ui.teal.button,.ui.teal.buttons .button{background-color:#00b5ad;color:#fff;text-shadow:none;background-image:none}.ui.teal.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.teal.button:hover,.ui.teal.buttons .button:hover{background-color:#009c95;color:#fff;text-shadow:none}.ui.teal.button:focus,.ui.teal.buttons .button:focus{background-color:#008c86;color:#fff;text-shadow:none}.ui.teal.button:active,.ui.teal.buttons .button:active{background-color:#00827c;color:#fff;text-shadow:none}.ui.teal.active.button,.ui.teal.button .active.button:active,.ui.teal.buttons .active.button,.ui.teal.buttons .active.button:active{background-color:#009c95;color:#fff;text-shadow:none}.ui.basic.teal.button,.ui.basic.teal.buttons .button{-webkit-box-shadow:0 0 0 1px #00b5ad inset!important;box-shadow:0 0 0 1px #00b5ad inset!important;color:#00b5ad!important}.ui.basic.teal.button:hover,.ui.basic.teal.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #009c95 inset!important;box-shadow:0 0 0 1px #009c95 inset!important;color:#009c95!important}.ui.basic.teal.button:focus,.ui.basic.teal.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #008c86 inset!important;box-shadow:0 0 0 1px #008c86 inset!important;color:#009c95!important}.ui.basic.teal.active.button,.ui.basic.teal.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #009c95 inset!important;box-shadow:0 0 0 1px #009c95 inset!important;color:#00827c!important}.ui.basic.teal.button:active,.ui.basic.teal.buttons .button:active{-webkit-box-shadow:0 0 0 1px #00827c inset!important;box-shadow:0 0 0 1px #00827c inset!important;color:#00827c!important}.ui.buttons:not(.vertical)>.basic.teal.button:not(:first-child){margin-left:-1px}.ui.inverted.teal.button,.ui.inverted.teal.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #6dffff inset!important;box-shadow:0 0 0 2px #6dffff inset!important;color:#6dffff}.ui.inverted.teal.button.active,.ui.inverted.teal.button:active,.ui.inverted.teal.button:focus,.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button.active,.ui.inverted.teal.buttons .button:active,.ui.inverted.teal.buttons .button:focus,.ui.inverted.teal.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button:hover{background-color:#54ffff}.ui.inverted.teal.button:focus,.ui.inverted.teal.buttons .button:focus{background-color:#4ff}.ui.inverted.teal.active.button,.ui.inverted.teal.buttons .active.button{background-color:#54ffff}.ui.inverted.teal.button:active,.ui.inverted.teal.buttons .button:active{background-color:#3affff}.ui.inverted.teal.basic.button,.ui.inverted.teal.basic.buttons .button,.ui.inverted.teal.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.teal.basic.button:hover,.ui.inverted.teal.basic.buttons .button:hover,.ui.inverted.teal.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #54ffff inset!important;box-shadow:0 0 0 2px #54ffff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.button:focus,.ui.inverted.teal.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #4ff inset!important;box-shadow:0 0 0 2px #4ff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.active.button,.ui.inverted.teal.basic.buttons .active.button,.ui.inverted.teal.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #54ffff inset!important;box-shadow:0 0 0 2px #54ffff inset!important;color:#6dffff!important}.ui.inverted.teal.basic.button:active,.ui.inverted.teal.basic.buttons .button:active,.ui.inverted.teal.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #3affff inset!important;box-shadow:0 0 0 2px #3affff inset!important;color:#6dffff!important}.ui.olive.button,.ui.olive.buttons .button{background-color:#b5cc18;color:#fff;text-shadow:none;background-image:none}.ui.olive.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.olive.button:hover,.ui.olive.buttons .button:hover{background-color:#a7bd0d;color:#fff;text-shadow:none}.ui.olive.button:focus,.ui.olive.buttons .button:focus{background-color:#a0b605;color:#fff;text-shadow:none}.ui.olive.button:active,.ui.olive.buttons .button:active{background-color:#8d9e13;color:#fff;text-shadow:none}.ui.olive.active.button,.ui.olive.button .active.button:active,.ui.olive.buttons .active.button,.ui.olive.buttons .active.button:active{background-color:#aac109;color:#fff;text-shadow:none}.ui.basic.olive.button,.ui.basic.olive.buttons .button{-webkit-box-shadow:0 0 0 1px #b5cc18 inset!important;box-shadow:0 0 0 1px #b5cc18 inset!important;color:#b5cc18!important}.ui.basic.olive.button:hover,.ui.basic.olive.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #a7bd0d inset!important;box-shadow:0 0 0 1px #a7bd0d inset!important;color:#a7bd0d!important}.ui.basic.olive.button:focus,.ui.basic.olive.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #a0b605 inset!important;box-shadow:0 0 0 1px #a0b605 inset!important;color:#a7bd0d!important}.ui.basic.olive.active.button,.ui.basic.olive.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #aac109 inset!important;box-shadow:0 0 0 1px #aac109 inset!important;color:#8d9e13!important}.ui.basic.olive.button:active,.ui.basic.olive.buttons .button:active{-webkit-box-shadow:0 0 0 1px #8d9e13 inset!important;box-shadow:0 0 0 1px #8d9e13 inset!important;color:#8d9e13!important}.ui.buttons:not(.vertical)>.basic.olive.button:not(:first-child){margin-left:-1px}.ui.inverted.olive.button,.ui.inverted.olive.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #d9e778 inset!important;box-shadow:0 0 0 2px #d9e778 inset!important;color:#d9e778}.ui.inverted.olive.button.active,.ui.inverted.olive.button:active,.ui.inverted.olive.button:focus,.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button.active,.ui.inverted.olive.buttons .button:active,.ui.inverted.olive.buttons .button:focus,.ui.inverted.olive.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button:hover{background-color:#d8ea5c}.ui.inverted.olive.button:focus,.ui.inverted.olive.buttons .button:focus{background-color:#daef47}.ui.inverted.olive.active.button,.ui.inverted.olive.buttons .active.button{background-color:#daed59}.ui.inverted.olive.button:active,.ui.inverted.olive.buttons .button:active{background-color:#cddf4d}.ui.inverted.olive.basic.button,.ui.inverted.olive.basic.buttons .button,.ui.inverted.olive.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.olive.basic.button:hover,.ui.inverted.olive.basic.buttons .button:hover,.ui.inverted.olive.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #d8ea5c inset!important;box-shadow:0 0 0 2px #d8ea5c inset!important;color:#d9e778!important}.ui.inverted.olive.basic.button:focus,.ui.inverted.olive.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #daef47 inset!important;box-shadow:0 0 0 2px #daef47 inset!important;color:#d9e778!important}.ui.inverted.olive.basic.active.button,.ui.inverted.olive.basic.buttons .active.button,.ui.inverted.olive.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #daed59 inset!important;box-shadow:0 0 0 2px #daed59 inset!important;color:#d9e778!important}.ui.inverted.olive.basic.button:active,.ui.inverted.olive.basic.buttons .button:active,.ui.inverted.olive.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #cddf4d inset!important;box-shadow:0 0 0 2px #cddf4d inset!important;color:#d9e778!important}.ui.yellow.button,.ui.yellow.buttons .button{background-color:#fbbd08;color:#fff;text-shadow:none;background-image:none}.ui.yellow.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.yellow.button:hover,.ui.yellow.buttons .button:hover{background-color:#eaae00;color:#fff;text-shadow:none}.ui.yellow.button:focus,.ui.yellow.buttons .button:focus{background-color:#daa300;color:#fff;text-shadow:none}.ui.yellow.button:active,.ui.yellow.buttons .button:active{background-color:#cd9903;color:#fff;text-shadow:none}.ui.yellow.active.button,.ui.yellow.button .active.button:active,.ui.yellow.buttons .active.button,.ui.yellow.buttons .active.button:active{background-color:#eaae00;color:#fff;text-shadow:none}.ui.basic.yellow.button,.ui.basic.yellow.buttons .button{-webkit-box-shadow:0 0 0 1px #fbbd08 inset!important;box-shadow:0 0 0 1px #fbbd08 inset!important;color:#fbbd08!important}.ui.basic.yellow.button:hover,.ui.basic.yellow.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #eaae00 inset!important;box-shadow:0 0 0 1px #eaae00 inset!important;color:#eaae00!important}.ui.basic.yellow.button:focus,.ui.basic.yellow.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #daa300 inset!important;box-shadow:0 0 0 1px #daa300 inset!important;color:#eaae00!important}.ui.basic.yellow.active.button,.ui.basic.yellow.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #eaae00 inset!important;box-shadow:0 0 0 1px #eaae00 inset!important;color:#cd9903!important}.ui.basic.yellow.button:active,.ui.basic.yellow.buttons .button:active{-webkit-box-shadow:0 0 0 1px #cd9903 inset!important;box-shadow:0 0 0 1px #cd9903 inset!important;color:#cd9903!important}.ui.buttons:not(.vertical)>.basic.yellow.button:not(:first-child){margin-left:-1px}.ui.inverted.yellow.button,.ui.inverted.yellow.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #ffe21f inset!important;box-shadow:0 0 0 2px #ffe21f inset!important;color:#ffe21f}.ui.inverted.yellow.button.active,.ui.inverted.yellow.button:active,.ui.inverted.yellow.button:focus,.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button.active,.ui.inverted.yellow.buttons .button:active,.ui.inverted.yellow.buttons .button:focus,.ui.inverted.yellow.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:rgba(0,0,0,.6)}.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button:hover{background-color:#ffdf05}.ui.inverted.yellow.button:focus,.ui.inverted.yellow.buttons .button:focus{background-color:#f5d500}.ui.inverted.yellow.active.button,.ui.inverted.yellow.buttons .active.button{background-color:#ffdf05}.ui.inverted.yellow.button:active,.ui.inverted.yellow.buttons .button:active{background-color:#ebcd00}.ui.inverted.yellow.basic.button,.ui.inverted.yellow.basic.buttons .button,.ui.inverted.yellow.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.yellow.basic.button:hover,.ui.inverted.yellow.basic.buttons .button:hover,.ui.inverted.yellow.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #ffdf05 inset!important;box-shadow:0 0 0 2px #ffdf05 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.button:focus,.ui.inverted.yellow.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #f5d500 inset!important;box-shadow:0 0 0 2px #f5d500 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.active.button,.ui.inverted.yellow.basic.buttons .active.button,.ui.inverted.yellow.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #ffdf05 inset!important;box-shadow:0 0 0 2px #ffdf05 inset!important;color:#ffe21f!important}.ui.inverted.yellow.basic.button:active,.ui.inverted.yellow.basic.buttons .button:active,.ui.inverted.yellow.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #ebcd00 inset!important;box-shadow:0 0 0 2px #ebcd00 inset!important;color:#ffe21f!important}.ui.primary.button,.ui.primary.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.primary.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.primary.button:hover,.ui.primary.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.primary.button:focus,.ui.primary.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.primary.button:active,.ui.primary.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.primary.active.button,.ui.primary.button .active.button:active,.ui.primary.buttons .active.button,.ui.primary.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.primary.button,.ui.basic.primary.buttons .button{-webkit-box-shadow:0 0 0 1px #2185d0 inset!important;box-shadow:0 0 0 1px #2185d0 inset!important;color:#2185d0!important}.ui.basic.primary.button:hover,.ui.basic.primary.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1678c2 inset!important;box-shadow:0 0 0 1px #1678c2 inset!important;color:#1678c2!important}.ui.basic.primary.button:focus,.ui.basic.primary.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0d71bb inset!important;box-shadow:0 0 0 1px #0d71bb inset!important;color:#1678c2!important}.ui.basic.primary.active.button,.ui.basic.primary.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #1279c6 inset!important;box-shadow:0 0 0 1px #1279c6 inset!important;color:#1a69a4!important}.ui.basic.primary.button:active,.ui.basic.primary.buttons .button:active{-webkit-box-shadow:0 0 0 1px #1a69a4 inset!important;box-shadow:0 0 0 1px #1a69a4 inset!important;color:#1a69a4!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.inverted.primary.button,.ui.inverted.primary.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #54c8ff inset!important;box-shadow:0 0 0 2px #54c8ff inset!important;color:#54c8ff}.ui.inverted.primary.button.active,.ui.inverted.primary.button:active,.ui.inverted.primary.button:focus,.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button.active,.ui.inverted.primary.buttons .button:active,.ui.inverted.primary.buttons .button:focus,.ui.inverted.primary.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button:hover{background-color:#3ac0ff}.ui.inverted.primary.button:focus,.ui.inverted.primary.buttons .button:focus{background-color:#2bbbff}.ui.inverted.primary.active.button,.ui.inverted.primary.buttons .active.button{background-color:#3ac0ff}.ui.inverted.primary.button:active,.ui.inverted.primary.buttons .button:active{background-color:#21b8ff}.ui.inverted.primary.basic.button,.ui.inverted.primary.basic.buttons .button,.ui.inverted.primary.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.primary.basic.button:hover,.ui.inverted.primary.basic.buttons .button:hover,.ui.inverted.primary.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.button:focus,.ui.inverted.primary.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #2bbbff inset!important;box-shadow:0 0 0 2px #2bbbff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.active.button,.ui.inverted.primary.basic.buttons .active.button,.ui.inverted.primary.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #3ac0ff inset!important;box-shadow:0 0 0 2px #3ac0ff inset!important;color:#54c8ff!important}.ui.inverted.primary.basic.button:active,.ui.inverted.primary.basic.buttons .button:active,.ui.inverted.primary.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #21b8ff inset!important;box-shadow:0 0 0 2px #21b8ff inset!important;color:#54c8ff!important}.ui.secondary.button,.ui.secondary.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.secondary.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.secondary.button:hover,.ui.secondary.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.secondary.button:focus,.ui.secondary.buttons .button:focus{background-color:#2e3032;color:#fff;text-shadow:none}.ui.secondary.button:active,.ui.secondary.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.secondary.active.button,.ui.secondary.button .active.button:active,.ui.secondary.buttons .active.button,.ui.secondary.buttons .active.button:active{background-color:#27292a;color:#fff;text-shadow:none}.ui.basic.secondary.button,.ui.basic.secondary.buttons .button{-webkit-box-shadow:0 0 0 1px #1b1c1d inset!important;box-shadow:0 0 0 1px #1b1c1d inset!important;color:#1b1c1d!important}.ui.basic.secondary.button:hover,.ui.basic.secondary.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#27292a!important}.ui.basic.secondary.button:focus,.ui.basic.secondary.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #2e3032 inset!important;box-shadow:0 0 0 1px #2e3032 inset!important;color:#27292a!important}.ui.basic.secondary.active.button,.ui.basic.secondary.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #27292a inset!important;box-shadow:0 0 0 1px #27292a inset!important;color:#343637!important}.ui.basic.secondary.button:active,.ui.basic.secondary.buttons .button:active{-webkit-box-shadow:0 0 0 1px #343637 inset!important;box-shadow:0 0 0 1px #343637 inset!important;color:#343637!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.inverted.secondary.button,.ui.inverted.secondary.buttons .button{background-color:transparent;-webkit-box-shadow:0 0 0 2px #545454 inset!important;box-shadow:0 0 0 2px #545454 inset!important;color:#545454}.ui.inverted.secondary.button.active,.ui.inverted.secondary.button:active,.ui.inverted.secondary.button:focus,.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button.active,.ui.inverted.secondary.buttons .button:active,.ui.inverted.secondary.buttons .button:focus,.ui.inverted.secondary.buttons .button:hover{-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button:hover{background-color:#616161}.ui.inverted.secondary.button:focus,.ui.inverted.secondary.buttons .button:focus{background-color:#686868}.ui.inverted.secondary.active.button,.ui.inverted.secondary.buttons .active.button{background-color:#616161}.ui.inverted.secondary.button:active,.ui.inverted.secondary.buttons .button:active{background-color:#6e6e6e}.ui.inverted.secondary.basic.button,.ui.inverted.secondary.basic.buttons .button,.ui.inverted.secondary.buttons .basic.button{background-color:transparent;-webkit-box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset!important;color:#fff!important}.ui.inverted.secondary.basic.button:hover,.ui.inverted.secondary.basic.buttons .button:hover,.ui.inverted.secondary.buttons .basic.button:hover{-webkit-box-shadow:0 0 0 2px #616161 inset!important;box-shadow:0 0 0 2px #616161 inset!important;color:#545454!important}.ui.inverted.secondary.basic.button:focus,.ui.inverted.secondary.basic.buttons .button:focus{-webkit-box-shadow:0 0 0 2px #686868 inset!important;box-shadow:0 0 0 2px #686868 inset!important;color:#545454!important}.ui.inverted.secondary.basic.active.button,.ui.inverted.secondary.basic.buttons .active.button,.ui.inverted.secondary.buttons .basic.active.button{-webkit-box-shadow:0 0 0 2px #616161 inset!important;box-shadow:0 0 0 2px #616161 inset!important;color:#545454!important}.ui.inverted.secondary.basic.button:active,.ui.inverted.secondary.basic.buttons .button:active,.ui.inverted.secondary.buttons .basic.button:active{-webkit-box-shadow:0 0 0 2px #6e6e6e inset!important;box-shadow:0 0 0 2px #6e6e6e inset!important;color:#545454!important}.ui.positive.button,.ui.positive.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.positive.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.positive.button:hover,.ui.positive.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.positive.button:focus,.ui.positive.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.positive.button:active,.ui.positive.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.positive.active.button,.ui.positive.button .active.button:active,.ui.positive.buttons .active.button,.ui.positive.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.positive.button,.ui.basic.positive.buttons .button{-webkit-box-shadow:0 0 0 1px #21ba45 inset!important;box-shadow:0 0 0 1px #21ba45 inset!important;color:#21ba45!important}.ui.basic.positive.button:hover,.ui.basic.positive.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #16ab39 inset!important;box-shadow:0 0 0 1px #16ab39 inset!important;color:#16ab39!important}.ui.basic.positive.button:focus,.ui.basic.positive.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #0ea432 inset!important;box-shadow:0 0 0 1px #0ea432 inset!important;color:#16ab39!important}.ui.basic.positive.active.button,.ui.basic.positive.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #13ae38 inset!important;box-shadow:0 0 0 1px #13ae38 inset!important;color:#198f35!important}.ui.basic.positive.button:active,.ui.basic.positive.buttons .button:active{-webkit-box-shadow:0 0 0 1px #198f35 inset!important;box-shadow:0 0 0 1px #198f35 inset!important;color:#198f35!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.negative.button,.ui.negative.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.negative.button{-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.negative.button:hover,.ui.negative.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.negative.button:focus,.ui.negative.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.negative.button:active,.ui.negative.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.negative.active.button,.ui.negative.button .active.button:active,.ui.negative.buttons .active.button,.ui.negative.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.negative.button,.ui.basic.negative.buttons .button{-webkit-box-shadow:0 0 0 1px #db2828 inset!important;box-shadow:0 0 0 1px #db2828 inset!important;color:#db2828!important}.ui.basic.negative.button:hover,.ui.basic.negative.buttons .button:hover{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d01919 inset!important;box-shadow:0 0 0 1px #d01919 inset!important;color:#d01919!important}.ui.basic.negative.button:focus,.ui.basic.negative.buttons .button:focus{background:0 0!important;-webkit-box-shadow:0 0 0 1px #ca1010 inset!important;box-shadow:0 0 0 1px #ca1010 inset!important;color:#d01919!important}.ui.basic.negative.active.button,.ui.basic.negative.buttons .active.button{background:0 0!important;-webkit-box-shadow:0 0 0 1px #d41515 inset!important;box-shadow:0 0 0 1px #d41515 inset!important;color:#b21e1e!important}.ui.basic.negative.button:active,.ui.basic.negative.buttons .button:active{-webkit-box-shadow:0 0 0 1px #b21e1e inset!important;box-shadow:0 0 0 1px #b21e1e inset!important;color:#b21e1e!important}.ui.buttons:not(.vertical)>.basic.primary.button:not(:first-child){margin-left:-1px}.ui.buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;font-size:0;vertical-align:baseline;margin:0 .25em 0 0}.ui.buttons:not(.basic):not(.inverted){-webkit-box-shadow:none;box-shadow:none}.ui.buttons:after{content:\\\".\\\";display:block;height:0;clear:both;visibility:hidden}.ui.buttons .button{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;margin:0;border-radius:0;margin:0}.ui.buttons:not(.basic):not(.inverted)>.button,.ui.buttons>.ui.button:not(.basic):not(.inverted){-webkit-box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.buttons .button:first-child{border-left:none;margin-left:0;border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.buttons .button:last-child{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.vertical.buttons .button{display:block;float:none;width:100%;margin:0;-webkit-box-shadow:none;box-shadow:none;border-radius:0}.ui.vertical.buttons .button:first-child{border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.vertical.buttons .button:last-child{margin-bottom:0;border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons .button:only-child{border-radius:.28571429rem}/*!\\n * # Semantic UI 2.4.0 - Container\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.container{display:block;max-width:100%!important}@media only screen and (max-width:767px){.ui.container{width:auto!important;margin-left:1em!important;margin-right:1em!important}.ui.grid.container{width:auto!important}.ui.relaxed.grid.container{width:auto!important}.ui.very.relaxed.grid.container{width:auto!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.container{width:723px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(723px + 2rem)!important}.ui.relaxed.grid.container{width:calc(723px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(723px + 5rem)!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.container{width:933px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(933px + 2rem)!important}.ui.relaxed.grid.container{width:calc(933px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(933px + 5rem)!important}}@media only screen and (min-width:1200px){.ui.container{width:1127px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(1127px + 2rem)!important}.ui.relaxed.grid.container{width:calc(1127px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(1127px + 5rem)!important}}.ui.text.container{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;max-width:700px!important;line-height:1.5}.ui.text.container{font-size:1.14285714rem}.ui.fluid.container{width:100%}.ui[class*=\\\"left aligned\\\"].container{text-align:left}.ui[class*=\\\"center aligned\\\"].container{text-align:center}.ui[class*=\\\"right aligned\\\"].container{text-align:right}.ui.justified.container{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}/*!\\n * # Semantic UI 2.4.0 - Divider\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.divider{margin:1rem 0;line-height:1;height:0;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:rgba(0,0,0,.85);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ui.divider:not(.vertical):not(.horizontal){border-top:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(255,255,255,.1)}.ui.grid>.column+.divider,.ui.grid>.row>.column+.divider{left:auto}.ui.horizontal.divider{display:table;white-space:nowrap;height:auto;margin:'';line-height:1;text-align:center}.ui.horizontal.divider:after,.ui.horizontal.divider:before{content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.horizontal.divider:before{background-position:right 1em top 50%}.ui.horizontal.divider:after{background-position:left 1em top 50%}.ui.vertical.divider{position:absolute;z-index:2;top:50%;left:50%;margin:0;padding:0;width:auto;height:50%;line-height:0;text-align:center;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ui.vertical.divider:after,.ui.vertical.divider:before{position:absolute;left:50%;content:'';z-index:3;border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(255,255,255,.1);width:0%;height:calc(100% - 1rem)}.ui.vertical.divider:before{top:-100%}.ui.vertical.divider:after{top:auto;bottom:0}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider,.ui.stackable.grid .ui.vertical.divider{display:table;white-space:nowrap;height:auto;margin:'';overflow:hidden;line-height:1;text-align:center;position:static;top:0;left:0;-webkit-transform:none;transform:none}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{position:static;left:0;border-left:none;border-right:none;content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:before{background-position:right 1em top 50%}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:after{background-position:left 1em top 50%}}.ui.divider>.icon{margin:0;font-size:1rem;height:1em;vertical-align:middle}.ui.hidden.divider{border-color:transparent!important}.ui.hidden.divider:after,.ui.hidden.divider:before{display:none}.ui.divider.inverted,.ui.horizontal.inverted.divider,.ui.vertical.inverted.divider{color:#fff}.ui.divider.inverted,.ui.divider.inverted:after,.ui.divider.inverted:before{border-top-color:rgba(34,36,38,.15)!important;border-left-color:rgba(34,36,38,.15)!important;border-bottom-color:rgba(255,255,255,.15)!important;border-right-color:rgba(255,255,255,.15)!important}.ui.fitted.divider{margin:0}.ui.clearing.divider{clear:both}.ui.section.divider{margin-top:2rem;margin-bottom:2rem}.ui.divider{font-size:1rem}.ui.horizontal.divider:after,.ui.horizontal.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}}/*!\\n * # Semantic UI 2.4.0 - Flag\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */i.flag:not(.icon){display:inline-block;width:16px;height:11px;line-height:11px;vertical-align:baseline;margin:0 .5em 0 0;text-decoration:inherit;speak:none;font-smoothing:antialiased;-webkit-backface-visibility:hidden;backface-visibility:hidden}i.flag:not(.icon):before{display:inline-block;content:'';background:url(themes/default/assets/images/flags.png) no-repeat -108px -1976px;width:16px;height:11px}i.flag.ad:before,i.flag.andorra:before{background-position:0 0}i.flag.ae:before,i.flag.uae:before,i.flag.united.arab.emirates:before{background-position:0 -26px}i.flag.af:before,i.flag.afghanistan:before{background-position:0 -52px}i.flag.ag:before,i.flag.antigua:before{background-position:0 -78px}i.flag.ai:before,i.flag.anguilla:before{background-position:0 -104px}i.flag.al:before,i.flag.albania:before{background-position:0 -130px}i.flag.am:before,i.flag.armenia:before{background-position:0 -156px}i.flag.an:before,i.flag.netherlands.antilles:before{background-position:0 -182px}i.flag.angola:before,i.flag.ao:before{background-position:0 -208px}i.flag.ar:before,i.flag.argentina:before{background-position:0 -234px}i.flag.american.samoa:before,i.flag.as:before{background-position:0 -260px}i.flag.at:before,i.flag.austria:before{background-position:0 -286px}i.flag.au:before,i.flag.australia:before{background-position:0 -312px}i.flag.aruba:before,i.flag.aw:before{background-position:0 -338px}i.flag.aland.islands:before,i.flag.ax:before{background-position:0 -364px}i.flag.az:before,i.flag.azerbaijan:before{background-position:0 -390px}i.flag.ba:before,i.flag.bosnia:before{background-position:0 -416px}i.flag.barbados:before,i.flag.bb:before{background-position:0 -442px}i.flag.bangladesh:before,i.flag.bd:before{background-position:0 -468px}i.flag.be:before,i.flag.belgium:before{background-position:0 -494px}i.flag.bf:before,i.flag.burkina.faso:before{background-position:0 -520px}i.flag.bg:before,i.flag.bulgaria:before{background-position:0 -546px}i.flag.bahrain:before,i.flag.bh:before{background-position:0 -572px}i.flag.bi:before,i.flag.burundi:before{background-position:0 -598px}i.flag.benin:before,i.flag.bj:before{background-position:0 -624px}i.flag.bermuda:before,i.flag.bm:before{background-position:0 -650px}i.flag.bn:before,i.flag.brunei:before{background-position:0 -676px}i.flag.bo:before,i.flag.bolivia:before{background-position:0 -702px}i.flag.br:before,i.flag.brazil:before{background-position:0 -728px}i.flag.bahamas:before,i.flag.bs:before{background-position:0 -754px}i.flag.bhutan:before,i.flag.bt:before{background-position:0 -780px}i.flag.bouvet.island:before,i.flag.bv:before{background-position:0 -806px}i.flag.botswana:before,i.flag.bw:before{background-position:0 -832px}i.flag.belarus:before,i.flag.by:before{background-position:0 -858px}i.flag.belize:before,i.flag.bz:before{background-position:0 -884px}i.flag.ca:before,i.flag.canada:before{background-position:0 -910px}i.flag.cc:before,i.flag.cocos.islands:before{background-position:0 -962px}i.flag.cd:before,i.flag.congo:before{background-position:0 -988px}i.flag.central.african.republic:before,i.flag.cf:before{background-position:0 -1014px}i.flag.cg:before,i.flag.congo.brazzaville:before{background-position:0 -1040px}i.flag.ch:before,i.flag.switzerland:before{background-position:0 -1066px}i.flag.ci:before,i.flag.cote.divoire:before{background-position:0 -1092px}i.flag.ck:before,i.flag.cook.islands:before{background-position:0 -1118px}i.flag.chile:before,i.flag.cl:before{background-position:0 -1144px}i.flag.cameroon:before,i.flag.cm:before{background-position:0 -1170px}i.flag.china:before,i.flag.cn:before{background-position:0 -1196px}i.flag.co:before,i.flag.colombia:before{background-position:0 -1222px}i.flag.costa.rica:before,i.flag.cr:before{background-position:0 -1248px}i.flag.cs:before,i.flag.serbia:before{background-position:0 -1274px}i.flag.cu:before,i.flag.cuba:before{background-position:0 -1300px}i.flag.cape.verde:before,i.flag.cv:before{background-position:0 -1326px}i.flag.christmas.island:before,i.flag.cx:before{background-position:0 -1352px}i.flag.cy:before,i.flag.cyprus:before{background-position:0 -1378px}i.flag.cz:before,i.flag.czech.republic:before{background-position:0 -1404px}i.flag.de:before,i.flag.germany:before{background-position:0 -1430px}i.flag.dj:before,i.flag.djibouti:before{background-position:0 -1456px}i.flag.denmark:before,i.flag.dk:before{background-position:0 -1482px}i.flag.dm:before,i.flag.dominica:before{background-position:0 -1508px}i.flag.do:before,i.flag.dominican.republic:before{background-position:0 -1534px}i.flag.algeria:before,i.flag.dz:before{background-position:0 -1560px}i.flag.ec:before,i.flag.ecuador:before{background-position:0 -1586px}i.flag.ee:before,i.flag.estonia:before{background-position:0 -1612px}i.flag.eg:before,i.flag.egypt:before{background-position:0 -1638px}i.flag.eh:before,i.flag.western.sahara:before{background-position:0 -1664px}i.flag.england:before,i.flag.gb.eng:before{background-position:0 -1690px}i.flag.er:before,i.flag.eritrea:before{background-position:0 -1716px}i.flag.es:before,i.flag.spain:before{background-position:0 -1742px}i.flag.et:before,i.flag.ethiopia:before{background-position:0 -1768px}i.flag.eu:before,i.flag.european.union:before{background-position:0 -1794px}i.flag.fi:before,i.flag.finland:before{background-position:0 -1846px}i.flag.fiji:before,i.flag.fj:before{background-position:0 -1872px}i.flag.falkland.islands:before,i.flag.fk:before{background-position:0 -1898px}i.flag.fm:before,i.flag.micronesia:before{background-position:0 -1924px}i.flag.faroe.islands:before,i.flag.fo:before{background-position:0 -1950px}i.flag.fr:before,i.flag.france:before{background-position:0 -1976px}i.flag.ga:before,i.flag.gabon:before{background-position:-36px 0}i.flag.gb:before,i.flag.uk:before,i.flag.united.kingdom:before{background-position:-36px -26px}i.flag.gd:before,i.flag.grenada:before{background-position:-36px -52px}i.flag.ge:before,i.flag.georgia:before{background-position:-36px -78px}i.flag.french.guiana:before,i.flag.gf:before{background-position:-36px -104px}i.flag.gh:before,i.flag.ghana:before{background-position:-36px -130px}i.flag.gi:before,i.flag.gibraltar:before{background-position:-36px -156px}i.flag.gl:before,i.flag.greenland:before{background-position:-36px -182px}i.flag.gambia:before,i.flag.gm:before{background-position:-36px -208px}i.flag.gn:before,i.flag.guinea:before{background-position:-36px -234px}i.flag.gp:before,i.flag.guadeloupe:before{background-position:-36px -260px}i.flag.equatorial.guinea:before,i.flag.gq:before{background-position:-36px -286px}i.flag.gr:before,i.flag.greece:before{background-position:-36px -312px}i.flag.gs:before,i.flag.sandwich.islands:before{background-position:-36px -338px}i.flag.gt:before,i.flag.guatemala:before{background-position:-36px -364px}i.flag.gu:before,i.flag.guam:before{background-position:-36px -390px}i.flag.guinea-bissau:before,i.flag.gw:before{background-position:-36px -416px}i.flag.guyana:before,i.flag.gy:before{background-position:-36px -442px}i.flag.hk:before,i.flag.hong.kong:before{background-position:-36px -468px}i.flag.heard.island:before,i.flag.hm:before{background-position:-36px -494px}i.flag.hn:before,i.flag.honduras:before{background-position:-36px -520px}i.flag.croatia:before,i.flag.hr:before{background-position:-36px -546px}i.flag.haiti:before,i.flag.ht:before{background-position:-36px -572px}i.flag.hu:before,i.flag.hungary:before{background-position:-36px -598px}i.flag.id:before,i.flag.indonesia:before{background-position:-36px -624px}i.flag.ie:before,i.flag.ireland:before{background-position:-36px -650px}i.flag.il:before,i.flag.israel:before{background-position:-36px -676px}i.flag.in:before,i.flag.india:before{background-position:-36px -702px}i.flag.indian.ocean.territory:before,i.flag.io:before{background-position:-36px -728px}i.flag.iq:before,i.flag.iraq:before{background-position:-36px -754px}i.flag.ir:before,i.flag.iran:before{background-position:-36px -780px}i.flag.iceland:before,i.flag.is:before{background-position:-36px -806px}i.flag.it:before,i.flag.italy:before{background-position:-36px -832px}i.flag.jamaica:before,i.flag.jm:before{background-position:-36px -858px}i.flag.jo:before,i.flag.jordan:before{background-position:-36px -884px}i.flag.japan:before,i.flag.jp:before{background-position:-36px -910px}i.flag.ke:before,i.flag.kenya:before{background-position:-36px -936px}i.flag.kg:before,i.flag.kyrgyzstan:before{background-position:-36px -962px}i.flag.cambodia:before,i.flag.kh:before{background-position:-36px -988px}i.flag.ki:before,i.flag.kiribati:before{background-position:-36px -1014px}i.flag.comoros:before,i.flag.km:before{background-position:-36px -1040px}i.flag.kn:before,i.flag.saint.kitts.and.nevis:before{background-position:-36px -1066px}i.flag.kp:before,i.flag.north.korea:before{background-position:-36px -1092px}i.flag.kr:before,i.flag.south.korea:before{background-position:-36px -1118px}i.flag.kuwait:before,i.flag.kw:before{background-position:-36px -1144px}i.flag.cayman.islands:before,i.flag.ky:before{background-position:-36px -1170px}i.flag.kazakhstan:before,i.flag.kz:before{background-position:-36px -1196px}i.flag.la:before,i.flag.laos:before{background-position:-36px -1222px}i.flag.lb:before,i.flag.lebanon:before{background-position:-36px -1248px}i.flag.lc:before,i.flag.saint.lucia:before{background-position:-36px -1274px}i.flag.li:before,i.flag.liechtenstein:before{background-position:-36px -1300px}i.flag.lk:before,i.flag.sri.lanka:before{background-position:-36px -1326px}i.flag.liberia:before,i.flag.lr:before{background-position:-36px -1352px}i.flag.lesotho:before,i.flag.ls:before{background-position:-36px -1378px}i.flag.lithuania:before,i.flag.lt:before{background-position:-36px -1404px}i.flag.lu:before,i.flag.luxembourg:before{background-position:-36px -1430px}i.flag.latvia:before,i.flag.lv:before{background-position:-36px -1456px}i.flag.libya:before,i.flag.ly:before{background-position:-36px -1482px}i.flag.ma:before,i.flag.morocco:before{background-position:-36px -1508px}i.flag.mc:before,i.flag.monaco:before{background-position:-36px -1534px}i.flag.md:before,i.flag.moldova:before{background-position:-36px -1560px}i.flag.me:before,i.flag.montenegro:before{background-position:-36px -1586px}i.flag.madagascar:before,i.flag.mg:before{background-position:-36px -1613px}i.flag.marshall.islands:before,i.flag.mh:before{background-position:-36px -1639px}i.flag.macedonia:before,i.flag.mk:before{background-position:-36px -1665px}i.flag.mali:before,i.flag.ml:before{background-position:-36px -1691px}i.flag.burma:before,i.flag.mm:before,i.flag.myanmar:before{background-position:-73px -1821px}i.flag.mn:before,i.flag.mongolia:before{background-position:-36px -1743px}i.flag.macau:before,i.flag.mo:before{background-position:-36px -1769px}i.flag.mp:before,i.flag.northern.mariana.islands:before{background-position:-36px -1795px}i.flag.martinique:before,i.flag.mq:before{background-position:-36px -1821px}i.flag.mauritania:before,i.flag.mr:before{background-position:-36px -1847px}i.flag.montserrat:before,i.flag.ms:before{background-position:-36px -1873px}i.flag.malta:before,i.flag.mt:before{background-position:-36px -1899px}i.flag.mauritius:before,i.flag.mu:before{background-position:-36px -1925px}i.flag.maldives:before,i.flag.mv:before{background-position:-36px -1951px}i.flag.malawi:before,i.flag.mw:before{background-position:-36px -1977px}i.flag.mexico:before,i.flag.mx:before{background-position:-72px 0}i.flag.malaysia:before,i.flag.my:before{background-position:-72px -26px}i.flag.mozambique:before,i.flag.mz:before{background-position:-72px -52px}i.flag.na:before,i.flag.namibia:before{background-position:-72px -78px}i.flag.nc:before,i.flag.new.caledonia:before{background-position:-72px -104px}i.flag.ne:before,i.flag.niger:before{background-position:-72px -130px}i.flag.nf:before,i.flag.norfolk.island:before{background-position:-72px -156px}i.flag.ng:before,i.flag.nigeria:before{background-position:-72px -182px}i.flag.ni:before,i.flag.nicaragua:before{background-position:-72px -208px}i.flag.netherlands:before,i.flag.nl:before{background-position:-72px -234px}i.flag.no:before,i.flag.norway:before{background-position:-72px -260px}i.flag.nepal:before,i.flag.np:before{background-position:-72px -286px}i.flag.nauru:before,i.flag.nr:before{background-position:-72px -312px}i.flag.niue:before,i.flag.nu:before{background-position:-72px -338px}i.flag.new.zealand:before,i.flag.nz:before{background-position:-72px -364px}i.flag.om:before,i.flag.oman:before{background-position:-72px -390px}i.flag.pa:before,i.flag.panama:before{background-position:-72px -416px}i.flag.pe:before,i.flag.peru:before{background-position:-72px -442px}i.flag.french.polynesia:before,i.flag.pf:before{background-position:-72px -468px}i.flag.new.guinea:before,i.flag.pg:before{background-position:-72px -494px}i.flag.ph:before,i.flag.philippines:before{background-position:-72px -520px}i.flag.pakistan:before,i.flag.pk:before{background-position:-72px -546px}i.flag.pl:before,i.flag.poland:before{background-position:-72px -572px}i.flag.pm:before,i.flag.saint.pierre:before{background-position:-72px -598px}i.flag.pitcairn.islands:before,i.flag.pn:before{background-position:-72px -624px}i.flag.pr:before,i.flag.puerto.rico:before{background-position:-72px -650px}i.flag.palestine:before,i.flag.ps:before{background-position:-72px -676px}i.flag.portugal:before,i.flag.pt:before{background-position:-72px -702px}i.flag.palau:before,i.flag.pw:before{background-position:-72px -728px}i.flag.paraguay:before,i.flag.py:before{background-position:-72px -754px}i.flag.qa:before,i.flag.qatar:before{background-position:-72px -780px}i.flag.re:before,i.flag.reunion:before{background-position:-72px -806px}i.flag.ro:before,i.flag.romania:before{background-position:-72px -832px}i.flag.rs:before,i.flag.serbia:before{background-position:-72px -858px}i.flag.ru:before,i.flag.russia:before{background-position:-72px -884px}i.flag.rw:before,i.flag.rwanda:before{background-position:-72px -910px}i.flag.sa:before,i.flag.saudi.arabia:before{background-position:-72px -936px}i.flag.sb:before,i.flag.solomon.islands:before{background-position:-72px -962px}i.flag.sc:before,i.flag.seychelles:before{background-position:-72px -988px}i.flag.gb.sct:before,i.flag.scotland:before{background-position:-72px -1014px}i.flag.sd:before,i.flag.sudan:before{background-position:-72px -1040px}i.flag.se:before,i.flag.sweden:before{background-position:-72px -1066px}i.flag.sg:before,i.flag.singapore:before{background-position:-72px -1092px}i.flag.saint.helena:before,i.flag.sh:before{background-position:-72px -1118px}i.flag.si:before,i.flag.slovenia:before{background-position:-72px -1144px}i.flag.jan.mayen:before,i.flag.sj:before,i.flag.svalbard:before{background-position:-72px -1170px}i.flag.sk:before,i.flag.slovakia:before{background-position:-72px -1196px}i.flag.sierra.leone:before,i.flag.sl:before{background-position:-72px -1222px}i.flag.san.marino:before,i.flag.sm:before{background-position:-72px -1248px}i.flag.senegal:before,i.flag.sn:before{background-position:-72px -1274px}i.flag.so:before,i.flag.somalia:before{background-position:-72px -1300px}i.flag.sr:before,i.flag.suriname:before{background-position:-72px -1326px}i.flag.sao.tome:before,i.flag.st:before{background-position:-72px -1352px}i.flag.el.salvador:before,i.flag.sv:before{background-position:-72px -1378px}i.flag.sy:before,i.flag.syria:before{background-position:-72px -1404px}i.flag.swaziland:before,i.flag.sz:before{background-position:-72px -1430px}i.flag.caicos.islands:before,i.flag.tc:before{background-position:-72px -1456px}i.flag.chad:before,i.flag.td:before{background-position:-72px -1482px}i.flag.french.territories:before,i.flag.tf:before{background-position:-72px -1508px}i.flag.tg:before,i.flag.togo:before{background-position:-72px -1534px}i.flag.th:before,i.flag.thailand:before{background-position:-72px -1560px}i.flag.tajikistan:before,i.flag.tj:before{background-position:-72px -1586px}i.flag.tk:before,i.flag.tokelau:before{background-position:-72px -1612px}i.flag.timorleste:before,i.flag.tl:before{background-position:-72px -1638px}i.flag.tm:before,i.flag.turkmenistan:before{background-position:-72px -1664px}i.flag.tn:before,i.flag.tunisia:before{background-position:-72px -1690px}i.flag.to:before,i.flag.tonga:before{background-position:-72px -1716px}i.flag.tr:before,i.flag.turkey:before{background-position:-72px -1742px}i.flag.trinidad:before,i.flag.tt:before{background-position:-72px -1768px}i.flag.tuvalu:before,i.flag.tv:before{background-position:-72px -1794px}i.flag.taiwan:before,i.flag.tw:before{background-position:-72px -1820px}i.flag.tanzania:before,i.flag.tz:before{background-position:-72px -1846px}i.flag.ua:before,i.flag.ukraine:before{background-position:-72px -1872px}i.flag.ug:before,i.flag.uganda:before{background-position:-72px -1898px}i.flag.um:before,i.flag.us.minor.islands:before{background-position:-72px -1924px}i.flag.america:before,i.flag.united.states:before,i.flag.us:before{background-position:-72px -1950px}i.flag.uruguay:before,i.flag.uy:before{background-position:-72px -1976px}i.flag.uz:before,i.flag.uzbekistan:before{background-position:-108px 0}i.flag.va:before,i.flag.vatican.city:before{background-position:-108px -26px}i.flag.saint.vincent:before,i.flag.vc:before{background-position:-108px -52px}i.flag.ve:before,i.flag.venezuela:before{background-position:-108px -78px}i.flag.british.virgin.islands:before,i.flag.vg:before{background-position:-108px -104px}i.flag.us.virgin.islands:before,i.flag.vi:before{background-position:-108px -130px}i.flag.vietnam:before,i.flag.vn:before{background-position:-108px -156px}i.flag.vanuatu:before,i.flag.vu:before{background-position:-108px -182px}i.flag.gb.wls:before,i.flag.wales:before{background-position:-108px -208px}i.flag.wallis.and.futuna:before,i.flag.wf:before{background-position:-108px -234px}i.flag.samoa:before,i.flag.ws:before{background-position:-108px -260px}i.flag.ye:before,i.flag.yemen:before{background-position:-108px -286px}i.flag.mayotte:before,i.flag.yt:before{background-position:-108px -312px}i.flag.south.africa:before,i.flag.za:before{background-position:-108px -338px}i.flag.zambia:before,i.flag.zm:before{background-position:-108px -364px}i.flag.zimbabwe:before,i.flag.zw:before{background-position:-108px -390px}/*!\\n * # Semantic UI 2.4.0 - Header\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.header{border:none;margin:calc(2rem - .14285714em) 0 1rem;padding:0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;line-height:1.28571429em;text-transform:none;color:rgba(0,0,0,.87)}.ui.header:first-child{margin-top:-.14285714em}.ui.header:last-child{margin-bottom:0}.ui.header .sub.header{display:block;font-weight:400;padding:0;margin:0;font-size:1rem;line-height:1.2em;color:rgba(0,0,0,.6)}.ui.header>.icon{display:table-cell;opacity:1;font-size:1.5em;padding-top:0;vertical-align:middle}.ui.header .icon:only-child{display:inline-block;padding:0;margin-right:.75rem}.ui.header>.image:not(.icon),.ui.header>img{display:inline-block;margin-top:.14285714em;width:2.5em;height:auto;vertical-align:middle}.ui.header>.image:not(.icon):only-child,.ui.header>img:only-child{margin-right:.75rem}.ui.header .content{display:inline-block;vertical-align:top}.ui.header>.image+.content,.ui.header>img+.content{padding-left:.75rem;vertical-align:middle}.ui.header>.icon+.content{padding-left:.75rem;display:table-cell;vertical-align:middle}.ui.header .ui.label{font-size:'';margin-left:.5rem;vertical-align:middle}.ui.header+p{margin-top:0}h1.ui.header{font-size:2rem}h2.ui.header{font-size:1.71428571rem}h3.ui.header{font-size:1.28571429rem}h4.ui.header{font-size:1.07142857rem}h5.ui.header{font-size:1rem}h1.ui.header .sub.header{font-size:1.14285714rem}h2.ui.header .sub.header{font-size:1.14285714rem}h3.ui.header .sub.header{font-size:1rem}h4.ui.header .sub.header{font-size:1rem}h5.ui.header .sub.header{font-size:.92857143rem}.ui.huge.header{min-height:1em;font-size:2em}.ui.large.header{font-size:1.71428571em}.ui.medium.header{font-size:1.28571429em}.ui.small.header{font-size:1.07142857em}.ui.tiny.header{font-size:1em}.ui.huge.header .sub.header{font-size:1.14285714rem}.ui.large.header .sub.header{font-size:1.14285714rem}.ui.header .sub.header{font-size:1rem}.ui.small.header .sub.header{font-size:1rem}.ui.tiny.header .sub.header{font-size:.92857143rem}.ui.sub.header{padding:0;margin-bottom:.14285714rem;font-weight:700;font-size:.85714286em;text-transform:uppercase;color:''}.ui.small.sub.header{font-size:.78571429em}.ui.sub.header{font-size:.85714286em}.ui.large.sub.header{font-size:.92857143em}.ui.huge.sub.header{font-size:1em}.ui.icon.header{display:inline-block;text-align:center;margin:2rem 0 1rem}.ui.icon.header:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.icon.header:first-child{margin-top:0}.ui.icon.header .icon{float:none;display:block;width:auto;height:auto;line-height:1;padding:0;font-size:3em;margin:0 auto .5rem;opacity:1}.ui.icon.header .content{display:block;padding:0}.ui.icon.header .circular.icon{font-size:2em}.ui.icon.header .square.icon{font-size:2em}.ui.block.icon.header .icon{margin-bottom:0}.ui.icon.header.aligned{margin-left:auto;margin-right:auto;display:block}.ui.disabled.header{opacity:.45}.ui.inverted.header{color:#fff}.ui.inverted.header .sub.header{color:rgba(255,255,255,.8)}.ui.inverted.attached.header{background:#545454 -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#545454 -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#545454 linear-gradient(transparent,rgba(0,0,0,.05));-webkit-box-shadow:none;box-shadow:none;border-color:transparent}.ui.inverted.block.header{background:#545454 -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#545454 -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#545454 linear-gradient(transparent,rgba(0,0,0,.05));-webkit-box-shadow:none;box-shadow:none}.ui.inverted.block.header{border-bottom:none}.ui.red.header{color:#db2828!important}a.ui.red.header:hover{color:#d01919!important}.ui.red.dividing.header{border-bottom:2px solid #db2828}.ui.inverted.red.header{color:#ff695e!important}a.ui.inverted.red.header:hover{color:#ff5144!important}.ui.orange.header{color:#f2711c!important}a.ui.orange.header:hover{color:#f26202!important}.ui.orange.dividing.header{border-bottom:2px solid #f2711c}.ui.inverted.orange.header{color:#ff851b!important}a.ui.inverted.orange.header:hover{color:#ff7701!important}.ui.olive.header{color:#b5cc18!important}a.ui.olive.header:hover{color:#a7bd0d!important}.ui.olive.dividing.header{border-bottom:2px solid #b5cc18}.ui.inverted.olive.header{color:#d9e778!important}a.ui.inverted.olive.header:hover{color:#d8ea5c!important}.ui.yellow.header{color:#fbbd08!important}a.ui.yellow.header:hover{color:#eaae00!important}.ui.yellow.dividing.header{border-bottom:2px solid #fbbd08}.ui.inverted.yellow.header{color:#ffe21f!important}a.ui.inverted.yellow.header:hover{color:#ffdf05!important}.ui.green.header{color:#21ba45!important}a.ui.green.header:hover{color:#16ab39!important}.ui.green.dividing.header{border-bottom:2px solid #21ba45}.ui.inverted.green.header{color:#2ecc40!important}a.ui.inverted.green.header:hover{color:#22be34!important}.ui.teal.header{color:#00b5ad!important}a.ui.teal.header:hover{color:#009c95!important}.ui.teal.dividing.header{border-bottom:2px solid #00b5ad}.ui.inverted.teal.header{color:#6dffff!important}a.ui.inverted.teal.header:hover{color:#54ffff!important}.ui.blue.header{color:#2185d0!important}a.ui.blue.header:hover{color:#1678c2!important}.ui.blue.dividing.header{border-bottom:2px solid #2185d0}.ui.inverted.blue.header{color:#54c8ff!important}a.ui.inverted.blue.header:hover{color:#3ac0ff!important}.ui.violet.header{color:#6435c9!important}a.ui.violet.header:hover{color:#5829bb!important}.ui.violet.dividing.header{border-bottom:2px solid #6435c9}.ui.inverted.violet.header{color:#a291fb!important}a.ui.inverted.violet.header:hover{color:#8a73ff!important}.ui.purple.header{color:#a333c8!important}a.ui.purple.header:hover{color:#9627ba!important}.ui.purple.dividing.header{border-bottom:2px solid #a333c8}.ui.inverted.purple.header{color:#dc73ff!important}a.ui.inverted.purple.header:hover{color:#d65aff!important}.ui.pink.header{color:#e03997!important}a.ui.pink.header:hover{color:#e61a8d!important}.ui.pink.dividing.header{border-bottom:2px solid #e03997}.ui.inverted.pink.header{color:#ff8edf!important}a.ui.inverted.pink.header:hover{color:#ff74d8!important}.ui.brown.header{color:#a5673f!important}a.ui.brown.header:hover{color:#975b33!important}.ui.brown.dividing.header{border-bottom:2px solid #a5673f}.ui.inverted.brown.header{color:#d67c1c!important}a.ui.inverted.brown.header:hover{color:#c86f11!important}.ui.grey.header{color:#767676!important}a.ui.grey.header:hover{color:#838383!important}.ui.grey.dividing.header{border-bottom:2px solid #767676}.ui.inverted.grey.header{color:#dcddde!important}a.ui.inverted.grey.header:hover{color:#cfd0d2!important}.ui.left.aligned.header{text-align:left}.ui.right.aligned.header{text-align:right}.ui.center.aligned.header,.ui.centered.header{text-align:center}.ui.justified.header{text-align:justify}.ui.justified.header:after{display:inline-block;content:'';width:100%}.ui.floated.header,.ui[class*=\\\"left floated\\\"].header{float:left;margin-top:0;margin-right:.5em}.ui[class*=\\\"right floated\\\"].header{float:right;margin-top:0;margin-left:.5em}.ui.fitted.header{padding:0}.ui.dividing.header{padding-bottom:.21428571rem;border-bottom:1px solid rgba(34,36,38,.15)}.ui.dividing.header .sub.header{padding-bottom:.21428571rem}.ui.dividing.header .icon{margin-bottom:0}.ui.inverted.dividing.header{border-bottom-color:rgba(255,255,255,.1)}.ui.block.header{background:#f3f4f5;padding:.78571429rem 1rem;-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5;border-radius:.28571429rem}.ui.tiny.block.header{font-size:.85714286rem}.ui.small.block.header{font-size:.92857143rem}.ui.block.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1rem}.ui.large.block.header{font-size:1.14285714rem}.ui.huge.block.header{font-size:1.42857143rem}.ui.attached.header{background:#fff;padding:.78571429rem 1rem;margin-left:-1px;margin-right:-1px;-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached.block.header{background:#f3f4f5}.ui.attached:not(.top):not(.bottom).header{margin-top:0;margin-bottom:0;border-top:none;border-radius:0}.ui.top.attached.header{margin-bottom:0;border-radius:.28571429rem .28571429rem 0 0}.ui.bottom.attached.header{margin-top:0;border-top:none;border-radius:0 0 .28571429rem .28571429rem}.ui.tiny.attached.header{font-size:.85714286em}.ui.small.attached.header{font-size:.92857143em}.ui.attached.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1em}.ui.large.attached.header{font-size:1.14285714em}.ui.huge.attached.header{font-size:1.42857143em}.ui.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-size:1.28571429em}/*!\\n * # Semantic UI 2.4.0 - Icon\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */@font-face{font-family:Icons;src:url(themes/default/assets/fonts/icons.eot);src:url(themes/default/assets/fonts/icons.eot?#iefix) format('embedded-opentype'),url(themes/default/assets/fonts/icons.woff2) format('woff2'),url(themes/default/assets/fonts/icons.woff) format('woff'),url(themes/default/assets/fonts/icons.ttf) format('truetype'),url(themes/default/assets/fonts/icons.svg#icons) format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon{display:inline-block;opacity:1;margin:0 .25rem 0 0;width:1.18em;height:1em;font-family:Icons;font-style:normal;font-weight:400;text-decoration:inherit;text-align:center;speak:none;font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-backface-visibility:hidden;backface-visibility:hidden}i.icon:before{background:0 0!important}i.icon.loading{height:1em;line-height:1;-webkit-animation:icon-loading 2s linear infinite;animation:icon-loading 2s linear infinite}@-webkit-keyframes icon-loading{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes icon-loading{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}i.icon.hover{opacity:1!important}i.icon.active{opacity:1!important}i.emphasized.icon{opacity:1!important}i.disabled.icon{opacity:.45!important}i.fitted.icon{width:auto;margin:0!important}i.link.icon,i.link.icons{cursor:pointer;opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}i.link.icon:hover,i.link.icons:hover{opacity:1!important}i.circular.icon{border-radius:500em!important;line-height:1!important;padding:.5em 0!important;-webkit-box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;width:2em!important;height:2em!important}i.circular.inverted.icon{border:none;-webkit-box-shadow:none;box-shadow:none}i.flipped.icon,i.horizontally.flipped.icon{-webkit-transform:scale(-1,1);transform:scale(-1,1)}i.vertically.flipped.icon{-webkit-transform:scale(1,-1);transform:scale(1,-1)}i.clockwise.rotated.icon,i.right.rotated.icon,i.rotated.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}i.counterclockwise.rotated.icon,i.left.rotated.icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}i.bordered.icon{line-height:1;vertical-align:baseline;width:2em;height:2em;padding:.5em 0!important;-webkit-box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset;box-shadow:0 0 0 .1em rgba(0,0,0,.1) inset}i.bordered.inverted.icon{border:none;-webkit-box-shadow:none;box-shadow:none}i.inverted.bordered.icon,i.inverted.circular.icon{background-color:#1b1c1d!important;color:#fff!important}i.inverted.icon{color:#fff}i.red.icon{color:#db2828!important}i.inverted.red.icon{color:#ff695e!important}i.inverted.bordered.red.icon,i.inverted.circular.red.icon{background-color:#db2828!important;color:#fff!important}i.orange.icon{color:#f2711c!important}i.inverted.orange.icon{color:#ff851b!important}i.inverted.bordered.orange.icon,i.inverted.circular.orange.icon{background-color:#f2711c!important;color:#fff!important}i.yellow.icon{color:#fbbd08!important}i.inverted.yellow.icon{color:#ffe21f!important}i.inverted.bordered.yellow.icon,i.inverted.circular.yellow.icon{background-color:#fbbd08!important;color:#fff!important}i.olive.icon{color:#b5cc18!important}i.inverted.olive.icon{color:#d9e778!important}i.inverted.bordered.olive.icon,i.inverted.circular.olive.icon{background-color:#b5cc18!important;color:#fff!important}i.green.icon{color:#21ba45!important}i.inverted.green.icon{color:#2ecc40!important}i.inverted.bordered.green.icon,i.inverted.circular.green.icon{background-color:#21ba45!important;color:#fff!important}i.teal.icon{color:#00b5ad!important}i.inverted.teal.icon{color:#6dffff!important}i.inverted.bordered.teal.icon,i.inverted.circular.teal.icon{background-color:#00b5ad!important;color:#fff!important}i.blue.icon{color:#2185d0!important}i.inverted.blue.icon{color:#54c8ff!important}i.inverted.bordered.blue.icon,i.inverted.circular.blue.icon{background-color:#2185d0!important;color:#fff!important}i.violet.icon{color:#6435c9!important}i.inverted.violet.icon{color:#a291fb!important}i.inverted.bordered.violet.icon,i.inverted.circular.violet.icon{background-color:#6435c9!important;color:#fff!important}i.purple.icon{color:#a333c8!important}i.inverted.purple.icon{color:#dc73ff!important}i.inverted.bordered.purple.icon,i.inverted.circular.purple.icon{background-color:#a333c8!important;color:#fff!important}i.pink.icon{color:#e03997!important}i.inverted.pink.icon{color:#ff8edf!important}i.inverted.bordered.pink.icon,i.inverted.circular.pink.icon{background-color:#e03997!important;color:#fff!important}i.brown.icon{color:#a5673f!important}i.inverted.brown.icon{color:#d67c1c!important}i.inverted.bordered.brown.icon,i.inverted.circular.brown.icon{background-color:#a5673f!important;color:#fff!important}i.grey.icon{color:#767676!important}i.inverted.grey.icon{color:#dcddde!important}i.inverted.bordered.grey.icon,i.inverted.circular.grey.icon{background-color:#767676!important;color:#fff!important}i.black.icon{color:#1b1c1d!important}i.inverted.black.icon{color:#545454!important}i.inverted.bordered.black.icon,i.inverted.circular.black.icon{background-color:#1b1c1d!important;color:#fff!important}i.mini.icon,i.mini.icons{line-height:1;font-size:.4em}i.tiny.icon,i.tiny.icons{line-height:1;font-size:.5em}i.small.icon,i.small.icons{line-height:1;font-size:.75em}i.icon,i.icons{font-size:1em}i.large.icon,i.large.icons{line-height:1;vertical-align:middle;font-size:1.5em}i.big.icon,i.big.icons{line-height:1;vertical-align:middle;font-size:2em}i.huge.icon,i.huge.icons{line-height:1;vertical-align:middle;font-size:4em}i.massive.icon,i.massive.icons{line-height:1;vertical-align:middle;font-size:8em}i.icons{display:inline-block;position:relative;line-height:1}i.icons .icon{position:absolute;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);margin:0;margin:0}i.icons .icon:first-child{position:static;width:auto;height:auto;vertical-align:top;-webkit-transform:none;transform:none;margin-right:.25rem}i.icons .corner.icon{top:auto;left:auto;right:0;bottom:0;-webkit-transform:none;transform:none;font-size:.45em;text-shadow:-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff,1px 1px 0 #fff}i.icons .top.right.corner.icon{top:0;left:auto;right:0;bottom:auto}i.icons .top.left.corner.icon{top:0;left:0;right:auto;bottom:auto}i.icons .bottom.left.corner.icon{top:auto;left:0;right:auto;bottom:0}i.icons .bottom.right.corner.icon{top:auto;left:auto;right:0;bottom:0}i.icons .inverted.corner.icon{text-shadow:-1px -1px 0 #1b1c1d,1px -1px 0 #1b1c1d,-1px 1px 0 #1b1c1d,1px 1px 0 #1b1c1d}i.icon.linkedin.in:before{content:\\\"\\\\f0e1\\\"}i.icon.zoom.in:before{content:\\\"\\\\f00e\\\"}i.icon.zoom.out:before{content:\\\"\\\\f010\\\"}i.icon.sign.in:before{content:\\\"\\\\f2f6\\\"}i.icon.in.cart:before{content:\\\"\\\\f218\\\"}i.icon.log.out:before{content:\\\"\\\\f2f5\\\"}i.icon.sign.out:before{content:\\\"\\\\f2f5\\\"}i.icon.\\\\35 00px:before{content:\\\"\\\\f26e\\\"}i.icon.accessible.icon:before{content:\\\"\\\\f368\\\"}i.icon.accusoft:before{content:\\\"\\\\f369\\\"}i.icon.address.book:before{content:\\\"\\\\f2b9\\\"}i.icon.address.card:before{content:\\\"\\\\f2bb\\\"}i.icon.adjust:before{content:\\\"\\\\f042\\\"}i.icon.adn:before{content:\\\"\\\\f170\\\"}i.icon.adversal:before{content:\\\"\\\\f36a\\\"}i.icon.affiliatetheme:before{content:\\\"\\\\f36b\\\"}i.icon.algolia:before{content:\\\"\\\\f36c\\\"}i.icon.align.center:before{content:\\\"\\\\f037\\\"}i.icon.align.justify:before{content:\\\"\\\\f039\\\"}i.icon.align.left:before{content:\\\"\\\\f036\\\"}i.icon.align.right:before{content:\\\"\\\\f038\\\"}i.icon.amazon:before{content:\\\"\\\\f270\\\"}i.icon.amazon.pay:before{content:\\\"\\\\f42c\\\"}i.icon.ambulance:before{content:\\\"\\\\f0f9\\\"}i.icon.american.sign.language.interpreting:before{content:\\\"\\\\f2a3\\\"}i.icon.amilia:before{content:\\\"\\\\f36d\\\"}i.icon.anchor:before{content:\\\"\\\\f13d\\\"}i.icon.android:before{content:\\\"\\\\f17b\\\"}i.icon.angellist:before{content:\\\"\\\\f209\\\"}i.icon.angle.double.down:before{content:\\\"\\\\f103\\\"}i.icon.angle.double.left:before{content:\\\"\\\\f100\\\"}i.icon.angle.double.right:before{content:\\\"\\\\f101\\\"}i.icon.angle.double.up:before{content:\\\"\\\\f102\\\"}i.icon.angle.down:before{content:\\\"\\\\f107\\\"}i.icon.angle.left:before{content:\\\"\\\\f104\\\"}i.icon.angle.right:before{content:\\\"\\\\f105\\\"}i.icon.angle.up:before{content:\\\"\\\\f106\\\"}i.icon.angrycreative:before{content:\\\"\\\\f36e\\\"}i.icon.angular:before{content:\\\"\\\\f420\\\"}i.icon.app.store:before{content:\\\"\\\\f36f\\\"}i.icon.app.store.ios:before{content:\\\"\\\\f370\\\"}i.icon.apper:before{content:\\\"\\\\f371\\\"}i.icon.apple:before{content:\\\"\\\\f179\\\"}i.icon.apple.pay:before{content:\\\"\\\\f415\\\"}i.icon.archive:before{content:\\\"\\\\f187\\\"}i.icon.arrow.alternate.circle.down:before{content:\\\"\\\\f358\\\"}i.icon.arrow.alternate.circle.left:before{content:\\\"\\\\f359\\\"}i.icon.arrow.alternate.circle.right:before{content:\\\"\\\\f35a\\\"}i.icon.arrow.alternate.circle.up:before{content:\\\"\\\\f35b\\\"}i.icon.arrow.circle.down:before{content:\\\"\\\\f0ab\\\"}i.icon.arrow.circle.left:before{content:\\\"\\\\f0a8\\\"}i.icon.arrow.circle.right:before{content:\\\"\\\\f0a9\\\"}i.icon.arrow.circle.up:before{content:\\\"\\\\f0aa\\\"}i.icon.arrow.down:before{content:\\\"\\\\f063\\\"}i.icon.arrow.left:before{content:\\\"\\\\f060\\\"}i.icon.arrow.right:before{content:\\\"\\\\f061\\\"}i.icon.arrow.up:before{content:\\\"\\\\f062\\\"}i.icon.arrows.alternate:before{content:\\\"\\\\f0b2\\\"}i.icon.arrows.alternate.horizontal:before{content:\\\"\\\\f337\\\"}i.icon.arrows.alternate.vertical:before{content:\\\"\\\\f338\\\"}i.icon.assistive.listening.systems:before{content:\\\"\\\\f2a2\\\"}i.icon.asterisk:before{content:\\\"\\\\f069\\\"}i.icon.asymmetrik:before{content:\\\"\\\\f372\\\"}i.icon.at:before{content:\\\"\\\\f1fa\\\"}i.icon.audible:before{content:\\\"\\\\f373\\\"}i.icon.audio.description:before{content:\\\"\\\\f29e\\\"}i.icon.autoprefixer:before{content:\\\"\\\\f41c\\\"}i.icon.avianex:before{content:\\\"\\\\f374\\\"}i.icon.aviato:before{content:\\\"\\\\f421\\\"}i.icon.aws:before{content:\\\"\\\\f375\\\"}i.icon.backward:before{content:\\\"\\\\f04a\\\"}i.icon.balance.scale:before{content:\\\"\\\\f24e\\\"}i.icon.ban:before{content:\\\"\\\\f05e\\\"}i.icon.band.aid:before{content:\\\"\\\\f462\\\"}i.icon.bandcamp:before{content:\\\"\\\\f2d5\\\"}i.icon.barcode:before{content:\\\"\\\\f02a\\\"}i.icon.bars:before{content:\\\"\\\\f0c9\\\"}i.icon.baseball.ball:before{content:\\\"\\\\f433\\\"}i.icon.basketball.ball:before{content:\\\"\\\\f434\\\"}i.icon.bath:before{content:\\\"\\\\f2cd\\\"}i.icon.battery.empty:before{content:\\\"\\\\f244\\\"}i.icon.battery.full:before{content:\\\"\\\\f240\\\"}i.icon.battery.half:before{content:\\\"\\\\f242\\\"}i.icon.battery.quarter:before{content:\\\"\\\\f243\\\"}i.icon.battery.three.quarters:before{content:\\\"\\\\f241\\\"}i.icon.bed:before{content:\\\"\\\\f236\\\"}i.icon.beer:before{content:\\\"\\\\f0fc\\\"}i.icon.behance:before{content:\\\"\\\\f1b4\\\"}i.icon.behance.square:before{content:\\\"\\\\f1b5\\\"}i.icon.bell:before{content:\\\"\\\\f0f3\\\"}i.icon.bell.slash:before{content:\\\"\\\\f1f6\\\"}i.icon.bicycle:before{content:\\\"\\\\f206\\\"}i.icon.bimobject:before{content:\\\"\\\\f378\\\"}i.icon.binoculars:before{content:\\\"\\\\f1e5\\\"}i.icon.birthday.cake:before{content:\\\"\\\\f1fd\\\"}i.icon.bitbucket:before{content:\\\"\\\\f171\\\"}i.icon.bitcoin:before{content:\\\"\\\\f379\\\"}i.icon.bity:before{content:\\\"\\\\f37a\\\"}i.icon.black.tie:before{content:\\\"\\\\f27e\\\"}i.icon.blackberry:before{content:\\\"\\\\f37b\\\"}i.icon.blind:before{content:\\\"\\\\f29d\\\"}i.icon.blogger:before{content:\\\"\\\\f37c\\\"}i.icon.blogger.b:before{content:\\\"\\\\f37d\\\"}i.icon.bluetooth:before{content:\\\"\\\\f293\\\"}i.icon.bluetooth.b:before{content:\\\"\\\\f294\\\"}i.icon.bold:before{content:\\\"\\\\f032\\\"}i.icon.bolt:before{content:\\\"\\\\f0e7\\\"}i.icon.bomb:before{content:\\\"\\\\f1e2\\\"}i.icon.book:before{content:\\\"\\\\f02d\\\"}i.icon.bookmark:before{content:\\\"\\\\f02e\\\"}i.icon.bowling.ball:before{content:\\\"\\\\f436\\\"}i.icon.box:before{content:\\\"\\\\f466\\\"}i.icon.boxes:before{content:\\\"\\\\f468\\\"}i.icon.braille:before{content:\\\"\\\\f2a1\\\"}i.icon.briefcase:before{content:\\\"\\\\f0b1\\\"}i.icon.btc:before{content:\\\"\\\\f15a\\\"}i.icon.bug:before{content:\\\"\\\\f188\\\"}i.icon.building:before{content:\\\"\\\\f1ad\\\"}i.icon.bullhorn:before{content:\\\"\\\\f0a1\\\"}i.icon.bullseye:before{content:\\\"\\\\f140\\\"}i.icon.buromobelexperte:before{content:\\\"\\\\f37f\\\"}i.icon.bus:before{content:\\\"\\\\f207\\\"}i.icon.buysellads:before{content:\\\"\\\\f20d\\\"}i.icon.calculator:before{content:\\\"\\\\f1ec\\\"}i.icon.calendar:before{content:\\\"\\\\f133\\\"}i.icon.calendar.alternate:before{content:\\\"\\\\f073\\\"}i.icon.calendar.check:before{content:\\\"\\\\f274\\\"}i.icon.calendar.minus:before{content:\\\"\\\\f272\\\"}i.icon.calendar.plus:before{content:\\\"\\\\f271\\\"}i.icon.calendar.times:before{content:\\\"\\\\f273\\\"}i.icon.camera:before{content:\\\"\\\\f030\\\"}i.icon.camera.retro:before{content:\\\"\\\\f083\\\"}i.icon.car:before{content:\\\"\\\\f1b9\\\"}i.icon.caret.down:before{content:\\\"\\\\f0d7\\\"}i.icon.caret.left:before{content:\\\"\\\\f0d9\\\"}i.icon.caret.right:before{content:\\\"\\\\f0da\\\"}i.icon.caret.square.down:before{content:\\\"\\\\f150\\\"}i.icon.caret.square.left:before{content:\\\"\\\\f191\\\"}i.icon.caret.square.right:before{content:\\\"\\\\f152\\\"}i.icon.caret.square.up:before{content:\\\"\\\\f151\\\"}i.icon.caret.up:before{content:\\\"\\\\f0d8\\\"}i.icon.cart.arrow.down:before{content:\\\"\\\\f218\\\"}i.icon.cart.plus:before{content:\\\"\\\\f217\\\"}i.icon.cc.amazon.pay:before{content:\\\"\\\\f42d\\\"}i.icon.cc.amex:before{content:\\\"\\\\f1f3\\\"}i.icon.cc.apple.pay:before{content:\\\"\\\\f416\\\"}i.icon.cc.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.cc.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.cc.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.cc.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.cc.paypal:before{content:\\\"\\\\f1f4\\\"}i.icon.cc.stripe:before{content:\\\"\\\\f1f5\\\"}i.icon.cc.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.centercode:before{content:\\\"\\\\f380\\\"}i.icon.certificate:before{content:\\\"\\\\f0a3\\\"}i.icon.chart.area:before{content:\\\"\\\\f1fe\\\"}i.icon.chart.bar:before{content:\\\"\\\\f080\\\"}i.icon.chart.line:before{content:\\\"\\\\f201\\\"}i.icon.chart.pie:before{content:\\\"\\\\f200\\\"}i.icon.check:before{content:\\\"\\\\f00c\\\"}i.icon.check.circle:before{content:\\\"\\\\f058\\\"}i.icon.check.square:before{content:\\\"\\\\f14a\\\"}i.icon.chess:before{content:\\\"\\\\f439\\\"}i.icon.chess.bishop:before{content:\\\"\\\\f43a\\\"}i.icon.chess.board:before{content:\\\"\\\\f43c\\\"}i.icon.chess.king:before{content:\\\"\\\\f43f\\\"}i.icon.chess.knight:before{content:\\\"\\\\f441\\\"}i.icon.chess.pawn:before{content:\\\"\\\\f443\\\"}i.icon.chess.queen:before{content:\\\"\\\\f445\\\"}i.icon.chess.rook:before{content:\\\"\\\\f447\\\"}i.icon.chevron.circle.down:before{content:\\\"\\\\f13a\\\"}i.icon.chevron.circle.left:before{content:\\\"\\\\f137\\\"}i.icon.chevron.circle.right:before{content:\\\"\\\\f138\\\"}i.icon.chevron.circle.up:before{content:\\\"\\\\f139\\\"}i.icon.chevron.down:before{content:\\\"\\\\f078\\\"}i.icon.chevron.left:before{content:\\\"\\\\f053\\\"}i.icon.chevron.right:before{content:\\\"\\\\f054\\\"}i.icon.chevron.up:before{content:\\\"\\\\f077\\\"}i.icon.child:before{content:\\\"\\\\f1ae\\\"}i.icon.chrome:before{content:\\\"\\\\f268\\\"}i.icon.circle:before{content:\\\"\\\\f111\\\"}i.icon.circle.notch:before{content:\\\"\\\\f1ce\\\"}i.icon.clipboard:before{content:\\\"\\\\f328\\\"}i.icon.clipboard.check:before{content:\\\"\\\\f46c\\\"}i.icon.clipboard.list:before{content:\\\"\\\\f46d\\\"}i.icon.clock:before{content:\\\"\\\\f017\\\"}i.icon.clone:before{content:\\\"\\\\f24d\\\"}i.icon.closed.captioning:before{content:\\\"\\\\f20a\\\"}i.icon.cloud:before{content:\\\"\\\\f0c2\\\"}i.icon.cloudscale:before{content:\\\"\\\\f383\\\"}i.icon.cloudsmith:before{content:\\\"\\\\f384\\\"}i.icon.cloudversify:before{content:\\\"\\\\f385\\\"}i.icon.code:before{content:\\\"\\\\f121\\\"}i.icon.code.branch:before{content:\\\"\\\\f126\\\"}i.icon.codepen:before{content:\\\"\\\\f1cb\\\"}i.icon.codiepie:before{content:\\\"\\\\f284\\\"}i.icon.coffee:before{content:\\\"\\\\f0f4\\\"}i.icon.cog:before{content:\\\"\\\\f013\\\"}i.icon.cogs:before{content:\\\"\\\\f085\\\"}i.icon.columns:before{content:\\\"\\\\f0db\\\"}i.icon.comment:before{content:\\\"\\\\f075\\\"}i.icon.comment.alternate:before{content:\\\"\\\\f27a\\\"}i.icon.comments:before{content:\\\"\\\\f086\\\"}i.icon.compass:before{content:\\\"\\\\f14e\\\"}i.icon.compress:before{content:\\\"\\\\f066\\\"}i.icon.connectdevelop:before{content:\\\"\\\\f20e\\\"}i.icon.contao:before{content:\\\"\\\\f26d\\\"}i.icon.copy:before{content:\\\"\\\\f0c5\\\"}i.icon.copyright:before{content:\\\"\\\\f1f9\\\"}i.icon.cpanel:before{content:\\\"\\\\f388\\\"}i.icon.creative.commons:before{content:\\\"\\\\f25e\\\"}i.icon.credit.card:before{content:\\\"\\\\f09d\\\"}i.icon.crop:before{content:\\\"\\\\f125\\\"}i.icon.crosshairs:before{content:\\\"\\\\f05b\\\"}i.icon.css3:before{content:\\\"\\\\f13c\\\"}i.icon.css3.alternate:before{content:\\\"\\\\f38b\\\"}i.icon.cube:before{content:\\\"\\\\f1b2\\\"}i.icon.cubes:before{content:\\\"\\\\f1b3\\\"}i.icon.cut:before{content:\\\"\\\\f0c4\\\"}i.icon.cuttlefish:before{content:\\\"\\\\f38c\\\"}i.icon.d.and.d:before{content:\\\"\\\\f38d\\\"}i.icon.dashcube:before{content:\\\"\\\\f210\\\"}i.icon.database:before{content:\\\"\\\\f1c0\\\"}i.icon.deaf:before{content:\\\"\\\\f2a4\\\"}i.icon.delicious:before{content:\\\"\\\\f1a5\\\"}i.icon.deploydog:before{content:\\\"\\\\f38e\\\"}i.icon.deskpro:before{content:\\\"\\\\f38f\\\"}i.icon.desktop:before{content:\\\"\\\\f108\\\"}i.icon.deviantart:before{content:\\\"\\\\f1bd\\\"}i.icon.digg:before{content:\\\"\\\\f1a6\\\"}i.icon.digital.ocean:before{content:\\\"\\\\f391\\\"}i.icon.discord:before{content:\\\"\\\\f392\\\"}i.icon.discourse:before{content:\\\"\\\\f393\\\"}i.icon.dna:before{content:\\\"\\\\f471\\\"}i.icon.dochub:before{content:\\\"\\\\f394\\\"}i.icon.docker:before{content:\\\"\\\\f395\\\"}i.icon.dollar.sign:before{content:\\\"\\\\f155\\\"}i.icon.dolly:before{content:\\\"\\\\f472\\\"}i.icon.dolly.flatbed:before{content:\\\"\\\\f474\\\"}i.icon.dot.circle:before{content:\\\"\\\\f192\\\"}i.icon.download:before{content:\\\"\\\\f019\\\"}i.icon.draft2digital:before{content:\\\"\\\\f396\\\"}i.icon.dribbble:before{content:\\\"\\\\f17d\\\"}i.icon.dribbble.square:before{content:\\\"\\\\f397\\\"}i.icon.dropbox:before{content:\\\"\\\\f16b\\\"}i.icon.drupal:before{content:\\\"\\\\f1a9\\\"}i.icon.dyalog:before{content:\\\"\\\\f399\\\"}i.icon.earlybirds:before{content:\\\"\\\\f39a\\\"}i.icon.edge:before{content:\\\"\\\\f282\\\"}i.icon.edit:before{content:\\\"\\\\f044\\\"}i.icon.eject:before{content:\\\"\\\\f052\\\"}i.icon.elementor:before{content:\\\"\\\\f430\\\"}i.icon.ellipsis.horizontal:before{content:\\\"\\\\f141\\\"}i.icon.ellipsis.vertical:before{content:\\\"\\\\f142\\\"}i.icon.ember:before{content:\\\"\\\\f423\\\"}i.icon.empire:before{content:\\\"\\\\f1d1\\\"}i.icon.envelope:before{content:\\\"\\\\f0e0\\\"}i.icon.envelope.open:before{content:\\\"\\\\f2b6\\\"}i.icon.envelope.square:before{content:\\\"\\\\f199\\\"}i.icon.envira:before{content:\\\"\\\\f299\\\"}i.icon.eraser:before{content:\\\"\\\\f12d\\\"}i.icon.erlang:before{content:\\\"\\\\f39d\\\"}i.icon.ethereum:before{content:\\\"\\\\f42e\\\"}i.icon.etsy:before{content:\\\"\\\\f2d7\\\"}i.icon.euro.sign:before{content:\\\"\\\\f153\\\"}i.icon.exchange.alternate:before{content:\\\"\\\\f362\\\"}i.icon.exclamation:before{content:\\\"\\\\f12a\\\"}i.icon.exclamation.circle:before{content:\\\"\\\\f06a\\\"}i.icon.exclamation.triangle:before{content:\\\"\\\\f071\\\"}i.icon.expand:before{content:\\\"\\\\f065\\\"}i.icon.expand.arrows.alternate:before{content:\\\"\\\\f31e\\\"}i.icon.expeditedssl:before{content:\\\"\\\\f23e\\\"}i.icon.external.alternate:before{content:\\\"\\\\f35d\\\"}i.icon.external.square.alternate:before{content:\\\"\\\\f360\\\"}i.icon.eye:before{content:\\\"\\\\f06e\\\"}i.icon.eye.dropper:before{content:\\\"\\\\f1fb\\\"}i.icon.eye.slash:before{content:\\\"\\\\f070\\\"}i.icon.facebook:before{content:\\\"\\\\f09a\\\"}i.icon.facebook.f:before{content:\\\"\\\\f39e\\\"}i.icon.facebook.messenger:before{content:\\\"\\\\f39f\\\"}i.icon.facebook.square:before{content:\\\"\\\\f082\\\"}i.icon.fast.backward:before{content:\\\"\\\\f049\\\"}i.icon.fast.forward:before{content:\\\"\\\\f050\\\"}i.icon.fax:before{content:\\\"\\\\f1ac\\\"}i.icon.female:before{content:\\\"\\\\f182\\\"}i.icon.fighter.jet:before{content:\\\"\\\\f0fb\\\"}i.icon.file:before{content:\\\"\\\\f15b\\\"}i.icon.file.alternate:before{content:\\\"\\\\f15c\\\"}i.icon.file.archive:before{content:\\\"\\\\f1c6\\\"}i.icon.file.audio:before{content:\\\"\\\\f1c7\\\"}i.icon.file.code:before{content:\\\"\\\\f1c9\\\"}i.icon.file.excel:before{content:\\\"\\\\f1c3\\\"}i.icon.file.image:before{content:\\\"\\\\f1c5\\\"}i.icon.file.pdf:before{content:\\\"\\\\f1c1\\\"}i.icon.file.powerpoint:before{content:\\\"\\\\f1c4\\\"}i.icon.file.video:before{content:\\\"\\\\f1c8\\\"}i.icon.file.word:before{content:\\\"\\\\f1c2\\\"}i.icon.film:before{content:\\\"\\\\f008\\\"}i.icon.filter:before{content:\\\"\\\\f0b0\\\"}i.icon.fire:before{content:\\\"\\\\f06d\\\"}i.icon.fire.extinguisher:before{content:\\\"\\\\f134\\\"}i.icon.firefox:before{content:\\\"\\\\f269\\\"}i.icon.first.aid:before{content:\\\"\\\\f479\\\"}i.icon.first.order:before{content:\\\"\\\\f2b0\\\"}i.icon.firstdraft:before{content:\\\"\\\\f3a1\\\"}i.icon.flag:before{content:\\\"\\\\f024\\\"}i.icon.flag.checkered:before{content:\\\"\\\\f11e\\\"}i.icon.flask:before{content:\\\"\\\\f0c3\\\"}i.icon.flickr:before{content:\\\"\\\\f16e\\\"}i.icon.flipboard:before{content:\\\"\\\\f44d\\\"}i.icon.fly:before{content:\\\"\\\\f417\\\"}i.icon.folder:before{content:\\\"\\\\f07b\\\"}i.icon.folder.open:before{content:\\\"\\\\f07c\\\"}i.icon.font:before{content:\\\"\\\\f031\\\"}i.icon.font.awesome:before{content:\\\"\\\\f2b4\\\"}i.icon.font.awesome.alternate:before{content:\\\"\\\\f35c\\\"}i.icon.font.awesome.flag:before{content:\\\"\\\\f425\\\"}i.icon.fonticons:before{content:\\\"\\\\f280\\\"}i.icon.fonticons.fi:before{content:\\\"\\\\f3a2\\\"}i.icon.football.ball:before{content:\\\"\\\\f44e\\\"}i.icon.fort.awesome:before{content:\\\"\\\\f286\\\"}i.icon.fort.awesome.alternate:before{content:\\\"\\\\f3a3\\\"}i.icon.forumbee:before{content:\\\"\\\\f211\\\"}i.icon.forward:before{content:\\\"\\\\f04e\\\"}i.icon.foursquare:before{content:\\\"\\\\f180\\\"}i.icon.free.code.camp:before{content:\\\"\\\\f2c5\\\"}i.icon.freebsd:before{content:\\\"\\\\f3a4\\\"}i.icon.frown:before{content:\\\"\\\\f119\\\"}i.icon.futbol:before{content:\\\"\\\\f1e3\\\"}i.icon.gamepad:before{content:\\\"\\\\f11b\\\"}i.icon.gavel:before{content:\\\"\\\\f0e3\\\"}i.icon.gem:before{content:\\\"\\\\f3a5\\\"}i.icon.genderless:before{content:\\\"\\\\f22d\\\"}i.icon.get.pocket:before{content:\\\"\\\\f265\\\"}i.icon.gg:before{content:\\\"\\\\f260\\\"}i.icon.gg.circle:before{content:\\\"\\\\f261\\\"}i.icon.gift:before{content:\\\"\\\\f06b\\\"}i.icon.git:before{content:\\\"\\\\f1d3\\\"}i.icon.git.square:before{content:\\\"\\\\f1d2\\\"}i.icon.github:before{content:\\\"\\\\f09b\\\"}i.icon.github.alternate:before{content:\\\"\\\\f113\\\"}i.icon.github.square:before{content:\\\"\\\\f092\\\"}i.icon.gitkraken:before{content:\\\"\\\\f3a6\\\"}i.icon.gitlab:before{content:\\\"\\\\f296\\\"}i.icon.gitter:before{content:\\\"\\\\f426\\\"}i.icon.glass.martini:before{content:\\\"\\\\f000\\\"}i.icon.glide:before{content:\\\"\\\\f2a5\\\"}i.icon.glide.g:before{content:\\\"\\\\f2a6\\\"}i.icon.globe:before{content:\\\"\\\\f0ac\\\"}i.icon.gofore:before{content:\\\"\\\\f3a7\\\"}i.icon.golf.ball:before{content:\\\"\\\\f450\\\"}i.icon.goodreads:before{content:\\\"\\\\f3a8\\\"}i.icon.goodreads.g:before{content:\\\"\\\\f3a9\\\"}i.icon.google:before{content:\\\"\\\\f1a0\\\"}i.icon.google.drive:before{content:\\\"\\\\f3aa\\\"}i.icon.google.play:before{content:\\\"\\\\f3ab\\\"}i.icon.google.plus:before{content:\\\"\\\\f2b3\\\"}i.icon.google.plus.g:before{content:\\\"\\\\f0d5\\\"}i.icon.google.plus.square:before{content:\\\"\\\\f0d4\\\"}i.icon.google.wallet:before{content:\\\"\\\\f1ee\\\"}i.icon.graduation.cap:before{content:\\\"\\\\f19d\\\"}i.icon.gratipay:before{content:\\\"\\\\f184\\\"}i.icon.grav:before{content:\\\"\\\\f2d6\\\"}i.icon.gripfire:before{content:\\\"\\\\f3ac\\\"}i.icon.grunt:before{content:\\\"\\\\f3ad\\\"}i.icon.gulp:before{content:\\\"\\\\f3ae\\\"}i.icon.h.square:before{content:\\\"\\\\f0fd\\\"}i.icon.hacker.news:before{content:\\\"\\\\f1d4\\\"}i.icon.hacker.news.square:before{content:\\\"\\\\f3af\\\"}i.icon.hand.lizard:before{content:\\\"\\\\f258\\\"}i.icon.hand.paper:before{content:\\\"\\\\f256\\\"}i.icon.hand.peace:before{content:\\\"\\\\f25b\\\"}i.icon.hand.point.down:before{content:\\\"\\\\f0a7\\\"}i.icon.hand.point.left:before{content:\\\"\\\\f0a5\\\"}i.icon.hand.point.right:before{content:\\\"\\\\f0a4\\\"}i.icon.hand.point.up:before{content:\\\"\\\\f0a6\\\"}i.icon.hand.pointer:before{content:\\\"\\\\f25a\\\"}i.icon.hand.rock:before{content:\\\"\\\\f255\\\"}i.icon.hand.scissors:before{content:\\\"\\\\f257\\\"}i.icon.hand.spock:before{content:\\\"\\\\f259\\\"}i.icon.handshake:before{content:\\\"\\\\f2b5\\\"}i.icon.hashtag:before{content:\\\"\\\\f292\\\"}i.icon.hdd:before{content:\\\"\\\\f0a0\\\"}i.icon.heading:before{content:\\\"\\\\f1dc\\\"}i.icon.headphones:before{content:\\\"\\\\f025\\\"}i.icon.heart:before{content:\\\"\\\\f004\\\"}i.icon.heartbeat:before{content:\\\"\\\\f21e\\\"}i.icon.hips:before{content:\\\"\\\\f452\\\"}i.icon.hire.a.helper:before{content:\\\"\\\\f3b0\\\"}i.icon.history:before{content:\\\"\\\\f1da\\\"}i.icon.hockey.puck:before{content:\\\"\\\\f453\\\"}i.icon.home:before{content:\\\"\\\\f015\\\"}i.icon.hooli:before{content:\\\"\\\\f427\\\"}i.icon.hospital:before{content:\\\"\\\\f0f8\\\"}i.icon.hospital.symbol:before{content:\\\"\\\\f47e\\\"}i.icon.hotjar:before{content:\\\"\\\\f3b1\\\"}i.icon.hourglass:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.end:before{content:\\\"\\\\f253\\\"}i.icon.hourglass.half:before{content:\\\"\\\\f252\\\"}i.icon.hourglass.start:before{content:\\\"\\\\f251\\\"}i.icon.houzz:before{content:\\\"\\\\f27c\\\"}i.icon.html5:before{content:\\\"\\\\f13b\\\"}i.icon.hubspot:before{content:\\\"\\\\f3b2\\\"}i.icon.i.cursor:before{content:\\\"\\\\f246\\\"}i.icon.id.badge:before{content:\\\"\\\\f2c1\\\"}i.icon.id.card:before{content:\\\"\\\\f2c2\\\"}i.icon.image:before{content:\\\"\\\\f03e\\\"}i.icon.images:before{content:\\\"\\\\f302\\\"}i.icon.imdb:before{content:\\\"\\\\f2d8\\\"}i.icon.inbox:before{content:\\\"\\\\f01c\\\"}i.icon.indent:before{content:\\\"\\\\f03c\\\"}i.icon.industry:before{content:\\\"\\\\f275\\\"}i.icon.info:before{content:\\\"\\\\f129\\\"}i.icon.info.circle:before{content:\\\"\\\\f05a\\\"}i.icon.instagram:before{content:\\\"\\\\f16d\\\"}i.icon.internet.explorer:before{content:\\\"\\\\f26b\\\"}i.icon.ioxhost:before{content:\\\"\\\\f208\\\"}i.icon.italic:before{content:\\\"\\\\f033\\\"}i.icon.itunes:before{content:\\\"\\\\f3b4\\\"}i.icon.itunes.note:before{content:\\\"\\\\f3b5\\\"}i.icon.jenkins:before{content:\\\"\\\\f3b6\\\"}i.icon.joget:before{content:\\\"\\\\f3b7\\\"}i.icon.joomla:before{content:\\\"\\\\f1aa\\\"}i.icon.js:before{content:\\\"\\\\f3b8\\\"}i.icon.js.square:before{content:\\\"\\\\f3b9\\\"}i.icon.jsfiddle:before{content:\\\"\\\\f1cc\\\"}i.icon.key:before{content:\\\"\\\\f084\\\"}i.icon.keyboard:before{content:\\\"\\\\f11c\\\"}i.icon.keycdn:before{content:\\\"\\\\f3ba\\\"}i.icon.kickstarter:before{content:\\\"\\\\f3bb\\\"}i.icon.kickstarter.k:before{content:\\\"\\\\f3bc\\\"}i.icon.korvue:before{content:\\\"\\\\f42f\\\"}i.icon.language:before{content:\\\"\\\\f1ab\\\"}i.icon.laptop:before{content:\\\"\\\\f109\\\"}i.icon.laravel:before{content:\\\"\\\\f3bd\\\"}i.icon.lastfm:before{content:\\\"\\\\f202\\\"}i.icon.lastfm.square:before{content:\\\"\\\\f203\\\"}i.icon.leaf:before{content:\\\"\\\\f06c\\\"}i.icon.leanpub:before{content:\\\"\\\\f212\\\"}i.icon.lemon:before{content:\\\"\\\\f094\\\"}i.icon.less:before{content:\\\"\\\\f41d\\\"}i.icon.level.down.alternate:before{content:\\\"\\\\f3be\\\"}i.icon.level.up.alternate:before{content:\\\"\\\\f3bf\\\"}i.icon.life.ring:before{content:\\\"\\\\f1cd\\\"}i.icon.lightbulb:before{content:\\\"\\\\f0eb\\\"}i.icon.linechat:before{content:\\\"\\\\f3c0\\\"}i.icon.linkify:before{content:\\\"\\\\f0c1\\\"}i.icon.linkedin:before{content:\\\"\\\\f08c\\\"}i.icon.linkedin.alt:before{content:\\\"\\\\f0e1\\\"}i.icon.linode:before{content:\\\"\\\\f2b8\\\"}i.icon.linux:before{content:\\\"\\\\f17c\\\"}i.icon.lira.sign:before{content:\\\"\\\\f195\\\"}i.icon.list:before{content:\\\"\\\\f03a\\\"}i.icon.list.alternate:before{content:\\\"\\\\f022\\\"}i.icon.list.ol:before{content:\\\"\\\\f0cb\\\"}i.icon.list.ul:before{content:\\\"\\\\f0ca\\\"}i.icon.location.arrow:before{content:\\\"\\\\f124\\\"}i.icon.lock:before{content:\\\"\\\\f023\\\"}i.icon.lock.open:before{content:\\\"\\\\f3c1\\\"}i.icon.long.arrow.alternate.down:before{content:\\\"\\\\f309\\\"}i.icon.long.arrow.alternate.left:before{content:\\\"\\\\f30a\\\"}i.icon.long.arrow.alternate.right:before{content:\\\"\\\\f30b\\\"}i.icon.long.arrow.alternate.up:before{content:\\\"\\\\f30c\\\"}i.icon.low.vision:before{content:\\\"\\\\f2a8\\\"}i.icon.lyft:before{content:\\\"\\\\f3c3\\\"}i.icon.magento:before{content:\\\"\\\\f3c4\\\"}i.icon.magic:before{content:\\\"\\\\f0d0\\\"}i.icon.magnet:before{content:\\\"\\\\f076\\\"}i.icon.male:before{content:\\\"\\\\f183\\\"}i.icon.map:before{content:\\\"\\\\f279\\\"}i.icon.map.marker:before{content:\\\"\\\\f041\\\"}i.icon.map.marker.alternate:before{content:\\\"\\\\f3c5\\\"}i.icon.map.pin:before{content:\\\"\\\\f276\\\"}i.icon.map.signs:before{content:\\\"\\\\f277\\\"}i.icon.mars:before{content:\\\"\\\\f222\\\"}i.icon.mars.double:before{content:\\\"\\\\f227\\\"}i.icon.mars.stroke:before{content:\\\"\\\\f229\\\"}i.icon.mars.stroke.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.mars.stroke.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.maxcdn:before{content:\\\"\\\\f136\\\"}i.icon.medapps:before{content:\\\"\\\\f3c6\\\"}i.icon.medium:before{content:\\\"\\\\f23a\\\"}i.icon.medium.m:before{content:\\\"\\\\f3c7\\\"}i.icon.medkit:before{content:\\\"\\\\f0fa\\\"}i.icon.medrt:before{content:\\\"\\\\f3c8\\\"}i.icon.meetup:before{content:\\\"\\\\f2e0\\\"}i.icon.meh:before{content:\\\"\\\\f11a\\\"}i.icon.mercury:before{content:\\\"\\\\f223\\\"}i.icon.microchip:before{content:\\\"\\\\f2db\\\"}i.icon.microphone:before{content:\\\"\\\\f130\\\"}i.icon.microphone.slash:before{content:\\\"\\\\f131\\\"}i.icon.microsoft:before{content:\\\"\\\\f3ca\\\"}i.icon.minus:before{content:\\\"\\\\f068\\\"}i.icon.minus.circle:before{content:\\\"\\\\f056\\\"}i.icon.minus.square:before{content:\\\"\\\\f146\\\"}i.icon.mix:before{content:\\\"\\\\f3cb\\\"}i.icon.mixcloud:before{content:\\\"\\\\f289\\\"}i.icon.mizuni:before{content:\\\"\\\\f3cc\\\"}i.icon.mobile:before{content:\\\"\\\\f10b\\\"}i.icon.mobile.alternate:before{content:\\\"\\\\f3cd\\\"}i.icon.modx:before{content:\\\"\\\\f285\\\"}i.icon.monero:before{content:\\\"\\\\f3d0\\\"}i.icon.money.bill.alternate:before{content:\\\"\\\\f3d1\\\"}i.icon.moon:before{content:\\\"\\\\f186\\\"}i.icon.motorcycle:before{content:\\\"\\\\f21c\\\"}i.icon.mouse.pointer:before{content:\\\"\\\\f245\\\"}i.icon.music:before{content:\\\"\\\\f001\\\"}i.icon.napster:before{content:\\\"\\\\f3d2\\\"}i.icon.neuter:before{content:\\\"\\\\f22c\\\"}i.icon.newspaper:before{content:\\\"\\\\f1ea\\\"}i.icon.nintendo.switch:before{content:\\\"\\\\f418\\\"}i.icon.node:before{content:\\\"\\\\f419\\\"}i.icon.node.js:before{content:\\\"\\\\f3d3\\\"}i.icon.npm:before{content:\\\"\\\\f3d4\\\"}i.icon.ns8:before{content:\\\"\\\\f3d5\\\"}i.icon.nutritionix:before{content:\\\"\\\\f3d6\\\"}i.icon.object.group:before{content:\\\"\\\\f247\\\"}i.icon.object.ungroup:before{content:\\\"\\\\f248\\\"}i.icon.odnoklassniki:before{content:\\\"\\\\f263\\\"}i.icon.odnoklassniki.square:before{content:\\\"\\\\f264\\\"}i.icon.opencart:before{content:\\\"\\\\f23d\\\"}i.icon.openid:before{content:\\\"\\\\f19b\\\"}i.icon.opera:before{content:\\\"\\\\f26a\\\"}i.icon.optin.monster:before{content:\\\"\\\\f23c\\\"}i.icon.osi:before{content:\\\"\\\\f41a\\\"}i.icon.outdent:before{content:\\\"\\\\f03b\\\"}i.icon.page4:before{content:\\\"\\\\f3d7\\\"}i.icon.pagelines:before{content:\\\"\\\\f18c\\\"}i.icon.paint.brush:before{content:\\\"\\\\f1fc\\\"}i.icon.palfed:before{content:\\\"\\\\f3d8\\\"}i.icon.pallet:before{content:\\\"\\\\f482\\\"}i.icon.paper.plane:before{content:\\\"\\\\f1d8\\\"}i.icon.paperclip:before{content:\\\"\\\\f0c6\\\"}i.icon.paragraph:before{content:\\\"\\\\f1dd\\\"}i.icon.paste:before{content:\\\"\\\\f0ea\\\"}i.icon.patreon:before{content:\\\"\\\\f3d9\\\"}i.icon.pause:before{content:\\\"\\\\f04c\\\"}i.icon.pause.circle:before{content:\\\"\\\\f28b\\\"}i.icon.paw:before{content:\\\"\\\\f1b0\\\"}i.icon.paypal:before{content:\\\"\\\\f1ed\\\"}i.icon.pen.square:before{content:\\\"\\\\f14b\\\"}i.icon.pencil.alternate:before{content:\\\"\\\\f303\\\"}i.icon.percent:before{content:\\\"\\\\f295\\\"}i.icon.periscope:before{content:\\\"\\\\f3da\\\"}i.icon.phabricator:before{content:\\\"\\\\f3db\\\"}i.icon.phoenix.framework:before{content:\\\"\\\\f3dc\\\"}i.icon.phone:before{content:\\\"\\\\f095\\\"}i.icon.phone.square:before{content:\\\"\\\\f098\\\"}i.icon.phone.volume:before{content:\\\"\\\\f2a0\\\"}i.icon.php:before{content:\\\"\\\\f457\\\"}i.icon.pied.piper:before{content:\\\"\\\\f2ae\\\"}i.icon.pied.piper.alternate:before{content:\\\"\\\\f1a8\\\"}i.icon.pied.piper.pp:before{content:\\\"\\\\f1a7\\\"}i.icon.pills:before{content:\\\"\\\\f484\\\"}i.icon.pinterest:before{content:\\\"\\\\f0d2\\\"}i.icon.pinterest.p:before{content:\\\"\\\\f231\\\"}i.icon.pinterest.square:before{content:\\\"\\\\f0d3\\\"}i.icon.plane:before{content:\\\"\\\\f072\\\"}i.icon.play:before{content:\\\"\\\\f04b\\\"}i.icon.play.circle:before{content:\\\"\\\\f144\\\"}i.icon.playstation:before{content:\\\"\\\\f3df\\\"}i.icon.plug:before{content:\\\"\\\\f1e6\\\"}i.icon.plus:before{content:\\\"\\\\f067\\\"}i.icon.plus.circle:before{content:\\\"\\\\f055\\\"}i.icon.plus.square:before{content:\\\"\\\\f0fe\\\"}i.icon.podcast:before{content:\\\"\\\\f2ce\\\"}i.icon.pound.sign:before{content:\\\"\\\\f154\\\"}i.icon.power.off:before{content:\\\"\\\\f011\\\"}i.icon.print:before{content:\\\"\\\\f02f\\\"}i.icon.product.hunt:before{content:\\\"\\\\f288\\\"}i.icon.pushed:before{content:\\\"\\\\f3e1\\\"}i.icon.puzzle.piece:before{content:\\\"\\\\f12e\\\"}i.icon.python:before{content:\\\"\\\\f3e2\\\"}i.icon.qq:before{content:\\\"\\\\f1d6\\\"}i.icon.qrcode:before{content:\\\"\\\\f029\\\"}i.icon.question:before{content:\\\"\\\\f128\\\"}i.icon.question.circle:before{content:\\\"\\\\f059\\\"}i.icon.quidditch:before{content:\\\"\\\\f458\\\"}i.icon.quinscape:before{content:\\\"\\\\f459\\\"}i.icon.quora:before{content:\\\"\\\\f2c4\\\"}i.icon.quote.left:before{content:\\\"\\\\f10d\\\"}i.icon.quote.right:before{content:\\\"\\\\f10e\\\"}i.icon.random:before{content:\\\"\\\\f074\\\"}i.icon.ravelry:before{content:\\\"\\\\f2d9\\\"}i.icon.react:before{content:\\\"\\\\f41b\\\"}i.icon.rebel:before{content:\\\"\\\\f1d0\\\"}i.icon.recycle:before{content:\\\"\\\\f1b8\\\"}i.icon.redriver:before{content:\\\"\\\\f3e3\\\"}i.icon.reddit:before{content:\\\"\\\\f1a1\\\"}i.icon.reddit.alien:before{content:\\\"\\\\f281\\\"}i.icon.reddit.square:before{content:\\\"\\\\f1a2\\\"}i.icon.redo:before{content:\\\"\\\\f01e\\\"}i.icon.redo.alternate:before{content:\\\"\\\\f2f9\\\"}i.icon.registered:before{content:\\\"\\\\f25d\\\"}i.icon.rendact:before{content:\\\"\\\\f3e4\\\"}i.icon.renren:before{content:\\\"\\\\f18b\\\"}i.icon.reply:before{content:\\\"\\\\f3e5\\\"}i.icon.reply.all:before{content:\\\"\\\\f122\\\"}i.icon.replyd:before{content:\\\"\\\\f3e6\\\"}i.icon.resolving:before{content:\\\"\\\\f3e7\\\"}i.icon.retweet:before{content:\\\"\\\\f079\\\"}i.icon.road:before{content:\\\"\\\\f018\\\"}i.icon.rocket:before{content:\\\"\\\\f135\\\"}i.icon.rocketchat:before{content:\\\"\\\\f3e8\\\"}i.icon.rockrms:before{content:\\\"\\\\f3e9\\\"}i.icon.rss:before{content:\\\"\\\\f09e\\\"}i.icon.rss.square:before{content:\\\"\\\\f143\\\"}i.icon.ruble.sign:before{content:\\\"\\\\f158\\\"}i.icon.rupee.sign:before{content:\\\"\\\\f156\\\"}i.icon.safari:before{content:\\\"\\\\f267\\\"}i.icon.sass:before{content:\\\"\\\\f41e\\\"}i.icon.save:before{content:\\\"\\\\f0c7\\\"}i.icon.schlix:before{content:\\\"\\\\f3ea\\\"}i.icon.scribd:before{content:\\\"\\\\f28a\\\"}i.icon.search:before{content:\\\"\\\\f002\\\"}i.icon.search.minus:before{content:\\\"\\\\f010\\\"}i.icon.search.plus:before{content:\\\"\\\\f00e\\\"}i.icon.searchengin:before{content:\\\"\\\\f3eb\\\"}i.icon.sellcast:before{content:\\\"\\\\f2da\\\"}i.icon.sellsy:before{content:\\\"\\\\f213\\\"}i.icon.server:before{content:\\\"\\\\f233\\\"}i.icon.servicestack:before{content:\\\"\\\\f3ec\\\"}i.icon.share:before{content:\\\"\\\\f064\\\"}i.icon.share.alternate:before{content:\\\"\\\\f1e0\\\"}i.icon.share.alternate.square:before{content:\\\"\\\\f1e1\\\"}i.icon.share.square:before{content:\\\"\\\\f14d\\\"}i.icon.shekel.sign:before{content:\\\"\\\\f20b\\\"}i.icon.shield.alternate:before{content:\\\"\\\\f3ed\\\"}i.icon.ship:before{content:\\\"\\\\f21a\\\"}i.icon.shipping.fast:before{content:\\\"\\\\f48b\\\"}i.icon.shirtsinbulk:before{content:\\\"\\\\f214\\\"}i.icon.shopping.bag:before{content:\\\"\\\\f290\\\"}i.icon.shopping.basket:before{content:\\\"\\\\f291\\\"}i.icon.shopping.cart:before{content:\\\"\\\\f07a\\\"}i.icon.shower:before{content:\\\"\\\\f2cc\\\"}i.icon.sign.language:before{content:\\\"\\\\f2a7\\\"}i.icon.signal:before{content:\\\"\\\\f012\\\"}i.icon.simplybuilt:before{content:\\\"\\\\f215\\\"}i.icon.sistrix:before{content:\\\"\\\\f3ee\\\"}i.icon.sitemap:before{content:\\\"\\\\f0e8\\\"}i.icon.skyatlas:before{content:\\\"\\\\f216\\\"}i.icon.skype:before{content:\\\"\\\\f17e\\\"}i.icon.slack:before{content:\\\"\\\\f198\\\"}i.icon.slack.hash:before{content:\\\"\\\\f3ef\\\"}i.icon.sliders.horizontal:before{content:\\\"\\\\f1de\\\"}i.icon.slideshare:before{content:\\\"\\\\f1e7\\\"}i.icon.smile:before{content:\\\"\\\\f118\\\"}i.icon.snapchat:before{content:\\\"\\\\f2ab\\\"}i.icon.snapchat.ghost:before{content:\\\"\\\\f2ac\\\"}i.icon.snapchat.square:before{content:\\\"\\\\f2ad\\\"}i.icon.snowflake:before{content:\\\"\\\\f2dc\\\"}i.icon.sort:before{content:\\\"\\\\f0dc\\\"}i.icon.sort.alphabet.down:before{content:\\\"\\\\f15d\\\"}i.icon.sort.alphabet.up:before{content:\\\"\\\\f15e\\\"}i.icon.sort.amount.down:before{content:\\\"\\\\f160\\\"}i.icon.sort.amount.up:before{content:\\\"\\\\f161\\\"}i.icon.sort.down:before{content:\\\"\\\\f0dd\\\"}i.icon.sort.numeric.down:before{content:\\\"\\\\f162\\\"}i.icon.sort.numeric.up:before{content:\\\"\\\\f163\\\"}i.icon.sort.up:before{content:\\\"\\\\f0de\\\"}i.icon.soundcloud:before{content:\\\"\\\\f1be\\\"}i.icon.space.shuttle:before{content:\\\"\\\\f197\\\"}i.icon.speakap:before{content:\\\"\\\\f3f3\\\"}i.icon.spinner:before{content:\\\"\\\\f110\\\"}i.icon.spotify:before{content:\\\"\\\\f1bc\\\"}i.icon.square:before{content:\\\"\\\\f0c8\\\"}i.icon.square.full:before{content:\\\"\\\\f45c\\\"}i.icon.stack.exchange:before{content:\\\"\\\\f18d\\\"}i.icon.stack.overflow:before{content:\\\"\\\\f16c\\\"}i.icon.star:before{content:\\\"\\\\f005\\\"}i.icon.star.half:before{content:\\\"\\\\f089\\\"}i.icon.staylinked:before{content:\\\"\\\\f3f5\\\"}i.icon.steam:before{content:\\\"\\\\f1b6\\\"}i.icon.steam.square:before{content:\\\"\\\\f1b7\\\"}i.icon.steam.symbol:before{content:\\\"\\\\f3f6\\\"}i.icon.step.backward:before{content:\\\"\\\\f048\\\"}i.icon.step.forward:before{content:\\\"\\\\f051\\\"}i.icon.stethoscope:before{content:\\\"\\\\f0f1\\\"}i.icon.sticker.mule:before{content:\\\"\\\\f3f7\\\"}i.icon.sticky.note:before{content:\\\"\\\\f249\\\"}i.icon.stop:before{content:\\\"\\\\f04d\\\"}i.icon.stop.circle:before{content:\\\"\\\\f28d\\\"}i.icon.stopwatch:before{content:\\\"\\\\f2f2\\\"}i.icon.strava:before{content:\\\"\\\\f428\\\"}i.icon.street.view:before{content:\\\"\\\\f21d\\\"}i.icon.strikethrough:before{content:\\\"\\\\f0cc\\\"}i.icon.stripe:before{content:\\\"\\\\f429\\\"}i.icon.stripe.s:before{content:\\\"\\\\f42a\\\"}i.icon.studiovinari:before{content:\\\"\\\\f3f8\\\"}i.icon.stumbleupon:before{content:\\\"\\\\f1a4\\\"}i.icon.stumbleupon.circle:before{content:\\\"\\\\f1a3\\\"}i.icon.subscript:before{content:\\\"\\\\f12c\\\"}i.icon.subway:before{content:\\\"\\\\f239\\\"}i.icon.suitcase:before{content:\\\"\\\\f0f2\\\"}i.icon.sun:before{content:\\\"\\\\f185\\\"}i.icon.superpowers:before{content:\\\"\\\\f2dd\\\"}i.icon.superscript:before{content:\\\"\\\\f12b\\\"}i.icon.supple:before{content:\\\"\\\\f3f9\\\"}i.icon.sync:before{content:\\\"\\\\f021\\\"}i.icon.sync.alternate:before{content:\\\"\\\\f2f1\\\"}i.icon.syringe:before{content:\\\"\\\\f48e\\\"}i.icon.table:before{content:\\\"\\\\f0ce\\\"}i.icon.table.tennis:before{content:\\\"\\\\f45d\\\"}i.icon.tablet:before{content:\\\"\\\\f10a\\\"}i.icon.tablet.alternate:before{content:\\\"\\\\f3fa\\\"}i.icon.tachometer.alternate:before{content:\\\"\\\\f3fd\\\"}i.icon.tag:before{content:\\\"\\\\f02b\\\"}i.icon.tags:before{content:\\\"\\\\f02c\\\"}i.icon.tasks:before{content:\\\"\\\\f0ae\\\"}i.icon.taxi:before{content:\\\"\\\\f1ba\\\"}i.icon.telegram:before{content:\\\"\\\\f2c6\\\"}i.icon.telegram.plane:before{content:\\\"\\\\f3fe\\\"}i.icon.tencent.weibo:before{content:\\\"\\\\f1d5\\\"}i.icon.terminal:before{content:\\\"\\\\f120\\\"}i.icon.text.height:before{content:\\\"\\\\f034\\\"}i.icon.text.width:before{content:\\\"\\\\f035\\\"}i.icon.th:before{content:\\\"\\\\f00a\\\"}i.icon.th.large:before{content:\\\"\\\\f009\\\"}i.icon.th.list:before{content:\\\"\\\\f00b\\\"}i.icon.themeisle:before{content:\\\"\\\\f2b2\\\"}i.icon.thermometer:before{content:\\\"\\\\f491\\\"}i.icon.thermometer.empty:before{content:\\\"\\\\f2cb\\\"}i.icon.thermometer.full:before{content:\\\"\\\\f2c7\\\"}i.icon.thermometer.half:before{content:\\\"\\\\f2c9\\\"}i.icon.thermometer.quarter:before{content:\\\"\\\\f2ca\\\"}i.icon.thermometer.three.quarters:before{content:\\\"\\\\f2c8\\\"}i.icon.thumbs.down:before{content:\\\"\\\\f165\\\"}i.icon.thumbs.up:before{content:\\\"\\\\f164\\\"}i.icon.thumbtack:before{content:\\\"\\\\f08d\\\"}i.icon.ticket.alternate:before{content:\\\"\\\\f3ff\\\"}i.icon.times:before{content:\\\"\\\\f00d\\\"}i.icon.times.circle:before{content:\\\"\\\\f057\\\"}i.icon.tint:before{content:\\\"\\\\f043\\\"}i.icon.toggle.off:before{content:\\\"\\\\f204\\\"}i.icon.toggle.on:before{content:\\\"\\\\f205\\\"}i.icon.trademark:before{content:\\\"\\\\f25c\\\"}i.icon.train:before{content:\\\"\\\\f238\\\"}i.icon.transgender:before{content:\\\"\\\\f224\\\"}i.icon.transgender.alternate:before{content:\\\"\\\\f225\\\"}i.icon.trash:before{content:\\\"\\\\f1f8\\\"}i.icon.trash.alternate:before{content:\\\"\\\\f2ed\\\"}i.icon.tree:before{content:\\\"\\\\f1bb\\\"}i.icon.trello:before{content:\\\"\\\\f181\\\"}i.icon.tripadvisor:before{content:\\\"\\\\f262\\\"}i.icon.trophy:before{content:\\\"\\\\f091\\\"}i.icon.truck:before{content:\\\"\\\\f0d1\\\"}i.icon.tty:before{content:\\\"\\\\f1e4\\\"}i.icon.tumblr:before{content:\\\"\\\\f173\\\"}i.icon.tumblr.square:before{content:\\\"\\\\f174\\\"}i.icon.tv:before{content:\\\"\\\\f26c\\\"}i.icon.twitch:before{content:\\\"\\\\f1e8\\\"}i.icon.twitter:before{content:\\\"\\\\f099\\\"}i.icon.twitter.square:before{content:\\\"\\\\f081\\\"}i.icon.typo3:before{content:\\\"\\\\f42b\\\"}i.icon.uber:before{content:\\\"\\\\f402\\\"}i.icon.uikit:before{content:\\\"\\\\f403\\\"}i.icon.umbrella:before{content:\\\"\\\\f0e9\\\"}i.icon.underline:before{content:\\\"\\\\f0cd\\\"}i.icon.undo:before{content:\\\"\\\\f0e2\\\"}i.icon.undo.alternate:before{content:\\\"\\\\f2ea\\\"}i.icon.uniregistry:before{content:\\\"\\\\f404\\\"}i.icon.universal.access:before{content:\\\"\\\\f29a\\\"}i.icon.university:before{content:\\\"\\\\f19c\\\"}i.icon.unlink:before{content:\\\"\\\\f127\\\"}i.icon.unlock:before{content:\\\"\\\\f09c\\\"}i.icon.unlock.alternate:before{content:\\\"\\\\f13e\\\"}i.icon.untappd:before{content:\\\"\\\\f405\\\"}i.icon.upload:before{content:\\\"\\\\f093\\\"}i.icon.usb:before{content:\\\"\\\\f287\\\"}i.icon.user:before{content:\\\"\\\\f007\\\"}i.icon.user.circle:before{content:\\\"\\\\f2bd\\\"}i.icon.user.md:before{content:\\\"\\\\f0f0\\\"}i.icon.user.plus:before{content:\\\"\\\\f234\\\"}i.icon.user.secret:before{content:\\\"\\\\f21b\\\"}i.icon.user.times:before{content:\\\"\\\\f235\\\"}i.icon.users:before{content:\\\"\\\\f0c0\\\"}i.icon.ussunnah:before{content:\\\"\\\\f407\\\"}i.icon.utensil.spoon:before{content:\\\"\\\\f2e5\\\"}i.icon.utensils:before{content:\\\"\\\\f2e7\\\"}i.icon.vaadin:before{content:\\\"\\\\f408\\\"}i.icon.venus:before{content:\\\"\\\\f221\\\"}i.icon.venus.double:before{content:\\\"\\\\f226\\\"}i.icon.venus.mars:before{content:\\\"\\\\f228\\\"}i.icon.viacoin:before{content:\\\"\\\\f237\\\"}i.icon.viadeo:before{content:\\\"\\\\f2a9\\\"}i.icon.viadeo.square:before{content:\\\"\\\\f2aa\\\"}i.icon.viber:before{content:\\\"\\\\f409\\\"}i.icon.video:before{content:\\\"\\\\f03d\\\"}i.icon.vimeo:before{content:\\\"\\\\f40a\\\"}i.icon.vimeo.square:before{content:\\\"\\\\f194\\\"}i.icon.vimeo.v:before{content:\\\"\\\\f27d\\\"}i.icon.vine:before{content:\\\"\\\\f1ca\\\"}i.icon.vk:before{content:\\\"\\\\f189\\\"}i.icon.vnv:before{content:\\\"\\\\f40b\\\"}i.icon.volleyball.ball:before{content:\\\"\\\\f45f\\\"}i.icon.volume.down:before{content:\\\"\\\\f027\\\"}i.icon.volume.off:before{content:\\\"\\\\f026\\\"}i.icon.volume.up:before{content:\\\"\\\\f028\\\"}i.icon.vuejs:before{content:\\\"\\\\f41f\\\"}i.icon.warehouse:before{content:\\\"\\\\f494\\\"}i.icon.weibo:before{content:\\\"\\\\f18a\\\"}i.icon.weight:before{content:\\\"\\\\f496\\\"}i.icon.weixin:before{content:\\\"\\\\f1d7\\\"}i.icon.whatsapp:before{content:\\\"\\\\f232\\\"}i.icon.whatsapp.square:before{content:\\\"\\\\f40c\\\"}i.icon.wheelchair:before{content:\\\"\\\\f193\\\"}i.icon.whmcs:before{content:\\\"\\\\f40d\\\"}i.icon.wifi:before{content:\\\"\\\\f1eb\\\"}i.icon.wikipedia.w:before{content:\\\"\\\\f266\\\"}i.icon.window.close:before{content:\\\"\\\\f410\\\"}i.icon.window.maximize:before{content:\\\"\\\\f2d0\\\"}i.icon.window.minimize:before{content:\\\"\\\\f2d1\\\"}i.icon.window.restore:before{content:\\\"\\\\f2d2\\\"}i.icon.windows:before{content:\\\"\\\\f17a\\\"}i.icon.won.sign:before{content:\\\"\\\\f159\\\"}i.icon.wordpress:before{content:\\\"\\\\f19a\\\"}i.icon.wordpress.simple:before{content:\\\"\\\\f411\\\"}i.icon.wpbeginner:before{content:\\\"\\\\f297\\\"}i.icon.wpexplorer:before{content:\\\"\\\\f2de\\\"}i.icon.wpforms:before{content:\\\"\\\\f298\\\"}i.icon.wrench:before{content:\\\"\\\\f0ad\\\"}i.icon.xbox:before{content:\\\"\\\\f412\\\"}i.icon.xing:before{content:\\\"\\\\f168\\\"}i.icon.xing.square:before{content:\\\"\\\\f169\\\"}i.icon.y.combinator:before{content:\\\"\\\\f23b\\\"}i.icon.yahoo:before{content:\\\"\\\\f19e\\\"}i.icon.yandex:before{content:\\\"\\\\f413\\\"}i.icon.yandex.international:before{content:\\\"\\\\f414\\\"}i.icon.yelp:before{content:\\\"\\\\f1e9\\\"}i.icon.yen.sign:before{content:\\\"\\\\f157\\\"}i.icon.yoast:before{content:\\\"\\\\f2b1\\\"}i.icon.youtube:before{content:\\\"\\\\f167\\\"}i.icon.youtube.square:before{content:\\\"\\\\f431\\\"}i.icon.chess.rock:before{content:\\\"\\\\f447\\\"}i.icon.ordered.list:before{content:\\\"\\\\f0cb\\\"}i.icon.unordered.list:before{content:\\\"\\\\f0ca\\\"}i.icon.user.doctor:before{content:\\\"\\\\f0f0\\\"}i.icon.shield:before{content:\\\"\\\\f3ed\\\"}i.icon.puzzle:before{content:\\\"\\\\f12e\\\"}i.icon.credit.card.amazon.pay:before{content:\\\"\\\\f42d\\\"}i.icon.credit.card.american.express:before{content:\\\"\\\\f1f3\\\"}i.icon.credit.card.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.credit.card.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.credit.card.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.credit.card.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.credit.card.paypal:before{content:\\\"\\\\f1f4\\\"}i.icon.credit.card.stripe:before{content:\\\"\\\\f1f5\\\"}i.icon.credit.card.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.add.circle:before{content:\\\"\\\\f055\\\"}i.icon.add.square:before{content:\\\"\\\\f0fe\\\"}i.icon.add.to.calendar:before{content:\\\"\\\\f271\\\"}i.icon.add.to.cart:before{content:\\\"\\\\f217\\\"}i.icon.add.user:before{content:\\\"\\\\f234\\\"}i.icon.add:before{content:\\\"\\\\f067\\\"}i.icon.alarm.mute:before{content:\\\"\\\\f1f6\\\"}i.icon.alarm:before{content:\\\"\\\\f0f3\\\"}i.icon.ald:before{content:\\\"\\\\f2a2\\\"}i.icon.als:before{content:\\\"\\\\f2a2\\\"}i.icon.american.express.card:before{content:\\\"\\\\f1f3\\\"}i.icon.american.express:before{content:\\\"\\\\f1f3\\\"}i.icon.amex:before{content:\\\"\\\\f1f3\\\"}i.icon.announcement:before{content:\\\"\\\\f0a1\\\"}i.icon.area.chart:before{content:\\\"\\\\f1fe\\\"}i.icon.area.graph:before{content:\\\"\\\\f1fe\\\"}i.icon.arrow.down.cart:before{content:\\\"\\\\f218\\\"}i.icon.asexual:before{content:\\\"\\\\f22d\\\"}i.icon.asl.interpreting:before{content:\\\"\\\\f2a3\\\"}i.icon.asl:before{content:\\\"\\\\f2a3\\\"}i.icon.assistive.listening.devices:before{content:\\\"\\\\f2a2\\\"}i.icon.attach:before{content:\\\"\\\\f0c6\\\"}i.icon.attention:before{content:\\\"\\\\f06a\\\"}i.icon.balance:before{content:\\\"\\\\f24e\\\"}i.icon.bar:before{content:\\\"\\\\f0fc\\\"}i.icon.bathtub:before{content:\\\"\\\\f2cd\\\"}i.icon.battery.four:before{content:\\\"\\\\f240\\\"}i.icon.battery.high:before{content:\\\"\\\\f241\\\"}i.icon.battery.low:before{content:\\\"\\\\f243\\\"}i.icon.battery.medium:before{content:\\\"\\\\f242\\\"}i.icon.battery.one:before{content:\\\"\\\\f243\\\"}i.icon.battery.three:before{content:\\\"\\\\f241\\\"}i.icon.battery.two:before{content:\\\"\\\\f242\\\"}i.icon.battery.zero:before{content:\\\"\\\\f244\\\"}i.icon.birthday:before{content:\\\"\\\\f1fd\\\"}i.icon.block.layout:before{content:\\\"\\\\f009\\\"}i.icon.bluetooth.alternative:before{content:\\\"\\\\f294\\\"}i.icon.broken.chain:before{content:\\\"\\\\f127\\\"}i.icon.browser:before{content:\\\"\\\\f022\\\"}i.icon.call.square:before{content:\\\"\\\\f098\\\"}i.icon.call:before{content:\\\"\\\\f095\\\"}i.icon.cancel:before{content:\\\"\\\\f00d\\\"}i.icon.cart:before{content:\\\"\\\\f07a\\\"}i.icon.cc:before{content:\\\"\\\\f20a\\\"}i.icon.chain:before{content:\\\"\\\\f0c1\\\"}i.icon.chat:before{content:\\\"\\\\f075\\\"}i.icon.checked.calendar:before{content:\\\"\\\\f274\\\"}i.icon.checkmark:before{content:\\\"\\\\f00c\\\"}i.icon.circle.notched:before{content:\\\"\\\\f1ce\\\"}i.icon.close:before{content:\\\"\\\\f00d\\\"}i.icon.cny:before{content:\\\"\\\\f157\\\"}i.icon.cocktail:before{content:\\\"\\\\f000\\\"}i.icon.commenting:before{content:\\\"\\\\f27a\\\"}i.icon.computer:before{content:\\\"\\\\f108\\\"}i.icon.configure:before{content:\\\"\\\\f0ad\\\"}i.icon.content:before{content:\\\"\\\\f0c9\\\"}i.icon.deafness:before{content:\\\"\\\\f2a4\\\"}i.icon.delete.calendar:before{content:\\\"\\\\f273\\\"}i.icon.delete:before{content:\\\"\\\\f00d\\\"}i.icon.detective:before{content:\\\"\\\\f21b\\\"}i.icon.diners.club.card:before{content:\\\"\\\\f24c\\\"}i.icon.diners.club:before{content:\\\"\\\\f24c\\\"}i.icon.discover.card:before{content:\\\"\\\\f1f2\\\"}i.icon.discover:before{content:\\\"\\\\f1f2\\\"}i.icon.discussions:before{content:\\\"\\\\f086\\\"}i.icon.doctor:before{content:\\\"\\\\f0f0\\\"}i.icon.dollar:before{content:\\\"\\\\f155\\\"}i.icon.dont:before{content:\\\"\\\\f05e\\\"}i.icon.dribble:before{content:\\\"\\\\f17d\\\"}i.icon.drivers.license:before{content:\\\"\\\\f2c2\\\"}i.icon.dropdown:before{content:\\\"\\\\f0d7\\\"}i.icon.eercast:before{content:\\\"\\\\f2da\\\"}i.icon.emergency:before{content:\\\"\\\\f0f9\\\"}i.icon.envira.gallery:before{content:\\\"\\\\f299\\\"}i.icon.erase:before{content:\\\"\\\\f12d\\\"}i.icon.eur:before{content:\\\"\\\\f153\\\"}i.icon.euro:before{content:\\\"\\\\f153\\\"}i.icon.eyedropper:before{content:\\\"\\\\f1fb\\\"}i.icon.fa:before{content:\\\"\\\\f2b4\\\"}i.icon.factory:before{content:\\\"\\\\f275\\\"}i.icon.favorite:before{content:\\\"\\\\f005\\\"}i.icon.feed:before{content:\\\"\\\\f09e\\\"}i.icon.female.homosexual:before{content:\\\"\\\\f226\\\"}i.icon.file.text:before{content:\\\"\\\\f15c\\\"}i.icon.find:before{content:\\\"\\\\f1e5\\\"}i.icon.first.aid:before{content:\\\"\\\\f0fa\\\"}i.icon.five.hundred.pixels:before{content:\\\"\\\\f26e\\\"}i.icon.fork:before{content:\\\"\\\\f126\\\"}i.icon.game:before{content:\\\"\\\\f11b\\\"}i.icon.gay:before{content:\\\"\\\\f227\\\"}i.icon.gbp:before{content:\\\"\\\\f154\\\"}i.icon.gittip:before{content:\\\"\\\\f184\\\"}i.icon.google.plus.circle:before{content:\\\"\\\\f2b3\\\"}i.icon.google.plus.official:before{content:\\\"\\\\f2b3\\\"}i.icon.grab:before{content:\\\"\\\\f255\\\"}i.icon.graduation:before{content:\\\"\\\\f19d\\\"}i.icon.grid.layout:before{content:\\\"\\\\f00a\\\"}i.icon.group:before{content:\\\"\\\\f0c0\\\"}i.icon.h:before{content:\\\"\\\\f0fd\\\"}i.icon.hand.victory:before{content:\\\"\\\\f25b\\\"}i.icon.handicap:before{content:\\\"\\\\f193\\\"}i.icon.hard.of.hearing:before{content:\\\"\\\\f2a4\\\"}i.icon.header:before{content:\\\"\\\\f1dc\\\"}i.icon.help.circle:before{content:\\\"\\\\f059\\\"}i.icon.help:before{content:\\\"\\\\f128\\\"}i.icon.heterosexual:before{content:\\\"\\\\f228\\\"}i.icon.hide:before{content:\\\"\\\\f070\\\"}i.icon.hotel:before{content:\\\"\\\\f236\\\"}i.icon.hourglass.four:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.full:before{content:\\\"\\\\f254\\\"}i.icon.hourglass.one:before{content:\\\"\\\\f251\\\"}i.icon.hourglass.three:before{content:\\\"\\\\f253\\\"}i.icon.hourglass.two:before{content:\\\"\\\\f252\\\"}i.icon.idea:before{content:\\\"\\\\f0eb\\\"}i.icon.ils:before{content:\\\"\\\\f20b\\\"}i.icon.in-cart:before{content:\\\"\\\\f218\\\"}i.icon.inr:before{content:\\\"\\\\f156\\\"}i.icon.intergender:before{content:\\\"\\\\f224\\\"}i.icon.intersex:before{content:\\\"\\\\f224\\\"}i.icon.japan.credit.bureau.card:before{content:\\\"\\\\f24b\\\"}i.icon.japan.credit.bureau:before{content:\\\"\\\\f24b\\\"}i.icon.jcb:before{content:\\\"\\\\f24b\\\"}i.icon.jpy:before{content:\\\"\\\\f157\\\"}i.icon.krw:before{content:\\\"\\\\f159\\\"}i.icon.lab:before{content:\\\"\\\\f0c3\\\"}i.icon.law:before{content:\\\"\\\\f24e\\\"}i.icon.legal:before{content:\\\"\\\\f0e3\\\"}i.icon.lesbian:before{content:\\\"\\\\f226\\\"}i.icon.lightning:before{content:\\\"\\\\f0e7\\\"}i.icon.like:before{content:\\\"\\\\f004\\\"}i.icon.line.graph:before{content:\\\"\\\\f201\\\"}i.icon.linkedin.square:before{content:\\\"\\\\f08c\\\"}i.icon.linkify:before{content:\\\"\\\\f0c1\\\"}i.icon.lira:before{content:\\\"\\\\f195\\\"}i.icon.list.layout:before{content:\\\"\\\\f00b\\\"}i.icon.magnify:before{content:\\\"\\\\f00e\\\"}i.icon.mail.forward:before{content:\\\"\\\\f064\\\"}i.icon.mail.square:before{content:\\\"\\\\f199\\\"}i.icon.mail:before{content:\\\"\\\\f0e0\\\"}i.icon.male.homosexual:before{content:\\\"\\\\f227\\\"}i.icon.man:before{content:\\\"\\\\f222\\\"}i.icon.marker:before{content:\\\"\\\\f041\\\"}i.icon.mars.alternate:before{content:\\\"\\\\f229\\\"}i.icon.mars.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.mars.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.mastercard.card:before{content:\\\"\\\\f1f1\\\"}i.icon.mastercard:before{content:\\\"\\\\f1f1\\\"}i.icon.microsoft.edge:before{content:\\\"\\\\f282\\\"}i.icon.military:before{content:\\\"\\\\f0fb\\\"}i.icon.ms.edge:before{content:\\\"\\\\f282\\\"}i.icon.mute:before{content:\\\"\\\\f131\\\"}i.icon.new.pied.piper:before{content:\\\"\\\\f2ae\\\"}i.icon.non.binary.transgender:before{content:\\\"\\\\f223\\\"}i.icon.numbered.list:before{content:\\\"\\\\f0cb\\\"}i.icon.optinmonster:before{content:\\\"\\\\f23c\\\"}i.icon.options:before{content:\\\"\\\\f1de\\\"}i.icon.other.gender.horizontal:before{content:\\\"\\\\f22b\\\"}i.icon.other.gender.vertical:before{content:\\\"\\\\f22a\\\"}i.icon.other.gender:before{content:\\\"\\\\f229\\\"}i.icon.payment:before{content:\\\"\\\\f09d\\\"}i.icon.paypal.card:before{content:\\\"\\\\f1f4\\\"}i.icon.pencil.square:before{content:\\\"\\\\f14b\\\"}i.icon.photo:before{content:\\\"\\\\f030\\\"}i.icon.picture:before{content:\\\"\\\\f03e\\\"}i.icon.pie.chart:before{content:\\\"\\\\f200\\\"}i.icon.pie.graph:before{content:\\\"\\\\f200\\\"}i.icon.pied.piper.hat:before{content:\\\"\\\\f2ae\\\"}i.icon.pin:before{content:\\\"\\\\f08d\\\"}i.icon.plus.cart:before{content:\\\"\\\\f217\\\"}i.icon.pocket:before{content:\\\"\\\\f265\\\"}i.icon.point:before{content:\\\"\\\\f041\\\"}i.icon.pointing.down:before{content:\\\"\\\\f0a7\\\"}i.icon.pointing.left:before{content:\\\"\\\\f0a5\\\"}i.icon.pointing.right:before{content:\\\"\\\\f0a4\\\"}i.icon.pointing.up:before{content:\\\"\\\\f0a6\\\"}i.icon.pound:before{content:\\\"\\\\f154\\\"}i.icon.power.cord:before{content:\\\"\\\\f1e6\\\"}i.icon.power:before{content:\\\"\\\\f011\\\"}i.icon.privacy:before{content:\\\"\\\\f084\\\"}i.icon.r.circle:before{content:\\\"\\\\f25d\\\"}i.icon.rain:before{content:\\\"\\\\f0e9\\\"}i.icon.record:before{content:\\\"\\\\f03d\\\"}i.icon.refresh:before{content:\\\"\\\\f021\\\"}i.icon.remove.circle:before{content:\\\"\\\\f057\\\"}i.icon.remove.from.calendar:before{content:\\\"\\\\f272\\\"}i.icon.remove.user:before{content:\\\"\\\\f235\\\"}i.icon.remove:before{content:\\\"\\\\f00d\\\"}i.icon.repeat:before{content:\\\"\\\\f01e\\\"}i.icon.rmb:before{content:\\\"\\\\f157\\\"}i.icon.rouble:before{content:\\\"\\\\f158\\\"}i.icon.rub:before{content:\\\"\\\\f158\\\"}i.icon.ruble:before{content:\\\"\\\\f158\\\"}i.icon.rupee:before{content:\\\"\\\\f156\\\"}i.icon.s15:before{content:\\\"\\\\f2cd\\\"}i.icon.selected.radio:before{content:\\\"\\\\f192\\\"}i.icon.send:before{content:\\\"\\\\f1d8\\\"}i.icon.setting:before{content:\\\"\\\\f013\\\"}i.icon.settings:before{content:\\\"\\\\f085\\\"}i.icon.shekel:before{content:\\\"\\\\f20b\\\"}i.icon.sheqel:before{content:\\\"\\\\f20b\\\"}i.icon.shipping:before{content:\\\"\\\\f0d1\\\"}i.icon.shop:before{content:\\\"\\\\f07a\\\"}i.icon.shuffle:before{content:\\\"\\\\f074\\\"}i.icon.shutdown:before{content:\\\"\\\\f011\\\"}i.icon.sidebar:before{content:\\\"\\\\f0c9\\\"}i.icon.signing:before{content:\\\"\\\\f2a7\\\"}i.icon.signup:before{content:\\\"\\\\f044\\\"}i.icon.sliders:before{content:\\\"\\\\f1de\\\"}i.icon.soccer:before{content:\\\"\\\\f1e3\\\"}i.icon.sort.alphabet.ascending:before{content:\\\"\\\\f15d\\\"}i.icon.sort.alphabet.descending:before{content:\\\"\\\\f15e\\\"}i.icon.sort.ascending:before{content:\\\"\\\\f0de\\\"}i.icon.sort.content.ascending:before{content:\\\"\\\\f160\\\"}i.icon.sort.content.descending:before{content:\\\"\\\\f161\\\"}i.icon.sort.descending:before{content:\\\"\\\\f0dd\\\"}i.icon.sort.numeric.ascending:before{content:\\\"\\\\f162\\\"}i.icon.sort.numeric.descending:before{content:\\\"\\\\f163\\\"}i.icon.sound:before{content:\\\"\\\\f025\\\"}i.icon.spy:before{content:\\\"\\\\f21b\\\"}i.icon.stripe.card:before{content:\\\"\\\\f1f5\\\"}i.icon.student:before{content:\\\"\\\\f19d\\\"}i.icon.talk:before{content:\\\"\\\\f27a\\\"}i.icon.target:before{content:\\\"\\\\f140\\\"}i.icon.teletype:before{content:\\\"\\\\f1e4\\\"}i.icon.television:before{content:\\\"\\\\f26c\\\"}i.icon.text.cursor:before{content:\\\"\\\\f246\\\"}i.icon.text.telephone:before{content:\\\"\\\\f1e4\\\"}i.icon.theme.isle:before{content:\\\"\\\\f2b2\\\"}i.icon.theme:before{content:\\\"\\\\f043\\\"}i.icon.thermometer:before{content:\\\"\\\\f2c7\\\"}i.icon.thumb.tack:before{content:\\\"\\\\f08d\\\"}i.icon.time:before{content:\\\"\\\\f017\\\"}i.icon.tm:before{content:\\\"\\\\f25c\\\"}i.icon.toggle.down:before{content:\\\"\\\\f150\\\"}i.icon.toggle.left:before{content:\\\"\\\\f191\\\"}i.icon.toggle.right:before{content:\\\"\\\\f152\\\"}i.icon.toggle.up:before{content:\\\"\\\\f151\\\"}i.icon.translate:before{content:\\\"\\\\f1ab\\\"}i.icon.travel:before{content:\\\"\\\\f0b1\\\"}i.icon.treatment:before{content:\\\"\\\\f0f1\\\"}i.icon.triangle.down:before{content:\\\"\\\\f0d7\\\"}i.icon.triangle.left:before{content:\\\"\\\\f0d9\\\"}i.icon.triangle.right:before{content:\\\"\\\\f0da\\\"}i.icon.triangle.up:before{content:\\\"\\\\f0d8\\\"}i.icon.try:before{content:\\\"\\\\f195\\\"}i.icon.unhide:before{content:\\\"\\\\f06e\\\"}i.icon.unlinkify:before{content:\\\"\\\\f127\\\"}i.icon.unmute:before{content:\\\"\\\\f130\\\"}i.icon.usd:before{content:\\\"\\\\f155\\\"}i.icon.user.cancel:before{content:\\\"\\\\f235\\\"}i.icon.user.close:before{content:\\\"\\\\f235\\\"}i.icon.user.delete:before{content:\\\"\\\\f235\\\"}i.icon.user.x:before{content:\\\"\\\\f235\\\"}i.icon.vcard:before{content:\\\"\\\\f2bb\\\"}i.icon.video.camera:before{content:\\\"\\\\f03d\\\"}i.icon.video.play:before{content:\\\"\\\\f144\\\"}i.icon.visa.card:before{content:\\\"\\\\f1f0\\\"}i.icon.visa:before{content:\\\"\\\\f1f0\\\"}i.icon.volume.control.phone:before{content:\\\"\\\\f2a0\\\"}i.icon.wait:before{content:\\\"\\\\f017\\\"}i.icon.warning.circle:before{content:\\\"\\\\f06a\\\"}i.icon.warning.sign:before{content:\\\"\\\\f071\\\"}i.icon.warning:before{content:\\\"\\\\f12a\\\"}i.icon.wechat:before{content:\\\"\\\\f1d7\\\"}i.icon.wi-fi:before{content:\\\"\\\\f1eb\\\"}i.icon.wikipedia:before{content:\\\"\\\\f266\\\"}i.icon.winner:before{content:\\\"\\\\f091\\\"}i.icon.wizard:before{content:\\\"\\\\f0d0\\\"}i.icon.woman:before{content:\\\"\\\\f221\\\"}i.icon.won:before{content:\\\"\\\\f159\\\"}i.icon.wordpress.beginner:before{content:\\\"\\\\f297\\\"}i.icon.wordpress.forms:before{content:\\\"\\\\f298\\\"}i.icon.world:before{content:\\\"\\\\f0ac\\\"}i.icon.write.square:before{content:\\\"\\\\f14b\\\"}i.icon.x:before{content:\\\"\\\\f00d\\\"}i.icon.yc:before{content:\\\"\\\\f23b\\\"}i.icon.ycombinator:before{content:\\\"\\\\f23b\\\"}i.icon.yen:before{content:\\\"\\\\f157\\\"}i.icon.zip:before{content:\\\"\\\\f187\\\"}i.icon.zoom-in:before{content:\\\"\\\\f00e\\\"}i.icon.zoom-out:before{content:\\\"\\\\f010\\\"}i.icon.zoom:before{content:\\\"\\\\f00e\\\"}i.icon.bitbucket.square:before{content:\\\"\\\\f171\\\"}i.icon.checkmark.box:before{content:\\\"\\\\f14a\\\"}i.icon.circle.thin:before{content:\\\"\\\\f111\\\"}i.icon.cloud.download:before{content:\\\"\\\\f381\\\"}i.icon.cloud.upload:before{content:\\\"\\\\f382\\\"}i.icon.compose:before{content:\\\"\\\\f303\\\"}i.icon.conversation:before{content:\\\"\\\\f086\\\"}i.icon.credit.card.alternative:before{content:\\\"\\\\f09d\\\"}i.icon.currency:before{content:\\\"\\\\f3d1\\\"}i.icon.dashboard:before{content:\\\"\\\\f3fd\\\"}i.icon.diamond:before{content:\\\"\\\\f3a5\\\"}i.icon.disk:before{content:\\\"\\\\f0a0\\\"}i.icon.exchange:before{content:\\\"\\\\f362\\\"}i.icon.external.share:before{content:\\\"\\\\f14d\\\"}i.icon.external.square:before{content:\\\"\\\\f360\\\"}i.icon.external:before{content:\\\"\\\\f35d\\\"}i.icon.facebook.official:before{content:\\\"\\\\f082\\\"}i.icon.food:before{content:\\\"\\\\f2e7\\\"}i.icon.hourglass.zero:before{content:\\\"\\\\f253\\\"}i.icon.level.down:before{content:\\\"\\\\f3be\\\"}i.icon.level.up:before{content:\\\"\\\\f3bf\\\"}i.icon.logout:before{content:\\\"\\\\f2f5\\\"}i.icon.meanpath:before{content:\\\"\\\\f0c8\\\"}i.icon.money:before{content:\\\"\\\\f3d1\\\"}i.icon.move:before{content:\\\"\\\\f0b2\\\"}i.icon.pencil:before{content:\\\"\\\\f303\\\"}i.icon.protect:before{content:\\\"\\\\f023\\\"}i.icon.radio:before{content:\\\"\\\\f192\\\"}i.icon.remove.bookmark:before{content:\\\"\\\\f02e\\\"}i.icon.resize.horizontal:before{content:\\\"\\\\f337\\\"}i.icon.resize.vertical:before{content:\\\"\\\\f338\\\"}i.icon.sign-in:before{content:\\\"\\\\f2f6\\\"}i.icon.sign-out:before{content:\\\"\\\\f2f5\\\"}i.icon.spoon:before{content:\\\"\\\\f2e5\\\"}i.icon.star.half.empty:before{content:\\\"\\\\f089\\\"}i.icon.star.half.full:before{content:\\\"\\\\f089\\\"}i.icon.ticket:before{content:\\\"\\\\f3ff\\\"}i.icon.times.rectangle:before{content:\\\"\\\\f410\\\"}i.icon.write:before{content:\\\"\\\\f303\\\"}i.icon.youtube.play:before{content:\\\"\\\\f167\\\"}@font-face{font-family:outline-icons;src:url(themes/default/assets/fonts/outline-icons.eot);src:url(themes/default/assets/fonts/outline-icons.eot?#iefix) format('embedded-opentype'),url(themes/default/assets/fonts/outline-icons.woff2) format('woff2'),url(themes/default/assets/fonts/outline-icons.woff) format('woff'),url(themes/default/assets/fonts/outline-icons.ttf) format('truetype'),url(themes/default/assets/fonts/outline-icons.svg#icons) format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon.outline{font-family:outline-icons}i.icon.address.book.outline:before{content:\\\"\\\\f2b9\\\"}i.icon.address.card.outline:before{content:\\\"\\\\f2bb\\\"}i.icon.arrow.alternate.circle.down.outline:before{content:\\\"\\\\f358\\\"}i.icon.arrow.alternate.circle.left.outline:before{content:\\\"\\\\f359\\\"}i.icon.arrow.alternate.circle.right.outline:before{content:\\\"\\\\f35a\\\"}i.icon.arrow.alternate.circle.up.outline:before{content:\\\"\\\\f35b\\\"}i.icon.bell.outline:before{content:\\\"\\\\f0f3\\\"}i.icon.bell.slash.outline:before{content:\\\"\\\\f1f6\\\"}i.icon.bookmark.outline:before{content:\\\"\\\\f02e\\\"}i.icon.building.outline:before{content:\\\"\\\\f1ad\\\"}i.icon.calendar.outline:before{content:\\\"\\\\f133\\\"}i.icon.calendar.alternate.outline:before{content:\\\"\\\\f073\\\"}i.icon.calendar.check.outline:before{content:\\\"\\\\f274\\\"}i.icon.calendar.minus.outline:before{content:\\\"\\\\f272\\\"}i.icon.calendar.plus.outline:before{content:\\\"\\\\f271\\\"}i.icon.calendar.times.outline:before{content:\\\"\\\\f273\\\"}i.icon.caret.square.down.outline:before{content:\\\"\\\\f150\\\"}i.icon.caret.square.left.outline:before{content:\\\"\\\\f191\\\"}i.icon.caret.square.right.outline:before{content:\\\"\\\\f152\\\"}i.icon.caret.square.up.outline:before{content:\\\"\\\\f151\\\"}i.icon.chart.bar.outline:before{content:\\\"\\\\f080\\\"}i.icon.check.circle.outline:before{content:\\\"\\\\f058\\\"}i.icon.check.square.outline:before{content:\\\"\\\\f14a\\\"}i.icon.circle.outline:before{content:\\\"\\\\f111\\\"}i.icon.clipboard.outline:before{content:\\\"\\\\f328\\\"}i.icon.clock.outline:before{content:\\\"\\\\f017\\\"}i.icon.clone.outline:before{content:\\\"\\\\f24d\\\"}i.icon.closed.captioning.outline:before{content:\\\"\\\\f20a\\\"}i.icon.comment.outline:before{content:\\\"\\\\f075\\\"}i.icon.comment.alternate.outline:before{content:\\\"\\\\f27a\\\"}i.icon.comments.outline:before{content:\\\"\\\\f086\\\"}i.icon.compass.outline:before{content:\\\"\\\\f14e\\\"}i.icon.copy.outline:before{content:\\\"\\\\f0c5\\\"}i.icon.copyright.outline:before{content:\\\"\\\\f1f9\\\"}i.icon.credit.card.outline:before{content:\\\"\\\\f09d\\\"}i.icon.dot.circle.outline:before{content:\\\"\\\\f192\\\"}i.icon.edit.outline:before{content:\\\"\\\\f044\\\"}i.icon.envelope.outline:before{content:\\\"\\\\f0e0\\\"}i.icon.envelope.open.outline:before{content:\\\"\\\\f2b6\\\"}i.icon.eye.slash.outline:before{content:\\\"\\\\f070\\\"}i.icon.file.outline:before{content:\\\"\\\\f15b\\\"}i.icon.file.alternate.outline:before{content:\\\"\\\\f15c\\\"}i.icon.file.archive.outline:before{content:\\\"\\\\f1c6\\\"}i.icon.file.audio.outline:before{content:\\\"\\\\f1c7\\\"}i.icon.file.code.outline:before{content:\\\"\\\\f1c9\\\"}i.icon.file.excel.outline:before{content:\\\"\\\\f1c3\\\"}i.icon.file.image.outline:before{content:\\\"\\\\f1c5\\\"}i.icon.file.pdf.outline:before{content:\\\"\\\\f1c1\\\"}i.icon.file.powerpoint.outline:before{content:\\\"\\\\f1c4\\\"}i.icon.file.video.outline:before{content:\\\"\\\\f1c8\\\"}i.icon.file.word.outline:before{content:\\\"\\\\f1c2\\\"}i.icon.flag.outline:before{content:\\\"\\\\f024\\\"}i.icon.folder.outline:before{content:\\\"\\\\f07b\\\"}i.icon.folder.open.outline:before{content:\\\"\\\\f07c\\\"}i.icon.frown.outline:before{content:\\\"\\\\f119\\\"}i.icon.futbol.outline:before{content:\\\"\\\\f1e3\\\"}i.icon.gem.outline:before{content:\\\"\\\\f3a5\\\"}i.icon.hand.lizard.outline:before{content:\\\"\\\\f258\\\"}i.icon.hand.paper.outline:before{content:\\\"\\\\f256\\\"}i.icon.hand.peace.outline:before{content:\\\"\\\\f25b\\\"}i.icon.hand.point.down.outline:before{content:\\\"\\\\f0a7\\\"}i.icon.hand.point.left.outline:before{content:\\\"\\\\f0a5\\\"}i.icon.hand.point.right.outline:before{content:\\\"\\\\f0a4\\\"}i.icon.hand.point.up.outline:before{content:\\\"\\\\f0a6\\\"}i.icon.hand.pointer.outline:before{content:\\\"\\\\f25a\\\"}i.icon.hand.rock.outline:before{content:\\\"\\\\f255\\\"}i.icon.hand.scissors.outline:before{content:\\\"\\\\f257\\\"}i.icon.hand.spock.outline:before{content:\\\"\\\\f259\\\"}i.icon.handshake.outline:before{content:\\\"\\\\f2b5\\\"}i.icon.hdd.outline:before{content:\\\"\\\\f0a0\\\"}i.icon.heart.outline:before{content:\\\"\\\\f004\\\"}i.icon.hospital.outline:before{content:\\\"\\\\f0f8\\\"}i.icon.hourglass.outline:before{content:\\\"\\\\f254\\\"}i.icon.id.badge.outline:before{content:\\\"\\\\f2c1\\\"}i.icon.id.card.outline:before{content:\\\"\\\\f2c2\\\"}i.icon.image.outline:before{content:\\\"\\\\f03e\\\"}i.icon.images.outline:before{content:\\\"\\\\f302\\\"}i.icon.keyboard.outline:before{content:\\\"\\\\f11c\\\"}i.icon.lemon.outline:before{content:\\\"\\\\f094\\\"}i.icon.life.ring.outline:before{content:\\\"\\\\f1cd\\\"}i.icon.lightbulb.outline:before{content:\\\"\\\\f0eb\\\"}i.icon.list.alternate.outline:before{content:\\\"\\\\f022\\\"}i.icon.map.outline:before{content:\\\"\\\\f279\\\"}i.icon.meh.outline:before{content:\\\"\\\\f11a\\\"}i.icon.minus.square.outline:before{content:\\\"\\\\f146\\\"}i.icon.money.bill.alternate.outline:before{content:\\\"\\\\f3d1\\\"}i.icon.moon.outline:before{content:\\\"\\\\f186\\\"}i.icon.newspaper.outline:before{content:\\\"\\\\f1ea\\\"}i.icon.object.group.outline:before{content:\\\"\\\\f247\\\"}i.icon.object.ungroup.outline:before{content:\\\"\\\\f248\\\"}i.icon.paper.plane.outline:before{content:\\\"\\\\f1d8\\\"}i.icon.pause.circle.outline:before{content:\\\"\\\\f28b\\\"}i.icon.play.circle.outline:before{content:\\\"\\\\f144\\\"}i.icon.plus.square.outline:before{content:\\\"\\\\f0fe\\\"}i.icon.question.circle.outline:before{content:\\\"\\\\f059\\\"}i.icon.registered.outline:before{content:\\\"\\\\f25d\\\"}i.icon.save.outline:before{content:\\\"\\\\f0c7\\\"}i.icon.share.square.outline:before{content:\\\"\\\\f14d\\\"}i.icon.smile.outline:before{content:\\\"\\\\f118\\\"}i.icon.snowflake.outline:before{content:\\\"\\\\f2dc\\\"}i.icon.square.outline:before{content:\\\"\\\\f0c8\\\"}i.icon.star.outline:before{content:\\\"\\\\f005\\\"}i.icon.star.half.outline:before{content:\\\"\\\\f089\\\"}i.icon.sticky.note.outline:before{content:\\\"\\\\f249\\\"}i.icon.stop.circle.outline:before{content:\\\"\\\\f28d\\\"}i.icon.sun.outline:before{content:\\\"\\\\f185\\\"}i.icon.thumbs.down.outline:before{content:\\\"\\\\f165\\\"}i.icon.thumbs.up.outline:before{content:\\\"\\\\f164\\\"}i.icon.times.circle.outline:before{content:\\\"\\\\f057\\\"}i.icon.trash.alternate.outline:before{content:\\\"\\\\f2ed\\\"}i.icon.user.outline:before{content:\\\"\\\\f007\\\"}i.icon.user.circle.outline:before{content:\\\"\\\\f2bd\\\"}i.icon.window.close.outline:before{content:\\\"\\\\f410\\\"}i.icon.window.maximize.outline:before{content:\\\"\\\\f2d0\\\"}i.icon.window.minimize.outline:before{content:\\\"\\\\f2d1\\\"}i.icon.window.restore.outline:before{content:\\\"\\\\f2d2\\\"}i.icon.disk.outline:before{content:\\\"\\\\f0a0\\\"}i.icon.heart.empty,i.icon.star.empty{font-family:outline-icons}i.icon.heart.empty:before{content:\\\"\\\\f004\\\"}i.icon.star.empty:before{content:\\\"\\\\f089\\\"}@font-face{font-family:brand-icons;src:url(themes/default/assets/fonts/brand-icons.eot);src:url(themes/default/assets/fonts/brand-icons.eot?#iefix) format('embedded-opentype'),url(themes/default/assets/fonts/brand-icons.woff2) format('woff2'),url(themes/default/assets/fonts/brand-icons.woff) format('woff'),url(themes/default/assets/fonts/brand-icons.ttf) format('truetype'),url(themes/default/assets/fonts/brand-icons.svg#icons) format('svg');font-style:normal;font-weight:400;font-variant:normal;text-decoration:inherit;text-transform:none}i.icon.\\\\35 00px,i.icon.accessible.icon,i.icon.accusoft,i.icon.adn,i.icon.adversal,i.icon.affiliatetheme,i.icon.algolia,i.icon.amazon,i.icon.amazon.pay,i.icon.amilia,i.icon.android,i.icon.angellist,i.icon.angrycreative,i.icon.angular,i.icon.app.store,i.icon.app.store.ios,i.icon.apper,i.icon.apple,i.icon.apple.pay,i.icon.asymmetrik,i.icon.audible,i.icon.autoprefixer,i.icon.avianex,i.icon.aviato,i.icon.aws,i.icon.bandcamp,i.icon.behance,i.icon.behance.square,i.icon.bimobject,i.icon.bitbucket,i.icon.bitcoin,i.icon.bity,i.icon.black.tie,i.icon.blackberry,i.icon.blogger,i.icon.blogger.b,i.icon.bluetooth,i.icon.bluetooth.b,i.icon.btc,i.icon.buromobelexperte,i.icon.buysellads,i.icon.cc.amazon.pay,i.icon.cc.amex,i.icon.cc.apple.pay,i.icon.cc.diners.club,i.icon.cc.discover,i.icon.cc.jcb,i.icon.cc.mastercard,i.icon.cc.paypal,i.icon.cc.stripe,i.icon.cc.visa,i.icon.centercode,i.icon.chrome,i.icon.cloudscale,i.icon.cloudsmith,i.icon.cloudversify,i.icon.codepen,i.icon.codiepie,i.icon.connectdevelop,i.icon.contao,i.icon.cpanel,i.icon.creative.commons,i.icon.css3,i.icon.css3.alternate,i.icon.cuttlefish,i.icon.d.and.d,i.icon.dashcube,i.icon.delicious,i.icon.deploydog,i.icon.deskpro,i.icon.deviantart,i.icon.digg,i.icon.digital.ocean,i.icon.discord,i.icon.discourse,i.icon.dochub,i.icon.docker,i.icon.draft2digital,i.icon.dribbble,i.icon.dribbble.square,i.icon.dropbox,i.icon.drupal,i.icon.dyalog,i.icon.earlybirds,i.icon.edge,i.icon.elementor,i.icon.ember,i.icon.empire,i.icon.envira,i.icon.erlang,i.icon.ethereum,i.icon.etsy,i.icon.expeditedssl,i.icon.facebook,i.icon.facebook.f,i.icon.facebook.messenger,i.icon.facebook.square,i.icon.firefox,i.icon.first.order,i.icon.firstdraft,i.icon.flickr,i.icon.flipboard,i.icon.fly,i.icon.font.awesome,i.icon.font.awesome.alternate,i.icon.font.awesome.flag,i.icon.fonticons,i.icon.fonticons.fi,i.icon.fort.awesome,i.icon.fort.awesome.alternate,i.icon.forumbee,i.icon.foursquare,i.icon.free.code.camp,i.icon.freebsd,i.icon.get.pocket,i.icon.gg,i.icon.gg.circle,i.icon.git,i.icon.git.square,i.icon.github,i.icon.github.alternate,i.icon.github.square,i.icon.gitkraken,i.icon.gitlab,i.icon.gitter,i.icon.glide,i.icon.glide.g,i.icon.gofore,i.icon.goodreads,i.icon.goodreads.g,i.icon.google,i.icon.google.drive,i.icon.google.play,i.icon.google.plus,i.icon.google.plus.g,i.icon.google.plus.square,i.icon.google.wallet,i.icon.gratipay,i.icon.grav,i.icon.gripfire,i.icon.grunt,i.icon.gulp,i.icon.hacker.news,i.icon.hacker.news.square,i.icon.hips,i.icon.hire.a.helper,i.icon.hooli,i.icon.hotjar,i.icon.houzz,i.icon.html5,i.icon.hubspot,i.icon.imdb,i.icon.instagram,i.icon.internet.explorer,i.icon.ioxhost,i.icon.itunes,i.icon.itunes.note,i.icon.jenkins,i.icon.joget,i.icon.joomla,i.icon.js,i.icon.js.square,i.icon.jsfiddle,i.icon.keycdn,i.icon.kickstarter,i.icon.kickstarter.k,i.icon.korvue,i.icon.laravel,i.icon.lastfm,i.icon.lastfm.square,i.icon.leanpub,i.icon.less,i.icon.linechat,i.icon.linkedin,i.icon.linkedin.alternate,i.icon.linkedin.in,i.icon.linode,i.icon.linux,i.icon.lyft,i.icon.magento,i.icon.maxcdn,i.icon.medapps,i.icon.medium,i.icon.medium.m,i.icon.medrt,i.icon.meetup,i.icon.microsoft,i.icon.mix,i.icon.mixcloud,i.icon.mizuni,i.icon.modx,i.icon.monero,i.icon.napster,i.icon.nintendo.switch,i.icon.node,i.icon.node.js,i.icon.npm,i.icon.ns8,i.icon.nutritionix,i.icon.odnoklassniki,i.icon.odnoklassniki.square,i.icon.opencart,i.icon.openid,i.icon.opera,i.icon.optin.monster,i.icon.osi,i.icon.page4,i.icon.pagelines,i.icon.palfed,i.icon.patreon,i.icon.paypal,i.icon.periscope,i.icon.phabricator,i.icon.phoenix.framework,i.icon.php,i.icon.pied.piper,i.icon.pied.piper.alternate,i.icon.pied.piper.pp,i.icon.pinterest,i.icon.pinterest.p,i.icon.pinterest.square,i.icon.playstation,i.icon.product.hunt,i.icon.pushed,i.icon.python,i.icon.qq,i.icon.quinscape,i.icon.quora,i.icon.ravelry,i.icon.react,i.icon.rebel,i.icon.reddit,i.icon.reddit.alien,i.icon.reddit.square,i.icon.redriver,i.icon.rendact,i.icon.renren,i.icon.replyd,i.icon.resolving,i.icon.rocketchat,i.icon.rockrms,i.icon.safari,i.icon.sass,i.icon.schlix,i.icon.scribd,i.icon.searchengin,i.icon.sellcast,i.icon.sellsy,i.icon.servicestack,i.icon.shirtsinbulk,i.icon.simplybuilt,i.icon.sistrix,i.icon.skyatlas,i.icon.skype,i.icon.slack,i.icon.slack.hash,i.icon.slideshare,i.icon.snapchat,i.icon.snapchat.ghost,i.icon.snapchat.square,i.icon.soundcloud,i.icon.speakap,i.icon.spotify,i.icon.stack.exchange,i.icon.stack.overflow,i.icon.staylinked,i.icon.steam,i.icon.steam.square,i.icon.steam.symbol,i.icon.sticker.mule,i.icon.strava,i.icon.stripe,i.icon.stripe.s,i.icon.studiovinari,i.icon.stumbleupon,i.icon.stumbleupon.circle,i.icon.superpowers,i.icon.supple,i.icon.telegram,i.icon.telegram.plane,i.icon.tencent.weibo,i.icon.themeisle,i.icon.trello,i.icon.tripadvisor,i.icon.tumblr,i.icon.tumblr.square,i.icon.twitch,i.icon.twitter,i.icon.twitter.square,i.icon.typo3,i.icon.uber,i.icon.uikit,i.icon.uniregistry,i.icon.untappd,i.icon.usb,i.icon.ussunnah,i.icon.vaadin,i.icon.viacoin,i.icon.viadeo,i.icon.viadeo.square,i.icon.viber,i.icon.vimeo,i.icon.vimeo.square,i.icon.vimeo.v,i.icon.vine,i.icon.vk,i.icon.vnv,i.icon.vuejs,i.icon.wechat,i.icon.weibo,i.icon.weixin,i.icon.whatsapp,i.icon.whatsapp.square,i.icon.whmcs,i.icon.wikipedia.w,i.icon.windows,i.icon.wordpress,i.icon.wordpress.simple,i.icon.wpbeginner,i.icon.wpexplorer,i.icon.wpforms,i.icon.xbox,i.icon.xing,i.icon.xing.square,i.icon.y.combinator,i.icon.yahoo,i.icon.yandex,i.icon.yandex.international,i.icon.yelp,i.icon.yoast,i.icon.youtube,i.icon.youtube.square{font-family:brand-icons}/*!\\n * # Semantic UI 2.4.0 - Image\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.image{position:relative;display:inline-block;vertical-align:middle;max-width:100%;background-color:transparent}img.ui.image{display:block}.ui.image img,.ui.image svg{display:block;max-width:100%;height:auto}.ui.hidden.image,.ui.hidden.images{display:none}.ui.hidden.transition.image,.ui.hidden.transition.images{display:block;visibility:hidden}.ui.images>.hidden.transition{display:inline-block;visibility:hidden}.ui.disabled.image,.ui.disabled.images{cursor:default;opacity:.45}.ui.inline.image,.ui.inline.image img,.ui.inline.image svg{display:inline-block}.ui.top.aligned.image,.ui.top.aligned.image img,.ui.top.aligned.image svg,.ui.top.aligned.images .image{display:inline-block;vertical-align:top}.ui.middle.aligned.image,.ui.middle.aligned.image img,.ui.middle.aligned.image svg,.ui.middle.aligned.images .image{display:inline-block;vertical-align:middle}.ui.bottom.aligned.image,.ui.bottom.aligned.image img,.ui.bottom.aligned.image svg,.ui.bottom.aligned.images .image{display:inline-block;vertical-align:bottom}.ui.rounded.image,.ui.rounded.image>*,.ui.rounded.images .image,.ui.rounded.images .image>*{border-radius:.3125em}.ui.bordered.image img,.ui.bordered.image svg,.ui.bordered.images .image,.ui.bordered.images img,.ui.bordered.images svg,img.ui.bordered.image{border:1px solid rgba(0,0,0,.1)}.ui.circular.image,.ui.circular.images{overflow:hidden}.ui.circular.image,.ui.circular.image>*,.ui.circular.images .image,.ui.circular.images .image>*{border-radius:500rem}.ui.fluid.image,.ui.fluid.image img,.ui.fluid.image svg,.ui.fluid.images,.ui.fluid.images img,.ui.fluid.images svg{display:block;width:100%;height:auto}.ui.avatar.image,.ui.avatar.image img,.ui.avatar.image svg,.ui.avatar.images .image,.ui.avatar.images img,.ui.avatar.images svg{margin-right:.25em;display:inline-block;width:2em;height:2em;border-radius:500rem}.ui.spaced.image{display:inline-block!important;margin-left:.5em;margin-right:.5em}.ui[class*=\\\"left spaced\\\"].image{margin-left:.5em;margin-right:0}.ui[class*=\\\"right spaced\\\"].image{margin-left:0;margin-right:.5em}.ui.floated.image,.ui.floated.images{float:left;margin-right:1em;margin-bottom:1em}.ui.right.floated.image,.ui.right.floated.images{float:right;margin-right:0;margin-bottom:1em;margin-left:1em}.ui.floated.image:last-child,.ui.floated.images:last-child{margin-bottom:0}.ui.centered.image,.ui.centered.images{margin-left:auto;margin-right:auto}.ui.mini.image,.ui.mini.images .image,.ui.mini.images img,.ui.mini.images svg{width:35px;height:auto;font-size:.78571429rem}.ui.tiny.image,.ui.tiny.images .image,.ui.tiny.images img,.ui.tiny.images svg{width:80px;height:auto;font-size:.85714286rem}.ui.small.image,.ui.small.images .image,.ui.small.images img,.ui.small.images svg{width:150px;height:auto;font-size:.92857143rem}.ui.medium.image,.ui.medium.images .image,.ui.medium.images img,.ui.medium.images svg{width:300px;height:auto;font-size:1rem}.ui.large.image,.ui.large.images .image,.ui.large.images img,.ui.large.images svg{width:450px;height:auto;font-size:1.14285714rem}.ui.big.image,.ui.big.images .image,.ui.big.images img,.ui.big.images svg{width:600px;height:auto;font-size:1.28571429rem}.ui.huge.image,.ui.huge.images .image,.ui.huge.images img,.ui.huge.images svg{width:800px;height:auto;font-size:1.42857143rem}.ui.massive.image,.ui.massive.images .image,.ui.massive.images img,.ui.massive.images svg{width:960px;height:auto;font-size:1.71428571rem}.ui.images{font-size:0;margin:0 -.25rem 0}.ui.images .image,.ui.images>img,.ui.images>svg{display:inline-block;margin:0 .25rem .5rem}/*!\\n * # Semantic UI 2.4.0 - Input\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.input{position:relative;font-weight:400;font-style:normal;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;color:rgba(0,0,0,.87)}.ui.input>input{margin:0;max-width:100%;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);text-align:left;line-height:1.21428571em;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;padding:.67857143em 1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-transition:border-color .1s ease,-webkit-box-shadow .1s ease;transition:border-color .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,border-color .1s ease;transition:box-shadow .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;-webkit-box-shadow:none;box-shadow:none}.ui.input>input::-webkit-input-placeholder{color:rgba(191,191,191,.87)}.ui.input>input::-moz-placeholder{color:rgba(191,191,191,.87)}.ui.input>input:-ms-input-placeholder{color:rgba(191,191,191,.87)}.ui.disabled.input,.ui.input:not(.disabled) input[disabled]{opacity:.45}.ui.disabled.input>input,.ui.input:not(.disabled) input[disabled]{pointer-events:none}.ui.input.down input,.ui.input>input:active{border-color:rgba(0,0,0,.3);background:#fafafa;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}.ui.loading.loading.input>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.loading.input>i.icon:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.input.focus>input,.ui.input>input:focus{border-color:#85b7d9;background:#fff;color:rgba(0,0,0,.8);-webkit-box-shadow:none;box-shadow:none}.ui.input.focus>input::-webkit-input-placeholder,.ui.input>input:focus::-webkit-input-placeholder{color:rgba(115,115,115,.87)}.ui.input.focus>input::-moz-placeholder,.ui.input>input:focus::-moz-placeholder{color:rgba(115,115,115,.87)}.ui.input.focus>input:-ms-input-placeholder,.ui.input>input:focus:-ms-input-placeholder{color:rgba(115,115,115,.87)}.ui.input.error>input{background-color:#fff6f6;border-color:#e0b4b4;color:#9f3a38;-webkit-box-shadow:none;box-shadow:none}.ui.input.error>input::-webkit-input-placeholder{color:#e7bdbc}.ui.input.error>input::-moz-placeholder{color:#e7bdbc}.ui.input.error>input:-ms-input-placeholder{color:#e7bdbc!important}.ui.input.error>input:focus::-webkit-input-placeholder{color:#da9796}.ui.input.error>input:focus::-moz-placeholder{color:#da9796}.ui.input.error>input:focus:-ms-input-placeholder{color:#da9796!important}.ui.transparent.input>input{border-color:transparent!important;background-color:transparent!important;padding:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;border-radius:0!important}.ui.transparent.icon.input>i.icon{width:1.1em}.ui.transparent.icon.input>input{padding-left:0!important;padding-right:2em!important}.ui.transparent[class*=\\\"left icon\\\"].input>input{padding-left:2em!important;padding-right:0!important}.ui.transparent.inverted.input{color:#fff}.ui.transparent.inverted.input>input{color:inherit}.ui.transparent.inverted.input>input::-webkit-input-placeholder{color:rgba(255,255,255,.5)}.ui.transparent.inverted.input>input::-moz-placeholder{color:rgba(255,255,255,.5)}.ui.transparent.inverted.input>input:-ms-input-placeholder{color:rgba(255,255,255,.5)}.ui.icon.input>i.icon{cursor:default;position:absolute;line-height:1;text-align:center;top:0;right:0;margin:0;height:100%;width:2.67142857em;opacity:.5;border-radius:0 .28571429rem .28571429rem 0;-webkit-transition:opacity .3s ease;transition:opacity .3s ease}.ui.icon.input>i.icon:not(.link){pointer-events:none}.ui.icon.input>input{padding-right:2.67142857em!important}.ui.icon.input>i.icon:after,.ui.icon.input>i.icon:before{left:0;position:absolute;text-align:center;top:50%;width:100%;margin-top:-.5em}.ui.icon.input>i.link.icon{cursor:pointer}.ui.icon.input>i.circular.icon{top:.35em;right:.5em}.ui[class*=\\\"left icon\\\"].input>i.icon{right:auto;left:1px;border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"left icon\\\"].input>i.circular.icon{right:auto;left:.5em}.ui[class*=\\\"left icon\\\"].input>input{padding-left:2.67142857em!important;padding-right:1em!important}.ui.icon.input>input:focus~i.icon{opacity:1}.ui.labeled.input>.label{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;margin:0;font-size:1em}.ui.labeled.input>.label:not(.corner){padding-top:.78571429em;padding-bottom:.78571429em}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child+input{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:transparent}.ui.labeled.input:not([class*=\\\"corner labeled\\\"]) .label:first-child+input:focus{border-left-color:#85b7d9}.ui[class*=\\\"right labeled\\\"].input>input{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right-color:transparent!important}.ui[class*=\\\"right labeled\\\"].input>input+.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*=\\\"right labeled\\\"].input>input:focus{border-right-color:#85b7d9!important}.ui.labeled.input .corner.label{top:1px;right:1px;font-size:.64285714em;border-radius:0 .28571429rem 0 0}.ui[class*=\\\"corner labeled\\\"]:not([class*=\\\"left corner labeled\\\"]).labeled.input>input{padding-right:2.5em!important}.ui[class*=\\\"corner labeled\\\"].icon.input:not([class*=\\\"left corner labeled\\\"])>input{padding-right:3.25em!important}.ui[class*=\\\"corner labeled\\\"].icon.input:not([class*=\\\"left corner labeled\\\"])>.icon{margin-right:1.25em}.ui[class*=\\\"left corner labeled\\\"].labeled.input>input{padding-left:2.5em!important}.ui[class*=\\\"left corner labeled\\\"].icon.input>input{padding-left:3.25em!important}.ui[class*=\\\"left corner labeled\\\"].icon.input>.icon{margin-left:1.25em}.ui.input>.ui.corner.label{top:1px;right:1px}.ui.input>.ui.left.corner.label{right:auto;left:1px}.ui.action.input>.button,.ui.action.input>.buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto}.ui.action.input>.button,.ui.action.input>.buttons>.button{padding-top:.78571429em;padding-bottom:.78571429em;margin:0}.ui.action.input:not([class*=\\\"left action\\\"])>input{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right-color:transparent!important}.ui.action.input:not([class*=\\\"left action\\\"])>.button:not(:first-child),.ui.action.input:not([class*=\\\"left action\\\"])>.buttons:not(:first-child)>.button,.ui.action.input:not([class*=\\\"left action\\\"])>.dropdown:not(:first-child){border-radius:0}.ui.action.input:not([class*=\\\"left action\\\"])>.button:last-child,.ui.action.input:not([class*=\\\"left action\\\"])>.buttons:last-child>.button,.ui.action.input:not([class*=\\\"left action\\\"])>.dropdown:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.action.input:not([class*=\\\"left action\\\"])>input:focus{border-right-color:#85b7d9!important}.ui[class*=\\\"left action\\\"].input>input{border-top-left-radius:0!important;border-bottom-left-radius:0!important;border-left-color:transparent!important}.ui[class*=\\\"left action\\\"].input>.button,.ui[class*=\\\"left action\\\"].input>.buttons>.button,.ui[class*=\\\"left action\\\"].input>.dropdown{border-radius:0}.ui[class*=\\\"left action\\\"].input>.button:first-child,.ui[class*=\\\"left action\\\"].input>.buttons:first-child>.button,.ui[class*=\\\"left action\\\"].input>.dropdown:first-child{border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"left action\\\"].input>input:focus{border-left-color:#85b7d9!important}.ui.inverted.input>input{border:none}.ui.fluid.input{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.fluid.input>input{width:0!important}.ui.mini.input{font-size:.78571429em}.ui.small.input{font-size:.92857143em}.ui.input{font-size:1em}.ui.large.input{font-size:1.14285714em}.ui.big.input{font-size:1.28571429em}.ui.huge.input{font-size:1.42857143em}.ui.massive.input{font-size:1.71428571em}/*!\\n * # Semantic UI 2.4.0 - Label\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.label{display:inline-block;line-height:1;vertical-align:baseline;margin:0 .14285714em;background-color:#e8e8e8;background-image:none;padding:.5833em .833em;color:rgba(0,0,0,.6);text-transform:none;font-weight:700;border:0 solid transparent;border-radius:.28571429rem;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.label:first-child{margin-left:0}.ui.label:last-child{margin-right:0}a.ui.label{cursor:pointer}.ui.label>a{cursor:pointer;color:inherit;opacity:.5;-webkit-transition:.1s opacity ease;transition:.1s opacity ease}.ui.label>a:hover{opacity:1}.ui.label>img{width:auto!important;vertical-align:middle;height:2.1666em!important}.ui.label>.icon{width:auto;margin:0 .75em 0 0}.ui.label>.detail{display:inline-block;vertical-align:top;font-weight:700;margin-left:1em;opacity:.8}.ui.label>.detail .icon{margin:0 .25em 0 0}.ui.label>.close.icon,.ui.label>.delete.icon{cursor:pointer;margin-right:0;margin-left:.5em;font-size:.92857143em;opacity:.5;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.label>.delete.icon:hover{opacity:1}.ui.labels>.label{margin:0 .5em .5em 0}.ui.header>.ui.label{margin-top:-.29165em}.ui.attached.segment>.ui.top.left.attached.label,.ui.bottom.attached.segment>.ui.top.left.attached.label{border-top-left-radius:0}.ui.attached.segment>.ui.top.right.attached.label,.ui.bottom.attached.segment>.ui.top.right.attached.label{border-top-right-radius:0}.ui.top.attached.segment>.ui.bottom.left.attached.label{border-bottom-left-radius:0}.ui.top.attached.segment>.ui.bottom.right.attached.label{border-bottom-right-radius:0}.ui.top.attached.label+[class*=\\\"right floated\\\"]+*,.ui.top.attached.label:first-child+:not(.attached){margin-top:2rem!important}.ui.bottom.attached.label:first-child~:last-child:not(.attached){margin-top:0;margin-bottom:2rem!important}.ui.image.label{width:auto!important;margin-top:0;margin-bottom:0;max-width:9999px;vertical-align:baseline;text-transform:none;background:#e8e8e8;padding:.5833em .833em .5833em .5em;border-radius:.28571429rem;-webkit-box-shadow:none;box-shadow:none}.ui.image.label img{display:inline-block;vertical-align:top;height:2.1666em;margin:-.5833em .5em -.5833em -.5em;border-radius:.28571429rem 0 0 .28571429rem}.ui.image.label .detail{background:rgba(0,0,0,.1);margin:-.5833em -.833em -.5833em .5em;padding:.5833em .833em;border-radius:0 .28571429rem .28571429rem 0}.ui.tag.label,.ui.tag.labels .label{margin-left:1em;position:relative;padding-left:1.5em;padding-right:1.5em;border-radius:0 .28571429rem .28571429rem 0;-webkit-transition:none;transition:none}.ui.tag.label:before,.ui.tag.labels .label:before{position:absolute;-webkit-transform:translateY(-50%) translateX(50%) rotate(-45deg);transform:translateY(-50%) translateX(50%) rotate(-45deg);top:50%;right:100%;content:'';background-color:inherit;background-image:none;width:1.56em;height:1.56em;-webkit-transition:none;transition:none}.ui.tag.label:after,.ui.tag.labels .label:after{position:absolute;content:'';top:50%;left:-.25em;margin-top:-.25em;background-color:#fff!important;width:.5em;height:.5em;-webkit-box-shadow:0 -1px 1px 0 rgba(0,0,0,.3);box-shadow:0 -1px 1px 0 rgba(0,0,0,.3);border-radius:500rem}.ui.corner.label{position:absolute;top:0;right:0;margin:0;padding:0;text-align:center;border-color:#e8e8e8;width:4em;height:4em;z-index:1;-webkit-transition:border-color .1s ease;transition:border-color .1s ease}.ui.corner.label{background-color:transparent!important}.ui.corner.label:after{position:absolute;content:\\\"\\\";right:0;top:0;z-index:-1;width:0;height:0;background-color:transparent!important;border-top:0 solid transparent;border-right:4em solid transparent;border-bottom:4em solid transparent;border-left:0 solid transparent;border-right-color:inherit;-webkit-transition:border-color .1s ease;transition:border-color .1s ease}.ui.corner.label .icon{cursor:default;position:relative;top:.64285714em;left:.78571429em;font-size:1.14285714em;margin:0}.ui.left.corner.label,.ui.left.corner.label:after{right:auto;left:0}.ui.left.corner.label:after{border-top:4em solid transparent;border-right:4em solid transparent;border-bottom:0 solid transparent;border-left:0 solid transparent;border-top-color:inherit}.ui.left.corner.label .icon{left:-.78571429em}.ui.segment>.ui.corner.label{top:-1px;right:-1px}.ui.segment>.ui.left.corner.label{right:auto;left:-1px}.ui.ribbon.label{position:relative;margin:0;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;border-radius:0 .28571429rem .28571429rem 0;border-color:rgba(0,0,0,.15)}.ui.ribbon.label:after{position:absolute;content:'';top:100%;left:0;background-color:transparent!important;border-style:solid;border-width:0 1.2em 1.2em 0;border-color:transparent;border-right-color:inherit;width:0;height:0}.ui.ribbon.label{left:calc(-1rem - 1.2em);margin-right:-1.2em;padding-left:calc(1rem + 1.2em);padding-right:1.2em}.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + 1rem + 1.2em);padding-left:1.2em;padding-right:calc(1rem + 1.2em)}.ui[class*=\\\"right ribbon\\\"].label{text-align:left;-webkit-transform:translateX(-100%);transform:translateX(-100%);border-radius:.28571429rem 0 0 .28571429rem}.ui[class*=\\\"right ribbon\\\"].label:after{left:auto;right:0;border-style:solid;border-width:1.2em 1.2em 0 0;border-color:transparent;border-top-color:inherit}.ui.card .image>.ribbon.label,.ui.image>.ribbon.label{position:absolute;top:1rem}.ui.card .image>.ui.ribbon.label,.ui.image>.ui.ribbon.label{left:calc(.05rem - 1.2em)}.ui.card .image>.ui[class*=\\\"right ribbon\\\"].label,.ui.image>.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + -.05rem + 1.2em);padding-left:.833em}.ui.table td>.ui.ribbon.label{left:calc(-.78571429em - 1.2em)}.ui.table td>.ui[class*=\\\"right ribbon\\\"].label{left:calc(100% + .78571429em + 1.2em);padding-left:.833em}.ui.attached.label,.ui[class*=\\\"top attached\\\"].label{width:100%;position:absolute;margin:0;top:0;left:0;padding:.75em 1em;border-radius:.21428571rem .21428571rem 0 0}.ui[class*=\\\"bottom attached\\\"].label{top:auto;bottom:0;border-radius:0 0 .21428571rem .21428571rem}.ui[class*=\\\"top left attached\\\"].label{width:auto;margin-top:0!important;border-radius:.21428571rem 0 .28571429rem 0}.ui[class*=\\\"top right attached\\\"].label{width:auto;left:auto;right:0;border-radius:0 .21428571rem 0 .28571429rem}.ui[class*=\\\"bottom left attached\\\"].label{width:auto;top:auto;bottom:0;border-radius:0 .28571429rem 0 .21428571rem}.ui[class*=\\\"bottom right attached\\\"].label{top:auto;bottom:0;left:auto;right:0;width:auto;border-radius:.28571429rem 0 .21428571rem 0}.ui.label.disabled{opacity:.5}a.ui.label:hover,a.ui.labels .label:hover{background-color:#e0e0e0;border-color:#e0e0e0;background-image:none;color:rgba(0,0,0,.8)}.ui.labels a.label:hover:before,a.ui.label:hover:before{color:rgba(0,0,0,.8)}.ui.active.label{background-color:#d0d0d0;border-color:#d0d0d0;background-image:none;color:rgba(0,0,0,.95)}.ui.active.label:before{background-color:#d0d0d0;background-image:none;color:rgba(0,0,0,.95)}a.ui.active.label:hover,a.ui.labels .active.label:hover{background-color:#c8c8c8;border-color:#c8c8c8;background-image:none;color:rgba(0,0,0,.95)}.ui.labels a.active.label:ActiveHover:before,a.ui.active.label:ActiveHover:before{background-color:#c8c8c8;background-image:none;color:rgba(0,0,0,.95)}.ui.label.visible:not(.dropdown),.ui.labels.visible .label{display:inline-block!important}.ui.label.hidden,.ui.labels.hidden .label{display:none!important}.ui.red.label,.ui.red.labels .label{background-color:#db2828!important;border-color:#db2828!important;color:#fff!important}.ui.red.labels .label:hover,a.ui.red.label:hover{background-color:#d01919!important;border-color:#d01919!important;color:#fff!important}.ui.red.corner.label,.ui.red.corner.label:hover{background-color:transparent!important}.ui.red.ribbon.label{border-color:#b21e1e!important}.ui.basic.red.label{background:none #fff!important;color:#db2828!important;border-color:#db2828!important}.ui.basic.red.labels a.label:hover,a.ui.basic.red.label:hover{background-color:#fff!important;color:#d01919!important;border-color:#d01919!important}.ui.orange.label,.ui.orange.labels .label{background-color:#f2711c!important;border-color:#f2711c!important;color:#fff!important}.ui.orange.labels .label:hover,a.ui.orange.label:hover{background-color:#f26202!important;border-color:#f26202!important;color:#fff!important}.ui.orange.corner.label,.ui.orange.corner.label:hover{background-color:transparent!important}.ui.orange.ribbon.label{border-color:#cf590c!important}.ui.basic.orange.label{background:none #fff!important;color:#f2711c!important;border-color:#f2711c!important}.ui.basic.orange.labels a.label:hover,a.ui.basic.orange.label:hover{background-color:#fff!important;color:#f26202!important;border-color:#f26202!important}.ui.yellow.label,.ui.yellow.labels .label{background-color:#fbbd08!important;border-color:#fbbd08!important;color:#fff!important}.ui.yellow.labels .label:hover,a.ui.yellow.label:hover{background-color:#eaae00!important;border-color:#eaae00!important;color:#fff!important}.ui.yellow.corner.label,.ui.yellow.corner.label:hover{background-color:transparent!important}.ui.yellow.ribbon.label{border-color:#cd9903!important}.ui.basic.yellow.label{background:none #fff!important;color:#fbbd08!important;border-color:#fbbd08!important}.ui.basic.yellow.labels a.label:hover,a.ui.basic.yellow.label:hover{background-color:#fff!important;color:#eaae00!important;border-color:#eaae00!important}.ui.olive.label,.ui.olive.labels .label{background-color:#b5cc18!important;border-color:#b5cc18!important;color:#fff!important}.ui.olive.labels .label:hover,a.ui.olive.label:hover{background-color:#a7bd0d!important;border-color:#a7bd0d!important;color:#fff!important}.ui.olive.corner.label,.ui.olive.corner.label:hover{background-color:transparent!important}.ui.olive.ribbon.label{border-color:#198f35!important}.ui.basic.olive.label{background:none #fff!important;color:#b5cc18!important;border-color:#b5cc18!important}.ui.basic.olive.labels a.label:hover,a.ui.basic.olive.label:hover{background-color:#fff!important;color:#a7bd0d!important;border-color:#a7bd0d!important}.ui.green.label,.ui.green.labels .label{background-color:#21ba45!important;border-color:#21ba45!important;color:#fff!important}.ui.green.labels .label:hover,a.ui.green.label:hover{background-color:#16ab39!important;border-color:#16ab39!important;color:#fff!important}.ui.green.corner.label,.ui.green.corner.label:hover{background-color:transparent!important}.ui.green.ribbon.label{border-color:#198f35!important}.ui.basic.green.label{background:none #fff!important;color:#21ba45!important;border-color:#21ba45!important}.ui.basic.green.labels a.label:hover,a.ui.basic.green.label:hover{background-color:#fff!important;color:#16ab39!important;border-color:#16ab39!important}.ui.teal.label,.ui.teal.labels .label{background-color:#00b5ad!important;border-color:#00b5ad!important;color:#fff!important}.ui.teal.labels .label:hover,a.ui.teal.label:hover{background-color:#009c95!important;border-color:#009c95!important;color:#fff!important}.ui.teal.corner.label,.ui.teal.corner.label:hover{background-color:transparent!important}.ui.teal.ribbon.label{border-color:#00827c!important}.ui.basic.teal.label{background:none #fff!important;color:#00b5ad!important;border-color:#00b5ad!important}.ui.basic.teal.labels a.label:hover,a.ui.basic.teal.label:hover{background-color:#fff!important;color:#009c95!important;border-color:#009c95!important}.ui.blue.label,.ui.blue.labels .label{background-color:#2185d0!important;border-color:#2185d0!important;color:#fff!important}.ui.blue.labels .label:hover,a.ui.blue.label:hover{background-color:#1678c2!important;border-color:#1678c2!important;color:#fff!important}.ui.blue.corner.label,.ui.blue.corner.label:hover{background-color:transparent!important}.ui.blue.ribbon.label{border-color:#1a69a4!important}.ui.basic.blue.label{background:none #fff!important;color:#2185d0!important;border-color:#2185d0!important}.ui.basic.blue.labels a.label:hover,a.ui.basic.blue.label:hover{background-color:#fff!important;color:#1678c2!important;border-color:#1678c2!important}.ui.violet.label,.ui.violet.labels .label{background-color:#6435c9!important;border-color:#6435c9!important;color:#fff!important}.ui.violet.labels .label:hover,a.ui.violet.label:hover{background-color:#5829bb!important;border-color:#5829bb!important;color:#fff!important}.ui.violet.corner.label,.ui.violet.corner.label:hover{background-color:transparent!important}.ui.violet.ribbon.label{border-color:#502aa1!important}.ui.basic.violet.label{background:none #fff!important;color:#6435c9!important;border-color:#6435c9!important}.ui.basic.violet.labels a.label:hover,a.ui.basic.violet.label:hover{background-color:#fff!important;color:#5829bb!important;border-color:#5829bb!important}.ui.purple.label,.ui.purple.labels .label{background-color:#a333c8!important;border-color:#a333c8!important;color:#fff!important}.ui.purple.labels .label:hover,a.ui.purple.label:hover{background-color:#9627ba!important;border-color:#9627ba!important;color:#fff!important}.ui.purple.corner.label,.ui.purple.corner.label:hover{background-color:transparent!important}.ui.purple.ribbon.label{border-color:#82299f!important}.ui.basic.purple.label{background:none #fff!important;color:#a333c8!important;border-color:#a333c8!important}.ui.basic.purple.labels a.label:hover,a.ui.basic.purple.label:hover{background-color:#fff!important;color:#9627ba!important;border-color:#9627ba!important}.ui.pink.label,.ui.pink.labels .label{background-color:#e03997!important;border-color:#e03997!important;color:#fff!important}.ui.pink.labels .label:hover,a.ui.pink.label:hover{background-color:#e61a8d!important;border-color:#e61a8d!important;color:#fff!important}.ui.pink.corner.label,.ui.pink.corner.label:hover{background-color:transparent!important}.ui.pink.ribbon.label{border-color:#c71f7e!important}.ui.basic.pink.label{background:none #fff!important;color:#e03997!important;border-color:#e03997!important}.ui.basic.pink.labels a.label:hover,a.ui.basic.pink.label:hover{background-color:#fff!important;color:#e61a8d!important;border-color:#e61a8d!important}.ui.brown.label,.ui.brown.labels .label{background-color:#a5673f!important;border-color:#a5673f!important;color:#fff!important}.ui.brown.labels .label:hover,a.ui.brown.label:hover{background-color:#975b33!important;border-color:#975b33!important;color:#fff!important}.ui.brown.corner.label,.ui.brown.corner.label:hover{background-color:transparent!important}.ui.brown.ribbon.label{border-color:#805031!important}.ui.basic.brown.label{background:none #fff!important;color:#a5673f!important;border-color:#a5673f!important}.ui.basic.brown.labels a.label:hover,a.ui.basic.brown.label:hover{background-color:#fff!important;color:#975b33!important;border-color:#975b33!important}.ui.grey.label,.ui.grey.labels .label{background-color:#767676!important;border-color:#767676!important;color:#fff!important}.ui.grey.labels .label:hover,a.ui.grey.label:hover{background-color:#838383!important;border-color:#838383!important;color:#fff!important}.ui.grey.corner.label,.ui.grey.corner.label:hover{background-color:transparent!important}.ui.grey.ribbon.label{border-color:#805031!important}.ui.basic.grey.label{background:none #fff!important;color:#767676!important;border-color:#767676!important}.ui.basic.grey.labels a.label:hover,a.ui.basic.grey.label:hover{background-color:#fff!important;color:#838383!important;border-color:#838383!important}.ui.black.label,.ui.black.labels .label{background-color:#1b1c1d!important;border-color:#1b1c1d!important;color:#fff!important}.ui.black.labels .label:hover,a.ui.black.label:hover{background-color:#27292a!important;border-color:#27292a!important;color:#fff!important}.ui.black.corner.label,.ui.black.corner.label:hover{background-color:transparent!important}.ui.black.ribbon.label{border-color:#805031!important}.ui.basic.black.label{background:none #fff!important;color:#1b1c1d!important;border-color:#1b1c1d!important}.ui.basic.black.labels a.label:hover,a.ui.basic.black.label:hover{background-color:#fff!important;color:#27292a!important;border-color:#27292a!important}.ui.basic.label{background:none #fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}a.ui.basic.label:hover{text-decoration:none;background:none #fff;color:#1e70bf;-webkit-box-shadow:1px solid rgba(34,36,38,.15);box-shadow:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.pointing.label:before{border-color:inherit}.ui.fluid.labels>.label,.ui.label.fluid{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.ui.inverted.label,.ui.inverted.labels .label{color:rgba(255,255,255,.9)!important}.ui.horizontal.label,.ui.horizontal.labels .label{margin:0 .5em 0 0;padding:.4em .833em;min-width:3em;text-align:center}.ui.circular.label,.ui.circular.labels .label{min-width:2em;min-height:2em;padding:.5em!important;line-height:1em;text-align:center;border-radius:500rem}.ui.empty.circular.label,.ui.empty.circular.labels .label{min-width:0;min-height:0;overflow:hidden;width:.5em;height:.5em;vertical-align:baseline}.ui.pointing.label{position:relative}.ui.attached.pointing.label{position:absolute}.ui.pointing.label:before{background-color:inherit;background-image:inherit;border-width:none;border-style:solid;border-color:inherit}.ui.pointing.label:before{position:absolute;content:'';-webkit-transform:rotate(45deg);transform:rotate(45deg);background-image:none;z-index:2;width:.6666em;height:.6666em;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.pointing.label,.ui[class*=\\\"pointing above\\\"].label{margin-top:1em}.ui.pointing.label:before,.ui[class*=\\\"pointing above\\\"].label:before{border-width:1px 0 0 1px;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);top:0;left:50%}.ui[class*=\\\"bottom pointing\\\"].label,.ui[class*=\\\"pointing below\\\"].label{margin-top:0;margin-bottom:1em}.ui[class*=\\\"bottom pointing\\\"].label:before,.ui[class*=\\\"pointing below\\\"].label:before{border-width:0 1px 1px 0;top:auto;right:auto;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);top:100%;left:50%}.ui[class*=\\\"left pointing\\\"].label{margin-top:0;margin-left:.6666em}.ui[class*=\\\"left pointing\\\"].label:before{border-width:0 0 1px 1px;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);bottom:auto;right:auto;top:50%;left:0}.ui[class*=\\\"right pointing\\\"].label{margin-top:0;margin-right:.6666em}.ui[class*=\\\"right pointing\\\"].label:before{border-width:1px 1px 0 0;-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg);top:50%;right:0;bottom:auto;left:auto}.ui.basic.pointing.label:before,.ui.basic[class*=\\\"pointing above\\\"].label:before{margin-top:-1px}.ui.basic[class*=\\\"bottom pointing\\\"].label:before,.ui.basic[class*=\\\"pointing below\\\"].label:before{bottom:auto;top:100%;margin-top:1px}.ui.basic[class*=\\\"left pointing\\\"].label:before{top:50%;left:-1px}.ui.basic[class*=\\\"right pointing\\\"].label:before{top:50%;right:-1px}.ui.floating.label{position:absolute;z-index:100;top:-1em;left:100%;margin:0 0 0 -1.5em!important}.ui.mini.label,.ui.mini.labels .label{font-size:.64285714rem}.ui.tiny.label,.ui.tiny.labels .label{font-size:.71428571rem}.ui.small.label,.ui.small.labels .label{font-size:.78571429rem}.ui.label,.ui.labels .label{font-size:.85714286rem}.ui.large.label,.ui.large.labels .label{font-size:1rem}.ui.big.label,.ui.big.labels .label{font-size:1.28571429rem}.ui.huge.label,.ui.huge.labels .label{font-size:1.42857143rem}.ui.massive.label,.ui.massive.labels .label{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - List\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.list,ol.ui.list,ul.ui.list{list-style-type:none;margin:1em 0;padding:0 0}.ui.list:first-child,ol.ui.list:first-child,ul.ui.list:first-child{margin-top:0;padding-top:0}.ui.list:last-child,ol.ui.list:last-child,ul.ui.list:last-child{margin-bottom:0;padding-bottom:0}.ui.list .list>.item,.ui.list>.item,ol.ui.list li,ul.ui.list li{display:list-item;table-layout:fixed;list-style-type:none;list-style-position:outside;padding:.21428571em 0;line-height:1.14285714em}.ui.list>.item:after,.ui.list>.list>.item,ol.ui.list>li:first-child:after,ul.ui.list>li:first-child:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.list .list>.item:first-child,.ui.list>.item:first-child,ol.ui.list li:first-child,ul.ui.list li:first-child{padding-top:0}.ui.list .list>.item:last-child,.ui.list>.item:last-child,ol.ui.list li:last-child,ul.ui.list li:last-child{padding-bottom:0}.ui.list .list,ol.ui.list ol,ul.ui.list ul{clear:both;margin:0;padding:.75em 0 .25em .5em}.ui.list .list>.item,ol.ui.list ol li,ul.ui.list ul li{padding:.14285714em 0;line-height:inherit}.ui.list .list>.item>i.icon,.ui.list>.item>i.icon{display:table-cell;margin:0;padding-top:0;padding-right:.28571429em;vertical-align:top;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.list .list>.item>i.icon:only-child,.ui.list>.item>i.icon:only-child{display:inline-block;vertical-align:top}.ui.list .list>.item>.image,.ui.list>.item>.image{display:table-cell;background-color:transparent;margin:0;vertical-align:top}.ui.list .list>.item>.image:not(:only-child):not(img),.ui.list>.item>.image:not(:only-child):not(img){padding-right:.5em}.ui.list .list>.item>.image img,.ui.list>.item>.image img{vertical-align:top}.ui.list .list>.item>.image:only-child,.ui.list .list>.item>img.image,.ui.list>.item>.image:only-child,.ui.list>.item>img.image{display:inline-block}.ui.list .list>.item>.content,.ui.list>.item>.content{line-height:1.14285714em}.ui.list .list>.item>.icon+.content,.ui.list .list>.item>.image+.content,.ui.list>.item>.icon+.content,.ui.list>.item>.image+.content{display:table-cell;width:100%;padding:0 0 0 .5em;vertical-align:top}.ui.list .list>.item>img.image+.content,.ui.list>.item>img.image+.content{display:inline-block;width:auto}.ui.list .list>.item>.content>.list,.ui.list>.item>.content>.list{margin-left:0;padding-left:0}.ui.list .list>.item .header,.ui.list>.item .header{display:block;margin:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;color:rgba(0,0,0,.87)}.ui.list .list>.item .description,.ui.list>.item .description{display:block;color:rgba(0,0,0,.7)}.ui.list .list>.item a,.ui.list>.item a{cursor:pointer}.ui.list .list>a.item,.ui.list>a.item{cursor:pointer;color:#4183c4}.ui.list .list>a.item:hover,.ui.list>a.item:hover{color:#1e70bf}.ui.list .list>a.item i.icon,.ui.list>a.item i.icon{color:rgba(0,0,0,.4)}.ui.list .list>.item a.header,.ui.list>.item a.header{cursor:pointer;color:#4183c4!important}.ui.list .list>.item a.header:hover,.ui.list>.item a.header:hover{color:#1e70bf!important}.ui[class*=\\\"left floated\\\"].list{float:left}.ui[class*=\\\"right floated\\\"].list{float:right}.ui.list .list>.item [class*=\\\"left floated\\\"],.ui.list>.item [class*=\\\"left floated\\\"]{float:left;margin:0 1em 0 0}.ui.list .list>.item [class*=\\\"right floated\\\"],.ui.list>.item [class*=\\\"right floated\\\"]{float:right;margin:0 0 0 1em}.ui.menu .ui.list .list>.item,.ui.menu .ui.list>.item{display:list-item;table-layout:fixed;background-color:transparent;list-style-type:none;list-style-position:outside;padding:.21428571em 0;line-height:1.14285714em}.ui.menu .ui.list .list>.item:before,.ui.menu .ui.list>.item:before{border:none;background:0 0}.ui.menu .ui.list .list>.item:first-child,.ui.menu .ui.list>.item:first-child{padding-top:0}.ui.menu .ui.list .list>.item:last-child,.ui.menu .ui.list>.item:last-child{padding-bottom:0}.ui.horizontal.list{display:inline-block;font-size:0}.ui.horizontal.list>.item{display:inline-block;margin-left:1em;font-size:1rem}.ui.horizontal.list:not(.celled)>.item:first-child{margin-left:0!important;padding-left:0!important}.ui.horizontal.list .list{padding-left:0;padding-bottom:0}.ui.horizontal.list .list>.item>.content,.ui.horizontal.list .list>.item>.icon,.ui.horizontal.list .list>.item>.image,.ui.horizontal.list>.item>.content,.ui.horizontal.list>.item>.icon,.ui.horizontal.list>.item>.image{vertical-align:middle}.ui.horizontal.list>.item:first-child,.ui.horizontal.list>.item:last-child{padding-top:.21428571em;padding-bottom:.21428571em}.ui.horizontal.list>.item>i.icon{margin:0;padding:0 .25em 0 0}.ui.horizontal.list>.item>.icon,.ui.horizontal.list>.item>.icon+.content{float:none;display:inline-block}.ui.list .list>.disabled.item,.ui.list>.disabled.item{pointer-events:none;color:rgba(40,40,40,.3)!important}.ui.inverted.list .list>.disabled.item,.ui.inverted.list>.disabled.item{color:rgba(225,225,225,.3)!important}.ui.list .list>a.item:hover .icon,.ui.list>a.item:hover .icon{color:rgba(0,0,0,.87)}.ui.inverted.list .list>a.item>.icon,.ui.inverted.list>a.item>.icon{color:rgba(255,255,255,.7)}.ui.inverted.list .list>.item .header,.ui.inverted.list>.item .header{color:rgba(255,255,255,.9)}.ui.inverted.list .list>.item .description,.ui.inverted.list>.item .description{color:rgba(255,255,255,.7)}.ui.inverted.list .list>a.item,.ui.inverted.list>a.item{cursor:pointer;color:rgba(255,255,255,.9)}.ui.inverted.list .list>a.item:hover,.ui.inverted.list>a.item:hover{color:#1e70bf}.ui.inverted.list .item a:not(.ui){color:rgba(255,255,255,.9)!important}.ui.inverted.list .item a:not(.ui):hover{color:#1e70bf!important}.ui.list [class*=\\\"top aligned\\\"],.ui.list[class*=\\\"top aligned\\\"] .content,.ui.list[class*=\\\"top aligned\\\"] .image{vertical-align:top!important}.ui.list [class*=\\\"middle aligned\\\"],.ui.list[class*=\\\"middle aligned\\\"] .content,.ui.list[class*=\\\"middle aligned\\\"] .image{vertical-align:middle!important}.ui.list [class*=\\\"bottom aligned\\\"],.ui.list[class*=\\\"bottom aligned\\\"] .content,.ui.list[class*=\\\"bottom aligned\\\"] .image{vertical-align:bottom!important}.ui.link.list .item,.ui.link.list .item a:not(.ui),.ui.link.list a.item{color:rgba(0,0,0,.4);-webkit-transition:.1s color ease;transition:.1s color ease}.ui.link.list.list .item a:not(.ui):hover,.ui.link.list.list a.item:hover{color:rgba(0,0,0,.8)}.ui.link.list.list .item a:not(.ui):active,.ui.link.list.list a.item:active{color:rgba(0,0,0,.9)}.ui.link.list.list .active.item,.ui.link.list.list .active.item a:not(.ui){color:rgba(0,0,0,.95)}.ui.inverted.link.list .item,.ui.inverted.link.list .item a:not(.ui),.ui.inverted.link.list a.item{color:rgba(255,255,255,.5)}.ui.inverted.link.list.list .item a:not(.ui):hover,.ui.inverted.link.list.list a.item:hover{color:#fff}.ui.inverted.link.list.list .item a:not(.ui):active,.ui.inverted.link.list.list a.item:active{color:#fff}.ui.inverted.link.list.list .active.item a:not(.ui),.ui.inverted.link.list.list a.active.item{color:#fff}.ui.selection.list .list>.item,.ui.selection.list>.item{cursor:pointer;background:0 0;padding:.5em .5em;margin:0;color:rgba(0,0,0,.4);border-radius:.5em;-webkit-transition:.1s color ease,.1s padding-left ease,.1s background-color ease;transition:.1s color ease,.1s padding-left ease,.1s background-color ease}.ui.selection.list .list>.item:last-child,.ui.selection.list>.item:last-child{margin-bottom:0}.ui.selection.list.list>.item:hover,.ui.selection.list>.item:hover{background:rgba(0,0,0,.03);color:rgba(0,0,0,.8)}.ui.selection.list .list>.item:active,.ui.selection.list>.item:active{background:rgba(0,0,0,.05);color:rgba(0,0,0,.9)}.ui.selection.list .list>.item.active,.ui.selection.list>.item.active{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.inverted.selection.list>.item{background:0 0;color:rgba(255,255,255,.5)}.ui.inverted.selection.list>.item:hover{background:rgba(255,255,255,.02);color:#fff}.ui.inverted.selection.list>.item:active{background:rgba(255,255,255,.08);color:#fff}.ui.inverted.selection.list>.item.active{background:rgba(255,255,255,.08);color:#fff}.ui.celled.selection.list .list>.item,.ui.celled.selection.list>.item,.ui.divided.selection.list .list>.item,.ui.divided.selection.list>.item{border-radius:0}.ui.animated.list>.item{-webkit-transition:.25s color ease .1s,.25s padding-left ease .1s,.25s background-color ease .1s;transition:.25s color ease .1s,.25s padding-left ease .1s,.25s background-color ease .1s}.ui.animated.list:not(.horizontal)>.item:hover{padding-left:1em}.ui.fitted.list:not(.selection) .list>.item,.ui.fitted.list:not(.selection)>.item{padding-left:0;padding-right:0}.ui.fitted.selection.list .list>.item,.ui.fitted.selection.list>.item{margin-left:-.5em;margin-right:-.5em}.ui.bulleted.list,ul.ui.list{margin-left:1.25rem}.ui.bulleted.list .list>.item,.ui.bulleted.list>.item,ul.ui.list li{position:relative}.ui.bulleted.list .list>.item:before,.ui.bulleted.list>.item:before,ul.ui.list li:before{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;position:absolute;top:auto;left:auto;font-weight:400;margin-left:-1.25rem;content:'•';opacity:1;color:inherit;vertical-align:top}.ui.bulleted.list .list>a.item:before,.ui.bulleted.list>a.item:before,ul.ui.list li:before{color:rgba(0,0,0,.87)}.ui.bulleted.list .list,ul.ui.list ul{padding-left:1.25rem}.ui.horizontal.bulleted.list,ul.ui.horizontal.bulleted.list{margin-left:0}.ui.horizontal.bulleted.list>.item,ul.ui.horizontal.bulleted.list li{margin-left:1.75rem}.ui.horizontal.bulleted.list>.item:first-child,ul.ui.horizontal.bulleted.list li:first-child{margin-left:0}.ui.horizontal.bulleted.list>.item::before,ul.ui.horizontal.bulleted.list li::before{color:rgba(0,0,0,.87)}.ui.horizontal.bulleted.list>.item:first-child::before,ul.ui.horizontal.bulleted.list li:first-child::before{display:none}.ui.ordered.list,.ui.ordered.list .list,ol.ui.list,ol.ui.list ol{counter-reset:ordered;margin-left:1.25rem;list-style-type:none}.ui.ordered.list .list>.item,.ui.ordered.list>.item,ol.ui.list li{list-style-type:none;position:relative}.ui.ordered.list .list>.item:before,.ui.ordered.list>.item:before,ol.ui.list li:before{position:absolute;top:auto;left:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;margin-left:-1.25rem;counter-increment:ordered;content:counters(ordered, \\\".\\\") \\\" \\\";text-align:right;color:rgba(0,0,0,.87);vertical-align:middle;opacity:.8}.ui.ordered.inverted.list .list>.item:before,.ui.ordered.inverted.list>.item:before,ol.ui.inverted.list li:before{color:rgba(255,255,255,.7)}.ui.ordered.list>.item[data-value],.ui.ordered.list>.list>.item[data-value]{content:attr(data-value)}ol.ui.list li[value]:before{content:attr(value)}.ui.ordered.list .list,ol.ui.list ol{margin-left:1em}.ui.ordered.list .list>.item:before,ol.ui.list ol li:before{margin-left:-2em}.ui.ordered.horizontal.list,ol.ui.horizontal.list{margin-left:0}.ui.ordered.horizontal.list .list>.item:before,.ui.ordered.horizontal.list>.item:before,ol.ui.horizontal.list li:before{position:static;margin:0 .5em 0 0}.ui.divided.list>.item{border-top:1px solid rgba(34,36,38,.15)}.ui.divided.list .list>.item{border-top:none}.ui.divided.list .item .list>.item{border-top:none}.ui.divided.list .list>.item:first-child,.ui.divided.list>.item:first-child{border-top:none}.ui.divided.list:not(.horizontal) .list>.item:first-child{border-top-width:1px}.ui.divided.bulleted.list .list,.ui.divided.bulleted.list:not(.horizontal){margin-left:0;padding-left:0}.ui.divided.bulleted.list>.item:not(.horizontal){padding-left:1.25rem}.ui.divided.ordered.list{margin-left:0}.ui.divided.ordered.list .list>.item,.ui.divided.ordered.list>.item{padding-left:1.25rem}.ui.divided.ordered.list .item .list{margin-left:0;margin-right:0;padding-bottom:.21428571em}.ui.divided.ordered.list .item .list>.item{padding-left:1em}.ui.divided.selection.list .list>.item,.ui.divided.selection.list>.item{margin:0;border-radius:0}.ui.divided.horizontal.list{margin-left:0}.ui.divided.horizontal.list>.item:not(:first-child){padding-left:.5em}.ui.divided.horizontal.list>.item:not(:last-child){padding-right:.5em}.ui.divided.horizontal.list>.item{border-top:none;border-left:1px solid rgba(34,36,38,.15);margin:0;line-height:.6}.ui.horizontal.divided.list>.item:first-child{border-left:none}.ui.divided.inverted.horizontal.list>.item,.ui.divided.inverted.list>.item,.ui.divided.inverted.list>.list{border-color:rgba(255,255,255,.1)}.ui.celled.list>.item,.ui.celled.list>.list{border-top:1px solid rgba(34,36,38,.15);padding-left:.5em;padding-right:.5em}.ui.celled.list>.item:last-child{border-bottom:1px solid rgba(34,36,38,.15)}.ui.celled.list>.item:first-child,.ui.celled.list>.item:last-child{padding-top:.21428571em;padding-bottom:.21428571em}.ui.celled.list .item .list>.item{border-width:0}.ui.celled.list .list>.item:first-child{border-top-width:0}.ui.celled.bulleted.list{margin-left:0}.ui.celled.bulleted.list .list>.item,.ui.celled.bulleted.list>.item{padding-left:1.25rem}.ui.celled.bulleted.list .item .list{margin-left:-1.25rem;margin-right:-1.25rem;padding-bottom:.21428571em}.ui.celled.ordered.list{margin-left:0}.ui.celled.ordered.list .list>.item,.ui.celled.ordered.list>.item{padding-left:1.25rem}.ui.celled.ordered.list .item .list{margin-left:0;margin-right:0;padding-bottom:.21428571em}.ui.celled.ordered.list .list>.item{padding-left:1em}.ui.horizontal.celled.list{margin-left:0}.ui.horizontal.celled.list .list>.item,.ui.horizontal.celled.list>.item{border-top:none;border-left:1px solid rgba(34,36,38,.15);margin:0;padding-left:.5em;padding-right:.5em;line-height:.6}.ui.horizontal.celled.list .list>.item:last-child,.ui.horizontal.celled.list>.item:last-child{border-bottom:none;border-right:1px solid rgba(34,36,38,.15)}.ui.celled.inverted.list>.item,.ui.celled.inverted.list>.list{border-color:1px solid rgba(255,255,255,.1)}.ui.celled.inverted.horizontal.list .list>.item,.ui.celled.inverted.horizontal.list>.item{border-color:1px solid rgba(255,255,255,.1)}.ui.relaxed.list:not(.horizontal)>.item:not(:first-child){padding-top:.42857143em}.ui.relaxed.list:not(.horizontal)>.item:not(:last-child){padding-bottom:.42857143em}.ui.horizontal.relaxed.list .list>.item:not(:first-child),.ui.horizontal.relaxed.list>.item:not(:first-child){padding-left:1rem}.ui.horizontal.relaxed.list .list>.item:not(:last-child),.ui.horizontal.relaxed.list>.item:not(:last-child){padding-right:1rem}.ui[class*=\\\"very relaxed\\\"].list:not(.horizontal)>.item:not(:first-child){padding-top:.85714286em}.ui[class*=\\\"very relaxed\\\"].list:not(.horizontal)>.item:not(:last-child){padding-bottom:.85714286em}.ui.horizontal[class*=\\\"very relaxed\\\"].list .list>.item:not(:first-child),.ui.horizontal[class*=\\\"very relaxed\\\"].list>.item:not(:first-child){padding-left:1.5rem}.ui.horizontal[class*=\\\"very relaxed\\\"].list .list>.item:not(:last-child),.ui.horizontal[class*=\\\"very relaxed\\\"].list>.item:not(:last-child){padding-right:1.5rem}.ui.mini.list{font-size:.78571429em}.ui.tiny.list{font-size:.85714286em}.ui.small.list{font-size:.92857143em}.ui.list{font-size:1em}.ui.large.list{font-size:1.14285714em}.ui.big.list{font-size:1.28571429em}.ui.huge.list{font-size:1.42857143em}.ui.massive.list{font-size:1.71428571em}.ui.mini.horizontal.list .list>.item,.ui.mini.horizontal.list>.item{font-size:.78571429rem}.ui.tiny.horizontal.list .list>.item,.ui.tiny.horizontal.list>.item{font-size:.85714286rem}.ui.small.horizontal.list .list>.item,.ui.small.horizontal.list>.item{font-size:.92857143rem}.ui.horizontal.list .list>.item,.ui.horizontal.list>.item{font-size:1rem}.ui.large.horizontal.list .list>.item,.ui.large.horizontal.list>.item{font-size:1.14285714rem}.ui.big.horizontal.list .list>.item,.ui.big.horizontal.list>.item{font-size:1.28571429rem}.ui.huge.horizontal.list .list>.item,.ui.huge.horizontal.list>.item{font-size:1.42857143rem}.ui.massive.horizontal.list .list>.item,.ui.massive.horizontal.list>.item{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Loader\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.loader{display:none;position:absolute;top:50%;left:50%;margin:0;text-align:center;z-index:1000;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.ui.loader:before{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loader:after{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;-webkit-animation:loader .6s linear;animation:loader .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}@-webkit-keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.mini.loader:after,.ui.mini.loader:before{width:1rem;height:1rem;margin:0 0 0 -.5rem}.ui.tiny.loader:after,.ui.tiny.loader:before{width:1.14285714rem;height:1.14285714rem;margin:0 0 0 -.57142857rem}.ui.small.loader:after,.ui.small.loader:before{width:1.71428571rem;height:1.71428571rem;margin:0 0 0 -.85714286rem}.ui.loader:after,.ui.loader:before{width:2.28571429rem;height:2.28571429rem;margin:0 0 0 -1.14285714rem}.ui.large.loader:after,.ui.large.loader:before{width:3.42857143rem;height:3.42857143rem;margin:0 0 0 -1.71428571rem}.ui.big.loader:after,.ui.big.loader:before{width:3.71428571rem;height:3.71428571rem;margin:0 0 0 -1.85714286rem}.ui.huge.loader:after,.ui.huge.loader:before{width:4.14285714rem;height:4.14285714rem;margin:0 0 0 -2.07142857rem}.ui.massive.loader:after,.ui.massive.loader:before{width:4.57142857rem;height:4.57142857rem;margin:0 0 0 -2.28571429rem}.ui.dimmer .loader{display:block}.ui.dimmer .ui.loader{color:rgba(255,255,255,.9)}.ui.dimmer .ui.loader:before{border-color:rgba(255,255,255,.15)}.ui.dimmer .ui.loader:after{border-color:#fff transparent transparent}.ui.inverted.dimmer .ui.loader{color:rgba(0,0,0,.87)}.ui.inverted.dimmer .ui.loader:before{border-color:rgba(0,0,0,.1)}.ui.inverted.dimmer .ui.loader:after{border-color:#767676 transparent transparent}.ui.text.loader{width:auto!important;height:auto!important;text-align:center;font-style:normal}.ui.indeterminate.loader:after{animation-direction:reverse;-webkit-animation-duration:1.2s;animation-duration:1.2s}.ui.loader.active,.ui.loader.visible{display:block}.ui.loader.disabled,.ui.loader.hidden{display:none}.ui.inverted.dimmer .ui.mini.loader,.ui.mini.loader{width:1rem;height:1rem;font-size:.78571429em}.ui.inverted.dimmer .ui.tiny.loader,.ui.tiny.loader{width:1.14285714rem;height:1.14285714rem;font-size:.85714286em}.ui.inverted.dimmer .ui.small.loader,.ui.small.loader{width:1.71428571rem;height:1.71428571rem;font-size:.92857143em}.ui.inverted.dimmer .ui.loader,.ui.loader{width:2.28571429rem;height:2.28571429rem;font-size:1em}.ui.inverted.dimmer .ui.large.loader,.ui.large.loader{width:3.42857143rem;height:3.42857143rem;font-size:1.14285714em}.ui.big.loader,.ui.inverted.dimmer .ui.big.loader{width:3.71428571rem;height:3.71428571rem;font-size:1.28571429em}.ui.huge.loader,.ui.inverted.dimmer .ui.huge.loader{width:4.14285714rem;height:4.14285714rem;font-size:1.42857143em}.ui.inverted.dimmer .ui.massive.loader,.ui.massive.loader{width:4.57142857rem;height:4.57142857rem;font-size:1.71428571em}.ui.mini.text.loader{min-width:1rem;padding-top:1.78571429rem}.ui.tiny.text.loader{min-width:1.14285714rem;padding-top:1.92857143rem}.ui.small.text.loader{min-width:1.71428571rem;padding-top:2.5rem}.ui.text.loader{min-width:2.28571429rem;padding-top:3.07142857rem}.ui.large.text.loader{min-width:3.42857143rem;padding-top:4.21428571rem}.ui.big.text.loader{min-width:3.71428571rem;padding-top:4.5rem}.ui.huge.text.loader{min-width:4.14285714rem;padding-top:4.92857143rem}.ui.massive.text.loader{min-width:4.57142857rem;padding-top:5.35714286rem}.ui.inverted.loader{color:rgba(255,255,255,.9)}.ui.inverted.loader:before{border-color:rgba(255,255,255,.15)}.ui.inverted.loader:after{border-top-color:#fff}.ui.inline.loader{position:relative;vertical-align:middle;margin:0;left:0;top:0;-webkit-transform:none;transform:none}.ui.inline.loader.active,.ui.inline.loader.visible{display:inline-block}.ui.centered.inline.loader.active,.ui.centered.inline.loader.visible{display:block;margin-left:auto;margin-right:auto}/*!\\n * # Semantic UI 2.4.0 - Loader\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.placeholder{position:static;overflow:hidden;-webkit-animation:placeholderShimmer 2s linear;animation:placeholderShimmer 2s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;background-color:#fff;background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.08)),color-stop(15%,rgba(0,0,0,.15)),color-stop(30%,rgba(0,0,0,.08)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.08) 0,rgba(0,0,0,.15) 15%,rgba(0,0,0,.08) 30%);background-image:linear-gradient(to right,rgba(0,0,0,.08) 0,rgba(0,0,0,.15) 15%,rgba(0,0,0,.08) 30%);background-size:1200px 100%;max-width:30rem}@-webkit-keyframes placeholderShimmer{0%{background-position:-1200px 0}100%{background-position:1200px 0}}@keyframes placeholderShimmer{0%{background-position:-1200px 0}100%{background-position:1200px 0}}.ui.placeholder+.ui.placeholder{margin-top:2rem}.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.15s;animation-delay:.15s}.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.3s;animation-delay:.3s}.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.45s;animation-delay:.45s}.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder+.ui.placeholder{-webkit-animation-delay:.6s;animation-delay:.6s}.ui.placeholder,.ui.placeholder .image.header:after,.ui.placeholder .line,.ui.placeholder .line:after,.ui.placeholder>:before{background-color:#fff}.ui.placeholder .image:not(.header):not(.ui){height:100px}.ui.placeholder .square.image:not(.header){height:0;overflow:hidden;padding-top:100%}.ui.placeholder .rectangular.image:not(.header){height:0;overflow:hidden;padding-top:75%}.ui.placeholder .line{position:relative;height:.85714286em}.ui.placeholder .line:after,.ui.placeholder .line:before{top:100%;position:absolute;content:'';background-color:inherit}.ui.placeholder .line:before{left:0}.ui.placeholder .line:after{right:0}.ui.placeholder .line{margin-bottom:.5em}.ui.placeholder .line:after,.ui.placeholder .line:before{height:.5em}.ui.placeholder .line:not(:first-child){margin-top:.5em}.ui.placeholder .header{position:relative;overflow:hidden}.ui.placeholder .line:nth-child(1):after{width:0%}.ui.placeholder .line:nth-child(2):after{width:50%}.ui.placeholder .line:nth-child(3):after{width:10%}.ui.placeholder .line:nth-child(4):after{width:35%}.ui.placeholder .line:nth-child(5):after{width:65%}.ui.placeholder .header .line{margin-bottom:.64285714em}.ui.placeholder .header .line:after,.ui.placeholder .header .line:before{height:.64285714em}.ui.placeholder .header .line:not(:first-child){margin-top:.64285714em}.ui.placeholder .header .line:after{width:20%}.ui.placeholder .header .line:nth-child(2):after{width:60%}.ui.placeholder .image.header .line{margin-left:3em}.ui.placeholder .image.header .line:before{width:.71428571rem}.ui.placeholder .image.header:after{display:block;height:.85714286em;content:'';margin-left:3em}.ui.placeholder .header .line:first-child,.ui.placeholder .image .line:first-child,.ui.placeholder .paragraph .line:first-child{height:.01px}.ui.placeholder .header:not(:first-child):before,.ui.placeholder .image:not(:first-child):before,.ui.placeholder .paragraph:not(:first-child):before{height:1.42857143em;content:'';display:block}.ui.inverted.placeholder{background-image:-webkit-gradient(linear,left top,right top,from(rgba(255,255,255,.08)),color-stop(15%,rgba(255,255,255,.14)),color-stop(30%,rgba(255,255,255,.08)));background-image:-webkit-linear-gradient(left,rgba(255,255,255,.08) 0,rgba(255,255,255,.14) 15%,rgba(255,255,255,.08) 30%);background-image:linear-gradient(to right,rgba(255,255,255,.08) 0,rgba(255,255,255,.14) 15%,rgba(255,255,255,.08) 30%)}.ui.inverted.placeholder,.ui.inverted.placeholder .image.header:after,.ui.inverted.placeholder .line,.ui.inverted.placeholder .line:after,.ui.inverted.placeholder>:before{background-color:#1b1c1d}.ui.placeholder .full.line.line.line:after{width:0%}.ui.placeholder .very.long.line.line.line:after{width:10%}.ui.placeholder .long.line.line.line:after{width:35%}.ui.placeholder .medium.line.line.line:after{width:50%}.ui.placeholder .short.line.line.line:after{width:65%}.ui.placeholder .very.short.line.line.line:after{width:80%}.ui.fluid.placeholder{max-width:none}/*!\\n * # Semantic UI 2.4.0 - Rail\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.rail{position:absolute;top:0;width:300px;height:100%}.ui.left.rail{left:auto;right:100%;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.right.rail{left:100%;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.left.internal.rail{left:0;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.right.internal.rail{left:auto;right:0;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.dividing.rail{width:302.5px}.ui.left.dividing.rail{padding:0 2.5rem 0 0;margin:0 2.5rem 0 0;border-right:1px solid rgba(34,36,38,.15)}.ui.right.dividing.rail{border-left:1px solid rgba(34,36,38,.15);padding:0 0 0 2.5rem;margin:0 0 0 2.5rem}.ui.close.rail{width:calc(300px + 1em)}.ui.close.left.rail{padding:0 1em 0 0;margin:0 1em 0 0}.ui.close.right.rail{padding:0 0 0 1em;margin:0 0 0 1em}.ui.very.close.rail{width:calc(300px + .5em)}.ui.very.close.left.rail{padding:0 .5em 0 0;margin:0 .5em 0 0}.ui.very.close.right.rail{padding:0 0 0 .5em;margin:0 0 0 .5em}.ui.attached.left.rail,.ui.attached.right.rail{padding:0;margin:0}.ui.mini.rail{font-size:.78571429rem}.ui.tiny.rail{font-size:.85714286rem}.ui.small.rail{font-size:.92857143rem}.ui.rail{font-size:1rem}.ui.large.rail{font-size:1.14285714rem}.ui.big.rail{font-size:1.28571429rem}.ui.huge.rail{font-size:1.42857143rem}.ui.massive.rail{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Reveal\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.reveal{display:inherit;position:relative!important;font-size:0!important}.ui.reveal>.visible.content{position:absolute!important;top:0!important;left:0!important;z-index:3!important;-webkit-transition:all .5s ease .1s;transition:all .5s ease .1s}.ui.reveal>.hidden.content{position:relative!important;z-index:2!important}.ui.active.reveal .visible.content,.ui.reveal:hover .visible.content{z-index:4!important}.ui.slide.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.slide.reveal>.content{display:block;width:100%;white-space:normal;float:left;margin:0;-webkit-transition:-webkit-transform .5s ease .1s;transition:-webkit-transform .5s ease .1s;transition:transform .5s ease .1s;transition:transform .5s ease .1s,-webkit-transform .5s ease .1s}.ui.slide.reveal>.visible.content{position:relative!important}.ui.slide.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important;-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.active.reveal>.visible.content,.ui.slide.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.active.reveal>.hidden.content,.ui.slide.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.visible.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.hidden.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.right.active.reveal>.visible.content,.ui.slide.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.right.active.reveal>.hidden.content,.ui.slide.right.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.up.reveal>.hidden.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.up.active.reveal>.visible.content,.ui.slide.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.up.active.reveal>.hidden.content,.ui.slide.up.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.slide.down.reveal>.hidden.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.down.active.reveal>.visible.content,.ui.slide.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.down.active.reveal>.hidden.content,.ui.slide.down.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.fade.reveal>.visible.content{opacity:1}.ui.fade.active.reveal>.visible.content,.ui.fade.reveal:hover>.visible.content{opacity:0}.ui.move.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.move.reveal>.content{display:block;float:left;white-space:normal;margin:0;-webkit-transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s,-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s}.ui.move.reveal>.visible.content{position:relative!important}.ui.move.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important}.ui.move.active.reveal>.visible.content,.ui.move.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.move.right.active.reveal>.visible.content,.ui.move.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.move.up.active.reveal>.visible.content,.ui.move.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.move.down.active.reveal>.visible.content,.ui.move.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.rotate.reveal>.visible.content{-webkit-transition-duration:.5s;transition-duration:.5s;-webkit-transform:rotate(0);transform:rotate(0)}.ui.rotate.reveal>.visible.content,.ui.rotate.right.reveal>.visible.content{-webkit-transform-origin:bottom right;transform-origin:bottom right}.ui.rotate.active.reveal>.visible.content,.ui.rotate.reveal:hover>.visible.content,.ui.rotate.right.active.reveal>.visible.content,.ui.rotate.right.reveal:hover>.visible.content{-webkit-transform:rotate(110deg);transform:rotate(110deg)}.ui.rotate.left.reveal>.visible.content{-webkit-transform-origin:bottom left;transform-origin:bottom left}.ui.rotate.left.active.reveal>.visible.content,.ui.rotate.left.reveal:hover>.visible.content{-webkit-transform:rotate(-110deg);transform:rotate(-110deg)}.ui.disabled.reveal:hover>.visible.visible.content{position:static!important;display:block!important;opacity:1!important;top:0!important;left:0!important;right:auto!important;bottom:auto!important;-webkit-transform:none!important;transform:none!important}.ui.disabled.reveal:hover>.hidden.hidden.content{display:none!important}.ui.reveal>.ui.ribbon.label{z-index:5}.ui.visible.reveal{overflow:visible}.ui.instant.reveal>.content{-webkit-transition-delay:0s!important;transition-delay:0s!important}.ui.reveal>.content{font-size:1rem!important}/*!\\n * # Semantic UI 2.4.0 - Segment\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.segment{position:relative;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);margin:1rem 0;padding:1em 1em;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.segment:first-child{margin-top:0}.ui.segment:last-child{margin-bottom:0}.ui.vertical.segment{margin:0;padding-left:0;padding-right:0;background:none transparent;border-radius:0;-webkit-box-shadow:none;box-shadow:none;border:none;border-bottom:1px solid rgba(34,36,38,.15)}.ui.vertical.segment:last-child{border-bottom:none}.ui.inverted.segment>.ui.header{color:#fff}.ui[class*=\\\"bottom attached\\\"].segment>[class*=\\\"top attached\\\"].label{border-top-left-radius:0;border-top-right-radius:0}.ui[class*=\\\"top attached\\\"].segment>[class*=\\\"bottom attached\\\"].label{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.attached.segment:not(.top):not(.bottom)>[class*=\\\"top attached\\\"].label{border-top-left-radius:0;border-top-right-radius:0}.ui.attached.segment:not(.top):not(.bottom)>[class*=\\\"bottom attached\\\"].label{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.grid>.row>.ui.segment.column,.ui.grid>.ui.segment.column,.ui.page.grid.segment{padding-top:2em;padding-bottom:2em}.ui.grid.segment{margin:1rem 0;border-radius:.28571429rem}.ui.basic.table.segment{background:#fff;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15)}.ui[class*=\\\"very basic\\\"].table.segment{padding:1em 1em}.ui.placeholder.segment{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;max-width:initial;-webkit-animation:none;animation:none;overflow:visible;padding:1em 1em;min-height:18rem;background:#f9fafb;border-color:rgba(34,36,38,.15);-webkit-box-shadow:0 2px 25px 0 rgba(34,36,38,.05) inset;box-shadow:0 2px 25px 0 rgba(34,36,38,.05) inset}.ui.placeholder.segment .button,.ui.placeholder.segment textarea{display:block}.ui.placeholder.segment .button,.ui.placeholder.segment .field,.ui.placeholder.segment textarea,.ui.placeholder.segment>.ui.input{max-width:15rem;margin-left:auto;margin-right:auto}.ui.placeholder.segment .column .button,.ui.placeholder.segment .column .field,.ui.placeholder.segment .column textarea,.ui.placeholder.segment .column>.ui.input{max-width:15rem;margin-left:auto;margin-right:auto}.ui.placeholder.segment>.inline{-ms-flex-item-align:center;align-self:center}.ui.placeholder.segment>.inline>.button{display:inline-block;width:auto;margin:0 .35714286rem 0 0}.ui.placeholder.segment>.inline>.button:last-child{margin-right:0}.ui.piled.segment,.ui.piled.segments{margin:3em 0;-webkit-box-shadow:'';box-shadow:'';z-index:auto}.ui.piled.segment:first-child{margin-top:0}.ui.piled.segment:last-child{margin-bottom:0}.ui.piled.segment:after,.ui.piled.segment:before,.ui.piled.segments:after,.ui.piled.segments:before{background-color:#fff;visibility:visible;content:'';display:block;height:100%;left:0;position:absolute;width:100%;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:'';box-shadow:''}.ui.piled.segment:before,.ui.piled.segments:before{-webkit-transform:rotate(-1.2deg);transform:rotate(-1.2deg);top:0;z-index:-2}.ui.piled.segment:after,.ui.piled.segments:after{-webkit-transform:rotate(1.2deg);transform:rotate(1.2deg);top:0;z-index:-1}.ui[class*=\\\"top attached\\\"].piled.segment{margin-top:3em;margin-bottom:0}.ui.piled.segment[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui.piled.segment[class*=\\\"bottom attached\\\"]{margin-top:0;margin-bottom:3em}.ui.piled.segment[class*=\\\"bottom attached\\\"]:last-child{margin-bottom:0}.ui.stacked.segment{padding-bottom:1.4em}.ui.stacked.segment:after,.ui.stacked.segment:before,.ui.stacked.segments:after,.ui.stacked.segments:before{content:'';position:absolute;bottom:-3px;left:0;border-top:1px solid rgba(34,36,38,.15);background:rgba(0,0,0,.03);width:100%;height:6px;visibility:visible}.ui.stacked.segment:before,.ui.stacked.segments:before{display:none}.ui.tall.stacked.segment:before,.ui.tall.stacked.segments:before{display:block;bottom:0}.ui.stacked.inverted.segment:after,.ui.stacked.inverted.segment:before,.ui.stacked.inverted.segments:after,.ui.stacked.inverted.segments:before{background-color:rgba(0,0,0,.03);border-top:1px solid rgba(34,36,38,.35)}.ui.padded.segment{padding:1.5em}.ui[class*=\\\"very padded\\\"].segment{padding:3em}.ui.padded.segment.vertical.segment,.ui[class*=\\\"very padded\\\"].vertical.segment{padding-left:0;padding-right:0}.ui.compact.segment{display:table}.ui.compact.segments{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.ui.compact.segments .segment,.ui.segments .compact.segment{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.ui.circular.segment{display:table-cell;padding:2em;text-align:center;vertical-align:middle;border-radius:500em}.ui.raised.segment,.ui.raised.segments{-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.segments{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:relative;margin:1rem 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);border-radius:.28571429rem}.ui.segments:first-child{margin-top:0}.ui.segments:last-child{margin-bottom:0}.ui.segments>.segment{top:0;bottom:0;border-radius:0;margin:0;width:auto;-webkit-box-shadow:none;box-shadow:none;border:none;border-top:1px solid rgba(34,36,38,.15)}.ui.segments:not(.horizontal)>.segment:first-child{border-top:none;margin-top:0;bottom:0;margin-bottom:0;top:0;border-radius:.28571429rem .28571429rem 0 0}.ui.segments:not(.horizontal)>.segment:last-child{top:0;bottom:0;margin-top:0;margin-bottom:0;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui.segments:not(.horizontal)>.segment:only-child{border-radius:.28571429rem}.ui.segments>.ui.segments{border-top:1px solid rgba(34,36,38,.15);margin:1rem 1rem}.ui.segments>.segments:first-child{border-top:none}.ui.segments>.segment+.segments:not(.horizontal){margin-top:0}.ui.horizontal.segments{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;background-color:transparent;border-radius:0;padding:0;background-color:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);margin:1rem 0;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.segments>.horizontal.segments{margin:0;background-color:transparent;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none;border-top:1px solid rgba(34,36,38,.15)}.ui.horizontal.segments>.segment{-webkit-box-flex:1;flex:1 1 auto;-ms-flex:1 1 0px;margin:0;min-width:0;background-color:transparent;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none;border-left:1px solid rgba(34,36,38,.15)}.ui.segments>.horizontal.segments:first-child{border-top:none}.ui.horizontal.segments>.segment:first-child{border-left:none}.ui.disabled.segment{opacity:.45;color:rgba(40,40,40,.3)}.ui.loading.segment{position:relative;cursor:default;pointer-events:none;text-shadow:none!important;color:transparent!important;-webkit-transition:all 0s linear;transition:all 0s linear}.ui.loading.segment:before{position:absolute;content:'';top:0;left:0;background:rgba(255,255,255,.8);width:100%;height:100%;border-radius:.28571429rem;z-index:100}.ui.loading.segment:after{position:absolute;content:'';top:50%;left:50%;margin:-1.5em 0 0 -1.5em;width:3em;height:3em;-webkit-animation:segment-spin .6s linear;animation:segment-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.1);border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;visibility:visible;z-index:101}@-webkit-keyframes segment-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes segment-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.basic.segment{background:none transparent;-webkit-box-shadow:none;box-shadow:none;border:none;border-radius:0}.ui.clearing.segment:after{content:\\\".\\\";display:block;height:0;clear:both;visibility:hidden}.ui.red.segment:not(.inverted){border-top:2px solid #db2828!important}.ui.inverted.red.segment{background-color:#db2828!important;color:#fff!important}.ui.orange.segment:not(.inverted){border-top:2px solid #f2711c!important}.ui.inverted.orange.segment{background-color:#f2711c!important;color:#fff!important}.ui.yellow.segment:not(.inverted){border-top:2px solid #fbbd08!important}.ui.inverted.yellow.segment{background-color:#fbbd08!important;color:#fff!important}.ui.olive.segment:not(.inverted){border-top:2px solid #b5cc18!important}.ui.inverted.olive.segment{background-color:#b5cc18!important;color:#fff!important}.ui.green.segment:not(.inverted){border-top:2px solid #21ba45!important}.ui.inverted.green.segment{background-color:#21ba45!important;color:#fff!important}.ui.teal.segment:not(.inverted){border-top:2px solid #00b5ad!important}.ui.inverted.teal.segment{background-color:#00b5ad!important;color:#fff!important}.ui.blue.segment:not(.inverted){border-top:2px solid #2185d0!important}.ui.inverted.blue.segment{background-color:#2185d0!important;color:#fff!important}.ui.violet.segment:not(.inverted){border-top:2px solid #6435c9!important}.ui.inverted.violet.segment{background-color:#6435c9!important;color:#fff!important}.ui.purple.segment:not(.inverted){border-top:2px solid #a333c8!important}.ui.inverted.purple.segment{background-color:#a333c8!important;color:#fff!important}.ui.pink.segment:not(.inverted){border-top:2px solid #e03997!important}.ui.inverted.pink.segment{background-color:#e03997!important;color:#fff!important}.ui.brown.segment:not(.inverted){border-top:2px solid #a5673f!important}.ui.inverted.brown.segment{background-color:#a5673f!important;color:#fff!important}.ui.grey.segment:not(.inverted){border-top:2px solid #767676!important}.ui.inverted.grey.segment{background-color:#767676!important;color:#fff!important}.ui.black.segment:not(.inverted){border-top:2px solid #1b1c1d!important}.ui.inverted.black.segment{background-color:#1b1c1d!important;color:#fff!important}.ui[class*=\\\"left aligned\\\"].segment{text-align:left}.ui[class*=\\\"right aligned\\\"].segment{text-align:right}.ui[class*=\\\"center aligned\\\"].segment{text-align:center}.ui.floated.segment,.ui[class*=\\\"left floated\\\"].segment{float:left;margin-right:1em}.ui[class*=\\\"right floated\\\"].segment{float:right;margin-left:1em}.ui.inverted.segment{border:none;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.segment,.ui.primary.inverted.segment{background:#1b1c1d;color:rgba(255,255,255,.9)}.ui.inverted.segment .segment{color:rgba(0,0,0,.87)}.ui.inverted.segment .inverted.segment{color:rgba(255,255,255,.9)}.ui.inverted.attached.segment{border-color:#555}.ui.secondary.segment{background:#f3f4f5;color:rgba(0,0,0,.6)}.ui.secondary.inverted.segment{background:#4c4f52 -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,.2)),to(rgba(255,255,255,.2)));background:#4c4f52 -webkit-linear-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.2) 100%);background:#4c4f52 linear-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.2) 100%);color:rgba(255,255,255,.8)}.ui.tertiary.segment{background:#dcddde;color:rgba(0,0,0,.6)}.ui.tertiary.inverted.segment{background:#717579 -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,.35)),to(rgba(255,255,255,.35)));background:#717579 -webkit-linear-gradient(rgba(255,255,255,.35) 0,rgba(255,255,255,.35) 100%);background:#717579 linear-gradient(rgba(255,255,255,.35) 0,rgba(255,255,255,.35) 100%);color:rgba(255,255,255,.8)}.ui.attached.segment{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached:not(.message)+.ui.attached.segment:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].segment{bottom:0;margin-bottom:0;top:0;margin-top:1rem;border-radius:.28571429rem .28571429rem 0 0}.ui.segment[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui.segment[class*=\\\"bottom attached\\\"]{bottom:0;margin-top:0;top:0;margin-bottom:1rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui.segment[class*=\\\"bottom attached\\\"]:last-child{margin-bottom:0}.ui.mini.segment,.ui.mini.segments .segment{font-size:.78571429rem}.ui.tiny.segment,.ui.tiny.segments .segment{font-size:.85714286rem}.ui.small.segment,.ui.small.segments .segment{font-size:.92857143rem}.ui.segment,.ui.segments .segment{font-size:1rem}.ui.large.segment,.ui.large.segments .segment{font-size:1.14285714rem}.ui.big.segment,.ui.big.segments .segment{font-size:1.28571429rem}.ui.huge.segment,.ui.huge.segments .segment{font-size:1.42857143rem}.ui.massive.segment,.ui.massive.segments .segment{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Step\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;margin:1em 0;background:'';-webkit-box-shadow:none;box-shadow:none;line-height:1.14285714em;border-radius:.28571429rem;border:1px solid rgba(34,36,38,.15)}.ui.steps:first-child{margin-top:0}.ui.steps:last-child{margin-bottom:0}.ui.steps .step{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;vertical-align:middle;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:0 0;padding:1.14285714em 2em;background:#fff;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none;border-radius:0;border:none;border-right:1px solid rgba(34,36,38,.15);-webkit-transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease}.ui.steps .step:after{display:none;position:absolute;z-index:2;content:'';top:50%;right:0;border:medium none;background-color:#fff;width:1.14285714em;height:1.14285714em;border-style:solid;border-color:rgba(34,36,38,.15);border-width:0 1px 1px 0;-webkit-transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease;transition:background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease;-webkit-transform:translateY(-50%) translateX(50%) rotate(-45deg);transform:translateY(-50%) translateX(50%) rotate(-45deg)}.ui.steps .step:first-child{padding-left:2em;border-radius:.28571429rem 0 0 .28571429rem}.ui.steps .step:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.steps .step:last-child{border-right:none;margin-right:0}.ui.steps .step:only-child{border-radius:.28571429rem}.ui.steps .step .title{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.14285714em;font-weight:700}.ui.steps .step>.title{width:100%}.ui.steps .step .description{font-weight:400;font-size:.92857143em;color:rgba(0,0,0,.87)}.ui.steps .step>.description{width:100%}.ui.steps .step .title~.description{margin-top:.25em}.ui.steps .step>.icon{line-height:1;font-size:2.5em;margin:0 1rem 0 0}.ui.steps .step>.icon,.ui.steps .step>.icon~.content{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-ms-flex-item-align:middle;align-self:middle}.ui.steps .step>.icon~.content{-webkit-box-flex:1 0 auto;-ms-flex-positive:1 0 auto;flex-grow:1 0 auto}.ui.steps:not(.vertical) .step>.icon{width:auto}.ui.steps .link.step,.ui.steps a.step{cursor:pointer}.ui.ordered.steps{counter-reset:ordered}.ui.ordered.steps .step:before{display:block;position:static;text-align:center;content:counters(ordered, \\\".\\\");-ms-flex-item-align:middle;align-self:middle;margin-right:1rem;font-size:2.5em;counter-increment:ordered;font-family:inherit;font-weight:700}.ui.ordered.steps .step>*{display:block;-ms-flex-item-align:middle;align-self:middle}.ui.vertical.steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:visible}.ui.vertical.steps .step{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;border-radius:0;padding:1.14285714em 2em;border-right:none;border-bottom:1px solid rgba(34,36,38,.15)}.ui.vertical.steps .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.steps .step:last-child{border-bottom:none;border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.steps .step:only-child{border-radius:.28571429rem}.ui.vertical.steps .step:after{display:none}.ui.vertical.steps .step:after{top:50%;right:0;border-width:0 1px 1px 0}.ui.vertical.steps .step:after{display:none}.ui.vertical.steps .active.step:after{display:block}.ui.vertical.steps .step:last-child:after{display:none}.ui.vertical.steps .active.step:last-child:after{display:block}@media only screen and (max-width:767px){.ui.steps:not(.unstackable){display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;overflow:visible;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.steps:not(.unstackable) .step{width:100%!important;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-radius:0;padding:1.14285714em 2em}.ui.steps:not(.unstackable) .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui.steps:not(.unstackable) .step:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.steps:not(.unstackable) .step:after{display:none!important}.ui.steps:not(.unstackable) .step .content{text-align:center}.ui.ordered.steps:not(.unstackable) .step:before,.ui.steps:not(.unstackable) .step>.icon{margin:0 0 1rem 0}}.ui.steps .link.step:hover,.ui.steps .link.step:hover::after,.ui.steps a.step:hover,.ui.steps a.step:hover::after{background:#f9fafb;color:rgba(0,0,0,.8)}.ui.steps .link.step:active,.ui.steps .link.step:active::after,.ui.steps a.step:active,.ui.steps a.step:active::after{background:#f3f4f5;color:rgba(0,0,0,.9)}.ui.steps .step.active{cursor:auto;background:#f3f4f5}.ui.steps .step.active:after{background:#f3f4f5}.ui.steps .step.active .title{color:#4183c4}.ui.ordered.steps .step.active:before,.ui.steps .active.step .icon{color:rgba(0,0,0,.85)}.ui.steps .step:after{display:block}.ui.steps .active.step:after{display:block}.ui.steps .step:last-child:after{display:none}.ui.steps .active.step:last-child:after{display:none}.ui.steps .link.active.step:hover,.ui.steps .link.active.step:hover::after,.ui.steps a.active.step:hover,.ui.steps a.active.step:hover::after{cursor:pointer;background:#dcddde;color:rgba(0,0,0,.87)}.ui.ordered.steps .step.completed:before,.ui.steps .step.completed>.icon:before{color:#21ba45}.ui.steps .disabled.step{cursor:auto;background:#fff;pointer-events:none}.ui.steps .disabled.step,.ui.steps .disabled.step .description,.ui.steps .disabled.step .title{color:rgba(40,40,40,.3)}.ui.steps .disabled.step:after{background:#fff}@media only screen and (max-width:991px){.ui[class*=\\\"tablet stackable\\\"].steps{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;overflow:visible;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui[class*=\\\"tablet stackable\\\"].steps .step{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-radius:0;padding:1.14285714em 2em}.ui[class*=\\\"tablet stackable\\\"].steps .step:first-child{padding:1.14285714em 2em;border-radius:.28571429rem .28571429rem 0 0}.ui[class*=\\\"tablet stackable\\\"].steps .step:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"tablet stackable\\\"].steps .step:after{display:none!important}.ui[class*=\\\"tablet stackable\\\"].steps .step .content{text-align:center}.ui[class*=\\\"tablet stackable\\\"].ordered.steps .step:before,.ui[class*=\\\"tablet stackable\\\"].steps .step>.icon{margin:0 0 1rem 0}}.ui.fluid.steps{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%}.ui.attached.steps{width:calc(100% + 2px)!important;margin:0 -1px 0;max-width:calc(100% + 2px);border-radius:.28571429rem .28571429rem 0 0}.ui.attached.steps .step:first-child{border-radius:.28571429rem 0 0 0}.ui.attached.steps .step:last-child{border-radius:0 .28571429rem 0 0}.ui.bottom.attached.steps{margin:0 -1px 0;border-radius:0 0 .28571429rem .28571429rem}.ui.bottom.attached.steps .step:first-child{border-radius:0 0 0 .28571429rem}.ui.bottom.attached.steps .step:last-child{border-radius:0 0 .28571429rem 0}.ui.eight.steps,.ui.five.steps,.ui.four.steps,.ui.one.steps,.ui.seven.steps,.ui.six.steps,.ui.three.steps,.ui.two.steps{width:100%}.ui.eight.steps>.step,.ui.five.steps>.step,.ui.four.steps>.step,.ui.one.steps>.step,.ui.seven.steps>.step,.ui.six.steps>.step,.ui.three.steps>.step,.ui.two.steps>.step{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.ui.one.steps>.step{width:100%}.ui.two.steps>.step{width:50%}.ui.three.steps>.step{width:33.333%}.ui.four.steps>.step{width:25%}.ui.five.steps>.step{width:20%}.ui.six.steps>.step{width:16.666%}.ui.seven.steps>.step{width:14.285%}.ui.eight.steps>.step{width:12.5%}.ui.mini.step,.ui.mini.steps .step{font-size:.78571429rem}.ui.tiny.step,.ui.tiny.steps .step{font-size:.85714286rem}.ui.small.step,.ui.small.steps .step{font-size:.92857143rem}.ui.step,.ui.steps .step{font-size:1rem}.ui.large.step,.ui.large.steps .step{font-size:1.14285714rem}.ui.big.step,.ui.big.steps .step{font-size:1.28571429rem}.ui.huge.step,.ui.huge.steps .step{font-size:1.42857143rem}.ui.massive.step,.ui.massive.steps .step{font-size:1.71428571rem}@font-face{font-family:Step;src:url(data:application/x-font-ttf;charset=utf-8;;base64,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) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,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) format('woff')}.ui.ordered.steps .step.completed:before,.ui.steps .step.completed>.icon:before{font-family:Step;content:'\\\\e800'}/*!\\n * # Semantic UI 2.4.0 - Breadcrumb\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.breadcrumb{line-height:1;display:inline-block;margin:0 0;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.7;margin:0 .21428571rem 0;font-size:.92857143em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#4183c4}.ui.breadcrumb a:hover{color:#1e70bf}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.78571429em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.78571429rem}.ui.tiny.breadcrumb{font-size:.85714286rem}.ui.small.breadcrumb{font-size:.92857143rem}.ui.breadcrumb{font-size:1rem}.ui.large.breadcrumb{font-size:1.14285714rem}.ui.big.breadcrumb{font-size:1.28571429rem}.ui.huge.breadcrumb{font-size:1.42857143rem}.ui.massive.breadcrumb{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Form\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.form{position:relative;max-width:100%}.ui.form>p{margin:1em 0}.ui.form .field{clear:both;margin:0 0 1em}.ui.form .field:last-child,.ui.form .fields:last-child .field{margin-bottom:0}.ui.form .fields .field{clear:both;margin:0}.ui.form .field>label{display:block;margin:0 0 .28571429rem 0;color:rgba(0,0,0,.87);font-size:.92857143em;font-weight:700;text-transform:none}.ui.form input:not([type]),.ui.form input[type=date],.ui.form input[type=datetime-local],.ui.form input[type=email],.ui.form input[type=file],.ui.form input[type=number],.ui.form input[type=password],.ui.form input[type=search],.ui.form input[type=tel],.ui.form input[type=text],.ui.form input[type=time],.ui.form input[type=url],.ui.form textarea{width:100%;vertical-align:top}.ui.form ::-webkit-datetime-edit,.ui.form ::-webkit-inner-spin-button{height:1.21428571em}.ui.form input:not([type]),.ui.form input[type=date],.ui.form input[type=datetime-local],.ui.form input[type=email],.ui.form input[type=file],.ui.form input[type=number],.ui.form input[type=password],.ui.form input[type=search],.ui.form input[type=tel],.ui.form input[type=text],.ui.form input[type=time],.ui.form input[type=url]{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;margin:0;outline:0;-webkit-appearance:none;tap-highlight-color:rgba(255,255,255,0);line-height:1.21428571em;padding:.67857143em 1em;font-size:1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease}.ui.form textarea{margin:0;-webkit-appearance:none;tap-highlight-color:rgba(255,255,255,0);padding:.78571429em 1em;background:#fff;border:1px solid rgba(34,36,38,.15);outline:0;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease;font-size:1em;line-height:1.2857;resize:vertical}.ui.form textarea:not([rows]){height:12em;min-height:8em;max-height:24em}.ui.form input[type=checkbox],.ui.form textarea{vertical-align:top}.ui.form input.attached{width:auto}.ui.form select{display:block;height:auto;width:100%;background:#fff;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;padding:.62em 1em;color:rgba(0,0,0,.87);-webkit-transition:color .1s ease,border-color .1s ease;transition:color .1s ease,border-color .1s ease}.ui.form .field>.selection.dropdown{width:100%}.ui.form .field>.selection.dropdown>.dropdown.icon{float:right}.ui.form .inline.field>.selection.dropdown,.ui.form .inline.fields .field>.selection.dropdown{width:auto}.ui.form .inline.field>.selection.dropdown>.dropdown.icon,.ui.form .inline.fields .field>.selection.dropdown>.dropdown.icon{float:none}.ui.form .field .ui.input,.ui.form .fields .field .ui.input,.ui.form .wide.field .ui.input{width:100%}.ui.form .inline.field:not(.wide) .ui.input,.ui.form .inline.fields .field:not(.wide) .ui.input{width:auto;vertical-align:middle}.ui.form .field .ui.input input,.ui.form .fields .field .ui.input input{width:auto}.ui.form .eight.fields .ui.input input,.ui.form .five.fields .ui.input input,.ui.form .four.fields .ui.input input,.ui.form .nine.fields .ui.input input,.ui.form .seven.fields .ui.input input,.ui.form .six.fields .ui.input input,.ui.form .ten.fields .ui.input input,.ui.form .three.fields .ui.input input,.ui.form .two.fields .ui.input input,.ui.form .wide.field .ui.input input{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;width:0}.ui.form .error.message,.ui.form .success.message,.ui.form .warning.message{display:none}.ui.form .message:first-child{margin-top:0}.ui.form .field .prompt.label{white-space:normal;background:#fff!important;border:1px solid #e0b4b4!important;color:#9f3a38!important}.ui.form .inline.field .prompt,.ui.form .inline.fields .field .prompt{vertical-align:top;margin:-.25em 0 -.5em .5em}.ui.form .inline.field .prompt:before,.ui.form .inline.fields .field .prompt:before{border-width:0 0 1px 1px;bottom:auto;right:auto;top:50%;left:0}.ui.form .field.field input:-webkit-autofill{-webkit-box-shadow:0 0 0 100px ivory inset!important;box-shadow:0 0 0 100px ivory inset!important;border-color:#e5dfa1!important}.ui.form .field.field input:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 100px ivory inset!important;box-shadow:0 0 0 100px ivory inset!important;border-color:#d5c315!important}.ui.form .error.error input:-webkit-autofill{-webkit-box-shadow:0 0 0 100px #fffaf0 inset!important;box-shadow:0 0 0 100px #fffaf0 inset!important;border-color:#e0b4b4!important}.ui.form ::-webkit-input-placeholder{color:rgba(191,191,191,.87)}.ui.form :-ms-input-placeholder{color:rgba(191,191,191,.87)!important}.ui.form ::-moz-placeholder{color:rgba(191,191,191,.87)}.ui.form :focus::-webkit-input-placeholder{color:rgba(115,115,115,.87)}.ui.form :focus:-ms-input-placeholder{color:rgba(115,115,115,.87)!important}.ui.form :focus::-moz-placeholder{color:rgba(115,115,115,.87)}.ui.form .error ::-webkit-input-placeholder{color:#e7bdbc}.ui.form .error :-ms-input-placeholder{color:#e7bdbc!important}.ui.form .error ::-moz-placeholder{color:#e7bdbc}.ui.form .error :focus::-webkit-input-placeholder{color:#da9796}.ui.form .error :focus:-ms-input-placeholder{color:#da9796!important}.ui.form .error :focus::-moz-placeholder{color:#da9796}.ui.form input:not([type]):focus,.ui.form input[type=date]:focus,.ui.form input[type=datetime-local]:focus,.ui.form input[type=email]:focus,.ui.form input[type=file]:focus,.ui.form input[type=number]:focus,.ui.form input[type=password]:focus,.ui.form input[type=search]:focus,.ui.form input[type=tel]:focus,.ui.form input[type=text]:focus,.ui.form input[type=time]:focus,.ui.form input[type=url]:focus{color:rgba(0,0,0,.95);border-color:#85b7d9;border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;box-shadow:0 0 0 0 rgba(34,36,38,.35) inset}.ui.form textarea:focus{color:rgba(0,0,0,.95);border-color:#85b7d9;border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;box-shadow:0 0 0 0 rgba(34,36,38,.35) inset;-webkit-appearance:none}.ui.form.success .success.message:not(:empty){display:block}.ui.form.success .compact.success.message:not(:empty){display:inline-block}.ui.form.success .icon.success.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form.warning .warning.message:not(:empty){display:block}.ui.form.warning .compact.warning.message:not(:empty){display:inline-block}.ui.form.warning .icon.warning.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form.error .error.message:not(:empty){display:block}.ui.form.error .compact.error.message:not(:empty){display:inline-block}.ui.form.error .icon.error.message:not(:empty){display:-webkit-box;display:-ms-flexbox;display:flex}.ui.form .field.error .input,.ui.form .field.error label,.ui.form .fields.error .field .input,.ui.form .fields.error .field label{color:#9f3a38}.ui.form .field.error .corner.label,.ui.form .fields.error .field .corner.label{border-color:#9f3a38;color:#fff}.ui.form .field.error input:not([type]),.ui.form .field.error input[type=date],.ui.form .field.error input[type=datetime-local],.ui.form .field.error input[type=email],.ui.form .field.error input[type=file],.ui.form .field.error input[type=number],.ui.form .field.error input[type=password],.ui.form .field.error input[type=search],.ui.form .field.error input[type=tel],.ui.form .field.error input[type=text],.ui.form .field.error input[type=time],.ui.form .field.error input[type=url],.ui.form .field.error select,.ui.form .field.error textarea,.ui.form .fields.error .field input:not([type]),.ui.form .fields.error .field input[type=date],.ui.form .fields.error .field input[type=datetime-local],.ui.form .fields.error .field input[type=email],.ui.form .fields.error .field input[type=file],.ui.form .fields.error .field input[type=number],.ui.form .fields.error .field input[type=password],.ui.form .fields.error .field input[type=search],.ui.form .fields.error .field input[type=tel],.ui.form .fields.error .field input[type=text],.ui.form .fields.error .field input[type=time],.ui.form .fields.error .field input[type=url],.ui.form .fields.error .field select,.ui.form .fields.error .field textarea{background:#fff6f6;border-color:#e0b4b4;color:#9f3a38;border-radius:'';-webkit-box-shadow:none;box-shadow:none}.ui.form .field.error input:not([type]):focus,.ui.form .field.error input[type=date]:focus,.ui.form .field.error input[type=datetime-local]:focus,.ui.form .field.error input[type=email]:focus,.ui.form .field.error input[type=file]:focus,.ui.form .field.error input[type=number]:focus,.ui.form .field.error input[type=password]:focus,.ui.form .field.error input[type=search]:focus,.ui.form .field.error input[type=tel]:focus,.ui.form .field.error input[type=text]:focus,.ui.form .field.error input[type=time]:focus,.ui.form .field.error input[type=url]:focus,.ui.form .field.error select:focus,.ui.form .field.error textarea:focus{background:#fff6f6;border-color:#e0b4b4;color:#9f3a38;-webkit-appearance:none;-webkit-box-shadow:none;box-shadow:none}.ui.form .field.error select{-webkit-appearance:menulist-button}.ui.form .field.error .ui.dropdown,.ui.form .field.error .ui.dropdown .item,.ui.form .field.error .ui.dropdown .text,.ui.form .fields.error .field .ui.dropdown,.ui.form .fields.error .field .ui.dropdown .item{background:#fff6f6;color:#9f3a38}.ui.form .field.error .ui.dropdown,.ui.form .fields.error .field .ui.dropdown{border-color:#e0b4b4!important}.ui.form .field.error .ui.dropdown:hover,.ui.form .fields.error .field .ui.dropdown:hover{border-color:#e0b4b4!important}.ui.form .field.error .ui.dropdown:hover .menu,.ui.form .fields.error .field .ui.dropdown:hover .menu{border-color:#e0b4b4}.ui.form .field.error .ui.multiple.selection.dropdown>.label,.ui.form .fields.error .field .ui.multiple.selection.dropdown>.label{background-color:#eacbcb;color:#9f3a38}.ui.form .field.error .ui.dropdown .menu .item:hover,.ui.form .fields.error .field .ui.dropdown .menu .item:hover{background-color:#fbe7e7}.ui.form .field.error .ui.dropdown .menu .selected.item,.ui.form .fields.error .field .ui.dropdown .menu .selected.item{background-color:#fbe7e7}.ui.form .field.error .ui.dropdown .menu .active.item,.ui.form .fields.error .field .ui.dropdown .menu .active.item{background-color:#fdcfcf!important}.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box,.ui.form .field.error .checkbox:not(.toggle):not(.slider) label,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) label{color:#9f3a38}.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box:before,.ui.form .field.error .checkbox:not(.toggle):not(.slider) label:before,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box:before,.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) label:before{background:#fff6f6;border-color:#e0b4b4}.ui.form .field.error .checkbox .box:after,.ui.form .field.error .checkbox label:after,.ui.form .fields.error .field .checkbox .box:after,.ui.form .fields.error .field .checkbox label:after{color:#9f3a38}.ui.form .disabled.field,.ui.form .disabled.fields .field,.ui.form .field :disabled{pointer-events:none;opacity:.45}.ui.form .field.disabled>label,.ui.form .fields.disabled>label{opacity:.45}.ui.form .field.disabled :disabled{opacity:1}.ui.loading.form{position:relative;cursor:default;pointer-events:none}.ui.loading.form:before{position:absolute;content:'';top:0;left:0;background:rgba(255,255,255,.8);width:100%;height:100%;z-index:100}.ui.loading.form:after{position:absolute;content:'';top:50%;left:50%;margin:-1.5em 0 0 -1.5em;width:3em;height:3em;-webkit-animation:form-spin .6s linear;animation:form-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.1);border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;visibility:visible;z-index:101}@-webkit-keyframes form-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes form-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.form .required.field>.checkbox:after,.ui.form .required.field>label:after,.ui.form .required.fields.grouped>label:after,.ui.form .required.fields:not(.grouped)>.field>.checkbox:after,.ui.form .required.fields:not(.grouped)>.field>label:after{margin:-.2em 0 0 .2em;content:'*';color:#db2828}.ui.form .required.field>label:after,.ui.form .required.fields.grouped>label:after,.ui.form .required.fields:not(.grouped)>.field>label:after{display:inline-block;vertical-align:top}.ui.form .required.field>.checkbox:after,.ui.form .required.fields:not(.grouped)>.field>.checkbox:after{position:absolute;top:0;left:100%}.ui.form .inverted.segment .ui.checkbox .box,.ui.form .inverted.segment .ui.checkbox label,.ui.form .inverted.segment label,.ui.inverted.form .inline.field>label,.ui.inverted.form .inline.field>p,.ui.inverted.form .inline.fields .field>label,.ui.inverted.form .inline.fields .field>p,.ui.inverted.form .inline.fields>label,.ui.inverted.form .ui.checkbox .box,.ui.inverted.form .ui.checkbox label,.ui.inverted.form label{color:rgba(255,255,255,.9)}.ui.inverted.form input:not([type]),.ui.inverted.form input[type=date],.ui.inverted.form input[type=datetime-local],.ui.inverted.form input[type=email],.ui.inverted.form input[type=file],.ui.inverted.form input[type=number],.ui.inverted.form input[type=password],.ui.inverted.form input[type=search],.ui.inverted.form input[type=tel],.ui.inverted.form input[type=text],.ui.inverted.form input[type=time],.ui.inverted.form input[type=url]{background:#fff;border-color:rgba(255,255,255,.1);color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none}.ui.form .grouped.fields{display:block;margin:0 0 1em}.ui.form .grouped.fields:last-child{margin-bottom:0}.ui.form .grouped.fields>label{margin:0 0 .28571429rem 0;color:rgba(0,0,0,.87);font-size:.92857143em;font-weight:700;text-transform:none}.ui.form .grouped.fields .field,.ui.form .grouped.inline.fields .field{display:block;margin:.5em 0;padding:0}.ui.form .fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin:0 -.5em 1em}.ui.form .fields>.field{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;padding-left:.5em;padding-right:.5em}.ui.form .fields>.field:first-child{border-left:none;-webkit-box-shadow:none;box-shadow:none}.ui.form .two.fields>.field,.ui.form .two.fields>.fields{width:50%}.ui.form .three.fields>.field,.ui.form .three.fields>.fields{width:33.33333333%}.ui.form .four.fields>.field,.ui.form .four.fields>.fields{width:25%}.ui.form .five.fields>.field,.ui.form .five.fields>.fields{width:20%}.ui.form .six.fields>.field,.ui.form .six.fields>.fields{width:16.66666667%}.ui.form .seven.fields>.field,.ui.form .seven.fields>.fields{width:14.28571429%}.ui.form .eight.fields>.field,.ui.form .eight.fields>.fields{width:12.5%}.ui.form .nine.fields>.field,.ui.form .nine.fields>.fields{width:11.11111111%}.ui.form .ten.fields>.field,.ui.form .ten.fields>.fields{width:10%}@media only screen and (max-width:767px){.ui.form .fields{-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.form:not(.unstackable) .eight.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .eight.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .nine.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .nine.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .seven.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .seven.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .six.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .six.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .ten.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .ten.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) [class*=\\\"equal width\\\"].fields:not(.unstackable)>.field,.ui[class*=\\\"equal width\\\"].form:not(.unstackable) .fields>.field{width:100%!important;margin:0 0 1em}}.ui.form .fields .wide.field{width:6.25%;padding-left:.5em;padding-right:.5em}.ui.form .one.wide.field{width:6.25%!important}.ui.form .two.wide.field{width:12.5%!important}.ui.form .three.wide.field{width:18.75%!important}.ui.form .four.wide.field{width:25%!important}.ui.form .five.wide.field{width:31.25%!important}.ui.form .six.wide.field{width:37.5%!important}.ui.form .seven.wide.field{width:43.75%!important}.ui.form .eight.wide.field{width:50%!important}.ui.form .nine.wide.field{width:56.25%!important}.ui.form .ten.wide.field{width:62.5%!important}.ui.form .eleven.wide.field{width:68.75%!important}.ui.form .twelve.wide.field{width:75%!important}.ui.form .thirteen.wide.field{width:81.25%!important}.ui.form .fourteen.wide.field{width:87.5%!important}.ui.form .fifteen.wide.field{width:93.75%!important}.ui.form .sixteen.wide.field{width:100%!important}@media only screen and (max-width:767px){.ui.form:not(.unstackable) .fields:not(.unstackable)>.eight.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.eleven.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.fifteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.five.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.four.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.fourteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.nine.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.seven.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.six.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.sixteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.ten.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.thirteen.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.three.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.twelve.wide.field,.ui.form:not(.unstackable) .fields:not(.unstackable)>.two.wide.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .five.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .four.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .three.fields:not(.unstackable)>.fields,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.field,.ui.form:not(.unstackable) .two.fields:not(.unstackable)>.fields{width:100%!important}.ui.form .fields{margin-bottom:0}}.ui.form [class*=\\\"equal width\\\"].fields>.field,.ui[class*=\\\"equal width\\\"].form .fields>.field{width:100%;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.ui.form .inline.fields{margin:0 0 1em;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.form .inline.fields .field{margin:0;padding:0 1em 0 0}.ui.form .inline.field>label,.ui.form .inline.field>p,.ui.form .inline.fields .field>label,.ui.form .inline.fields .field>p,.ui.form .inline.fields>label{display:inline-block;width:auto;margin-top:0;margin-bottom:0;vertical-align:baseline;font-size:.92857143em;font-weight:700;color:rgba(0,0,0,.87);text-transform:none}.ui.form .inline.fields>label{margin:.035714em 1em 0 0}.ui.form .inline.field>input,.ui.form .inline.field>select,.ui.form .inline.fields .field>input,.ui.form .inline.fields .field>select{display:inline-block;width:auto;margin-top:0;margin-bottom:0;vertical-align:middle;font-size:1em}.ui.form .inline.field>:first-child,.ui.form .inline.fields .field>:first-child{margin:0 .85714286em 0 0}.ui.form .inline.field>:only-child,.ui.form .inline.fields .field>:only-child{margin:0}.ui.form .inline.fields .wide.field{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.form .inline.fields .wide.field>input,.ui.form .inline.fields .wide.field>select{width:100%}.ui.mini.form{font-size:.78571429rem}.ui.tiny.form{font-size:.85714286rem}.ui.small.form{font-size:.92857143rem}.ui.form{font-size:1rem}.ui.large.form{font-size:1.14285714rem}.ui.big.form{font-size:1.28571429rem}.ui.huge.form{font-size:1.42857143rem}.ui.massive.form{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Grid\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.grid{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;padding:0}.ui.grid{margin-top:-1rem;margin-bottom:-1rem;margin-left:-1rem;margin-right:-1rem}.ui.relaxed.grid{margin-left:-1.5rem;margin-right:-1.5rem}.ui[class*=\\\"very relaxed\\\"].grid{margin-left:-2.5rem;margin-right:-2.5rem}.ui.grid+.grid{margin-top:1rem}.ui.grid>.column:not(.row),.ui.grid>.row>.column{position:relative;display:inline-block;width:6.25%;padding-left:1rem;padding-right:1rem;vertical-align:top}.ui.grid>*{padding-left:1rem;padding-right:1rem}.ui.grid>.row{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:inherit;-ms-flex-pack:inherit;justify-content:inherit;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%!important;padding:0;padding-top:1rem;padding-bottom:1rem}.ui.grid>.column:not(.row){padding-top:1rem;padding-bottom:1rem}.ui.grid>.row>.column{margin-top:0;margin-bottom:0}.ui.grid>.row>.column>img,.ui.grid>.row>img{max-width:100%}.ui.grid>.ui.grid:first-child{margin-top:0}.ui.grid>.ui.grid:last-child{margin-bottom:0}.ui.aligned.grid .column>.segment:not(.compact):not(.attached),.ui.grid .aligned.row>.column>.segment:not(.compact):not(.attached){width:100%}.ui.grid .row+.ui.divider{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;margin:1rem 1rem}.ui.grid .column+.ui.vertical.divider{height:calc(50% - 1rem)}.ui.grid>.column:last-child>.horizontal.segment,.ui.grid>.row>.column:last-child>.horizontal.segment{-webkit-box-shadow:none;box-shadow:none}@media only screen and (max-width:767px){.ui.page.grid{width:auto;padding-left:0;padding-right:0;margin-left:0;margin-right:0}}@media only screen and (min-width:768px) and (max-width:991px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:2em;padding-right:2em}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:3%;padding-right:3%}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:15%;padding-right:15%}}@media only screen and (min-width:1920px){.ui.page.grid{width:auto;margin-left:0;margin-right:0;padding-left:23%;padding-right:23%}}.ui.grid>.column:only-child,.ui.grid>.row>.column:only-child{width:100%}.ui[class*=\\\"one column\\\"].grid>.column:not(.row),.ui[class*=\\\"one column\\\"].grid>.row>.column{width:100%}.ui[class*=\\\"two column\\\"].grid>.column:not(.row),.ui[class*=\\\"two column\\\"].grid>.row>.column{width:50%}.ui[class*=\\\"three column\\\"].grid>.column:not(.row),.ui[class*=\\\"three column\\\"].grid>.row>.column{width:33.33333333%}.ui[class*=\\\"four column\\\"].grid>.column:not(.row),.ui[class*=\\\"four column\\\"].grid>.row>.column{width:25%}.ui[class*=\\\"five column\\\"].grid>.column:not(.row),.ui[class*=\\\"five column\\\"].grid>.row>.column{width:20%}.ui[class*=\\\"six column\\\"].grid>.column:not(.row),.ui[class*=\\\"six column\\\"].grid>.row>.column{width:16.66666667%}.ui[class*=\\\"seven column\\\"].grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].grid>.row>.column{width:14.28571429%}.ui[class*=\\\"eight column\\\"].grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].grid>.row>.column{width:12.5%}.ui[class*=\\\"nine column\\\"].grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].grid>.row>.column{width:11.11111111%}.ui[class*=\\\"ten column\\\"].grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].grid>.row>.column{width:10%}.ui[class*=\\\"eleven column\\\"].grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].grid>.row>.column{width:9.09090909%}.ui[class*=\\\"twelve column\\\"].grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].grid>.row>.column{width:8.33333333%}.ui[class*=\\\"thirteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].grid>.row>.column{width:7.69230769%}.ui[class*=\\\"fourteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].grid>.row>.column{width:7.14285714%}.ui[class*=\\\"fifteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].grid>.row>.column{width:6.66666667%}.ui[class*=\\\"sixteen column\\\"].grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].grid>.row>.column{width:6.25%}.ui.grid>[class*=\\\"one column\\\"].row>.column{width:100%!important}.ui.grid>[class*=\\\"two column\\\"].row>.column{width:50%!important}.ui.grid>[class*=\\\"three column\\\"].row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"four column\\\"].row>.column{width:25%!important}.ui.grid>[class*=\\\"five column\\\"].row>.column{width:20%!important}.ui.grid>[class*=\\\"six column\\\"].row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"seven column\\\"].row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"eight column\\\"].row>.column{width:12.5%!important}.ui.grid>[class*=\\\"nine column\\\"].row>.column{width:11.11111111%!important}.ui.grid>[class*=\\\"ten column\\\"].row>.column{width:10%!important}.ui.grid>[class*=\\\"eleven column\\\"].row>.column{width:9.09090909%!important}.ui.grid>[class*=\\\"twelve column\\\"].row>.column{width:8.33333333%!important}.ui.grid>[class*=\\\"thirteen column\\\"].row>.column{width:7.69230769%!important}.ui.grid>[class*=\\\"fourteen column\\\"].row>.column{width:7.14285714%!important}.ui.grid>[class*=\\\"fifteen column\\\"].row>.column{width:6.66666667%!important}.ui.grid>[class*=\\\"sixteen column\\\"].row>.column{width:6.25%!important}.ui.celled.page.grid{-webkit-box-shadow:none;box-shadow:none}.ui.column.grid>[class*=\\\"one wide\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide\\\"].column,.ui.grid>.row>[class*=\\\"one wide\\\"].column,.ui.grid>[class*=\\\"one wide\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide\\\"].column,.ui.grid>.row>[class*=\\\"two wide\\\"].column,.ui.grid>[class*=\\\"two wide\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide\\\"].column,.ui.grid>.row>[class*=\\\"three wide\\\"].column,.ui.grid>[class*=\\\"three wide\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide\\\"].column,.ui.grid>.row>[class*=\\\"four wide\\\"].column,.ui.grid>[class*=\\\"four wide\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide\\\"].column,.ui.grid>.row>[class*=\\\"five wide\\\"].column,.ui.grid>[class*=\\\"five wide\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide\\\"].column,.ui.grid>.row>[class*=\\\"six wide\\\"].column,.ui.grid>[class*=\\\"six wide\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide\\\"].column,.ui.grid>.row>[class*=\\\"seven wide\\\"].column,.ui.grid>[class*=\\\"seven wide\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide\\\"].column,.ui.grid>.row>[class*=\\\"eight wide\\\"].column,.ui.grid>[class*=\\\"eight wide\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide\\\"].column,.ui.grid>.row>[class*=\\\"nine wide\\\"].column,.ui.grid>[class*=\\\"nine wide\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide\\\"].column,.ui.grid>.row>[class*=\\\"ten wide\\\"].column,.ui.grid>[class*=\\\"ten wide\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide\\\"].column,.ui.grid>[class*=\\\"eleven wide\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide\\\"].column,.ui.grid>[class*=\\\"twelve wide\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide\\\"].column,.ui.grid>[class*=\\\"thirteen wide\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide\\\"].column,.ui.grid>[class*=\\\"fourteen wide\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide\\\"].column,.ui.grid>[class*=\\\"fifteen wide\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide\\\"].column,.ui.grid>[class*=\\\"sixteen wide\\\"].column{width:100%!important}@media only screen and (min-width:320px) and (max-width:767px){.ui.column.grid>[class*=\\\"one wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"one wide mobile\\\"].column,.ui.grid>[class*=\\\"one wide mobile\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"two wide mobile\\\"].column,.ui.grid>[class*=\\\"two wide mobile\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"three wide mobile\\\"].column,.ui.grid>[class*=\\\"three wide mobile\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"four wide mobile\\\"].column,.ui.grid>[class*=\\\"four wide mobile\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"five wide mobile\\\"].column,.ui.grid>[class*=\\\"five wide mobile\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"six wide mobile\\\"].column,.ui.grid>[class*=\\\"six wide mobile\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"seven wide mobile\\\"].column,.ui.grid>[class*=\\\"seven wide mobile\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"eight wide mobile\\\"].column,.ui.grid>[class*=\\\"eight wide mobile\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"nine wide mobile\\\"].column,.ui.grid>[class*=\\\"nine wide mobile\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"ten wide mobile\\\"].column,.ui.grid>[class*=\\\"ten wide mobile\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide mobile\\\"].column,.ui.grid>[class*=\\\"eleven wide mobile\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide mobile\\\"].column,.ui.grid>[class*=\\\"twelve wide mobile\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide mobile\\\"].column,.ui.grid>[class*=\\\"thirteen wide mobile\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide mobile\\\"].column,.ui.grid>[class*=\\\"fourteen wide mobile\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide mobile\\\"].column,.ui.grid>[class*=\\\"fifteen wide mobile\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide mobile\\\"].column,.ui.grid>[class*=\\\"sixteen wide mobile\\\"].column{width:100%!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.column.grid>[class*=\\\"one wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"one wide tablet\\\"].column,.ui.grid>[class*=\\\"one wide tablet\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"two wide tablet\\\"].column,.ui.grid>[class*=\\\"two wide tablet\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"three wide tablet\\\"].column,.ui.grid>[class*=\\\"three wide tablet\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"four wide tablet\\\"].column,.ui.grid>[class*=\\\"four wide tablet\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"five wide tablet\\\"].column,.ui.grid>[class*=\\\"five wide tablet\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"six wide tablet\\\"].column,.ui.grid>[class*=\\\"six wide tablet\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"seven wide tablet\\\"].column,.ui.grid>[class*=\\\"seven wide tablet\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"eight wide tablet\\\"].column,.ui.grid>[class*=\\\"eight wide tablet\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"nine wide tablet\\\"].column,.ui.grid>[class*=\\\"nine wide tablet\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"ten wide tablet\\\"].column,.ui.grid>[class*=\\\"ten wide tablet\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide tablet\\\"].column,.ui.grid>[class*=\\\"eleven wide tablet\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide tablet\\\"].column,.ui.grid>[class*=\\\"twelve wide tablet\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide tablet\\\"].column,.ui.grid>[class*=\\\"thirteen wide tablet\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide tablet\\\"].column,.ui.grid>[class*=\\\"fourteen wide tablet\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide tablet\\\"].column,.ui.grid>[class*=\\\"fifteen wide tablet\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide tablet\\\"].column,.ui.grid>[class*=\\\"sixteen wide tablet\\\"].column{width:100%!important}}@media only screen and (min-width:992px){.ui.column.grid>[class*=\\\"one wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide computer\\\"].column,.ui.grid>.row>[class*=\\\"one wide computer\\\"].column,.ui.grid>[class*=\\\"one wide computer\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide computer\\\"].column,.ui.grid>.row>[class*=\\\"two wide computer\\\"].column,.ui.grid>[class*=\\\"two wide computer\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide computer\\\"].column,.ui.grid>.row>[class*=\\\"three wide computer\\\"].column,.ui.grid>[class*=\\\"three wide computer\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide computer\\\"].column,.ui.grid>.row>[class*=\\\"four wide computer\\\"].column,.ui.grid>[class*=\\\"four wide computer\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide computer\\\"].column,.ui.grid>.row>[class*=\\\"five wide computer\\\"].column,.ui.grid>[class*=\\\"five wide computer\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide computer\\\"].column,.ui.grid>.row>[class*=\\\"six wide computer\\\"].column,.ui.grid>[class*=\\\"six wide computer\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide computer\\\"].column,.ui.grid>.row>[class*=\\\"seven wide computer\\\"].column,.ui.grid>[class*=\\\"seven wide computer\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide computer\\\"].column,.ui.grid>.row>[class*=\\\"eight wide computer\\\"].column,.ui.grid>[class*=\\\"eight wide computer\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide computer\\\"].column,.ui.grid>.row>[class*=\\\"nine wide computer\\\"].column,.ui.grid>[class*=\\\"nine wide computer\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide computer\\\"].column,.ui.grid>.row>[class*=\\\"ten wide computer\\\"].column,.ui.grid>[class*=\\\"ten wide computer\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide computer\\\"].column,.ui.grid>[class*=\\\"eleven wide computer\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide computer\\\"].column,.ui.grid>[class*=\\\"twelve wide computer\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide computer\\\"].column,.ui.grid>[class*=\\\"thirteen wide computer\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide computer\\\"].column,.ui.grid>[class*=\\\"fourteen wide computer\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide computer\\\"].column,.ui.grid>[class*=\\\"fifteen wide computer\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide computer\\\"].column,.ui.grid>[class*=\\\"sixteen wide computer\\\"].column{width:100%!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.column.grid>[class*=\\\"one wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"one wide large screen\\\"].column,.ui.grid>[class*=\\\"one wide large screen\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"two wide large screen\\\"].column,.ui.grid>[class*=\\\"two wide large screen\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"three wide large screen\\\"].column,.ui.grid>[class*=\\\"three wide large screen\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"four wide large screen\\\"].column,.ui.grid>[class*=\\\"four wide large screen\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"five wide large screen\\\"].column,.ui.grid>[class*=\\\"five wide large screen\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"six wide large screen\\\"].column,.ui.grid>[class*=\\\"six wide large screen\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"seven wide large screen\\\"].column,.ui.grid>[class*=\\\"seven wide large screen\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"eight wide large screen\\\"].column,.ui.grid>[class*=\\\"eight wide large screen\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"nine wide large screen\\\"].column,.ui.grid>[class*=\\\"nine wide large screen\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"ten wide large screen\\\"].column,.ui.grid>[class*=\\\"ten wide large screen\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide large screen\\\"].column,.ui.grid>[class*=\\\"eleven wide large screen\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide large screen\\\"].column,.ui.grid>[class*=\\\"twelve wide large screen\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide large screen\\\"].column,.ui.grid>[class*=\\\"thirteen wide large screen\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide large screen\\\"].column,.ui.grid>[class*=\\\"fourteen wide large screen\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide large screen\\\"].column,.ui.grid>[class*=\\\"fifteen wide large screen\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide large screen\\\"].column,.ui.grid>[class*=\\\"sixteen wide large screen\\\"].column{width:100%!important}}@media only screen and (min-width:1920px){.ui.column.grid>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"one wide widescreen\\\"].column,.ui.grid>[class*=\\\"one wide widescreen\\\"].column{width:6.25%!important}.ui.column.grid>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"two wide widescreen\\\"].column,.ui.grid>[class*=\\\"two wide widescreen\\\"].column{width:12.5%!important}.ui.column.grid>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"three wide widescreen\\\"].column,.ui.grid>[class*=\\\"three wide widescreen\\\"].column{width:18.75%!important}.ui.column.grid>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"four wide widescreen\\\"].column,.ui.grid>[class*=\\\"four wide widescreen\\\"].column{width:25%!important}.ui.column.grid>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"five wide widescreen\\\"].column,.ui.grid>[class*=\\\"five wide widescreen\\\"].column{width:31.25%!important}.ui.column.grid>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"six wide widescreen\\\"].column,.ui.grid>[class*=\\\"six wide widescreen\\\"].column{width:37.5%!important}.ui.column.grid>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"seven wide widescreen\\\"].column,.ui.grid>[class*=\\\"seven wide widescreen\\\"].column{width:43.75%!important}.ui.column.grid>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"eight wide widescreen\\\"].column,.ui.grid>[class*=\\\"eight wide widescreen\\\"].column{width:50%!important}.ui.column.grid>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"nine wide widescreen\\\"].column,.ui.grid>[class*=\\\"nine wide widescreen\\\"].column{width:56.25%!important}.ui.column.grid>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"ten wide widescreen\\\"].column,.ui.grid>[class*=\\\"ten wide widescreen\\\"].column{width:62.5%!important}.ui.column.grid>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"eleven wide widescreen\\\"].column,.ui.grid>[class*=\\\"eleven wide widescreen\\\"].column{width:68.75%!important}.ui.column.grid>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"twelve wide widescreen\\\"].column,.ui.grid>[class*=\\\"twelve wide widescreen\\\"].column{width:75%!important}.ui.column.grid>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"thirteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"thirteen wide widescreen\\\"].column{width:81.25%!important}.ui.column.grid>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"fourteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"fourteen wide widescreen\\\"].column{width:87.5%!important}.ui.column.grid>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"fifteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"fifteen wide widescreen\\\"].column{width:93.75%!important}.ui.column.grid>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>.column.row>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>.row>[class*=\\\"sixteen wide widescreen\\\"].column,.ui.grid>[class*=\\\"sixteen wide widescreen\\\"].column{width:100%!important}}.ui.centered.grid,.ui.centered.grid>.row,.ui.grid>.centered.row{text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.centered.grid>.column:not(.aligned):not(.justified):not(.row),.ui.centered.grid>.row>.column:not(.aligned):not(.justified),.ui.grid .centered.row>.column:not(.aligned):not(.justified){text-align:left}.ui.grid>.centered.column,.ui.grid>.row>.centered.column{display:block;margin-left:auto;margin-right:auto}.ui.grid>.relaxed.row>.column,.ui.relaxed.grid>.column:not(.row),.ui.relaxed.grid>.row>.column{padding-left:1.5rem;padding-right:1.5rem}.ui.grid>[class*=\\\"very relaxed\\\"].row>.column,.ui[class*=\\\"very relaxed\\\"].grid>.column:not(.row),.ui[class*=\\\"very relaxed\\\"].grid>.row>.column{padding-left:2.5rem;padding-right:2.5rem}.ui.grid .relaxed.row+.ui.divider,.ui.relaxed.grid .row+.ui.divider{margin-left:1.5rem;margin-right:1.5rem}.ui.grid [class*=\\\"very relaxed\\\"].row+.ui.divider,.ui[class*=\\\"very relaxed\\\"].grid .row+.ui.divider{margin-left:2.5rem;margin-right:2.5rem}.ui.padded.grid:not(.vertically):not(.horizontally){margin:0!important}[class*=\\\"horizontally padded\\\"].ui.grid{margin-left:0!important;margin-right:0!important}[class*=\\\"vertically padded\\\"].ui.grid{margin-top:0!important;margin-bottom:0!important}.ui.grid [class*=\\\"left floated\\\"].column{margin-right:auto}.ui.grid [class*=\\\"right floated\\\"].column{margin-left:auto}.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row),.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"vertically divided\\\"].grid>.column:not(.row),.ui[class*=\\\"vertically divided\\\"].grid>.row>.column{margin-top:1rem;margin-bottom:1rem;padding-top:0;padding-bottom:0}.ui[class*=\\\"vertically divided\\\"].grid>.row{margin-top:0;margin-bottom:0}.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"vertically divided\\\"].grid>.row:first-child>.column{margin-top:0}.ui.grid>.divided.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui.grid>.divided.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"vertically divided\\\"].grid>.row{position:relative}.ui[class*=\\\"vertically divided\\\"].grid>.row:before{position:absolute;content:\\\"\\\";top:0;left:0;width:calc(100% - 2rem);height:1px;margin:0 1rem;-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.padded.divided.grid:not(.vertically):not(.horizontally),[class*=\\\"horizontally padded\\\"].ui.divided.grid{width:100%}.ui[class*=\\\"vertically divided\\\"].grid>.row:first-child:before{-webkit-box-shadow:none;box-shadow:none}.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row),.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column{-webkit-box-shadow:-1px 0 0 0 rgba(255,255,255,.1);box-shadow:-1px 0 0 0 rgba(255,255,255,.1)}.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.column:not(.row):first-child,.ui.inverted.divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.inverted[class*=\\\"vertically divided\\\"].grid>.row:before{-webkit-box-shadow:0 -1px 0 0 rgba(255,255,255,.1);box-shadow:0 -1px 0 0 rgba(255,255,255,.1)}.ui.relaxed[class*=\\\"vertically divided\\\"].grid>.row:before{margin-left:1.5rem;margin-right:1.5rem;width:calc(100% - 3rem)}.ui[class*=\\\"very relaxed\\\"][class*=\\\"vertically divided\\\"].grid>.row:before{margin-left:5rem;margin-right:5rem;width:calc(100% - 5rem)}.ui.celled.grid{width:100%;margin:1em 0;-webkit-box-shadow:0 0 0 1px #d4d4d5;box-shadow:0 0 0 1px #d4d4d5}.ui.celled.grid>.row{width:100%!important;margin:0;padding:0;-webkit-box-shadow:0 -1px 0 0 #d4d4d5;box-shadow:0 -1px 0 0 #d4d4d5}.ui.celled.grid>.column:not(.row),.ui.celled.grid>.row>.column{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui.celled.grid>.column:first-child,.ui.celled.grid>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.celled.grid>.column:not(.row),.ui.celled.grid>.row>.column{padding:1em}.ui.relaxed.celled.grid>.column:not(.row),.ui.relaxed.celled.grid>.row>.column{padding:1.5em}.ui[class*=\\\"very relaxed\\\"].celled.grid>.column:not(.row),.ui[class*=\\\"very relaxed\\\"].celled.grid>.row>.column{padding:2em}.ui[class*=\\\"internally celled\\\"].grid{-webkit-box-shadow:none;box-shadow:none;margin:0}.ui[class*=\\\"internally celled\\\"].grid>.row:first-child{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"internally celled\\\"].grid>.row>.column:first-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid>.row>[class*=\\\"top aligned\\\"].column,.ui.grid>[class*=\\\"top aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"top aligned\\\"].row>.column,.ui[class*=\\\"top aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"top aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:top;-ms-flex-item-align:start!important;align-self:flex-start!important}.ui.grid>.row>[class*=\\\"middle aligned\\\"].column,.ui.grid>[class*=\\\"middle aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"middle aligned\\\"].row>.column,.ui[class*=\\\"middle aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"middle aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:middle;-ms-flex-item-align:center!important;align-self:center!important}.ui.grid>.row>[class*=\\\"bottom aligned\\\"].column,.ui.grid>[class*=\\\"bottom aligned\\\"].column:not(.row),.ui.grid>[class*=\\\"bottom aligned\\\"].row>.column,.ui[class*=\\\"bottom aligned\\\"].grid>.column:not(.row),.ui[class*=\\\"bottom aligned\\\"].grid>.row>.column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;vertical-align:bottom;-ms-flex-item-align:end!important;align-self:flex-end!important}.ui.grid>.row>.stretched.column,.ui.grid>.stretched.column:not(.row),.ui.grid>.stretched.row>.column,.ui.stretched.grid>.column,.ui.stretched.grid>.row>.column{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important;-ms-flex-item-align:stretch;align-self:stretch;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.grid>.row>.stretched.column>*,.ui.grid>.stretched.column:not(.row)>*,.ui.grid>.stretched.row>.column>*,.ui.stretched.grid>.column>*,.ui.stretched.grid>.row>.column>*{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.ui.grid>.row>[class*=\\\"left aligned\\\"].column.column,.ui.grid>[class*=\\\"left aligned\\\"].column.column,.ui.grid>[class*=\\\"left aligned\\\"].row>.column,.ui[class*=\\\"left aligned\\\"].grid>.column,.ui[class*=\\\"left aligned\\\"].grid>.row>.column{text-align:left;-ms-flex-item-align:inherit;align-self:inherit}.ui.grid>.row>[class*=\\\"center aligned\\\"].column.column,.ui.grid>[class*=\\\"center aligned\\\"].column.column,.ui.grid>[class*=\\\"center aligned\\\"].row>.column,.ui[class*=\\\"center aligned\\\"].grid>.column,.ui[class*=\\\"center aligned\\\"].grid>.row>.column{text-align:center;-ms-flex-item-align:inherit;align-self:inherit}.ui[class*=\\\"center aligned\\\"].grid{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.grid>.row>[class*=\\\"right aligned\\\"].column.column,.ui.grid>[class*=\\\"right aligned\\\"].column.column,.ui.grid>[class*=\\\"right aligned\\\"].row>.column,.ui[class*=\\\"right aligned\\\"].grid>.column,.ui[class*=\\\"right aligned\\\"].grid>.row>.column{text-align:right;-ms-flex-item-align:inherit;align-self:inherit}.ui.grid>.justified.column.column,.ui.grid>.justified.row>.column,.ui.grid>.row>.justified.column.column,.ui.justified.grid>.column,.ui.justified.grid>.row>.column{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.ui.grid>.row>.black.column,.ui.grid>.row>.blue.column,.ui.grid>.row>.brown.column,.ui.grid>.row>.green.column,.ui.grid>.row>.grey.column,.ui.grid>.row>.olive.column,.ui.grid>.row>.orange.column,.ui.grid>.row>.pink.column,.ui.grid>.row>.purple.column,.ui.grid>.row>.red.column,.ui.grid>.row>.teal.column,.ui.grid>.row>.violet.column,.ui.grid>.row>.yellow.column{margin-top:-1rem;margin-bottom:-1rem;padding-top:1rem;padding-bottom:1rem}.ui.grid>.red.column,.ui.grid>.red.row,.ui.grid>.row>.red.column{background-color:#db2828!important;color:#fff}.ui.grid>.orange.column,.ui.grid>.orange.row,.ui.grid>.row>.orange.column{background-color:#f2711c!important;color:#fff}.ui.grid>.row>.yellow.column,.ui.grid>.yellow.column,.ui.grid>.yellow.row{background-color:#fbbd08!important;color:#fff}.ui.grid>.olive.column,.ui.grid>.olive.row,.ui.grid>.row>.olive.column{background-color:#b5cc18!important;color:#fff}.ui.grid>.green.column,.ui.grid>.green.row,.ui.grid>.row>.green.column{background-color:#21ba45!important;color:#fff}.ui.grid>.row>.teal.column,.ui.grid>.teal.column,.ui.grid>.teal.row{background-color:#00b5ad!important;color:#fff}.ui.grid>.blue.column,.ui.grid>.blue.row,.ui.grid>.row>.blue.column{background-color:#2185d0!important;color:#fff}.ui.grid>.row>.violet.column,.ui.grid>.violet.column,.ui.grid>.violet.row{background-color:#6435c9!important;color:#fff}.ui.grid>.purple.column,.ui.grid>.purple.row,.ui.grid>.row>.purple.column{background-color:#a333c8!important;color:#fff}.ui.grid>.pink.column,.ui.grid>.pink.row,.ui.grid>.row>.pink.column{background-color:#e03997!important;color:#fff}.ui.grid>.brown.column,.ui.grid>.brown.row,.ui.grid>.row>.brown.column{background-color:#a5673f!important;color:#fff}.ui.grid>.grey.column,.ui.grid>.grey.row,.ui.grid>.row>.grey.column{background-color:#767676!important;color:#fff}.ui.grid>.black.column,.ui.grid>.black.row,.ui.grid>.row>.black.column{background-color:#1b1c1d!important;color:#fff}.ui.grid>[class*=\\\"equal width\\\"].row>.column,.ui[class*=\\\"equal width\\\"].grid>.column:not(.row),.ui[class*=\\\"equal width\\\"].grid>.row>.column{display:inline-block;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.ui.grid>[class*=\\\"equal width\\\"].row>.wide.column,.ui[class*=\\\"equal width\\\"].grid>.row>.wide.column,.ui[class*=\\\"equal width\\\"].grid>.wide.column{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}@media only screen and (max-width:767px){.ui.grid>[class*=\\\"mobile reversed\\\"].row,.ui[class*=\\\"mobile reversed\\\"].grid,.ui[class*=\\\"mobile reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui.stackable[class*=\\\"mobile reversed\\\"],.ui[class*=\\\"mobile vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"mobile reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"mobile vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"mobile vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"mobile reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"mobile reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:768px) and (max-width:991px){.ui.grid>[class*=\\\"tablet reversed\\\"].row,.ui[class*=\\\"tablet reversed\\\"].grid,.ui[class*=\\\"tablet reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui[class*=\\\"tablet vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"tablet reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"tablet vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"tablet vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"tablet reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"tablet reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:992px){.ui.grid>[class*=\\\"computer reversed\\\"].row,.ui[class*=\\\"computer reversed\\\"].grid,.ui[class*=\\\"computer reversed\\\"].grid>.row{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.ui[class*=\\\"computer vertically reversed\\\"].grid{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:first-child,.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 0 rgba(34,36,38,.15)}.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.column:last-child,.ui[class*=\\\"computer reversed\\\"].divided.grid:not([class*=\\\"vertically divided\\\"])>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"computer vertically reversed\\\"]>.row:first-child:before{-webkit-box-shadow:0 -1px 0 0 rgba(34,36,38,.15);box-shadow:0 -1px 0 0 rgba(34,36,38,.15)}.ui.grid[class*=\\\"vertically divided\\\"][class*=\\\"computer vertically reversed\\\"]>.row:last-child:before{-webkit-box-shadow:none;box-shadow:none}.ui[class*=\\\"computer reversed\\\"].celled.grid>.row>.column:first-child{-webkit-box-shadow:-1px 0 0 0 #d4d4d5;box-shadow:-1px 0 0 0 #d4d4d5}.ui[class*=\\\"computer reversed\\\"].celled.grid>.row>.column:last-child{-webkit-box-shadow:none;box-shadow:none}}@media only screen and (min-width:768px) and (max-width:991px){.ui.doubling.grid{width:auto}.ui.doubling.grid>.row,.ui.grid>.doubling.row{margin:0!important;padding:0!important}.ui.doubling.grid>.row>.column,.ui.grid>.doubling.row>.column{display:inline-block!important;padding-top:1rem!important;padding-bottom:1rem!important;-webkit-box-shadow:none!important;box-shadow:none!important;margin:0}.ui.grid>[class*=\\\"two column\\\"].doubling.row.row>.column,.ui[class*=\\\"two column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"two column\\\"].doubling.grid>.row>.column{width:100%!important}.ui.grid>[class*=\\\"three column\\\"].doubling.row.row>.column,.ui[class*=\\\"three column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"three column\\\"].doubling.grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"four column\\\"].doubling.row.row>.column,.ui[class*=\\\"four column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"four column\\\"].doubling.grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"five column\\\"].doubling.row.row>.column,.ui[class*=\\\"five column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"five column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"six column\\\"].doubling.row.row>.column,.ui[class*=\\\"six column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"six column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"seven column\\\"].doubling.row.row>.column,.ui[class*=\\\"seven column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].doubling.grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"eight column\\\"].doubling.row.row>.column,.ui[class*=\\\"eight column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].doubling.grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"nine column\\\"].doubling.row.row>.column,.ui[class*=\\\"nine column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].doubling.grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"ten column\\\"].doubling.row.row>.column,.ui[class*=\\\"ten column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].doubling.grid>.row>.column{width:20%!important}.ui.grid>[class*=\\\"eleven column\\\"].doubling.row.row>.column,.ui[class*=\\\"eleven column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].doubling.grid>.row>.column{width:20%!important}.ui.grid>[class*=\\\"twelve column\\\"].doubling.row.row>.column,.ui[class*=\\\"twelve column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].doubling.grid>.row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"thirteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"thirteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].doubling.grid>.row>.column{width:16.66666667%!important}.ui.grid>[class*=\\\"fourteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"fourteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].doubling.grid>.row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"fifteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"fifteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].doubling.grid>.row>.column{width:14.28571429%!important}.ui.grid>[class*=\\\"sixteen column\\\"].doubling.row.row>.column,.ui[class*=\\\"sixteen column\\\"].doubling.grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].doubling.grid>.row>.column{width:12.5%!important}}@media only screen and (max-width:767px){.ui.doubling.grid>.row,.ui.grid>.doubling.row{margin:0!important;padding:0!important}.ui.doubling.grid>.row>.column,.ui.grid>.doubling.row>.column{padding-top:1rem!important;padding-bottom:1rem!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.grid>[class*=\\\"two column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"two column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"two column\\\"].doubling:not(.stackable).grid>.row>.column{width:100%!important}.ui.grid>[class*=\\\"three column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"three column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"three column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"four column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"four column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"four column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"five column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"five column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"five column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"six column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"six column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"six column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"seven column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"seven column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"seven column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"eight column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"eight column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"eight column\\\"].doubling:not(.stackable).grid>.row>.column{width:50%!important}.ui.grid>[class*=\\\"nine column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"nine column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"nine column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"ten column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"ten column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"ten column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"eleven column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"eleven column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"eleven column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"twelve column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"twelve column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"twelve column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"thirteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"thirteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"thirteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:33.33333333%!important}.ui.grid>[class*=\\\"fourteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"fourteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"fourteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"fifteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"fifteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"fifteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}.ui.grid>[class*=\\\"sixteen column\\\"].doubling:not(.stackable).row.row>.column,.ui[class*=\\\"sixteen column\\\"].doubling:not(.stackable).grid>.column:not(.row),.ui[class*=\\\"sixteen column\\\"].doubling:not(.stackable).grid>.row>.column{width:25%!important}}@media only screen and (max-width:767px){.ui.stackable.grid{width:auto;margin-left:0!important;margin-right:0!important}.ui.grid>.stackable.stackable.row>.column,.ui.stackable.grid>.column.grid>.column,.ui.stackable.grid>.column.row>.column,.ui.stackable.grid>.column:not(.row),.ui.stackable.grid>.row>.column,.ui.stackable.grid>.row>.wide.column,.ui.stackable.grid>.wide.column{width:100%!important;margin:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important;padding:1rem 1rem!important}.ui.stackable.grid:not(.vertically)>.row{margin:0;padding:0}.ui.container>.ui.stackable.grid>.column,.ui.container>.ui.stackable.grid>.row>.column{padding-left:0!important;padding-right:0!important}.ui.grid .ui.stackable.grid,.ui.segment:not(.vertical) .ui.stackable.page.grid{margin-left:-1rem!important;margin-right:-1rem!important}.ui.stackable.celled.grid>.column:not(.row):first-child,.ui.stackable.celled.grid>.row:first-child>.column:first-child,.ui.stackable.divided.grid>.column:not(.row):first-child,.ui.stackable.divided.grid>.row:first-child>.column:first-child{border-top:none!important}.ui.inverted.stackable.celled.grid>.column:not(.row),.ui.inverted.stackable.celled.grid>.row>.column,.ui.inverted.stackable.divided.grid>.column:not(.row),.ui.inverted.stackable.divided.grid>.row>.column{border-top:1px solid rgba(255,255,255,.1)}.ui.stackable.celled.grid>.column:not(.row),.ui.stackable.celled.grid>.row>.column,.ui.stackable.divided:not(.vertically).grid>.column:not(.row),.ui.stackable.divided:not(.vertically).grid>.row>.column{border-top:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none!important;box-shadow:none!important;padding-top:2rem!important;padding-bottom:2rem!important}.ui.stackable.celled.grid>.row{-webkit-box-shadow:none!important;box-shadow:none!important}.ui.stackable.divided:not(.vertically).grid>.column:not(.row),.ui.stackable.divided:not(.vertically).grid>.row>.column{padding-left:0!important;padding-right:0!important}}@media only screen and (max-width:767px){.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.mobile),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"computer only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].row:not(.mobile),.ui[class*=\\\"computer only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.tablet),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.tablet){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"computer only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].column:not(.tablet),.ui.grid.grid.grid>[class*=\\\"computer only\\\"].row:not(.tablet),.ui[class*=\\\"computer only\\\"].grid.grid.grid:not(.tablet){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"large screen only\\\"].row:not(.mobile),.ui[class*=\\\"large screen only\\\"].grid.grid.grid:not(.mobile){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].column:not(.mobile),.ui.grid.grid.grid>[class*=\\\"widescreen only\\\"].row:not(.mobile),.ui[class*=\\\"widescreen only\\\"].grid.grid.grid:not(.mobile){display:none!important}}@media only screen and (min-width:1920px){.ui.grid.grid.grid>.row>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"mobile only\\\"].row:not(.computer),.ui[class*=\\\"mobile only\\\"].grid.grid.grid:not(.computer){display:none!important}.ui.grid.grid.grid>.row>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].column:not(.computer),.ui.grid.grid.grid>[class*=\\\"tablet only\\\"].row:not(.computer),.ui[class*=\\\"tablet only\\\"].grid.grid.grid:not(.computer){display:none!important}}.ui.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1rem 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;background:#fff;font-weight:400;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15);border-radius:.28571429rem;min-height:2.85714286em}.ui.menu:after{content:'';display:block;height:0;clear:both;visibility:hidden}.ui.menu:first-child{margin-top:0}.ui.menu:last-child{margin-bottom:0}.ui.menu .menu{margin:0}.ui.menu:not(.vertical)>.menu{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.menu:not(.vertical) .item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.menu .item{position:relative;vertical-align:middle;line-height:1;text-decoration:none;-webkit-tap-highlight-color:transparent;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:0 0;padding:.92857143em 1.14285714em;text-transform:none;color:rgba(0,0,0,.87);font-weight:400;-webkit-transition:background .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background .1s ease,color .1s ease,-webkit-box-shadow .1s ease;transition:background .1s ease,box-shadow .1s ease,color .1s ease;transition:background .1s ease,box-shadow .1s ease,color .1s ease,-webkit-box-shadow .1s ease}.ui.menu>.item:first-child{border-radius:.28571429rem 0 0 .28571429rem}.ui.menu .item:before{position:absolute;content:'';top:0;right:0;height:100%;width:1px;background:rgba(34,36,38,.1)}.ui.menu .item>a:not(.ui),.ui.menu .item>p:only-child,.ui.menu .text.item>*{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;line-height:1.3}.ui.menu .item>p:first-child{margin-top:0}.ui.menu .item>p:last-child{margin-bottom:0}.ui.menu .item>i.icon{opacity:.9;float:none;margin:0 .35714286em 0 0}.ui.menu:not(.vertical) .item>.button{position:relative;top:0;margin:-.5em 0;padding-bottom:.78571429em;padding-top:.78571429em;font-size:1em}.ui.menu>.container,.ui.menu>.grid{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:inherit;-ms-flex-align:inherit;align-items:inherit;-webkit-box-orient:inherit;-webkit-box-direction:inherit;-ms-flex-direction:inherit;flex-direction:inherit}.ui.menu .item>.input{width:100%}.ui.menu:not(.vertical) .item>.input{position:relative;top:0;margin:-.5em 0}.ui.menu .item>.input input{font-size:1em;padding-top:.57142857em;padding-bottom:.57142857em}.ui.menu .header.item,.ui.vertical.menu .header.item{margin:0;background:'';text-transform:normal;font-weight:700}.ui.vertical.menu .item>.header:not(.ui){margin:0 0 .5em;font-size:1em;font-weight:700}.ui.menu .item>i.dropdown.icon{padding:0;float:right;margin:0 0 0 1em}.ui.menu .dropdown.item .menu{min-width:calc(100% - 1px);border-radius:0 0 .28571429rem .28571429rem;background:#fff;margin:0 0 0;-webkit-box-shadow:0 1px 3px 0 rgba(0,0,0,.08);box-shadow:0 1px 3px 0 rgba(0,0,0,.08);-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.ui.menu .ui.dropdown .menu>.item{margin:0;text-align:left;font-size:1em!important;padding:.78571429em 1.14285714em!important;background:0 0!important;color:rgba(0,0,0,.87)!important;text-transform:none!important;font-weight:400!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-transition:none!important;transition:none!important}.ui.menu .ui.dropdown .menu>.item:hover{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown .menu>.selected.item{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown .menu>.active.item{background:rgba(0,0,0,.03)!important;font-weight:700!important;color:rgba(0,0,0,.95)!important}.ui.menu .ui.dropdown.item .menu .item:not(.filtered){display:block}.ui.menu .ui.dropdown .menu>.item .icon:not(.dropdown){display:inline-block;font-size:1em!important;float:none;margin:0 .75em 0 0!important}.ui.secondary.menu .dropdown.item>.menu,.ui.text.menu .dropdown.item>.menu{border-radius:.28571429rem;margin-top:.35714286em}.ui.menu .pointing.dropdown.item .menu{margin-top:.75em}.ui.inverted.menu .search.dropdown.item>.search,.ui.inverted.menu .search.dropdown.item>.text{color:rgba(255,255,255,.9)}.ui.vertical.menu .dropdown.item>.icon{float:right;content:\\\"\\\\f0da\\\";margin-left:1em}.ui.vertical.menu .dropdown.item .menu{left:100%;min-width:0;margin:0;-webkit-box-shadow:0 1px 3px 0 rgba(0,0,0,.08);box-shadow:0 1px 3px 0 rgba(0,0,0,.08);border-radius:0 .28571429rem .28571429rem .28571429rem}.ui.vertical.menu .dropdown.item.upward .menu{bottom:0}.ui.vertical.menu .dropdown.item:not(.upward) .menu{top:0}.ui.vertical.menu .active.dropdown.item{border-top-right-radius:0;border-bottom-right-radius:0}.ui.vertical.menu .dropdown.active.item{-webkit-box-shadow:none;box-shadow:none}.ui.item.menu .dropdown .menu .item{width:100%}.ui.menu .item>.label{background:#999;color:#fff;margin-left:1em;padding:.3em .78571429em}.ui.vertical.menu .item>.label{background:#999;color:#fff;margin-top:-.15em;margin-bottom:-.15em;padding:.3em .78571429em}.ui.menu .item>.floating.label{padding:.3em .78571429em}.ui.menu .item>img:not(.ui){display:inline-block;vertical-align:middle;margin:-.3em 0;width:2.5em}.ui.vertical.menu .item>img:not(.ui):only-child{display:block;max-width:100%;width:auto}.ui.menu .list .item:before{background:0 0!important}.ui.vertical.sidebar.menu>.item:first-child:before{display:block!important}.ui.vertical.sidebar.menu>.item::before{top:auto;bottom:0}@media only screen and (max-width:767px){.ui.menu>.ui.container{width:100%!important;margin-left:0!important;margin-right:0!important}}@media only screen and (min-width:768px){.ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless)>.container>.item:not(.right):not(.borderless):first-child{border-left:1px solid rgba(34,36,38,.1)}}.ui.link.menu .item:hover,.ui.menu .dropdown.item:hover,.ui.menu .link.item:hover,.ui.menu a.item:hover{cursor:pointer;background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.link.menu .item:active,.ui.menu .link.item:active,.ui.menu a.item:active{background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.menu .active.item{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);font-weight:400;-webkit-box-shadow:none;box-shadow:none}.ui.menu .active.item>i.icon{opacity:1}.ui.menu .active.item:hover,.ui.vertical.menu .active.item:hover{background-color:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.menu .item.disabled,.ui.menu .item.disabled:hover{cursor:default!important;background-color:transparent!important;color:rgba(40,40,40,.3)!important}.ui.menu:not(.vertical) .left.item,.ui.menu:not(.vertical) :not(.dropdown)>.left.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin-right:auto!important}.ui.menu:not(.vertical) .right.item,.ui.menu:not(.vertical) .right.menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin-left:auto!important}.ui.menu .right.item::before,.ui.menu .right.menu>.item::before{right:auto;left:0}.ui.vertical.menu{display:block;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15)}.ui.vertical.menu .item{display:block;background:0 0;border-top:none;border-right:none}.ui.vertical.menu>.item:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.menu>.item:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.menu .item>.label{float:right;text-align:center}.ui.vertical.menu .item>i.icon{width:1.18em;float:right;margin:0 0 0 .5em}.ui.vertical.menu .item>.label+i.icon{float:none;margin:0 .5em 0 0}.ui.vertical.menu .item:before{position:absolute;content:'';top:0;left:0;width:100%;height:1px;background:rgba(34,36,38,.1)}.ui.vertical.menu .item:first-child:before{display:none!important}.ui.vertical.menu .item>.menu{margin:.5em -1.14285714em 0}.ui.vertical.menu .menu .item{background:0 0;padding:.5em 1.33333333em;font-size:.85714286em;color:rgba(0,0,0,.5)}.ui.vertical.menu .item .menu .link.item:hover,.ui.vertical.menu .item .menu a.item:hover{color:rgba(0,0,0,.85)}.ui.vertical.menu .menu .item:before{display:none}.ui.vertical.menu .active.item{background:rgba(0,0,0,.05);border-radius:0;-webkit-box-shadow:none;box-shadow:none}.ui.vertical.menu>.active.item:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.vertical.menu>.active.item:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.vertical.menu>.active.item:only-child{border-radius:.28571429rem}.ui.vertical.menu .active.item .menu .active.item{border-left:none}.ui.vertical.menu .item .menu .active.item{background-color:transparent;font-weight:700;color:rgba(0,0,0,.95)}.ui.tabular.menu{border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border:none;background:none transparent;border-bottom:1px solid #d4d4d5}.ui.tabular.fluid.menu{width:calc(100% + 2px)!important}.ui.tabular.menu .item{background:0 0;border-bottom:none;border-left:1px solid transparent;border-right:1px solid transparent;border-top:2px solid transparent;padding:.92857143em 1.42857143em;color:rgba(0,0,0,.87)}.ui.tabular.menu .item:before{display:none}.ui.tabular.menu .item:hover{background-color:transparent;color:rgba(0,0,0,.8)}.ui.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-top-width:1px;border-color:#d4d4d5;font-weight:700;margin-bottom:-1px;-webkit-box-shadow:none;box-shadow:none;border-radius:.28571429rem .28571429rem 0 0!important}.ui.tabular.menu+.attached:not(.top).segment,.ui.tabular.menu+.attached:not(.top).segment+.attached:not(.top).segment{border-top:none;margin-left:0;margin-top:0;margin-right:0;width:100%}.top.attached.segment+.ui.bottom.tabular.menu{position:relative;width:calc(100% + 2px);left:-1px}.ui.bottom.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-top:1px solid #d4d4d5}.ui.bottom.tabular.menu .item{background:0 0;border-left:1px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-top:none}.ui.bottom.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:-1px 0 0 0;border-radius:0 0 .28571429rem .28571429rem!important}.ui.vertical.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-right:1px solid #d4d4d5}.ui.vertical.tabular.menu .item{background:0 0;border-left:1px solid transparent;border-bottom:1px solid transparent;border-top:1px solid transparent;border-right:none}.ui.vertical.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:0 -1px 0 0;border-radius:.28571429rem 0 0 .28571429rem!important}.ui.vertical.right.tabular.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;border-bottom:none;border-right:none;border-left:1px solid #d4d4d5}.ui.vertical.right.tabular.menu .item{background:0 0;border-right:1px solid transparent;border-bottom:1px solid transparent;border-top:1px solid transparent;border-left:none}.ui.vertical.right.tabular.menu .active.item{background:none #fff;color:rgba(0,0,0,.95);border-color:#d4d4d5;margin:0 0 0 -1px;border-radius:0 .28571429rem .28571429rem 0!important}.ui.tabular.menu .active.dropdown.item{margin-bottom:0;border-left:1px solid transparent;border-right:1px solid transparent;border-top:2px solid transparent;border-bottom:none}.ui.pagination.menu{margin:0;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.ui.pagination.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.compact.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.pagination.menu .item:last-child:before{display:none}.ui.pagination.menu .item{min-width:3em;text-align:center}.ui.pagination.menu .icon.item i.icon{vertical-align:top}.ui.pagination.menu .active.item{border-top:none;padding-top:.92857143em;background-color:rgba(0,0,0,.05);color:rgba(0,0,0,.95);-webkit-box-shadow:none;box-shadow:none}.ui.secondary.menu{background:0 0;margin-left:-.35714286em;margin-right:-.35714286em;border-radius:0;border:none;-webkit-box-shadow:none;box-shadow:none}.ui.secondary.menu .item{-ms-flex-item-align:center;align-self:center;-webkit-box-shadow:none;box-shadow:none;border:none;padding:.78571429em .92857143em;margin:0 .35714286em;background:0 0;-webkit-transition:color .1s ease;transition:color .1s ease;border-radius:.28571429rem}.ui.secondary.menu .item:before{display:none!important}.ui.secondary.menu .header.item{border-radius:0;border-right:none;background:none transparent}.ui.secondary.menu .item>img:not(.ui){margin:0}.ui.secondary.menu .dropdown.item:hover,.ui.secondary.menu .link.item:hover,.ui.secondary.menu a.item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.secondary.menu .active.item{-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);border-radius:.28571429rem}.ui.secondary.menu .active.item:hover{-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.secondary.inverted.menu .link.item,.ui.secondary.inverted.menu a.item{color:rgba(255,255,255,.7)!important}.ui.secondary.inverted.menu .dropdown.item:hover,.ui.secondary.inverted.menu .link.item:hover,.ui.secondary.inverted.menu a.item:hover{background:rgba(255,255,255,.08);color:#fff!important}.ui.secondary.inverted.menu .active.item{background:rgba(255,255,255,.15);color:#fff!important}.ui.secondary.item.menu{margin-left:0;margin-right:0}.ui.secondary.item.menu .item:last-child{margin-right:0}.ui.secondary.attached.menu{-webkit-box-shadow:none;box-shadow:none}.ui.vertical.secondary.menu .item:not(.dropdown)>.menu{margin:0 -.92857143em}.ui.vertical.secondary.menu .item:not(.dropdown)>.menu>.item{margin:0;padding:.5em 1.33333333em}.ui.secondary.vertical.menu>.item{border:none;margin:0 0 .35714286em;border-radius:.28571429rem!important}.ui.secondary.vertical.menu>.header.item{border-radius:0}.ui.vertical.secondary.menu .item>.menu .item{background-color:transparent}.ui.secondary.inverted.menu{background-color:transparent}.ui.secondary.pointing.menu{margin-left:0;margin-right:0;border-bottom:2px solid rgba(34,36,38,.15)}.ui.secondary.pointing.menu .item{border-bottom-color:transparent;border-bottom-style:solid;border-radius:0;-ms-flex-item-align:end;align-self:flex-end;margin:0 0 -2px;padding:.85714286em 1.14285714em;border-bottom-width:2px;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.secondary.pointing.menu .header.item{color:rgba(0,0,0,.85)!important}.ui.secondary.pointing.menu .text.item{-webkit-box-shadow:none!important;box-shadow:none!important}.ui.secondary.pointing.menu .item:after{display:none}.ui.secondary.pointing.menu .dropdown.item:hover,.ui.secondary.pointing.menu .link.item:hover,.ui.secondary.pointing.menu a.item:hover{background-color:transparent;color:rgba(0,0,0,.87)}.ui.secondary.pointing.menu .dropdown.item:active,.ui.secondary.pointing.menu .link.item:active,.ui.secondary.pointing.menu a.item:active{background-color:transparent;border-color:rgba(34,36,38,.15)}.ui.secondary.pointing.menu .active.item{background-color:transparent;-webkit-box-shadow:none;box-shadow:none;border-color:#1b1c1d;font-weight:700;color:rgba(0,0,0,.95)}.ui.secondary.pointing.menu .active.item:hover{border-color:#1b1c1d;color:rgba(0,0,0,.95)}.ui.secondary.pointing.menu .active.dropdown.item{border-color:transparent}.ui.secondary.vertical.pointing.menu{border-bottom-width:0;border-right-width:2px;border-right-style:solid;border-right-color:rgba(34,36,38,.15)}.ui.secondary.vertical.pointing.menu .item{border-bottom:none;border-right-style:solid;border-right-color:transparent;border-radius:0!important;margin:0 -2px 0 0;border-right-width:2px}.ui.secondary.vertical.pointing.menu .active.item{border-color:#1b1c1d}.ui.secondary.inverted.pointing.menu{border-color:rgba(255,255,255,.1)}.ui.secondary.inverted.pointing.menu{border-width:2px;border-color:rgba(34,36,38,.15)}.ui.secondary.inverted.pointing.menu .item{color:rgba(255,255,255,.9)}.ui.secondary.inverted.pointing.menu .header.item{color:#fff!important}.ui.secondary.inverted.pointing.menu .link.item:hover,.ui.secondary.inverted.pointing.menu a.item:hover{color:rgba(0,0,0,.95)}.ui.secondary.inverted.pointing.menu .active.item{border-color:#fff;color:#fff}.ui.text.menu{background:none transparent;border-radius:0;-webkit-box-shadow:none;box-shadow:none;border:none;margin:1em -.5em}.ui.text.menu .item{border-radius:0;-webkit-box-shadow:none;box-shadow:none;-ms-flex-item-align:center;align-self:center;margin:0 0;padding:.35714286em .5em;font-weight:400;color:rgba(0,0,0,.6);-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.text.menu .item:before,.ui.text.menu .menu .item:before{display:none!important}.ui.text.menu .header.item{background-color:transparent;opacity:1;color:rgba(0,0,0,.85);font-size:.92857143em;text-transform:uppercase;font-weight:700}.ui.text.menu .item>img:not(.ui){margin:0}.ui.text.item.menu .item{margin:0}.ui.vertical.text.menu{margin:1em 0}.ui.vertical.text.menu:first-child{margin-top:0}.ui.vertical.text.menu:last-child{margin-bottom:0}.ui.vertical.text.menu .item{margin:.57142857em 0;padding-left:0;padding-right:0}.ui.vertical.text.menu .item>i.icon{float:none;margin:0 .35714286em 0 0}.ui.vertical.text.menu .header.item{margin:.57142857em 0 .71428571em}.ui.vertical.text.menu .item:not(.dropdown)>.menu{margin:0}.ui.vertical.text.menu .item:not(.dropdown)>.menu>.item{margin:0;padding:.5em 0}.ui.text.menu .item:hover{opacity:1;background-color:transparent}.ui.text.menu .active.item{background-color:transparent;border:none;-webkit-box-shadow:none;box-shadow:none;font-weight:400;color:rgba(0,0,0,.95)}.ui.text.menu .active.item:hover{background-color:transparent}.ui.text.pointing.menu .active.item:after{-webkit-box-shadow:none;box-shadow:none}.ui.text.attached.menu{-webkit-box-shadow:none;box-shadow:none}.ui.inverted.text.menu,.ui.inverted.text.menu .active.item,.ui.inverted.text.menu .item,.ui.inverted.text.menu .item:hover{background-color:transparent!important}.ui.fluid.text.menu{margin-left:0;margin-right:0}.ui.vertical.icon.menu{display:inline-block;width:auto}.ui.icon.menu .item{height:auto;text-align:center;color:#1b1c1d}.ui.icon.menu .item>.icon:not(.dropdown){margin:0;opacity:1}.ui.icon.menu .icon:before{opacity:1}.ui.menu .icon.item>.icon{width:auto;margin:0 auto}.ui.vertical.icon.menu .item>.icon:not(.dropdown){display:block;opacity:1;margin:0 auto;float:none}.ui.inverted.icon.menu .item{color:#fff}.ui.labeled.icon.menu{text-align:center}.ui.labeled.icon.menu .item{min-width:6em;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.labeled.icon.menu .item>.icon:not(.dropdown){height:1em;display:block;font-size:1.71428571em!important;margin:0 auto .5rem!important}.ui.fluid.labeled.icon.menu>.item{min-width:0}@media only screen and (max-width:767px){.ui.stackable.menu{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.stackable.menu .item{width:100%!important}.ui.stackable.menu .item:before{position:absolute;content:'';top:auto;bottom:0;left:0;width:100%;height:1px;background:rgba(34,36,38,.1)}.ui.stackable.menu .left.item,.ui.stackable.menu .left.menu{margin-right:0!important}.ui.stackable.menu .right.item,.ui.stackable.menu .right.menu{margin-left:0!important}.ui.stackable.menu .left.menu,.ui.stackable.menu .right.menu{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.ui.menu .red.active.item,.ui.red.menu .active.item{border-color:#db2828!important;color:#db2828!important}.ui.menu .orange.active.item,.ui.orange.menu .active.item{border-color:#f2711c!important;color:#f2711c!important}.ui.menu .yellow.active.item,.ui.yellow.menu .active.item{border-color:#fbbd08!important;color:#fbbd08!important}.ui.menu .olive.active.item,.ui.olive.menu .active.item{border-color:#b5cc18!important;color:#b5cc18!important}.ui.green.menu .active.item,.ui.menu .green.active.item{border-color:#21ba45!important;color:#21ba45!important}.ui.menu .teal.active.item,.ui.teal.menu .active.item{border-color:#00b5ad!important;color:#00b5ad!important}.ui.blue.menu .active.item,.ui.menu .blue.active.item{border-color:#2185d0!important;color:#2185d0!important}.ui.menu .violet.active.item,.ui.violet.menu .active.item{border-color:#6435c9!important;color:#6435c9!important}.ui.menu .purple.active.item,.ui.purple.menu .active.item{border-color:#a333c8!important;color:#a333c8!important}.ui.menu .pink.active.item,.ui.pink.menu .active.item{border-color:#e03997!important;color:#e03997!important}.ui.brown.menu .active.item,.ui.menu .brown.active.item{border-color:#a5673f!important;color:#a5673f!important}.ui.grey.menu .active.item,.ui.menu .grey.active.item{border-color:#767676!important;color:#767676!important}.ui.inverted.menu{border:0 solid transparent;background:#1b1c1d;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.menu .item,.ui.inverted.menu .item>a:not(.ui){background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.menu .item.menu{background:0 0}.ui.inverted.menu .item:before{background:rgba(255,255,255,.08)}.ui.vertical.inverted.menu .item:before{background:rgba(255,255,255,.08)}.ui.vertical.inverted.menu .menu .item,.ui.vertical.inverted.menu .menu .item a:not(.ui){color:rgba(255,255,255,.5)}.ui.inverted.menu .header.item{margin:0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.menu .item.disabled,.ui.inverted.menu .item.disabled:hover{color:rgba(225,225,225,.3)}.ui.inverted.menu .dropdown.item:hover,.ui.inverted.menu .link.item:hover,.ui.inverted.menu a.item:hover,.ui.link.inverted.menu .item:hover{background:rgba(255,255,255,.08);color:#fff}.ui.vertical.inverted.menu .item .menu .link.item:hover,.ui.vertical.inverted.menu .item .menu a.item:hover{background:0 0;color:#fff}.ui.inverted.menu .link.item:active,.ui.inverted.menu a.item:active{background:rgba(255,255,255,.08);color:#fff}.ui.inverted.menu .active.item{background:rgba(255,255,255,.15);color:#fff!important}.ui.inverted.vertical.menu .item .menu .active.item{background:0 0;color:#fff}.ui.inverted.pointing.menu .active.item:after{background:#3d3e3f!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;border:none!important}.ui.inverted.menu .active.item:hover{background:rgba(255,255,255,.15);color:#fff!important}.ui.inverted.pointing.menu .active.item:hover:after{background:#3d3e3f!important}.ui.floated.menu{float:left;margin:0 .5rem 0 0}.ui.floated.menu .item:last-child:before{display:none}.ui.right.floated.menu{float:right;margin:0 0 0 .5rem}.ui.inverted.menu .red.active.item,.ui.inverted.red.menu{background-color:#db2828}.ui.inverted.red.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.red.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .orange.active.item,.ui.inverted.orange.menu{background-color:#f2711c}.ui.inverted.orange.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.orange.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .yellow.active.item,.ui.inverted.yellow.menu{background-color:#fbbd08}.ui.inverted.yellow.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.yellow.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .olive.active.item,.ui.inverted.olive.menu{background-color:#b5cc18}.ui.inverted.olive.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.olive.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.green.menu,.ui.inverted.menu .green.active.item{background-color:#21ba45}.ui.inverted.green.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.green.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .teal.active.item,.ui.inverted.teal.menu{background-color:#00b5ad}.ui.inverted.teal.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.teal.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.blue.menu,.ui.inverted.menu .blue.active.item{background-color:#2185d0}.ui.inverted.blue.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.blue.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .violet.active.item,.ui.inverted.violet.menu{background-color:#6435c9}.ui.inverted.violet.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.violet.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .purple.active.item,.ui.inverted.purple.menu{background-color:#a333c8}.ui.inverted.purple.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.purple.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.menu .pink.active.item,.ui.inverted.pink.menu{background-color:#e03997}.ui.inverted.pink.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.pink.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.brown.menu,.ui.inverted.menu .brown.active.item{background-color:#a5673f}.ui.inverted.brown.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.brown.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.inverted.grey.menu,.ui.inverted.menu .grey.active.item{background-color:#767676}.ui.inverted.grey.menu .item:before{background-color:rgba(34,36,38,.1)}.ui.inverted.grey.menu .active.item{background-color:rgba(0,0,0,.1)!important}.ui.fitted.menu .item,.ui.fitted.menu .item .menu .item,.ui.menu .fitted.item{padding:0}.ui.horizontally.fitted.menu .item,.ui.horizontally.fitted.menu .item .menu .item,.ui.menu .horizontally.fitted.item{padding-top:.92857143em;padding-bottom:.92857143em}.ui.menu .vertically.fitted.item,.ui.vertically.fitted.menu .item,.ui.vertically.fitted.menu .item .menu .item{padding-left:1.14285714em;padding-right:1.14285714em}.ui.borderless.menu .item .menu .item:before,.ui.borderless.menu .item:before,.ui.menu .borderless.item:before{background:0 0!important}.ui.compact.menu{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin:0;vertical-align:middle}.ui.compact.vertical.menu{display:inline-block}.ui.compact.menu .item:last-child{border-radius:0 .28571429rem .28571429rem 0}.ui.compact.menu .item:last-child:before{display:none}.ui.compact.vertical.menu{width:auto!important}.ui.compact.vertical.menu .item:last-child::before{display:block}.ui.menu.fluid,.ui.vertical.menu.fluid{width:100%!important}.ui.item.menu,.ui.item.menu .item{width:100%;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important;text-align:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.attached.item.menu{margin:0 -1px!important}.ui.item.menu .item:last-child:before{display:none}.ui.menu.two.item .item{width:50%}.ui.menu.three.item .item{width:33.333%}.ui.menu.four.item .item{width:25%}.ui.menu.five.item .item{width:20%}.ui.menu.six.item .item{width:16.666%}.ui.menu.seven.item .item{width:14.285%}.ui.menu.eight.item .item{width:12.5%}.ui.menu.nine.item .item{width:11.11%}.ui.menu.ten.item .item{width:10%}.ui.menu.eleven.item .item{width:9.09%}.ui.menu.twelve.item .item{width:8.333%}.ui.menu.fixed{position:fixed;z-index:101;margin:0;width:100%}.ui.menu.fixed,.ui.menu.fixed .item:first-child,.ui.menu.fixed .item:last-child{border-radius:0!important}.ui.fixed.menu,.ui[class*=\\\"top fixed\\\"].menu{top:0;left:0;right:auto;bottom:auto}.ui[class*=\\\"top fixed\\\"].menu{border-top:none;border-left:none;border-right:none}.ui[class*=\\\"right fixed\\\"].menu{border-top:none;border-bottom:none;border-right:none;top:0;right:0;left:auto;bottom:auto;width:auto;height:100%}.ui[class*=\\\"bottom fixed\\\"].menu{border-bottom:none;border-left:none;border-right:none;bottom:0;left:0;top:auto;right:auto}.ui[class*=\\\"left fixed\\\"].menu{border-top:none;border-bottom:none;border-left:none;top:0;left:0;right:auto;bottom:auto;width:auto;height:100%}.ui.fixed.menu+.ui.grid{padding-top:2.75rem}.ui.pointing.menu .item:after{visibility:hidden;position:absolute;content:'';top:100%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);background:0 0;margin:.5px 0 0;width:.57142857em;height:.57142857em;border:none;border-bottom:1px solid #d4d4d5;border-right:1px solid #d4d4d5;z-index:2;-webkit-transition:background .1s ease;transition:background .1s ease}.ui.vertical.pointing.menu .item:after{position:absolute;top:50%;right:0;bottom:auto;left:auto;-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg);margin:0 -.5px 0 0;border:none;border-top:1px solid #d4d4d5;border-right:1px solid #d4d4d5}.ui.pointing.menu .active.item:after{visibility:visible}.ui.pointing.menu .active.dropdown.item:after{visibility:hidden}.ui.pointing.menu .active.item .menu .active.item:after,.ui.pointing.menu .dropdown.active.item:after{display:none}.ui.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.pointing.menu .active.item:after{background-color:#f2f2f2}.ui.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .active.item:hover:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .active.item:after{background-color:#f2f2f2}.ui.vertical.pointing.menu .menu .active.item:after{background-color:#fff}.ui.attached.menu{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none}.ui.attached+.ui.attached.menu:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].menu{bottom:0;margin-bottom:0;top:0;margin-top:1rem;border-radius:.28571429rem .28571429rem 0 0}.ui.menu[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui[class*=\\\"bottom attached\\\"].menu{bottom:0;margin-top:0;top:0;margin-bottom:1rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),none;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].menu:last-child{margin-bottom:0}.ui.top.attached.menu>.item:first-child{border-radius:.28571429rem 0 0 0}.ui.bottom.attached.menu>.item:first-child{border-radius:0 0 0 .28571429rem}.ui.attached.menu:not(.tabular){border:1px solid #d4d4d5}.ui.attached.inverted.menu{border:none}.ui.attached.tabular.menu{margin-left:0;margin-right:0;width:100%}.ui.mini.menu{font-size:.78571429rem}.ui.mini.vertical.menu{width:9rem}.ui.tiny.menu{font-size:.85714286rem}.ui.tiny.vertical.menu{width:11rem}.ui.small.menu{font-size:.92857143rem}.ui.small.vertical.menu{width:13rem}.ui.menu{font-size:1rem}.ui.vertical.menu{width:15rem}.ui.large.menu{font-size:1.07142857rem}.ui.large.vertical.menu{width:18rem}.ui.huge.menu{font-size:1.21428571rem}.ui.huge.vertical.menu{width:22rem}.ui.big.menu{font-size:1.14285714rem}.ui.big.vertical.menu{width:20rem}.ui.massive.menu{font-size:1.28571429rem}.ui.massive.vertical.menu{width:25rem}/*!\\n * # Semantic UI 2.4.0 - Message\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.message{position:relative;min-height:1em;margin:1em 0;background:#f8f8f9;padding:1em 1.5em;line-height:1.4285em;color:rgba(0,0,0,.87);-webkit-transition:opacity .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease,-webkit-box-shadow .1s ease;border-radius:.28571429rem;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 0 0 0 transparent;box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 0 0 0 transparent}.ui.message:first-child{margin-top:0}.ui.message:last-child{margin-bottom:0}.ui.message .header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;margin:-.14285714em 0 0 0}.ui.message .header:not(.ui){font-size:1.14285714em}.ui.message p{opacity:.85;margin:.75em 0}.ui.message p:first-child{margin-top:0}.ui.message p:last-child{margin-bottom:0}.ui.message .header+p{margin-top:.25em}.ui.message .list:not(.ui){text-align:left;padding:0;opacity:.85;list-style-position:inside;margin:.5em 0 0}.ui.message .list:not(.ui):first-child{margin-top:0}.ui.message .list:not(.ui):last-child{margin-bottom:0}.ui.message .list:not(.ui) li{position:relative;list-style-type:none;margin:0 0 .3em 1em;padding:0}.ui.message .list:not(.ui) li:before{position:absolute;content:'•';left:-1em;height:100%;vertical-align:baseline}.ui.message .list:not(.ui) li:last-child{margin-bottom:0}.ui.message>.icon{margin-right:.6em}.ui.message>.close.icon{cursor:pointer;position:absolute;margin:0;top:.78575em;right:.5em;opacity:.7;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.message>.close.icon:hover{opacity:1}.ui.message>:first-child{margin-top:0}.ui.message>:last-child{margin-bottom:0}.ui.dropdown .menu>.message{margin:0 -1px}.ui.visible.visible.visible.visible.message{display:block}.ui.icon.visible.visible.visible.visible.message{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.hidden.hidden.hidden.hidden.message{display:none}.ui.compact.message{display:inline-block}.ui.compact.icon.message{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.ui.attached.message{margin-bottom:-1px;border-radius:.28571429rem .28571429rem 0 0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;margin-left:-1px;margin-right:-1px}.ui.attached+.ui.attached.message:not(.top):not(.bottom){margin-top:-1px;border-radius:0}.ui.bottom.attached.message{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset,0 1px 2px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px rgba(34,36,38,.15) inset,0 1px 2px 0 rgba(34,36,38,.15)}.ui.bottom.attached.message:not(:last-child){margin-bottom:1em}.ui.attached.icon.message{width:auto}.ui.icon.message{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.icon.message>.icon:not(.close){display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;line-height:1;vertical-align:middle;font-size:3em;opacity:.8}.ui.icon.message>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;vertical-align:middle}.ui.icon.message .icon:not(.close)+.content{padding-left:0}.ui.icon.message .circular.icon{width:1em}.ui.floating.message{-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.black.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.positive.message{background-color:#fcfff5;color:#2c662d}.ui.attached.positive.message,.ui.positive.message{-webkit-box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.positive.message .header{color:#1a531b}.ui.negative.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.negative.message,.ui.negative.message{-webkit-box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.negative.message .header{color:#912d2b}.ui.info.message{background-color:#f8ffff;color:#276f86}.ui.attached.info.message,.ui.info.message{-webkit-box-shadow:0 0 0 1px #a9d5de inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a9d5de inset,0 0 0 0 transparent}.ui.info.message .header{color:#0e566c}.ui.warning.message{background-color:#fffaf3;color:#573a08}.ui.attached.warning.message,.ui.warning.message{-webkit-box-shadow:0 0 0 1px #c9ba9b inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #c9ba9b inset,0 0 0 0 transparent}.ui.warning.message .header{color:#794b02}.ui.error.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.error.message,.ui.error.message{-webkit-box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.error.message .header{color:#912d2b}.ui.success.message{background-color:#fcfff5;color:#2c662d}.ui.attached.success.message,.ui.success.message{-webkit-box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.success.message .header{color:#1a531b}.ui.black.message,.ui.inverted.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.red.message{background-color:#ffe8e6;color:#db2828;-webkit-box-shadow:0 0 0 1px #db2828 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #db2828 inset,0 0 0 0 transparent}.ui.red.message .header{color:#c82121}.ui.orange.message{background-color:#ffedde;color:#f2711c;-webkit-box-shadow:0 0 0 1px #f2711c inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #f2711c inset,0 0 0 0 transparent}.ui.orange.message .header{color:#e7640d}.ui.yellow.message{background-color:#fff8db;color:#b58105;-webkit-box-shadow:0 0 0 1px #b58105 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #b58105 inset,0 0 0 0 transparent}.ui.yellow.message .header{color:#9c6f04}.ui.olive.message{background-color:#fbfdef;color:#8abc1e;-webkit-box-shadow:0 0 0 1px #8abc1e inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #8abc1e inset,0 0 0 0 transparent}.ui.olive.message .header{color:#7aa61a}.ui.green.message{background-color:#e5f9e7;color:#1ebc30;-webkit-box-shadow:0 0 0 1px #1ebc30 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #1ebc30 inset,0 0 0 0 transparent}.ui.green.message .header{color:#1aa62a}.ui.teal.message{background-color:#e1f7f7;color:#10a3a3;-webkit-box-shadow:0 0 0 1px #10a3a3 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #10a3a3 inset,0 0 0 0 transparent}.ui.teal.message .header{color:#0e8c8c}.ui.blue.message{background-color:#dff0ff;color:#2185d0;-webkit-box-shadow:0 0 0 1px #2185d0 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #2185d0 inset,0 0 0 0 transparent}.ui.blue.message .header{color:#1e77ba}.ui.violet.message{background-color:#eae7ff;color:#6435c9;-webkit-box-shadow:0 0 0 1px #6435c9 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #6435c9 inset,0 0 0 0 transparent}.ui.violet.message .header{color:#5a30b5}.ui.purple.message{background-color:#f6e7ff;color:#a333c8;-webkit-box-shadow:0 0 0 1px #a333c8 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a333c8 inset,0 0 0 0 transparent}.ui.purple.message .header{color:#922eb4}.ui.pink.message{background-color:#ffe3fb;color:#e03997;-webkit-box-shadow:0 0 0 1px #e03997 inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #e03997 inset,0 0 0 0 transparent}.ui.pink.message .header{color:#dd238b}.ui.brown.message{background-color:#f1e2d3;color:#a5673f;-webkit-box-shadow:0 0 0 1px #a5673f inset,0 0 0 0 transparent;box-shadow:0 0 0 1px #a5673f inset,0 0 0 0 transparent}.ui.brown.message .header{color:#935b38}.ui.mini.message{font-size:.78571429em}.ui.tiny.message{font-size:.85714286em}.ui.small.message{font-size:.92857143em}.ui.message{font-size:1em}.ui.large.message{font-size:1.14285714em}.ui.big.message{font-size:1.28571429em}.ui.huge.message{font-size:1.42857143em}.ui.massive.message{font-size:1.71428571em}/*!\\n * # Semantic UI 2.4.0 - Table\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.table{width:100%;background:#fff;margin:1em 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none;border-radius:.28571429rem;text-align:left;color:rgba(0,0,0,.87);border-collapse:separate;border-spacing:0}.ui.table:first-child{margin-top:0}.ui.table:last-child{margin-bottom:0}.ui.table td,.ui.table th{-webkit-transition:background .1s ease,color .1s ease;transition:background .1s ease,color .1s ease}.ui.table thead{-webkit-box-shadow:none;box-shadow:none}.ui.table thead th{cursor:auto;background:#f9fafb;text-align:inherit;color:rgba(0,0,0,.87);padding:.92857143em .78571429em;vertical-align:inherit;font-style:none;font-weight:700;text-transform:none;border-bottom:1px solid rgba(34,36,38,.1);border-left:none}.ui.table thead tr>th:first-child{border-left:none}.ui.table thead tr:first-child>th:first-child{border-radius:.28571429rem 0 0 0}.ui.table thead tr:first-child>th:last-child{border-radius:0 .28571429rem 0 0}.ui.table thead tr:first-child>th:only-child{border-radius:.28571429rem .28571429rem 0 0}.ui.table tfoot{-webkit-box-shadow:none;box-shadow:none}.ui.table tfoot th{cursor:auto;border-top:1px solid rgba(34,36,38,.15);background:#f9fafb;text-align:inherit;color:rgba(0,0,0,.87);padding:.78571429em .78571429em;vertical-align:middle;font-style:normal;font-weight:400;text-transform:none}.ui.table tfoot tr>th:first-child{border-left:none}.ui.table tfoot tr:first-child>th:first-child{border-radius:0 0 0 .28571429rem}.ui.table tfoot tr:first-child>th:last-child{border-radius:0 0 .28571429rem 0}.ui.table tfoot tr:first-child>th:only-child{border-radius:0 0 .28571429rem .28571429rem}.ui.table tr td{border-top:1px solid rgba(34,36,38,.1)}.ui.table tr:first-child td{border-top:none}.ui.table tbody+tbody tr:first-child td{border-top:1px solid rgba(34,36,38,.1)}.ui.table td{padding:.78571429em .78571429em;text-align:inherit}.ui.table>.icon{vertical-align:baseline}.ui.table>.icon:only-child{margin:0}.ui.table.segment{padding:0}.ui.table.segment:after{display:none}.ui.table.segment.stacked:after{display:block}@media only screen and (max-width:767px){.ui.table:not(.unstackable){width:100%}.ui.table:not(.unstackable) tbody,.ui.table:not(.unstackable) tr,.ui.table:not(.unstackable) tr>td,.ui.table:not(.unstackable) tr>th{width:auto!important;display:block!important}.ui.table:not(.unstackable){padding:0}.ui.table:not(.unstackable) thead{display:block}.ui.table:not(.unstackable) tfoot{display:block}.ui.table:not(.unstackable) tr{padding-top:1em;padding-bottom:1em;-webkit-box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important;box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important}.ui.table:not(.unstackable) tr>td,.ui.table:not(.unstackable) tr>th{background:0 0;border:none!important;padding:.25em .75em!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.table:not(.unstackable) td:first-child,.ui.table:not(.unstackable) th:first-child{font-weight:700}.ui.definition.table:not(.unstackable) thead th:first-child{-webkit-box-shadow:none!important;box-shadow:none!important}}.ui.table td .image,.ui.table td .image img,.ui.table th .image,.ui.table th .image img{max-width:none}.ui.structured.table{border-collapse:collapse}.ui.structured.table thead th{border-left:none;border-right:none}.ui.structured.sortable.table thead th{border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(34,36,38,.15)}.ui.structured.basic.table th{border-left:none;border-right:none}.ui.structured.celled.table tr td,.ui.structured.celled.table tr th{border-left:1px solid rgba(34,36,38,.1);border-right:1px solid rgba(34,36,38,.1)}.ui.definition.table thead:not(.full-width) th:first-child{pointer-events:none;background:0 0;font-weight:400;color:rgba(0,0,0,.4);-webkit-box-shadow:-1px -1px 0 1px #fff;box-shadow:-1px -1px 0 1px #fff}.ui.definition.table tfoot:not(.full-width) th:first-child{pointer-events:none;background:0 0;font-weight:rgba(0,0,0,.4);color:normal;-webkit-box-shadow:1px 1px 0 1px #fff;box-shadow:1px 1px 0 1px #fff}.ui.celled.definition.table thead:not(.full-width) th:first-child{-webkit-box-shadow:0 -1px 0 1px #fff;box-shadow:0 -1px 0 1px #fff}.ui.celled.definition.table tfoot:not(.full-width) th:first-child{-webkit-box-shadow:0 1px 0 1px #fff;box-shadow:0 1px 0 1px #fff}.ui.definition.table tr td.definition,.ui.definition.table tr td:first-child:not(.ignored){background:rgba(0,0,0,.03);font-weight:700;color:rgba(0,0,0,.95);text-transform:'';-webkit-box-shadow:'';box-shadow:'';text-align:'';font-size:1em;padding-left:'';padding-right:''}.ui.definition.table thead:not(.full-width) th:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.definition.table tfoot:not(.full-width) th:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.definition.table td:nth-child(2){border-left:1px solid rgba(34,36,38,.15)}.ui.table td.positive,.ui.table tr.positive{-webkit-box-shadow:0 0 0 #a3c293 inset;box-shadow:0 0 0 #a3c293 inset}.ui.table td.positive,.ui.table tr.positive{background:#fcfff5!important;color:#2c662d!important}.ui.table td.negative,.ui.table tr.negative{-webkit-box-shadow:0 0 0 #e0b4b4 inset;box-shadow:0 0 0 #e0b4b4 inset}.ui.table td.negative,.ui.table tr.negative{background:#fff6f6!important;color:#9f3a38!important}.ui.table td.error,.ui.table tr.error{-webkit-box-shadow:0 0 0 #e0b4b4 inset;box-shadow:0 0 0 #e0b4b4 inset}.ui.table td.error,.ui.table tr.error{background:#fff6f6!important;color:#9f3a38!important}.ui.table td.warning,.ui.table tr.warning{-webkit-box-shadow:0 0 0 #c9ba9b inset;box-shadow:0 0 0 #c9ba9b inset}.ui.table td.warning,.ui.table tr.warning{background:#fffaf3!important;color:#573a08!important}.ui.table td.active,.ui.table tr.active{-webkit-box-shadow:0 0 0 rgba(0,0,0,.87) inset;box-shadow:0 0 0 rgba(0,0,0,.87) inset}.ui.table td.active,.ui.table tr.active{background:#e0e0e0!important;color:rgba(0,0,0,.87)!important}.ui.table tr td.disabled,.ui.table tr.disabled td,.ui.table tr.disabled:hover,.ui.table tr:hover td.disabled{pointer-events:none;color:rgba(40,40,40,.3)}@media only screen and (max-width:991px){.ui[class*=\\\"tablet stackable\\\"].table,.ui[class*=\\\"tablet stackable\\\"].table tbody,.ui[class*=\\\"tablet stackable\\\"].table tr,.ui[class*=\\\"tablet stackable\\\"].table tr>td,.ui[class*=\\\"tablet stackable\\\"].table tr>th{width:100%!important;display:block!important}.ui[class*=\\\"tablet stackable\\\"].table{padding:0}.ui[class*=\\\"tablet stackable\\\"].table thead{display:block}.ui[class*=\\\"tablet stackable\\\"].table tfoot{display:block}.ui[class*=\\\"tablet stackable\\\"].table tr{padding-top:1em;padding-bottom:1em;-webkit-box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important;box-shadow:0 -1px 0 0 rgba(0,0,0,.1) inset!important}.ui[class*=\\\"tablet stackable\\\"].table tr>td,.ui[class*=\\\"tablet stackable\\\"].table tr>th{background:0 0;border:none!important;padding:.25em .75em;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.definition[class*=\\\"tablet stackable\\\"].table thead th:first-child{-webkit-box-shadow:none!important;box-shadow:none!important}}.ui.table [class*=\\\"left aligned\\\"],.ui.table[class*=\\\"left aligned\\\"]{text-align:left}.ui.table [class*=\\\"center aligned\\\"],.ui.table[class*=\\\"center aligned\\\"]{text-align:center}.ui.table [class*=\\\"right aligned\\\"],.ui.table[class*=\\\"right aligned\\\"]{text-align:right}.ui.table [class*=\\\"top aligned\\\"],.ui.table[class*=\\\"top aligned\\\"]{vertical-align:top}.ui.table [class*=\\\"middle aligned\\\"],.ui.table[class*=\\\"middle aligned\\\"]{vertical-align:middle}.ui.table [class*=\\\"bottom aligned\\\"],.ui.table[class*=\\\"bottom aligned\\\"]{vertical-align:bottom}.ui.table td.collapsing,.ui.table th.collapsing{width:1px;white-space:nowrap}.ui.fixed.table{table-layout:fixed}.ui.fixed.table td,.ui.fixed.table th{overflow:hidden;text-overflow:ellipsis}.ui.selectable.table tbody tr:hover,.ui.table tbody tr td.selectable:hover{background:rgba(0,0,0,.05)!important;color:rgba(0,0,0,.95)!important}.ui.inverted.table tbody tr td.selectable:hover,.ui.selectable.inverted.table tbody tr:hover{background:rgba(255,255,255,.08)!important;color:#fff!important}.ui.table tbody tr td.selectable{padding:0}.ui.table tbody tr td.selectable>a:not(.ui){display:block;color:inherit;padding:.78571429em .78571429em}.ui.selectable.table tr.error:hover,.ui.selectable.table tr:hover td.error,.ui.table tr td.selectable.error:hover{background:#ffe7e7!important;color:#943634!important}.ui.selectable.table tr.warning:hover,.ui.selectable.table tr:hover td.warning,.ui.table tr td.selectable.warning:hover{background:#fff4e4!important;color:#493107!important}.ui.selectable.table tr.active:hover,.ui.selectable.table tr:hover td.active,.ui.table tr td.selectable.active:hover{background:#e0e0e0!important;color:rgba(0,0,0,.87)!important}.ui.selectable.table tr.positive:hover,.ui.selectable.table tr:hover td.positive,.ui.table tr td.selectable.positive:hover{background:#f7ffe6!important;color:#275b28!important}.ui.selectable.table tr.negative:hover,.ui.selectable.table tr:hover td.negative,.ui.table tr td.selectable.negative:hover{background:#ffe7e7!important;color:#943634!important}.ui.attached.table{top:0;bottom:0;border-radius:0;margin:0 -1px;width:calc(100% + 2px);max-width:calc(100% + 2px);-webkit-box-shadow:none;box-shadow:none;border:1px solid #d4d4d5}.ui.attached+.ui.attached.table:not(.top){border-top:none}.ui[class*=\\\"top attached\\\"].table{bottom:0;margin-bottom:0;top:0;margin-top:1em;border-radius:.28571429rem .28571429rem 0 0}.ui.table[class*=\\\"top attached\\\"]:first-child{margin-top:0}.ui[class*=\\\"bottom attached\\\"].table{bottom:0;margin-top:0;top:0;margin-bottom:1em;-webkit-box-shadow:none,none;box-shadow:none,none;border-radius:0 0 .28571429rem .28571429rem}.ui[class*=\\\"bottom attached\\\"].table:last-child{margin-bottom:0}.ui.striped.table tbody tr:nth-child(2n),.ui.striped.table>tr:nth-child(2n){background-color:rgba(0,0,50,.02)}.ui.inverted.striped.table tbody tr:nth-child(2n),.ui.inverted.striped.table>tr:nth-child(2n){background-color:rgba(255,255,255,.05)}.ui.striped.selectable.selectable.selectable.table tbody tr.active:hover{background:#efefef!important;color:rgba(0,0,0,.95)!important}.ui.table [class*=\\\"single line\\\"],.ui.table[class*=\\\"single line\\\"]{white-space:nowrap}.ui.table [class*=\\\"single line\\\"],.ui.table[class*=\\\"single line\\\"]{white-space:nowrap}.ui.red.table{border-top:.2em solid #db2828}.ui.inverted.red.table{background-color:#db2828!important;color:#fff!important}.ui.orange.table{border-top:.2em solid #f2711c}.ui.inverted.orange.table{background-color:#f2711c!important;color:#fff!important}.ui.yellow.table{border-top:.2em solid #fbbd08}.ui.inverted.yellow.table{background-color:#fbbd08!important;color:#fff!important}.ui.olive.table{border-top:.2em solid #b5cc18}.ui.inverted.olive.table{background-color:#b5cc18!important;color:#fff!important}.ui.green.table{border-top:.2em solid #21ba45}.ui.inverted.green.table{background-color:#21ba45!important;color:#fff!important}.ui.teal.table{border-top:.2em solid #00b5ad}.ui.inverted.teal.table{background-color:#00b5ad!important;color:#fff!important}.ui.blue.table{border-top:.2em solid #2185d0}.ui.inverted.blue.table{background-color:#2185d0!important;color:#fff!important}.ui.violet.table{border-top:.2em solid #6435c9}.ui.inverted.violet.table{background-color:#6435c9!important;color:#fff!important}.ui.purple.table{border-top:.2em solid #a333c8}.ui.inverted.purple.table{background-color:#a333c8!important;color:#fff!important}.ui.pink.table{border-top:.2em solid #e03997}.ui.inverted.pink.table{background-color:#e03997!important;color:#fff!important}.ui.brown.table{border-top:.2em solid #a5673f}.ui.inverted.brown.table{background-color:#a5673f!important;color:#fff!important}.ui.grey.table{border-top:.2em solid #767676}.ui.inverted.grey.table{background-color:#767676!important;color:#fff!important}.ui.black.table{border-top:.2em solid #1b1c1d}.ui.inverted.black.table{background-color:#1b1c1d!important;color:#fff!important}.ui.one.column.table td{width:100%}.ui.two.column.table td{width:50%}.ui.three.column.table td{width:33.33333333%}.ui.four.column.table td{width:25%}.ui.five.column.table td{width:20%}.ui.six.column.table td{width:16.66666667%}.ui.seven.column.table td{width:14.28571429%}.ui.eight.column.table td{width:12.5%}.ui.nine.column.table td{width:11.11111111%}.ui.ten.column.table td{width:10%}.ui.eleven.column.table td{width:9.09090909%}.ui.twelve.column.table td{width:8.33333333%}.ui.thirteen.column.table td{width:7.69230769%}.ui.fourteen.column.table td{width:7.14285714%}.ui.fifteen.column.table td{width:6.66666667%}.ui.sixteen.column.table td{width:6.25%}.ui.table td.one.wide,.ui.table th.one.wide{width:6.25%}.ui.table td.two.wide,.ui.table th.two.wide{width:12.5%}.ui.table td.three.wide,.ui.table th.three.wide{width:18.75%}.ui.table td.four.wide,.ui.table th.four.wide{width:25%}.ui.table td.five.wide,.ui.table th.five.wide{width:31.25%}.ui.table td.six.wide,.ui.table th.six.wide{width:37.5%}.ui.table td.seven.wide,.ui.table th.seven.wide{width:43.75%}.ui.table td.eight.wide,.ui.table th.eight.wide{width:50%}.ui.table td.nine.wide,.ui.table th.nine.wide{width:56.25%}.ui.table td.ten.wide,.ui.table th.ten.wide{width:62.5%}.ui.table td.eleven.wide,.ui.table th.eleven.wide{width:68.75%}.ui.table td.twelve.wide,.ui.table th.twelve.wide{width:75%}.ui.table td.thirteen.wide,.ui.table th.thirteen.wide{width:81.25%}.ui.table td.fourteen.wide,.ui.table th.fourteen.wide{width:87.5%}.ui.table td.fifteen.wide,.ui.table th.fifteen.wide{width:93.75%}.ui.table td.sixteen.wide,.ui.table th.sixteen.wide{width:100%}.ui.sortable.table thead th{cursor:pointer;white-space:nowrap;border-left:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87)}.ui.sortable.table thead th:first-child{border-left:none}.ui.sortable.table thead th.sorted,.ui.sortable.table thead th.sorted:hover{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui.sortable.table thead th:after{display:none;font-style:normal;font-weight:400;text-decoration:inherit;content:'';height:1em;width:auto;opacity:.8;margin:0 0 0 .5em;font-family:Icons}.ui.sortable.table thead th.ascending:after{content:'\\\\f0d8'}.ui.sortable.table thead th.descending:after{content:'\\\\f0d7'}.ui.sortable.table th.disabled:hover{cursor:auto;color:rgba(40,40,40,.3)}.ui.sortable.table thead th:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.8)}.ui.sortable.table thead th.sorted{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.sortable.table thead th.sorted:after{display:inline-block}.ui.sortable.table thead th.sorted:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95)}.ui.inverted.sortable.table thead th.sorted{background:rgba(255,255,255,.15) -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:rgba(255,255,255,.15) -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:rgba(255,255,255,.15) linear-gradient(transparent,rgba(0,0,0,.05));color:#fff}.ui.inverted.sortable.table thead th:hover{background:rgba(255,255,255,.08) -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:rgba(255,255,255,.08) -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:rgba(255,255,255,.08) linear-gradient(transparent,rgba(0,0,0,.05));color:#fff}.ui.inverted.sortable.table thead th{border-left-color:transparent;border-right-color:transparent}.ui.inverted.table{background:#333;color:rgba(255,255,255,.9);border:none}.ui.inverted.table th{background-color:rgba(0,0,0,.15);border-color:rgba(255,255,255,.1)!important;color:rgba(255,255,255,.9)!important}.ui.inverted.table tr td{border-color:rgba(255,255,255,.1)!important}.ui.inverted.table tr td.disabled,.ui.inverted.table tr.disabled td,.ui.inverted.table tr.disabled:hover td,.ui.inverted.table tr:hover td.disabled{pointer-events:none;color:rgba(225,225,225,.3)}.ui.inverted.definition.table tfoot:not(.full-width) th:first-child,.ui.inverted.definition.table thead:not(.full-width) th:first-child{background:#fff}.ui.inverted.definition.table tr td:first-child{background:rgba(255,255,255,.02);color:#fff}.ui.collapsing.table{width:auto}.ui.basic.table{background:0 0;border:1px solid rgba(34,36,38,.15);-webkit-box-shadow:none;box-shadow:none}.ui.basic.table tfoot,.ui.basic.table thead{-webkit-box-shadow:none;box-shadow:none}.ui.basic.table th{background:0 0;border-left:none}.ui.basic.table tbody tr{border-bottom:1px solid rgba(0,0,0,.1)}.ui.basic.table td{background:0 0}.ui.basic.striped.table tbody tr:nth-child(2n){background-color:rgba(0,0,0,.05)!important}.ui[class*=\\\"very basic\\\"].table{border:none}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th{padding:''}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td:first-child,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th:first-child{padding-left:0}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) td:last-child,.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) th:last-child{padding-right:0}.ui[class*=\\\"very basic\\\"].table:not(.sortable):not(.striped) thead tr:first-child th{padding-top:0}.ui.celled.table tr td,.ui.celled.table tr th{border-left:1px solid rgba(34,36,38,.1)}.ui.celled.table tr td:first-child,.ui.celled.table tr th:first-child{border-left:none}.ui.padded.table th{padding-left:1em;padding-right:1em}.ui.padded.table td,.ui.padded.table th{padding:1em 1em}.ui[class*=\\\"very padded\\\"].table th{padding-left:1.5em;padding-right:1.5em}.ui[class*=\\\"very padded\\\"].table td{padding:1.5em 1.5em}.ui.compact.table th{padding-left:.7em;padding-right:.7em}.ui.compact.table td{padding:.5em .7em}.ui[class*=\\\"very compact\\\"].table th{padding-left:.6em;padding-right:.6em}.ui[class*=\\\"very compact\\\"].table td{padding:.4em .6em}.ui.small.table{font-size:.9em}.ui.table{font-size:1em}.ui.large.table{font-size:1.1em}/*!\\n * # Semantic UI 2.4.0 - Ad\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Copyright 2013 Contributors\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child{margin:0}.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*=\\\"medium rectangle\\\"].ad{width:300px;height:250px}.ui[class*=\\\"large rectangle\\\"].ad{width:336px;height:280px}.ui[class*=\\\"half page\\\"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*=\\\"small square\\\"].ad{width:200px;height:200px}.ui[class*=\\\"small rectangle\\\"].ad{width:180px;height:150px}.ui[class*=\\\"vertical rectangle\\\"].ad{width:240px;height:400px}.ui.button.ad{width:120px;height:90px}.ui[class*=\\\"square button\\\"].ad{width:125px;height:125px}.ui[class*=\\\"small button\\\"].ad{width:120px;height:60px}.ui.skyscraper.ad{width:120px;height:600px}.ui[class*=\\\"wide skyscraper\\\"].ad{width:160px}.ui.banner.ad{width:468px;height:60px}.ui[class*=\\\"vertical banner\\\"].ad{width:120px;height:240px}.ui[class*=\\\"top banner\\\"].ad{width:930px;height:180px}.ui[class*=\\\"half banner\\\"].ad{width:234px;height:60px}.ui[class*=\\\"large leaderboard\\\"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:120px}.ui.netboard.ad{width:580px;height:400px}.ui[class*=\\\"large mobile banner\\\"].ad{width:320px;height:100px}.ui[class*=\\\"mobile leaderboard\\\"].ad{width:320px;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#545454}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714286em}.ui.test.ad[data-text]:after{content:attr(data-text)}/*!\\n * # Semantic UI 2.4.0 - Item\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.card,.ui.cards>.card{max-width:100%;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:290px;min-height:0;background:#fff;padding:0;border:none;border-radius:.28571429rem;-webkit-box-shadow:0 1px 3px 0 #d4d4d5,0 0 0 1px #d4d4d5;box-shadow:0 1px 3px 0 #d4d4d5,0 0 0 1px #d4d4d5;-webkit-transition:-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:box-shadow .1s ease,transform .1s ease;transition:box-shadow .1s ease,transform .1s ease,-webkit-box-shadow .1s ease,-webkit-transform .1s ease;z-index:''}.ui.card{margin:1em 0}.ui.card a,.ui.cards>.card a{cursor:pointer}.ui.card:first-child{margin-top:0}.ui.card:last-child{margin-bottom:0}.ui.cards{display:-webkit-box;display:-ms-flexbox;display:flex;margin:-.875em -.5em;-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.cards>.card{display:-webkit-box;display:-ms-flexbox;display:flex;margin:.875em .5em;float:none}.ui.card:after,.ui.cards:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.cards~.ui.cards{margin-top:.875em}.ui.card>:first-child,.ui.cards>.card>:first-child{border-radius:.28571429rem .28571429rem 0 0!important;border-top:none!important}.ui.card>:last-child,.ui.cards>.card>:last-child{border-radius:0 0 .28571429rem .28571429rem!important}.ui.card>:only-child,.ui.cards>.card>:only-child{border-radius:.28571429rem!important}.ui.card>.image,.ui.cards>.card>.image{position:relative;display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding:0;background:rgba(0,0,0,.05)}.ui.card>.image>img,.ui.cards>.card>.image>img{display:block;width:100%;height:auto;border-radius:inherit}.ui.card>.image:not(.ui)>img,.ui.cards>.card>.image:not(.ui)>img{border:none}.ui.card>.content,.ui.cards>.card>.content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;border:none;border-top:1px solid rgba(34,36,38,.1);background:0 0;margin:0;padding:1em 1em;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border-radius:0}.ui.card>.content:after,.ui.cards>.card>.content:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.card>.content>.header,.ui.cards>.card>.content>.header{display:block;margin:'';font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;color:rgba(0,0,0,.85)}.ui.card>.content>.header:not(.ui),.ui.cards>.card>.content>.header:not(.ui){font-weight:700;font-size:1.28571429em;margin-top:-.21425em;line-height:1.28571429em}.ui.card>.content>.header+.description,.ui.card>.content>.meta+.description,.ui.cards>.card>.content>.header+.description,.ui.cards>.card>.content>.meta+.description{margin-top:.5em}.ui.card [class*=\\\"left floated\\\"],.ui.cards>.card [class*=\\\"left floated\\\"]{float:left}.ui.card [class*=\\\"right floated\\\"],.ui.cards>.card [class*=\\\"right floated\\\"]{float:right}.ui.card [class*=\\\"left aligned\\\"],.ui.cards>.card [class*=\\\"left aligned\\\"]{text-align:left}.ui.card [class*=\\\"center aligned\\\"],.ui.cards>.card [class*=\\\"center aligned\\\"]{text-align:center}.ui.card [class*=\\\"right aligned\\\"],.ui.cards>.card [class*=\\\"right aligned\\\"]{text-align:right}.ui.card .content img,.ui.cards>.card .content img{display:inline-block;vertical-align:middle;width:''}.ui.card .avatar img,.ui.card img.avatar,.ui.cards>.card .avatar img,.ui.cards>.card img.avatar{width:2em;height:2em;border-radius:500rem}.ui.card>.content>.description,.ui.cards>.card>.content>.description{clear:both;color:rgba(0,0,0,.68)}.ui.card>.content p,.ui.cards>.card>.content p{margin:0 0 .5em}.ui.card>.content p:last-child,.ui.cards>.card>.content p:last-child{margin-bottom:0}.ui.card .meta,.ui.cards>.card .meta{font-size:1em;color:rgba(0,0,0,.4)}.ui.card .meta *,.ui.cards>.card .meta *{margin-right:.3em}.ui.card .meta :last-child,.ui.cards>.card .meta :last-child{margin-right:0}.ui.card .meta [class*=\\\"right floated\\\"],.ui.cards>.card .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.card>.content a:not(.ui),.ui.cards>.card>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content a:not(.ui):hover,.ui.cards>.card>.content a:not(.ui):hover{color:''}.ui.card>.content>a.header,.ui.cards>.card>.content>a.header{color:rgba(0,0,0,.85)}.ui.card>.content>a.header:hover,.ui.cards>.card>.content>a.header:hover{color:#1e70bf}.ui.card .meta>a:not(.ui),.ui.cards>.card .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.card .meta>a:not(.ui):hover,.ui.cards>.card .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.card>.button,.ui.card>.buttons,.ui.cards>.card>.button,.ui.cards>.card>.buttons{margin:0 -1px;width:calc(100% + 2px)}.ui.card .dimmer,.ui.cards>.card .dimmer{background-color:'';z-index:10}.ui.card>.content .star.icon,.ui.cards>.card>.content .star.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content .star.icon:hover,.ui.cards>.card>.content .star.icon:hover{opacity:1;color:#ffb70a}.ui.card>.content .active.star.icon,.ui.cards>.card>.content .active.star.icon{color:#ffe623}.ui.card>.content .like.icon,.ui.cards>.card>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.content .like.icon:hover,.ui.cards>.card>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.card>.content .active.like.icon,.ui.cards>.card>.content .active.like.icon{color:#ff2733}.ui.card>.extra,.ui.cards>.card>.extra{max-width:100%;min-height:0!important;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;border-top:1px solid rgba(0,0,0,.05)!important;position:static;background:0 0;width:auto;margin:0 0;padding:.75em 1em;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.card>.extra a:not(.ui),.ui.cards>.card>.extra a:not(.ui){color:rgba(0,0,0,.4)}.ui.card>.extra a:not(.ui):hover,.ui.cards>.card>.extra a:not(.ui):hover{color:#1e70bf}.ui.raised.card,.ui.raised.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.link.cards .raised.card:hover,.ui.link.raised.card:hover,.ui.raised.cards a.card:hover,a.ui.raised.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25)}.ui.raised.card,.ui.raised.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.centered.cards{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ui.centered.card{margin-left:auto;margin-right:auto}.ui.fluid.card{width:100%;max-width:9999px}.ui.cards a.card,.ui.link.card,.ui.link.cards .card,a.ui.card{-webkit-transform:none;transform:none}.ui.cards a.card:hover,.ui.link.card:hover,.ui.link.cards .card:hover,a.ui.card:hover{cursor:pointer;z-index:5;background:#fff;border:none;-webkit-box-shadow:0 1px 3px 0 #bcbdbd,0 0 0 1px #d4d4d5;box-shadow:0 1px 3px 0 #bcbdbd,0 0 0 1px #d4d4d5;-webkit-transform:translateY(-3px);transform:translateY(-3px)}.ui.cards>.red.card,.ui.red.card,.ui.red.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #db2828,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #db2828,0 1px 3px 0 #d4d4d5}.ui.cards>.red.card:hover,.ui.red.card:hover,.ui.red.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #d01919,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #d01919,0 1px 3px 0 #bcbdbd}.ui.cards>.orange.card,.ui.orange.card,.ui.orange.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f2711c,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f2711c,0 1px 3px 0 #d4d4d5}.ui.cards>.orange.card:hover,.ui.orange.card:hover,.ui.orange.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f26202,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f26202,0 1px 3px 0 #bcbdbd}.ui.cards>.yellow.card,.ui.yellow.card,.ui.yellow.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #fbbd08,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #fbbd08,0 1px 3px 0 #d4d4d5}.ui.cards>.yellow.card:hover,.ui.yellow.card:hover,.ui.yellow.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #eaae00,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #eaae00,0 1px 3px 0 #bcbdbd}.ui.cards>.olive.card,.ui.olive.card,.ui.olive.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #b5cc18,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #b5cc18,0 1px 3px 0 #d4d4d5}.ui.cards>.olive.card:hover,.ui.olive.card:hover,.ui.olive.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a7bd0d,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a7bd0d,0 1px 3px 0 #bcbdbd}.ui.cards>.green.card,.ui.green.card,.ui.green.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #21ba45,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #21ba45,0 1px 3px 0 #d4d4d5}.ui.cards>.green.card:hover,.ui.green.card:hover,.ui.green.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #16ab39,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #16ab39,0 1px 3px 0 #bcbdbd}.ui.cards>.teal.card,.ui.teal.card,.ui.teal.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #00b5ad,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #00b5ad,0 1px 3px 0 #d4d4d5}.ui.cards>.teal.card:hover,.ui.teal.card:hover,.ui.teal.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #009c95,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #009c95,0 1px 3px 0 #bcbdbd}.ui.blue.card,.ui.blue.cards>.card,.ui.cards>.blue.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5}.ui.blue.card:hover,.ui.blue.cards>.card:hover,.ui.cards>.blue.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd}.ui.cards>.violet.card,.ui.violet.card,.ui.violet.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #6435c9,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #6435c9,0 1px 3px 0 #d4d4d5}.ui.cards>.violet.card:hover,.ui.violet.card:hover,.ui.violet.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #5829bb,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #5829bb,0 1px 3px 0 #bcbdbd}.ui.cards>.purple.card,.ui.purple.card,.ui.purple.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a333c8,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a333c8,0 1px 3px 0 #d4d4d5}.ui.cards>.purple.card:hover,.ui.purple.card:hover,.ui.purple.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #9627ba,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #9627ba,0 1px 3px 0 #bcbdbd}.ui.cards>.pink.card,.ui.pink.card,.ui.pink.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e03997,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e03997,0 1px 3px 0 #d4d4d5}.ui.cards>.pink.card:hover,.ui.pink.card:hover,.ui.pink.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e61a8d,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e61a8d,0 1px 3px 0 #bcbdbd}.ui.brown.card,.ui.brown.cards>.card,.ui.cards>.brown.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a5673f,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a5673f,0 1px 3px 0 #d4d4d5}.ui.brown.card:hover,.ui.brown.cards>.card:hover,.ui.cards>.brown.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #975b33,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #975b33,0 1px 3px 0 #bcbdbd}.ui.cards>.grey.card,.ui.grey.card,.ui.grey.cards>.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #767676,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #767676,0 1px 3px 0 #d4d4d5}.ui.cards>.grey.card:hover,.ui.grey.card:hover,.ui.grey.cards>.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #838383,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #838383,0 1px 3px 0 #bcbdbd}.ui.black.card,.ui.black.cards>.card,.ui.cards>.black.card{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5}.ui.black.card:hover,.ui.black.cards>.card:hover,.ui.cards>.black.card:hover{-webkit-box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd;box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd}.ui.one.cards{margin-left:0;margin-right:0}.ui.one.cards>.card{width:100%}.ui.two.cards{margin-left:-1em;margin-right:-1em}.ui.two.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.three.cards{margin-left:-1em;margin-right:-1em}.ui.three.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.four.cards{margin-left:-.75em;margin-right:-.75em}.ui.four.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.five.cards{margin-left:-.75em;margin-right:-.75em}.ui.five.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.six.cards{margin-left:-.75em;margin-right:-.75em}.ui.six.cards>.card{width:calc(16.66666667% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.seven.cards{margin-left:-.5em;margin-right:-.5em}.ui.seven.cards>.card{width:calc(14.28571429% - 1em);margin-left:.5em;margin-right:.5em}.ui.eight.cards{margin-left:-.5em;margin-right:-.5em}.ui.eight.cards>.card{width:calc(12.5% - 1em);margin-left:.5em;margin-right:.5em;font-size:11px}.ui.nine.cards{margin-left:-.5em;margin-right:-.5em}.ui.nine.cards>.card{width:calc(11.11111111% - 1em);margin-left:.5em;margin-right:.5em;font-size:10px}.ui.ten.cards{margin-left:-.5em;margin-right:-.5em}.ui.ten.cards>.card{width:calc(10% - 1em);margin-left:.5em;margin-right:.5em}@media only screen and (max-width:767px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.seven.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.seven.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.nine.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.nine.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.ten.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.ten.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}}@media only screen and (min-width:768px) and (max-width:991px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.eight.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.nine.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.nine.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.ten.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.ten.doubling.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}}@media only screen and (max-width:767px){.ui.stackable.cards{display:block!important}.ui.stackable.cards .card:first-child{margin-top:0!important}.ui.stackable.cards>.card{display:block!important;height:auto!important;margin:1em 1em;padding:0!important;width:calc(100% - 2em)!important}}.ui.cards>.card{font-size:1em}/*!\\n * # Semantic UI 2.4.0 - Comment\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.comments{margin:1.5em 0;max-width:650px}.ui.comments:first-child{margin-top:0}.ui.comments:last-child{margin-bottom:0}.ui.comments .comment{position:relative;background:0 0;margin:.5em 0 0;padding:.5em 0 0;border:none;border-top:none;line-height:1.2}.ui.comments .comment:first-child{margin-top:0;padding-top:0}.ui.comments .comment .comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment .comments:before{position:absolute;top:0;left:0}.ui.comments .comment .comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.87);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#1e70bf}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.87);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment .comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;-webkit-box-shadow:-1px 0 0 rgba(34,36,38,.15);box-shadow:-1px 0 0 rgba(34,36,38,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;-webkit-transition-delay:.1s;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.mini.comments{font-size:.78571429rem}.ui.tiny.comments{font-size:.85714286rem}.ui.small.comments{font-size:.92857143rem}.ui.comments{font-size:1rem}.ui.large.comments{font-size:1.14285714rem}.ui.big.comments{font-size:1.28571429rem}.ui.huge.comments{font-size:1.42857143rem}.ui.massive.comments{font-size:1.71428571rem}/*!\\n * # Semantic UI 2.4.0 - Feed\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.feed{margin:1em 0}.ui.feed:first-child{margin-top:0}.ui.feed:last-child{margin-bottom:0}.ui.feed>.event{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;width:100%;padding:.21428571rem 0;margin:0;background:0 0;border-top:none}.ui.feed>.event:first-child{border-top:0;padding-top:0}.ui.feed>.event:last-child{padding-bottom:0}.ui.feed>.event>.label{display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:2.5em;height:auto;-ms-flex-item-align:stretch;align-self:stretch;text-align:left}.ui.feed>.event>.label .icon{opacity:1;font-size:1.5em;width:100%;padding:.25em;background:0 0;border:none;border-radius:none;color:rgba(0,0,0,.6)}.ui.feed>.event>.label img{width:100%;height:auto;border-radius:500rem}.ui.feed>.event>.label+.content{margin:.5em 0 .35714286em 1.14285714em}.ui.feed>.event>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-item-align:stretch;align-self:stretch;text-align:left;word-wrap:break-word}.ui.feed>.event:last-child>.content{padding-bottom:0}.ui.feed>.event>.content a{cursor:pointer}.ui.feed>.event>.content .date{margin:-.5rem 0 0;padding:0;font-weight:400;font-size:1em;font-style:normal;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .summary{margin:0;font-size:1em;font-weight:700;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .summary img{display:inline-block;width:auto;height:10em;margin:-.25em .25em 0 0;border-radius:.25em;vertical-align:middle}.ui.feed>.event>.content .user{display:inline-block;font-weight:700;margin-right:0;vertical-align:baseline}.ui.feed>.event>.content .user img{margin:-.25em .25em 0 0;width:auto;height:10em;vertical-align:middle}.ui.feed>.event>.content .summary>.date{display:inline-block;float:none;font-weight:400;font-size:.85714286em;font-style:normal;margin:0 0 0 .5em;padding:0;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .extra{margin:.5em 0 0;background:0 0;padding:0;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .extra.images img{display:inline-block;margin:0 .25em 0 0;width:6em}.ui.feed>.event>.content .extra.text{padding:0;border-left:none;font-size:1em;max-width:500px;line-height:1.4285em}.ui.feed>.event>.content .meta{display:inline-block;font-size:.85714286em;margin:.5em 0 0;background:0 0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;padding:0;color:rgba(0,0,0,.6)}.ui.feed>.event>.content .meta>*{position:relative;margin-left:.75em}.ui.feed>.event>.content .meta>:after{content:'';color:rgba(0,0,0,.2);top:0;left:-1em;opacity:1;position:absolute;vertical-align:top}.ui.feed>.event>.content .meta .like{color:'';-webkit-transition:.2s color ease;transition:.2s color ease}.ui.feed>.event>.content .meta .like:hover .icon{color:#ff2733}.ui.feed>.event>.content .meta .active.like .icon{color:#ef404a}.ui.feed>.event>.content .meta>:first-child{margin-left:0}.ui.feed>.event>.content .meta>:first-child::after{display:none}.ui.feed>.event>.content .meta a,.ui.feed>.event>.content .meta>.icon{cursor:pointer;opacity:1;color:rgba(0,0,0,.5);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.feed>.event>.content .meta a:hover,.ui.feed>.event>.content .meta a:hover .icon,.ui.feed>.event>.content .meta>.icon:hover{color:rgba(0,0,0,.95)}.ui.small.feed{font-size:.92857143rem}.ui.feed{font-size:1rem}.ui.large.feed{font-size:1.14285714rem}/*!\\n * # Semantic UI 2.4.0 - Item\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:top;align-self:top}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:top;align-self:top;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:middle;align-self:middle;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}@media only screen and (max-width:767px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}/*!\\n * # Semantic UI 2.4.0 - Statistic\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.statistic{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:1em 0;max-width:auto}.ui.statistic+.ui.statistic{margin:0 0 0 1.5em}.ui.statistic:first-child{margin-top:0}.ui.statistic:last-child{margin-bottom:0}.ui.statistics{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-ms-flex-wrap:wrap;flex-wrap:wrap}.ui.statistics>.statistic{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 1.5em 1em;max-width:auto}.ui.statistics{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em -1.5em -1em}.ui.statistics:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.statistics:first-child{margin-top:0}.ui.statistic>.value,.ui.statistics .statistic>.value{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:4rem;font-weight:400;line-height:1em;color:#1b1c1d;text-transform:uppercase;text-align:center}.ui.statistic>.label,.ui.statistics .statistic>.label{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;font-weight:700;color:rgba(0,0,0,.87);text-transform:uppercase;text-align:center}.ui.statistic>.label~.value,.ui.statistics .statistic>.label~.value{margin-top:0}.ui.statistic>.value~.label,.ui.statistics .statistic>.value~.label{margin-top:0}.ui.statistic>.value .icon,.ui.statistics .statistic>.value .icon{opacity:1;width:auto;margin:0}.ui.statistic>.text.value,.ui.statistics .statistic>.text.value{line-height:1em;min-height:2em;font-weight:700;text-align:center}.ui.statistic>.text.value+.label,.ui.statistics .statistic>.text.value+.label{text-align:center}.ui.statistic>.value img,.ui.statistics .statistic>.value img{max-height:3rem;vertical-align:baseline}.ui.ten.statistics{margin:0 0 -1em}.ui.ten.statistics .statistic{min-width:10%;margin:0 0 1em}.ui.nine.statistics{margin:0 0 -1em}.ui.nine.statistics .statistic{min-width:11.11111111%;margin:0 0 1em}.ui.eight.statistics{margin:0 0 -1em}.ui.eight.statistics .statistic{min-width:12.5%;margin:0 0 1em}.ui.seven.statistics{margin:0 0 -1em}.ui.seven.statistics .statistic{min-width:14.28571429%;margin:0 0 1em}.ui.six.statistics{margin:0 0 -1em}.ui.six.statistics .statistic{min-width:16.66666667%;margin:0 0 1em}.ui.five.statistics{margin:0 0 -1em}.ui.five.statistics .statistic{min-width:20%;margin:0 0 1em}.ui.four.statistics{margin:0 0 -1em}.ui.four.statistics .statistic{min-width:25%;margin:0 0 1em}.ui.three.statistics{margin:0 0 -1em}.ui.three.statistics .statistic{min-width:33.33333333%;margin:0 0 1em}.ui.two.statistics{margin:0 0 -1em}.ui.two.statistics .statistic{min-width:50%;margin:0 0 1em}.ui.one.statistics{margin:0 0 -1em}.ui.one.statistics .statistic{min-width:100%;margin:0 0 1em}.ui.horizontal.statistic{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.horizontal.statistics{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0;max-width:none}.ui.horizontal.statistics .statistic{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:none;margin:1em 0}.ui.horizontal.statistic>.text.value,.ui.horizontal.statistics>.statistic>.text.value{min-height:0!important}.ui.horizontal.statistic>.value .icon,.ui.horizontal.statistics .statistic>.value .icon{width:1.18em}.ui.horizontal.statistic>.value,.ui.horizontal.statistics .statistic>.value{display:inline-block;vertical-align:middle}.ui.horizontal.statistic>.label,.ui.horizontal.statistics .statistic>.label{display:inline-block;vertical-align:middle;margin:0 0 0 .75em}.ui.red.statistic>.value,.ui.red.statistics .statistic>.value,.ui.statistics .red.statistic>.value{color:#db2828}.ui.orange.statistic>.value,.ui.orange.statistics .statistic>.value,.ui.statistics .orange.statistic>.value{color:#f2711c}.ui.statistics .yellow.statistic>.value,.ui.yellow.statistic>.value,.ui.yellow.statistics .statistic>.value{color:#fbbd08}.ui.olive.statistic>.value,.ui.olive.statistics .statistic>.value,.ui.statistics .olive.statistic>.value{color:#b5cc18}.ui.green.statistic>.value,.ui.green.statistics .statistic>.value,.ui.statistics .green.statistic>.value{color:#21ba45}.ui.statistics .teal.statistic>.value,.ui.teal.statistic>.value,.ui.teal.statistics .statistic>.value{color:#00b5ad}.ui.blue.statistic>.value,.ui.blue.statistics .statistic>.value,.ui.statistics .blue.statistic>.value{color:#2185d0}.ui.statistics .violet.statistic>.value,.ui.violet.statistic>.value,.ui.violet.statistics .statistic>.value{color:#6435c9}.ui.purple.statistic>.value,.ui.purple.statistics .statistic>.value,.ui.statistics .purple.statistic>.value{color:#a333c8}.ui.pink.statistic>.value,.ui.pink.statistics .statistic>.value,.ui.statistics .pink.statistic>.value{color:#e03997}.ui.brown.statistic>.value,.ui.brown.statistics .statistic>.value,.ui.statistics .brown.statistic>.value{color:#a5673f}.ui.grey.statistic>.value,.ui.grey.statistics .statistic>.value,.ui.statistics .grey.statistic>.value{color:#767676}.ui.inverted.statistic .value,.ui.inverted.statistics .statistic>.value{color:#fff}.ui.inverted.statistic .label,.ui.inverted.statistics .statistic>.label{color:rgba(255,255,255,.9)}.ui.inverted.red.statistic>.value,.ui.inverted.red.statistics .statistic>.value,.ui.statistics .inverted.red.statistic>.value{color:#ff695e}.ui.inverted.orange.statistic>.value,.ui.inverted.orange.statistics .statistic>.value,.ui.statistics .inverted.orange.statistic>.value{color:#ff851b}.ui.inverted.yellow.statistic>.value,.ui.inverted.yellow.statistics .statistic>.value,.ui.statistics .inverted.yellow.statistic>.value{color:#ffe21f}.ui.inverted.olive.statistic>.value,.ui.inverted.olive.statistics .statistic>.value,.ui.statistics .inverted.olive.statistic>.value{color:#d9e778}.ui.inverted.green.statistic>.value,.ui.inverted.green.statistics .statistic>.value,.ui.statistics .inverted.green.statistic>.value{color:#2ecc40}.ui.inverted.teal.statistic>.value,.ui.inverted.teal.statistics .statistic>.value,.ui.statistics .inverted.teal.statistic>.value{color:#6dffff}.ui.inverted.blue.statistic>.value,.ui.inverted.blue.statistics .statistic>.value,.ui.statistics .inverted.blue.statistic>.value{color:#54c8ff}.ui.inverted.violet.statistic>.value,.ui.inverted.violet.statistics .statistic>.value,.ui.statistics .inverted.violet.statistic>.value{color:#a291fb}.ui.inverted.purple.statistic>.value,.ui.inverted.purple.statistics .statistic>.value,.ui.statistics .inverted.purple.statistic>.value{color:#dc73ff}.ui.inverted.pink.statistic>.value,.ui.inverted.pink.statistics .statistic>.value,.ui.statistics .inverted.pink.statistic>.value{color:#ff8edf}.ui.inverted.brown.statistic>.value,.ui.inverted.brown.statistics .statistic>.value,.ui.statistics .inverted.brown.statistic>.value{color:#d67c1c}.ui.inverted.grey.statistic>.value,.ui.inverted.grey.statistics .statistic>.value,.ui.statistics .inverted.grey.statistic>.value{color:#dcddde}.ui[class*=\\\"left floated\\\"].statistic{float:left;margin:0 2em 1em 0}.ui[class*=\\\"right floated\\\"].statistic{float:right;margin:0 0 1em 2em}.ui.floated.statistic:last-child{margin-bottom:0}.ui.mini.statistic>.value,.ui.mini.statistics .statistic>.value{font-size:1.5rem!important}.ui.mini.horizontal.statistic>.value,.ui.mini.horizontal.statistics .statistic>.value{font-size:1.5rem!important}.ui.mini.statistic>.text.value,.ui.mini.statistics .statistic>.text.value{font-size:1rem!important}.ui.tiny.statistic>.value,.ui.tiny.statistics .statistic>.value{font-size:2rem!important}.ui.tiny.horizontal.statistic>.value,.ui.tiny.horizontal.statistics .statistic>.value{font-size:2rem!important}.ui.tiny.statistic>.text.value,.ui.tiny.statistics .statistic>.text.value{font-size:1rem!important}.ui.small.statistic>.value,.ui.small.statistics .statistic>.value{font-size:3rem!important}.ui.small.horizontal.statistic>.value,.ui.small.horizontal.statistics .statistic>.value{font-size:2rem!important}.ui.small.statistic>.text.value,.ui.small.statistics .statistic>.text.value{font-size:1rem!important}.ui.statistic>.value,.ui.statistics .statistic>.value{font-size:4rem!important}.ui.horizontal.statistic>.value,.ui.horizontal.statistics .statistic>.value{font-size:3rem!important}.ui.statistic>.text.value,.ui.statistics .statistic>.text.value{font-size:2rem!important}.ui.large.statistic>.value,.ui.large.statistics .statistic>.value{font-size:5rem!important}.ui.large.horizontal.statistic>.value,.ui.large.horizontal.statistics .statistic>.value{font-size:4rem!important}.ui.large.statistic>.text.value,.ui.large.statistics .statistic>.text.value{font-size:2.5rem!important}.ui.huge.statistic>.value,.ui.huge.statistics .statistic>.value{font-size:6rem!important}.ui.huge.horizontal.statistic>.value,.ui.huge.horizontal.statistics .statistic>.value{font-size:5rem!important}.ui.huge.statistic>.text.value,.ui.huge.statistics .statistic>.text.value{font-size:2.5rem!important}/*!\\n * # Semantic UI 2.4.0 - Accordion\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.accordion,.ui.accordion .accordion{max-width:100%}.ui.accordion .accordion{margin:1em 0 0;padding:0}.ui.accordion .accordion .title,.ui.accordion .title{cursor:pointer}.ui.accordion .title:not(.ui){padding:.5em 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;color:rgba(0,0,0,.87)}.ui.accordion .accordion .title~.content,.ui.accordion .title~.content{display:none}.ui.accordion:not(.styled) .accordion .title~.content:not(.ui),.ui.accordion:not(.styled) .title~.content:not(.ui){margin:'';padding:.5em 0 1em}.ui.accordion:not(.styled) .title~.content:not(.ui):last-child{padding-bottom:0}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{display:inline-block;float:none;opacity:1;width:1.25em;height:1em;margin:0 .25rem 0 0;padding:0;font-size:1em;-webkit-transition:opacity .1s ease,-webkit-transform .1s ease;transition:opacity .1s ease,-webkit-transform .1s ease;transition:transform .1s ease,opacity .1s ease;transition:transform .1s ease,opacity .1s ease,-webkit-transform .1s ease;vertical-align:baseline;-webkit-transform:none;transform:none}.ui.accordion.menu .item .title{display:block;padding:0}.ui.accordion.menu .item .title>.dropdown.icon{float:right;margin:.21425em 0 0 1em;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.ui.accordion .ui.header .dropdown.icon{font-size:1em;margin:0 .25rem 0 0}.ui.accordion .accordion .active.title .dropdown.icon,.ui.accordion .active.title .dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.accordion.menu .item .active.title>.dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.styled.accordion{width:600px}.ui.styled.accordion,.ui.styled.accordion .accordion{border-radius:.28571429rem;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15);box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15)}.ui.styled.accordion .accordion .title,.ui.styled.accordion .title{margin:0;padding:.75em 1em;color:rgba(0,0,0,.4);font-weight:700;border-top:1px solid rgba(34,36,38,.15);-webkit-transition:background .1s ease,color .1s ease;transition:background .1s ease,color .1s ease}.ui.styled.accordion .accordion .title:first-child,.ui.styled.accordion>.title:first-child{border-top:none}.ui.styled.accordion .accordion .content,.ui.styled.accordion .content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .content{padding:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover,.ui.styled.accordion .active.title,.ui.styled.accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.styled.accordion .accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.accordion .accordion .active.content,.ui.accordion .active.content{display:block}.ui.fluid.accordion,.ui.fluid.accordion .accordion{width:100%}.ui.inverted.accordion .title:not(.ui){color:rgba(255,255,255,.9)}@font-face{font-family:Accordion;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggjB5AAAAC8AAAAYGNtYXAPfOIKAAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5Zryj6HgAAAFwAAAAyGhlYWT/0IhHAAACOAAAADZoaGVhApkB5wAAAnAAAAAkaG10eAJuABIAAAKUAAAAGGxvY2EAjABWAAACrAAAAA5tYXhwAAgAFgAAArwAAAAgbmFtZfC1n04AAALcAAABPHBvc3QAAwAAAAAEGAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQASAEkAtwFuABMAADc0PwE2FzYXFh0BFAcGJwYvASY1EgaABQgHBQYGBQcIBYAG2wcGfwcBAQcECf8IBAcBAQd/BgYAAAAAAQAAAEkApQFuABMAADcRNDc2MzIfARYVFA8BBiMiJyY1AAUGBwgFgAYGgAUIBwYFWwEACAUGBoAFCAcFgAYGBQcAAAABAAAAAQAAqWYls18PPPUACwIAAAAAAM/9o+4AAAAAz/2j7gAAAAAAtwFuAAAACAACAAAAAAAAAAEAAAHg/+AAAAIAAAAAAAC3AAEAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAQAAAAC3ABIAtwAAAAAAAAAKABQAHgBCAGQAAAABAAAABgAUAAEAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AAASwAAoAAAAABGgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAAS0AAAEtFpovuE9TLzIAAAIkAAAAYAAAAGAIIweQY21hcAAAAoQAAABMAAAATA984gpnYXNwAAAC0AAAAAgAAAAIAAAAEGhlYWQAAALYAAAANgAAADb/0IhHaGhlYQAAAxAAAAAkAAAAJAKZAedobXR4AAADNAAAABgAAAAYAm4AEm1heHAAAANMAAAABgAAAAYABlAAbmFtZQAAA1QAAAE8AAABPPC1n05wb3N0AAAEkAAAACAAAAAgAAMAAAEABAQAAQEBB3JhdGluZwABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeLa/iU+HQFHQAAAHkPHQAAAH4RHQAAAAkdAAABJBIABwEBBw0PERQZHnJhdGluZ3JhdGluZ3UwdTF1MjB1RjBEOXVGMERBAAACAYkABAAGAQEEBwoNVp38lA78lA78lA77lA773Z33bxWLkI2Qj44I9xT3FAWOj5CNkIuQi4+JjoePiI2Gi4YIi/uUBYuGiYeHiIiHh4mGi4aLho2Ijwj7FPcUBYeOiY+LkAgO+92L5hWL95QFi5CNkI6Oj4+PjZCLkIuQiY6HCPcU+xQFj4iNhouGi4aJh4eICPsU+xQFiIeGiYaLhouHjYePiI6Jj4uQCA74lBT4lBWLDAoAAAAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAEAADfYOJZfDzz1AAsCAAAAAADP/aPuAAAAAM/9o+4AAAAAALcBbgAAAAgAAgAAAAAAAAABAAAB4P/gAAACAAAAAAAAtwABAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAEAAAAAtwASALcAAAAAUAAABgAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('woff');font-weight:400;font-style:normal}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{font-family:Accordion;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.accordion .accordion .title .dropdown.icon:before,.ui.accordion .title .dropdown.icon:before{content:'\\\\f0da'}/*!\\n * # Semantic UI 2.4.0 - Checkbox\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.checkbox{position:relative;display:inline-block;-webkit-backface-visibility:hidden;backface-visibility:hidden;outline:0;vertical-align:baseline;font-style:normal;min-height:17px;font-size:1rem;line-height:17px;min-width:17px}.ui.checkbox input[type=checkbox],.ui.checkbox input[type=radio]{cursor:pointer;position:absolute;top:0;left:0;opacity:0!important;outline:0;z-index:3;width:17px;height:17px}.ui.checkbox .box,.ui.checkbox label{cursor:auto;position:relative;display:block;padding-left:1.85714em;outline:0;font-size:1em}.ui.checkbox .box:before,.ui.checkbox label:before{position:absolute;top:0;left:0;width:17px;height:17px;content:'';background:#fff;border-radius:.21428571rem;-webkit-transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;border:1px solid #d4d4d5}.ui.checkbox .box:after,.ui.checkbox label:after{position:absolute;font-size:14px;top:0;left:0;width:17px;height:17px;text-align:center;opacity:0;color:rgba(0,0,0,.87);-webkit-transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease,-webkit-transform .1s ease,-webkit-box-shadow .1s ease}.ui.checkbox label,.ui.checkbox+label{color:rgba(0,0,0,.87);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.checkbox+label{vertical-align:middle}.ui.checkbox .box:hover::before,.ui.checkbox label:hover::before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox label:hover,.ui.checkbox+label:hover{color:rgba(0,0,0,.8)}.ui.checkbox .box:active::before,.ui.checkbox label:active::before{background:#f9fafb;border-color:rgba(34,36,38,.35)}.ui.checkbox .box:active::after,.ui.checkbox label:active::after{color:rgba(0,0,0,.95)}.ui.checkbox input:active~label{color:rgba(0,0,0,.95)}.ui.checkbox input:focus~.box:before,.ui.checkbox input:focus~label:before{background:#fff;border-color:#96c8da}.ui.checkbox input:focus~.box:after,.ui.checkbox input:focus~label:after{color:rgba(0,0,0,.95)}.ui.checkbox input:focus~label{color:rgba(0,0,0,.95)}.ui.checkbox input:checked~.box:before,.ui.checkbox input:checked~label:before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:checked~.box:after,.ui.checkbox input:checked~label:after{opacity:1;color:rgba(0,0,0,.95)}.ui.checkbox input:not([type=radio]):indeterminate~.box:before,.ui.checkbox input:not([type=radio]):indeterminate~label:before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:not([type=radio]):indeterminate~.box:after,.ui.checkbox input:not([type=radio]):indeterminate~label:after{opacity:1;color:rgba(0,0,0,.95)}.ui.checkbox input:checked:focus~.box:before,.ui.checkbox input:checked:focus~label:before,.ui.checkbox input:not([type=radio]):indeterminate:focus~.box:before,.ui.checkbox input:not([type=radio]):indeterminate:focus~label:before{background:#fff;border-color:#96c8da}.ui.checkbox input:checked:focus~.box:after,.ui.checkbox input:checked:focus~label:after,.ui.checkbox input:not([type=radio]):indeterminate:focus~.box:after,.ui.checkbox input:not([type=radio]):indeterminate:focus~label:after{color:rgba(0,0,0,.95)}.ui.read-only.checkbox,.ui.read-only.checkbox label{cursor:default}.ui.checkbox input[disabled]~.box:after,.ui.checkbox input[disabled]~label,.ui.disabled.checkbox .box:after,.ui.disabled.checkbox label{cursor:default!important;opacity:.5;color:#000}.ui.checkbox input.hidden{z-index:-1}.ui.checkbox input.hidden+label{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui.radio.checkbox{min-height:15px}.ui.radio.checkbox .box,.ui.radio.checkbox label{padding-left:1.85714em}.ui.radio.checkbox .box:before,.ui.radio.checkbox label:before{content:'';-webkit-transform:none;transform:none;width:15px;height:15px;border-radius:500rem;top:1px;left:0}.ui.radio.checkbox .box:after,.ui.radio.checkbox label:after{border:none;content:''!important;width:15px;height:15px;line-height:15px}.ui.radio.checkbox .box:after,.ui.radio.checkbox label:after{top:1px;left:0;width:15px;height:15px;border-radius:500rem;-webkit-transform:scale(.46666667);transform:scale(.46666667);background-color:rgba(0,0,0,.87)}.ui.radio.checkbox input:focus~.box:before,.ui.radio.checkbox input:focus~label:before{background-color:#fff}.ui.radio.checkbox input:focus~.box:after,.ui.radio.checkbox input:focus~label:after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:indeterminate~.box:after,.ui.radio.checkbox input:indeterminate~label:after{opacity:0}.ui.radio.checkbox input:checked~.box:before,.ui.radio.checkbox input:checked~label:before{background-color:#fff}.ui.radio.checkbox input:checked~.box:after,.ui.radio.checkbox input:checked~label:after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:focus:checked~.box:before,.ui.radio.checkbox input:focus:checked~label:before{background-color:#fff}.ui.radio.checkbox input:focus:checked~.box:after,.ui.radio.checkbox input:focus:checked~label:after{background-color:rgba(0,0,0,.95)}.ui.slider.checkbox{min-height:1.25rem}.ui.slider.checkbox input{width:3.5rem;height:1.25rem}.ui.slider.checkbox .box,.ui.slider.checkbox label{padding-left:4.5rem;line-height:1rem;color:rgba(0,0,0,.4)}.ui.slider.checkbox .box:before,.ui.slider.checkbox label:before{display:block;position:absolute;content:'';border:none!important;left:0;z-index:1;top:.4rem;background-color:rgba(0,0,0,.05);width:3.5rem;height:.21428571rem;-webkit-transform:none;transform:none;border-radius:500rem;-webkit-transition:background .3s ease;transition:background .3s ease}.ui.slider.checkbox .box:after,.ui.slider.checkbox label:after{background:#fff -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#fff -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:''!important;opacity:1;z-index:2;border:none;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:-.25rem;left:0;-webkit-transform:none;transform:none;border-radius:500rem;-webkit-transition:left .3s ease;transition:left .3s ease}.ui.slider.checkbox input:focus~.box:before,.ui.slider.checkbox input:focus~label:before{background-color:rgba(0,0,0,.15);border:none}.ui.slider.checkbox .box:hover,.ui.slider.checkbox label:hover{color:rgba(0,0,0,.8)}.ui.slider.checkbox .box:hover::before,.ui.slider.checkbox label:hover::before{background:rgba(0,0,0,.15)}.ui.slider.checkbox input:checked~.box,.ui.slider.checkbox input:checked~label{color:rgba(0,0,0,.95)!important}.ui.slider.checkbox input:checked~.box:before,.ui.slider.checkbox input:checked~label:before{background-color:#545454!important}.ui.slider.checkbox input:checked~.box:after,.ui.slider.checkbox input:checked~label:after{left:2rem}.ui.slider.checkbox input:focus:checked~.box,.ui.slider.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)!important}.ui.slider.checkbox input:focus:checked~.box:before,.ui.slider.checkbox input:focus:checked~label:before{background-color:#000!important}.ui.toggle.checkbox{min-height:1.5rem}.ui.toggle.checkbox input{width:3.5rem;height:1.5rem}.ui.toggle.checkbox .box,.ui.toggle.checkbox label{min-height:1.5rem;padding-left:4.5rem;color:rgba(0,0,0,.87)}.ui.toggle.checkbox label{padding-top:.15em}.ui.toggle.checkbox .box:before,.ui.toggle.checkbox label:before{display:block;position:absolute;content:'';z-index:1;-webkit-transform:none;transform:none;border:none;top:0;background:rgba(0,0,0,.05);-webkit-box-shadow:none;box-shadow:none;width:3.5rem;height:1.5rem;border-radius:500rem}.ui.toggle.checkbox .box:after,.ui.toggle.checkbox label:after{background:#fff -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.05)));background:#fff -webkit-linear-gradient(transparent,rgba(0,0,0,.05));background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:''!important;opacity:1;z-index:2;border:none;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:0;left:0;border-radius:500rem;-webkit-transition:background .3s ease,left .3s ease;transition:background .3s ease,left .3s ease}.ui.toggle.checkbox input~.box:after,.ui.toggle.checkbox input~label:after{left:-.05rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus~.box:before,.ui.toggle.checkbox input:focus~label:before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox .box:hover::before,.ui.toggle.checkbox label:hover::before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox input:checked~.box,.ui.toggle.checkbox input:checked~label{color:rgba(0,0,0,.95)!important}.ui.toggle.checkbox input:checked~.box:before,.ui.toggle.checkbox input:checked~label:before{background-color:#2185d0!important}.ui.toggle.checkbox input:checked~.box:after,.ui.toggle.checkbox input:checked~label:after{left:2.15rem;-webkit-box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus:checked~.box,.ui.toggle.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)!important}.ui.toggle.checkbox input:focus:checked~.box:before,.ui.toggle.checkbox input:focus:checked~label:before{background-color:#0d71bb!important}.ui.fitted.checkbox .box,.ui.fitted.checkbox label{padding-left:0!important}.ui.fitted.toggle.checkbox{width:3.5rem}.ui.fitted.slider.checkbox{width:3.5rem}@font-face{font-family:Checkbox;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBD8AAAC8AAAAYGNtYXAYVtCJAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zn4huwUAAAF4AAABYGhlYWQGPe1ZAAAC2AAAADZoaGVhB30DyAAAAxAAAAAkaG10eBBKAEUAAAM0AAAAHGxvY2EAmgESAAADUAAAABBtYXhwAAkALwAAA2AAAAAgbmFtZSC8IugAAAOAAAABknBvc3QAAwAAAAAFFAAAACAAAwMTAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADoAgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6AL//f//AAAAAAAg6AD//f//AAH/4xgEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAEUAUQO7AvgAGgAAARQHAQYjIicBJjU0PwE2MzIfAQE2MzIfARYVA7sQ/hQQFhcQ/uMQEE4QFxcQqAF2EBcXEE4QAnMWEP4UEBABHRAXFhBOEBCoAXcQEE4QFwAAAAABAAABbgMlAkkAFAAAARUUBwYjISInJj0BNDc2MyEyFxYVAyUQEBf9SRcQEBAQFwK3FxAQAhJtFxAQEBAXbRcQEBAQFwAAAAABAAAASQMlA24ALAAAARUUBwYrARUUBwYrASInJj0BIyInJj0BNDc2OwE1NDc2OwEyFxYdATMyFxYVAyUQEBfuEBAXbhYQEO4XEBAQEBfuEBAWbhcQEO4XEBACEm0XEBDuFxAQEBAX7hAQF20XEBDuFxAQEBAX7hAQFwAAAQAAAAIAAHRSzT9fDzz1AAsEAAAAAADRsdR3AAAAANGx1HcAAAAAA7sDbgAAAAgAAgAAAAAAAAABAAADwP/AAAAEAAAAAAADuwABAAAAAAAAAAAAAAAAAAAABwQAAAAAAAAAAAAAAAIAAAAEAABFAyUAAAMlAAAAAAAAAAoAFAAeAE4AcgCwAAEAAAAHAC0AAQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAIAAAAAQAAAAAAAgAHAGkAAQAAAAAAAwAIADkAAQAAAAAABAAIAH4AAQAAAAAABQALABgAAQAAAAAABgAIAFEAAQAAAAAACgAaAJYAAwABBAkAAQAQAAgAAwABBAkAAgAOAHAAAwABBAkAAwAQAEEAAwABBAkABAAQAIYAAwABBAkABQAWACMAAwABBAkABgAQAFkAAwABBAkACgA0ALBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhWZXJzaW9uIDIuMABWAGUAcgBzAGkAbwBuACAAMgAuADBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhDaGVja2JveABDAGgAZQBjAGsAYgBvAHhSZWd1bGFyAFIAZQBnAHUAbABhAHJDaGVja2JveABDAGgAZQBjAGsAYgBvAHhGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype')}.ui.checkbox .box:after,.ui.checkbox label:after{font-family:Checkbox}.ui.checkbox input:checked~.box:after,.ui.checkbox input:checked~label:after{content:'\\\\e800'}.ui.checkbox input:indeterminate~.box:after,.ui.checkbox input:indeterminate~label:after{font-size:12px;content:'\\\\e801'}/*!\\n * # Semantic UI 2.4.0 - Dimmer\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.dimmable:not(body){position:relative}.ui.dimmer{display:none;position:absolute;top:0!important;left:0!important;width:100%;height:100%;text-align:center;vertical-align:middle;padding:1em;background-color:rgba(0,0,0,.85);opacity:0;line-height:1;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-transition:background-color .5s linear;transition:background-color .5s linear;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;color:#fff}.ui.segment>.ui.dimmer{border-radius:inherit!important}.ui.dimmer:not(.inverted)::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.dimmed.dimmable>.ui.animating.legacy.dimmer,.dimmed.dimmable>.ui.visible.legacy.dimmer,.ui.active.legacy.dimmer{display:block}.ui[class*=\\\"top aligned\\\"].dimmer{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.ui[class*=\\\"bottom aligned\\\"].dimmer{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.ui.page.dimmer{position:fixed;-webkit-transform-style:'';transform-style:'';-webkit-perspective:2000px;perspective:2000px;-webkit-transform-origin:center center;transform-origin:center center}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}.blurring.dimmable>:not(.dimmer){-webkit-filter:blur(0) grayscale(0);filter:blur(0) grayscale(0);-webkit-transition:.8s -webkit-filter ease;transition:.8s -webkit-filter ease;transition:.8s filter ease;transition:.8s filter ease,.8s -webkit-filter ease}.blurring.dimmed.dimmable>:not(.dimmer){-webkit-filter:blur(5px) grayscale(.7);filter:blur(5px) grayscale(.7)}.blurring.dimmable>.dimmer{background-color:rgba(0,0,0,.6)}.blurring.dimmable>.inverted.dimmer{background-color:rgba(255,255,255,.6)}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.ui.inverted.dimmer{background-color:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content>*{color:#fff}.ui.simple.dimmer{display:block;overflow:hidden;opacity:1;width:0%;height:0%;z-index:-100;background-color:rgba(0,0,0,0)}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background-color:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,.85)}/*!\\n * # Semantic UI 2.4.0 - Dropdown\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.dropdown{cursor:pointer;position:relative;display:inline-block;outline:0;text-align:left;-webkit-transition:width .1s ease,-webkit-box-shadow .1s ease;transition:width .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,width .1s ease;transition:box-shadow .1s ease,width .1s ease,-webkit-box-shadow .1s ease;-webkit-tap-highlight-color:transparent}.ui.dropdown .menu{cursor:auto;position:absolute;display:none;outline:0;top:100%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;margin:0;padding:0 0;background:#fff;font-size:1em;text-shadow:none;text-align:left;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15);border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;z-index:11;will-change:transform,opacity}.ui.dropdown .menu>*{white-space:nowrap}.ui.dropdown>input:not(.search):first-child,.ui.dropdown>select{display:none!important}.ui.dropdown>.dropdown.icon{position:relative;width:auto;font-size:.85714286em;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon{width:auto;float:right;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon+.text{margin-right:1em}.ui.dropdown>.text{display:inline-block;-webkit-transition:none;transition:none}.ui.dropdown .menu>.item{position:relative;cursor:pointer;display:block;border:none;height:auto;text-align:left;border-top:none;line-height:1em;color:rgba(0,0,0,.87);padding:.78571429rem 1.14285714rem!important;font-size:1rem;text-transform:none;font-weight:400;-webkit-box-shadow:none;box-shadow:none;-webkit-touch-callout:none}.ui.dropdown .menu>.item:first-child{border-top-width:0}.ui.dropdown .menu .item>[class*=\\\"right floated\\\"],.ui.dropdown>.text>[class*=\\\"right floated\\\"]{float:right!important;margin-right:0!important;margin-left:1em!important}.ui.dropdown .menu .item>[class*=\\\"left floated\\\"],.ui.dropdown>.text>[class*=\\\"left floated\\\"]{float:left!important;margin-left:0!important;margin-right:1em!important}.ui.dropdown .menu .item>.flag.floated,.ui.dropdown .menu .item>.icon.floated,.ui.dropdown .menu .item>.image.floated,.ui.dropdown .menu .item>img.floated{margin-top:0}.ui.dropdown .menu>.header{margin:1rem 0 .75rem;padding:0 1.14285714rem;color:rgba(0,0,0,.85);font-size:.78571429em;font-weight:700;text-transform:uppercase}.ui.dropdown .menu>.divider{border-top:1px solid rgba(34,36,38,.1);height:0;margin:.5em 0}.ui.dropdown.dropdown .menu>.input{width:auto;display:-webkit-box;display:-ms-flexbox;display:flex;margin:1.14285714rem .78571429rem;min-width:10rem}.ui.dropdown .menu>.header+.input{margin-top:0}.ui.dropdown .menu>.input:not(.transparent) input{padding:.5em 1em}.ui.dropdown .menu>.input:not(.transparent) .button,.ui.dropdown .menu>.input:not(.transparent) .icon,.ui.dropdown .menu>.input:not(.transparent) .label{padding-top:.5em;padding-bottom:.5em}.ui.dropdown .menu>.item>.description,.ui.dropdown>.text>.description{float:right;margin:0 0 0 1em;color:rgba(0,0,0,.4)}.ui.dropdown .menu>.message{padding:.78571429rem 1.14285714rem;font-weight:400}.ui.dropdown .menu>.message:not(.ui){color:rgba(0,0,0,.4)}.ui.dropdown .menu .menu{top:0!important;left:100%;right:auto;margin:0 0 0 -.5em!important;border-radius:.28571429rem!important;z-index:21!important}.ui.dropdown .menu .menu:after{display:none}.ui.dropdown>.text>.flag,.ui.dropdown>.text>.icon,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.icon,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.icon,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.flag,.ui.dropdown>.text>.icon,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>img{margin-left:0;float:none;margin-right:.78571429rem}.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.image,.ui.dropdown>.text>img{display:inline-block;vertical-align:top;width:auto;margin-top:-.5em;margin-bottom:-.5em;max-height:2em}.ui.dropdown .ui.menu>.item:before,.ui.menu .ui.dropdown .menu>.item:before{display:none}.ui.menu .ui.dropdown .menu .active.item{border-left:none}.ui.buttons>.ui.dropdown:last-child .menu,.ui.menu .right.dropdown.item .menu,.ui.menu .right.menu .dropdown:last-child .menu{left:auto;right:0}.ui.label.dropdown .menu{min-width:100%}.ui.dropdown.icon.button>.dropdown.icon{margin:0}.ui.button.dropdown .menu{min-width:100%}.ui.selection.dropdown{cursor:pointer;word-wrap:break-word;line-height:1em;white-space:normal;outline:0;-webkit-transform:rotateZ(0);transform:rotateZ(0);min-width:14em;min-height:2.71428571em;background:#fff;display:inline-block;padding:.78571429em 2.1em .78571429em 1em;color:rgba(0,0,0,.87);-webkit-box-shadow:none;box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;-webkit-transition:width .1s ease,-webkit-box-shadow .1s ease;transition:width .1s ease,-webkit-box-shadow .1s ease;transition:box-shadow .1s ease,width .1s ease;transition:box-shadow .1s ease,width .1s ease,-webkit-box-shadow .1s ease}.ui.selection.dropdown.active,.ui.selection.dropdown.visible{z-index:10}select.ui.dropdown{height:38px;padding:.5em;border:1px solid rgba(34,36,38,.15);visibility:visible}.ui.selection.dropdown>.delete.icon,.ui.selection.dropdown>.dropdown.icon,.ui.selection.dropdown>.search.icon{cursor:pointer;position:absolute;width:auto;height:auto;line-height:1.21428571em;top:.78571429em;right:1em;z-index:3;margin:-.78571429em;padding:.91666667em;opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.compact.selection.dropdown{min-width:0}.ui.selection.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch;border-top-width:0!important;width:auto;outline:0;margin:0 -1px;min-width:calc(100% + 2px);width:calc(100% + 2px);border-radius:0 0 .28571429rem .28571429rem;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15);-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.selection.dropdown .menu:after,.ui.selection.dropdown .menu:before{display:none}.ui.selection.dropdown .menu>.message{padding:.78571429rem 1.14285714rem}@media only screen and (max-width:767px){.ui.selection.dropdown .menu{max-height:8.01428571rem}}@media only screen and (min-width:768px){.ui.selection.dropdown .menu{max-height:10.68571429rem}}@media only screen and (min-width:992px){.ui.selection.dropdown .menu{max-height:16.02857143rem}}@media only screen and (min-width:1920px){.ui.selection.dropdown .menu{max-height:21.37142857rem}}.ui.selection.dropdown .menu>.item{border-top:1px solid #fafafa;padding:.78571429rem 1.14285714rem!important;white-space:normal;word-wrap:normal}.ui.selection.dropdown .menu>.hidden.addition.item{display:none}.ui.selection.dropdown:hover{border-color:rgba(34,36,38,.35);-webkit-box-shadow:none;box-shadow:none}.ui.selection.active.dropdown{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.dropdown:focus{border-color:#96c8da;-webkit-box-shadow:none;box-shadow:none}.ui.selection.dropdown:focus .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.visible.dropdown>.text:not(.default){font-weight:400;color:rgba(0,0,0,.8)}.ui.selection.active.dropdown:hover{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown:hover .menu{border-color:#96c8da;-webkit-box-shadow:0 2px 3px 0 rgba(34,36,38,.15);box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.active.selection.dropdown>.dropdown.icon,.ui.visible.selection.dropdown>.dropdown.icon{opacity:'';z-index:3}.ui.active.selection.dropdown{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.ui.active.empty.selection.dropdown{border-radius:.28571429rem!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.active.empty.selection.dropdown .menu{border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.search.dropdown{min-width:''}.ui.search.dropdown>input.search{background:none transparent!important;border:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;cursor:text;top:0;left:1px;width:100%;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);padding:inherit}.ui.search.dropdown>input.search{position:absolute;z-index:2}.ui.search.dropdown>.text{cursor:text;position:relative;left:1px;z-index:3}.ui.search.selection.dropdown>input.search{line-height:1.21428571em;padding:.67857143em 2.1em .67857143em 1em}.ui.search.selection.dropdown>span.sizer{line-height:1.21428571em;padding:.67857143em 2.1em .67857143em 1em;display:none;white-space:pre}.ui.search.dropdown.active>input.search,.ui.search.dropdown.visible>input.search{cursor:auto}.ui.search.dropdown.active>.text,.ui.search.dropdown.visible>.text{pointer-events:none}.ui.active.search.dropdown input.search:focus+.text .flag,.ui.active.search.dropdown input.search:focus+.text .icon{opacity:.45}.ui.active.search.dropdown input.search:focus+.text{color:rgba(115,115,115,.87)!important}.ui.search.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch}@media only screen and (max-width:767px){.ui.search.dropdown .menu{max-height:8.01428571rem}}@media only screen and (min-width:768px){.ui.search.dropdown .menu{max-height:10.68571429rem}}@media only screen and (min-width:992px){.ui.search.dropdown .menu{max-height:16.02857143rem}}@media only screen and (min-width:1920px){.ui.search.dropdown .menu{max-height:21.37142857rem}}.ui.multiple.dropdown{padding:.22619048em 2.1em .22619048em .35714286em}.ui.multiple.dropdown .menu{cursor:auto}.ui.multiple.search.dropdown,.ui.multiple.search.dropdown>input.search{cursor:text}.ui.multiple.dropdown>.label{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:inline-block;vertical-align:top;white-space:normal;font-size:1em;padding:.35714286em .78571429em;margin:.14285714rem .28571429rem .14285714rem 0;-webkit-box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.multiple.dropdown .dropdown.icon{margin:'';padding:''}.ui.multiple.dropdown>.text{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.dropdown>.label~input.search{margin-left:.14285714em!important}.ui.multiple.dropdown>.label~.text{display:none}.ui.multiple.search.dropdown>.text{display:inline-block;position:absolute;top:0;left:0;padding:inherit;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.search.dropdown>.label~.text{display:none}.ui.multiple.search.dropdown>input.search{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;width:2.2em;line-height:1.21428571em}.ui.inline.dropdown{cursor:pointer;display:inline-block;color:inherit}.ui.inline.dropdown .dropdown.icon{margin:0 .21428571em 0 .21428571em;vertical-align:baseline}.ui.inline.dropdown>.text{font-weight:700}.ui.inline.dropdown .menu{cursor:auto;margin-top:.21428571em;border-radius:.28571429rem}.ui.dropdown .menu .active.item{background:0 0;font-weight:700;color:rgba(0,0,0,.95);-webkit-box-shadow:none;box-shadow:none;z-index:12}.ui.dropdown .menu>.item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);z-index:13}.ui.loading.dropdown>i.icon{height:1em!important}.ui.loading.selection.dropdown>i.icon{padding:1.5em 1.28571429em!important}.ui.loading.dropdown>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.dropdown>i.icon:after{position:absolute;content:'';top:50%;left:50%;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:dropdown-spin .6s linear;animation:dropdown-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em}.ui.loading.dropdown.button>i.icon:after,.ui.loading.dropdown.button>i.icon:before{display:none}@-webkit-keyframes dropdown-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dropdown-spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.default.dropdown:not(.button)>.text,.ui.dropdown:not(.button)>.default.text{color:rgba(191,191,191,.87)}.ui.default.dropdown:not(.button)>input:focus~.text,.ui.dropdown:not(.button)>input:focus~.default.text{color:rgba(115,115,115,.87)}.ui.loading.dropdown>.text{-webkit-transition:none;transition:none}.ui.dropdown .loading.menu{display:block;visibility:hidden;z-index:-1}.ui.dropdown>.loading.menu{left:0!important;right:auto!important}.ui.dropdown>.menu .loading.menu{left:100%!important;right:auto!important}.ui.dropdown .menu .selected.item,.ui.dropdown.selected{background:rgba(0,0,0,.03);color:rgba(0,0,0,.95)}.ui.dropdown>.filtered.text{visibility:hidden}.ui.dropdown .filtered.item{display:none!important}.ui.dropdown.error,.ui.dropdown.error>.default.text,.ui.dropdown.error>.text{color:#9f3a38}.ui.selection.dropdown.error{background:#fff6f6;border-color:#e0b4b4}.ui.selection.dropdown.error:hover{border-color:#e0b4b4}.ui.dropdown.error>.menu,.ui.dropdown.error>.menu .menu{border-color:#e0b4b4}.ui.dropdown.error>.menu>.item{color:#9f3a38}.ui.multiple.selection.error.dropdown>.label{border-color:#e0b4b4}.ui.dropdown.error>.menu>.item:hover{background-color:#fff2f2}.ui.dropdown.error>.menu .active.item{background-color:#fdcfcf}.ui.dropdown>.clear.dropdown.icon{opacity:.8;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.dropdown>.clear.dropdown.icon:hover{opacity:1}.ui.disabled.dropdown,.ui.dropdown .menu>.disabled.item{cursor:default;pointer-events:none;opacity:.45}.ui.dropdown .menu{left:0}.ui.dropdown .menu .right.menu,.ui.dropdown .right.menu>.menu{left:100%!important;right:auto!important;border-radius:.28571429rem!important}.ui.dropdown>.left.menu{left:auto!important;right:0!important}.ui.dropdown .menu .left.menu,.ui.dropdown>.left.menu .menu{left:auto;right:100%;margin:0 -.5em 0 0!important;border-radius:.28571429rem!important}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon+.text,.ui.dropdown .left.menu .item .dropdown.icon+.text{margin-left:1em;margin-right:0}.ui.upward.dropdown>.menu{top:auto;bottom:100%;-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.08);box-shadow:0 0 3px 0 rgba(0,0,0,.08);border-radius:.28571429rem .28571429rem 0 0}.ui.dropdown .upward.menu{top:auto!important;bottom:0!important}.ui.simple.upward.active.dropdown,.ui.simple.upward.dropdown:hover{border-radius:.28571429rem .28571429rem 0 0!important}.ui.upward.dropdown.button:not(.pointing):not(.floating).active{border-radius:.28571429rem .28571429rem 0 0}.ui.upward.selection.dropdown .menu{border-top-width:1px!important;border-bottom-width:0!important;-webkit-box-shadow:0 -2px 3px 0 rgba(0,0,0,.08);box-shadow:0 -2px 3px 0 rgba(0,0,0,.08)}.ui.upward.selection.dropdown:hover{-webkit-box-shadow:0 0 2px 0 rgba(0,0,0,.05);box-shadow:0 0 2px 0 rgba(0,0,0,.05)}.ui.active.upward.selection.dropdown{border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.selection.dropdown.visible{-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.08);box-shadow:0 0 3px 0 rgba(0,0,0,.08);border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.active.selection.dropdown:hover{-webkit-box-shadow:0 0 3px 0 rgba(0,0,0,.05);box-shadow:0 0 3px 0 rgba(0,0,0,.05)}.ui.upward.active.selection.dropdown:hover .menu{-webkit-box-shadow:0 -2px 3px 0 rgba(0,0,0,.08);box-shadow:0 -2px 3px 0 rgba(0,0,0,.08)}.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{overflow-x:hidden;overflow-y:auto}.ui.scrolling.dropdown .menu{overflow-x:hidden;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:touch;min-width:100%!important;width:auto!important}.ui.dropdown .scrolling.menu{position:static;overflow-y:auto;border:none;-webkit-box-shadow:none!important;box-shadow:none!important;border-radius:0!important;margin:0!important;min-width:100%!important;width:auto!important;border-top:1px solid rgba(34,36,38,.15)}.ui.dropdown .scrolling.menu>.item.item.item,.ui.scrolling.dropdown .menu .item.item.item{border-top:none}.ui.dropdown .scrolling.menu .item:first-child,.ui.scrolling.dropdown .menu .item:first-child{border-top:none}.ui.dropdown>.animating.menu .scrolling.menu,.ui.dropdown>.visible.menu .scrolling.menu{display:block}@media all and (-ms-high-contrast:none){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{min-width:calc(100% - 17px)}}@media only screen and (max-width:767px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:10.28571429rem}}@media only screen and (min-width:768px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:15.42857143rem}}@media only screen and (min-width:992px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}}@media only screen and (min-width:1920px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}}.ui.simple.dropdown .menu:after,.ui.simple.dropdown .menu:before{display:none}.ui.simple.dropdown .menu{position:absolute;display:block;overflow:hidden;top:-9999px!important;opacity:0;width:0;height:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.simple.active.dropdown,.ui.simple.dropdown:hover{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.ui.simple.active.dropdown>.menu,.ui.simple.dropdown:hover>.menu{overflow:visible;width:auto;height:auto;top:100%!important;opacity:1}.ui.simple.dropdown:hover>.menu>.item:hover>.menu,.ui.simple.dropdown>.menu>.item:active>.menu{overflow:visible;width:auto;height:auto;top:0!important;left:100%!important;opacity:1}.ui.simple.disabled.dropdown:hover .menu{display:none;height:0;width:0;overflow:hidden}.ui.simple.visible.dropdown>.menu{display:block}.ui.fluid.dropdown{display:block;width:100%;min-width:0}.ui.fluid.dropdown>.dropdown.icon{float:right}.ui.floating.dropdown .menu{left:0;right:auto;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)!important;box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)!important;border-radius:.28571429rem!important}.ui.floating.dropdown>.menu{margin-top:.5em!important;border-radius:.28571429rem!important}.ui.pointing.dropdown>.menu{top:100%;margin-top:.78571429rem;border-radius:.28571429rem}.ui.pointing.dropdown>.menu:after{display:block;position:absolute;pointer-events:none;content:'';visibility:visible;-webkit-transform:rotate(45deg);transform:rotate(45deg);width:.5em;height:.5em;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);background:#fff;z-index:2}.ui.pointing.dropdown>.menu:after{top:-.25em;left:50%;margin:0 0 0 -.25em}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu:after{top:-.25em;left:1em;right:auto;margin:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ui.top.right.pointing.dropdown>.menu{top:100%;bottom:auto;right:0;left:auto;margin:1em 0 0}.ui.top.pointing.dropdown>.left.menu:after,.ui.top.right.pointing.dropdown>.menu:after{top:-.25em;left:auto!important;right:1em!important;margin:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ui.left.pointing.dropdown>.menu{top:0;left:100%;right:auto;margin:0 0 0 1em}.ui.left.pointing.dropdown>.menu:after{top:1em;left:-.25em;margin:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu{left:auto!important;right:100%!important;margin:0 1em 0 0}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu:after{top:1em;left:auto;right:-.25em;margin:0;-webkit-transform:rotate(135deg);transform:rotate(135deg)}.ui.right.pointing.dropdown>.menu{top:0;left:auto;right:100%;margin:0 1em 0 0}.ui.right.pointing.dropdown>.menu:after{top:1em;left:auto;right:-.25em;margin:0;-webkit-transform:rotate(135deg);transform:rotate(135deg)}.ui.bottom.pointing.dropdown>.menu{top:auto;bottom:100%;left:0;right:auto;margin:0 0 1em}.ui.bottom.pointing.dropdown>.menu:after{top:auto;bottom:-.25em;right:auto;margin:0;-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.ui.bottom.pointing.dropdown>.menu .menu{top:auto!important;bottom:0!important}.ui.bottom.left.pointing.dropdown>.menu{left:0;right:auto}.ui.bottom.left.pointing.dropdown>.menu:after{left:1em;right:auto}.ui.bottom.right.pointing.dropdown>.menu{right:0;left:auto}.ui.bottom.right.pointing.dropdown>.menu:after{left:auto;right:1em}.ui.pointing.upward.dropdown .menu,.ui.top.pointing.upward.dropdown .menu{top:auto!important;bottom:100%!important;margin:0 0 .78571429rem;border-radius:.28571429rem}.ui.pointing.upward.dropdown .menu:after,.ui.top.pointing.upward.dropdown .menu:after{top:100%!important;bottom:auto!important;-webkit-box-shadow:1px 1px 0 0 rgba(34,36,38,.15);box-shadow:1px 1px 0 0 rgba(34,36,38,.15);margin:-.25em 0 0}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 1em 0 0}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after{top:auto!important;bottom:0!important;margin:0 0 1em 0;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 0 0 1em}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after{top:auto!important;bottom:0!important;margin:0 0 1em 0;-webkit-box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}@font-face{font-family:Dropdown;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAVgAA8AAAAACFAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABWAAAABwAAAAchGgaq0dERUYAAAF0AAAAHAAAAB4AJwAPT1MvMgAAAZAAAABDAAAAVnW4TJdjbWFwAAAB1AAAAEsAAAFS8CcaqmN2dCAAAAIgAAAABAAAAAQAEQFEZ2FzcAAAAiQAAAAIAAAACP//AANnbHlmAAACLAAAAQoAAAGkrRHP9WhlYWQAAAM4AAAAMAAAADYPK8YyaGhlYQAAA2gAAAAdAAAAJANCAb1obXR4AAADiAAAACIAAAAiCBkAOGxvY2EAAAOsAAAAFAAAABQBnAIybWF4cAAAA8AAAAAfAAAAIAEVAF5uYW1lAAAD4AAAATAAAAKMFGlj5HBvc3QAAAUQAAAARgAAAHJoedjqd2ViZgAABVgAAAAGAAAABrO7W5UAAAABAAAAANXulPUAAAAA1r4hgAAAAADXu2Q1eNpjYGRgYOABYjEgZmJgBEIOIGYB8xgAA/YAN3jaY2BktGOcwMDKwMI4jTGNgYHBHUp/ZZBkaGFgYGJgZWbACgLSXFMYHFT/fLjFeOD/AQY9xjMMbkBhRpAcAN48DQYAeNpjYGBgZoBgGQZGBhDwAfIYwXwWBgMgzQGETAwMqn8+8H649f8/lHX9//9b7Pzf+fWgusCAkY0BzmUE6gHpQwGMDMMeAACbxg7SAAARAUQAAAAB//8AAnjadZBPSsNAGMXfS+yMqYgOhpSuSlKadmUhiVEhEMQzFF22m17BbbvzCh5BXCUn6EG8gjeQ4DepwYo4i+/ffL95j4EDA+CFC7jQuKyIeVHrI3wkleq9F7XrSInKteOeHdda8bOoaeepSc00NWPz/LRec9G8GabyGtEdF7h19z033GAMTK7zbM42xNEZpzYof0RtQ5CUHAQJ73OtVyutc+3b7Ou//b8XNlsPx3jgjUifABdhEohKJJL5iM5p39uqc7X1+sRQSqmGrUVhlsJ4lpmEUVwyT8SUYtg0P9DyNzPADDs+tjrGV6KRCRfsui3eHcL4/p8ZXvfMlcnEU+CLv7hDykOP+AKTPTxbAAB42mNgZGBgAGKuf5KP4vltvjLIMzGAwLV9ig0g+vruFFMQzdjACOJzMIClARh0CTJ42mNgZGBgPPD/AJD8wgAEjA0MjAyogAMAbOQEAQAAAAC7ABEAAAAAAKoAAAH0AAABgAAAAUAACAFAAAgAwAAXAAAAAAAAACoAKgAqADIAbACGAKAAugDSeNpjYGRgYOBkUGFgYgABEMkFhAwM/xn0QAIADdUBdAB42qWQvUoDQRSFv3GjaISUQaymSmGxJoGAsRC0iPYLsU50Y6IxrvlRtPCJJKUPIBb+PIHv4EN4djKuKAqCDHfmu+feOdwZoMCUAJNbAlYUMzaUlM14jjxbngOq7HnOia89z1Pk1vMCa9x7ztPkzfMyJbPj+ZGi6Xp+omxuPD+zaD7meaFg7mb8GrBqHmhwxoAxlm0uiRkpP9X5m26pKRoMxTGR1D49Dv/Yb/91o6l8qL6eu5n2hZQzn68utR9m3FU2cB4t9cdSLG2utI+44Eh/P9bqKO+oJ/WxmXssj77YkrjasZQD6SFddythk3Wtzrf+UF2p076Udla1VNzsERP3kkjVRKel7mp1udXYcHtZSlV7RfmJe1GiFWveluaeKD5/MuJcSk8Tpm/vvwPIbmJleNpjYGKAAFYG7ICTgYGRiZGZkYWRlZGNkZ2Rg5GTLT2nsiDDEEIZsZfmZRqZujmDaDcDAxcI7WIOpS2gtCWUdgQAZkcSmQAAAAFblbO6AAA=) format('woff');font-weight:400;font-style:normal}.ui.dropdown>.dropdown.icon{font-family:Dropdown;line-height:1;height:1em;width:1.23em;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.dropdown>.dropdown.icon{width:auto}.ui.dropdown>.dropdown.icon:before{content:'\\\\f0d7'}.ui.dropdown .menu .item .dropdown.icon:before{content:'\\\\f0da'}.ui.dropdown .item .left.dropdown.icon:before,.ui.dropdown .left.menu .item .dropdown.icon:before{content:\\\"\\\\f0d9\\\"}.ui.vertical.menu .dropdown.item>.dropdown.icon:before{content:\\\"\\\\f0da\\\"}.ui.dropdown>.clear.icon:before{content:\\\"\\\\f00d\\\"}/*!\\n * # Semantic UI 2.4.0 - Video\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.embed{position:relative;max-width:100%;height:0;overflow:hidden;background:#dcddde;padding-bottom:56.25%}.ui.embed embed,.ui.embed iframe,.ui.embed object{position:absolute;border:none;width:100%;height:100%;top:0;left:0;margin:0;padding:0}.ui.embed>.embed{display:none}.ui.embed>.placeholder{position:absolute;cursor:pointer;top:0;left:0;display:block;width:100%;height:100%;background-color:radial-gradient(transparent 45%,rgba(0,0,0,.3))}.ui.embed>.icon{cursor:pointer;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.ui.embed>.icon:after{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;content:'';background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:.5;-webkit-transition:opacity .5s ease;transition:opacity .5s ease}.ui.embed>.icon:before{position:absolute;top:50%;left:50%;z-index:4;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);color:#fff;font-size:6rem;text-shadow:0 2px 10px rgba(34,36,38,.2);-webkit-transition:opacity .5s ease,color .5s ease;transition:opacity .5s ease,color .5s ease;z-index:10}.ui.embed .icon:hover:after{background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:1}.ui.embed .icon:hover:before{color:#fff}.ui.active.embed>.icon,.ui.active.embed>.placeholder{display:none}.ui.active.embed>.embed{display:block}.ui.square.embed{padding-bottom:100%}.ui[class*=\\\"4:3\\\"].embed{padding-bottom:75%}.ui[class*=\\\"16:9\\\"].embed{padding-bottom:56.25%}.ui[class*=\\\"21:9\\\"].embed{padding-bottom:42.85714286%}/*!\\n * # Semantic UI 2.4.0 - Modal\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.modal{position:absolute;display:none;z-index:1001;text-align:left;background:#fff;border:none;-webkit-box-shadow:1px 3px 3px 0 rgba(0,0,0,.2),1px 3px 15px 2px rgba(0,0,0,.2);box-shadow:1px 3px 3px 0 rgba(0,0,0,.2),1px 3px 15px 2px rgba(0,0,0,.2);-webkit-transform-origin:50% 25%;transform-origin:50% 25%;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;border-radius:.28571429rem;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;will-change:top,left,margin,transform,opacity}.ui.modal>.icon:first-child+*,.ui.modal>:first-child:not(.icon){border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.modal>:last-child{border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.modal>.close{cursor:pointer;position:absolute;top:-2.5rem;right:-2.5rem;z-index:1;opacity:.8;font-size:1.25em;color:#fff;width:2.25rem;height:2.25rem;padding:.625rem 0 0 0}.ui.modal>.close:hover{opacity:1}.ui.modal>.header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;background:#fff;margin:0;padding:1.25rem 1.5rem;-webkit-box-shadow:none;box-shadow:none;color:rgba(0,0,0,.85);border-bottom:1px solid rgba(34,36,38,.15)}.ui.modal>.header:not(.ui){font-size:1.42857143rem;line-height:1.28571429em;font-weight:700}.ui.modal>.content{display:block;width:100%;font-size:1em;line-height:1.4;padding:1.5rem;background:#fff}.ui.modal>.image.content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.ui.modal>.content>.image{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:'';-ms-flex-item-align:top;align-self:top}.ui.modal>[class*=\\\"top aligned\\\"]{-ms-flex-item-align:top;align-self:top}.ui.modal>[class*=\\\"middle aligned\\\"]{-ms-flex-item-align:middle;align-self:middle}.ui.modal>[class*=stretched]{-ms-flex-item-align:stretch;align-self:stretch}.ui.modal>.content>.description{display:block;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;min-width:0;-ms-flex-item-align:top;align-self:top}.ui.modal>.content>.icon+.description,.ui.modal>.content>.image+.description{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;min-width:'';width:auto;padding-left:2em}.ui.modal>.content>.image>i.icon{margin:0;opacity:1;width:auto;line-height:1;font-size:8rem}.ui.modal>.actions{background:#f9fafb;padding:1rem 1rem;border-top:1px solid rgba(34,36,38,.15);text-align:right}.ui.modal .actions>.button{margin-left:.75em}@media only screen and (max-width:767px){.ui.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.modal{width:88%;margin:0}}@media only screen and (min-width:992px){.ui.modal{width:850px;margin:0}}@media only screen and (min-width:1200px){.ui.modal{width:900px;margin:0}}@media only screen and (min-width:1920px){.ui.modal{width:950px;margin:0}}@media only screen and (max-width:991px){.ui.modal>.header{padding-right:2.25rem}.ui.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}}@media only screen and (max-width:767px){.ui.modal>.header{padding:.75rem 1rem!important;padding-right:2.25rem!important}.ui.modal>.content{display:block;padding:1rem!important}.ui.modal>.close{top:.5rem!important;right:.5rem!important}.ui.modal .image.content{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.modal .content>.image{display:block;max-width:100%;margin:0 auto!important;text-align:center;padding:0 0 1rem!important}.ui.modal>.content>.image>i.icon{font-size:5rem;text-align:center}.ui.modal .content>.description{display:block;width:100%!important;margin:0!important;padding:1rem 0!important;-webkit-box-shadow:none;box-shadow:none}.ui.modal>.actions{padding:1rem 1rem 0!important}.ui.modal .actions>.button,.ui.modal .actions>.buttons{margin-bottom:1rem}}.ui.inverted.dimmer>.ui.modal{-webkit-box-shadow:1px 3px 10px 2px rgba(0,0,0,.2);box-shadow:1px 3px 10px 2px rgba(0,0,0,.2)}.ui.basic.modal{background-color:transparent;border:none;border-radius:0;-webkit-box-shadow:none!important;box-shadow:none!important;color:#fff}.ui.basic.modal>.actions,.ui.basic.modal>.content,.ui.basic.modal>.header{background-color:transparent}.ui.basic.modal>.header{color:#fff}.ui.basic.modal>.close{top:1rem;right:1.5rem}.ui.inverted.dimmer>.basic.modal{color:rgba(0,0,0,.87)}.ui.inverted.dimmer>.ui.basic.modal>.header{color:rgba(0,0,0,.85)}.ui.legacy.modal,.ui.legacy.page.dimmer>.ui.modal{top:50%;left:50%}.ui.legacy.page.dimmer>.ui.scrolling.modal,.ui.page.dimmer>.ui.scrolling.legacy.modal,.ui.top.aligned.dimmer>.ui.legacy.modal,.ui.top.aligned.legacy.page.dimmer>.ui.modal{top:auto}@media only screen and (max-width:991px){.ui.basic.modal>.close{color:#fff}}.ui.loading.modal{display:block;visibility:hidden;z-index:-1}.ui.active.modal{display:block}.modals.dimmer[class*=\\\"top aligned\\\"] .modal{margin:5vh auto}@media only screen and (max-width:767px){.modals.dimmer[class*=\\\"top aligned\\\"] .modal{margin:1rem auto}}.legacy.modals.dimmer[class*=\\\"top aligned\\\"]{padding-top:5vh}@media only screen and (max-width:767px){.legacy.modals.dimmer[class*=\\\"top aligned\\\"]{padding-top:1rem}}.scrolling.dimmable.dimmed{overflow:hidden}.scrolling.dimmable>.dimmer{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.scrolling.dimmable.dimmed>.dimmer{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.dimmable>.dimmer{position:fixed}.modals.dimmer .ui.scrolling.modal{margin:1rem auto}.scrolling.undetached.dimmable.dimmed{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.undetached.dimmable.dimmed>.dimmer{overflow:hidden}.scrolling.undetached.dimmable .ui.scrolling.modal{position:absolute;left:50%;margin-top:1rem!important}.ui.modal .scrolling.content{max-height:calc(70vh);overflow:auto}.ui.fullscreen.modal{width:95%!important;left:0!important;margin:1em auto}.ui.fullscreen.scrolling.modal{left:0!important}.ui.fullscreen.modal>.header{padding-right:2.25rem}.ui.fullscreen.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}.ui.modal{font-size:1rem}.ui.mini.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.mini.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.mini.modal{width:35.2%;margin:0}}@media only screen and (min-width:992px){.ui.mini.modal{width:340px;margin:0}}@media only screen and (min-width:1200px){.ui.mini.modal{width:360px;margin:0}}@media only screen and (min-width:1920px){.ui.mini.modal{width:380px;margin:0}}.ui.small.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.tiny.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.tiny.modal{width:52.8%;margin:0}}@media only screen and (min-width:992px){.ui.tiny.modal{width:510px;margin:0}}@media only screen and (min-width:1200px){.ui.tiny.modal{width:540px;margin:0}}@media only screen and (min-width:1920px){.ui.tiny.modal{width:570px;margin:0}}.ui.small.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.small.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.small.modal{width:70.4%;margin:0}}@media only screen and (min-width:992px){.ui.small.modal{width:680px;margin:0}}@media only screen and (min-width:1200px){.ui.small.modal{width:720px;margin:0}}@media only screen and (min-width:1920px){.ui.small.modal{width:760px;margin:0}}.ui.large.modal>.header{font-size:1.6em}@media only screen and (max-width:767px){.ui.large.modal{width:95%;margin:0}}@media only screen and (min-width:768px){.ui.large.modal{width:88%;margin:0}}@media only screen and (min-width:992px){.ui.large.modal{width:1020px;margin:0}}@media only screen and (min-width:1200px){.ui.large.modal{width:1080px;margin:0}}@media only screen and (min-width:1920px){.ui.large.modal{width:1140px;margin:0}}/*!\\n * # Semantic UI 2.4.0 - Nag\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.nag{display:none;opacity:.95;position:relative;top:0;left:0;z-index:999;min-height:0;width:100%;margin:0;padding:.75em 1em;background:#555;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.2);box-shadow:0 1px 2px 0 rgba(0,0,0,.2);font-size:1rem;text-align:center;color:rgba(0,0,0,.87);border-radius:0 0 .28571429rem .28571429rem;-webkit-transition:.2s background ease;transition:.2s background ease}a.ui.nag{cursor:pointer}.ui.nag>.title{display:inline-block;margin:0 .5em;color:#fff}.ui.nag>.close.icon{cursor:pointer;opacity:.4;position:absolute;top:50%;right:1em;font-size:1em;margin:-.5em 0 0;color:#fff;-webkit-transition:opacity .2s ease;transition:opacity .2s ease}.ui.nag:hover{background:#555;opacity:1}.ui.nag .close:hover{opacity:1}.ui.overlay.nag{position:absolute;display:block}.ui.fixed.nag{position:fixed}.ui.bottom.nag,.ui.bottom.nags{border-radius:.28571429rem .28571429rem 0 0;top:auto;bottom:0}.ui.inverted.nag,.ui.inverted.nags .nag{background-color:#f3f4f5;color:rgba(0,0,0,.85)}.ui.inverted.nag .close,.ui.inverted.nag .title,.ui.inverted.nags .nag .close,.ui.inverted.nags .nag .title{color:rgba(0,0,0,.4)}.ui.nags .nag{border-radius:0!important}.ui.nags .nag:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.bottom.nags .nag:last-child{border-radius:.28571429rem .28571429rem 0 0}/*!\\n * # Semantic UI 2.4.0 - Popup\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-webkit-min-content;min-width:-moz-min-content;min-width:min-content;z-index:1900;border:1px solid #d4d4d5;line-height:1.4285em;max-width:250px;background:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.popup>.header{padding:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.14285714em;line-height:1.2;font-weight:700}.ui.popup>.header+.content{padding-top:.5em}.ui.popup:before{position:absolute;content:'';width:.71428571em;height:.71428571em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg);z-index:2;-webkit-box-shadow:1px 1px 0 0 #bababc;box-shadow:1px 1px 0 0 #bababc}[data-tooltip]{position:relative}[data-tooltip]:before{pointer-events:none;position:absolute;content:'';font-size:1rem;width:.71428571em;height:.71428571em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg);z-index:2;-webkit-box-shadow:1px 1px 0 0 #bababc;box-shadow:1px 1px 0 0 #bababc}[data-tooltip]:after{pointer-events:none;content:attr(data-tooltip);position:absolute;text-transform:none;text-align:left;white-space:nowrap;font-size:1rem;border:1px solid #d4d4d5;line-height:1.4285em;max-width:none;background:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.87);border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);z-index:1}[data-tooltip]:not([data-position]):before{top:auto;right:auto;bottom:100%;left:50%;background:#fff;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-tooltip]:not([data-position]):after{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:100%;margin-bottom:.5em}[data-tooltip]:after,[data-tooltip]:before{pointer-events:none;visibility:hidden}[data-tooltip]:before{opacity:0;-webkit-transform:rotate(45deg) scale(0)!important;transform:rotate(45deg) scale(0)!important;-webkit-transform-origin:center top;transform-origin:center top;-webkit-transition:all .1s ease;transition:all .1s ease}[data-tooltip]:after{opacity:1;-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-transition:all .1s ease;transition:all .1s ease}[data-tooltip]:hover:after,[data-tooltip]:hover:before{visibility:visible;pointer-events:auto}[data-tooltip]:hover:before{-webkit-transform:rotate(45deg) scale(1)!important;transform:rotate(45deg) scale(1)!important;opacity:1}[data-tooltip]:after,[data-tooltip][data-position=\\\"bottom center\\\"]:after,[data-tooltip][data-position=\\\"top center\\\"]:after{-webkit-transform:translateX(-50%) scale(0)!important;transform:translateX(-50%) scale(0)!important}[data-tooltip]:hover:after,[data-tooltip][data-position=\\\"bottom center\\\"]:hover:after{-webkit-transform:translateX(-50%) scale(1)!important;transform:translateX(-50%) scale(1)!important}[data-tooltip][data-position=\\\"left center\\\"]:after,[data-tooltip][data-position=\\\"right center\\\"]:after{-webkit-transform:translateY(-50%) scale(0)!important;transform:translateY(-50%) scale(0)!important}[data-tooltip][data-position=\\\"left center\\\"]:hover:after,[data-tooltip][data-position=\\\"right center\\\"]:hover:after{-webkit-transform:translateY(-50%) scale(1)!important;transform:translateY(-50%) scale(1)!important}[data-tooltip][data-position=\\\"bottom left\\\"]:after,[data-tooltip][data-position=\\\"bottom right\\\"]:after,[data-tooltip][data-position=\\\"top left\\\"]:after,[data-tooltip][data-position=\\\"top right\\\"]:after{-webkit-transform:scale(0)!important;transform:scale(0)!important}[data-tooltip][data-position=\\\"bottom left\\\"]:hover:after,[data-tooltip][data-position=\\\"bottom right\\\"]:hover:after,[data-tooltip][data-position=\\\"top left\\\"]:hover:after,[data-tooltip][data-position=\\\"top right\\\"]:hover:after{-webkit-transform:scale(1)!important;transform:scale(1)!important}[data-tooltip][data-inverted]:before{-webkit-box-shadow:none!important;box-shadow:none!important}[data-tooltip][data-inverted]:before{background:#1b1c1d}[data-tooltip][data-inverted]:after{background:#1b1c1d;color:#fff;border:none;-webkit-box-shadow:none;box-shadow:none}[data-tooltip][data-inverted]:after .header{background-color:none;color:#fff}[data-position=\\\"top center\\\"][data-tooltip]:after{top:auto;right:auto;left:50%;bottom:100%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin-bottom:.5em}[data-position=\\\"top center\\\"][data-tooltip]:before{top:auto;right:auto;bottom:100%;left:50%;background:#fff;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"top left\\\"][data-tooltip]:after{top:auto;right:auto;left:0;bottom:100%;margin-bottom:.5em}[data-position=\\\"top left\\\"][data-tooltip]:before{top:auto;right:auto;bottom:100%;left:1em;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"top right\\\"][data-tooltip]:after{top:auto;left:auto;right:0;bottom:100%;margin-bottom:.5em}[data-position=\\\"top right\\\"][data-tooltip]:before{top:auto;left:auto;bottom:100%;right:1em;margin-left:-.07142857rem;margin-bottom:.14285714rem}[data-position=\\\"bottom center\\\"][data-tooltip]:after{bottom:auto;right:auto;left:50%;top:100%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin-top:.5em}[data-position=\\\"bottom center\\\"][data-tooltip]:before{bottom:auto;right:auto;top:100%;left:50%;margin-left:-.07142857rem;margin-top:.14285714rem}[data-position=\\\"bottom left\\\"][data-tooltip]:after{left:0;top:100%;margin-top:.5em}[data-position=\\\"bottom left\\\"][data-tooltip]:before{bottom:auto;right:auto;top:100%;left:1em;margin-left:-.07142857rem;margin-top:.14285714rem}[data-position=\\\"bottom right\\\"][data-tooltip]:after{right:0;top:100%;margin-top:.5em}[data-position=\\\"bottom right\\\"][data-tooltip]:before{bottom:auto;left:auto;top:100%;right:1em;margin-left:-.14285714rem;margin-top:.07142857rem}[data-position=\\\"left center\\\"][data-tooltip]:after{right:100%;top:50%;margin-right:.5em;-webkit-transform:translateY(-50%);transform:translateY(-50%)}[data-position=\\\"left center\\\"][data-tooltip]:before{right:100%;top:50%;margin-top:-.14285714rem;margin-right:-.07142857rem}[data-position=\\\"right center\\\"][data-tooltip]:after{left:100%;top:50%;margin-left:.5em;-webkit-transform:translateY(-50%);transform:translateY(-50%)}[data-position=\\\"right center\\\"][data-tooltip]:before{left:100%;top:50%;margin-top:-.07142857rem;margin-left:.14285714rem}[data-position~=bottom][data-tooltip]:before{background:#fff;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}[data-position=\\\"left center\\\"][data-tooltip]:before{background:#fff;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}[data-position=\\\"right center\\\"][data-tooltip]:before{background:#fff;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}[data-position~=top][data-tooltip]:before{background:#fff}[data-inverted][data-position~=bottom][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}[data-inverted][data-position=\\\"left center\\\"][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}[data-inverted][data-position=\\\"right center\\\"][data-tooltip]:before{background:#1b1c1d;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}[data-inverted][data-position~=top][data-tooltip]:before{background:#1b1c1d}[data-position~=bottom][data-tooltip]:before{-webkit-transform-origin:center bottom;transform-origin:center bottom}[data-position~=bottom][data-tooltip]:after{-webkit-transform-origin:center top;transform-origin:center top}[data-position=\\\"left center\\\"][data-tooltip]:before{-webkit-transform-origin:top center;transform-origin:top center}[data-position=\\\"left center\\\"][data-tooltip]:after{-webkit-transform-origin:right center;transform-origin:right center}[data-position=\\\"right center\\\"][data-tooltip]:before{-webkit-transform-origin:right center;transform-origin:right center}[data-position=\\\"right center\\\"][data-tooltip]:after{-webkit-transform-origin:left center;transform-origin:left center}.ui.popup{margin:0}.ui.top.popup{margin:0 0 .71428571em}.ui.top.left.popup{-webkit-transform-origin:left bottom;transform-origin:left bottom}.ui.top.center.popup{-webkit-transform-origin:center bottom;transform-origin:center bottom}.ui.top.right.popup{-webkit-transform-origin:right bottom;transform-origin:right bottom}.ui.left.center.popup{margin:0 .71428571em 0 0;-webkit-transform-origin:right 50%;transform-origin:right 50%}.ui.right.center.popup{margin:0 0 0 .71428571em;-webkit-transform-origin:left 50%;transform-origin:left 50%}.ui.bottom.popup{margin:.71428571em 0 0}.ui.bottom.left.popup{-webkit-transform-origin:left top;transform-origin:left top}.ui.bottom.center.popup{-webkit-transform-origin:center top;transform-origin:center top}.ui.bottom.right.popup{-webkit-transform-origin:right top;transform-origin:right top}.ui.bottom.center.popup:before{margin-left:-.30714286em;top:-.30714286em;left:50%;right:auto;bottom:auto;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.left.popup{margin-left:0}.ui.bottom.left.popup:before{top:-.30714286em;left:1em;right:auto;bottom:auto;margin-left:0;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.right.popup{margin-right:0}.ui.bottom.right.popup:before{top:-.30714286em;right:1em;bottom:auto;left:auto;margin-left:0;-webkit-box-shadow:-1px -1px 0 0 #bababc;box-shadow:-1px -1px 0 0 #bababc}.ui.top.center.popup:before{top:auto;right:auto;bottom:-.30714286em;left:50%;margin-left:-.30714286em}.ui.top.left.popup{margin-left:0}.ui.top.left.popup:before{bottom:-.30714286em;left:1em;top:auto;right:auto;margin-left:0}.ui.top.right.popup{margin-right:0}.ui.top.right.popup:before{bottom:-.30714286em;right:1em;top:auto;left:auto;margin-left:0}.ui.left.center.popup:before{top:50%;right:-.30714286em;bottom:auto;left:auto;margin-top:-.30714286em;-webkit-box-shadow:1px -1px 0 0 #bababc;box-shadow:1px -1px 0 0 #bababc}.ui.right.center.popup:before{top:50%;left:-.30714286em;bottom:auto;right:auto;margin-top:-.30714286em;-webkit-box-shadow:-1px 1px 0 0 #bababc;box-shadow:-1px 1px 0 0 #bababc}.ui.bottom.popup:before{background:#fff}.ui.left.center.popup:before,.ui.right.center.popup:before{background:#fff}.ui.top.popup:before{background:#fff}.ui.inverted.bottom.popup:before{background:#1b1c1d}.ui.inverted.left.center.popup:before,.ui.inverted.right.center.popup:before{background:#1b1c1d}.ui.inverted.top.popup:before{background:#1b1c1d}.ui.popup>.ui.grid:not(.padded){width:calc(100% + 1.75rem);margin:-.7rem -.875rem}.ui.loading.popup{display:block;visibility:hidden;z-index:-1}.ui.animating.popup,.ui.visible.popup{display:block}.ui.visible.popup{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.basic.popup:before{display:none}.ui.wide.popup{max-width:350px}.ui[class*=\\\"very wide\\\"].popup{max-width:550px}@media only screen and (max-width:767px){.ui.wide.popup,.ui[class*=\\\"very wide\\\"].popup{max-width:250px}}.ui.fluid.popup{width:100%;max-width:none}.ui.inverted.popup{background:#1b1c1d;color:#fff;border:none;-webkit-box-shadow:none;box-shadow:none}.ui.inverted.popup .header{background-color:none;color:#fff}.ui.inverted.popup:before{background-color:#1b1c1d;-webkit-box-shadow:none!important;box-shadow:none!important}.ui.flowing.popup{max-width:none}.ui.mini.popup{font-size:.78571429rem}.ui.tiny.popup{font-size:.85714286rem}.ui.small.popup{font-size:.92857143rem}.ui.popup{font-size:1rem}.ui.large.popup{font-size:1.14285714rem}.ui.huge.popup{font-size:1.42857143rem}/*!\\n * # Semantic UI 2.4.0 - Progress Bar\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.progress{position:relative;display:block;max-width:100%;border:none;margin:1em 0 2.5em;-webkit-box-shadow:none;box-shadow:none;background:rgba(0,0,0,.1);padding:0;border-radius:.28571429rem}.ui.progress:first-child{margin:0 0 2.5em}.ui.progress:last-child{margin:0 0 1.5em}.ui.progress .bar{display:block;line-height:1;position:relative;width:0%;min-width:2em;background:#888;border-radius:.28571429rem;-webkit-transition:width .1s ease,background-color .1s ease;transition:width .1s ease,background-color .1s ease}.ui.progress .bar>.progress{white-space:nowrap;position:absolute;width:auto;font-size:.92857143em;top:50%;right:.5em;left:auto;bottom:auto;color:rgba(255,255,255,.7);text-shadow:none;margin-top:-.5em;font-weight:700;text-align:left}.ui.progress>.label{position:absolute;width:100%;font-size:1em;top:100%;right:auto;left:0;bottom:auto;color:rgba(0,0,0,.87);font-weight:700;text-shadow:none;margin-top:.2em;text-align:center;-webkit-transition:color .4s ease;transition:color .4s ease}.ui.indicating.progress[data-percent^=\\\"1\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"2\\\"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent^=\\\"3\\\"] .bar{background-color:#efbc72}.ui.indicating.progress[data-percent^=\\\"4\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"5\\\"] .bar{background-color:#e6bb48}.ui.indicating.progress[data-percent^=\\\"6\\\"] .bar{background-color:#ddc928}.ui.indicating.progress[data-percent^=\\\"7\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"8\\\"] .bar{background-color:#b4d95c}.ui.indicating.progress[data-percent^=\\\"100\\\"] .bar,.ui.indicating.progress[data-percent^=\\\"9\\\"] .bar{background-color:#66da81}.ui.indicating.progress[data-percent^=\\\"1\\\"] .label,.ui.indicating.progress[data-percent^=\\\"2\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"3\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"4\\\"] .label,.ui.indicating.progress[data-percent^=\\\"5\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"6\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"7\\\"] .label,.ui.indicating.progress[data-percent^=\\\"8\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^=\\\"100\\\"] .label,.ui.indicating.progress[data-percent^=\\\"9\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent=\\\"1\\\"] .bar,.ui.indicating.progress[data-percent=\\\"2\\\"] .bar,.ui.indicating.progress[data-percent=\\\"3\\\"] .bar,.ui.indicating.progress[data-percent=\\\"4\\\"] .bar,.ui.indicating.progress[data-percent=\\\"5\\\"] .bar,.ui.indicating.progress[data-percent=\\\"6\\\"] .bar,.ui.indicating.progress[data-percent=\\\"7\\\"] .bar,.ui.indicating.progress[data-percent=\\\"8\\\"] .bar,.ui.indicating.progress[data-percent=\\\"9\\\"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent=\\\"1\\\"] .label,.ui.indicating.progress[data-percent=\\\"2\\\"] .label,.ui.indicating.progress[data-percent=\\\"3\\\"] .label,.ui.indicating.progress[data-percent=\\\"4\\\"] .label,.ui.indicating.progress[data-percent=\\\"5\\\"] .label,.ui.indicating.progress[data-percent=\\\"6\\\"] .label,.ui.indicating.progress[data-percent=\\\"7\\\"] .label,.ui.indicating.progress[data-percent=\\\"8\\\"] .label,.ui.indicating.progress[data-percent=\\\"9\\\"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress.success .label{color:#1a531b}.ui.progress.success .bar{background-color:#21ba45!important}.ui.progress.success .bar,.ui.progress.success .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.success>.label{color:#1a531b}.ui.progress.warning .bar{background-color:#f2c037!important}.ui.progress.warning .bar,.ui.progress.warning .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.warning>.label{color:#794b02}.ui.progress.error .bar{background-color:#db2828!important}.ui.progress.error .bar,.ui.progress.error .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.error>.label{color:#912d2b}.ui.active.progress .bar{position:relative;min-width:2em}.ui.active.progress .bar::after{content:'';opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff;border-radius:.28571429rem;-webkit-animation:progress-active 2s ease infinite;animation:progress-active 2s ease infinite}@-webkit-keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}@keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}.ui.disabled.progress{opacity:.35}.ui.disabled.progress .bar,.ui.disabled.progress .bar::after{-webkit-animation:none!important;animation:none!important}.ui.inverted.progress{background:rgba(255,255,255,.08);border:none}.ui.inverted.progress .bar{background:#888}.ui.inverted.progress .bar>.progress{color:#f9fafb}.ui.inverted.progress>.label{color:#fff}.ui.inverted.progress.success>.label{color:#21ba45}.ui.inverted.progress.warning>.label{color:#f2c037}.ui.inverted.progress.error>.label{color:#db2828}.ui.progress.attached{background:0 0;position:relative;border:none;margin:0}.ui.progress.attached,.ui.progress.attached .bar{display:block;height:.2rem;padding:0;overflow:hidden;border-radius:0 0 .28571429rem .28571429rem}.ui.progress.attached .bar{border-radius:0}.ui.progress.top.attached,.ui.progress.top.attached .bar{top:0;border-radius:.28571429rem .28571429rem 0 0}.ui.progress.top.attached .bar{border-radius:0}.ui.card>.ui.attached.progress,.ui.segment>.ui.attached.progress{position:absolute;top:auto;left:0;bottom:100%;width:100%}.ui.card>.ui.bottom.attached.progress,.ui.segment>.ui.bottom.attached.progress{top:100%;bottom:auto}.ui.red.progress .bar{background-color:#db2828}.ui.red.inverted.progress .bar{background-color:#ff695e}.ui.orange.progress .bar{background-color:#f2711c}.ui.orange.inverted.progress .bar{background-color:#ff851b}.ui.yellow.progress .bar{background-color:#fbbd08}.ui.yellow.inverted.progress .bar{background-color:#ffe21f}.ui.olive.progress .bar{background-color:#b5cc18}.ui.olive.inverted.progress .bar{background-color:#d9e778}.ui.green.progress .bar{background-color:#21ba45}.ui.green.inverted.progress .bar{background-color:#2ecc40}.ui.teal.progress .bar{background-color:#00b5ad}.ui.teal.inverted.progress .bar{background-color:#6dffff}.ui.blue.progress .bar{background-color:#2185d0}.ui.blue.inverted.progress .bar{background-color:#54c8ff}.ui.violet.progress .bar{background-color:#6435c9}.ui.violet.inverted.progress .bar{background-color:#a291fb}.ui.purple.progress .bar{background-color:#a333c8}.ui.purple.inverted.progress .bar{background-color:#dc73ff}.ui.pink.progress .bar{background-color:#e03997}.ui.pink.inverted.progress .bar{background-color:#ff8edf}.ui.brown.progress .bar{background-color:#a5673f}.ui.brown.inverted.progress .bar{background-color:#d67c1c}.ui.grey.progress .bar{background-color:#767676}.ui.grey.inverted.progress .bar{background-color:#dcddde}.ui.black.progress .bar{background-color:#1b1c1d}.ui.black.inverted.progress .bar{background-color:#545454}.ui.tiny.progress{font-size:.85714286rem}.ui.tiny.progress .bar{height:.5em}.ui.small.progress{font-size:.92857143rem}.ui.small.progress .bar{height:1em}.ui.progress{font-size:1rem}.ui.progress .bar{height:1.75em}.ui.large.progress{font-size:1.14285714rem}.ui.large.progress .bar{height:2.5em}.ui.big.progress{font-size:1.28571429rem}.ui.big.progress .bar{height:3.5em}/*!\\n * # Semantic UI 2.4.0 - Rating\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.rating{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;white-space:nowrap;vertical-align:baseline}.ui.rating:last-child{margin-right:0}.ui.rating .icon{padding:0;margin:0;text-align:center;font-weight:400;font-style:normal;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;cursor:pointer;width:1.25em;height:auto;-webkit-transition:opacity .1s ease,background .1s ease,text-shadow .1s ease,color .1s ease;transition:opacity .1s ease,background .1s ease,text-shadow .1s ease,color .1s ease}.ui.rating .icon{background:0 0;color:rgba(0,0,0,.15)}.ui.rating .active.icon{background:0 0;color:rgba(0,0,0,.85)}.ui.rating .icon.selected,.ui.rating .icon.selected.active{background:0 0;color:rgba(0,0,0,.87)}.ui.star.rating .icon{width:1.25em;height:auto;background:0 0;color:rgba(0,0,0,.15);text-shadow:none}.ui.star.rating .active.icon{background:0 0!important;color:#ffe623!important;text-shadow:0 -1px 0 #ddc507,-1px 0 0 #ddc507,0 1px 0 #ddc507,1px 0 0 #ddc507!important}.ui.star.rating .icon.selected,.ui.star.rating .icon.selected.active{background:0 0!important;color:#fc0!important;text-shadow:0 -1px 0 #e6a200,-1px 0 0 #e6a200,0 1px 0 #e6a200,1px 0 0 #e6a200!important}.ui.heart.rating .icon{width:1.4em;height:auto;background:0 0;color:rgba(0,0,0,.15);text-shadow:none!important}.ui.heart.rating .active.icon{background:0 0!important;color:#ff6d75!important;text-shadow:0 -1px 0 #cd0707,-1px 0 0 #cd0707,0 1px 0 #cd0707,1px 0 0 #cd0707!important}.ui.heart.rating .icon.selected,.ui.heart.rating .icon.selected.active{background:0 0!important;color:#ff3000!important;text-shadow:0 -1px 0 #aa0101,-1px 0 0 #aa0101,0 1px 0 #aa0101,1px 0 0 #aa0101!important}.ui.disabled.rating .icon{cursor:default}.ui.rating.selected .active.icon{opacity:1}.ui.rating .icon.selected,.ui.rating.selected .icon.selected{opacity:1}.ui.mini.rating{font-size:.78571429rem}.ui.tiny.rating{font-size:.85714286rem}.ui.small.rating{font-size:.92857143rem}.ui.rating{font-size:1rem}.ui.large.rating{font-size:1.14285714rem}.ui.huge.rating{font-size:1.42857143rem}.ui.massive.rating{font-size:2rem}@font-face{font-family:Rating;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggjCBsAAAC8AAAAYGNtYXCj2pm8AAABHAAAAKRnYXNwAAAAEAAAAcAAAAAIZ2x5ZlJbXMYAAAHIAAARnGhlYWQBGAe5AAATZAAAADZoaGVhA+IB/QAAE5wAAAAkaG10eCzgAEMAABPAAAAAcGxvY2EwXCxOAAAUMAAAADptYXhwACIAnAAAFGwAAAAgbmFtZfC1n04AABSMAAABPHBvc3QAAwAAAAAVyAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADxZQHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEAJAAAAAgACAABAAAAAEAIOYF8AbwDfAj8C7wbvBw8Irwl/Cc8SPxZf/9//8AAAAAACDmAPAE8AzwI/Au8G7wcPCH8JfwnPEj8WT//f//AAH/4xoEEAYQAQ/sD+IPow+iD4wPgA98DvYOtgADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAP/tAgAB0wAKABUAAAEvAQ8BFwc3Fyc3BQc3Jz8BHwEHFycCALFPT7GAHp6eHoD/AHAWW304OH1bFnABGRqgoBp8sFNTsHyyOnxYEnFxElh8OgAAAAACAAD/7QIAAdMACgASAAABLwEPARcHNxcnNwUxER8BBxcnAgCxT0+xgB6enh6A/wA4fVsWcAEZGqCgGnywU1OwfLIBHXESWHw6AAAAAQAA/+0CAAHTAAoAAAEvAQ8BFwc3Fyc3AgCxT0+xgB6enh6AARkaoKAafLBTU7B8AAAAAAEAAAAAAgABwAArAAABFA4CBzEHDgMjIi4CLwEuAzU0PgIzMh4CFz4DMzIeAhUCAAcMEgugBgwMDAYGDAwMBqALEgwHFyg2HhAfGxkKChkbHxAeNigXAS0QHxsZCqAGCwkGBQkLBqAKGRsfEB42KBcHDBILCxIMBxcoNh4AAAAAAgAAAAACAAHAACsAWAAAATQuAiMiDgIHLgMjIg4CFRQeAhcxFx4DMzI+Aj8BPgM1DwEiFCIGMTAmIjQjJy4DNTQ+AjMyHgIfATc+AzMyHgIVFA4CBwIAFyg2HhAfGxkKChkbHxAeNigXBwwSC6AGDAwMBgYMDAwGoAsSDAdbogEBAQEBAaIGCgcEDRceEQkREA4GLy8GDhARCREeFw0EBwoGAS0eNigXBwwSCwsSDAcXKDYeEB8bGQqgBgsJBgUJCwagChkbHxA+ogEBAQGiBg4QEQkRHhcNBAcKBjQ0BgoHBA0XHhEJERAOBgABAAAAAAIAAcAAMQAAARQOAgcxBw4DIyIuAi8BLgM1ND4CMzIeAhcHFwc3Jzc+AzMyHgIVAgAHDBILoAYMDAwGBgwMDAagCxIMBxcoNh4KFRMSCC9wQLBwJwUJCgkFHjYoFwEtEB8bGQqgBgsJBgUJCwagChkbHxAeNigXAwUIBUtAoMBAOwECAQEXKDYeAAABAAAAAAIAAbcAKgAAEzQ3NjMyFxYXFhcWFzY3Njc2NzYzMhcWFRQPAQYjIi8BJicmJyYnJicmNQAkJUARExIQEAsMCgoMCxAQEhMRQCUkQbIGBwcGsgMFBQsKCQkGBwExPyMkBgYLCgkKCgoKCQoLBgYkIz8/QawFBawCBgUNDg4OFRQTAAAAAQAAAA0B2wHSACYAABM0PwI2FzYfAhYVFA8BFxQVFAcGByYvAQcGByYnJjU0PwEnJjUAEI9BBQkIBkCPEAdoGQMDBgUGgIEGBQYDAwEYaAcBIwsCFoEMAQEMgRYCCwYIZJABBQUFAwEBAkVFAgEBAwUFAwOQZAkFAAAAAAIAAAANAdsB0gAkAC4AABM0PwI2FzYfAhYVFA8BFxQVFAcmLwEHBgcmJyY1ND8BJyY1HwEHNxcnNy8BBwAQj0EFCQgGQI8QB2gZDAUGgIEGBQYDAwEYaAc/WBVsaxRXeDY2ASMLAhaBDAEBDIEWAgsGCGSQAQUNAQECRUUCAQEDBQUDA5BkCQURVXg4OHhVEW5uAAABACMAKQHdAXwAGgAANzQ/ATYXNh8BNzYXNh8BFhUUDwEGByYvASY1IwgmCAwLCFS8CAsMCCYICPUIDAsIjgjSCwkmCQEBCVS7CQEBCSYJCg0H9gcBAQePBwwAAAEAHwAfAXMBcwAsAAA3ND8BJyY1ND8BNjMyHwE3NjMyHwEWFRQPARcWFRQPAQYjIi8BBwYjIi8BJjUfCFRUCAgnCAwLCFRUCAwLCCcICFRUCAgnCAsMCFRUCAsMCCcIYgsIVFQIDAsIJwgIVFQICCcICwwIVFQICwwIJwgIVFQICCcIDAAAAAACAAAAJQFJAbcAHwArAAA3NTQ3NjsBNTQ3NjMyFxYdATMyFxYdARQHBiMhIicmNTczNTQnJiMiBwYdAQAICAsKJSY1NCYmCQsICAgIC/7tCwgIW5MWFR4fFRZApQsICDc0JiYmJjQ3CAgLpQsICAgIC8A3HhYVFRYeNwAAAQAAAAcBbgG3ACEAADcRNDc2NzYzITIXFhcWFREUBwYHBiMiLwEHBiMiJyYnJjUABgUKBgYBLAYGCgUGBgUKBQcOCn5+Cg4GBgoFBicBcAoICAMDAwMICAr+kAoICAQCCXl5CQIECAgKAAAAAwAAACUCAAFuABgAMQBKAAA3NDc2NzYzMhcWFxYVFAcGBwYjIicmJyY1MxYXFjMyNzY3JicWFRQHBiMiJyY1NDcGBzcUFxYzMjc2NTQ3NjMyNzY1NCcmIyIHBhUABihDREtLREMoBgYoQ0RLS0RDKAYlJjk5Q0M5OSYrQREmJTU1JSYRQSuEBAQGBgQEEREZBgQEBAQGJBkayQoKQSgoKChBCgoKCkEoJycoQQoKOiMjIyM6RCEeIjUmJSUmNSIeIUQlBgQEBAQGGBIRBAQGBgQEGhojAAAABQAAAAkCAAGJACwAOABRAGgAcAAANzQ3Njc2MzIXNzYzMhcWFxYXFhcWFxYVFDEGBwYPAQYjIicmNTQ3JicmJyY1MxYXNyYnJjU0NwYHNxQXFjMyNzY1NDc2MzI3NjU0JyYjIgcGFRc3Njc2NyYnNxYXFhcWFRQHBgcGBwYjPwEWFRQHBgcABitBQU0ZGhADBQEEBAUFBAUEBQEEHjw8Hg4DBQQiBQ0pIyIZBiUvSxYZDg4RQSuEBAQGBgQEEREZBgQEBAQGJBkaVxU9MzQiIDASGxkZEAYGCxQrODk/LlACFxYlyQsJQycnBRwEAgEDAwIDAwIBAwUCNmxsNhkFFAMFBBUTHh8nCQtKISgSHBsfIh4hRCUGBAQEBAYYEhEEBAYGBAQaGiPJJQUiIjYzISASGhkbCgoKChIXMRsbUZANCyghIA8AAAMAAAAAAbcB2wA5AEoAlAAANzU0NzY7ATY3Njc2NzY3Njc2MzIXFhcWFRQHMzIXFhUUBxYVFAcUFRQHFgcGKwEiJyYnJisBIicmNTcUFxYzMjc2NTQnJiMiBwYVFzMyFxYXFhcWFxYXFhcWOwEyNTQnNjc2NTQnNjU0JyYnNjc2NTQnJisBNDc2NTQnJiMGBwYHBgcGBwYHBgcGBwYHBgcGBwYrARUACwoQTgodEQ4GBAMFBgwLDxgTEwoKDjMdFhYOAgoRARkZKCUbGxsjIQZSEAoLJQUFCAcGBQUGBwgFBUkJBAUFBAQHBwMDBwcCPCUjNwIJBQUFDwMDBAkGBgsLDmUODgoJGwgDAwYFDAYQAQUGAwQGBgYFBgUGBgQJSbcPCwsGJhUPCBERExMMCgkJFBQhGxwWFR4ZFQoKFhMGBh0WKBcXBgcMDAoLDxIHBQYGBQcIBQYGBQgSAQEBAQICAQEDAgEULwgIBQoLCgsJDhQHCQkEAQ0NCg8LCxAdHREcDQ4IEBETEw0GFAEHBwUECAgFBQUFAgO3AAADAAD/2wG3AbcAPABNAJkAADc1NDc2OwEyNzY3NjsBMhcWBxUWFRQVFhUUBxYVFAcGKwEWFRQHBgcGIyInJicmJyYnJicmJyYnIyInJjU3FBcWMzI3NjU0JyYjIgcGFRczMhcWFxYXFhcWFxYXFhcWFxYXFhcWFzI3NjU0JyY1MzI3NjU0JyYjNjc2NTQnNjU0JyYnNjU0JyYrASIHIgcGBwYHBgcGIwYrARUACwoQUgYhJRsbHiAoGRkBEQoCDhYWHTMOCgoTExgPCwoFBgIBBAMFDhEdCk4QCgslBQUIBwYFBQYHCAUFSQkEBgYFBgUGBgYEAwYFARAGDAUGAwMIGwkKDg5lDgsLBgYJBAMDDwUFBQkCDg4ZJSU8AgcHAwMHBwQEBQUECbe3DwsKDAwHBhcWJwIWHQYGExYKChUZHhYVHRoiExQJCgsJDg4MDAwNBg4WJQcLCw+kBwUGBgUHCAUGBgUIpAMCBQYFBQcIBAUHBwITBwwTExERBw0OHBEdHRALCw8KDQ0FCQkHFA4JCwoLCgUICBgMCxUDAgEBAgMBAQG3AAAAAQAAAA0A7gHSABQAABM0PwI2FxEHBgcmJyY1ND8BJyY1ABCPQQUJgQYFBgMDARhoBwEjCwIWgQwB/oNFAgEBAwUFAwOQZAkFAAAAAAIAAAAAAgABtwAqAFkAABM0NzYzMhcWFxYXFhc2NzY3Njc2MzIXFhUUDwEGIyIvASYnJicmJyYnJjUzFB8BNzY1NCcmJyYnJicmIyIHBgcGBwYHBiMiJyYnJicmJyYjIgcGBwYHBgcGFQAkJUARExIQEAsMCgoMCxAQEhMRQCUkQbIGBwcGsgMFBQsKCQkGByU1pqY1BgYJCg4NDg0PDhIRDg8KCgcFCQkFBwoKDw4REg4PDQ4NDgoJBgYBMT8jJAYGCwoJCgoKCgkKCwYGJCM/P0GsBQWsAgYFDQ4ODhUUEzA1oJ82MBcSEgoLBgcCAgcHCwsKCQgHBwgJCgsLBwcCAgcGCwoSEhcAAAACAAAABwFuAbcAIQAoAAA3ETQ3Njc2MyEyFxYXFhURFAcGBwYjIi8BBwYjIicmJyY1PwEfAREhEQAGBQoGBgEsBgYKBQYGBQoFBw4Kfn4KDgYGCgUGJZIZef7cJwFwCggIAwMDAwgICv6QCggIBAIJeXkJAgQICAoIjRl0AWP+nQAAAAABAAAAJQHbAbcAMgAANzU0NzY7ATU0NzYzMhcWHQEUBwYrASInJj0BNCcmIyIHBh0BMzIXFh0BFAcGIyEiJyY1AAgIC8AmJjQ1JiUFBQgSCAUFFhUfHhUWHAsICAgIC/7tCwgIQKULCAg3NSUmJiU1SQgFBgYFCEkeFhUVFh43CAgLpQsICAgICwAAAAIAAQANAdsB0gAiAC0AABM2PwI2MzIfAhYXFg8BFxYHBiMiLwEHBiMiJyY/AScmNx8CLwE/AS8CEwEDDJBABggJBUGODgIDCmcYAgQCCAMIf4IFBgYEAgEZaQgC7hBbEgINSnkILgEBJggCFYILC4IVAggICWWPCgUFA0REAwUFCo9lCQipCTBmEw1HEhFc/u0AAAADAAAAAAHJAbcAFAAlAHkAADc1NDc2OwEyFxYdARQHBisBIicmNTcUFxYzMjc2NTQnJiMiBwYVFzU0NzYzNjc2NzY3Njc2NzY3Njc2NzY3NjMyFxYXFhcWFxYXFhUUFRQHBgcGBxQHBgcGBzMyFxYVFAcWFRYHFgcGBxYHBgcjIicmJyYnJiciJyY1AAUGB1MHBQYGBQdTBwYFJQUFCAcGBQUGBwgFBWQFBQgGDw8OFAkFBAQBAQMCAQIEBAYFBw4KCgcHBQQCAwEBAgMDAgYCAgIBAU8XEBAQBQEOBQUECwMREiYlExYXDAwWJAoHBQY3twcGBQUGB7cIBQUFBQgkBwYFBQYHCAUGBgUIJLcHBQYBEBATGQkFCQgGBQwLBgcICQUGAwMFBAcHBgYICQQEBwsLCwYGCgIDBAMCBBEQFhkSDAoVEhAREAsgFBUBBAUEBAcMAQUFCAAAAAADAAD/2wHJAZIAFAAlAHkAADcUFxYXNxY3Nj0BNCcmBycGBwYdATc0NzY3FhcWFRQHBicGJyY1FzU0NzY3Fjc2NzY3NjcXNhcWBxYXFgcWBxQHFhUUBwYHJxYXFhcWFRYXFhcWFRQVFAcGBwYHBgcGBwYnBicmJyYnJicmJyYnJicmJyYnJiciJyY1AAUGB1MHBQYGBQdTBwYFJQUFCAcGBQUGBwgFBWQGBQcKJBYMDBcWEyUmEhEDCwQFBQ4BBRAQEBdPAQECAgIGAgMDAgEBAwIEBQcHCgoOBwUGBAQCAQIDAQEEBAUJFA4PDwYIBQWlBwYFAQEBBwQJtQkEBwEBAQUGB7eTBwYEAQEEBgcJBAYBAQYECZS4BwYEAgENBwUCBgMBAQEXEyEJEhAREBcIDhAaFhEPAQEFAgQCBQELBQcKDAkIBAUHCgUGBwgDBgIEAQEHBQkIBwUMCwcECgcGCRoREQ8CBgQIAAAAAQAAAAEAAJth57dfDzz1AAsCAAAAAADP/GODAAAAAM/8Y4MAAP/bAgAB2wAAAAgAAgAAAAAAAAABAAAB4P/gAAACAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAdwAAAHcAAACAAAjAZMAHwFJAAABbgAAAgAAAAIAAAACAAAAAgAAAAEAAAACAAAAAW4AAAHcAAAB3AABAdwAAAHcAAAAAAAAAAoAFAAeAEoAcACKAMoBQAGIAcwCCgJUAoICxgMEAzoDpgRKBRgF7AYSBpgG2gcgB2oIGAjOAAAAAQAAABwAmgAFAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAwAAAABAAAAAAACAA4AQAABAAAAAAADAAwAIgABAAAAAAAEAAwATgABAAAAAAAFABYADAABAAAAAAAGAAYALgABAAAAAAAKADQAWgADAAEECQABAAwAAAADAAEECQACAA4AQAADAAEECQADAAwAIgADAAEECQAEAAwATgADAAEECQAFABYADAADAAEECQAGAAwANAADAAEECQAKADQAWgByAGEAdABpAG4AZwBWAGUAcgBzAGkAbwBuACAAMQAuADAAcgBhAHQAaQBuAGdyYXRpbmcAcgBhAHQAaQBuAGcAUgBlAGcAdQBsAGEAcgByAGEAdABpAG4AZwBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AABcUAAoAAAAAFswAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAEuEAABLho6TvIE9TLzIAABPYAAAAYAAAAGAIIwgbY21hcAAAFDgAAACkAAAApKPambxnYXNwAAAU3AAAAAgAAAAIAAAAEGhlYWQAABTkAAAANgAAADYBGAe5aGhlYQAAFRwAAAAkAAAAJAPiAf1obXR4AAAVQAAAAHAAAABwLOAAQ21heHAAABWwAAAABgAAAAYAHFAAbmFtZQAAFbgAAAE8AAABPPC1n05wb3N0AAAW9AAAACAAAAAgAAMAAAEABAQAAQEBB3JhdGluZwABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeLZviU+HQFHQAAAP0PHQAAAQIRHQAAAAkdAAAS2BIAHQEBBw0PERQZHiMoLTI3PEFGS1BVWl9kaW5zeH2Ch4xyYXRpbmdyYXRpbmd1MHUxdTIwdUU2MDB1RTYwMXVFNjAydUU2MDN1RTYwNHVFNjA1dUYwMDR1RjAwNXVGMDA2dUYwMEN1RjAwRHVGMDIzdUYwMkV1RjA2RXVGMDcwdUYwODd1RjA4OHVGMDg5dUYwOEF1RjA5N3VGMDlDdUYxMjN1RjE2NHVGMTY1AAACAYkAGgAcAgABAAQABwAKAA0AVgCWAL0BAgGMAeQCbwLwA4cD5QR0BQMFdgZgB8MJkQtxC7oM2Q1jDggOmRAYEZr8lA78lA78lA77lA74lPetFftFpTz3NDz7NPtFcfcU+xBt+0T3Mt73Mjht90T3FPcQBfuU+0YV+wRRofcQMOP3EZ3D9wXD+wX3EXkwM6H7EPsExQUO+JT3rRX7RaU89zQ8+zT7RXH3FPsQbftE9zLe9zI4bfdE9xT3EAX7lPtGFYuLi/exw/sF9xF5MDOh+xD7BMUFDviU960V+0WlPPc0PPs0+0Vx9xT7EG37RPcy3vcyOG33RPcU9xAFDviU98EVi2B4ZG5wCIuL+zT7NAV7e3t7e4t7i3ube5sI+zT3NAVupniyi7aL3M3N3Iu2i7J4pm6mqLKetovci81JizoIDviU98EVi9xJzTqLYItkeHBucKhknmCLOotJSYs6i2CeZKhwCIuL9zT7NAWbe5t7m4ubi5ubm5sI9zT3NAWopp6yi7YIME0V+zb7NgWKioqKiouKi4qMiowI+zb3NgV6m4Ghi6OLubCwuYuji6GBm3oIule6vwWbnKGVo4u5i7Bmi12Lc4F1ensIDviU98EVi2B4ZG5wCIuL+zT7NAV7e3t7e4t7i3ube5sI+zT3NAVupniyi7aL3M3N3Iuni6WDoX4IXED3BEtL+zT3RPdU+wTLssYFl46YjZiL3IvNSYs6CA6L98UVi7WXrKOio6Otl7aLlouXiZiHl4eWhZaEloSUhZKFk4SShZKEkpKSkZOSkpGUkZaSCJaSlpGXj5iPl42Wi7aLrX+jc6N0l2qLYYthdWBgYAj7RvtABYeIh4mGi4aLh42Hjgj7RvdABYmNiY2Hj4iOhpGDlISUhZWFlIWVhpaHmYaYiZiLmAgOZ4v3txWLkpCPlo0I9yOgzPcWBY6SkI+Ri5CLkIePhAjL+xb3I3YFlomQh4uEi4aJh4aGCCMmpPsjBYuKi4mLiIuHioiJiImIiIqHi4iLh4yHjQj7FM/7FUcFh4mHioiLh4uIjImOiY6KjouPi4yLjYyOCKP3IyPwBYaQiZCLjwgOZ4v3txWLkpCPlo0I9yOgzPcWBY6SkI+Ri5CLkIePhAjL+xb3I3YFlomQh4uEi4aJh4aGCCMmpPsjBYuKi4mLiIuCh4aDi4iLh4yHjQj7FM/7FUcFh4mHioiLh4uIjImOiY6KjouPi4yLjYyOCKP3IyPwBYaQiZCLjwjKeRXjN3b7DfcAxPZSd/cN4t/7DJ1V9wFV+wEFDq73ZhWLk42RkZEIsbIFkZCRjpOLkouSiJCGCN8291D3UAWQkJKOkouTi5GIkYYIsWQFkYaNhIuEi4OJhYWFCPuJ+4kFhYWFiYOLhIuEjYaRCPsi9yIFhZCJkouSCA77AartFYuSjpKQkAjf3zffBYaQiJKLk4uSjpKQkAiysgWRkJGOk4uSi5KIkIYI3zff3wWQkJKOk4uSi5KIkIYIsmQFkIaOhIuEi4OIhIaGCDc33zcFkIaOhIuEi4OIhYaFCGRkBYaGhIiEi4OLhI6GkAg33zc3BYaGhIiEi4OLhY6FkAhksgWGkYiRi5MIDvtLi8sVi/c5BYuSjpKQkJCQko6SiwiVi4vCBYuul6mkpKSkqpiui66LqX6kcqRymG2LaAiLVJSLBZKLkoiQhpCGjoSLhAiL+zkFi4OIhYaGhoWEiYSLCPuniwWEi4SNhpGGkIiRi5MI5vdUFfcni4vCBYufhJx8mn2ZepJ3i3aLeoR9fX18g3qLdwiLVAUO+yaLshWL+AQFi5GNkY+RjpCQj5KNj42PjI+LCPfAiwWPi4+Kj4mRiZCHj4aPhY2Fi4UIi/wEBYuEiYWHhoeGhoeFiIiKhoqHi4GLhI6EkQj7EvcN+xL7DQWEhYOIgouHi4eLh42EjoaPiJCHkImRi5IIDov3XRWLko2Rj5Kltq+vuKW4pbuZvYu9i7t9uHG4ca9npWCPhI2Fi4SLhYmEh4RxYGdoXnAIXnFbflmLWYtbmF6lXqZnrnG2h5KJkouRCLCLFaRkq2yxdLF0tH+4i7iLtJexorGiq6qksm64Z61goZZ3kXaLdItnfm1ycnJybX9oiwhoi22XcqRypH6pi6+LopGglp9gdWdpbl4I9xiwFYuHjIiOiI6IjoqPi4+LjoyOjo2OjY6Lj4ubkJmXl5eWmZGbi4+LjoyOjo2OjY6LjwiLj4mOiY6IjYiNh4tzi3eCenp6eoJ3i3MIDov3XRWLko2Sj5GouK+utqW3pbqYvouci5yJnIgIm6cFjY6NjI+LjIuNi42JjYqOio+JjomOiY6KjomOiY6JjoqNioyKjomMiYuHi4qLiouLCHdnbVVjQ2NDbVV3Zwh9cgWJiIiJiIuJi36SdJiIjYmOi46LjY+UlJlvl3KcdJ90oHeie6WHkYmSi5IIsIsVqlq0Z711CKGzBXqXfpqCnoKdhp6LoIuikaCWn2B1Z2luXgj3GLAVi4eMiI6IjoiOio+Lj4uOjI6OjY6NjouPi5uQmZeXl5aZkZuLj4uOjI6OjY6NjouPCIuPiY6JjoiNiI2Hi3OLd4J6enp6gneLcwji+10VoLAFtI+wmK2hrqKnqKKvdq1wp2uhCJ2rBZ1/nHycepx6mHqWeY+EjYWLhIuEiYWHhIR/gH1+fG9qaXJmeWV5Y4Jhiwi53BXb9yQFjIKMg4uEi3CDc3x1fHV3fHOBCA6L1BWL90sFi5WPlJKSkpKTj5aLCNmLBZKPmJqepJaZlZeVlY+Qj5ONl42WjpeOmI+YkZWTk5OSk46Vi5uLmYiYhZiFlIGSfgiSfo55i3WLeYd5gXgIvosFn4uchJl8mn2Seot3i3qGfIJ9jYSLhYuEi3yIfoR+i4eLh4uHi3eGen99i3CDdnt8CHt8dYNwiwhmiwV5i3mNeY95kHeRc5N1k36Ph4sIOYsFgIuDjoSShJKHlIuVCLCdFYuGjIePiI+Hj4mQi5CLj42Pj46OjY+LkIuQiZCIjoePh42Gi4aLh4mHh4eIioaLhgjUeRWUiwWNi46Lj4qOi4+KjYqOi4+Kj4mQio6KjYqNio+Kj4mQio6KjIqzfquEpIsIrosFr4uemouri5CKkYqQkY6QkI6SjpKNkouSi5KJkoiRlZWQlouYi5CKkImRiZGJj4iOCJGMkI+PlI+UjZKLkouViJODk4SSgo+CiwgmiwWLlpCalJ6UnpCbi5aLnoiYhJSFlH+QeYuGhoeDiYCJf4h/h3+IfoWBg4KHh4SCgH4Ii4qIiYiGh4aIh4mIiIiIh4eGh4aHh4eHiIiHiIeHiIiHiIeKh4mIioiLCIKLi/tLBQ6L90sVi/dLBYuVj5OSk5KSk46WiwjdiwWPi5iPoZOkk6CRnZCdj56Nn4sIq4sFpougg5x8m3yTd4txCIuJBZd8kHuLd4uHi4eLh5J+jn6LfIuEi4SJhZR9kHyLeot3hHp8fH19eoR3iwhYiwWVeI95i3mLdIh6hH6EfoKBfoV+hX2He4uBi4OPg5KFkYaTh5SHlYiTipOKk4qTiJMIiZSIkYiPgZSBl4CaeKR+moSPCD2LBYCLg4+EkoSSh5SLlQiw9zgVi4aMh4+Ij4ePiZCLkIuPjY+Pjo6Nj4uQi5CJkIiOh4+HjYaLhouHiYeHh4iKhouGCNT7OBWUiwWOi46Kj4mPio+IjoiPh4+IjoePiI+Hj4aPho6HjoiNiI6Hj4aOho6Ii4qWfpKDj4YIk4ORgY5+j36OgI1/jYCPg5CGnYuXj5GUkpSOmYuei5aGmoKfgp6GmouWCPCLBZSLlI+SkpOTjpOLlYuSiZKHlIeUho+Fi46PjY+NkY2RjJCLkIuYhpaBlY6RjZKLkgiLkomSiJKIkoaQhY6MkIyRi5CLm4aXgpOBkn6Pe4sIZosFcotrhGN9iouIioaJh4qHiomKiYqIioaKh4mHioiKiYuHioiLh4qIi4mLCIKLi/tLBQ77lIv3txWLkpCPlo0I9yOgzPcWBY6SkI+RiwiL/BL7FUcFh4mHioiLh4uIjImOiY6KjouPi4yLjYyOCKP3IyPwBYaQiZCLjwgOi/fFFYu1l6yjoqOjrZe2i5aLl4mYh5eHloWWhJaElIWShZOE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) format('woff');font-weight:400;font-style:normal}.ui.rating .icon{font-family:Rating;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.rating .icon:before{content:'\\\\f005'}.ui.rating .active.icon:before{content:'\\\\f005'}.ui.star.rating .icon:before{content:'\\\\f005'}.ui.star.rating .active.icon:before{content:'\\\\f005'}.ui.star.rating .partial.icon:before{content:'\\\\f006'}.ui.star.rating .partial.icon{content:'\\\\f005'}.ui.heart.rating .icon:before{content:'\\\\f004'}.ui.heart.rating .active.icon:before{content:'\\\\f004'}/*!\\n * # Semantic UI 2.4.0 - Search\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.search{position:relative}.ui.search>.prompt{margin:0;outline:0;-webkit-appearance:none;-webkit-tap-highlight-color:rgba(255,255,255,0);text-shadow:none;font-style:normal;font-weight:400;line-height:1.21428571em;padding:.67857143em 1em;font-size:1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);-webkit-box-shadow:0 0 0 0 transparent inset;box-shadow:0 0 0 0 transparent inset;-webkit-transition:background-color .1s ease,color .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,color .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease;transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease;transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease,-webkit-box-shadow .1s ease}.ui.search .prompt{border-radius:500rem}.ui.search .prompt~.search.icon{cursor:pointer}.ui.search>.results{display:none;position:absolute;top:100%;left:0;-webkit-transform-origin:center top;transform-origin:center top;white-space:normal;text-align:left;text-transform:none;background:#fff;margin-top:.5em;width:18em;border-radius:.28571429rem;-webkit-box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);border:1px solid #d4d4d5;z-index:998}.ui.search>.results>:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.search>.results>:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.search>.results .result{cursor:pointer;display:block;overflow:hidden;font-size:1em;padding:.85714286em 1.14285714em;color:rgba(0,0,0,.87);line-height:1.33;border-bottom:1px solid rgba(34,36,38,.1)}.ui.search>.results .result:last-child{border-bottom:none!important}.ui.search>.results .result .image{float:right;overflow:hidden;background:0 0;width:5em;height:3em;border-radius:.25em}.ui.search>.results .result .image img{display:block;width:auto;height:100%}.ui.search>.results .result .image+.content{margin:0 6em 0 0}.ui.search>.results .result .title{margin:-.14285714em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;font-size:1em;color:rgba(0,0,0,.85)}.ui.search>.results .result .description{margin-top:0;font-size:.92857143em;color:rgba(0,0,0,.4)}.ui.search>.results .result .price{float:right;color:#21ba45}.ui.search>.results>.message{padding:1em 1em}.ui.search>.results>.message .header{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1rem;font-weight:700;color:rgba(0,0,0,.87)}.ui.search>.results>.message .description{margin-top:.25rem;font-size:1em;color:rgba(0,0,0,.87)}.ui.search>.results>.action{display:block;border-top:none;background:#f3f4f5;padding:.92857143em 1em;color:rgba(0,0,0,.87);font-weight:700;text-align:center}.ui.search>.prompt:focus{border-color:rgba(34,36,38,.35);background:#fff;color:rgba(0,0,0,.95)}.ui.loading.search .input>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.search .input>i.icon:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}.ui.category.search>.results .category .result:hover,.ui.search>.results .result:hover{background:#f9fafb}.ui.search .action:hover{background:#e0e0e0}.ui.category.search>.results .category.active{background:#f3f4f5}.ui.category.search>.results .category.active>.name{color:rgba(0,0,0,.87)}.ui.category.search>.results .category .result.active,.ui.search>.results .result.active{position:relative;border-left-color:rgba(34,36,38,.1);background:#f3f4f5;-webkit-box-shadow:none;box-shadow:none}.ui.search>.results .result.active .title{color:rgba(0,0,0,.85)}.ui.search>.results .result.active .description{color:rgba(0,0,0,.85)}.ui.disabled.search{cursor:default;pointer-events:none;opacity:.45}.ui.search.selection .prompt{border-radius:.28571429rem}.ui.search.selection>.icon.input>.remove.icon{pointer-events:none;position:absolute;left:auto;opacity:0;color:'';top:0;right:0;-webkit-transition:color .1s ease,opacity .1s ease;transition:color .1s ease,opacity .1s ease}.ui.search.selection>.icon.input>.active.remove.icon{cursor:pointer;opacity:.8;pointer-events:auto}.ui.search.selection>.icon.input:not([class*=\\\"left icon\\\"])>.icon~.remove.icon{right:1.85714em}.ui.search.selection>.icon.input>.remove.icon:hover{opacity:1;color:#db2828}.ui.category.search .results{width:28em}.ui.category.search .results.animating,.ui.category.search .results.visible{display:table}.ui.category.search>.results .category{display:table-row;background:#f3f4f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease}.ui.category.search>.results .category:last-child{border-bottom:none}.ui.category.search>.results .category:first-child .name+.result{border-radius:0 .28571429rem 0 0}.ui.category.search>.results .category:last-child .result:last-child{border-radius:0 0 .28571429rem 0}.ui.category.search>.results .category>.name{display:table-cell;text-overflow:ellipsis;width:100px;white-space:nowrap;background:0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;padding:.4em 1em;font-weight:700;color:rgba(0,0,0,.4);border-bottom:1px solid rgba(34,36,38,.1)}.ui.category.search>.results .category .results{display:table-cell;background:#fff;border-left:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(34,36,38,.1)}.ui.category.search>.results .category .result{border-bottom:1px solid rgba(34,36,38,.1);-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease;padding:.85714286em 1.14285714em}.ui[class*=\\\"left aligned\\\"].search>.results{right:auto;left:0}.ui[class*=\\\"right aligned\\\"].search>.results{right:0;left:auto}.ui.fluid.search .results{width:100%}.ui.mini.search{font-size:.78571429em}.ui.small.search{font-size:.92857143em}.ui.search{font-size:1em}.ui.large.search{font-size:1.14285714em}.ui.big.search{font-size:1.28571429em}.ui.huge.search{font-size:1.42857143em}.ui.massive.search{font-size:1.71428571em}@media only screen and (max-width:767px){.ui.search .results{max-width:calc(100vw - 2rem)}}/*!\\n * # Semantic UI 2.4.0 - Shape\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.shape{position:relative;vertical-align:top;display:inline-block;-webkit-perspective:2000px;perspective:2000px;-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape .sides{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.ui.shape .side{opacity:1;width:100%;margin:0!important;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.shape .side{display:none}.ui.shape .side *{-webkit-backface-visibility:visible!important;backface-visibility:visible!important}.ui.cube.shape .side{min-width:15em;height:15em;padding:2em;background-color:#e6e6e6;color:rgba(0,0,0,.87);-webkit-box-shadow:0 0 2px rgba(0,0,0,.3);box-shadow:0 0 2px rgba(0,0,0,.3)}.ui.cube.shape .side>.content{width:100%;height:100%;display:table;text-align:center;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.cube.shape .side>.content>div{display:table-cell;vertical-align:middle;font-size:2em}.ui.text.shape.animating .sides{position:static}.ui.text.shape .side{white-space:nowrap}.ui.text.shape .side>*{white-space:normal}.ui.loading.shape{position:absolute;top:-9999px;left:-9999px}.ui.shape .animating.side{position:absolute;top:0;left:0;display:block;z-index:100}.ui.shape .hidden.side{opacity:.6}.ui.shape.animating .sides{position:absolute}.ui.shape.animating .sides{-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape.animating .side{-webkit-transition:opacity .6s ease-in-out;transition:opacity .6s ease-in-out}.ui.shape .active.side{display:block}/*!\\n * # Semantic UI 2.4.0 - Sidebar\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.sidebar{position:fixed;top:0;left:0;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:none;transition:none;will-change:transform;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);visibility:hidden;-webkit-overflow-scrolling:touch;height:100%!important;max-height:100%;border-radius:0!important;margin:0!important;overflow-y:auto!important;z-index:102}.ui.sidebar>*{-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.left.sidebar{right:auto;left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.sidebar{right:0!important;left:auto!important;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.bottom.sidebar,.ui.top.sidebar{width:100%!important;height:auto!important}.ui.top.sidebar{top:0!important;bottom:auto!important;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.sidebar{top:auto!important;bottom:0!important;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.pushable{height:100%;overflow-x:hidden;padding:0!important}body.pushable{background:#545454!important}.pushable:not(body){-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pushable:not(body)>.fixed,.pushable:not(body)>.pusher:after,.pushable:not(body)>.ui.sidebar{position:absolute}.pushable>.fixed{position:fixed;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;will-change:transform;z-index:101}.pushable>.pusher{position:relative;-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;min-height:100%;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:2}body.pushable>.pusher{background:#fff}.pushable>.pusher{background:inherit}.pushable>.pusher:after{position:fixed;top:0;right:0;content:'';background-color:rgba(0,0,0,.4);overflow:hidden;opacity:0;-webkit-transition:opacity .5s;transition:opacity .5s;will-change:opacity;z-index:1000}.ui.sidebar.menu .item{border-radius:0!important}.pushable>.pusher.dimmed:after{width:100%!important;height:100%!important;opacity:1!important}.ui.animating.sidebar{visibility:visible}.ui.visible.sidebar{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.left.visible.sidebar,.ui.right.visible.sidebar{-webkit-box-shadow:0 0 20px rgba(34,36,38,.15);box-shadow:0 0 20px rgba(34,36,38,.15)}.ui.bottom.visible.sidebar,.ui.top.visible.sidebar{-webkit-box-shadow:0 0 20px rgba(34,36,38,.15);box-shadow:0 0 20px rgba(34,36,38,.15)}.ui.visible.left.sidebar~.fixed,.ui.visible.left.sidebar~.pusher{-webkit-transform:translate3d(260px,0,0);transform:translate3d(260px,0,0)}.ui.visible.right.sidebar~.fixed,.ui.visible.right.sidebar~.pusher{-webkit-transform:translate3d(-260px,0,0);transform:translate3d(-260px,0,0)}.ui.visible.top.sidebar~.fixed,.ui.visible.top.sidebar~.pusher{-webkit-transform:translate3d(0,36px,0);transform:translate3d(0,36px,0)}.ui.visible.bottom.sidebar~.fixed,.ui.visible.bottom.sidebar~.pusher{-webkit-transform:translate3d(0,-36px,0);transform:translate3d(0,-36px,0)}.ui.visible.left.sidebar~.ui.visible.right.sidebar~.fixed,.ui.visible.left.sidebar~.ui.visible.right.sidebar~.pusher,.ui.visible.right.sidebar~.ui.visible.left.sidebar~.fixed,.ui.visible.right.sidebar~.ui.visible.left.sidebar~.pusher{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.thin.left.sidebar,.ui.thin.right.sidebar{width:150px}.ui[class*=\\\"very thin\\\"].left.sidebar,.ui[class*=\\\"very thin\\\"].right.sidebar{width:60px}.ui.left.sidebar,.ui.right.sidebar{width:260px}.ui.wide.left.sidebar,.ui.wide.right.sidebar{width:350px}.ui[class*=\\\"very wide\\\"].left.sidebar,.ui[class*=\\\"very wide\\\"].right.sidebar{width:475px}.ui.visible.thin.left.sidebar~.fixed,.ui.visible.thin.left.sidebar~.pusher{-webkit-transform:translate3d(150px,0,0);transform:translate3d(150px,0,0)}.ui.visible[class*=\\\"very thin\\\"].left.sidebar~.fixed,.ui.visible[class*=\\\"very thin\\\"].left.sidebar~.pusher{-webkit-transform:translate3d(60px,0,0);transform:translate3d(60px,0,0)}.ui.visible.wide.left.sidebar~.fixed,.ui.visible.wide.left.sidebar~.pusher{-webkit-transform:translate3d(350px,0,0);transform:translate3d(350px,0,0)}.ui.visible[class*=\\\"very wide\\\"].left.sidebar~.fixed,.ui.visible[class*=\\\"very wide\\\"].left.sidebar~.pusher{-webkit-transform:translate3d(475px,0,0);transform:translate3d(475px,0,0)}.ui.visible.thin.right.sidebar~.fixed,.ui.visible.thin.right.sidebar~.pusher{-webkit-transform:translate3d(-150px,0,0);transform:translate3d(-150px,0,0)}.ui.visible[class*=\\\"very thin\\\"].right.sidebar~.fixed,.ui.visible[class*=\\\"very thin\\\"].right.sidebar~.pusher{-webkit-transform:translate3d(-60px,0,0);transform:translate3d(-60px,0,0)}.ui.visible.wide.right.sidebar~.fixed,.ui.visible.wide.right.sidebar~.pusher{-webkit-transform:translate3d(-350px,0,0);transform:translate3d(-350px,0,0)}.ui.visible[class*=\\\"very wide\\\"].right.sidebar~.fixed,.ui.visible[class*=\\\"very wide\\\"].right.sidebar~.pusher{-webkit-transform:translate3d(-475px,0,0);transform:translate3d(-475px,0,0)}.ui.overlay.sidebar{z-index:102}.ui.left.overlay.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.overlay.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.overlay.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.overlay.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.animating.ui.overlay.sidebar,.ui.visible.overlay.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.left.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.right.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.top.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.bottom.overlay.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.overlay.sidebar~.fixed,.ui.visible.overlay.sidebar~.pusher{-webkit-transform:none!important;transform:none!important}.ui.push.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:102}.ui.left.push.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.push.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.push.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.push.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.ui.visible.push.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.uncover.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:1}.ui.visible.uncover.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.slide.along.sidebar{z-index:1}.ui.left.slide.along.sidebar{-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui.right.slide.along.sidebar{-webkit-transform:translate3d(50%,0,0);transform:translate3d(50%,0,0)}.ui.top.slide.along.sidebar{-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.ui.bottom.slide.along.sidebar{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.ui.animating.slide.along.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.slide.along.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.slide.out.sidebar{z-index:1}.ui.left.slide.out.sidebar{-webkit-transform:translate3d(50%,0,0);transform:translate3d(50%,0,0)}.ui.right.slide.out.sidebar{-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui.top.slide.out.sidebar{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.ui.bottom.slide.out.sidebar{-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.ui.animating.slide.out.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.visible.slide.out.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.scale.down.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:102}.ui.left.scale.down.sidebar{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.ui.right.scale.down.sidebar{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.ui.top.scale.down.sidebar{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.ui.bottom.scale.down.sidebar{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.ui.scale.down.left.sidebar~.pusher{-webkit-transform-origin:75% 50%;transform-origin:75% 50%}.ui.scale.down.right.sidebar~.pusher{-webkit-transform-origin:25% 50%;transform-origin:25% 50%}.ui.scale.down.top.sidebar~.pusher{-webkit-transform-origin:50% 75%;transform-origin:50% 75%}.ui.scale.down.bottom.sidebar~.pusher{-webkit-transform-origin:50% 25%;transform-origin:50% 25%}.ui.animating.scale.down>.visible.ui.sidebar{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.ui.animating.scale.down.sidebar~.pusher,.ui.visible.scale.down.sidebar~.pusher{display:block!important;width:100%;height:100%;overflow:hidden!important}.ui.visible.scale.down.sidebar{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui.visible.scale.down.sidebar~.pusher{-webkit-transform:scale(.75);transform:scale(.75)}/*!\\n * # Semantic UI 2.4.0 - Sticky\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.sticky{position:static;-webkit-transition:none;transition:none;z-index:800}.ui.sticky.bound{position:absolute;left:auto;right:auto}.ui.sticky.fixed{position:fixed;left:auto;right:auto}.ui.sticky.bound.top,.ui.sticky.fixed.top{top:0;bottom:auto}.ui.sticky.bound.bottom,.ui.sticky.fixed.bottom{top:auto;bottom:0}.ui.native.sticky{position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;position:sticky}/*!\\n * # Semantic UI 2.4.0 - Tab\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.tab{display:none}.ui.tab.active,.ui.tab.open{display:block}.ui.tab.loading{position:relative;overflow:hidden;display:block;min-height:250px}.ui.tab.loading *{position:relative!important;left:-10000px!important}.ui.tab.loading.segment:before,.ui.tab.loading:before{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.tab.loading.segment:after,.ui.tab.loading:after{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}/*!\\n * # Semantic UI 2.4.0 - Transition\\n * http://github.com/semantic-org/semantic-ui/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.transition{-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animating.transition{-webkit-backface-visibility:hidden;backface-visibility:hidden;visibility:visible!important}.loading.transition{position:absolute;top:-99999px;left:-99999px}.hidden.transition{display:none;visibility:hidden}.visible.transition{display:block!important;visibility:visible!important}.disabled.transition{-webkit-animation-play-state:paused;animation-play-state:paused}.looping.transition{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.transition.browse{-webkit-animation-duration:.5s;animation-duration:.5s}.transition.browse.in{-webkit-animation-name:browseIn;animation-name:browseIn}.transition.browse.left.out,.transition.browse.out{-webkit-animation-name:browseOutLeft;animation-name:browseOutLeft}.transition.browse.right.out{-webkit-animation-name:browseOutRight;animation-name:browseOutRight}@-webkit-keyframes browseIn{0%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1}10%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1;opacity:.7}80%{-webkit-transform:scale(1.05) translateZ(0);transform:scale(1.05) translateZ(0);opacity:1;z-index:999}100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);z-index:999}}@keyframes browseIn{0%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1}10%{-webkit-transform:scale(.8) translateZ(0);transform:scale(.8) translateZ(0);z-index:-1;opacity:.7}80%{-webkit-transform:scale(1.05) translateZ(0);transform:scale(1.05) translateZ(0);opacity:1;z-index:999}100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);z-index:999}}@-webkit-keyframes browseOutLeft{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:-1;-webkit-transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:-1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@keyframes browseOutLeft{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:-1;-webkit-transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(-105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:-1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@-webkit-keyframes browseOutRight{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:1;-webkit-transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}@keyframes browseOutRight{0%{z-index:999;-webkit-transform:translateX(0) rotateY(0) rotateX(0);transform:translateX(0) rotateY(0) rotateX(0)}50%{z-index:1;-webkit-transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px);transform:translateX(105%) rotateY(35deg) rotateX(10deg) translateZ(-10px)}80%{opacity:1}100%{z-index:1;-webkit-transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);transform:translateX(0) rotateY(0) rotateX(0) translateZ(-10px);opacity:0}}.drop.transition{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:cubic-bezier(.34,1.61,.7,1);animation-timing-function:cubic-bezier(.34,1.61,.7,1)}.drop.transition.in{-webkit-animation-name:dropIn;animation-name:dropIn}.drop.transition.out{-webkit-animation-name:dropOut;animation-name:dropOut}@-webkit-keyframes dropIn{0%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes dropIn{0%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes dropOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}@keyframes dropOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}.transition.fade.in{-webkit-animation-name:fadeIn;animation-name:fadeIn}.transition[class*=\\\"fade up\\\"].in{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}.transition[class*=\\\"fade down\\\"].in{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}.transition[class*=\\\"fade left\\\"].in{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}.transition[class*=\\\"fade right\\\"].in{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}.transition.fade.out{-webkit-animation-name:fadeOut;animation-name:fadeOut}.transition[class*=\\\"fade up\\\"].out{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}.transition[class*=\\\"fade down\\\"].out{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}.transition[class*=\\\"fade left\\\"].out{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}.transition[class*=\\\"fade right\\\"].out{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(5%);transform:translateY(5%)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(5%);transform:translateY(5%)}}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-5%);transform:translateY(-5%)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-5%);transform:translateY(-5%)}}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(5%);transform:translateX(5%)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(5%);transform:translateX(5%)}}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-5%);transform:translateX(-5%)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-5%);transform:translateX(-5%)}}.flip.transition.in,.flip.transition.out{-webkit-animation-duration:.6s;animation-duration:.6s}.horizontal.flip.transition.in{-webkit-animation-name:horizontalFlipIn;animation-name:horizontalFlipIn}.horizontal.flip.transition.out{-webkit-animation-name:horizontalFlipOut;animation-name:horizontalFlipOut}.vertical.flip.transition.in{-webkit-animation-name:verticalFlipIn;animation-name:verticalFlipIn}.vertical.flip.transition.out{-webkit-animation-name:verticalFlipOut;animation-name:verticalFlipOut}@-webkit-keyframes horizontalFlipIn{0%{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}}@keyframes horizontalFlipIn{0%{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}}@-webkit-keyframes verticalFlipIn{0%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}}@keyframes verticalFlipIn{0%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}100%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}}@-webkit-keyframes horizontalFlipOut{0%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);opacity:0}}@keyframes horizontalFlipOut{0%{-webkit-transform:perspective(2000px) rotateY(0);transform:perspective(2000px) rotateY(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);opacity:0}}@-webkit-keyframes verticalFlipOut{0%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}}@keyframes verticalFlipOut{0%{-webkit-transform:perspective(2000px) rotateX(0);transform:perspective(2000px) rotateX(0);opacity:1}100%{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}}.scale.transition.in{-webkit-animation-name:scaleIn;animation-name:scaleIn}.scale.transition.out{-webkit-animation-name:scaleOut;animation-name:scaleOut}@-webkit-keyframes scaleIn{0%{opacity:0;-webkit-transform:scale(.8);transform:scale(.8)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes scaleIn{0%{opacity:0;-webkit-transform:scale(.8);transform:scale(.8)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes scaleOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(.9);transform:scale(.9)}}@keyframes scaleOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:0;-webkit-transform:scale(.9);transform:scale(.9)}}.transition.fly{-webkit-animation-duration:.6s;animation-duration:.6s;-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}.transition.fly.in{-webkit-animation-name:flyIn;animation-name:flyIn}.transition[class*=\\\"fly up\\\"].in{-webkit-animation-name:flyInUp;animation-name:flyInUp}.transition[class*=\\\"fly down\\\"].in{-webkit-animation-name:flyInDown;animation-name:flyInDown}.transition[class*=\\\"fly left\\\"].in{-webkit-animation-name:flyInLeft;animation-name:flyInLeft}.transition[class*=\\\"fly right\\\"].in{-webkit-animation-name:flyInRight;animation-name:flyInRight}.transition.fly.out{-webkit-animation-name:flyOut;animation-name:flyOut}.transition[class*=\\\"fly up\\\"].out{-webkit-animation-name:flyOutUp;animation-name:flyOutUp}.transition[class*=\\\"fly down\\\"].out{-webkit-animation-name:flyOutDown;animation-name:flyOutDown}.transition[class*=\\\"fly left\\\"].out{-webkit-animation-name:flyOutLeft;animation-name:flyOutLeft}.transition[class*=\\\"fly right\\\"].out{-webkit-animation-name:flyOutRight;animation-name:flyOutRight}@-webkit-keyframes flyIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes flyIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@-webkit-keyframes flyInUp{0%{opacity:0;-webkit-transform:translate3d(0,1500px,0);transform:translate3d(0,1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes flyInUp{0%{opacity:0;-webkit-transform:translate3d(0,1500px,0);transform:translate3d(0,1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes flyInDown{0%{opacity:0;-webkit-transform:translate3d(0,-1500px,0);transform:translate3d(0,-1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInDown{0%{opacity:0;-webkit-transform:translate3d(0,-1500px,0);transform:translate3d(0,-1500px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyInLeft{0%{opacity:0;-webkit-transform:translate3d(1500px,0,0);transform:translate3d(1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInLeft{0%{opacity:0;-webkit-transform:translate3d(1500px,0,0);transform:translate3d(1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyInRight{0%{opacity:0;-webkit-transform:translate3d(-1500px,0,0);transform:translate3d(-1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes flyInRight{0%{opacity:0;-webkit-transform:translate3d(-1500px,0,0);transform:translate3d(-1500px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@-webkit-keyframes flyOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes flyOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@-webkit-keyframes flyOutUp{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes flyOutUp{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@-webkit-keyframes flyOutDown{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes flyOutDown{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@-webkit-keyframes flyOutRight{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes flyOutRight{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@-webkit-keyframes flyOutLeft{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes flyOutLeft{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.transition.slide.in,.transition[class*=\\\"slide down\\\"].in{-webkit-animation-name:slideInY;animation-name:slideInY;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"slide up\\\"].in{-webkit-animation-name:slideInY;animation-name:slideInY;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"slide left\\\"].in{-webkit-animation-name:slideInX;animation-name:slideInX;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"slide right\\\"].in{-webkit-animation-name:slideInX;animation-name:slideInX;-webkit-transform-origin:center left;transform-origin:center left}.transition.slide.out,.transition[class*=\\\"slide down\\\"].out{-webkit-animation-name:slideOutY;animation-name:slideOutY;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"slide up\\\"].out{-webkit-animation-name:slideOutY;animation-name:slideOutY;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"slide left\\\"].out{-webkit-animation-name:slideOutX;animation-name:slideOutX;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"slide right\\\"].out{-webkit-animation-name:slideOutX;animation-name:slideOutX;-webkit-transform-origin:center left;transform-origin:center left}@-webkit-keyframes slideInY{0%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}100%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@keyframes slideInY{0%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}100%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@-webkit-keyframes slideInX{0%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}100%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes slideInX{0%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}100%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@-webkit-keyframes slideOutY{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}100%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@keyframes slideOutY{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}100%{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@-webkit-keyframes slideOutX{0%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}100%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}}@keyframes slideOutX{0%{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}100%{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}}.transition.swing{-webkit-animation-duration:.8s;animation-duration:.8s}.transition[class*=\\\"swing down\\\"].in{-webkit-animation-name:swingInX;animation-name:swingInX;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"swing up\\\"].in{-webkit-animation-name:swingInX;animation-name:swingInX;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"swing left\\\"].in{-webkit-animation-name:swingInY;animation-name:swingInY;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"swing right\\\"].in{-webkit-animation-name:swingInY;animation-name:swingInY;-webkit-transform-origin:center left;transform-origin:center left}.transition.swing.out,.transition[class*=\\\"swing down\\\"].out{-webkit-animation-name:swingOutX;animation-name:swingOutX;-webkit-transform-origin:top center;transform-origin:top center}.transition[class*=\\\"swing up\\\"].out{-webkit-animation-name:swingOutX;animation-name:swingOutX;-webkit-transform-origin:bottom center;transform-origin:bottom center}.transition[class*=\\\"swing left\\\"].out{-webkit-animation-name:swingOutY;animation-name:swingOutY;-webkit-transform-origin:center right;transform-origin:center right}.transition[class*=\\\"swing right\\\"].out{-webkit-animation-name:swingOutY;animation-name:swingOutY;-webkit-transform-origin:center left;transform-origin:center left}@-webkit-keyframes swingInX{0%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateX(15deg);transform:perspective(1000px) rotateX(15deg)}80%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}100%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}}@keyframes swingInX{0%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateX(15deg);transform:perspective(1000px) rotateX(15deg)}80%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}100%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}}@-webkit-keyframes swingInY{0%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateY(-17.5deg);transform:perspective(1000px) rotateY(-17.5deg)}80%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}100%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}}@keyframes swingInY{0%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}40%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}60%{-webkit-transform:perspective(1000px) rotateY(-17.5deg);transform:perspective(1000px) rotateY(-17.5deg)}80%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}100%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}}@-webkit-keyframes swingOutX{0%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}40%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}60%{-webkit-transform:perspective(1000px) rotateX(17.5deg);transform:perspective(1000px) rotateX(17.5deg)}80%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}}@keyframes swingOutX{0%{-webkit-transform:perspective(1000px) rotateX(0);transform:perspective(1000px) rotateX(0)}40%{-webkit-transform:perspective(1000px) rotateX(-7.5deg);transform:perspective(1000px) rotateX(-7.5deg)}60%{-webkit-transform:perspective(1000px) rotateX(17.5deg);transform:perspective(1000px) rotateX(17.5deg)}80%{-webkit-transform:perspective(1000px) rotateX(-30deg);transform:perspective(1000px) rotateX(-30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateX(90deg);transform:perspective(1000px) rotateX(90deg);opacity:0}}@-webkit-keyframes swingOutY{0%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}40%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}60%{-webkit-transform:perspective(1000px) rotateY(-10deg);transform:perspective(1000px) rotateY(-10deg)}80%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}}@keyframes swingOutY{0%{-webkit-transform:perspective(1000px) rotateY(0);transform:perspective(1000px) rotateY(0)}40%{-webkit-transform:perspective(1000px) rotateY(7.5deg);transform:perspective(1000px) rotateY(7.5deg)}60%{-webkit-transform:perspective(1000px) rotateY(-10deg);transform:perspective(1000px) rotateY(-10deg)}80%{-webkit-transform:perspective(1000px) rotateY(30deg);transform:perspective(1000px) rotateY(30deg);opacity:1}100%{-webkit-transform:perspective(1000px) rotateY(-90deg);transform:perspective(1000px) rotateY(-90deg);opacity:0}}.transition.zoom.in{-webkit-animation-name:zoomIn;animation-name:zoomIn}.transition.zoom.out{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomIn{0%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes zoomIn{0%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes zoomOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}}@keyframes zoomOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}100%{opacity:1;-webkit-transform:scale(0);transform:scale(0)}}.flash.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:flash;animation-name:flash}.shake.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:shake;animation-name:shake}.bounce.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:bounce;animation-name:bounce}.tada.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:tada;animation-name:tada}.pulse.transition{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-name:pulse;animation-name:pulse}.jiggle.transition{-webkit-animation-duration:750ms;animation-duration:750ms;-webkit-animation-name:jiggle;animation-name:jiggle}.transition.glow{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:cubic-bezier(.19,1,.22,1);animation-timing-function:cubic-bezier(.19,1,.22,1)}.transition.glow{-webkit-animation-name:glow;animation-name:glow}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@-webkit-keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@-webkit-keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9) rotate(-3deg);transform:scale(.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}@keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9) rotate(-3deg);transform:scale(.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.9);transform:scale(.9);opacity:.7}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(.9);transform:scale(.9);opacity:.7}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes jiggle{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes jiggle{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@-webkit-keyframes glow{0%{background-color:#fcfcfd}30%{background-color:#fff6cd}100%{background-color:#fcfcfd}}@keyframes glow{0%{background-color:#fcfcfd}30%{background-color:#fff6cd}100%{background-color:#fcfcfd}}\"]}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n  MIT License http://www.opensource.org/licenses/mit-license.php\n  Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n  var list = []; // return the list of modules as css string\n\n  list.toString = function toString() {\n    return this.map(function (item) {\n      var content = cssWithMappingToString(item, useSourceMap);\n\n      if (item[2]) {\n        return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n      }\n\n      return content;\n    }).join('');\n  }; // import a list of modules into the list\n  // eslint-disable-next-line func-names\n\n\n  list.i = function (modules, mediaQuery, dedupe) {\n    if (typeof modules === 'string') {\n      // eslint-disable-next-line no-param-reassign\n      modules = [[null, modules, '']];\n    }\n\n    var alreadyImportedModules = {};\n\n    if (dedupe) {\n      for (var i = 0; i < this.length; i++) {\n        // eslint-disable-next-line prefer-destructuring\n        var id = this[i][0];\n\n        if (id != null) {\n          alreadyImportedModules[id] = true;\n        }\n      }\n    }\n\n    for (var _i = 0; _i < modules.length; _i++) {\n      var item = [].concat(modules[_i]);\n\n      if (dedupe && alreadyImportedModules[item[0]]) {\n        // eslint-disable-next-line no-continue\n        continue;\n      }\n\n      if (mediaQuery) {\n        if (!item[2]) {\n          item[2] = mediaQuery;\n        } else {\n          item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n        }\n      }\n\n      list.push(item);\n    }\n  };\n\n  return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n  var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring\n\n  var cssMapping = item[3];\n\n  if (!cssMapping) {\n    return content;\n  }\n\n  if (useSourceMap && typeof btoa === 'function') {\n    var sourceMapping = toComment(cssMapping);\n    var sourceURLs = cssMapping.sources.map(function (source) {\n      return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || '').concat(source, \" */\");\n    });\n    return [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n  }\n\n  return [content].join('\\n');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n  // eslint-disable-next-line no-undef\n  var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n  var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n  return \"/*# \".concat(data, \" */\");\n}","\"use strict\";\n\nmodule.exports = function (url, options) {\n  if (!options) {\n    // eslint-disable-next-line no-param-reassign\n    options = {};\n  } // eslint-disable-next-line no-underscore-dangle, no-param-reassign\n\n\n  url = url && url.__esModule ? url.default : url;\n\n  if (typeof url !== 'string') {\n    return url;\n  } // If url is already wrapped in quotes, remove them\n\n\n  if (/^['\"].*['\"]$/.test(url)) {\n    // eslint-disable-next-line no-param-reassign\n    url = url.slice(1, -1);\n  }\n\n  if (options.hash) {\n    // eslint-disable-next-line no-param-reassign\n    url += options.hash;\n  } // Should url be wrapped?\n  // See https://drafts.csswg.org/css-values-3/#urls\n\n\n  if (/[\"'() \\t\\n]/.test(url) || options.needQuotes) {\n    return \"\\\"\".concat(url.replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n'), \"\\\"\");\n  }\n\n  return url;\n};","export default function addLeadingZeros(number, targetLength) {\n  var sign = number < 0 ? '-' : '';\n  var output = Math.abs(number).toString();\n\n  while (output.length < targetLength) {\n    output = '0' + output;\n  }\n\n  return sign + output;\n}","export default function assign(target, dirtyObject) {\n  if (target == null) {\n    throw new TypeError('assign requires that input parameter not be null or undefined');\n  }\n\n  dirtyObject = dirtyObject || {};\n\n  for (var property in dirtyObject) {\n    if (dirtyObject.hasOwnProperty(property)) {\n      target[property] = dirtyObject[property];\n    }\n  }\n\n  return target;\n}","import assign from '../assign/index.js';\nexport default function cloneObject(dirtyObject) {\n  return assign({}, dirtyObject);\n}","import lightFormatters from '../lightFormatters/index.js';\nimport getUTCDayOfYear from '../../../_lib/getUTCDayOfYear/index.js';\nimport getUTCISOWeek from '../../../_lib/getUTCISOWeek/index.js';\nimport getUTCISOWeekYear from '../../../_lib/getUTCISOWeekYear/index.js';\nimport getUTCWeek from '../../../_lib/getUTCWeek/index.js';\nimport getUTCWeekYear from '../../../_lib/getUTCWeekYear/index.js';\nimport addLeadingZeros from '../../addLeadingZeros/index.js';\nvar dayPeriodEnum = {\n  am: 'am',\n  pm: 'pm',\n  midnight: 'midnight',\n  noon: 'noon',\n  morning: 'morning',\n  afternoon: 'afternoon',\n  evening: 'evening',\n  night: 'night'\n  /*\n   * |     | Unit                           |     | Unit                           |\n   * |-----|--------------------------------|-----|--------------------------------|\n   * |  a  | AM, PM                         |  A* | Milliseconds in day            |\n   * |  b  | AM, PM, noon, midnight         |  B  | Flexible day period            |\n   * |  c  | Stand-alone local day of week  |  C* | Localized hour w/ day period   |\n   * |  d  | Day of month                   |  D  | Day of year                    |\n   * |  e  | Local day of week              |  E  | Day of week                    |\n   * |  f  |                                |  F* | Day of week in month           |\n   * |  g* | Modified Julian day            |  G  | Era                            |\n   * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n   * |  i! | ISO day of week                |  I! | ISO week of year               |\n   * |  j* | Localized hour w/ day period   |  J* | Localized hour w/o day period  |\n   * |  k  | Hour [1-24]                    |  K  | Hour [0-11]                    |\n   * |  l* | (deprecated)                   |  L  | Stand-alone month              |\n   * |  m  | Minute                         |  M  | Month                          |\n   * |  n  |                                |  N  |                                |\n   * |  o! | Ordinal number modifier        |  O  | Timezone (GMT)                 |\n   * |  p! | Long localized time            |  P! | Long localized date            |\n   * |  q  | Stand-alone quarter            |  Q  | Quarter                        |\n   * |  r* | Related Gregorian year         |  R! | ISO week-numbering year        |\n   * |  s  | Second                         |  S  | Fraction of second             |\n   * |  t! | Seconds timestamp              |  T! | Milliseconds timestamp         |\n   * |  u  | Extended year                  |  U* | Cyclic year                    |\n   * |  v* | Timezone (generic non-locat.)  |  V* | Timezone (location)            |\n   * |  w  | Local week of year             |  W* | Week of month                  |\n   * |  x  | Timezone (ISO-8601 w/o Z)      |  X  | Timezone (ISO-8601)            |\n   * |  y  | Year (abs)                     |  Y  | Local week-numbering year      |\n   * |  z  | Timezone (specific non-locat.) |  Z* | Timezone (aliases)             |\n   *\n   * Letters marked by * are not implemented but reserved by Unicode standard.\n   *\n   * Letters marked by ! are non-standard, but implemented by date-fns:\n   * - `o` modifies the previous token to turn it into an ordinal (see `format` docs)\n   * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n   *   i.e. 7 for Sunday, 1 for Monday, etc.\n   * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n   * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n   *   `R` is supposed to be used in conjunction with `I` and `i`\n   *   for universal ISO week-numbering date, whereas\n   *   `Y` is supposed to be used in conjunction with `w` and `e`\n   *   for week-numbering date specific to the locale.\n   * - `P` is long localized date format\n   * - `p` is long localized time format\n   */\n\n};\nvar formatters = {\n  // Era\n  G: function (date, token, localize) {\n    var era = date.getUTCFullYear() > 0 ? 1 : 0;\n\n    switch (token) {\n      // AD, BC\n      case 'G':\n      case 'GG':\n      case 'GGG':\n        return localize.era(era, {\n          width: 'abbreviated'\n        });\n      // A, B\n\n      case 'GGGGG':\n        return localize.era(era, {\n          width: 'narrow'\n        });\n      // Anno Domini, Before Christ\n\n      case 'GGGG':\n      default:\n        return localize.era(era, {\n          width: 'wide'\n        });\n    }\n  },\n  // Year\n  y: function (date, token, localize) {\n    // Ordinal number\n    if (token === 'yo') {\n      var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n      var year = signedYear > 0 ? signedYear : 1 - signedYear;\n      return localize.ordinalNumber(year, {\n        unit: 'year'\n      });\n    }\n\n    return lightFormatters.y(date, token);\n  },\n  // Local week-numbering year\n  Y: function (date, token, localize, options) {\n    var signedWeekYear = getUTCWeekYear(date, options); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n    var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear; // Two digit year\n\n    if (token === 'YY') {\n      var twoDigitYear = weekYear % 100;\n      return addLeadingZeros(twoDigitYear, 2);\n    } // Ordinal number\n\n\n    if (token === 'Yo') {\n      return localize.ordinalNumber(weekYear, {\n        unit: 'year'\n      });\n    } // Padding\n\n\n    return addLeadingZeros(weekYear, token.length);\n  },\n  // ISO week-numbering year\n  R: function (date, token) {\n    var isoWeekYear = getUTCISOWeekYear(date); // Padding\n\n    return addLeadingZeros(isoWeekYear, token.length);\n  },\n  // Extended year. This is a single number designating the year of this calendar system.\n  // The main difference between `y` and `u` localizers are B.C. years:\n  // | Year | `y` | `u` |\n  // |------|-----|-----|\n  // | AC 1 |   1 |   1 |\n  // | BC 1 |   1 |   0 |\n  // | BC 2 |   2 |  -1 |\n  // Also `yy` always returns the last two digits of a year,\n  // while `uu` pads single digit years to 2 characters and returns other years unchanged.\n  u: function (date, token) {\n    var year = date.getUTCFullYear();\n    return addLeadingZeros(year, token.length);\n  },\n  // Quarter\n  Q: function (date, token, localize) {\n    var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);\n\n    switch (token) {\n      // 1, 2, 3, 4\n      case 'Q':\n        return String(quarter);\n      // 01, 02, 03, 04\n\n      case 'QQ':\n        return addLeadingZeros(quarter, 2);\n      // 1st, 2nd, 3rd, 4th\n\n      case 'Qo':\n        return localize.ordinalNumber(quarter, {\n          unit: 'quarter'\n        });\n      // Q1, Q2, Q3, Q4\n\n      case 'QQQ':\n        return localize.quarter(quarter, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n      case 'QQQQQ':\n        return localize.quarter(quarter, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // 1st quarter, 2nd quarter, ...\n\n      case 'QQQQ':\n      default:\n        return localize.quarter(quarter, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone quarter\n  q: function (date, token, localize) {\n    var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);\n\n    switch (token) {\n      // 1, 2, 3, 4\n      case 'q':\n        return String(quarter);\n      // 01, 02, 03, 04\n\n      case 'qq':\n        return addLeadingZeros(quarter, 2);\n      // 1st, 2nd, 3rd, 4th\n\n      case 'qo':\n        return localize.ordinalNumber(quarter, {\n          unit: 'quarter'\n        });\n      // Q1, Q2, Q3, Q4\n\n      case 'qqq':\n        return localize.quarter(quarter, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n      case 'qqqqq':\n        return localize.quarter(quarter, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // 1st quarter, 2nd quarter, ...\n\n      case 'qqqq':\n      default:\n        return localize.quarter(quarter, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // Month\n  M: function (date, token, localize) {\n    var month = date.getUTCMonth();\n\n    switch (token) {\n      case 'M':\n      case 'MM':\n        return lightFormatters.M(date, token);\n      // 1st, 2nd, ..., 12th\n\n      case 'Mo':\n        return localize.ordinalNumber(month + 1, {\n          unit: 'month'\n        });\n      // Jan, Feb, ..., Dec\n\n      case 'MMM':\n        return localize.month(month, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // J, F, ..., D\n\n      case 'MMMMM':\n        return localize.month(month, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // January, February, ..., December\n\n      case 'MMMM':\n      default:\n        return localize.month(month, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone month\n  L: function (date, token, localize) {\n    var month = date.getUTCMonth();\n\n    switch (token) {\n      // 1, 2, ..., 12\n      case 'L':\n        return String(month + 1);\n      // 01, 02, ..., 12\n\n      case 'LL':\n        return addLeadingZeros(month + 1, 2);\n      // 1st, 2nd, ..., 12th\n\n      case 'Lo':\n        return localize.ordinalNumber(month + 1, {\n          unit: 'month'\n        });\n      // Jan, Feb, ..., Dec\n\n      case 'LLL':\n        return localize.month(month, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // J, F, ..., D\n\n      case 'LLLLL':\n        return localize.month(month, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // January, February, ..., December\n\n      case 'LLLL':\n      default:\n        return localize.month(month, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // Local week of year\n  w: function (date, token, localize, options) {\n    var week = getUTCWeek(date, options);\n\n    if (token === 'wo') {\n      return localize.ordinalNumber(week, {\n        unit: 'week'\n      });\n    }\n\n    return addLeadingZeros(week, token.length);\n  },\n  // ISO week of year\n  I: function (date, token, localize) {\n    var isoWeek = getUTCISOWeek(date);\n\n    if (token === 'Io') {\n      return localize.ordinalNumber(isoWeek, {\n        unit: 'week'\n      });\n    }\n\n    return addLeadingZeros(isoWeek, token.length);\n  },\n  // Day of the month\n  d: function (date, token, localize) {\n    if (token === 'do') {\n      return localize.ordinalNumber(date.getUTCDate(), {\n        unit: 'date'\n      });\n    }\n\n    return lightFormatters.d(date, token);\n  },\n  // Day of year\n  D: function (date, token, localize) {\n    var dayOfYear = getUTCDayOfYear(date);\n\n    if (token === 'Do') {\n      return localize.ordinalNumber(dayOfYear, {\n        unit: 'dayOfYear'\n      });\n    }\n\n    return addLeadingZeros(dayOfYear, token.length);\n  },\n  // Day of week\n  E: function (date, token, localize) {\n    var dayOfWeek = date.getUTCDay();\n\n    switch (token) {\n      // Tue\n      case 'E':\n      case 'EE':\n      case 'EEE':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'EEEEE':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'EEEEEE':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'EEEE':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Local day of week\n  e: function (date, token, localize, options) {\n    var dayOfWeek = date.getUTCDay();\n    var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n\n    switch (token) {\n      // Numerical value (Nth day of week with current locale or weekStartsOn)\n      case 'e':\n        return String(localDayOfWeek);\n      // Padded numerical value\n\n      case 'ee':\n        return addLeadingZeros(localDayOfWeek, 2);\n      // 1st, 2nd, ..., 7th\n\n      case 'eo':\n        return localize.ordinalNumber(localDayOfWeek, {\n          unit: 'day'\n        });\n\n      case 'eee':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'eeeee':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'eeeeee':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'eeee':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone local day of week\n  c: function (date, token, localize, options) {\n    var dayOfWeek = date.getUTCDay();\n    var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n\n    switch (token) {\n      // Numerical value (same as in `e`)\n      case 'c':\n        return String(localDayOfWeek);\n      // Padded numerical value\n\n      case 'cc':\n        return addLeadingZeros(localDayOfWeek, token.length);\n      // 1st, 2nd, ..., 7th\n\n      case 'co':\n        return localize.ordinalNumber(localDayOfWeek, {\n          unit: 'day'\n        });\n\n      case 'ccc':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // T\n\n      case 'ccccc':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // Tu\n\n      case 'cccccc':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'standalone'\n        });\n      // Tuesday\n\n      case 'cccc':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // ISO day of week\n  i: function (date, token, localize) {\n    var dayOfWeek = date.getUTCDay();\n    var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;\n\n    switch (token) {\n      // 2\n      case 'i':\n        return String(isoDayOfWeek);\n      // 02\n\n      case 'ii':\n        return addLeadingZeros(isoDayOfWeek, token.length);\n      // 2nd\n\n      case 'io':\n        return localize.ordinalNumber(isoDayOfWeek, {\n          unit: 'day'\n        });\n      // Tue\n\n      case 'iii':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'iiiii':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'iiiiii':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'iiii':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // AM or PM\n  a: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';\n\n    switch (token) {\n      case 'a':\n      case 'aa':\n      case 'aaa':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'aaaaa':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'aaaa':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // AM, PM, midnight, noon\n  b: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue;\n\n    if (hours === 12) {\n      dayPeriodEnumValue = dayPeriodEnum.noon;\n    } else if (hours === 0) {\n      dayPeriodEnumValue = dayPeriodEnum.midnight;\n    } else {\n      dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';\n    }\n\n    switch (token) {\n      case 'b':\n      case 'bb':\n      case 'bbb':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'bbbbb':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'bbbb':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // in the morning, in the afternoon, in the evening, at night\n  B: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue;\n\n    if (hours >= 17) {\n      dayPeriodEnumValue = dayPeriodEnum.evening;\n    } else if (hours >= 12) {\n      dayPeriodEnumValue = dayPeriodEnum.afternoon;\n    } else if (hours >= 4) {\n      dayPeriodEnumValue = dayPeriodEnum.morning;\n    } else {\n      dayPeriodEnumValue = dayPeriodEnum.night;\n    }\n\n    switch (token) {\n      case 'B':\n      case 'BB':\n      case 'BBB':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'BBBBB':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'BBBB':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Hour [1-12]\n  h: function (date, token, localize) {\n    if (token === 'ho') {\n      var hours = date.getUTCHours() % 12;\n      if (hours === 0) hours = 12;\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return lightFormatters.h(date, token);\n  },\n  // Hour [0-23]\n  H: function (date, token, localize) {\n    if (token === 'Ho') {\n      return localize.ordinalNumber(date.getUTCHours(), {\n        unit: 'hour'\n      });\n    }\n\n    return lightFormatters.H(date, token);\n  },\n  // Hour [0-11]\n  K: function (date, token, localize) {\n    var hours = date.getUTCHours() % 12;\n\n    if (token === 'Ko') {\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return addLeadingZeros(hours, token.length);\n  },\n  // Hour [1-24]\n  k: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    if (hours === 0) hours = 24;\n\n    if (token === 'ko') {\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return addLeadingZeros(hours, token.length);\n  },\n  // Minute\n  m: function (date, token, localize) {\n    if (token === 'mo') {\n      return localize.ordinalNumber(date.getUTCMinutes(), {\n        unit: 'minute'\n      });\n    }\n\n    return lightFormatters.m(date, token);\n  },\n  // Second\n  s: function (date, token, localize) {\n    if (token === 'so') {\n      return localize.ordinalNumber(date.getUTCSeconds(), {\n        unit: 'second'\n      });\n    }\n\n    return lightFormatters.s(date, token);\n  },\n  // Fraction of second\n  S: function (date, token) {\n    return lightFormatters.S(date, token);\n  },\n  // Timezone (ISO-8601. If offset is 0, output is always `'Z'`)\n  X: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    if (timezoneOffset === 0) {\n      return 'Z';\n    }\n\n    switch (token) {\n      // Hours and optional minutes\n      case 'X':\n        return formatTimezoneWithOptionalMinutes(timezoneOffset);\n      // Hours, minutes and optional seconds without `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `XX`\n\n      case 'XXXX':\n      case 'XX':\n        // Hours and minutes without `:` delimiter\n        return formatTimezone(timezoneOffset);\n      // Hours, minutes and optional seconds with `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `XXX`\n\n      case 'XXXXX':\n      case 'XXX': // Hours and minutes with `:` delimiter\n\n      default:\n        return formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)\n  x: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Hours and optional minutes\n      case 'x':\n        return formatTimezoneWithOptionalMinutes(timezoneOffset);\n      // Hours, minutes and optional seconds without `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `xx`\n\n      case 'xxxx':\n      case 'xx':\n        // Hours and minutes without `:` delimiter\n        return formatTimezone(timezoneOffset);\n      // Hours, minutes and optional seconds with `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `xxx`\n\n      case 'xxxxx':\n      case 'xxx': // Hours and minutes with `:` delimiter\n\n      default:\n        return formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (GMT)\n  O: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Short\n      case 'O':\n      case 'OO':\n      case 'OOO':\n        return 'GMT' + formatTimezoneShort(timezoneOffset, ':');\n      // Long\n\n      case 'OOOO':\n      default:\n        return 'GMT' + formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (specific non-location)\n  z: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Short\n      case 'z':\n      case 'zz':\n      case 'zzz':\n        return 'GMT' + formatTimezoneShort(timezoneOffset, ':');\n      // Long\n\n      case 'zzzz':\n      default:\n        return 'GMT' + formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Seconds timestamp\n  t: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timestamp = Math.floor(originalDate.getTime() / 1000);\n    return addLeadingZeros(timestamp, token.length);\n  },\n  // Milliseconds timestamp\n  T: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timestamp = originalDate.getTime();\n    return addLeadingZeros(timestamp, token.length);\n  }\n};\n\nfunction formatTimezoneShort(offset, dirtyDelimiter) {\n  var sign = offset > 0 ? '-' : '+';\n  var absOffset = Math.abs(offset);\n  var hours = Math.floor(absOffset / 60);\n  var minutes = absOffset % 60;\n\n  if (minutes === 0) {\n    return sign + String(hours);\n  }\n\n  var delimiter = dirtyDelimiter || '';\n  return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);\n}\n\nfunction formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) {\n  if (offset % 60 === 0) {\n    var sign = offset > 0 ? '-' : '+';\n    return sign + addLeadingZeros(Math.abs(offset) / 60, 2);\n  }\n\n  return formatTimezone(offset, dirtyDelimiter);\n}\n\nfunction formatTimezone(offset, dirtyDelimiter) {\n  var delimiter = dirtyDelimiter || '';\n  var sign = offset > 0 ? '-' : '+';\n  var absOffset = Math.abs(offset);\n  var hours = addLeadingZeros(Math.floor(absOffset / 60), 2);\n  var minutes = addLeadingZeros(absOffset % 60, 2);\n  return sign + hours + delimiter + minutes;\n}\n\nexport default formatters;","import addLeadingZeros from '../../addLeadingZeros/index.js';\n/*\n * |     | Unit                           |     | Unit                           |\n * |-----|--------------------------------|-----|--------------------------------|\n * |  a  | AM, PM                         |  A* |                                |\n * |  d  | Day of month                   |  D  |                                |\n * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n * |  m  | Minute                         |  M  | Month                          |\n * |  s  | Second                         |  S  | Fraction of second             |\n * |  y  | Year (abs)                     |  Y  |                                |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n */\n\nvar formatters = {\n  // Year\n  y: function (date, token) {\n    // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens\n    // | Year     |     y | yy |   yyy |  yyyy | yyyyy |\n    // |----------|-------|----|-------|-------|-------|\n    // | AD 1     |     1 | 01 |   001 |  0001 | 00001 |\n    // | AD 12    |    12 | 12 |   012 |  0012 | 00012 |\n    // | AD 123   |   123 | 23 |   123 |  0123 | 00123 |\n    // | AD 1234  |  1234 | 34 |  1234 |  1234 | 01234 |\n    // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n    var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n    var year = signedYear > 0 ? signedYear : 1 - signedYear;\n    return addLeadingZeros(token === 'yy' ? year % 100 : year, token.length);\n  },\n  // Month\n  M: function (date, token) {\n    var month = date.getUTCMonth();\n    return token === 'M' ? String(month + 1) : addLeadingZeros(month + 1, 2);\n  },\n  // Day of the month\n  d: function (date, token) {\n    return addLeadingZeros(date.getUTCDate(), token.length);\n  },\n  // AM or PM\n  a: function (date, token) {\n    var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am';\n\n    switch (token) {\n      case 'a':\n      case 'aa':\n      case 'aaa':\n        return dayPeriodEnumValue.toUpperCase();\n\n      case 'aaaaa':\n        return dayPeriodEnumValue[0];\n\n      case 'aaaa':\n      default:\n        return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.';\n    }\n  },\n  // Hour [1-12]\n  h: function (date, token) {\n    return addLeadingZeros(date.getUTCHours() % 12 || 12, token.length);\n  },\n  // Hour [0-23]\n  H: function (date, token) {\n    return addLeadingZeros(date.getUTCHours(), token.length);\n  },\n  // Minute\n  m: function (date, token) {\n    return addLeadingZeros(date.getUTCMinutes(), token.length);\n  },\n  // Second\n  s: function (date, token) {\n    return addLeadingZeros(date.getUTCSeconds(), token.length);\n  },\n  // Fraction of second\n  S: function (date, token) {\n    var numberOfDigits = token.length;\n    var milliseconds = date.getUTCMilliseconds();\n    var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3));\n    return addLeadingZeros(fractionalSeconds, token.length);\n  }\n};\nexport default formatters;","function dateLongFormatter(pattern, formatLong) {\n  switch (pattern) {\n    case 'P':\n      return formatLong.date({\n        width: 'short'\n      });\n\n    case 'PP':\n      return formatLong.date({\n        width: 'medium'\n      });\n\n    case 'PPP':\n      return formatLong.date({\n        width: 'long'\n      });\n\n    case 'PPPP':\n    default:\n      return formatLong.date({\n        width: 'full'\n      });\n  }\n}\n\nfunction timeLongFormatter(pattern, formatLong) {\n  switch (pattern) {\n    case 'p':\n      return formatLong.time({\n        width: 'short'\n      });\n\n    case 'pp':\n      return formatLong.time({\n        width: 'medium'\n      });\n\n    case 'ppp':\n      return formatLong.time({\n        width: 'long'\n      });\n\n    case 'pppp':\n    default:\n      return formatLong.time({\n        width: 'full'\n      });\n  }\n}\n\nfunction dateTimeLongFormatter(pattern, formatLong) {\n  var matchResult = pattern.match(/(P+)(p+)?/);\n  var datePattern = matchResult[1];\n  var timePattern = matchResult[2];\n\n  if (!timePattern) {\n    return dateLongFormatter(pattern, formatLong);\n  }\n\n  var dateTimeFormat;\n\n  switch (datePattern) {\n    case 'P':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'short'\n      });\n      break;\n\n    case 'PP':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'medium'\n      });\n      break;\n\n    case 'PPP':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'long'\n      });\n      break;\n\n    case 'PPPP':\n    default:\n      dateTimeFormat = formatLong.dateTime({\n        width: 'full'\n      });\n      break;\n  }\n\n  return dateTimeFormat.replace('{{date}}', dateLongFormatter(datePattern, formatLong)).replace('{{time}}', timeLongFormatter(timePattern, formatLong));\n}\n\nvar longFormatters = {\n  p: timeLongFormatter,\n  P: dateTimeLongFormatter\n};\nexport default longFormatters;","var MILLISECONDS_IN_MINUTE = 60000;\n\nfunction getDateMillisecondsPart(date) {\n  return date.getTime() % MILLISECONDS_IN_MINUTE;\n}\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\n\n\nexport default function getTimezoneOffsetInMilliseconds(dirtyDate) {\n  var date = new Date(dirtyDate.getTime());\n  var baseTimezoneOffset = Math.ceil(date.getTimezoneOffset());\n  date.setSeconds(0, 0);\n  var hasNegativeUTCOffset = baseTimezoneOffset > 0;\n  var millisecondsPartOfTimezoneOffset = hasNegativeUTCOffset ? (MILLISECONDS_IN_MINUTE + getDateMillisecondsPart(date)) % MILLISECONDS_IN_MINUTE : getDateMillisecondsPart(date);\n  return baseTimezoneOffset * MILLISECONDS_IN_MINUTE + millisecondsPartOfTimezoneOffset;\n}","import toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 86400000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var timestamp = date.getTime();\n  date.setUTCMonth(0, 1);\n  date.setUTCHours(0, 0, 0, 0);\n  var startOfYearTimestamp = date.getTime();\n  var difference = timestamp - startOfYearTimestamp;\n  return Math.floor(difference / MILLISECONDS_IN_DAY) + 1;\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport startOfUTCISOWeekYear from '../startOfUTCISOWeekYear/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfUTCISOWeek(date).getTime() - startOfUTCISOWeekYear(date).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getUTCFullYear();\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0);\n  var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear);\n  var fourthOfJanuaryOfThisYear = new Date(0);\n  fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4);\n  fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0);\n  var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport startOfUTCWeekYear from '../startOfUTCWeekYear/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfUTCWeek(date, options).getTime() - startOfUTCWeekYear(date, options).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate, dirtyOptions);\n  var year = date.getUTCFullYear();\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var firstWeekOfNextYear = new Date(0);\n  firstWeekOfNextYear.setUTCFullYear(year + 1, 0, firstWeekContainsDate);\n  firstWeekOfNextYear.setUTCHours(0, 0, 0, 0);\n  var startOfNextYear = startOfUTCWeek(firstWeekOfNextYear, dirtyOptions);\n  var firstWeekOfThisYear = new Date(0);\n  firstWeekOfThisYear.setUTCFullYear(year, 0, firstWeekContainsDate);\n  firstWeekOfThisYear.setUTCHours(0, 0, 0, 0);\n  var startOfThisYear = startOfUTCWeek(firstWeekOfThisYear, dirtyOptions);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","var protectedDayOfYearTokens = ['D', 'DD'];\nvar protectedWeekYearTokens = ['YY', 'YYYY'];\nexport function isProtectedDayOfYearToken(token) {\n  return protectedDayOfYearTokens.indexOf(token) !== -1;\n}\nexport function isProtectedWeekYearToken(token) {\n  return protectedWeekYearTokens.indexOf(token) !== -1;\n}\nexport function throwProtectedError(token, format, input) {\n  if (token === 'YYYY') {\n    throw new RangeError(\"Use `yyyy` instead of `YYYY` (in `\".concat(format, \"`) for formatting years to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'YY') {\n    throw new RangeError(\"Use `yy` instead of `YY` (in `\".concat(format, \"`) for formatting years to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'D') {\n    throw new RangeError(\"Use `d` instead of `D` (in `\".concat(format, \"`) for formatting days of the month to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'DD') {\n    throw new RangeError(\"Use `dd` instead of `DD` (in `\".concat(format, \"`) for formatting days of the month to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  }\n}","export default function requiredArgs(required, args) {\n  if (args.length < required) {\n    throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');\n  }\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCDay(dirtyDate, dirtyDay, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = toInteger(dirtyDay);\n  var currentDay = date.getUTCDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISODay(dirtyDate, dirtyDay) {\n  requiredArgs(2, arguments);\n  var day = toInteger(dirtyDay);\n\n  if (day % 7 === 0) {\n    day = day - 7;\n  }\n\n  var weekStartsOn = 1;\n  var date = toDate(dirtyDate);\n  var currentDay = date.getUTCDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport getUTCISOWeek from '../getUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISOWeek(dirtyDate, dirtyISOWeek) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeek = toInteger(dirtyISOWeek);\n  var diff = getUTCISOWeek(date) - isoWeek;\n  date.setUTCDate(date.getUTCDate() - diff * 7);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport getUTCWeek from '../getUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCWeek(dirtyDate, dirtyWeek, options) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var week = toInteger(dirtyWeek);\n  var diff = getUTCWeek(date, options) - week;\n  date.setUTCDate(date.getUTCDate() - diff * 7);\n  return date;\n}","import toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var weekStartsOn = 1;\n  var date = toDate(dirtyDate);\n  var day = date.getUTCDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setUTCDate(date.getUTCDate() - diff);\n  date.setUTCHours(0, 0, 0, 0);\n  return date;\n}","import getUTCISOWeekYear from '../getUTCISOWeekYear/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getUTCISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setUTCFullYear(year, 0, 4);\n  fourthOfJanuary.setUTCHours(0, 0, 0, 0);\n  var date = startOfUTCISOWeek(fourthOfJanuary);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getUTCDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setUTCDate(date.getUTCDate() - diff);\n  date.setUTCHours(0, 0, 0, 0);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport getUTCWeekYear from '../getUTCWeekYear/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var year = getUTCWeekYear(dirtyDate, dirtyOptions);\n  var firstWeek = new Date(0);\n  firstWeek.setUTCFullYear(year, 0, firstWeekContainsDate);\n  firstWeek.setUTCHours(0, 0, 0, 0);\n  var date = startOfUTCWeek(firstWeek, dirtyOptions);\n  return date;\n}","export default function toInteger(dirtyNumber) {\n  if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {\n    return NaN;\n  }\n\n  var number = Number(dirtyNumber);\n\n  if (isNaN(number)) {\n    return number;\n  }\n\n  return number < 0 ? Math.ceil(number) : Math.floor(number);\n}","import addDays from '../addDays/index.js';\nimport addMonths from '../addMonths/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name add\n * @category Common Helpers\n * @summary Add the specified years, months, weeks, days, hours, minutes and seconds to the given date.\n *\n * @description\n * Add the specified years, months, weeks, days, hours, minutes and seconds to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Duration} duration - the object with years, months, weeks, days, hours, minutes and seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n *\n * | Key            | Description                        |\n * |----------------|------------------------------------|\n * | years          | Amount of years to be added        |\n * | months         | Amount of months to be added       |\n * | weeks          | Amount of weeks to be added       |\n * | days           | Amount of days to be added         |\n * | hours          | Amount of hours to be added        |\n * | minutes        | Amount of minutes to be added      |\n * | seconds        | Amount of seconds to be added      |\n *\n * All values default to 0\n *\n * @returns {Date} the new date with the seconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add the following duration to 1 September 2014, 10:19:50\n * var result = add(new Date(2014, 8, 1, 10, 19, 50), {\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30,\n * })\n * //=> Thu Jun 15 2017 15:29:20\n */\n\nexport default function add(dirtyDate, duration) {\n  requiredArgs(2, arguments);\n  if (!duration || typeof duration !== 'object') return new Date(NaN);\n  var years = 'years' in duration ? toInteger(duration.years) : 0;\n  var months = 'months' in duration ? toInteger(duration.months) : 0;\n  var weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0;\n  var days = 'days' in duration ? toInteger(duration.days) : 0;\n  var hours = 'hours' in duration ? toInteger(duration.hours) : 0;\n  var minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0;\n  var seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0; // Add years and months\n\n  var date = toDate(dirtyDate);\n  var dateWithMonths = months || years ? addMonths(date, months + years * 12) : date; // Add weeks and days\n\n  var dateWithDays = days || weeks ? addDays(dateWithMonths, days + weeks * 7) : dateWithMonths; // Add days, hours, minutes and seconds\n\n  var minutesToAdd = minutes + hours * 60;\n  var secondsToAdd = seconds + minutesToAdd * 60;\n  var msToAdd = secondsToAdd * 1000;\n  var finalDate = new Date(dateWithDays.getTime() + msToAdd);\n  return finalDate;\n}","import isWeekend from '../isWeekend/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport isSunday from '../isSunday/index.js';\nimport isSaturday from '../isSaturday/index.js';\n/**\n * @name addBusinessDays\n * @category Day Helpers\n * @summary Add the specified number of business days (mon - fri) to the given date.\n *\n * @description\n * Add the specified number of business days (mon - fri) to the given date, ignoring weekends.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of business days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the business days added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 10 business days to 1 September 2014:\n * var result = addBusinessDays(new Date(2014, 8, 1), 10)\n * //=> Mon Sep 15 2014 00:00:00 (skipped weekend days)\n */\n\nexport default function addBusinessDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var startedOnWeekend = isWeekend(date);\n  var amount = toInteger(dirtyAmount);\n  if (isNaN(amount)) return new Date(NaN);\n  var hours = date.getHours();\n  var sign = amount < 0 ? -1 : 1;\n  var fullWeeks = toInteger(amount / 5);\n  date.setDate(date.getDate() + fullWeeks * 7); // Get remaining days not part of a full week\n\n  var restDays = Math.abs(amount % 5); // Loops over remaining days\n\n  while (restDays > 0) {\n    date.setDate(date.getDate() + sign);\n    if (!isWeekend(date)) restDays -= 1;\n  } // If the date is a weekend day and we reduce a dividable of\n  // 5 from it, we land on a weekend date.\n  // To counter this, we add days accordingly to land on the next business day\n\n\n  if (startedOnWeekend && isWeekend(date) && amount !== 0) {\n    // If we're reducing days, we want to add days until we land on a weekday\n    // If we're adding days we want to reduce days until we land on a weekday\n    if (isSaturday(date)) date.setDate(date.getDate() + (sign < 0 ? 2 : -1));\n    if (isSunday(date)) date.setDate(date.getDate() + (sign < 0 ? 1 : -2));\n  } // Restore hours to avoid DST lag\n\n\n  date.setHours(hours);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addDays\n * @category Day Helpers\n * @summary Add the specified number of days to the given date.\n *\n * @description\n * Add the specified number of days to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the days added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 10 days to 1 September 2014:\n * var result = addDays(new Date(2014, 8, 1), 10)\n * //=> Thu Sep 11 2014 00:00:00\n */\n\nexport default function addDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var amount = toInteger(dirtyAmount);\n\n  if (isNaN(amount)) {\n    return new Date(NaN);\n  }\n\n  if (!amount) {\n    // If 0 days, no-op to avoid changing times in the hour before end of DST\n    return date;\n  }\n\n  date.setDate(date.getDate() + amount);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\n/**\n * @name addHours\n * @category Hour Helpers\n * @summary Add the specified number of hours to the given date.\n *\n * @description\n * Add the specified number of hours to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of hours to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the hours added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 2 hours to 10 July 2014 23:00:00:\n * var result = addHours(new Date(2014, 6, 10, 23, 0), 2)\n * //=> Fri Jul 11 2014 01:00:00\n */\n\nexport default function addHours(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport getISOWeekYear from '../getISOWeekYear/index.js';\nimport setISOWeekYear from '../setISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Add the specified number of ISO week-numbering years to the given date.\n *\n * @description\n * Add the specified number of ISO week-numbering years to the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `addISOYears` to `addISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of ISO week-numbering years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the ISO week-numbering years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 ISO week-numbering years to 2 July 2010:\n * var result = addISOWeekYears(new Date(2010, 6, 2), 5)\n * //=> Fri Jun 26 2015 00:00:00\n */\n\nexport default function addISOWeekYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return setISOWeekYear(dirtyDate, getISOWeekYear(dirtyDate) + amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addMilliseconds\n * @category Millisecond Helpers\n * @summary Add the specified number of milliseconds to the given date.\n *\n * @description\n * Add the specified number of milliseconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of milliseconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the milliseconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 750 milliseconds to 10 July 2014 12:45:30.000:\n * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)\n * //=> Thu Jul 10 2014 12:45:30.750\n */\n\nexport default function addMilliseconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var timestamp = toDate(dirtyDate).getTime();\n  var amount = toInteger(dirtyAmount);\n  return new Date(timestamp + amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_MINUTE = 60000;\n/**\n * @name addMinutes\n * @category Minute Helpers\n * @summary Add the specified number of minutes to the given date.\n *\n * @description\n * Add the specified number of minutes to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of minutes to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the minutes added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 minutes to 10 July 2014 12:00:00:\n * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30)\n * //=> Thu Jul 10 2014 12:30:00\n */\n\nexport default function addMinutes(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addMonths\n * @category Month Helpers\n * @summary Add the specified number of months to the given date.\n *\n * @description\n * Add the specified number of months to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the months added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 months to 1 September 2014:\n * var result = addMonths(new Date(2014, 8, 1), 5)\n * //=> Sun Feb 01 2015 00:00:00\n */\n\nexport default function addMonths(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var amount = toInteger(dirtyAmount);\n\n  if (isNaN(amount)) {\n    return new Date(NaN);\n  }\n\n  if (!amount) {\n    // If 0 months, no-op to avoid changing times in the hour before end of DST\n    return date;\n  }\n\n  var dayOfMonth = date.getDate(); // The JS Date object supports date math by accepting out-of-bounds values for\n  // month, day, etc. For example, new Date(2020, 1, 0) returns 31 Dec 2019 and\n  // new Date(2020, 13, 1) returns 1 Feb 2021.  This is *almost* the behavior we\n  // want except that dates will wrap around the end of a month, meaning that\n  // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So\n  // we'll default to the end of the desired month by adding 1 to the desired\n  // month and using a date of 0 to back up one day to the end of the desired\n  // month.\n\n  var endOfDesiredMonth = new Date(date.getTime());\n  endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);\n  var daysInMonth = endOfDesiredMonth.getDate();\n\n  if (dayOfMonth >= daysInMonth) {\n    // If we're already at the end of the month, then this is the correct date\n    // and we're done.\n    return endOfDesiredMonth;\n  } else {\n    // Otherwise, we now know that setting the original day-of-month value won't\n    // cause an overflow, so set the desired day-of-month. Note that we can't\n    // just set the date of `endOfDesiredMonth` because that object may have had\n    // its time changed in the unusual case where where a DST transition was on\n    // the last day of the month and its local time was in the hour skipped or\n    // repeated next to a DST transition.  So we use `date` instead which is\n    // guaranteed to still have the original time.\n    date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);\n    return date;\n  }\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addQuarters\n * @category Quarter Helpers\n * @summary Add the specified number of year quarters to the given date.\n *\n * @description\n * Add the specified number of year quarters to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of quarters to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the quarters added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 1 quarter to 1 September 2014:\n * var result = addQuarters(new Date(2014, 8, 1), 1)\n * //=> Mon Dec 01 2014 00:00:00\n */\n\nexport default function addQuarters(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  var months = amount * 3;\n  return addMonths(dirtyDate, months);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addSeconds\n * @category Second Helpers\n * @summary Add the specified number of seconds to the given date.\n *\n * @description\n * Add the specified number of seconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 seconds to 10 July 2014 12:45:00:\n * var result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:45:30\n */\n\nexport default function addSeconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * 1000);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addDays from '../addDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addWeeks\n * @category Week Helpers\n * @summary Add the specified number of weeks to the given date.\n *\n * @description\n * Add the specified number of week to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of weeks to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the weeks added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 4 weeks to 1 September 2014:\n * var result = addWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Sep 29 2014 00:00:00\n */\n\nexport default function addWeeks(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  var days = amount * 7;\n  return addDays(dirtyDate, days);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addYears\n * @category Year Helpers\n * @summary Add the specified number of years to the given date.\n *\n * @description\n * Add the specified number of years to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 years to 1 September 2014:\n * var result = addYears(new Date(2014, 8, 1), 5)\n * //=> Sun Sep 01 2019 00:00:00\n */\n\nexport default function addYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMonths(dirtyDate, amount * 12);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name areIntervalsOverlapping\n * @category Interval Helpers\n * @summary Is the given time interval overlapping with another time interval?\n *\n * @description\n * Is the given time interval overlapping with another time interval? Adjacent intervals do not count as overlapping.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `areRangesOverlapping` to `areIntervalsOverlapping`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   areRangesOverlapping(\n *     new Date(2014, 0, 10), new Date(2014, 0, 20),\n *     new Date(2014, 0, 17), new Date(2014, 0, 21)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   areIntervalsOverlapping(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *     { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n *   )\n *   ```\n *\n * @param {Interval} intervalLeft - the first interval to compare. See [Interval]{@link docs/types/Interval}\n * @param {Interval} intervalRight - the second interval to compare. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - the object with options\n * @param {Boolean} [options.inclusive=false] - whether the comparison is inclusive or not\n * @returns {Boolean} whether the time intervals are overlapping\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For overlapping time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n * )\n * //=> true\n *\n * @example\n * // For non-overlapping time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 21), end: new Date(2014, 0, 22) }\n * )\n * //=> false\n *\n * @example\n * // For adjacent time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 30) }\n * )\n * //=> false\n *\n * @example\n * // Using the inclusive option:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 24) }\n * )\n * //=> false\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 24) },\n *   { inclusive: true }\n * )\n * //=> true\n */\n\nexport default function areIntervalsOverlapping(dirtyIntervalLeft, dirtyIntervalRight) {\n  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n  requiredArgs(2, arguments);\n  var intervalLeft = dirtyIntervalLeft || {};\n  var intervalRight = dirtyIntervalRight || {};\n  var leftStartTime = toDate(intervalLeft.start).getTime();\n  var leftEndTime = toDate(intervalLeft.end).getTime();\n  var rightStartTime = toDate(intervalRight.start).getTime();\n  var rightEndTime = toDate(intervalRight.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  if (options.inclusive) {\n    return leftStartTime <= rightEndTime && rightStartTime <= leftEndTime;\n  }\n\n  return leftStartTime < rightEndTime && rightStartTime < leftEndTime;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name closestIndexTo\n * @category Common Helpers\n * @summary Return an index of the closest date from the array comparing to the given date.\n *\n * @description\n * Return an index of the closest date from the array comparing to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now, `closestIndexTo` doesn't throw an exception\n *   when the second argument is not an array, and returns Invalid Date instead.\n *\n * @param {Date|Number} dateToCompare - the date to compare with\n * @param {Date[]|Number[]} datesArray - the array to search\n * @returns {Number} an index of the date closest to the given date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Which date is closer to 6 September 2015?\n * var dateToCompare = new Date(2015, 8, 6)\n * var datesArray = [\n *   new Date(2015, 0, 1),\n *   new Date(2016, 0, 1),\n *   new Date(2017, 0, 1)\n * ]\n * var result = closestIndexTo(dateToCompare, datesArray)\n * //=> 1\n */\n\nexport default function closestIndexTo(dirtyDateToCompare, dirtyDatesArray) {\n  requiredArgs(2, arguments);\n  var dateToCompare = toDate(dirtyDateToCompare);\n\n  if (isNaN(dateToCompare)) {\n    return NaN;\n  }\n\n  var timeToCompare = dateToCompare.getTime();\n  var datesArray; // `dirtyDatesArray` is undefined or null\n\n  if (dirtyDatesArray == null) {\n    datesArray = []; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n  } else if (typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array\n  } else {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  }\n\n  var result;\n  var minDistance;\n  datesArray.forEach(function (dirtyDate, index) {\n    var currentDate = toDate(dirtyDate);\n\n    if (isNaN(currentDate)) {\n      result = NaN;\n      minDistance = NaN;\n      return;\n    }\n\n    var distance = Math.abs(timeToCompare - currentDate.getTime());\n\n    if (result == null || distance < minDistance) {\n      result = index;\n      minDistance = distance;\n    }\n  });\n  return result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name closestTo\n * @category Common Helpers\n * @summary Return a date from the array closest to the given date.\n *\n * @description\n * Return a date from the array closest to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now, `closestTo` doesn't throw an exception\n *   when the second argument is not an array, and returns Invalid Date instead.\n *\n * @param {Date|Number} dateToCompare - the date to compare with\n * @param {Date[]|Number[]} datesArray - the array to search\n * @returns {Date} the date from the array closest to the given date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030?\n * var dateToCompare = new Date(2015, 8, 6)\n * var result = closestTo(dateToCompare, [\n *   new Date(2000, 0, 1),\n *   new Date(2030, 0, 1)\n * ])\n * //=> Tue Jan 01 2030 00:00:00\n */\n\nexport default function closestTo(dirtyDateToCompare, dirtyDatesArray) {\n  requiredArgs(2, arguments);\n  var dateToCompare = toDate(dirtyDateToCompare);\n\n  if (isNaN(dateToCompare)) {\n    return new Date(NaN);\n  }\n\n  var timeToCompare = dateToCompare.getTime();\n  var datesArray; // `dirtyDatesArray` is undefined or null\n\n  if (dirtyDatesArray == null) {\n    datesArray = []; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n  } else if (typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array\n  } else {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  }\n\n  var result;\n  var minDistance;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (isNaN(currentDate)) {\n      result = new Date(NaN);\n      minDistance = NaN;\n      return;\n    }\n\n    var distance = Math.abs(timeToCompare - currentDate.getTime());\n\n    if (result == null || distance < minDistance) {\n      result = currentDate;\n      minDistance = distance;\n    }\n  });\n  return result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name compareAsc\n * @category Common Helpers\n * @summary Compare the two dates and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return 1 if the first date is after the second,\n * -1 if the first date is before the second or 0 if dates are equal.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Number} the result of the comparison\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989:\n * var result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> -1\n *\n * @example\n * // Sort the array of dates:\n * var result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareAsc)\n * //=> [\n * //   Wed Feb 11 1987 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Sun Jul 02 1995 00:00:00\n * // ]\n */\n\nexport default function compareAsc(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var diff = dateLeft.getTime() - dateRight.getTime();\n\n  if (diff < 0) {\n    return -1;\n  } else if (diff > 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name compareDesc\n * @category Common Helpers\n * @summary Compare the two dates reverse chronologically and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return -1 if the first date is after the second,\n * 1 if the first date is before the second or 0 if dates are equal.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Number} the result of the comparison\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989 reverse chronologically:\n * var result = compareDesc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> 1\n *\n * @example\n * // Sort the array of dates in reverse chronological order:\n * var result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareDesc)\n * //=> [\n * //   Sun Jul 02 1995 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Wed Feb 11 1987 00:00:00\n * // ]\n */\n\nexport default function compareDesc(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var diff = dateLeft.getTime() - dateRight.getTime();\n\n  if (diff > 0) {\n    return -1;\n  } else if (diff < 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}","/**\n *  Maximum allowed time.\n *  @constant\n *  @type {number}\n *  @default\n */\nexport var maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;\n/**\n *  Minimum allowed time.\n *  @constant\n *  @type {number}\n *  @default\n */\n\nexport var minTime = -maxTime;","import isValid from '../isValid/index.js';\nimport isWeekend from '../isWeekend/index.js';\nimport toDate from '../toDate/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport addDays from '../addDays/index.js';\nimport isSameDay from '../isSameDay/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInBusinessDays\n * @category Day Helpers\n * @summary Get the number of business days between the given dates.\n *\n * @description\n * Get the number of business day periods between the given dates.\n * Business days being days that arent in the weekend.\n * Like `differenceInCalendarDays`, the function removes the times from\n * the dates before calculating the difference.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of business days\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many business days are between\n * // 10 January 2014 and 20 July 2014?\n * var result = differenceInBusinessDays(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 0, 10)\n * )\n * //=> 136\n */\n\nexport default function differenceInBusinessDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  if (!isValid(dateLeft) || !isValid(dateRight)) return new Date(NaN);\n  var calendarDifference = differenceInCalendarDays(dateLeft, dateRight);\n  var sign = calendarDifference < 0 ? -1 : 1;\n  var weeks = toInteger(calendarDifference / 7);\n  var result = weeks * 5;\n  dateRight = addDays(dateRight, weeks * 7); // the loop below will run at most 6 times to account for the remaining days that don't makeup a full week\n\n  while (!isSameDay(dateLeft, dateRight)) {\n    // sign is used to account for both negative and positive differences\n    result += isWeekend(dateRight) ? 0 : sign;\n    dateRight = addDays(dateRight, sign);\n  }\n\n  return result === 0 ? 0 : result;\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport startOfDay from '../startOfDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 86400000;\n/**\n * @name differenceInCalendarDays\n * @category Day Helpers\n * @summary Get the number of calendar days between the given dates.\n *\n * @description\n * Get the number of calendar days between the given dates. This means that the times are removed\n * from the dates and then the difference in days is calculated.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar days\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar days are between\n * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?\n * var result = differenceInCalendarDays(\n *   new Date(2012, 6, 2, 0, 0),\n *   new Date(2011, 6, 2, 23, 0)\n * )\n * //=> 366\n * // How many calendar days are between\n * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?\n * var result = differenceInCalendarDays(\n *   new Date(2011, 6, 3, 0, 1),\n *   new Date(2011, 6, 2, 23, 59)\n * )\n * //=> 1\n */\n\nexport default function differenceInCalendarDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var startOfDayLeft = startOfDay(dirtyDateLeft);\n  var startOfDayRight = startOfDay(dirtyDateRight);\n  var timestampLeft = startOfDayLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfDayLeft);\n  var timestampRight = startOfDayRight.getTime() - getTimezoneOffsetInMilliseconds(startOfDayRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a day is not constant\n  // (e.g. it's different in the day of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY);\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of calendar ISO week-numbering years between the given dates.\n *\n * @description\n * Get the number of calendar ISO week-numbering years between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `differenceInCalendarISOYears` to `differenceInCalendarISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar ISO week-numbering years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar ISO week-numbering years are 1 January 2010 and 1 January 2012?\n * var result = differenceInCalendarISOWeekYears(\n *   new Date(2012, 0, 1),\n *   new Date(2010, 0, 1)\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarISOWeekYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  return getISOWeekYear(dirtyDateLeft) - getISOWeekYear(dirtyDateRight);\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name differenceInCalendarISOWeeks\n * @category ISO Week Helpers\n * @summary Get the number of calendar ISO weeks between the given dates.\n *\n * @description\n * Get the number of calendar ISO weeks between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar ISO weeks\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar ISO weeks are between 6 July 2014 and 21 July 2014?\n * var result = differenceInCalendarISOWeeks(\n *   new Date(2014, 6, 21),\n *   new Date(2014, 6, 6)\n * )\n * //=> 3\n */\n\nexport default function differenceInCalendarISOWeeks(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var startOfISOWeekLeft = startOfISOWeek(dirtyDateLeft);\n  var startOfISOWeekRight = startOfISOWeek(dirtyDateRight);\n  var timestampLeft = startOfISOWeekLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfISOWeekLeft);\n  var timestampRight = startOfISOWeekRight.getTime() - getTimezoneOffsetInMilliseconds(startOfISOWeekRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarMonths\n * @category Month Helpers\n * @summary Get the number of calendar months between the given dates.\n *\n * @description\n * Get the number of calendar months between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar months\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar months are between 31 January 2014 and 1 September 2014?\n * var result = differenceInCalendarMonths(\n *   new Date(2014, 8, 1),\n *   new Date(2014, 0, 31)\n * )\n * //=> 8\n */\n\nexport default function differenceInCalendarMonths(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();\n  var monthDiff = dateLeft.getMonth() - dateRight.getMonth();\n  return yearDiff * 12 + monthDiff;\n}","import getQuarter from '../getQuarter/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarQuarters\n * @category Quarter Helpers\n * @summary Get the number of calendar quarters between the given dates.\n *\n * @description\n * Get the number of calendar quarters between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar quarters\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar quarters are between 31 December 2013 and 2 July 2014?\n * var result = differenceInCalendarQuarters(\n *   new Date(2014, 6, 2),\n *   new Date(2013, 11, 31)\n * )\n * //=> 3\n */\n\nexport default function differenceInCalendarQuarters(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();\n  var quarterDiff = getQuarter(dateLeft) - getQuarter(dateRight);\n  return yearDiff * 4 + quarterDiff;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name differenceInCalendarWeeks\n * @category Week Helpers\n * @summary Get the number of calendar weeks between the given dates.\n *\n * @description\n * Get the number of calendar weeks between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInCalendarWeeks(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 6, 5)\n * )\n * //=> 3\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInCalendarWeeks(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 6, 5),\n *   { weekStartsOn: 1 }\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarWeeks(dirtyDateLeft, dirtyDateRight, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var startOfWeekLeft = startOfWeek(dirtyDateLeft, dirtyOptions);\n  var startOfWeekRight = startOfWeek(dirtyDateRight, dirtyOptions);\n  var timestampLeft = startOfWeekLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekLeft);\n  var timestampRight = startOfWeekRight.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarYears\n * @category Year Helpers\n * @summary Get the number of calendar years between the given dates.\n *\n * @description\n * Get the number of calendar years between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar years are between 31 December 2013 and 11 February 2015?\n * var result = differenceInCalendarYears(\n *   new Date(2015, 1, 11),\n *   new Date(2013, 11, 31)\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() - dateRight.getFullYear();\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // Like `compareAsc` but uses local time not UTC, which is needed\n// for accurate equality comparisons of UTC timestamps that end up\n// having the same representation in local time, e.g. one hour before\n// DST ends vs. the instant that DST ends.\n\nfunction compareLocalAsc(dateLeft, dateRight) {\n  var diff = dateLeft.getFullYear() - dateRight.getFullYear() || dateLeft.getMonth() - dateRight.getMonth() || dateLeft.getDate() - dateRight.getDate() || dateLeft.getHours() - dateRight.getHours() || dateLeft.getMinutes() - dateRight.getMinutes() || dateLeft.getSeconds() - dateRight.getSeconds() || dateLeft.getMilliseconds() - dateRight.getMilliseconds();\n\n  if (diff < 0) {\n    return -1;\n  } else if (diff > 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}\n/**\n * @name differenceInDays\n * @category Day Helpers\n * @summary Get the number of full days between the given dates.\n *\n * @description\n * Get the number of full day periods between two dates. Fractional days are\n * truncated towards zero.\n *\n * One \"full day\" is the distance between a local time in one day to the same\n * local time on the next or previous day. A full day can sometimes be less than\n * or more than 24 hours if a daylight savings change happens between two dates.\n *\n * To ignore DST and only measure exact 24-hour periods, use this instead:\n * `Math.floor(differenceInHours(dateLeft, dateRight)/24)|0`.\n *\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full days according to the local timezone\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full days are between\n * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?\n * var result = differenceInDays(\n *   new Date(2012, 6, 2, 0, 0),\n *   new Date(2011, 6, 2, 23, 0)\n * )\n * //=> 365\n * // How many full days are between\n * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?\n * var result = differenceInDays(\n *   new Date(2011, 6, 3, 0, 1),\n *   new Date(2011, 6, 2, 23, 59)\n * )\n * //=> 0\n * // How many full days are between\n * // 1 March 2020 0:00 and 1 June 2020 0:00 ?\n * // Note: because local time is used, the\n * // result will always be 92 days, even in\n * // time zones where DST starts and the\n * // period has only 92*24-1 hours.\n * var result = differenceInDays(\n *   new Date(2020, 5, 1),\n *   new Date(2020, 2, 1)\n * )\n//=> 92\n */\n\n\nexport default function differenceInDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareLocalAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarDays(dateLeft, dateRight));\n  dateLeft.setDate(dateLeft.getDate() - sign * difference); // Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastDayNotFull = compareLocalAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastDayNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\n/**\n * @name differenceInHours\n * @category Hour Helpers\n * @summary Get the number of hours between the given dates.\n *\n * @description\n * Get the number of hours between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of hours\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00?\n * var result = differenceInHours(\n *   new Date(2014, 6, 2, 19, 0),\n *   new Date(2014, 6, 2, 6, 50)\n * )\n * //=> 12\n */\n\nexport default function differenceInHours(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_HOUR;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarISOWeekYears from '../differenceInCalendarISOWeekYears/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport subISOWeekYears from '../subISOWeekYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of full ISO week-numbering years between the given dates.\n *\n * @description\n * Get the number of full ISO week-numbering years between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `differenceInISOYears` to `differenceInISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full ISO week-numbering years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full ISO week-numbering years are between 1 January 2010 and 1 January 2012?\n * var result = differenceInISOWeekYears(\n *   new Date(2012, 0, 1),\n *   new Date(2010, 0, 1)\n * )\n * //=> 1\n */\n\nexport default function differenceInISOWeekYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarISOWeekYears(dateLeft, dateRight));\n  dateLeft = subISOWeekYears(dateLeft, sign * difference); // Math.abs(diff in full ISO years - diff in calendar ISO years) === 1\n  // if last calendar ISO year is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastISOWeekYearNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastISOWeekYearNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInMilliseconds\n * @category Millisecond Helpers\n * @summary Get the number of milliseconds between the given dates.\n *\n * @description\n * Get the number of milliseconds between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of milliseconds\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many milliseconds are between\n * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?\n * var result = differenceInMilliseconds(\n *   new Date(2014, 6, 2, 12, 30, 21, 700),\n *   new Date(2014, 6, 2, 12, 30, 20, 600)\n * )\n * //=> 1100\n */\n\nexport default function differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getTime() - dateRight.getTime();\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_MINUTE = 60000;\n/**\n * @name differenceInMinutes\n * @category Minute Helpers\n * @summary Get the number of minutes between the given dates.\n *\n * @description\n * Get the signed number of full (rounded towards 0) minutes between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of minutes\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00?\n * var result = differenceInMinutes(\n *   new Date(2014, 6, 2, 12, 20, 0),\n *   new Date(2014, 6, 2, 12, 7, 59)\n * )\n * //=> 12\n *\n * @example\n * // How many minutes are from 10:01:59 to 10:00:00\n * var result = differenceInMinutes(\n *   new Date(2000, 0, 1, 10, 0, 0),\n *   new Date(2000, 0, 1, 10, 1, 59)\n * )\n * //=> -1\n */\n\nexport default function differenceInMinutes(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_MINUTE;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarMonths from '../differenceInCalendarMonths/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInMonths\n * @category Month Helpers\n * @summary Get the number of full months between the given dates.\n *\n * @description\n * Get the number of full months between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full months\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full months are between 31 January 2014 and 1 September 2014?\n * var result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))\n * //=> 7\n */\n\nexport default function differenceInMonths(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarMonths(dateLeft, dateRight));\n  dateLeft.setMonth(dateLeft.getMonth() - sign * difference); // Math.abs(diff in full months - diff in calendar months) === 1 if last calendar month is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastMonthNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastMonthNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import differenceInMonths from '../differenceInMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInQuarters\n * @category Quarter Helpers\n * @summary Get the number of full quarters between the given dates.\n *\n * @description\n * Get the number of full quarters between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full quarters\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full quarters are between 31 December 2013 and 2 July 2014?\n * var result = differenceInQuarters(new Date(2014, 6, 2), new Date(2013, 11, 31))\n * //=> 2\n */\n\nexport default function differenceInQuarters(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMonths(dirtyDateLeft, dirtyDateRight) / 3;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInSeconds\n * @category Second Helpers\n * @summary Get the number of seconds between the given dates.\n *\n * @description\n * Get the number of seconds between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of seconds\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many seconds are between\n * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?\n * var result = differenceInSeconds(\n *   new Date(2014, 6, 2, 12, 30, 20, 0),\n *   new Date(2014, 6, 2, 12, 30, 7, 999)\n * )\n * //=> 12\n */\n\nexport default function differenceInSeconds(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / 1000;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import differenceInDays from '../differenceInDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInWeeks\n * @category Week Helpers\n * @summary Get the number of full weeks between the given dates.\n *\n * @description\n * Get the number of full weeks between two dates. Fractional weeks are\n * truncated towards zero.\n *\n * One \"full week\" is the distance between a local time in one day to the same\n * local time 7 days earlier or later. A full week can sometimes be less than\n * or more than 7*24 hours if a daylight savings change happens between two dates.\n *\n * To ignore DST and only measure exact 7*24-hour periods, use this instead:\n * `Math.floor(differenceInHours(dateLeft, dateRight)/(7*24))|0`.\n *\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full weeks\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInWeeks(new Date(2014, 6, 20), new Date(2014, 6, 5))\n * //=> 2\n *\n * // How many full weeks are between\n * // 1 March 2020 0:00 and 6 June 2020 0:00 ?\n * // Note: because local time is used, the\n * // result will always be 8 weeks (54 days),\n * // even if DST starts and the period has\n * // only 54*24-1 hours.\n * var result = differenceInWeeks(\n *   new Date(2020, 5, 1),\n *   new Date(2020, 2, 6)\n * )\n * //=> 8\n */\n\nexport default function differenceInWeeks(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInDays(dirtyDateLeft, dirtyDateRight) / 7;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarYears from '../differenceInCalendarYears/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInYears\n * @category Year Helpers\n * @summary Get the number of full years between the given dates.\n *\n * @description\n * Get the number of full years between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full years are between 31 December 2013 and 11 February 2015?\n * var result = differenceInYears(new Date(2015, 1, 11), new Date(2013, 11, 31))\n * //=> 1\n */\n\nexport default function differenceInYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarYears(dateLeft, dateRight)); // Set both dates to a valid leap year for accurate comparison when dealing\n  // with leap days\n\n  dateLeft.setFullYear('1584');\n  dateRight.setFullYear('1584'); // Math.abs(diff in full years - diff in calendar years) === 1 if last calendar year is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastYearNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastYearNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachDayOfInterval\n * @category Interval Helpers\n * @summary Return the array of dates within the specified time interval.\n *\n * @description\n * Return the array of dates within the specified time interval.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `eachDay` to `eachDayOfInterval`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   eachDay(new Date(2014, 0, 10), new Date(2014, 0, 20))\n *\n *   // v2.0.0 onward\n *\n *   eachDayOfInterval(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) }\n *   )\n *   ```\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.step=1] - the step to increment by. The value should be more than 1.\n * @returns {Date[]} the array with starts of days from the day of the interval start to the day of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.step` must be a number greater than 1\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each day between 6 October 2014 and 10 October 2014:\n * var result = eachDayOfInterval({\n *   start: new Date(2014, 9, 6),\n *   end: new Date(2014, 9, 10)\n * })\n * //=> [\n * //   Mon Oct 06 2014 00:00:00,\n * //   Tue Oct 07 2014 00:00:00,\n * //   Wed Oct 08 2014 00:00:00,\n * //   Thu Oct 09 2014 00:00:00,\n * //   Fri Oct 10 2014 00:00:00\n * // ]\n */\n\nexport default function eachDayOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  var step = options && 'step' in options ? Number(options.step) : 1;\n  if (step < 1 || isNaN(step)) throw new RangeError('`options.step` must be a number greater than 1');\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setDate(currentDate.getDate() + step);\n    currentDate.setHours(0, 0, 0, 0);\n  }\n\n  return dates;\n}","import addHours from '../addHours/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachHourOfInterval\n * @category Interval Helpers\n * @summary Return the array of hours within the specified time interval.\n *\n * @description\n * Return the array of hours within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.step=1] - the step to increment by. The value should be more than 1.\n * @returns {Date[]} the array with starts of hours from the hour of the interval start to the hour of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.step` must be a number greater than 1\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each hour between 6 October 2014, 12:00 and 10 October 2014, 15:00\n * var result = eachHourOfInterval({\n *   start: new Date(2014, 9, 6, 12),\n *   end: new Date(2014, 9, 6, 15)\n * })\n * //=> [\n * //   Mon Oct 06 2014 12:00:00,\n * //   Mon Oct 06 2014 13:00:00,\n * //   Mon Oct 06 2014 14:00:00,\n * //   Mon Oct 06 2014 15:00:00\n * // ]\n */\n\nexport default function eachHourOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var startTime = startDate.getTime();\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startTime <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setMinutes(0, 0, 0);\n  var step = options && 'step' in options ? Number(options.step) : 1;\n  if (step < 1 || isNaN(step)) throw new RangeError('`options.step` must be a number greater than 1');\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate = addHours(currentDate, step);\n  }\n\n  return dates;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachMonthOfInterval\n * @category Interval Helpers\n * @summary Return the array of months within the specified time interval.\n *\n * @description\n * Return the array of months within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of months from the month of the interval start to the month of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each month between 6 February 2014 and 10 August 2014:\n * var result = eachMonthOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2014, 7, 10)\n * })\n * //=> [\n * //   Sat Feb 01 2014 00:00:00,\n * //   Sat Mar 01 2014 00:00:00,\n * //   Tue Apr 01 2014 00:00:00,\n * //   Thu May 01 2014 00:00:00,\n * //   Sun Jun 01 2014 00:00:00,\n * //   Tue Jul 01 2014 00:00:00,\n * //   Fri Aug 01 2014 00:00:00\n * // ]\n */\n\nexport default function eachMonthOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  currentDate.setDate(1);\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setMonth(currentDate.getMonth() + 1);\n  }\n\n  return dates;\n}","import addQuarters from '../addQuarters/index.js';\nimport startOfQuarter from '../startOfQuarter/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachQuarterOfInterval\n * @category Interval Helpers\n * @summary Return the array of quarters within the specified time interval.\n *\n * @description\n * Return the array of quarters within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of quarters from the quarter of the interval start to the quarter of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each quarter within interval 6 February 2014 - 10 August 2014:\n * var result = eachQuarterOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2014, 7, 10)\n * })\n * //=> [\n * //   Wed Jan 01 2014 00:00:00,\n * //   Tue Apr 01 2014 00:00:00,\n * //   Tue Jul 01 2014 00:00:00,\n * // ]\n */\n\nexport default function eachQuarterOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var startDateQuarter = startOfQuarter(startDate);\n  var endDateQuarter = startOfQuarter(endDate);\n  endTime = endDateQuarter.getTime();\n  var quarters = [];\n  var currentQuarter = startDateQuarter;\n\n  while (currentQuarter.getTime() <= endTime) {\n    quarters.push(toDate(currentQuarter));\n    currentQuarter = addQuarters(currentQuarter, 1);\n  }\n\n  return quarters;\n}","import addWeeks from '../addWeeks/index.js';\nimport startOfWeek from '../startOfWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekOfInterval\n * @category Interval Helpers\n * @summary Return the array of weeks within the specified time interval.\n *\n * @description\n * Return the array of weeks within the specified time interval.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date[]} the array with starts of weeks from the week of the interval start to the week of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be 0, 1, ..., 6\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each week within interval 6 October 2014 - 23 November 2014:\n * var result = eachWeekOfInterval({\n *   start: new Date(2014, 9, 6),\n *   end: new Date(2014, 10, 23)\n * })\n * //=> [\n * //   Sun Oct 05 2014 00:00:00,\n * //   Sun Oct 12 2014 00:00:00,\n * //   Sun Oct 19 2014 00:00:00,\n * //   Sun Oct 26 2014 00:00:00,\n * //   Sun Nov 02 2014 00:00:00,\n * //   Sun Nov 09 2014 00:00:00,\n * //   Sun Nov 16 2014 00:00:00,\n * //   Sun Nov 23 2014 00:00:00\n * // ]\n */\n\nexport default function eachWeekOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var startDateWeek = startOfWeek(startDate, options);\n  var endDateWeek = startOfWeek(endDate, options); // Some timezones switch DST at midnight, making start of day unreliable in these timezones, 3pm is a safe bet\n\n  startDateWeek.setHours(15);\n  endDateWeek.setHours(15);\n  endTime = endDateWeek.getTime();\n  var weeks = [];\n  var currentWeek = startDateWeek;\n\n  while (currentWeek.getTime() <= endTime) {\n    currentWeek.setHours(0);\n    weeks.push(toDate(currentWeek));\n    currentWeek = addWeeks(currentWeek, 1);\n    currentWeek.setHours(15);\n  }\n\n  return weeks;\n}","import eachDayOfInterval from '../eachDayOfInterval/index.js';\nimport isSunday from '../isSunday/index.js';\nimport isWeekend from '../isWeekend/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfInterval\n * @category Interval Helpers\n * @summary List all the Saturdays and Sundays in the given date interval.\n *\n * @description\n * Get all the Saturdays and Sundays in the given date interval.\n *\n * @param {Interval} interval - the given interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Lists all Saturdays and Sundays in the given date interval\n * var result = eachWeekendOfInterval({\n *   start: new Date(2018, 8, 17),\n *   end: new Date(2018, 8, 30)\n * })\n * //=> [\n * //   Sat Sep 22 2018 00:00:00,\n * //   Sun Sep 23 2018 00:00:00,\n * //   Sat Sep 29 2018 00:00:00,\n * //   Sun Sep 30 2018 00:00:00\n * // ]\n */\n\nexport default function eachWeekendOfInterval(interval) {\n  requiredArgs(1, arguments);\n  var dateInterval = eachDayOfInterval(interval);\n  var weekends = [];\n  var index = 0;\n\n  while (index < dateInterval.length) {\n    var date = dateInterval[index++];\n\n    if (isWeekend(date)) {\n      weekends.push(date);\n      if (isSunday(date)) index = index + 5;\n    }\n  }\n\n  return weekends;\n}","import eachWeekendOfInterval from '../eachWeekendOfInterval/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport endOfMonth from '../endOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfMonth\n * @category Month Helpers\n * @summary List all the Saturdays and Sundays in the given month.\n *\n * @description\n * Get all the Saturdays and Sundays in the given month.\n *\n * @param {Date|Number} date - the given month\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The passed date is invalid\n *\n * @example\n * // Lists all Saturdays and Sundays in the given month\n * var result = eachWeekendOfMonth(new Date(2022, 1, 1))\n * //=> [\n * //   Sat Feb 05 2022 00:00:00,\n * //   Sun Feb 06 2022 00:00:00,\n * //   Sat Feb 12 2022 00:00:00,\n * //   Sun Feb 13 2022 00:00:00,\n * //   Sat Feb 19 2022 00:00:00,\n * //   Sun Feb 20 2022 00:00:00,\n * //   Sat Feb 26 2022 00:00:00,\n * //   Sun Feb 27 2022 00:00:00\n * // ]\n */\n\nexport default function eachWeekendOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var startDate = startOfMonth(dirtyDate);\n  if (isNaN(startDate)) throw new RangeError('The passed date is invalid');\n  var endDate = endOfMonth(dirtyDate);\n  return eachWeekendOfInterval({\n    start: startDate,\n    end: endDate\n  });\n}","import eachWeekendOfInterval from '../eachWeekendOfInterval/index.js';\nimport startOfYear from '../startOfYear/index.js';\nimport endOfYear from '../endOfYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfYear\n * @category Year Helpers\n * @summary List all the Saturdays and Sundays in the year.\n *\n * @description\n * Get all the Saturdays and Sundays in the year.\n *\n * @param {Date|Number} date - the given year\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The passed date is invalid\n *\n * @example\n * // Lists all Saturdays and Sundays in the year\n * var result = eachWeekendOfYear(new Date(2020, 1, 1))\n * //=> [\n * //   Sat Jan 03 2020 00:00:00,\n * //   Sun Jan 04 2020 00:00:00,\n * //   ...\n * //   Sun Dec 27 2020 00:00:00\n * // ]\n * ]\n */\n\nexport default function eachWeekendOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var startDate = startOfYear(dirtyDate);\n  if (isNaN(startDate)) throw new RangeError('The passed date is invalid');\n  var endDate = endOfYear(dirtyDate);\n  return eachWeekendOfInterval({\n    start: startDate,\n    end: endDate\n  });\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachYearOfInterval\n * @category Interval Helpers\n * @summary Return the array of yearly timestamps within the specified time interval.\n *\n * @description\n * Return the array of yearly timestamps within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of yearly timestamps from the month of the interval start to the month of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each year between 6 February 2014 and 10 August 2017:\n * var result = eachYearOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2017, 7, 10)\n * })\n * //=> [\n * //   Wed Jan 01 2014 00:00:00,\n * //   Thu Jan 01 2015 00:00:00,\n * //   Fri Jan 01 2016 00:00:00,\n * //   Sun Jan 01 2017 00:00:00\n * // ]\n */\n\nexport default function eachYearOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  currentDate.setMonth(0, 1);\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setFullYear(currentDate.getFullYear() + 1);\n  }\n\n  return dates;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfDay\n * @category Day Helpers\n * @summary Return the end of a day for the given date.\n *\n * @description\n * Return the end of a day for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a day\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a day for 2 September 2014 11:55:00:\n * var result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 23:59:59.999\n */\n\nexport default function endOfDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfDecade\n * @category Decade Helpers\n * @summary Return the end of a decade for the given date.\n *\n * @description\n * Return the end of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a decade\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // The end of a decade for 12 May 1984 00:00:00:\n * var result = endOfDecade(new Date(1984, 4, 12, 00, 00, 00))\n * //=> Dec 31 1989 23:59:59.999\n */\n\nexport default function endOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = 9 + Math.floor(year / 10) * 10;\n  date.setFullYear(decade, 11, 31);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfHour\n * @category Hour Helpers\n * @summary Return the end of an hour for the given date.\n *\n * @description\n * Return the end of an hour for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an hour for 2 September 2014 11:55:00:\n * var result = endOfHour(new Date(2014, 8, 2, 11, 55))\n * //=> Tue Sep 02 2014 11:59:59.999\n */\n\nexport default function endOfHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMinutes(59, 59, 999);\n  return date;\n}","import endOfWeek from '../endOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the end of an ISO week for the given date.\n *\n * @description\n * Return the end of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an ISO week for 2 September 2014 11:55:00:\n * var result = endOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Sep 07 2014 23:59:59.999\n */\n\nexport default function endOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return endOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the end of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the end of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `endOfISOYear` to `endOfISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an ISO week-numbering year for 2 July 2005:\n * var result = endOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Sun Jan 01 2006 23:59:59.999\n */\n\nexport default function endOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuaryOfNextYear);\n  date.setMilliseconds(date.getMilliseconds() - 1);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfMinute\n * @category Minute Helpers\n * @summary Return the end of a minute for the given date.\n *\n * @description\n * Return the end of a minute for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a minute for 1 December 2014 22:15:45.400:\n * var result = endOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:59.999\n */\n\nexport default function endOfMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setSeconds(59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfMonth\n * @category Month Helpers\n * @summary Return the end of a month for the given date.\n *\n * @description\n * Return the end of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a month for 2 September 2014 11:55:00:\n * var result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\n\nexport default function endOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  date.setFullYear(date.getFullYear(), month + 1, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfQuarter\n * @category Quarter Helpers\n * @summary Return the end of a year quarter for the given date.\n *\n * @description\n * Return the end of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a quarter for 2 September 2014 11:55:00:\n * var result = endOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\n\nexport default function endOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3 + 3;\n  date.setMonth(month, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfSecond\n * @category Second Helpers\n * @summary Return the end of a second for the given date.\n *\n * @description\n * Return the end of a second for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a second for 1 December 2014 22:15:45.400:\n * var result = endOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:45.999\n */\n\nexport default function endOfSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMilliseconds(999);\n  return date;\n}","import endOfDay from '../endOfDay/index.js';\n/**\n * @name endOfToday\n * @category Day Helpers\n * @summary Return the end of today.\n * @pure false\n *\n * @description\n * Return the end of today.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of today\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfToday()\n * //=> Mon Oct 6 2014 23:59:59.999\n */\n\nexport default function endOfToday() {\n  return endOfDay(Date.now());\n}","/**\n * @name endOfTomorrow\n * @category Day Helpers\n * @summary Return the end of tomorrow.\n * @pure false\n *\n * @description\n * Return the end of tomorrow.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of tomorrow\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfTomorrow()\n * //=> Tue Oct 7 2014 23:59:59.999\n */\nexport default function endOfTomorrow() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day + 1);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfWeek\n * @category Week Helpers\n * @summary Return the end of a week for the given date.\n *\n * @description\n * Return the end of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the end of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The end of a week for 2 September 2014 11:55:00:\n * var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sat Sep 06 2014 23:59:59.999\n *\n * @example\n * // If the week starts on Monday, the end of the week for 2 September 2014 11:55:00:\n * var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 23:59:59.999\n */\n\nexport default function endOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);\n  date.setDate(date.getDate() + diff);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfYear\n * @category Year Helpers\n * @summary Return the end of a year for the given date.\n *\n * @description\n * Return the end of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a year for 2 September 2014 11:55:00:\n * var result = endOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Dec 31 2014 23:59:59.999\n */\n\nexport default function endOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  date.setFullYear(year + 1, 0, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","/**\n * @name endOfYesterday\n * @category Day Helpers\n * @summary Return the end of yesterday.\n * @pure false\n *\n * @description\n * Return the end of yesterday.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of yesterday\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfYesterday()\n * //=> Sun Oct 5 2014 23:59:59.999\n */\nexport default function endOfYesterday() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day - 1);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import isValid from '../isValid/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport formatters from '../_lib/format/formatters/index.js';\nimport longFormatters from '../_lib/format/longFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport { isProtectedDayOfYearToken, isProtectedWeekYearToken, throwProtectedError } from '../_lib/protectedTokens/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n//   (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\n\nvar longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name format\n * @category Common Helpers\n * @summary Format the date.\n *\n * @description\n * Return the formatted date string in the given format. The result may vary by locale.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n * (see the last example)\n *\n * Format of the string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 7 below the table).\n *\n * Accepted patterns:\n * | Unit                            | Pattern | Result examples                   | Notes |\n * |---------------------------------|---------|-----------------------------------|-------|\n * | Era                             | G..GGG  | AD, BC                            |       |\n * |                                 | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 | GGGGG   | A, B                              |       |\n * | Calendar year                   | y       | 44, 1, 1900, 2017                 | 5     |\n * |                                 | yo      | 44th, 1st, 0th, 17th              | 5,7   |\n * |                                 | yy      | 44, 01, 00, 17                    | 5     |\n * |                                 | yyy     | 044, 001, 1900, 2017              | 5     |\n * |                                 | yyyy    | 0044, 0001, 1900, 2017            | 5     |\n * |                                 | yyyyy   | ...                               | 3,5   |\n * | Local week-numbering year       | Y       | 44, 1, 1900, 2017                 | 5     |\n * |                                 | Yo      | 44th, 1st, 1900th, 2017th         | 5,7   |\n * |                                 | YY      | 44, 01, 00, 17                    | 5,8   |\n * |                                 | YYY     | 044, 001, 1900, 2017              | 5     |\n * |                                 | YYYY    | 0044, 0001, 1900, 2017            | 5,8   |\n * |                                 | YYYYY   | ...                               | 3,5   |\n * | ISO week-numbering year         | R       | -43, 0, 1, 1900, 2017             | 5,7   |\n * |                                 | RR      | -43, 00, 01, 1900, 2017           | 5,7   |\n * |                                 | RRR     | -043, 000, 001, 1900, 2017        | 5,7   |\n * |                                 | RRRR    | -0043, 0000, 0001, 1900, 2017     | 5,7   |\n * |                                 | RRRRR   | ...                               | 3,5,7 |\n * | Extended year                   | u       | -43, 0, 1, 1900, 2017             | 5     |\n * |                                 | uu      | -43, 01, 1900, 2017               | 5     |\n * |                                 | uuu     | -043, 001, 1900, 2017             | 5     |\n * |                                 | uuuu    | -0043, 0001, 1900, 2017           | 5     |\n * |                                 | uuuuu   | ...                               | 3,5   |\n * | Quarter (formatting)            | Q       | 1, 2, 3, 4                        |       |\n * |                                 | Qo      | 1st, 2nd, 3rd, 4th                | 7     |\n * |                                 | QQ      | 01, 02, 03, 04                    |       |\n * |                                 | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | q       | 1, 2, 3, 4                        |       |\n * |                                 | qo      | 1st, 2nd, 3rd, 4th                | 7     |\n * |                                 | qq      | 01, 02, 03, 04                    |       |\n * |                                 | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 | qqqqq   | 1, 2, 3, 4                        | 4     |\n * | Month (formatting)              | M       | 1, 2, ..., 12                     |       |\n * |                                 | Mo      | 1st, 2nd, ..., 12th               | 7     |\n * |                                 | MM      | 01, 02, ..., 12                   |       |\n * |                                 | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 | MMMM    | January, February, ..., December  | 2     |\n * |                                 | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | L       | 1, 2, ..., 12                     |       |\n * |                                 | Lo      | 1st, 2nd, ..., 12th               | 7     |\n * |                                 | LL      | 01, 02, ..., 12                   |       |\n * |                                 | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 | LLLL    | January, February, ..., December  | 2     |\n * |                                 | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | w       | 1, 2, ..., 53                     |       |\n * |                                 | wo      | 1st, 2nd, ..., 53th               | 7     |\n * |                                 | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | I       | 1, 2, ..., 53                     | 7     |\n * |                                 | Io      | 1st, 2nd, ..., 53th               | 7     |\n * |                                 | II      | 01, 02, ..., 53                   | 7     |\n * | Day of month                    | d       | 1, 2, ..., 31                     |       |\n * |                                 | do      | 1st, 2nd, ..., 31st               | 7     |\n * |                                 | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     | D       | 1, 2, ..., 365, 366               | 9     |\n * |                                 | Do      | 1st, 2nd, ..., 365th, 366th       | 7     |\n * |                                 | DD      | 01, 02, ..., 365, 366             | 9     |\n * |                                 | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 | DDDD    | ...                               | 3     |\n * | Day of week (formatting)        | E..EEE  | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    | i       | 1, 2, 3, ..., 7                   | 7     |\n * |                                 | io      | 1st, 2nd, ..., 7th                | 7     |\n * |                                 | ii      | 01, 02, ..., 07                   | 7     |\n * |                                 | iii     | Mon, Tue, Wed, ..., Sun           | 7     |\n * |                                 | iiii    | Monday, Tuesday, ..., Sunday      | 2,7   |\n * |                                 | iiiii   | M, T, W, T, F, S, S               | 7     |\n * |                                 | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 7     |\n * | Local day of week (formatting)  | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 | eo      | 2nd, 3rd, ..., 1st                | 7     |\n * |                                 | ee      | 02, 03, ..., 01                   |       |\n * |                                 | eee     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 | co      | 2nd, 3rd, ..., 1st                | 7     |\n * |                                 | cc      | 02, 03, ..., 01                   |       |\n * |                                 | ccc     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          | a..aaa  | AM, PM                            |       |\n * |                                 | aaaa    | a.m., p.m.                        | 2     |\n * |                                 | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             | B..BBB  | at night, in the morning, ...     |       |\n * |                                 | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 | ho      | 1st, 2nd, ..., 11th, 12th         | 7     |\n * |                                 | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 | Ho      | 0th, 1st, 2nd, ..., 23rd          | 7     |\n * |                                 | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 | Ko      | 1st, 2nd, ..., 11th, 0th          | 7     |\n * |                                 | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 | ko      | 24th, 1st, 2nd, ..., 23rd         | 7     |\n * |                                 | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          | m       | 0, 1, ..., 59                     |       |\n * |                                 | mo      | 0th, 1st, ..., 59th               | 7     |\n * |                                 | mm      | 00, 01, ..., 59                   |       |\n * | Second                          | s       | 0, 1, ..., 59                     |       |\n * |                                 | so      | 0th, 1st, ..., 59th               | 7     |\n * |                                 | ss      | 00, 01, ..., 59                   |       |\n * | Fraction of second              | S       | 0, 1, ..., 9                      |       |\n * |                                 | SS      | 00, 01, ..., 99                   |       |\n * |                                 | SSS     | 000, 0001, ..., 999               |       |\n * |                                 | SSSS    | ...                               | 3     |\n * | Timezone (ISO-8601 w/ Z)        | X       | -08, +0530, Z                     |       |\n * |                                 | XX      | -0800, +0530, Z                   |       |\n * |                                 | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       | x       | -08, +0530, +00                   |       |\n * |                                 | xx      | -0800, +0530, +0000               |       |\n * |                                 | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Timezone (GMT)                  | O...OOO | GMT-8, GMT+5:30, GMT+0            |       |\n * |                                 | OOOO    | GMT-08:00, GMT+05:30, GMT+00:00   | 2     |\n * | Timezone (specific non-locat.)  | z...zzz | GMT-8, GMT+5:30, GMT+0            | 6     |\n * |                                 | zzzz    | GMT-08:00, GMT+05:30, GMT+00:00   | 2,6   |\n * | Seconds timestamp               | t       | 512969520                         | 7     |\n * |                                 | tt      | ...                               | 3,7   |\n * | Milliseconds timestamp          | T       | 512969520900                      | 7     |\n * |                                 | TT      | ...                               | 3,7   |\n * | Long localized date             | P       | 05/29/1453                        | 7     |\n * |                                 | PP      | May 29, 1453                      | 7     |\n * |                                 | PPP     | May 29th, 1453                    | 7     |\n * |                                 | PPPP    | Sunday, May 29th, 1453            | 2,7   |\n * | Long localized time             | p       | 12:00 AM                          | 7     |\n * |                                 | pp      | 12:00:00 AM                       | 7     |\n * |                                 | ppp     | 12:00:00 AM GMT+2                 | 7     |\n * |                                 | pppp    | 12:00:00 AM GMT+02:00             | 2,7   |\n * | Combination of date and time    | Pp      | 05/29/1453, 12:00 AM              | 7     |\n * |                                 | PPpp    | May 29, 1453, 12:00:00 AM         | 7     |\n * |                                 | PPPppp  | May 29th, 1453 at ...             | 7     |\n * |                                 | PPPPpppp| Sunday, May 29th, 1453 at ...     | 2,7   |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)\n *    the output will be the same as default pattern for this unit, usually\n *    the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units\n *    are marked with \"2\" in the last column of the table.\n *\n *    `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`\n *\n * 3. Some patterns could be unlimited length (such as `yyyyyyyy`).\n *    The output will be padded with zeros to match the length of the pattern.\n *\n *    `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`\n *\n * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 5. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` always returns the last two digits of a year,\n *    while `uu` pads single digit years to 2 characters and returns other years unchanged:\n *\n *    | Year | `yy` | `uu` |\n *    |------|------|------|\n *    | 1    |   01 |   01 |\n *    | 14   |   14 |   14 |\n *    | 376  |   76 |  376 |\n *    | 1453 |   53 | 1453 |\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [getISOWeekYear]{@link https://date-fns.org/docs/getISOWeekYear}\n *    and [getWeekYear]{@link https://date-fns.org/docs/getWeekYear}).\n *\n * 6. Specific non-location timezones are currently unavailable in `date-fns`,\n *    so right now these tokens fall back to GMT timezones.\n *\n * 7. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `t`: seconds timestamp\n *    - `T`: milliseconds timestamp\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 9. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The second argument is now required for the sake of explicitness.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   format(new Date(2016, 0, 1))\n *\n *   // v2.0.0 onward\n *   format(new Date(2016, 0, 1), \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\")\n *   ```\n *\n * - New format string API for `format` function\n *   which is based on [Unicode Technical Standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).\n *   See [this post](https://blog.date-fns.org/post/unicode-tokens-in-date-fns-v2-sreatyki91jg) for more details.\n *\n * - Characters are now escaped using single quote symbols (`'`) instead of square brackets.\n *\n * @param {Date|Number} date - the original date\n * @param {String} format - the string of tokens\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {Number} [options.firstWeekContainsDate=1] - the day of January, which is\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {String} the formatted date string\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `localize` property\n * @throws {RangeError} `options.locale` must contain `formatLong` property\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Represent 11 February 2014 in middle-endian format:\n * var result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')\n * //=> '02/11/2014'\n *\n * @example\n * // Represent 2 July 2014 in Esperanto:\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = format(new Date(2014, 6, 2), \"do 'de' MMMM yyyy\", {\n *   locale: eoLocale\n * })\n * //=> '2-a de julio 2014'\n *\n * @example\n * // Escape string by single quote characters:\n * var result = format(new Date(2014, 6, 2, 15), \"h 'o''clock'\")\n * //=> \"3 o'clock\"\n */\n\nexport default function format(dirtyDate, dirtyFormatStr, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var formatStr = String(dirtyFormatStr);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n  var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  if (!locale.localize) {\n    throw new RangeError('locale must contain localize property');\n  }\n\n  if (!locale.formatLong) {\n    throw new RangeError('locale must contain formatLong property');\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376\n\n\n  var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);\n  var utcDate = subMilliseconds(originalDate, timezoneOffset);\n  var formatterOptions = {\n    firstWeekContainsDate: firstWeekContainsDate,\n    weekStartsOn: weekStartsOn,\n    locale: locale,\n    _originalDate: originalDate\n  };\n  var result = formatStr.match(longFormattingTokensRegExp).map(function (substring) {\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === 'p' || firstCharacter === 'P') {\n      var longFormatter = longFormatters[firstCharacter];\n      return longFormatter(substring, locale.formatLong, formatterOptions);\n    }\n\n    return substring;\n  }).join('').match(formattingTokensRegExp).map(function (substring) {\n    // Replace two single quote characters with one single quote character\n    if (substring === \"''\") {\n      return \"'\";\n    }\n\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === \"'\") {\n      return cleanEscapedString(substring);\n    }\n\n    var formatter = formatters[firstCharacter];\n\n    if (formatter) {\n      if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(substring)) {\n        throwProtectedError(substring, dirtyFormatStr, dirtyDate);\n      }\n\n      if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(substring)) {\n        throwProtectedError(substring, dirtyFormatStr, dirtyDate);\n      }\n\n      return formatter(utcDate, substring, locale.localize, formatterOptions);\n    }\n\n    if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n      throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n    }\n\n    return substring;\n  }).join('');\n  return result;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","import compareAsc from '../compareAsc/index.js';\nimport differenceInMonths from '../differenceInMonths/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport toDate from '../toDate/index.js';\nimport cloneObject from '../_lib/cloneObject/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MINUTES_IN_DAY = 1440;\nvar MINUTES_IN_ALMOST_TWO_DAYS = 2520;\nvar MINUTES_IN_MONTH = 43200;\nvar MINUTES_IN_TWO_MONTHS = 86400;\n/**\n * @name formatDistance\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words.\n *\n * | Distance between dates                                            | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance between dates | Result               |\n * |------------------------|----------------------|\n * | 0 secs ... 5 secs      | less than 5 seconds  |\n * | 5 secs ... 10 secs     | less than 10 seconds |\n * | 10 secs ... 20 secs    | less than 20 seconds |\n * | 20 secs ... 40 secs    | half a minute        |\n * | 40 secs ... 60 secs    | less than a minute   |\n * | 60 secs ... 90 secs    | 1 minute             |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWords ` to `formatDistance`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n * - The order of arguments is swapped to make the function\n *   consistent with `differenceIn...` functions.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWords(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 11, 32, 0),\n *     { addSuffix: true }\n *   ) //=> 'in about 1 hour'\n *\n *   // v2.0.0 onward\n *\n *   formatDistance(\n *     new Date(1986, 3, 4, 11, 32, 0),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { addSuffix: true }\n *   ) //=> 'in about 1 hour'\n *   ```\n *\n * @param {Date|Number} date - the date\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * var result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00, including seconds?\n * var result = formatDistance(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0),\n *   { includeSeconds: true }\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * var result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> 'about 1 year ago'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> 'pli ol 1 jaro'\n */\n\nexport default function formatDistance(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.formatDistance) {\n    throw new RangeError('locale must contain formatDistance property');\n  }\n\n  var comparison = compareAsc(dirtyDate, dirtyBaseDate);\n\n  if (isNaN(comparison)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var localizeOptions = cloneObject(options);\n  localizeOptions.addSuffix = Boolean(options.addSuffix);\n  localizeOptions.comparison = comparison;\n  var dateLeft;\n  var dateRight;\n\n  if (comparison > 0) {\n    dateLeft = toDate(dirtyBaseDate);\n    dateRight = toDate(dirtyDate);\n  } else {\n    dateLeft = toDate(dirtyDate);\n    dateRight = toDate(dirtyBaseDate);\n  }\n\n  var seconds = differenceInSeconds(dateRight, dateLeft);\n  var offsetInSeconds = (getTimezoneOffsetInMilliseconds(dateRight) - getTimezoneOffsetInMilliseconds(dateLeft)) / 1000;\n  var minutes = Math.round((seconds - offsetInSeconds) / 60);\n  var months; // 0 up to 2 mins\n\n  if (minutes < 2) {\n    if (options.includeSeconds) {\n      if (seconds < 5) {\n        return locale.formatDistance('lessThanXSeconds', 5, localizeOptions);\n      } else if (seconds < 10) {\n        return locale.formatDistance('lessThanXSeconds', 10, localizeOptions);\n      } else if (seconds < 20) {\n        return locale.formatDistance('lessThanXSeconds', 20, localizeOptions);\n      } else if (seconds < 40) {\n        return locale.formatDistance('halfAMinute', null, localizeOptions);\n      } else if (seconds < 60) {\n        return locale.formatDistance('lessThanXMinutes', 1, localizeOptions);\n      } else {\n        return locale.formatDistance('xMinutes', 1, localizeOptions);\n      }\n    } else {\n      if (minutes === 0) {\n        return locale.formatDistance('lessThanXMinutes', 1, localizeOptions);\n      } else {\n        return locale.formatDistance('xMinutes', minutes, localizeOptions);\n      }\n    } // 2 mins up to 0.75 hrs\n\n  } else if (minutes < 45) {\n    return locale.formatDistance('xMinutes', minutes, localizeOptions); // 0.75 hrs up to 1.5 hrs\n  } else if (minutes < 90) {\n    return locale.formatDistance('aboutXHours', 1, localizeOptions); // 1.5 hrs up to 24 hrs\n  } else if (minutes < MINUTES_IN_DAY) {\n    var hours = Math.round(minutes / 60);\n    return locale.formatDistance('aboutXHours', hours, localizeOptions); // 1 day up to 1.75 days\n  } else if (minutes < MINUTES_IN_ALMOST_TWO_DAYS) {\n    return locale.formatDistance('xDays', 1, localizeOptions); // 1.75 days up to 30 days\n  } else if (minutes < MINUTES_IN_MONTH) {\n    var days = Math.round(minutes / MINUTES_IN_DAY);\n    return locale.formatDistance('xDays', days, localizeOptions); // 1 month up to 2 months\n  } else if (minutes < MINUTES_IN_TWO_MONTHS) {\n    months = Math.round(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('aboutXMonths', months, localizeOptions);\n  }\n\n  months = differenceInMonths(dateRight, dateLeft); // 2 months up to 12 months\n\n  if (months < 12) {\n    var nearestMonth = Math.round(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('xMonths', nearestMonth, localizeOptions); // 1 year up to max Date\n  } else {\n    var monthsSinceStartOfYear = months % 12;\n    var years = Math.floor(months / 12); // N years up to 1 years 3 months\n\n    if (monthsSinceStartOfYear < 3) {\n      return locale.formatDistance('aboutXYears', years, localizeOptions); // N years 3 months up to N years 9 months\n    } else if (monthsSinceStartOfYear < 9) {\n      return locale.formatDistance('overXYears', years, localizeOptions); // N years 9 months up to N year 12 months\n    } else {\n      return locale.formatDistance('almostXYears', years + 1, localizeOptions);\n    }\n  }\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport toDate from '../toDate/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport cloneObject from '../_lib/cloneObject/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MINUTES_IN_DAY = 1440;\nvar MINUTES_IN_MONTH = 43200;\nvar MINUTES_IN_YEAR = 525600;\n/**\n * @name formatDistanceStrict\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words, using strict units.\n * This is like `formatDistance`, but does not use helpers like 'almost', 'over',\n * 'less than' and the like.\n *\n * | Distance between dates | Result              |\n * |------------------------|---------------------|\n * | 0 ... 59 secs          | [0..59] seconds     |\n * | 1 ... 59 mins          | [1..59] minutes     |\n * | 1 ... 23 hrs           | [1..23] hours       |\n * | 1 ... 29 days          | [1..29] days        |\n * | 1 ... 11 months        | [1..11] months      |\n * | 1 ... N years          | [1..N]  years       |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWordsStrict` to `formatDistanceStrict`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n * - The order of arguments is swapped to make the function\n *   consistent with `differenceIn...` functions.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(2015, 0, 2),\n *     new Date(2014, 6, 2)\n *   ) //=> '6 months'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(2014, 6, 2),\n *     new Date(2015, 0, 2)\n *   ) //=> '6 months'\n *   ```\n *\n * - `partialMethod` option is renamed to `roundingMethod`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     { partialMethod: 'ceil' }\n *   ) //=> '2 minutes'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { roundingMethod: 'ceil' }\n *   ) //=> '2 minutes'\n *   ```\n *\n * - If `roundingMethod` is not specified, it now defaults to `round` instead of `floor`.\n *\n * - `unit` option now accepts one of the strings:\n *   'second', 'minute', 'hour', 'day', 'month' or 'year' instead of 's', 'm', 'h', 'd', 'M' or 'Y'\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     { unit: 'm' }\n *   )\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { unit: 'minute' }\n *   )\n *   ```\n *\n * @param {Date|Number} date - the date\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {'second'|'minute'|'hour'|'day'|'month'|'year'} [options.unit] - if specified, will force a unit\n * @param {'floor'|'ceil'|'round'} [options.roundingMethod='round'] - which way to round partial units\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.roundingMethod` must be 'floor', 'ceil' or 'round'\n * @throws {RangeError} `options.unit` must be 'second', 'minute', 'hour', 'day', 'month' or 'year'\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * var result = formatDistanceStrict(new Date(2014, 6, 2), new Date(2015, 0, 2))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00?\n * var result = formatDistanceStrict(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0)\n * )\n * //=> '15 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * var result = formatDistanceStrict(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> '1 year ago'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, in minutes?\n * var result = formatDistanceStrict(new Date(2016, 0, 1), new Date(2015, 0, 1), {\n *   unit: 'minute'\n * })\n * //=> '525600 minutes'\n *\n * @example\n * // What is the distance from 1 January 2015\n * // to 28 January 2015, in months, rounded up?\n * var result = formatDistanceStrict(new Date(2015, 0, 28), new Date(2015, 0, 1), {\n *   unit: 'month',\n *   roundingMethod: 'ceil'\n * })\n * //=> '1 month'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = formatDistanceStrict(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> '1 jaro'\n */\n\nexport default function formatDistanceStrict(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.formatDistance) {\n    throw new RangeError('locale must contain localize.formatDistance property');\n  }\n\n  var comparison = compareAsc(dirtyDate, dirtyBaseDate);\n\n  if (isNaN(comparison)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var localizeOptions = cloneObject(options);\n  localizeOptions.addSuffix = Boolean(options.addSuffix);\n  localizeOptions.comparison = comparison;\n  var dateLeft;\n  var dateRight;\n\n  if (comparison > 0) {\n    dateLeft = toDate(dirtyBaseDate);\n    dateRight = toDate(dirtyDate);\n  } else {\n    dateLeft = toDate(dirtyDate);\n    dateRight = toDate(dirtyBaseDate);\n  }\n\n  var roundingMethod = options.roundingMethod == null ? 'round' : String(options.roundingMethod);\n  var roundingMethodFn;\n\n  if (roundingMethod === 'floor') {\n    roundingMethodFn = Math.floor;\n  } else if (roundingMethod === 'ceil') {\n    roundingMethodFn = Math.ceil;\n  } else if (roundingMethod === 'round') {\n    roundingMethodFn = Math.round;\n  } else {\n    throw new RangeError(\"roundingMethod must be 'floor', 'ceil' or 'round'\");\n  }\n\n  var seconds = differenceInSeconds(dateRight, dateLeft);\n  var offsetInSeconds = (getTimezoneOffsetInMilliseconds(dateRight) - getTimezoneOffsetInMilliseconds(dateLeft)) / 1000;\n  var minutes = roundingMethodFn((seconds - offsetInSeconds) / 60);\n  var unit;\n\n  if (options.unit == null) {\n    if (minutes < 1) {\n      unit = 'second';\n    } else if (minutes < 60) {\n      unit = 'minute';\n    } else if (minutes < MINUTES_IN_DAY) {\n      unit = 'hour';\n    } else if (minutes < MINUTES_IN_MONTH) {\n      unit = 'day';\n    } else if (minutes < MINUTES_IN_YEAR) {\n      unit = 'month';\n    } else {\n      unit = 'year';\n    }\n  } else {\n    unit = String(options.unit);\n  } // 0 up to 60 seconds\n\n\n  if (unit === 'second') {\n    return locale.formatDistance('xSeconds', seconds, localizeOptions); // 1 up to 60 mins\n  } else if (unit === 'minute') {\n    return locale.formatDistance('xMinutes', minutes, localizeOptions); // 1 up to 24 hours\n  } else if (unit === 'hour') {\n    var hours = roundingMethodFn(minutes / 60);\n    return locale.formatDistance('xHours', hours, localizeOptions); // 1 up to 30 days\n  } else if (unit === 'day') {\n    var days = roundingMethodFn(minutes / MINUTES_IN_DAY);\n    return locale.formatDistance('xDays', days, localizeOptions); // 1 up to 12 months\n  } else if (unit === 'month') {\n    var months = roundingMethodFn(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('xMonths', months, localizeOptions); // 1 year up to max Date\n  } else if (unit === 'year') {\n    var years = roundingMethodFn(minutes / MINUTES_IN_YEAR);\n    return locale.formatDistance('xYears', years, localizeOptions);\n  }\n\n  throw new RangeError(\"unit must be 'second', 'minute', 'hour', 'day', 'month' or 'year'\");\n}","import distanceInWords from '../formatDistance/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatDistanceToNow\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given date and now in words.\n *\n * | Distance to now                                                   | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance to now     | Result               |\n * |---------------------|----------------------|\n * | 0 secs ... 5 secs   | less than 5 seconds  |\n * | 5 secs ... 10 secs  | less than 10 seconds |\n * | 10 secs ... 20 secs | less than 20 seconds |\n * | 20 secs ... 40 secs | half a minute        |\n * | 40 secs ... 60 secs | less than a minute   |\n * | 60 secs ... 90 secs | 1 minute             |\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWordsToNow ` to `formatDistanceToNow`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsToNow(new Date(2014, 6, 2), { addSuffix: true })\n *   //=> 'in 6 months'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceToNow(new Date(2014, 6, 2), { addSuffix: true })\n *   //=> 'in 6 months'\n *   ```\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - the object with options\n * @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed\n * @param {Boolean} [options.addSuffix=false] - result specifies if now is earlier or later than the passed date\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * var result = formatDistanceToNow(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * var result = formatDistanceToNow(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   {includeSeconds: true}\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * var result = formatDistanceToNow(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in about 1 year'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * var eoLocale = require('date-fns/locale/eo')\n * var result = formatDistanceToNow(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> 'pli ol 1 jaro'\n */\n\nexport default function formatDistanceToNow(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  return distanceInWords(dirtyDate, Date.now(), dirtyOptions);\n}","import distanceInStrictWords from '../formatDistanceStrict/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatDistanceToNowStrict\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given dates in words, using strict units.\n * This is like `formatDistance`, but does not use helpers like 'almost', 'over',\n * 'less than' and the like.\n *\n * | Distance between dates | Result              |\n * |------------------------|---------------------|\n * | 0 ... 59 secs          | [0..59] seconds     |\n * | 1 ... 59 mins          | [1..59] minutes     |\n * | 1 ... 23 hrs           | [1..23] hours       |\n * | 1 ... 29 days          | [1..29] days        |\n * | 1 ... 11 months        | [1..11] months      |\n * | 1 ... N years          | [1..N]  years       |\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {'second'|'minute'|'hour'|'day'|'month'|'year'} [options.unit] - if specified, will force a unit\n * @param {'floor'|'ceil'|'round'} [options.roundingMethod='round'] - which way to round partial units\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * var result = formatDistanceToNowStrict(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * var result = formatDistanceToNowStrict(\n *   new Date(2015, 0, 1, 0, 0, 15)\n * )\n * //=> '20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * var result = formatDistanceToNowStrict(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in 1 year'\n *\n * @example\n * // If today is 28 January 2015,\n * // what is the distance to 1 January 2015, in months, rounded up??\n * var result = formatDistanceToNowStrict(new Date(2015, 0, 1), {\n *   unit: 'month',\n *   roundingMethod: 'ceil'\n * })\n * //=> '1 month'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * var eoLocale = require('date-fns/locale/eo')\n * var result = formatDistanceToNowStrict(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> '1 jaro'\n */\n\nexport default function formatDistanceToNowStrict(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  return distanceInStrictWords(dirtyDate, Date.now(), dirtyOptions);\n}","import defaultLocale from '../locale/en-US/index.js';\nvar defaultFormat = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'];\n/**\n * @name formatDuration\n * @category Common Helpers\n * @summary Formats a duration in human-readable format\n *\n * @description\n * Return human-readable duration string i.e. \"9 months 2 days\"\n *\n * @param {Duration} duration - the duration to format\n * @param {Object} [options] - an object with options.\n\n * @param {string[]} [options.format=['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds']] - the array of units to format\n * @param {boolean} [options.zero=false] - should be zeros be included in the output?\n * @param {string} [options.delimiter=' '] - delimiter string\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {string} the formatted date string\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Format full duration\n * formatDuration({\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30\n * })\n * //=> '2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds\n *\n * @example\n * // Format partial duration\n * formatDuration({ months: 9, days: 2 })\n * //=> '9 months 2 days'\n *\n * @example\n * // Customize the format\n * formatDuration(\n *   {\n *     years: 2,\n *     months: 9,\n *     weeks: 1,\n *     days: 7,\n *     hours: 5,\n *     minutes: 9,\n *     seconds: 30\n *   },\n *   { format: ['months', 'weeks'] }\n * ) === '9 months 1 week'\n *\n * @example\n * // Customize the zeros presence\n * formatDuration({ years: 0, months: 9 })\n * //=> '9 months'\n * formatDuration({ years: 0, months: 9 }, null, { zero: true })\n * //=> '0 years 9 months'\n *\n * @example\n * // Customize the delimiter\n * formatDuration({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' })\n * //=> '2 years, 9 months, 3 weeks'\n */\n\nexport default function formatDuration(duration) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var format = options.format || defaultFormat;\n  var locale = options.locale || defaultLocale;\n  var zero = options.zero || false;\n  var delimiter = options.delimiter || ' ';\n  var result = format.reduce(function (acc, unit) {\n    var token = \"x\".concat(unit.replace(/(^.)/, function (m) {\n      return m.toUpperCase();\n    }));\n    var addChunk = typeof duration[unit] === 'number' && (zero || duration[unit]);\n    return addChunk ? acc.concat(locale.formatDistance(token, duration[unit])) : acc;\n  }, []).join(delimiter);\n  return result;\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\n/**\n * @name formatISO\n * @category Common Helpers\n * @summary Format the date according to the ISO 8601 standard (http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003169814.htm).\n *\n * @description\n * Return the formatted date string in ISO 8601 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.\n * @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time with time zone, or both.\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.format` must be 'extended' or 'basic'\n * @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18T19:00:52Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601, short format (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })\n * //=> '20190918T190052'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format, date only:\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })\n * //=> '2019-09-18'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format, time only (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })\n * //=> '19:00:52Z'\n */\n\nexport default function formatISO(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var format = options.format == null ? 'extended' : String(options.format);\n  var representation = options.representation == null ? 'complete' : String(options.representation);\n\n  if (format !== 'extended' && format !== 'basic') {\n    throw new RangeError(\"format must be 'extended' or 'basic'\");\n  }\n\n  if (representation !== 'date' && representation !== 'time' && representation !== 'complete') {\n    throw new RangeError(\"representation must be 'date', 'time', or 'complete'\");\n  }\n\n  var result = '';\n  var tzOffset = '';\n  var dateDelimiter = format === 'extended' ? '-' : '';\n  var timeDelimiter = format === 'extended' ? ':' : ''; // Representation is either 'date' or 'complete'\n\n  if (representation !== 'time') {\n    var day = addLeadingZeros(originalDate.getDate(), 2);\n    var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n    var year = addLeadingZeros(originalDate.getFullYear(), 4); // yyyyMMdd or yyyy-MM-dd.\n\n    result = \"\".concat(year).concat(dateDelimiter).concat(month).concat(dateDelimiter).concat(day);\n  } // Representation is either 'time' or 'complete'\n\n\n  if (representation !== 'date') {\n    // Add the timezone.\n    var offset = originalDate.getTimezoneOffset();\n\n    if (offset !== 0) {\n      var absoluteOffset = Math.abs(offset);\n      var hourOffset = addLeadingZeros(Math.floor(absoluteOffset / 60), 2);\n      var minuteOffset = addLeadingZeros(absoluteOffset % 60, 2); // If less than 0, the sign is +, because it is ahead of time.\n\n      var sign = offset < 0 ? '+' : '-';\n      tzOffset = \"\".concat(sign).concat(hourOffset, \":\").concat(minuteOffset);\n    } else {\n      tzOffset = 'Z';\n    }\n\n    var hour = addLeadingZeros(originalDate.getHours(), 2);\n    var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n    var second = addLeadingZeros(originalDate.getSeconds(), 2); // If there's also date, separate it with time with 'T'\n\n    var separator = result === '' ? '' : 'T'; // Creates a time string consisting of hour, minute, and second, separated by delimiters, if defined.\n\n    var time = [hour, minute, second].join(timeDelimiter); // HHmmss or HH:mm:ss.\n\n    result = \"\".concat(result).concat(separator).concat(time).concat(tzOffset);\n  }\n\n  return result;\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\n/**\n * @name formatISO9075\n * @category Common Helpers\n * @summary Format the date according to the ISO 9075 standard (https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_get-format).\n *\n * @description\n * Return the formatted date string in ISO 9075 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.\n * @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time, or both.\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.format` must be 'extended' or 'basic'\n * @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18 19:00:52'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075, short format:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })\n * //=> '20190918 190052'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format, date only:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })\n * //=> '2019-09-18'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format, time only:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })\n * //=> '19:00:52'\n */\n\nexport default function formatISO9075(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var format = options.format == null ? 'extended' : String(options.format);\n  var representation = options.representation == null ? 'complete' : String(options.representation);\n\n  if (format !== 'extended' && format !== 'basic') {\n    throw new RangeError(\"format must be 'extended' or 'basic'\");\n  }\n\n  if (representation !== 'date' && representation !== 'time' && representation !== 'complete') {\n    throw new RangeError(\"representation must be 'date', 'time', or 'complete'\");\n  }\n\n  var result = '';\n  var dateDelimiter = format === 'extended' ? '-' : '';\n  var timeDelimiter = format === 'extended' ? ':' : ''; // Representation is either 'date' or 'complete'\n\n  if (representation !== 'time') {\n    var day = addLeadingZeros(originalDate.getDate(), 2);\n    var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n    var year = addLeadingZeros(originalDate.getFullYear(), 4); // yyyyMMdd or yyyy-MM-dd.\n\n    result = \"\".concat(year).concat(dateDelimiter).concat(month).concat(dateDelimiter).concat(day);\n  } // Representation is either 'time' or 'complete'\n\n\n  if (representation !== 'date') {\n    var hour = addLeadingZeros(originalDate.getHours(), 2);\n    var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n    var second = addLeadingZeros(originalDate.getSeconds(), 2); // If there's also date, separate it with time with a space\n\n    var separator = result === '' ? '' : ' '; // HHmmss or HH:mm:ss.\n\n    result = \"\".concat(result).concat(separator).concat(hour).concat(timeDelimiter).concat(minute).concat(timeDelimiter).concat(second);\n  }\n\n  return result;\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatISODuration\n * @category Common Helpers\n * @summary Format a duration object according as ISO 8601 duration string\n *\n * @description\n * Format a duration object according to the ISO 8601 duration standard (https://www.digi.com/resources/documentation/digidocs/90001437-13/reference/r_iso_8601_duration_format.htm)\n *\n * @param {Duration} duration - the duration to format\n *\n * @returns {String} The ISO 8601 duration string\n * @throws {TypeError} Requires 1 argument\n * @throws {Error} Argument must be an object\n *\n * @example\n * // Format the given duration as ISO 8601 string\n * formatISODuration({\n *   years: 39,\n *   months: 2,\n *   days: 20,\n *   hours: 7,\n *   minutes: 5,\n *   seconds: 0\n * })\n * //=> 'P39Y2M20DT0H0M0S'\n */\n\nexport default function formatISODuration(duration) {\n  requiredArgs(1, arguments);\n  if (typeof duration !== 'object') throw new Error('Duration must be an object');\n  var _duration$years = duration.years,\n      years = _duration$years === void 0 ? 0 : _duration$years,\n      _duration$months = duration.months,\n      months = _duration$months === void 0 ? 0 : _duration$months,\n      _duration$days = duration.days,\n      days = _duration$days === void 0 ? 0 : _duration$days,\n      _duration$hours = duration.hours,\n      hours = _duration$hours === void 0 ? 0 : _duration$hours,\n      _duration$minutes = duration.minutes,\n      minutes = _duration$minutes === void 0 ? 0 : _duration$minutes,\n      _duration$seconds = duration.seconds,\n      seconds = _duration$seconds === void 0 ? 0 : _duration$seconds;\n  return \"P\".concat(years, \"Y\").concat(months, \"M\").concat(days, \"DT\").concat(hours, \"H\").concat(minutes, \"M\").concat(seconds, \"S\");\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name formatRFC3339\n * @category Common Helpers\n * @summary Format the date according to the ISO 3339 standard (https://tools.ietf.org/html/rfc3339#section-5.6).\n *\n * @description\n * Return the formatted date string in ISO 3339 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {0|1|2|3} [options.fractionDigits=0] - number of digits after the decimal point after seconds\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.fractionDigits` must be between 0 and 3\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format:\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18T19:00:52Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format, 2 digits of second fraction:\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52, 234), { fractionDigits: 2 })\n * //=> '2019-09-18T19:00:52.23Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format, 3 digits of second fraction\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52, 234), { fractionDigits: 3 })\n * //=> '2019-09-18T19:00:52.234Z'\n */\n\nexport default function formatRFC3339(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 arguments required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var fractionDigits = options.fractionDigits == null ? 0 : toInteger(options.fractionDigits); // Test if fractionDigits is between 0 and 3 _and_ is not NaN\n\n  if (!(fractionDigits >= 0 && fractionDigits <= 3)) {\n    throw new RangeError('fractionDigits must be between 0 and 3 inclusively');\n  }\n\n  var day = addLeadingZeros(originalDate.getDate(), 2);\n  var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n  var year = originalDate.getFullYear();\n  var hour = addLeadingZeros(originalDate.getHours(), 2);\n  var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n  var second = addLeadingZeros(originalDate.getSeconds(), 2);\n  var fractionalSecond = '';\n\n  if (fractionDigits > 0) {\n    var milliseconds = originalDate.getMilliseconds();\n    var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, fractionDigits - 3));\n    fractionalSecond = '.' + addLeadingZeros(fractionalSeconds, fractionDigits);\n  }\n\n  var offset = '';\n  var tzOffset = originalDate.getTimezoneOffset();\n\n  if (tzOffset !== 0) {\n    var absoluteOffset = Math.abs(tzOffset);\n    var hourOffset = addLeadingZeros(toInteger(absoluteOffset / 60), 2);\n    var minuteOffset = addLeadingZeros(absoluteOffset % 60, 2); // If less than 0, the sign is +, because it is ahead of time.\n\n    var sign = tzOffset < 0 ? '+' : '-';\n    offset = \"\".concat(sign).concat(hourOffset, \":\").concat(minuteOffset);\n  } else {\n    offset = 'Z';\n  }\n\n  return \"\".concat(year, \"-\").concat(month, \"-\").concat(day, \"T\").concat(hour, \":\").concat(minute, \":\").concat(second).concat(fractionalSecond).concat(offset);\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\nvar days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n/**\n * @name formatRFC7231\n * @category Common Helpers\n * @summary Format the date according to the RFC 7231 standard (https://tools.ietf.org/html/rfc7231#section-7.1.1.1).\n *\n * @description\n * Return the formatted date string in RFC 7231 format.\n * The result will always be in UTC timezone.\n *\n * @param {Date|Number} date - the original date\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n *\n * @example\n * // Represent 18 September 2019 in RFC 7231 format:\n * const result = formatRFC7231(new Date(2019, 8, 18, 19, 0, 52))\n * //=> 'Wed, 18 Sep 2019 19:00:52 GMT'\n */\n\nexport default function formatRFC7231(dirtyDate) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 arguments required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var dayName = days[originalDate.getUTCDay()];\n  var dayOfMonth = addLeadingZeros(originalDate.getUTCDate(), 2);\n  var monthName = months[originalDate.getUTCMonth()];\n  var year = originalDate.getUTCFullYear();\n  var hour = addLeadingZeros(originalDate.getUTCHours(), 2);\n  var minute = addLeadingZeros(originalDate.getUTCMinutes(), 2);\n  var second = addLeadingZeros(originalDate.getUTCSeconds(), 2); // Result variables.\n\n  return \"\".concat(dayName, \", \").concat(dayOfMonth, \" \").concat(monthName, \" \").concat(year, \" \").concat(hour, \":\").concat(minute, \":\").concat(second, \" GMT\");\n}","import differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport format from '../format/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatRelative\n * @category Common Helpers\n * @summary Represent the date in words relative to the given base date.\n *\n * @description\n * Represent the date in words relative to the given base date.\n *\n * | Distance to the base date | Result                    |\n * |---------------------------|---------------------------|\n * | Previous 6 days           | last Sunday at 04:30 AM   |\n * | Last day                  | yesterday at 04:30 AM     |\n * | Same day                  | today at 04:30 AM         |\n * | Next day                  | tomorrow at 04:30 AM      |\n * | Next 6 days               | Sunday at 04:30 AM        |\n * | Other                     | 12/31/2017                |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to format\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {String} the date in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.locale` must contain `localize` property\n * @throws {RangeError} `options.locale` must contain `formatLong` property\n * @throws {RangeError} `options.locale` must contain `formatRelative` property\n */\n\nexport default function formatRelative(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var baseDate = toDate(dirtyBaseDate);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.localize) {\n    throw new RangeError('locale must contain localize property');\n  }\n\n  if (!locale.formatLong) {\n    throw new RangeError('locale must contain formatLong property');\n  }\n\n  if (!locale.formatRelative) {\n    throw new RangeError('locale must contain formatRelative property');\n  }\n\n  var diff = differenceInCalendarDays(date, baseDate);\n\n  if (isNaN(diff)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var token;\n\n  if (diff < -6) {\n    token = 'other';\n  } else if (diff < -1) {\n    token = 'lastWeek';\n  } else if (diff < 0) {\n    token = 'yesterday';\n  } else if (diff < 1) {\n    token = 'today';\n  } else if (diff < 2) {\n    token = 'tomorrow';\n  } else if (diff < 7) {\n    token = 'nextWeek';\n  } else {\n    token = 'other';\n  }\n\n  var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));\n  var utcBaseDate = subMilliseconds(baseDate, getTimezoneOffsetInMilliseconds(baseDate));\n  var formatStr = locale.formatRelative(token, utcDate, utcBaseDate, options);\n  return format(date, formatStr, options);\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name fromUnixTime\n * @category Timestamp Helpers\n * @summary Create a date from a Unix timestamp.\n *\n * @description\n * Create a date from a Unix timestamp.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Number} unixTime - the given Unix timestamp\n * @returns {Date} the date\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Create the date 29 February 2012 11:45:05:\n * var result = fromUnixTime(1330515905)\n * //=> Wed Feb 29 2012 11:45:05\n */\n\nexport default function fromUnixTime(dirtyUnixTime) {\n  requiredArgs(1, arguments);\n  var unixTime = toInteger(dirtyUnixTime);\n  return toDate(unixTime * 1000);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDate\n * @category Day Helpers\n * @summary Get the day of the month of the given date.\n *\n * @description\n * Get the day of the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the month is 29 February 2012?\n * var result = getDate(new Date(2012, 1, 29))\n * //=> 29\n */\n\nexport default function getDate(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfMonth = date.getDate();\n  return dayOfMonth;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDay\n * @category Weekday Helpers\n * @summary Get the day of the week of the given date.\n *\n * @description\n * Get the day of the week of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {0|1|2|3|4|5|6} the day of week, 0 represents Sunday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the week is 29 February 2012?\n * var result = getDay(new Date(2012, 1, 29))\n * //=> 3\n */\n\nexport default function getDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  return day;\n}","import toDate from '../toDate/index.js';\nimport startOfYear from '../startOfYear/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDayOfYear\n * @category Day Helpers\n * @summary Get the day of the year of the given date.\n *\n * @description\n * Get the day of the year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the year is 2 July 2014?\n * var result = getDayOfYear(new Date(2014, 6, 2))\n * //=> 183\n */\n\nexport default function getDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = differenceInCalendarDays(date, startOfYear(date));\n  var dayOfYear = diff + 1;\n  return dayOfYear;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of days in a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many days are in February 2000?\n * var result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\n\nexport default function getDaysInMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var monthIndex = date.getMonth();\n  var lastDayOfMonth = new Date(0);\n  lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n  lastDayOfMonth.setHours(0, 0, 0, 0);\n  return lastDayOfMonth.getDate();\n}","import toDate from '../toDate/index.js';\nimport isLeapYear from '../isLeapYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDaysInYear\n * @category Year Helpers\n * @summary Get the number of days in a year of the given date.\n *\n * @description\n * Get the number of days in a year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of days in a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many days are in 2012?\n * var result = getDaysInYear(new Date(2012, 0, 1))\n * //=> 366\n */\n\nexport default function getDaysInYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n\n  if (isNaN(date)) {\n    return NaN;\n  }\n\n  return isLeapYear(date) ? 366 : 365;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDecade\n * @category Decade Helpers\n * @summary Get the decade of the given date.\n *\n * @description\n * Get the decade of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the year of decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which decade belongs 27 November 1942?\n * var result = getDecade(new Date(1942, 10, 27))\n * //=> 1940\n */\n\nexport default function getDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = Math.floor(year / 10) * 10;\n  return decade;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getHours\n * @category Hour Helpers\n * @summary Get the hours of the given date.\n *\n * @description\n * Get the hours of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the hours\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the hours of 29 February 2012 11:45:00:\n * var result = getHours(new Date(2012, 1, 29, 11, 45))\n * //=> 11\n */\n\nexport default function getHours(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var hours = date.getHours();\n  return hours;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getISODay\n * @category Weekday Helpers\n * @summary Get the day of the ISO week of the given date.\n *\n * @description\n * Get the day of the ISO week of the given date,\n * which is 7 for Sunday, 1 for Monday etc.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the ISO week is 26 February 2012?\n * var result = getISODay(new Date(2012, 1, 26))\n * //=> 7\n */\n\nexport default function getISODay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n\n  if (day === 0) {\n    day = 7;\n  }\n\n  return day;\n}","import toDate from '../toDate/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getISOWeek\n * @category ISO Week Helpers\n * @summary Get the ISO week of the given date.\n *\n * @description\n * Get the ISO week of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which week of the ISO-week numbering year is 2 January 2005?\n * var result = getISOWeek(new Date(2005, 0, 2))\n * //=> 53\n */\n\nexport default function getISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfISOWeek(date).getTime() - startOfISOWeekYear(date).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toDate from '../toDate/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the ISO week-numbering year of the given date.\n *\n * @description\n * Get the ISO week-numbering year of the given date,\n * which always starts 3 days before the year's first Thursday.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `getISOYear` to `getISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which ISO-week numbering year is 2 January 2005?\n * var result = getISOWeekYear(new Date(2005, 0, 2))\n * //=> 2004\n */\n\nexport default function getISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n  var startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear);\n  var fourthOfJanuaryOfThisYear = new Date(0);\n  fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);\n  fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);\n  var startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport addWeeks from '../addWeeks/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getISOWeeksInYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of weeks in an ISO week-numbering year of the given date.\n *\n * @description\n * Get the number of weeks in an ISO week-numbering year of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of ISO weeks in a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many weeks are in ISO week-numbering year 2015?\n * var result = getISOWeeksInYear(new Date(2015, 1, 11))\n * //=> 53\n */\n\nexport default function getISOWeeksInYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var thisYear = startOfISOWeekYear(dirtyDate);\n  var nextYear = startOfISOWeekYear(addWeeks(thisYear, 60));\n  var diff = nextYear.valueOf() - thisYear.valueOf(); // Round the number of weeks to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMilliseconds\n * @category Millisecond Helpers\n * @summary Get the milliseconds of the given date.\n *\n * @description\n * Get the milliseconds of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the milliseconds\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the milliseconds of 29 February 2012 11:45:05.123:\n * var result = getMilliseconds(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 123\n */\n\nexport default function getMilliseconds(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var milliseconds = date.getMilliseconds();\n  return milliseconds;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMinutes\n * @category Minute Helpers\n * @summary Get the minutes of the given date.\n *\n * @description\n * Get the minutes of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the minutes\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the minutes of 29 February 2012 11:45:05:\n * var result = getMinutes(new Date(2012, 1, 29, 11, 45, 5))\n * //=> 45\n */\n\nexport default function getMinutes(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var minutes = date.getMinutes();\n  return minutes;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMonth\n * @category Month Helpers\n * @summary Get the month of the given date.\n *\n * @description\n * Get the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which month is 29 February 2012?\n * var result = getMonth(new Date(2012, 1, 29))\n * //=> 1\n */\n\nexport default function getMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  return month;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;\n/**\n * @name getOverlappingDaysInIntervals\n * @category Interval Helpers\n * @summary Get the number of days that overlap in two time intervals\n *\n * @description\n * Get the number of days that overlap in two time intervals\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `getOverlappingDaysInRanges` to `getOverlappingDaysInIntervals`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   getOverlappingDaysInRanges(\n *     new Date(2014, 0, 10), new Date(2014, 0, 20),\n *     new Date(2014, 0, 17), new Date(2014, 0, 21)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   getOverlappingDaysInIntervals(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *     { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n *   )\n *   ```\n *\n * @param {Interval} intervalLeft - the first interval to compare. See [Interval]{@link docs/Interval}\n * @param {Interval} intervalRight - the second interval to compare. See [Interval]{@link docs/Interval}\n * @returns {Number} the number of days that overlap in two time intervals\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For overlapping time intervals adds 1 for each started overlapping day:\n * getOverlappingDaysInIntervals(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n * )\n * //=> 3\n *\n * @example\n * // For non-overlapping time intervals returns 0:\n * getOverlappingDaysInIntervals(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 21), end: new Date(2014, 0, 22) }\n * )\n * //=> 0\n */\n\nexport default function getOverlappingDaysInIntervals(dirtyIntervalLeft, dirtyIntervalRight) {\n  requiredArgs(2, arguments);\n  var intervalLeft = dirtyIntervalLeft || {};\n  var intervalRight = dirtyIntervalRight || {};\n  var leftStartTime = toDate(intervalLeft.start).getTime();\n  var leftEndTime = toDate(intervalLeft.end).getTime();\n  var rightStartTime = toDate(intervalRight.start).getTime();\n  var rightEndTime = toDate(intervalRight.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var isOverlapping = leftStartTime < rightEndTime && rightStartTime < leftEndTime;\n\n  if (!isOverlapping) {\n    return 0;\n  }\n\n  var overlapStartDate = rightStartTime < leftStartTime ? leftStartTime : rightStartTime;\n  var overlapEndDate = rightEndTime > leftEndTime ? leftEndTime : rightEndTime;\n  var differenceInMs = overlapEndDate - overlapStartDate;\n  return Math.ceil(differenceInMs / MILLISECONDS_IN_DAY);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getQuarter\n * @category Quarter Helpers\n * @summary Get the year quarter of the given date.\n *\n * @description\n * Get the year quarter of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which quarter is 2 July 2014?\n * var result = getQuarter(new Date(2014, 6, 2))\n * //=> 3\n */\n\nexport default function getQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var quarter = Math.floor(date.getMonth() / 3) + 1;\n  return quarter;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getSeconds\n * @category Second Helpers\n * @summary Get the seconds of the given date.\n *\n * @description\n * Get the seconds of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the seconds\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the seconds of 29 February 2012 11:45:05.123:\n * var result = getSeconds(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 5\n */\n\nexport default function getSeconds(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var seconds = date.getSeconds();\n  return seconds;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getTime\n * @category Timestamp Helpers\n * @summary Get the milliseconds timestamp of the given date.\n *\n * @description\n * Get the milliseconds timestamp of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the timestamp\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the timestamp of 29 February 2012 11:45:05.123:\n * var result = getTime(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 1330515905123\n */\n\nexport default function getTime(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var timestamp = date.getTime();\n  return timestamp;\n}","import getTime from '../getTime/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getUnixTime\n * @category Timestamp Helpers\n * @summary Get the seconds timestamp of the given date.\n *\n * @description\n * Get the seconds timestamp of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the timestamp\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the timestamp of 29 February 2012 11:45:05 CET:\n * var result = getUnixTime(new Date(2012, 1, 29, 11, 45, 5))\n * //=> 1330512305\n */\n\nexport default function getUnixTime(dirtyDate) {\n  requiredArgs(1, arguments);\n  return Math.floor(getTime(dirtyDate) / 1000);\n}","import startOfWeek from '../startOfWeek/index.js';\nimport startOfWeekYear from '../startOfWeekYear/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getWeek\n * @category Week Helpers\n * @summary Get the local week index of the given date.\n *\n * @description\n * Get the local week index of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week of the local week numbering year is 2 January 2005 with default options?\n * var result = getISOWeek(new Date(2005, 0, 2))\n * //=> 2\n *\n * // Which week of the local week numbering year is 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January?\n * var result = getISOWeek(new Date(2005, 0, 2), {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> 53\n */\n\nexport default function getWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfWeek(date, options).getTime() - startOfWeekYear(date, options).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import getDate from '../getDate/index.js';\nimport getDay from '../getDay/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeekOfMonth\n * @category Week Helpers\n * @summary Get the week of the month of the given date.\n *\n * @description\n * Get the week of the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the week of month\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Which week of the month is 9 November 2017?\n * var result = getWeekOfMonth(new Date(2017, 10, 9))\n * //=> 2\n */\n\nexport default function getWeekOfMonth(date, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var currentDayOfMonth = getDate(date);\n\n  if (isNaN(currentDayOfMonth)) {\n    return currentDayOfMonth;\n  }\n\n  var startWeekDay = getDay(startOfMonth(date));\n  var lastDayOfFirstWeek = 0;\n\n  if (startWeekDay >= weekStartsOn) {\n    lastDayOfFirstWeek = weekStartsOn + 7 - startWeekDay;\n  } else {\n    lastDayOfFirstWeek = weekStartsOn - startWeekDay;\n  }\n\n  var weekNumber = 1;\n\n  if (currentDayOfMonth > lastDayOfFirstWeek) {\n    var remainingDaysAfterFirstWeek = currentDayOfMonth - lastDayOfFirstWeek;\n    weekNumber = weekNumber + Math.ceil(remainingDaysAfterFirstWeek / 7);\n  }\n\n  return weekNumber;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Get the local week-numbering year of the given date.\n *\n * @description\n * Get the local week-numbering year of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the local week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week numbering year is 26 December 2004 with the default settings?\n * var result = getWeekYear(new Date(2004, 11, 26))\n * //=> 2005\n *\n * @example\n * // Which week numbering year is 26 December 2004 if week starts on Saturday?\n * var result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })\n * //=> 2004\n *\n * @example\n * // Which week numbering year is 26 December 2004 if the first week contains 4 January?\n * var result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })\n * //=> 2004\n */\n\nexport default function getWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var firstWeekOfNextYear = new Date(0);\n  firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);\n  firstWeekOfNextYear.setHours(0, 0, 0, 0);\n  var startOfNextYear = startOfWeek(firstWeekOfNextYear, dirtyOptions);\n  var firstWeekOfThisYear = new Date(0);\n  firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);\n  firstWeekOfThisYear.setHours(0, 0, 0, 0);\n  var startOfThisYear = startOfWeek(firstWeekOfThisYear, dirtyOptions);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import differenceInCalendarWeeks from '../differenceInCalendarWeeks/index.js';\nimport lastDayOfMonth from '../lastDayOfMonth/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeeksInMonth\n * @category Week Helpers\n * @summary Get the number of calendar weeks a month spans.\n *\n * @description\n * Get the number of calendar weeks the month in the given date spans.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks does February 2015 span?\n * var result = getWeeksInMonth(new Date(2015, 1, 8))\n * //=> 4\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks does July 2017 span?\n * var result = getWeeksInMonth(new Date(2017, 6, 5), { weekStartsOn: 1 })\n * //=> 6\n */\n\nexport default function getWeeksInMonth(date, options) {\n  requiredArgs(1, arguments);\n  return differenceInCalendarWeeks(lastDayOfMonth(date), startOfMonth(date), options) + 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getYear\n * @category Year Helpers\n * @summary Get the year of the given date.\n *\n * @description\n * Get the year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which year is 2 July 2014?\n * var result = getYear(new Date(2014, 6, 2))\n * //=> 2014\n */\n\nexport default function getYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  return year;\n}","// This file is generated automatically by `scripts/build/indices.js`. Please, don't change it.\nexport { default as add } from './add/index.js';\nexport { default as addBusinessDays } from './addBusinessDays/index.js';\nexport { default as addDays } from './addDays/index.js';\nexport { default as addHours } from './addHours/index.js';\nexport { default as addISOWeekYears } from './addISOWeekYears/index.js';\nexport { default as addMilliseconds } from './addMilliseconds/index.js';\nexport { default as addMinutes } from './addMinutes/index.js';\nexport { default as addMonths } from './addMonths/index.js';\nexport { default as addQuarters } from './addQuarters/index.js';\nexport { default as addSeconds } from './addSeconds/index.js';\nexport { default as addWeeks } from './addWeeks/index.js';\nexport { default as addYears } from './addYears/index.js';\nexport { default as areIntervalsOverlapping } from './areIntervalsOverlapping/index.js';\nexport { default as closestIndexTo } from './closestIndexTo/index.js';\nexport { default as closestTo } from './closestTo/index.js';\nexport { default as compareAsc } from './compareAsc/index.js';\nexport { default as compareDesc } from './compareDesc/index.js';\nexport { default as differenceInBusinessDays } from './differenceInBusinessDays/index.js';\nexport { default as differenceInCalendarDays } from './differenceInCalendarDays/index.js';\nexport { default as differenceInCalendarISOWeekYears } from './differenceInCalendarISOWeekYears/index.js';\nexport { default as differenceInCalendarISOWeeks } from './differenceInCalendarISOWeeks/index.js';\nexport { default as differenceInCalendarMonths } from './differenceInCalendarMonths/index.js';\nexport { default as differenceInCalendarQuarters } from './differenceInCalendarQuarters/index.js';\nexport { default as differenceInCalendarWeeks } from './differenceInCalendarWeeks/index.js';\nexport { default as differenceInCalendarYears } from './differenceInCalendarYears/index.js';\nexport { default as differenceInDays } from './differenceInDays/index.js';\nexport { default as differenceInHours } from './differenceInHours/index.js';\nexport { default as differenceInISOWeekYears } from './differenceInISOWeekYears/index.js';\nexport { default as differenceInMilliseconds } from './differenceInMilliseconds/index.js';\nexport { default as differenceInMinutes } from './differenceInMinutes/index.js';\nexport { default as differenceInMonths } from './differenceInMonths/index.js';\nexport { default as differenceInQuarters } from './differenceInQuarters/index.js';\nexport { default as differenceInSeconds } from './differenceInSeconds/index.js';\nexport { default as differenceInWeeks } from './differenceInWeeks/index.js';\nexport { default as differenceInYears } from './differenceInYears/index.js';\nexport { default as eachDayOfInterval } from './eachDayOfInterval/index.js';\nexport { default as eachHourOfInterval } from './eachHourOfInterval/index.js';\nexport { default as eachMonthOfInterval } from './eachMonthOfInterval/index.js';\nexport { default as eachQuarterOfInterval } from './eachQuarterOfInterval/index.js';\nexport { default as eachWeekOfInterval } from './eachWeekOfInterval/index.js';\nexport { default as eachWeekendOfInterval } from './eachWeekendOfInterval/index.js';\nexport { default as eachWeekendOfMonth } from './eachWeekendOfMonth/index.js';\nexport { default as eachWeekendOfYear } from './eachWeekendOfYear/index.js';\nexport { default as eachYearOfInterval } from './eachYearOfInterval/index.js';\nexport { default as endOfDay } from './endOfDay/index.js';\nexport { default as endOfDecade } from './endOfDecade/index.js';\nexport { default as endOfHour } from './endOfHour/index.js';\nexport { default as endOfISOWeek } from './endOfISOWeek/index.js';\nexport { default as endOfISOWeekYear } from './endOfISOWeekYear/index.js';\nexport { default as endOfMinute } from './endOfMinute/index.js';\nexport { default as endOfMonth } from './endOfMonth/index.js';\nexport { default as endOfQuarter } from './endOfQuarter/index.js';\nexport { default as endOfSecond } from './endOfSecond/index.js';\nexport { default as endOfToday } from './endOfToday/index.js';\nexport { default as endOfTomorrow } from './endOfTomorrow/index.js';\nexport { default as endOfWeek } from './endOfWeek/index.js';\nexport { default as endOfYear } from './endOfYear/index.js';\nexport { default as endOfYesterday } from './endOfYesterday/index.js';\nexport { default as format } from './format/index.js';\nexport { default as formatDistance } from './formatDistance/index.js';\nexport { default as formatDistanceStrict } from './formatDistanceStrict/index.js';\nexport { default as formatDistanceToNow } from './formatDistanceToNow/index.js';\nexport { default as formatDistanceToNowStrict } from './formatDistanceToNowStrict/index.js';\nexport { default as formatDuration } from './formatDuration/index.js';\nexport { default as formatISO } from './formatISO/index.js';\nexport { default as formatISO9075 } from './formatISO9075/index.js';\nexport { default as formatISODuration } from './formatISODuration/index.js';\nexport { default as formatRFC3339 } from './formatRFC3339/index.js';\nexport { default as formatRFC7231 } from './formatRFC7231/index.js';\nexport { default as formatRelative } from './formatRelative/index.js';\nexport { default as fromUnixTime } from './fromUnixTime/index.js';\nexport { default as getDate } from './getDate/index.js';\nexport { default as getDay } from './getDay/index.js';\nexport { default as getDayOfYear } from './getDayOfYear/index.js';\nexport { default as getDaysInMonth } from './getDaysInMonth/index.js';\nexport { default as getDaysInYear } from './getDaysInYear/index.js';\nexport { default as getDecade } from './getDecade/index.js';\nexport { default as getHours } from './getHours/index.js';\nexport { default as getISODay } from './getISODay/index.js';\nexport { default as getISOWeek } from './getISOWeek/index.js';\nexport { default as getISOWeekYear } from './getISOWeekYear/index.js';\nexport { default as getISOWeeksInYear } from './getISOWeeksInYear/index.js';\nexport { default as getMilliseconds } from './getMilliseconds/index.js';\nexport { default as getMinutes } from './getMinutes/index.js';\nexport { default as getMonth } from './getMonth/index.js';\nexport { default as getOverlappingDaysInIntervals } from './getOverlappingDaysInIntervals/index.js';\nexport { default as getQuarter } from './getQuarter/index.js';\nexport { default as getSeconds } from './getSeconds/index.js';\nexport { default as getTime } from './getTime/index.js';\nexport { default as getUnixTime } from './getUnixTime/index.js';\nexport { default as getWeek } from './getWeek/index.js';\nexport { default as getWeekOfMonth } from './getWeekOfMonth/index.js';\nexport { default as getWeekYear } from './getWeekYear/index.js';\nexport { default as getWeeksInMonth } from './getWeeksInMonth/index.js';\nexport { default as getYear } from './getYear/index.js';\nexport { default as intervalToDuration } from './intervalToDuration/index.js';\nexport { default as isAfter } from './isAfter/index.js';\nexport { default as isBefore } from './isBefore/index.js';\nexport { default as isDate } from './isDate/index.js';\nexport { default as isEqual } from './isEqual/index.js';\nexport { default as isExists } from './isExists/index.js';\nexport { default as isFirstDayOfMonth } from './isFirstDayOfMonth/index.js';\nexport { default as isFriday } from './isFriday/index.js';\nexport { default as isFuture } from './isFuture/index.js';\nexport { default as isLastDayOfMonth } from './isLastDayOfMonth/index.js';\nexport { default as isLeapYear } from './isLeapYear/index.js';\nexport { default as isMatch } from './isMatch/index.js';\nexport { default as isMonday } from './isMonday/index.js';\nexport { default as isPast } from './isPast/index.js';\nexport { default as isSameDay } from './isSameDay/index.js';\nexport { default as isSameHour } from './isSameHour/index.js';\nexport { default as isSameISOWeek } from './isSameISOWeek/index.js';\nexport { default as isSameISOWeekYear } from './isSameISOWeekYear/index.js';\nexport { default as isSameMinute } from './isSameMinute/index.js';\nexport { default as isSameMonth } from './isSameMonth/index.js';\nexport { default as isSameQuarter } from './isSameQuarter/index.js';\nexport { default as isSameSecond } from './isSameSecond/index.js';\nexport { default as isSameWeek } from './isSameWeek/index.js';\nexport { default as isSameYear } from './isSameYear/index.js';\nexport { default as isSaturday } from './isSaturday/index.js';\nexport { default as isSunday } from './isSunday/index.js';\nexport { default as isThisHour } from './isThisHour/index.js';\nexport { default as isThisISOWeek } from './isThisISOWeek/index.js';\nexport { default as isThisMinute } from './isThisMinute/index.js';\nexport { default as isThisMonth } from './isThisMonth/index.js';\nexport { default as isThisQuarter } from './isThisQuarter/index.js';\nexport { default as isThisSecond } from './isThisSecond/index.js';\nexport { default as isThisWeek } from './isThisWeek/index.js';\nexport { default as isThisYear } from './isThisYear/index.js';\nexport { default as isThursday } from './isThursday/index.js';\nexport { default as isToday } from './isToday/index.js';\nexport { default as isTomorrow } from './isTomorrow/index.js';\nexport { default as isTuesday } from './isTuesday/index.js';\nexport { default as isValid } from './isValid/index.js';\nexport { default as isWednesday } from './isWednesday/index.js';\nexport { default as isWeekend } from './isWeekend/index.js';\nexport { default as isWithinInterval } from './isWithinInterval/index.js';\nexport { default as isYesterday } from './isYesterday/index.js';\nexport { default as lastDayOfDecade } from './lastDayOfDecade/index.js';\nexport { default as lastDayOfISOWeek } from './lastDayOfISOWeek/index.js';\nexport { default as lastDayOfISOWeekYear } from './lastDayOfISOWeekYear/index.js';\nexport { default as lastDayOfMonth } from './lastDayOfMonth/index.js';\nexport { default as lastDayOfQuarter } from './lastDayOfQuarter/index.js';\nexport { default as lastDayOfWeek } from './lastDayOfWeek/index.js';\nexport { default as lastDayOfYear } from './lastDayOfYear/index.js';\nexport { default as lightFormat } from './lightFormat/index.js';\nexport { default as max } from './max/index.js';\nexport { default as min } from './min/index.js';\nexport { default as parse } from './parse/index.js';\nexport { default as parseISO } from './parseISO/index.js';\nexport { default as parseJSON } from './parseJSON/index.js';\nexport { default as roundToNearestMinutes } from './roundToNearestMinutes/index.js';\nexport { default as set } from './set/index.js';\nexport { default as setDate } from './setDate/index.js';\nexport { default as setDay } from './setDay/index.js';\nexport { default as setDayOfYear } from './setDayOfYear/index.js';\nexport { default as setHours } from './setHours/index.js';\nexport { default as setISODay } from './setISODay/index.js';\nexport { default as setISOWeek } from './setISOWeek/index.js';\nexport { default as setISOWeekYear } from './setISOWeekYear/index.js';\nexport { default as setMilliseconds } from './setMilliseconds/index.js';\nexport { default as setMinutes } from './setMinutes/index.js';\nexport { default as setMonth } from './setMonth/index.js';\nexport { default as setQuarter } from './setQuarter/index.js';\nexport { default as setSeconds } from './setSeconds/index.js';\nexport { default as setWeek } from './setWeek/index.js';\nexport { default as setWeekYear } from './setWeekYear/index.js';\nexport { default as setYear } from './setYear/index.js';\nexport { default as startOfDay } from './startOfDay/index.js';\nexport { default as startOfDecade } from './startOfDecade/index.js';\nexport { default as startOfHour } from './startOfHour/index.js';\nexport { default as startOfISOWeek } from './startOfISOWeek/index.js';\nexport { default as startOfISOWeekYear } from './startOfISOWeekYear/index.js';\nexport { default as startOfMinute } from './startOfMinute/index.js';\nexport { default as startOfMonth } from './startOfMonth/index.js';\nexport { default as startOfQuarter } from './startOfQuarter/index.js';\nexport { default as startOfSecond } from './startOfSecond/index.js';\nexport { default as startOfToday } from './startOfToday/index.js';\nexport { default as startOfTomorrow } from './startOfTomorrow/index.js';\nexport { default as startOfWeek } from './startOfWeek/index.js';\nexport { default as startOfWeekYear } from './startOfWeekYear/index.js';\nexport { default as startOfYear } from './startOfYear/index.js';\nexport { default as startOfYesterday } from './startOfYesterday/index.js';\nexport { default as sub } from './sub/index.js';\nexport { default as subBusinessDays } from './subBusinessDays/index.js';\nexport { default as subDays } from './subDays/index.js';\nexport { default as subHours } from './subHours/index.js';\nexport { default as subISOWeekYears } from './subISOWeekYears/index.js';\nexport { default as subMilliseconds } from './subMilliseconds/index.js';\nexport { default as subMinutes } from './subMinutes/index.js';\nexport { default as subMonths } from './subMonths/index.js';\nexport { default as subQuarters } from './subQuarters/index.js';\nexport { default as subSeconds } from './subSeconds/index.js';\nexport { default as subWeeks } from './subWeeks/index.js';\nexport { default as subYears } from './subYears/index.js';\nexport { default as toDate } from './toDate/index.js';\nexport * from './constants/index.js';","import compareAsc from '../compareAsc/index.js';\nimport differenceInYears from '../differenceInYears/index.js';\nimport differenceInMonths from '../differenceInMonths/index.js';\nimport differenceInDays from '../differenceInDays/index.js';\nimport differenceInHours from '../differenceInHours/index.js';\nimport differenceInMinutes from '../differenceInMinutes/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport isValid from '../isValid/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toDate from '../toDate/index.js';\nimport sub from '../sub/index.js';\n/**\n * @name intervalToDuration\n * @category Common Helpers\n * @summary Convert interval to duration\n *\n * @description\n * Convert a interval object to a duration object.\n *\n * @param {Interval} interval - the interval to convert to duration\n *\n * @returns {Duration} The duration Object\n * @throws {TypeError} Requires 2 arguments\n * @throws {RangeError} `start` must not be Invalid Date\n * @throws {RangeError} `end` must not be Invalid Date\n *\n * @example\n * // Get the duration between January 15, 1929 and April 4, 1968.\n * intervalToDuration({\n *   start: new Date(1929, 0, 15, 12, 0, 0),\n *   end: new Date(1968, 3, 4, 19, 5, 0)\n * })\n * // => { years: 39, months: 2, days: 20, hours: 7, minutes: 5, seconds: 0 }\n */\n\nexport default function intervalToDuration(_ref) {\n  var start = _ref.start,\n      end = _ref.end;\n  requiredArgs(1, arguments);\n  var dateLeft = toDate(start);\n  var dateRight = toDate(end);\n\n  if (!isValid(dateLeft)) {\n    throw new RangeError('Start Date is invalid');\n  }\n\n  if (!isValid(dateRight)) {\n    throw new RangeError('End Date is invalid');\n  }\n\n  var duration = {\n    years: 0,\n    months: 0,\n    days: 0,\n    hours: 0,\n    minutes: 0,\n    seconds: 0\n  };\n  var sign = compareAsc(dateLeft, dateRight);\n  duration.years = Math.abs(differenceInYears(dateLeft, dateRight));\n  var remainingMonths = sub(dateLeft, {\n    years: sign * duration.years\n  });\n  duration.months = Math.abs(differenceInMonths(remainingMonths, dateRight));\n  var remainingDays = sub(remainingMonths, {\n    months: sign * duration.months\n  });\n  duration.days = Math.abs(differenceInDays(remainingDays, dateRight));\n  var remainingHours = sub(remainingDays, {\n    days: sign * duration.days\n  });\n  duration.hours = Math.abs(differenceInHours(remainingHours, dateRight));\n  var remainingMinutes = sub(remainingHours, {\n    hours: sign * duration.hours\n  });\n  duration.minutes = Math.abs(differenceInMinutes(remainingMinutes, dateRight));\n  var remainingSeconds = sub(remainingMinutes, {\n    minutes: sign * duration.minutes\n  });\n  duration.seconds = Math.abs(differenceInSeconds(remainingSeconds, dateRight));\n  return duration;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isAfter\n * @category Common Helpers\n * @summary Is the first date after the second one?\n *\n * @description\n * Is the first date after the second one?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date that should be after the other one to return true\n * @param {Date|Number} dateToCompare - the date to compare with\n * @returns {Boolean} the first date is after the second date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Is 10 July 1989 after 11 February 1987?\n * var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11))\n * //=> true\n */\n\nexport default function isAfter(dirtyDate, dirtyDateToCompare) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dateToCompare = toDate(dirtyDateToCompare);\n  return date.getTime() > dateToCompare.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isBefore\n * @category Common Helpers\n * @summary Is the first date before the second one?\n *\n * @description\n * Is the first date before the second one?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date that should be before the other one to return true\n * @param {Date|Number} dateToCompare - the date to compare with\n * @returns {Boolean} the first date is before the second date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Is 10 July 1989 before 11 February 1987?\n * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))\n * //=> false\n */\n\nexport default function isBefore(dirtyDate, dirtyDateToCompare) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dateToCompare = toDate(dirtyDateToCompare);\n  return date.getTime() < dateToCompare.getTime();\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {*} value - the value to check\n * @returns {boolean} true if the given value is a date\n * @throws {TypeError} 1 arguments required\n *\n * @example\n * // For a valid date:\n * var result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * var result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * var result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * var result = isDate({})\n * //=> false\n */\n\nexport default function isDate(value) {\n  requiredArgs(1, arguments);\n  return value instanceof Date || typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]';\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isEqual\n * @category Common Helpers\n * @summary Are the given dates equal?\n *\n * @description\n * Are the given dates equal?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Boolean} the dates are equal\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal?\n * var result = isEqual(\n *   new Date(2014, 6, 2, 6, 30, 45, 0),\n *   new Date(2014, 6, 2, 6, 30, 45, 500)\n * )\n * //=> false\n */\n\nexport default function isEqual(dirtyLeftDate, dirtyRightDate) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyLeftDate);\n  var dateRight = toDate(dirtyRightDate);\n  return dateLeft.getTime() === dateRight.getTime();\n}","/**\n * @name isExists\n * @category Common Helpers\n * @summary Is the given date exists?\n *\n * @description\n * Checks if the given arguments convert to an existing date.\n *\n * @param {Number} year of the date to check\n * @param {Number} month of the date to check\n * @param {Number} day of the date to check\n * @returns {Boolean} the date exists\n * @throws {TypeError} 3 arguments required\n *\n * @example\n * // For the valid date:\n * var result = isExists(2018, 0, 31)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * var result = isExists(2018, 1, 31)\n * //=> false\n */\nexport default function isExists(year, month, day) {\n  if (arguments.length < 3) {\n    throw new TypeError('3 argument required, but only ' + arguments.length + ' present');\n  }\n\n  var date = new Date(year, month, day);\n  return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFirstDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the first day of a month?\n *\n * @description\n * Is the given date the first day of a month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is the first day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 1 September 2014 the first day of a month?\n * var result = isFirstDayOfMonth(new Date(2014, 8, 1))\n * //=> true\n */\n\nexport default function isFirstDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDate() === 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFriday\n * @category Weekday Helpers\n * @summary Is the given date Friday?\n *\n * @description\n * Is the given date Friday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Friday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 26 September 2014 Friday?\n * var result = isFriday(new Date(2014, 8, 26))\n * //=> true\n */\n\nexport default function isFriday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 5;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFuture\n * @category Common Helpers\n * @summary Is the given date in the future?\n * @pure false\n *\n * @description\n * Is the given date in the future?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the future\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 31 December 2014 in the future?\n * var result = isFuture(new Date(2014, 11, 31))\n * //=> true\n */\n\nexport default function isFuture(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getTime() > Date.now();\n}","import toDate from '../toDate/index.js';\nimport endOfDay from '../endOfDay/index.js';\nimport endOfMonth from '../endOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isLastDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the last day of a month?\n *\n * @description\n * Is the given date the last day of a month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is the last day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 28 February 2014 the last day of a month?\n * var result = isLastDayOfMonth(new Date(2014, 1, 28))\n * //=> true\n */\n\nexport default function isLastDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  return endOfDay(date).getTime() === endOfMonth(date).getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isLeapYear\n * @category Year Helpers\n * @summary Is the given date in the leap year?\n *\n * @description\n * Is the given date in the leap year?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the leap year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 1 September 2012 in the leap year?\n * var result = isLeapYear(new Date(2012, 8, 1))\n * //=> true\n */\n\nexport default function isLeapYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}","import parse from '../parse/index.js';\nimport isValid from '../isValid/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isMatch\n * @category Common Helpers\n * @summary validates the date string against given formats\n *\n * @description\n * Return the true if given date is string correct against the given format else\n * will return false.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters in the format string wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the format string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 5 below the table).\n *\n * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited\n * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:\n *\n * ```javascript\n * isMatch('23 AM', 'HH a')\n * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time\n * ```\n *\n * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true\n *\n * Accepted format string patterns:\n * | Unit                            |Prior| Pattern | Result examples                   | Notes |\n * |---------------------------------|-----|---------|-----------------------------------|-------|\n * | Era                             | 140 | G..GGG  | AD, BC                            |       |\n * |                                 |     | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 |     | GGGGG   | A, B                              |       |\n * | Calendar year                   | 130 | y       | 44, 1, 1900, 2017, 9999           | 4     |\n * |                                 |     | yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | yy      | 44, 01, 00, 17                    | 4     |\n * |                                 |     | yyy     | 044, 001, 123, 999                | 4     |\n * |                                 |     | yyyy    | 0044, 0001, 1900, 2017            | 4     |\n * |                                 |     | yyyyy   | ...                               | 2,4   |\n * | Local week-numbering year       | 130 | Y       | 44, 1, 1900, 2017, 9000           | 4     |\n * |                                 |     | Yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | YY      | 44, 01, 00, 17                    | 4,6   |\n * |                                 |     | YYY     | 044, 001, 123, 999                | 4     |\n * |                                 |     | YYYY    | 0044, 0001, 1900, 2017            | 4,6   |\n * |                                 |     | YYYYY   | ...                               | 2,4   |\n * | ISO week-numbering year         | 130 | R       | -43, 1, 1900, 2017, 9999, -9999   | 4,5   |\n * |                                 |     | RR      | -43, 01, 00, 17                   | 4,5   |\n * |                                 |     | RRR     | -043, 001, 123, 999, -999         | 4,5   |\n * |                                 |     | RRRR    | -0043, 0001, 2017, 9999, -9999    | 4,5   |\n * |                                 |     | RRRRR   | ...                               | 2,4,5 |\n * | Extended year                   | 130 | u       | -43, 1, 1900, 2017, 9999, -999    | 4     |\n * |                                 |     | uu      | -43, 01, 99, -99                  | 4     |\n * |                                 |     | uuu     | -043, 001, 123, 999, -999         | 4     |\n * |                                 |     | uuuu    | -0043, 0001, 2017, 9999, -9999    | 4     |\n * |                                 |     | uuuuu   | ...                               | 2,4   |\n * | Quarter (formatting)            | 120 | Q       | 1, 2, 3, 4                        |       |\n * |                                 |     | Qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | QQ      | 01, 02, 03, 04                    |       |\n * |                                 |     | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | 120 | q       | 1, 2, 3, 4                        |       |\n * |                                 |     | qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | qq      | 01, 02, 03, 04                    |       |\n * |                                 |     | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | qqqqq   | 1, 2, 3, 4                        | 3     |\n * | Month (formatting)              | 110 | M       | 1, 2, ..., 12                     |       |\n * |                                 |     | Mo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | MM      | 01, 02, ..., 12                   |       |\n * |                                 |     | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | MMMM    | January, February, ..., December  | 2     |\n * |                                 |     | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | 110 | L       | 1, 2, ..., 12                     |       |\n * |                                 |     | Lo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | LL      | 01, 02, ..., 12                   |       |\n * |                                 |     | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | LLLL    | January, February, ..., December  | 2     |\n * |                                 |     | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | 100 | w       | 1, 2, ..., 53                     |       |\n * |                                 |     | wo      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | 100 | I       | 1, 2, ..., 53                     | 5     |\n * |                                 |     | Io      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | II      | 01, 02, ..., 53                   | 5     |\n * | Day of month                    |  90 | d       | 1, 2, ..., 31                     |       |\n * |                                 |     | do      | 1st, 2nd, ..., 31st               | 5     |\n * |                                 |     | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     |  90 | D       | 1, 2, ..., 365, 366               | 7     |\n * |                                 |     | Do      | 1st, 2nd, ..., 365th, 366th       | 5     |\n * |                                 |     | DD      | 01, 02, ..., 365, 366             | 7     |\n * |                                 |     | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 |     | DDDD    | ...                               | 2     |\n * | Day of week (formatting)        |  90 | E..EEE  | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 |     | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    |  90 | i       | 1, 2, 3, ..., 7                   | 5     |\n * |                                 |     | io      | 1st, 2nd, ..., 7th                | 5     |\n * |                                 |     | ii      | 01, 02, ..., 07                   | 5     |\n * |                                 |     | iii     | Mon, Tue, Wed, ..., Su            | 5     |\n * |                                 |     | iiii    | Monday, Tuesday, ..., Sunday      | 2,5   |\n * |                                 |     | iiiii   | M, T, W, T, F, S, S               | 5     |\n * |                                 |     | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 5     |\n * | Local day of week (formatting)  |  90 | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | eo      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | ee      | 02, 03, ..., 01                   |       |\n * |                                 |     | eee     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 |     | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) |  90 | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | co      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | cc      | 02, 03, ..., 01                   |       |\n * |                                 |     | ccc     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 |     | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          |  80 | a..aaa  | AM, PM                            |       |\n * |                                 |     | aaaa    | a.m., p.m.                        | 2     |\n * |                                 |     | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          |  80 | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 |     | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 |     | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             |  80 | B..BBB  | at night, in the morning, ...     |       |\n * |                                 |     | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 |     | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     |  70 | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 |     | ho      | 1st, 2nd, ..., 11th, 12th         | 5     |\n * |                                 |     | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     |  70 | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 |     | Ho      | 0th, 1st, 2nd, ..., 23rd          | 5     |\n * |                                 |     | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     |  70 | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 |     | Ko      | 1st, 2nd, ..., 11th, 0th          | 5     |\n * |                                 |     | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     |  70 | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 |     | ko      | 24th, 1st, 2nd, ..., 23rd         | 5     |\n * |                                 |     | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          |  60 | m       | 0, 1, ..., 59                     |       |\n * |                                 |     | mo      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | mm      | 00, 01, ..., 59                   |       |\n * | Second                          |  50 | s       | 0, 1, ..., 59                     |       |\n * |                                 |     | so      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | ss      | 00, 01, ..., 59                   |       |\n * | Seconds timestamp               |  40 | t       | 512969520                         |       |\n * |                                 |     | tt      | ...                               | 2     |\n * | Fraction of second              |  30 | S       | 0, 1, ..., 9                      |       |\n * |                                 |     | SS      | 00, 01, ..., 99                   |       |\n * |                                 |     | SSS     | 000, 0001, ..., 999               |       |\n * |                                 |     | SSSS    | ...                               | 2     |\n * | Milliseconds timestamp          |  20 | T       | 512969520900                      |       |\n * |                                 |     | TT      | ...                               | 2     |\n * | Timezone (ISO-8601 w/ Z)        |  10 | X       | -08, +0530, Z                     |       |\n * |                                 |     | XX      | -0800, +0530, Z                   |       |\n * |                                 |     | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 |     | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 |     | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       |  10 | x       | -08, +0530, +00                   |       |\n * |                                 |     | xx      | -0800, +0530, +0000               |       |\n * |                                 |     | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 |     | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 |     | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Long localized date             |  NA | P       | 05/29/1453                        | 5,8   |\n * |                                 |     | PP      | May 29, 1453                      |       |\n * |                                 |     | PPP     | May 29th, 1453                    |       |\n * |                                 |     | PPPP    | Sunday, May 29th, 1453            | 2,5,8 |\n * | Long localized time             |  NA | p       | 12:00 AM                          | 5,8   |\n * |                                 |     | pp      | 12:00:00 AM                       |       |\n * | Combination of date and time    |  NA | Pp      | 05/29/1453, 12:00 AM              |       |\n * |                                 |     | PPpp    | May 29, 1453, 12:00:00 AM         |       |\n * |                                 |     | PPPpp   | May 29th, 1453 at ...             |       |\n * |                                 |     | PPPPpp  | Sunday, May 29th, 1453 at ...     | 2,5,8 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular.\n *    In `format` function, they will produce different result:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n *    `isMatch` will try to match both formatting and stand-alone units interchangably.\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table:\n *    - for numerical units (`yyyyyyyy`) `isMatch` will try to match a number\n *      as wide as the sequence\n *    - for text units (`MMMMMMMM`) `isMatch` will try to match the widest variation of the unit.\n *      These variations are marked with \"2\" in the last column of the table.\n *\n * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 4. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:\n *\n *    `isMatch('50', 'yy') //=> true`\n *\n *    `isMatch('75', 'yy') //=> true`\n *\n *    while `uu` will use the year as is:\n *\n *    `isMatch('50', 'uu') //=> true`\n *\n *    `isMatch('75', 'uu') //=> true`\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}\n *    and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).\n *\n * 5. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based\n *    on the given locale.\n *\n *    using `en-US` locale: `P` => `MM/dd/yyyy`\n *    using `en-US` locale: `p` => `hh:mm a`\n *    using `pt-BR` locale: `P` => `dd/MM/yyyy`\n *    using `pt-BR` locale: `p` => `HH:mm`\n *\n * Values will be checked in the descending order of its unit's priority.\n * Units of an equal priority overwrite each other in the order of appearance.\n *\n * If no values of higher priority are matched (e.g. when matching string 'January 1st' without a year),\n * the values will be taken from today's using `new Date()` date which works as a context of parsing.\n *\n * The result may vary by locale.\n *\n * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.\n *\n *\n *\n * @param {String} dateString - the date string to verify\n * @param {String} formatString - the string of tokens\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {Boolean}\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} `options.locale` must contain `match` property\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Match 11 February 2014 from middle-endian format:\n * var result = isMatch('02/11/2014', 'MM/dd/yyyy')\n * //=> true\n *\n * @example\n * // Match 28th of February in Esperanto locale in the context of 2010 year:\n * import eo from 'date-fns/locale/eo'\n * var result = isMatch('28-a de februaro', \"do 'de' MMMM\", {\n *   locale: eo\n * })\n * //=> true\n */\n\nexport default function isMatch(dateString, formatString, dirtyOptions) {\n  requiredArgs(2, arguments);\n  return isValid(parse(dateString, formatString, new Date(), dirtyOptions));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isMonday\n * @category Weekday Helpers\n * @summary Is the given date Monday?\n *\n * @description\n * Is the given date Monday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Monday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 22 September 2014 Monday?\n * var result = isMonday(new Date(2014, 8, 22))\n * //=> true\n */\n\nexport default function isMonday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isPast\n * @category Common Helpers\n * @summary Is the given date in the past?\n * @pure false\n *\n * @description\n * Is the given date in the past?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the past\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 2 July 2014 in the past?\n * var result = isPast(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isPast(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getTime() < Date.now();\n}","import startOfDay from '../startOfDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameDay\n * @category Day Helpers\n * @summary Are the given dates in the same day?\n *\n * @description\n * Are the given dates in the same day?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same day\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?\n * var result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))\n * //=> true\n */\n\nexport default function isSameDay(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfDay = startOfDay(dirtyDateLeft);\n  var dateRightStartOfDay = startOfDay(dirtyDateRight);\n  return dateLeftStartOfDay.getTime() === dateRightStartOfDay.getTime();\n}","import startOfHour from '../startOfHour/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameHour\n * @category Hour Helpers\n * @summary Are the given dates in the same hour?\n *\n * @description\n * Are the given dates in the same hour?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same hour\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:00:00 and 4 September 06:30:00 in the same hour?\n * var result = isSameHour(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 6, 30))\n * //=> true\n */\n\nexport default function isSameHour(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfHour = startOfHour(dirtyDateLeft);\n  var dateRightStartOfHour = startOfHour(dirtyDateRight);\n  return dateLeftStartOfHour.getTime() === dateRightStartOfHour.getTime();\n}","import isSameWeek from '../isSameWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameISOWeek\n * @category ISO Week Helpers\n * @summary Are the given dates in the same ISO week?\n *\n * @description\n * Are the given dates in the same ISO week?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same ISO week\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 1 September 2014 and 7 September 2014 in the same ISO week?\n * var result = isSameISOWeek(new Date(2014, 8, 1), new Date(2014, 8, 7))\n * //=> true\n */\n\nexport default function isSameISOWeek(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  return isSameWeek(dirtyDateLeft, dirtyDateRight, {\n    weekStartsOn: 1\n  });\n}","import startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Are the given dates in the same ISO week-numbering year?\n *\n * @description\n * Are the given dates in the same ISO week-numbering year?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `isSameISOYear` to `isSameISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same ISO week-numbering year\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 29 December 2003 and 2 January 2005 in the same ISO week-numbering year?\n * var result = isSameISOWeekYear(new Date(2003, 11, 29), new Date(2005, 0, 2))\n * //=> true\n */\n\nexport default function isSameISOWeekYear(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfYear = startOfISOWeekYear(dirtyDateLeft);\n  var dateRightStartOfYear = startOfISOWeekYear(dirtyDateRight);\n  return dateLeftStartOfYear.getTime() === dateRightStartOfYear.getTime();\n}","import startOfMinute from '../startOfMinute/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameMinute\n * @category Minute Helpers\n * @summary Are the given dates in the same minute?\n *\n * @description\n * Are the given dates in the same minute?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same minute\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:30:00 and 4 September 2014 06:30:15\n * // in the same minute?\n * var result = isSameMinute(\n *   new Date(2014, 8, 4, 6, 30),\n *   new Date(2014, 8, 4, 6, 30, 15)\n * )\n * //=> true\n */\n\nexport default function isSameMinute(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfMinute = startOfMinute(dirtyDateLeft);\n  var dateRightStartOfMinute = startOfMinute(dirtyDateRight);\n  return dateLeftStartOfMinute.getTime() === dateRightStartOfMinute.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameMonth\n * @category Month Helpers\n * @summary Are the given dates in the same month?\n *\n * @description\n * Are the given dates in the same month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same month\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 September 2014 and 25 September 2014 in the same month?\n * var result = isSameMonth(new Date(2014, 8, 2), new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isSameMonth(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() === dateRight.getFullYear() && dateLeft.getMonth() === dateRight.getMonth();\n}","import startOfQuarter from '../startOfQuarter/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameQuarter\n * @category Quarter Helpers\n * @summary Are the given dates in the same year quarter?\n *\n * @description\n * Are the given dates in the same year quarter?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same quarter\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 1 January 2014 and 8 March 2014 in the same quarter?\n * var result = isSameQuarter(new Date(2014, 0, 1), new Date(2014, 2, 8))\n * //=> true\n */\n\nexport default function isSameQuarter(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfQuarter = startOfQuarter(dirtyDateLeft);\n  var dateRightStartOfQuarter = startOfQuarter(dirtyDateRight);\n  return dateLeftStartOfQuarter.getTime() === dateRightStartOfQuarter.getTime();\n}","import startOfSecond from '../startOfSecond/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameSecond\n * @category Second Helpers\n * @summary Are the given dates in the same second?\n *\n * @description\n * Are the given dates in the same second?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same second\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:30:15.000 and 4 September 2014 06:30.15.500\n * // in the same second?\n * var result = isSameSecond(\n *   new Date(2014, 8, 4, 6, 30, 15),\n *   new Date(2014, 8, 4, 6, 30, 15, 500)\n * )\n * //=> true\n */\n\nexport default function isSameSecond(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfSecond = startOfSecond(dirtyDateLeft);\n  var dateRightStartOfSecond = startOfSecond(dirtyDateRight);\n  return dateLeftStartOfSecond.getTime() === dateRightStartOfSecond.getTime();\n}","import startOfWeek from '../startOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameWeek\n * @category Week Helpers\n * @summary Are the given dates in the same week?\n *\n * @description\n * Are the given dates in the same week?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Boolean} the dates are in the same week\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Are 31 August 2014 and 4 September 2014 in the same week?\n * var result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4))\n * //=> true\n *\n * @example\n * // If week starts with Monday,\n * // are 31 August 2014 and 4 September 2014 in the same week?\n * var result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4), {\n *   weekStartsOn: 1\n * })\n * //=> false\n */\n\nexport default function isSameWeek(dirtyDateLeft, dirtyDateRight, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfWeek = startOfWeek(dirtyDateLeft, dirtyOptions);\n  var dateRightStartOfWeek = startOfWeek(dirtyDateRight, dirtyOptions);\n  return dateLeftStartOfWeek.getTime() === dateRightStartOfWeek.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameYear\n * @category Year Helpers\n * @summary Are the given dates in the same year?\n *\n * @description\n * Are the given dates in the same year?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same year\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 September 2014 and 25 September 2014 in the same year?\n * var result = isSameYear(new Date(2014, 8, 2), new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isSameYear(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() === dateRight.getFullYear();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSaturday\n * @category Weekday Helpers\n * @summary Is the given date Saturday?\n *\n * @description\n * Is the given date Saturday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Saturday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 27 September 2014 Saturday?\n * var result = isSaturday(new Date(2014, 8, 27))\n * //=> true\n */\n\nexport default function isSaturday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 6;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSunday\n * @category Weekday Helpers\n * @summary Is the given date Sunday?\n *\n * @description\n * Is the given date Sunday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Sunday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 21 September 2014 Sunday?\n * var result = isSunday(new Date(2014, 8, 21))\n * //=> true\n */\n\nexport default function isSunday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 0;\n}","import isSameHour from '../isSameHour/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisHour\n * @category Hour Helpers\n * @summary Is the given date in the same hour as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same hour as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:00:00 in this hour?\n * var result = isThisHour(new Date(2014, 8, 25, 18))\n * //=> true\n */\n\nexport default function isThisHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameHour(Date.now(), dirtyDate);\n}","import isSameISOWeek from '../isSameISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisISOWeek\n * @category ISO Week Helpers\n * @summary Is the given date in the same ISO week as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same ISO week as the current date?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 22 September 2014 in this ISO week?\n * var result = isThisISOWeek(new Date(2014, 8, 22))\n * //=> true\n */\n\nexport default function isThisISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameISOWeek(dirtyDate, Date.now());\n}","import isSameMinute from '../isSameMinute/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisMinute\n * @category Minute Helpers\n * @summary Is the given date in the same minute as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same minute as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:30:00 in this minute?\n * var result = isThisMinute(new Date(2014, 8, 25, 18, 30))\n * //=> true\n */\n\nexport default function isThisMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameMinute(Date.now(), dirtyDate);\n}","import isSameMonth from '../isSameMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisMonth\n * @category Month Helpers\n * @summary Is the given date in the same month as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same month as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 15 September 2014 in this month?\n * var result = isThisMonth(new Date(2014, 8, 15))\n * //=> true\n */\n\nexport default function isThisMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameMonth(Date.now(), dirtyDate);\n}","import isSameQuarter from '../isSameQuarter/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisQuarter\n * @category Quarter Helpers\n * @summary Is the given date in the same quarter as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same quarter as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 2 July 2014 in this quarter?\n * var result = isThisQuarter(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isThisQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameQuarter(Date.now(), dirtyDate);\n}","import isSameSecond from '../isSameSecond/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisSecond\n * @category Second Helpers\n * @summary Is the given date in the same second as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same second as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:30:15.000 in this second?\n * var result = isThisSecond(new Date(2014, 8, 25, 18, 30, 15))\n * //=> true\n */\n\nexport default function isThisSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameSecond(Date.now(), dirtyDate);\n}","import isSameWeek from '../isSameWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisWeek\n * @category Week Helpers\n * @summary Is the given date in the same week as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same week as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @param {Object} [options] - the object with options\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Boolean} the date is in this week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // If today is 25 September 2014, is 21 September 2014 in this week?\n * var result = isThisWeek(new Date(2014, 8, 21))\n * //=> true\n *\n * @example\n * // If today is 25 September 2014 and week starts with Monday\n * // is 21 September 2014 in this week?\n * var result = isThisWeek(new Date(2014, 8, 21), { weekStartsOn: 1 })\n * //=> false\n */\n\nexport default function isThisWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  return isSameWeek(dirtyDate, Date.now(), options);\n}","import isSameYear from '../isSameYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisYear\n * @category Year Helpers\n * @summary Is the given date in the same year as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same year as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 2 July 2014 in this year?\n * var result = isThisYear(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isThisYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameYear(dirtyDate, Date.now());\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThursday\n * @category Weekday Helpers\n * @summary Is the given date Thursday?\n *\n * @description\n * Is the given date Thursday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Thursday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 25 September 2014 Thursday?\n * var result = isThursday(new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isThursday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 4;\n}","import isSameDay from '../isSameDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isToday\n * @category Day Helpers\n * @summary Is the given date today?\n * @pure false\n *\n * @description\n * Is the given date today?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is today\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 6 October 14:00:00 today?\n * var result = isToday(new Date(2014, 9, 6, 14, 0))\n * //=> true\n */\n\nexport default function isToday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, Date.now());\n}","import addDays from '../addDays/index.js';\nimport isSameDay from '../isSameDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isTomorrow\n * @category Day Helpers\n * @summary Is the given date tomorrow?\n * @pure false\n *\n * @description\n * Is the given date tomorrow?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is tomorrow\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 7 October 14:00:00 tomorrow?\n * var result = isTomorrow(new Date(2014, 9, 7, 14, 0))\n * //=> true\n */\n\nexport default function isTomorrow(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, addDays(Date.now(), 1));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isTuesday\n * @category Weekday Helpers\n * @summary Is the given date Tuesday?\n *\n * @description\n * Is the given date Tuesday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Tuesday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 23 September 2014 Tuesday?\n * var result = isTuesday(new Date(2014, 8, 23))\n * //=> true\n */\n\nexport default function isTuesday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 2;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now `isValid` doesn't throw an exception\n *   if the first argument is not an instance of Date.\n *   Instead, argument is converted beforehand using `toDate`.\n *\n *   Examples:\n *\n *   | `isValid` argument        | Before v2.0.0 | v2.0.0 onward |\n *   |---------------------------|---------------|---------------|\n *   | `new Date()`              | `true`        | `true`        |\n *   | `new Date('2016-01-01')`  | `true`        | `true`        |\n *   | `new Date('')`            | `false`       | `false`       |\n *   | `new Date(1488370835081)` | `true`        | `true`        |\n *   | `new Date(NaN)`           | `false`       | `false`       |\n *   | `'2016-01-01'`            | `TypeError`   | `false`       |\n *   | `''`                      | `TypeError`   | `false`       |\n *   | `1488370835081`           | `TypeError`   | `true`        |\n *   | `NaN`                     | `TypeError`   | `false`       |\n *\n *   We introduce this change to make *date-fns* consistent with ECMAScript behavior\n *   that try to coerce arguments to the expected type\n *   (which is also the case with other *date-fns* functions).\n *\n * @param {*} date - the date to check\n * @returns {Boolean} the date is valid\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // For the valid date:\n * var result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * var result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * var result = isValid(new Date(''))\n * //=> false\n */\n\nexport default function isValid(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  return !isNaN(date);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWednesday\n * @category Weekday Helpers\n * @summary Is the given date Wednesday?\n *\n * @description\n * Is the given date Wednesday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Wednesday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 24 September 2014 Wednesday?\n * var result = isWednesday(new Date(2014, 8, 24))\n * //=> true\n */\n\nexport default function isWednesday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 3;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWeekend\n * @category Weekday Helpers\n * @summary Does the given date fall on a weekend?\n *\n * @description\n * Does the given date fall on a weekend?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date falls on a weekend\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Does 5 October 2014 fall on a weekend?\n * var result = isWeekend(new Date(2014, 9, 5))\n * //=> true\n */\n\nexport default function isWeekend(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  return day === 0 || day === 6;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWithinInterval\n * @category Interval Helpers\n * @summary Is the given date within the interval?\n *\n * @description\n * Is the given date within the interval? (Including start and end.)\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `isWithinRange` to `isWithinInterval`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   isWithinRange(\n *     new Date(2014, 0, 3),\n *     new Date(2014, 0, 1), new Date(2014, 0, 7)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   isWithinInterval(\n *     new Date(2014, 0, 3),\n *     { start: new Date(2014, 0, 1), end: new Date(2014, 0, 7) }\n *   )\n *   ```\n *\n * @param {Date|Number} date - the date to check\n * @param {Interval} interval - the interval to check\n * @returns {Boolean} the date is within the interval\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For the date within the interval:\n * isWithinInterval(new Date(2014, 0, 3), {\n *   start: new Date(2014, 0, 1),\n *   end: new Date(2014, 0, 7)\n * })\n * //=> true\n *\n * @example\n * // For the date outside of the interval:\n * isWithinInterval(new Date(2014, 0, 10), {\n *   start: new Date(2014, 0, 1),\n *   end: new Date(2014, 0, 7)\n * })\n * //=> false\n *\n * @example\n * // For date equal to interval start:\n * isWithinInterval(date, { start, end: date }) // => true\n *\n * @example\n * // For date equal to interval end:\n * isWithinInterval(date, { start: date, end }) // => true\n */\n\nexport default function isWithinInterval(dirtyDate, dirtyInterval) {\n  requiredArgs(2, arguments);\n  var interval = dirtyInterval || {};\n  var time = toDate(dirtyDate).getTime();\n  var startTime = toDate(interval.start).getTime();\n  var endTime = toDate(interval.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startTime <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  return time >= startTime && time <= endTime;\n}","import isSameDay from '../isSameDay/index.js';\nimport subDays from '../subDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isYesterday\n * @category Day Helpers\n * @summary Is the given date yesterday?\n * @pure false\n *\n * @description\n * Is the given date yesterday?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is yesterday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 5 October 14:00:00 yesterday?\n * var result = isYesterday(new Date(2014, 9, 5, 14, 0))\n * //=> true\n */\n\nexport default function isYesterday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, subDays(Date.now(), 1));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfDecade\n * @category Decade Helpers\n * @summary Return the last day of a decade for the given date.\n *\n * @description\n * Return the last day of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a decade for 21 December 2012 21:12:00:\n * var result = lastDayOfDecade(new Date(2012, 11, 21, 21, 12, 00))\n * //=> Wed Dec 31 2019 00:00:00\n */\n\nexport default function lastDayOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = 9 + Math.floor(year / 10) * 10;\n  date.setFullYear(decade + 1, 0, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import lastDayOfWeek from '../lastDayOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the last day of an ISO week for the given date.\n *\n * @description\n * Return the last day of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of an ISO week for 2 September 2014 11:55:00:\n * var result = lastDayOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function lastDayOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return lastDayOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the last day of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the last day of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `lastDayOfISOYear` to `lastDayOfISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of an ISO week-numbering year for 2 July 2005:\n * var result = lastDayOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Sun Jan 01 2006 00:00:00\n */\n\nexport default function lastDayOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(year + 1, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuary);\n  date.setDate(date.getDate() - 1);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfMonth\n * @category Month Helpers\n * @summary Return the last day of a month for the given date.\n *\n * @description\n * Return the last day of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a month for 2 September 2014 11:55:00:\n * var result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function lastDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  date.setFullYear(date.getFullYear(), month + 1, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfQuarter\n * @category Quarter Helpers\n * @summary Return the last day of a year quarter for the given date.\n *\n * @description\n * Return the last day of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * @returns {Date} the last day of a quarter\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // The last day of a quarter for 2 September 2014 11:55:00:\n * var result = lastDayOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function lastDayOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3 + 3;\n  date.setMonth(month, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfWeek\n * @category Week Helpers\n * @summary Return the last day of a week for the given date.\n *\n * @description\n * Return the last day of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the last day of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The last day of a week for 2 September 2014 11:55:00:\n * var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sat Sep 06 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the last day of the week for 2 September 2014 11:55:00:\n * var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function lastDayOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);\n  date.setHours(0, 0, 0, 0);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfYear\n * @category Year Helpers\n * @summary Return the last day of a year for the given date.\n *\n * @description\n * Return the last day of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a year for 2 September 2014 11:55:00:\n * var result = lastDayOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Dec 31 2014 00:00:00\n */\n\nexport default function lastDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  date.setFullYear(year + 1, 0, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport formatters from '../_lib/format/lightFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport isValid from '../isValid/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // This RegExp consists of three parts separated by `|`:\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /(\\w)\\1*|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name lightFormat\n * @category Common Helpers\n * @summary Format the date.\n *\n * @description\n * Return the formatted date string in the given format. Unlike `format`,\n * `lightFormat` doesn't use locales and outputs date using the most popular tokens.\n *\n * > ⚠️ Please note that the `lightFormat` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n *\n * Accepted patterns:\n * | Unit                            | Pattern | Result examples                   |\n * |---------------------------------|---------|-----------------------------------|\n * | AM, PM                          | a..aaa  | AM, PM                            |\n * |                                 | aaaa    | a.m., p.m.                        |\n * |                                 | aaaaa   | a, p                              |\n * | Calendar year                   | y       | 44, 1, 1900, 2017                 |\n * |                                 | yy      | 44, 01, 00, 17                    |\n * |                                 | yyy     | 044, 001, 000, 017                |\n * |                                 | yyyy    | 0044, 0001, 1900, 2017            |\n * | Month (formatting)              | M       | 1, 2, ..., 12                     |\n * |                                 | MM      | 01, 02, ..., 12                   |\n * | Day of month                    | d       | 1, 2, ..., 31                     |\n * |                                 | dd      | 01, 02, ..., 31                   |\n * | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |\n * |                                 | hh      | 01, 02, ..., 11, 12               |\n * | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |\n * |                                 | HH      | 00, 01, 02, ..., 23               |\n * | Minute                          | m       | 0, 1, ..., 59                     |\n * |                                 | mm      | 00, 01, ..., 59                   |\n * | Second                          | s       | 0, 1, ..., 59                     |\n * |                                 | ss      | 00, 01, ..., 59                   |\n * | Fraction of second              | S       | 0, 1, ..., 9                      |\n * |                                 | SS      | 00, 01, ..., 99                   |\n * |                                 | SSS     | 000, 0001, ..., 999               |\n * |                                 | SSSS    | ...                               |\n *\n * @param {Date|Number} date - the original date\n * @param {String} format - the string of tokens\n * @returns {String} the formatted date string\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * var result = lightFormat(new Date(2014, 1, 11), 'yyyy-MM-dd')\n * //=> '2014-02-11'\n */\n\nexport default function lightFormat(dirtyDate, dirtyFormatStr) {\n  requiredArgs(2, arguments);\n  var formatStr = String(dirtyFormatStr);\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376\n\n\n  var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);\n  var utcDate = subMilliseconds(originalDate, timezoneOffset);\n  var result = formatStr.match(formattingTokensRegExp).map(function (substring) {\n    // Replace two single quote characters with one single quote character\n    if (substring === \"''\") {\n      return \"'\";\n    }\n\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === \"'\") {\n      return cleanEscapedString(substring);\n    }\n\n    var formatter = formatters[firstCharacter];\n\n    if (formatter) {\n      return formatter(utcDate, substring, null, {});\n    }\n\n    if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n      throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n    }\n\n    return substring;\n  }).join('');\n  return result;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","export default function buildFormatLongFn(args) {\n  return function (dirtyOptions) {\n    var options = dirtyOptions || {};\n    var width = options.width ? String(options.width) : args.defaultWidth;\n    var format = args.formats[width] || args.formats[args.defaultWidth];\n    return format;\n  };\n}","export default function buildLocalizeFn(args) {\n  return function (dirtyIndex, dirtyOptions) {\n    var options = dirtyOptions || {};\n    var context = options.context ? String(options.context) : 'standalone';\n    var valuesArray;\n\n    if (context === 'formatting' && args.formattingValues) {\n      var defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n      var width = options.width ? String(options.width) : defaultWidth;\n      valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];\n    } else {\n      var _defaultWidth = args.defaultWidth;\n\n      var _width = options.width ? String(options.width) : args.defaultWidth;\n\n      valuesArray = args.values[_width] || args.values[_defaultWidth];\n    }\n\n    var index = args.argumentCallback ? args.argumentCallback(dirtyIndex) : dirtyIndex;\n    return valuesArray[index];\n  };\n}","export default function buildMatchFn(args) {\n  return function (dirtyString, dirtyOptions) {\n    var string = String(dirtyString);\n    var options = dirtyOptions || {};\n    var width = options.width;\n    var matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];\n    var matchResult = string.match(matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n\n    var matchedString = matchResult[0];\n    var parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];\n    var value;\n\n    if (Object.prototype.toString.call(parsePatterns) === '[object Array]') {\n      value = findIndex(parsePatterns, function (pattern) {\n        return pattern.test(matchedString);\n      });\n    } else {\n      value = findKey(parsePatterns, function (pattern) {\n        return pattern.test(matchedString);\n      });\n    }\n\n    value = args.valueCallback ? args.valueCallback(value) : value;\n    value = options.valueCallback ? options.valueCallback(value) : value;\n    return {\n      value: value,\n      rest: string.slice(matchedString.length)\n    };\n  };\n}\n\nfunction findKey(object, predicate) {\n  for (var key in object) {\n    if (object.hasOwnProperty(key) && predicate(object[key])) {\n      return key;\n    }\n  }\n}\n\nfunction findIndex(array, predicate) {\n  for (var key = 0; key < array.length; key++) {\n    if (predicate(array[key])) {\n      return key;\n    }\n  }\n}","export default function buildMatchPatternFn(args) {\n  return function (dirtyString, dirtyOptions) {\n    var string = String(dirtyString);\n    var options = dirtyOptions || {};\n    var matchResult = string.match(args.matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n\n    var matchedString = matchResult[0];\n    var parseResult = string.match(args.parsePattern);\n\n    if (!parseResult) {\n      return null;\n    }\n\n    var value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];\n    value = options.valueCallback ? options.valueCallback(value) : value;\n    return {\n      value: value,\n      rest: string.slice(matchedString.length)\n    };\n  };\n}","var formatDistanceLocale = {\n  lessThanXSeconds: {\n    one: 'less than a second',\n    other: 'less than {{count}} seconds'\n  },\n  xSeconds: {\n    one: '1 second',\n    other: '{{count}} seconds'\n  },\n  halfAMinute: 'half a minute',\n  lessThanXMinutes: {\n    one: 'less than a minute',\n    other: 'less than {{count}} minutes'\n  },\n  xMinutes: {\n    one: '1 minute',\n    other: '{{count}} minutes'\n  },\n  aboutXHours: {\n    one: 'about 1 hour',\n    other: 'about {{count}} hours'\n  },\n  xHours: {\n    one: '1 hour',\n    other: '{{count}} hours'\n  },\n  xDays: {\n    one: '1 day',\n    other: '{{count}} days'\n  },\n  aboutXWeeks: {\n    one: 'about 1 week',\n    other: 'about {{count}} weeks'\n  },\n  xWeeks: {\n    one: '1 week',\n    other: '{{count}} weeks'\n  },\n  aboutXMonths: {\n    one: 'about 1 month',\n    other: 'about {{count}} months'\n  },\n  xMonths: {\n    one: '1 month',\n    other: '{{count}} months'\n  },\n  aboutXYears: {\n    one: 'about 1 year',\n    other: 'about {{count}} years'\n  },\n  xYears: {\n    one: '1 year',\n    other: '{{count}} years'\n  },\n  overXYears: {\n    one: 'over 1 year',\n    other: 'over {{count}} years'\n  },\n  almostXYears: {\n    one: 'almost 1 year',\n    other: 'almost {{count}} years'\n  }\n};\nexport default function formatDistance(token, count, options) {\n  options = options || {};\n  var result;\n\n  if (typeof formatDistanceLocale[token] === 'string') {\n    result = formatDistanceLocale[token];\n  } else if (count === 1) {\n    result = formatDistanceLocale[token].one;\n  } else {\n    result = formatDistanceLocale[token].other.replace('{{count}}', count);\n  }\n\n  if (options.addSuffix) {\n    if (options.comparison > 0) {\n      return 'in ' + result;\n    } else {\n      return result + ' ago';\n    }\n  }\n\n  return result;\n}","import buildFormatLongFn from '../../../_lib/buildFormatLongFn/index.js';\nvar dateFormats = {\n  full: 'EEEE, MMMM do, y',\n  long: 'MMMM do, y',\n  medium: 'MMM d, y',\n  short: 'MM/dd/yyyy'\n};\nvar timeFormats = {\n  full: 'h:mm:ss a zzzz',\n  long: 'h:mm:ss a z',\n  medium: 'h:mm:ss a',\n  short: 'h:mm a'\n};\nvar dateTimeFormats = {\n  full: \"{{date}} 'at' {{time}}\",\n  long: \"{{date}} 'at' {{time}}\",\n  medium: '{{date}}, {{time}}',\n  short: '{{date}}, {{time}}'\n};\nvar formatLong = {\n  date: buildFormatLongFn({\n    formats: dateFormats,\n    defaultWidth: 'full'\n  }),\n  time: buildFormatLongFn({\n    formats: timeFormats,\n    defaultWidth: 'full'\n  }),\n  dateTime: buildFormatLongFn({\n    formats: dateTimeFormats,\n    defaultWidth: 'full'\n  })\n};\nexport default formatLong;","var formatRelativeLocale = {\n  lastWeek: \"'last' eeee 'at' p\",\n  yesterday: \"'yesterday at' p\",\n  today: \"'today at' p\",\n  tomorrow: \"'tomorrow at' p\",\n  nextWeek: \"eeee 'at' p\",\n  other: 'P'\n};\nexport default function formatRelative(token, _date, _baseDate, _options) {\n  return formatRelativeLocale[token];\n}","import buildLocalizeFn from '../../../_lib/buildLocalizeFn/index.js';\nvar eraValues = {\n  narrow: ['B', 'A'],\n  abbreviated: ['BC', 'AD'],\n  wide: ['Before Christ', 'Anno Domini']\n};\nvar quarterValues = {\n  narrow: ['1', '2', '3', '4'],\n  abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'],\n  wide: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'] // Note: in English, the names of days of the week and months are capitalized.\n  // If you are making a new locale based on this one, check if the same is true for the language you're working on.\n  // Generally, formatted dates should look like they are in the middle of a sentence,\n  // e.g. in Spanish language the weekdays and months should be in the lowercase.\n\n};\nvar monthValues = {\n  narrow: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],\n  abbreviated: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n  wide: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n};\nvar dayValues = {\n  narrow: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],\n  short: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\n  abbreviated: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n  wide: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n};\nvar dayPeriodValues = {\n  narrow: {\n    am: 'a',\n    pm: 'p',\n    midnight: 'mi',\n    noon: 'n',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  },\n  abbreviated: {\n    am: 'AM',\n    pm: 'PM',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  },\n  wide: {\n    am: 'a.m.',\n    pm: 'p.m.',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  }\n};\nvar formattingDayPeriodValues = {\n  narrow: {\n    am: 'a',\n    pm: 'p',\n    midnight: 'mi',\n    noon: 'n',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  },\n  abbreviated: {\n    am: 'AM',\n    pm: 'PM',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  },\n  wide: {\n    am: 'a.m.',\n    pm: 'p.m.',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  }\n};\n\nfunction ordinalNumber(dirtyNumber, _dirtyOptions) {\n  var number = Number(dirtyNumber); // If ordinal numbers depend on context, for example,\n  // if they are different for different grammatical genders,\n  // use `options.unit`:\n  //\n  //   var options = dirtyOptions || {}\n  //   var unit = String(options.unit)\n  //\n  // where `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',\n  // 'day', 'hour', 'minute', 'second'\n\n  var rem100 = number % 100;\n\n  if (rem100 > 20 || rem100 < 10) {\n    switch (rem100 % 10) {\n      case 1:\n        return number + 'st';\n\n      case 2:\n        return number + 'nd';\n\n      case 3:\n        return number + 'rd';\n    }\n  }\n\n  return number + 'th';\n}\n\nvar localize = {\n  ordinalNumber: ordinalNumber,\n  era: buildLocalizeFn({\n    values: eraValues,\n    defaultWidth: 'wide'\n  }),\n  quarter: buildLocalizeFn({\n    values: quarterValues,\n    defaultWidth: 'wide',\n    argumentCallback: function (quarter) {\n      return Number(quarter) - 1;\n    }\n  }),\n  month: buildLocalizeFn({\n    values: monthValues,\n    defaultWidth: 'wide'\n  }),\n  day: buildLocalizeFn({\n    values: dayValues,\n    defaultWidth: 'wide'\n  }),\n  dayPeriod: buildLocalizeFn({\n    values: dayPeriodValues,\n    defaultWidth: 'wide',\n    formattingValues: formattingDayPeriodValues,\n    defaultFormattingWidth: 'wide'\n  })\n};\nexport default localize;","import buildMatchPatternFn from '../../../_lib/buildMatchPatternFn/index.js';\nimport buildMatchFn from '../../../_lib/buildMatchFn/index.js';\nvar matchOrdinalNumberPattern = /^(\\d+)(th|st|nd|rd)?/i;\nvar parseOrdinalNumberPattern = /\\d+/i;\nvar matchEraPatterns = {\n  narrow: /^(b|a)/i,\n  abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n  wide: /^(before christ|before common era|anno domini|common era)/i\n};\nvar parseEraPatterns = {\n  any: [/^b/i, /^(a|c)/i]\n};\nvar matchQuarterPatterns = {\n  narrow: /^[1234]/i,\n  abbreviated: /^q[1234]/i,\n  wide: /^[1234](th|st|nd|rd)? quarter/i\n};\nvar parseQuarterPatterns = {\n  any: [/1/i, /2/i, /3/i, /4/i]\n};\nvar matchMonthPatterns = {\n  narrow: /^[jfmasond]/i,\n  abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n  wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i\n};\nvar parseMonthPatterns = {\n  narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],\n  any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i]\n};\nvar matchDayPatterns = {\n  narrow: /^[smtwf]/i,\n  short: /^(su|mo|tu|we|th|fr|sa)/i,\n  abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n  wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i\n};\nvar parseDayPatterns = {\n  narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n  any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]\n};\nvar matchDayPeriodPatterns = {\n  narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n  any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i\n};\nvar parseDayPeriodPatterns = {\n  any: {\n    am: /^a/i,\n    pm: /^p/i,\n    midnight: /^mi/i,\n    noon: /^no/i,\n    morning: /morning/i,\n    afternoon: /afternoon/i,\n    evening: /evening/i,\n    night: /night/i\n  }\n};\nvar match = {\n  ordinalNumber: buildMatchPatternFn({\n    matchPattern: matchOrdinalNumberPattern,\n    parsePattern: parseOrdinalNumberPattern,\n    valueCallback: function (value) {\n      return parseInt(value, 10);\n    }\n  }),\n  era: buildMatchFn({\n    matchPatterns: matchEraPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseEraPatterns,\n    defaultParseWidth: 'any'\n  }),\n  quarter: buildMatchFn({\n    matchPatterns: matchQuarterPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseQuarterPatterns,\n    defaultParseWidth: 'any',\n    valueCallback: function (index) {\n      return index + 1;\n    }\n  }),\n  month: buildMatchFn({\n    matchPatterns: matchMonthPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseMonthPatterns,\n    defaultParseWidth: 'any'\n  }),\n  day: buildMatchFn({\n    matchPatterns: matchDayPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseDayPatterns,\n    defaultParseWidth: 'any'\n  }),\n  dayPeriod: buildMatchFn({\n    matchPatterns: matchDayPeriodPatterns,\n    defaultMatchWidth: 'any',\n    parsePatterns: parseDayPeriodPatterns,\n    defaultParseWidth: 'any'\n  })\n};\nexport default match;","import formatDistance from './_lib/formatDistance/index.js';\nimport formatLong from './_lib/formatLong/index.js';\nimport formatRelative from './_lib/formatRelative/index.js';\nimport localize from './_lib/localize/index.js';\nimport match from './_lib/match/index.js';\n/**\n * @type {Locale}\n * @category Locales\n * @summary English locale (United States).\n * @language English\n * @iso-639-2 eng\n * @author Sasha Koss [@kossnocorp]{@link https://github.com/kossnocorp}\n * @author Lesha Koss [@leshakoss]{@link https://github.com/leshakoss}\n */\n\nvar locale = {\n  code: 'en-US',\n  formatDistance: formatDistance,\n  formatLong: formatLong,\n  formatRelative: formatRelative,\n  localize: localize,\n  match: match,\n  options: {\n    weekStartsOn: 0\n    /* Sunday */\n    ,\n    firstWeekContainsDate: 1\n  }\n};\nexport default locale;","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name max\n * @category Common Helpers\n * @summary Return the latest of the given dates.\n *\n * @description\n * Return the latest of the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - `max` function now accepts an array of dates rather than spread arguments.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   var date1 = new Date(1989, 6, 10)\n *   var date2 = new Date(1987, 1, 11)\n *   var maxDate = max(date1, date2)\n *\n *   // v2.0.0 onward:\n *   var dates = [new Date(1989, 6, 10), new Date(1987, 1, 11)]\n *   var maxDate = max(dates)\n *   ```\n *\n * @param {Date[]|Number[]} datesArray - the dates to compare\n * @returns {Date} the latest of the dates\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which of these dates is the latest?\n * var result = max([\n *   new Date(1989, 6, 10),\n *   new Date(1987, 1, 11),\n *   new Date(1995, 6, 2),\n *   new Date(1990, 0, 1)\n * ])\n * //=> Sun Jul 02 1995 00:00:00\n */\n\nexport default function max(dirtyDatesArray) {\n  requiredArgs(1, arguments);\n  var datesArray; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n\n  if (dirtyDatesArray && typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array.\n  } else if (typeof dirtyDatesArray === 'object' && dirtyDatesArray !== null) {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  } else {\n    // `dirtyDatesArray` is non-iterable, return Invalid Date\n    return new Date(NaN);\n  }\n\n  var result;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (result === undefined || result < currentDate || isNaN(currentDate)) {\n      result = currentDate;\n    }\n  });\n  return result || new Date(NaN);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name min\n * @category Common Helpers\n * @summary Return the earliest of the given dates.\n *\n * @description\n * Return the earliest of the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - `min` function now accepts an array of dates rather than spread arguments.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   var date1 = new Date(1989, 6, 10)\n *   var date2 = new Date(1987, 1, 11)\n *   var minDate = min(date1, date2)\n *\n *   // v2.0.0 onward:\n *   var dates = [new Date(1989, 6, 10), new Date(1987, 1, 11)]\n *   var minDate = min(dates)\n *   ```\n *\n * @param {Date[]|Number[]} datesArray - the dates to compare\n * @returns {Date} the earliest of the dates\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which of these dates is the earliest?\n * var result = min([\n *   new Date(1989, 6, 10),\n *   new Date(1987, 1, 11),\n *   new Date(1995, 6, 2),\n *   new Date(1990, 0, 1)\n * ])\n * //=> Wed Feb 11 1987 00:00:00\n */\n\nexport default function min(dirtyDatesArray) {\n  requiredArgs(1, arguments);\n  var datesArray; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n\n  if (dirtyDatesArray && typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array.\n  } else if (typeof dirtyDatesArray === 'object' && dirtyDatesArray !== null) {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  } else {\n    // `dirtyDatesArray` is non-iterable, return Invalid Date\n    return new Date(NaN);\n  }\n\n  var result;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (result === undefined || result > currentDate || isNaN(currentDate)) {\n      result = currentDate;\n    }\n  });\n  return result || new Date(NaN);\n}","import getUTCWeekYear from '../../../_lib/getUTCWeekYear/index.js';\nimport setUTCDay from '../../../_lib/setUTCDay/index.js';\nimport setUTCISODay from '../../../_lib/setUTCISODay/index.js';\nimport setUTCISOWeek from '../../../_lib/setUTCISOWeek/index.js';\nimport setUTCWeek from '../../../_lib/setUTCWeek/index.js';\nimport startOfUTCISOWeek from '../../../_lib/startOfUTCISOWeek/index.js';\nimport startOfUTCWeek from '../../../_lib/startOfUTCWeek/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar MILLISECONDS_IN_SECOND = 1000;\nvar numericPatterns = {\n  month: /^(1[0-2]|0?\\d)/,\n  // 0 to 12\n  date: /^(3[0-1]|[0-2]?\\d)/,\n  // 0 to 31\n  dayOfYear: /^(36[0-6]|3[0-5]\\d|[0-2]?\\d?\\d)/,\n  // 0 to 366\n  week: /^(5[0-3]|[0-4]?\\d)/,\n  // 0 to 53\n  hour23h: /^(2[0-3]|[0-1]?\\d)/,\n  // 0 to 23\n  hour24h: /^(2[0-4]|[0-1]?\\d)/,\n  // 0 to 24\n  hour11h: /^(1[0-1]|0?\\d)/,\n  // 0 to 11\n  hour12h: /^(1[0-2]|0?\\d)/,\n  // 0 to 12\n  minute: /^[0-5]?\\d/,\n  // 0 to 59\n  second: /^[0-5]?\\d/,\n  // 0 to 59\n  singleDigit: /^\\d/,\n  // 0 to 9\n  twoDigits: /^\\d{1,2}/,\n  // 0 to 99\n  threeDigits: /^\\d{1,3}/,\n  // 0 to 999\n  fourDigits: /^\\d{1,4}/,\n  // 0 to 9999\n  anyDigitsSigned: /^-?\\d+/,\n  singleDigitSigned: /^-?\\d/,\n  // 0 to 9, -0 to -9\n  twoDigitsSigned: /^-?\\d{1,2}/,\n  // 0 to 99, -0 to -99\n  threeDigitsSigned: /^-?\\d{1,3}/,\n  // 0 to 999, -0 to -999\n  fourDigitsSigned: /^-?\\d{1,4}/ // 0 to 9999, -0 to -9999\n\n};\nvar timezonePatterns = {\n  basicOptionalMinutes: /^([+-])(\\d{2})(\\d{2})?|Z/,\n  basic: /^([+-])(\\d{2})(\\d{2})|Z/,\n  basicOptionalSeconds: /^([+-])(\\d{2})(\\d{2})((\\d{2}))?|Z/,\n  extended: /^([+-])(\\d{2}):(\\d{2})|Z/,\n  extendedOptionalSeconds: /^([+-])(\\d{2}):(\\d{2})(:(\\d{2}))?|Z/\n};\n\nfunction parseNumericPattern(pattern, string, valueCallback) {\n  var matchResult = string.match(pattern);\n\n  if (!matchResult) {\n    return null;\n  }\n\n  var value = parseInt(matchResult[0], 10);\n  return {\n    value: valueCallback ? valueCallback(value) : value,\n    rest: string.slice(matchResult[0].length)\n  };\n}\n\nfunction parseTimezonePattern(pattern, string) {\n  var matchResult = string.match(pattern);\n\n  if (!matchResult) {\n    return null;\n  } // Input is 'Z'\n\n\n  if (matchResult[0] === 'Z') {\n    return {\n      value: 0,\n      rest: string.slice(1)\n    };\n  }\n\n  var sign = matchResult[1] === '+' ? 1 : -1;\n  var hours = matchResult[2] ? parseInt(matchResult[2], 10) : 0;\n  var minutes = matchResult[3] ? parseInt(matchResult[3], 10) : 0;\n  var seconds = matchResult[5] ? parseInt(matchResult[5], 10) : 0;\n  return {\n    value: sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * MILLISECONDS_IN_SECOND),\n    rest: string.slice(matchResult[0].length)\n  };\n}\n\nfunction parseAnyDigitsSigned(string, valueCallback) {\n  return parseNumericPattern(numericPatterns.anyDigitsSigned, string, valueCallback);\n}\n\nfunction parseNDigits(n, string, valueCallback) {\n  switch (n) {\n    case 1:\n      return parseNumericPattern(numericPatterns.singleDigit, string, valueCallback);\n\n    case 2:\n      return parseNumericPattern(numericPatterns.twoDigits, string, valueCallback);\n\n    case 3:\n      return parseNumericPattern(numericPatterns.threeDigits, string, valueCallback);\n\n    case 4:\n      return parseNumericPattern(numericPatterns.fourDigits, string, valueCallback);\n\n    default:\n      return parseNumericPattern(new RegExp('^\\\\d{1,' + n + '}'), string, valueCallback);\n  }\n}\n\nfunction parseNDigitsSigned(n, string, valueCallback) {\n  switch (n) {\n    case 1:\n      return parseNumericPattern(numericPatterns.singleDigitSigned, string, valueCallback);\n\n    case 2:\n      return parseNumericPattern(numericPatterns.twoDigitsSigned, string, valueCallback);\n\n    case 3:\n      return parseNumericPattern(numericPatterns.threeDigitsSigned, string, valueCallback);\n\n    case 4:\n      return parseNumericPattern(numericPatterns.fourDigitsSigned, string, valueCallback);\n\n    default:\n      return parseNumericPattern(new RegExp('^-?\\\\d{1,' + n + '}'), string, valueCallback);\n  }\n}\n\nfunction dayPeriodEnumToHours(enumValue) {\n  switch (enumValue) {\n    case 'morning':\n      return 4;\n\n    case 'evening':\n      return 17;\n\n    case 'pm':\n    case 'noon':\n    case 'afternoon':\n      return 12;\n\n    case 'am':\n    case 'midnight':\n    case 'night':\n    default:\n      return 0;\n  }\n}\n\nfunction normalizeTwoDigitYear(twoDigitYear, currentYear) {\n  var isCommonEra = currentYear > 0; // Absolute number of the current year:\n  // 1 -> 1 AC\n  // 0 -> 1 BC\n  // -1 -> 2 BC\n\n  var absCurrentYear = isCommonEra ? currentYear : 1 - currentYear;\n  var result;\n\n  if (absCurrentYear <= 50) {\n    result = twoDigitYear || 100;\n  } else {\n    var rangeEnd = absCurrentYear + 50;\n    var rangeEndCentury = Math.floor(rangeEnd / 100) * 100;\n    var isPreviousCentury = twoDigitYear >= rangeEnd % 100;\n    result = twoDigitYear + rangeEndCentury - (isPreviousCentury ? 100 : 0);\n  }\n\n  return isCommonEra ? result : 1 - result;\n}\n\nvar DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nvar DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // User for validation\n\nfunction isLeapYearIndex(year) {\n  return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}\n/*\n * |     | Unit                           |     | Unit                           |\n * |-----|--------------------------------|-----|--------------------------------|\n * |  a  | AM, PM                         |  A* | Milliseconds in day            |\n * |  b  | AM, PM, noon, midnight         |  B  | Flexible day period            |\n * |  c  | Stand-alone local day of week  |  C* | Localized hour w/ day period   |\n * |  d  | Day of month                   |  D  | Day of year                    |\n * |  e  | Local day of week              |  E  | Day of week                    |\n * |  f  |                                |  F* | Day of week in month           |\n * |  g* | Modified Julian day            |  G  | Era                            |\n * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n * |  i! | ISO day of week                |  I! | ISO week of year               |\n * |  j* | Localized hour w/ day period   |  J* | Localized hour w/o day period  |\n * |  k  | Hour [1-24]                    |  K  | Hour [0-11]                    |\n * |  l* | (deprecated)                   |  L  | Stand-alone month              |\n * |  m  | Minute                         |  M  | Month                          |\n * |  n  |                                |  N  |                                |\n * |  o! | Ordinal number modifier        |  O* | Timezone (GMT)                 |\n * |  p  |                                |  P  |                                |\n * |  q  | Stand-alone quarter            |  Q  | Quarter                        |\n * |  r* | Related Gregorian year         |  R! | ISO week-numbering year        |\n * |  s  | Second                         |  S  | Fraction of second             |\n * |  t! | Seconds timestamp              |  T! | Milliseconds timestamp         |\n * |  u  | Extended year                  |  U* | Cyclic year                    |\n * |  v* | Timezone (generic non-locat.)  |  V* | Timezone (location)            |\n * |  w  | Local week of year             |  W* | Week of month                  |\n * |  x  | Timezone (ISO-8601 w/o Z)      |  X  | Timezone (ISO-8601)            |\n * |  y  | Year (abs)                     |  Y  | Local week-numbering year      |\n * |  z* | Timezone (specific non-locat.) |  Z* | Timezone (aliases)             |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n *\n * Letters marked by ! are non-standard, but implemented by date-fns:\n * - `o` modifies the previous token to turn it into an ordinal (see `parse` docs)\n * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n *   i.e. 7 for Sunday, 1 for Monday, etc.\n * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n *   `R` is supposed to be used in conjunction with `I` and `i`\n *   for universal ISO week-numbering date, whereas\n *   `Y` is supposed to be used in conjunction with `w` and `e`\n *   for week-numbering date specific to the locale.\n */\n\n\nvar parsers = {\n  // Era\n  G: {\n    priority: 140,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // AD, BC\n        case 'G':\n        case 'GG':\n        case 'GGG':\n          return match.era(string, {\n            width: 'abbreviated'\n          }) || match.era(string, {\n            width: 'narrow'\n          });\n        // A, B\n\n        case 'GGGGG':\n          return match.era(string, {\n            width: 'narrow'\n          });\n        // Anno Domini, Before Christ\n\n        case 'GGGG':\n        default:\n          return match.era(string, {\n            width: 'wide'\n          }) || match.era(string, {\n            width: 'abbreviated'\n          }) || match.era(string, {\n            width: 'narrow'\n          });\n      }\n    },\n    set: function (date, flags, value, _options) {\n      flags.era = value;\n      date.setUTCFullYear(value, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['R', 'u', 't', 'T']\n  },\n  // Year\n  y: {\n    // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns\n    // | Year     |     y | yy |   yyy |  yyyy | yyyyy |\n    // |----------|-------|----|-------|-------|-------|\n    // | AD 1     |     1 | 01 |   001 |  0001 | 00001 |\n    // | AD 12    |    12 | 12 |   012 |  0012 | 00012 |\n    // | AD 123   |   123 | 23 |   123 |  0123 | 00123 |\n    // | AD 1234  |  1234 | 34 |  1234 |  1234 | 01234 |\n    // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n    priority: 130,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (year) {\n        return {\n          year: year,\n          isTwoDigitYear: token === 'yy'\n        };\n      };\n\n      switch (token) {\n        case 'y':\n          return parseNDigits(4, string, valueCallback);\n\n        case 'yo':\n          return match.ordinalNumber(string, {\n            unit: 'year',\n            valueCallback: valueCallback\n          });\n\n        default:\n          return parseNDigits(token.length, string, valueCallback);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value.isTwoDigitYear || value.year > 0;\n    },\n    set: function (date, flags, value, _options) {\n      var currentYear = date.getUTCFullYear();\n\n      if (value.isTwoDigitYear) {\n        var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n        date.setUTCFullYear(normalizedTwoDigitYear, 0, 1);\n        date.setUTCHours(0, 0, 0, 0);\n        return date;\n      }\n\n      var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n      date.setUTCFullYear(year, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'u', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local week-numbering year\n  Y: {\n    priority: 130,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (year) {\n        return {\n          year: year,\n          isTwoDigitYear: token === 'YY'\n        };\n      };\n\n      switch (token) {\n        case 'Y':\n          return parseNDigits(4, string, valueCallback);\n\n        case 'Yo':\n          return match.ordinalNumber(string, {\n            unit: 'year',\n            valueCallback: valueCallback\n          });\n\n        default:\n          return parseNDigits(token.length, string, valueCallback);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value.isTwoDigitYear || value.year > 0;\n    },\n    set: function (date, flags, value, options) {\n      var currentYear = getUTCWeekYear(date, options);\n\n      if (value.isTwoDigitYear) {\n        var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n        date.setUTCFullYear(normalizedTwoDigitYear, 0, options.firstWeekContainsDate);\n        date.setUTCHours(0, 0, 0, 0);\n        return startOfUTCWeek(date, options);\n      }\n\n      var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n      date.setUTCFullYear(year, 0, options.firstWeekContainsDate);\n      date.setUTCHours(0, 0, 0, 0);\n      return startOfUTCWeek(date, options);\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'Q', 'q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n  },\n  // ISO week-numbering year\n  R: {\n    priority: 130,\n    parse: function (string, token, _match, _options) {\n      if (token === 'R') {\n        return parseNDigitsSigned(4, string);\n      }\n\n      return parseNDigitsSigned(token.length, string);\n    },\n    set: function (_date, _flags, value, _options) {\n      var firstWeekOfYear = new Date(0);\n      firstWeekOfYear.setUTCFullYear(value, 0, 4);\n      firstWeekOfYear.setUTCHours(0, 0, 0, 0);\n      return startOfUTCISOWeek(firstWeekOfYear);\n    },\n    incompatibleTokens: ['G', 'y', 'Y', 'u', 'Q', 'q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n  },\n  // Extended year\n  u: {\n    priority: 130,\n    parse: function (string, token, _match, _options) {\n      if (token === 'u') {\n        return parseNDigitsSigned(4, string);\n      }\n\n      return parseNDigitsSigned(token.length, string);\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCFullYear(value, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['G', 'y', 'Y', 'R', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n  },\n  // Quarter\n  Q: {\n    priority: 120,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // 1, 2, 3, 4\n        case 'Q':\n        case 'QQ':\n          // 01, 02, 03, 04\n          return parseNDigits(token.length, string);\n        // 1st, 2nd, 3rd, 4th\n\n        case 'Qo':\n          return match.ordinalNumber(string, {\n            unit: 'quarter'\n          });\n        // Q1, Q2, Q3, Q4\n\n        case 'QQQ':\n          return match.quarter(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n        case 'QQQQQ':\n          return match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // 1st quarter, 2nd quarter, ...\n\n        case 'QQQQ':\n        default:\n          return match.quarter(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 4;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth((value - 1) * 3, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Stand-alone quarter\n  q: {\n    priority: 120,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // 1, 2, 3, 4\n        case 'q':\n        case 'qq':\n          // 01, 02, 03, 04\n          return parseNDigits(token.length, string);\n        // 1st, 2nd, 3rd, 4th\n\n        case 'qo':\n          return match.ordinalNumber(string, {\n            unit: 'quarter'\n          });\n        // Q1, Q2, Q3, Q4\n\n        case 'qqq':\n          return match.quarter(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n        case 'qqqqq':\n          return match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // 1st quarter, 2nd quarter, ...\n\n        case 'qqqq':\n        default:\n          return match.quarter(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 4;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth((value - 1) * 3, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'Q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Month\n  M: {\n    priority: 110,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        return value - 1;\n      };\n\n      switch (token) {\n        // 1, 2, ..., 12\n        case 'M':\n          return parseNumericPattern(numericPatterns.month, string, valueCallback);\n        // 01, 02, ..., 12\n\n        case 'MM':\n          return parseNDigits(2, string, valueCallback);\n        // 1st, 2nd, ..., 12th\n\n        case 'Mo':\n          return match.ordinalNumber(string, {\n            unit: 'month',\n            valueCallback: valueCallback\n          });\n        // Jan, Feb, ..., Dec\n\n        case 'MMM':\n          return match.month(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // J, F, ..., D\n\n        case 'MMMMM':\n          return match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // January, February, ..., December\n\n        case 'MMMM':\n        default:\n          return match.month(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(value, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'L', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Stand-alone month\n  L: {\n    priority: 110,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        return value - 1;\n      };\n\n      switch (token) {\n        // 1, 2, ..., 12\n        case 'L':\n          return parseNumericPattern(numericPatterns.month, string, valueCallback);\n        // 01, 02, ..., 12\n\n        case 'LL':\n          return parseNDigits(2, string, valueCallback);\n        // 1st, 2nd, ..., 12th\n\n        case 'Lo':\n          return match.ordinalNumber(string, {\n            unit: 'month',\n            valueCallback: valueCallback\n          });\n        // Jan, Feb, ..., Dec\n\n        case 'LLL':\n          return match.month(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // J, F, ..., D\n\n        case 'LLLLL':\n          return match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // January, February, ..., December\n\n        case 'LLLL':\n        default:\n          return match.month(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(value, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local week of year\n  w: {\n    priority: 100,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'w':\n          return parseNumericPattern(numericPatterns.week, string);\n\n        case 'wo':\n          return match.ordinalNumber(string, {\n            unit: 'week'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 53;\n    },\n    set: function (date, _flags, value, options) {\n      return startOfUTCWeek(setUTCWeek(date, value, options), options);\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n  },\n  // ISO week of year\n  I: {\n    priority: 100,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'I':\n          return parseNumericPattern(numericPatterns.week, string);\n\n        case 'Io':\n          return match.ordinalNumber(string, {\n            unit: 'week'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 53;\n    },\n    set: function (date, _flags, value, options) {\n      return startOfUTCISOWeek(setUTCISOWeek(date, value, options), options);\n    },\n    incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n  },\n  // Day of the month\n  d: {\n    priority: 90,\n    subPriority: 1,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'd':\n          return parseNumericPattern(numericPatterns.date, string);\n\n        case 'do':\n          return match.ordinalNumber(string, {\n            unit: 'date'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (date, value, _options) {\n      var year = date.getUTCFullYear();\n      var isLeapYear = isLeapYearIndex(year);\n      var month = date.getUTCMonth();\n\n      if (isLeapYear) {\n        return value >= 1 && value <= DAYS_IN_MONTH_LEAP_YEAR[month];\n      } else {\n        return value >= 1 && value <= DAYS_IN_MONTH[month];\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCDate(value);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Day of year\n  D: {\n    priority: 90,\n    subPriority: 1,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'D':\n        case 'DD':\n          return parseNumericPattern(numericPatterns.dayOfYear, string);\n\n        case 'Do':\n          return match.ordinalNumber(string, {\n            unit: 'date'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (date, value, _options) {\n      var year = date.getUTCFullYear();\n      var isLeapYear = isLeapYearIndex(year);\n\n      if (isLeapYear) {\n        return value >= 1 && value <= 366;\n      } else {\n        return value >= 1 && value <= 365;\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(0, value);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'L', 'w', 'I', 'd', 'E', 'i', 'e', 'c', 't', 'T']\n  },\n  // Day of week\n  E: {\n    priority: 90,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // Tue\n        case 'E':\n        case 'EE':\n        case 'EEE':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // T\n\n        case 'EEEEE':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tu\n\n        case 'EEEEEE':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tuesday\n\n        case 'EEEE':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local day of week\n  e: {\n    priority: 90,\n    parse: function (string, token, match, options) {\n      var valueCallback = function (value) {\n        var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n        return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n      };\n\n      switch (token) {\n        // 3\n        case 'e':\n        case 'ee':\n          // 03\n          return parseNDigits(token.length, string, valueCallback);\n        // 3rd\n\n        case 'eo':\n          return match.ordinalNumber(string, {\n            unit: 'day',\n            valueCallback: valueCallback\n          });\n        // Tue\n\n        case 'eee':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // T\n\n        case 'eeeee':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tu\n\n        case 'eeeeee':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tuesday\n\n        case 'eeee':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'c', 't', 'T']\n  },\n  // Stand-alone local day of week\n  c: {\n    priority: 90,\n    parse: function (string, token, match, options) {\n      var valueCallback = function (value) {\n        var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n        return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n      };\n\n      switch (token) {\n        // 3\n        case 'c':\n        case 'cc':\n          // 03\n          return parseNDigits(token.length, string, valueCallback);\n        // 3rd\n\n        case 'co':\n          return match.ordinalNumber(string, {\n            unit: 'day',\n            valueCallback: valueCallback\n          });\n        // Tue\n\n        case 'ccc':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // T\n\n        case 'ccccc':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // Tu\n\n        case 'cccccc':\n          return match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // Tuesday\n\n        case 'cccc':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'e', 't', 'T']\n  },\n  // ISO day of week\n  i: {\n    priority: 90,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        if (value === 0) {\n          return 7;\n        }\n\n        return value;\n      };\n\n      switch (token) {\n        // 2\n        case 'i':\n        case 'ii':\n          // 02\n          return parseNDigits(token.length, string);\n        // 2nd\n\n        case 'io':\n          return match.ordinalNumber(string, {\n            unit: 'day'\n          });\n        // Tue\n\n        case 'iii':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // T\n\n        case 'iiiii':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // Tu\n\n        case 'iiiiii':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // Tuesday\n\n        case 'iiii':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 7;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCISODay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'E', 'e', 'c', 't', 'T']\n  },\n  // AM or PM\n  a: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'a':\n        case 'aa':\n        case 'aaa':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'aaaaa':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'aaaa':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['b', 'B', 'H', 'K', 'k', 't', 'T']\n  },\n  // AM, PM, midnight\n  b: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'b':\n        case 'bb':\n        case 'bbb':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'bbbbb':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'bbbb':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'B', 'H', 'K', 'k', 't', 'T']\n  },\n  // in the morning, in the afternoon, in the evening, at night\n  B: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'B':\n        case 'BB':\n        case 'BBB':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'BBBBB':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'BBBB':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 't', 'T']\n  },\n  // Hour [1-12]\n  h: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'h':\n          return parseNumericPattern(numericPatterns.hour12h, string);\n\n        case 'ho':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 12;\n    },\n    set: function (date, _flags, value, _options) {\n      var isPM = date.getUTCHours() >= 12;\n\n      if (isPM && value < 12) {\n        date.setUTCHours(value + 12, 0, 0, 0);\n      } else if (!isPM && value === 12) {\n        date.setUTCHours(0, 0, 0, 0);\n      } else {\n        date.setUTCHours(value, 0, 0, 0);\n      }\n\n      return date;\n    },\n    incompatibleTokens: ['H', 'K', 'k', 't', 'T']\n  },\n  // Hour [0-23]\n  H: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'H':\n          return parseNumericPattern(numericPatterns.hour23h, string);\n\n        case 'Ho':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 23;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(value, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'K', 'k', 't', 'T']\n  },\n  // Hour [0-11]\n  K: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'K':\n          return parseNumericPattern(numericPatterns.hour11h, string);\n\n        case 'Ko':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      var isPM = date.getUTCHours() >= 12;\n\n      if (isPM && value < 12) {\n        date.setUTCHours(value + 12, 0, 0, 0);\n      } else {\n        date.setUTCHours(value, 0, 0, 0);\n      }\n\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'H', 'k', 't', 'T']\n  },\n  // Hour [1-24]\n  k: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'k':\n          return parseNumericPattern(numericPatterns.hour24h, string);\n\n        case 'ko':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 24;\n    },\n    set: function (date, _flags, value, _options) {\n      var hours = value <= 24 ? value % 24 : value;\n      date.setUTCHours(hours, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'H', 'K', 't', 'T']\n  },\n  // Minute\n  m: {\n    priority: 60,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'm':\n          return parseNumericPattern(numericPatterns.minute, string);\n\n        case 'mo':\n          return match.ordinalNumber(string, {\n            unit: 'minute'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 59;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMinutes(value, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Second\n  s: {\n    priority: 50,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 's':\n          return parseNumericPattern(numericPatterns.second, string);\n\n        case 'so':\n          return match.ordinalNumber(string, {\n            unit: 'second'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 59;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCSeconds(value, 0);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Fraction of second\n  S: {\n    priority: 30,\n    parse: function (string, token, _match, _options) {\n      var valueCallback = function (value) {\n        return Math.floor(value * Math.pow(10, -token.length + 3));\n      };\n\n      return parseNDigits(token.length, string, valueCallback);\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMilliseconds(value);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Timezone (ISO-8601. +00:00 is `'Z'`)\n  X: {\n    priority: 10,\n    parse: function (string, token, _match, _options) {\n      switch (token) {\n        case 'X':\n          return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n        case 'XX':\n          return parseTimezonePattern(timezonePatterns.basic, string);\n\n        case 'XXXX':\n          return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n        case 'XXXXX':\n          return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n        case 'XXX':\n        default:\n          return parseTimezonePattern(timezonePatterns.extended, string);\n      }\n    },\n    set: function (date, flags, value, _options) {\n      if (flags.timestampIsSet) {\n        return date;\n      }\n\n      return new Date(date.getTime() - value);\n    },\n    incompatibleTokens: ['t', 'T', 'x']\n  },\n  // Timezone (ISO-8601)\n  x: {\n    priority: 10,\n    parse: function (string, token, _match, _options) {\n      switch (token) {\n        case 'x':\n          return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n        case 'xx':\n          return parseTimezonePattern(timezonePatterns.basic, string);\n\n        case 'xxxx':\n          return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n        case 'xxxxx':\n          return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n        case 'xxx':\n        default:\n          return parseTimezonePattern(timezonePatterns.extended, string);\n      }\n    },\n    set: function (date, flags, value, _options) {\n      if (flags.timestampIsSet) {\n        return date;\n      }\n\n      return new Date(date.getTime() - value);\n    },\n    incompatibleTokens: ['t', 'T', 'X']\n  },\n  // Seconds timestamp\n  t: {\n    priority: 40,\n    parse: function (string, _token, _match, _options) {\n      return parseAnyDigitsSigned(string);\n    },\n    set: function (_date, _flags, value, _options) {\n      return [new Date(value * 1000), {\n        timestampIsSet: true\n      }];\n    },\n    incompatibleTokens: '*'\n  },\n  // Milliseconds timestamp\n  T: {\n    priority: 20,\n    parse: function (string, _token, _match, _options) {\n      return parseAnyDigitsSigned(string);\n    },\n    set: function (_date, _flags, value, _options) {\n      return [new Date(value), {\n        timestampIsSet: true\n      }];\n    },\n    incompatibleTokens: '*'\n  }\n};\nexport default parsers;","import defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport assign from '../_lib/assign/index.js';\nimport longFormatters from '../_lib/format/longFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport { isProtectedDayOfYearToken, isProtectedWeekYearToken, throwProtectedError } from '../_lib/protectedTokens/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport parsers from './_lib/parsers/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar TIMEZONE_UNIT_PRIORITY = 10; // This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n//   (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\n\nvar longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar notWhitespaceRegExp = /\\S/;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name parse\n * @category Common Helpers\n * @summary Parse the date.\n *\n * @description\n * Return the date parsed from string using the given format string.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters in the format string wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the format string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 5 below the table).\n *\n * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited\n * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:\n *\n * ```javascript\n * parse('23 AM', 'HH a', new Date())\n * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time\n * ```\n *\n * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true\n *\n * Accepted format string patterns:\n * | Unit                            |Prior| Pattern | Result examples                   | Notes |\n * |---------------------------------|-----|---------|-----------------------------------|-------|\n * | Era                             | 140 | G..GGG  | AD, BC                            |       |\n * |                                 |     | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 |     | GGGGG   | A, B                              |       |\n * | Calendar year                   | 130 | y       | 44, 1, 1900, 2017, 9999           | 4     |\n * |                                 |     | yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | yy      | 44, 01, 00, 17                    | 4     |\n * |                                 |     | yyy     | 044, 001, 123, 999                | 4     |\n * |                                 |     | yyyy    | 0044, 0001, 1900, 2017            | 4     |\n * |                                 |     | yyyyy   | ...                               | 2,4   |\n * | Local week-numbering year       | 130 | Y       | 44, 1, 1900, 2017, 9000           | 4     |\n * |                                 |     | Yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | YY      | 44, 01, 00, 17                    | 4,6   |\n * |                                 |     | YYY     | 044, 001, 123, 999                | 4     |\n * |                                 |     | YYYY    | 0044, 0001, 1900, 2017            | 4,6   |\n * |                                 |     | YYYYY   | ...                               | 2,4   |\n * | ISO week-numbering year         | 130 | R       | -43, 1, 1900, 2017, 9999, -9999   | 4,5   |\n * |                                 |     | RR      | -43, 01, 00, 17                   | 4,5   |\n * |                                 |     | RRR     | -043, 001, 123, 999, -999         | 4,5   |\n * |                                 |     | RRRR    | -0043, 0001, 2017, 9999, -9999    | 4,5   |\n * |                                 |     | RRRRR   | ...                               | 2,4,5 |\n * | Extended year                   | 130 | u       | -43, 1, 1900, 2017, 9999, -999    | 4     |\n * |                                 |     | uu      | -43, 01, 99, -99                  | 4     |\n * |                                 |     | uuu     | -043, 001, 123, 999, -999         | 4     |\n * |                                 |     | uuuu    | -0043, 0001, 2017, 9999, -9999    | 4     |\n * |                                 |     | uuuuu   | ...                               | 2,4   |\n * | Quarter (formatting)            | 120 | Q       | 1, 2, 3, 4                        |       |\n * |                                 |     | Qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | QQ      | 01, 02, 03, 04                    |       |\n * |                                 |     | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | 120 | q       | 1, 2, 3, 4                        |       |\n * |                                 |     | qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | qq      | 01, 02, 03, 04                    |       |\n * |                                 |     | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | qqqqq   | 1, 2, 3, 4                        | 3     |\n * | Month (formatting)              | 110 | M       | 1, 2, ..., 12                     |       |\n * |                                 |     | Mo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | MM      | 01, 02, ..., 12                   |       |\n * |                                 |     | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | MMMM    | January, February, ..., December  | 2     |\n * |                                 |     | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | 110 | L       | 1, 2, ..., 12                     |       |\n * |                                 |     | Lo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | LL      | 01, 02, ..., 12                   |       |\n * |                                 |     | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | LLLL    | January, February, ..., December  | 2     |\n * |                                 |     | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | 100 | w       | 1, 2, ..., 53                     |       |\n * |                                 |     | wo      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | 100 | I       | 1, 2, ..., 53                     | 5     |\n * |                                 |     | Io      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | II      | 01, 02, ..., 53                   | 5     |\n * | Day of month                    |  90 | d       | 1, 2, ..., 31                     |       |\n * |                                 |     | do      | 1st, 2nd, ..., 31st               | 5     |\n * |                                 |     | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     |  90 | D       | 1, 2, ..., 365, 366               | 7     |\n * |                                 |     | Do      | 1st, 2nd, ..., 365th, 366th       | 5     |\n * |                                 |     | DD      | 01, 02, ..., 365, 366             | 7     |\n * |                                 |     | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 |     | DDDD    | ...                               | 2     |\n * | Day of week (formatting)        |  90 | E..EEE  | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 |     | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 |     | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    |  90 | i       | 1, 2, 3, ..., 7                   | 5     |\n * |                                 |     | io      | 1st, 2nd, ..., 7th                | 5     |\n * |                                 |     | ii      | 01, 02, ..., 07                   | 5     |\n * |                                 |     | iii     | Mon, Tue, Wed, ..., Sun           | 5     |\n * |                                 |     | iiii    | Monday, Tuesday, ..., Sunday      | 2,5   |\n * |                                 |     | iiiii   | M, T, W, T, F, S, S               | 5     |\n * |                                 |     | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 5     |\n * | Local day of week (formatting)  |  90 | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | eo      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | ee      | 02, 03, ..., 01                   |       |\n * |                                 |     | eee     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 |     | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 |     | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) |  90 | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | co      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | cc      | 02, 03, ..., 01                   |       |\n * |                                 |     | ccc     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 |     | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 |     | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          |  80 | a..aaa  | AM, PM                            |       |\n * |                                 |     | aaaa    | a.m., p.m.                        | 2     |\n * |                                 |     | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          |  80 | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 |     | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 |     | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             |  80 | B..BBB  | at night, in the morning, ...     |       |\n * |                                 |     | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 |     | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     |  70 | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 |     | ho      | 1st, 2nd, ..., 11th, 12th         | 5     |\n * |                                 |     | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     |  70 | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 |     | Ho      | 0th, 1st, 2nd, ..., 23rd          | 5     |\n * |                                 |     | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     |  70 | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 |     | Ko      | 1st, 2nd, ..., 11th, 0th          | 5     |\n * |                                 |     | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     |  70 | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 |     | ko      | 24th, 1st, 2nd, ..., 23rd         | 5     |\n * |                                 |     | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          |  60 | m       | 0, 1, ..., 59                     |       |\n * |                                 |     | mo      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | mm      | 00, 01, ..., 59                   |       |\n * | Second                          |  50 | s       | 0, 1, ..., 59                     |       |\n * |                                 |     | so      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | ss      | 00, 01, ..., 59                   |       |\n * | Seconds timestamp               |  40 | t       | 512969520                         |       |\n * |                                 |     | tt      | ...                               | 2     |\n * | Fraction of second              |  30 | S       | 0, 1, ..., 9                      |       |\n * |                                 |     | SS      | 00, 01, ..., 99                   |       |\n * |                                 |     | SSS     | 000, 0001, ..., 999               |       |\n * |                                 |     | SSSS    | ...                               | 2     |\n * | Milliseconds timestamp          |  20 | T       | 512969520900                      |       |\n * |                                 |     | TT      | ...                               | 2     |\n * | Timezone (ISO-8601 w/ Z)        |  10 | X       | -08, +0530, Z                     |       |\n * |                                 |     | XX      | -0800, +0530, Z                   |       |\n * |                                 |     | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 |     | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 |     | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       |  10 | x       | -08, +0530, +00                   |       |\n * |                                 |     | xx      | -0800, +0530, +0000               |       |\n * |                                 |     | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 |     | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 |     | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Long localized date             |  NA | P       | 05/29/1453                        | 5,8   |\n * |                                 |     | PP      | May 29, 1453                      |       |\n * |                                 |     | PPP     | May 29th, 1453                    |       |\n * |                                 |     | PPPP    | Sunday, May 29th, 1453            | 2,5,8 |\n * | Long localized time             |  NA | p       | 12:00 AM                          | 5,8   |\n * |                                 |     | pp      | 12:00:00 AM                       |       |\n * | Combination of date and time    |  NA | Pp      | 05/29/1453, 12:00 AM              |       |\n * |                                 |     | PPpp    | May 29, 1453, 12:00:00 AM         |       |\n * |                                 |     | PPPpp   | May 29th, 1453 at ...             |       |\n * |                                 |     | PPPPpp  | Sunday, May 29th, 1453 at ...     | 2,5,8 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular.\n *    In `format` function, they will produce different result:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n *    `parse` will try to match both formatting and stand-alone units interchangably.\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table:\n *    - for numerical units (`yyyyyyyy`) `parse` will try to match a number\n *      as wide as the sequence\n *    - for text units (`MMMMMMMM`) `parse` will try to match the widest variation of the unit.\n *      These variations are marked with \"2\" in the last column of the table.\n *\n * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 4. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:\n *\n *    `parse('50', 'yy', new Date(2018, 0, 1)) //=> Sat Jan 01 2050 00:00:00`\n *\n *    `parse('75', 'yy', new Date(2018, 0, 1)) //=> Wed Jan 01 1975 00:00:00`\n *\n *    while `uu` will just assign the year as is:\n *\n *    `parse('50', 'uu', new Date(2018, 0, 1)) //=> Sat Jan 01 0050 00:00:00`\n *\n *    `parse('75', 'uu', new Date(2018, 0, 1)) //=> Tue Jan 01 0075 00:00:00`\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}\n *    and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).\n *\n * 5. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based\n *    on the given locale.\n *\n *    using `en-US` locale: `P` => `MM/dd/yyyy`\n *    using `en-US` locale: `p` => `hh:mm a`\n *    using `pt-BR` locale: `P` => `dd/MM/yyyy`\n *    using `pt-BR` locale: `p` => `HH:mm`\n *\n * Values will be assigned to the date in the descending order of its unit's priority.\n * Units of an equal priority overwrite each other in the order of appearance.\n *\n * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year),\n * the values will be taken from 3rd argument `referenceDate` which works as a context of parsing.\n *\n * `referenceDate` must be passed for correct work of the function.\n * If you're not sure which `referenceDate` to supply, create a new instance of Date:\n * `parse('02/11/2014', 'MM/dd/yyyy', new Date())`\n * In this case parsing will be done in the context of the current date.\n * If `referenceDate` is `Invalid Date` or a value not convertible to valid `Date`,\n * then `Invalid Date` will be returned.\n *\n * The result may vary by locale.\n *\n * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.\n *\n * If parsing failed, `Invalid Date` will be returned.\n * Invalid Date is a Date, whose time value is NaN.\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Old `parse` was renamed to `toDate`.\n *   Now `parse` is a new function which parses a string using a provided format.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   parse('2016-01-01')\n *\n *   // v2.0.0 onward\n *   toDate('2016-01-01')\n *   parse('2016-01-01', 'yyyy-MM-dd', new Date())\n *   ```\n *\n * @param {String} dateString - the string to parse\n * @param {String} formatString - the string of tokens\n * @param {Date|Number} referenceDate - defines values missing from the parsed dateString\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {Date} the parsed date\n * @throws {TypeError} 3 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} `options.locale` must contain `match` property\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Parse 11 February 2014 from middle-endian format:\n * var result = parse('02/11/2014', 'MM/dd/yyyy', new Date())\n * //=> Tue Feb 11 2014 00:00:00\n *\n * @example\n * // Parse 28th of February in Esperanto locale in the context of 2010 year:\n * import eo from 'date-fns/locale/eo'\n * var result = parse('28-a de februaro', \"do 'de' MMMM\", new Date(2010, 0, 1), {\n *   locale: eo\n * })\n * //=> Sun Feb 28 2010 00:00:00\n */\n\nexport default function parse(dirtyDateString, dirtyFormatString, dirtyReferenceDate, dirtyOptions) {\n  requiredArgs(3, arguments);\n  var dateString = String(dirtyDateString);\n  var formatString = String(dirtyFormatString);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.match) {\n    throw new RangeError('locale must contain match property');\n  }\n\n  var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  if (formatString === '') {\n    if (dateString === '') {\n      return toDate(dirtyReferenceDate);\n    } else {\n      return new Date(NaN);\n    }\n  }\n\n  var subFnOptions = {\n    firstWeekContainsDate: firstWeekContainsDate,\n    weekStartsOn: weekStartsOn,\n    locale: locale // If timezone isn't specified, it will be set to the system timezone\n\n  };\n  var setters = [{\n    priority: TIMEZONE_UNIT_PRIORITY,\n    subPriority: -1,\n    set: dateToSystemTimezone,\n    index: 0\n  }];\n  var i;\n  var tokens = formatString.match(longFormattingTokensRegExp).map(function (substring) {\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === 'p' || firstCharacter === 'P') {\n      var longFormatter = longFormatters[firstCharacter];\n      return longFormatter(substring, locale.formatLong, subFnOptions);\n    }\n\n    return substring;\n  }).join('').match(formattingTokensRegExp);\n  var usedTokens = [];\n\n  for (i = 0; i < tokens.length; i++) {\n    var token = tokens[i];\n\n    if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(token)) {\n      throwProtectedError(token, formatString, dirtyDateString);\n    }\n\n    if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(token)) {\n      throwProtectedError(token, formatString, dirtyDateString);\n    }\n\n    var firstCharacter = token[0];\n    var parser = parsers[firstCharacter];\n\n    if (parser) {\n      var incompatibleTokens = parser.incompatibleTokens;\n\n      if (Array.isArray(incompatibleTokens)) {\n        var incompatibleToken = void 0;\n\n        for (var _i = 0; _i < usedTokens.length; _i++) {\n          var usedToken = usedTokens[_i].token;\n\n          if (incompatibleTokens.indexOf(usedToken) !== -1 || usedToken === firstCharacter) {\n            incompatibleToken = usedTokens[_i];\n            break;\n          }\n        }\n\n        if (incompatibleToken) {\n          throw new RangeError(\"The format string mustn't contain `\".concat(incompatibleToken.fullToken, \"` and `\").concat(token, \"` at the same time\"));\n        }\n      } else if (parser.incompatibleTokens === '*' && usedTokens.length) {\n        throw new RangeError(\"The format string mustn't contain `\".concat(token, \"` and any other token at the same time\"));\n      }\n\n      usedTokens.push({\n        token: firstCharacter,\n        fullToken: token\n      });\n      var parseResult = parser.parse(dateString, token, locale.match, subFnOptions);\n\n      if (!parseResult) {\n        return new Date(NaN);\n      }\n\n      setters.push({\n        priority: parser.priority,\n        subPriority: parser.subPriority || 0,\n        set: parser.set,\n        validate: parser.validate,\n        value: parseResult.value,\n        index: setters.length\n      });\n      dateString = parseResult.rest;\n    } else {\n      if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n        throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n      } // Replace two single quote characters with one single quote character\n\n\n      if (token === \"''\") {\n        token = \"'\";\n      } else if (firstCharacter === \"'\") {\n        token = cleanEscapedString(token);\n      } // Cut token from string, or, if string doesn't match the token, return Invalid Date\n\n\n      if (dateString.indexOf(token) === 0) {\n        dateString = dateString.slice(token.length);\n      } else {\n        return new Date(NaN);\n      }\n    }\n  } // Check if the remaining input contains something other than whitespace\n\n\n  if (dateString.length > 0 && notWhitespaceRegExp.test(dateString)) {\n    return new Date(NaN);\n  }\n\n  var uniquePrioritySetters = setters.map(function (setter) {\n    return setter.priority;\n  }).sort(function (a, b) {\n    return b - a;\n  }).filter(function (priority, index, array) {\n    return array.indexOf(priority) === index;\n  }).map(function (priority) {\n    return setters.filter(function (setter) {\n      return setter.priority === priority;\n    }).sort(function (a, b) {\n      return b.subPriority - a.subPriority;\n    });\n  }).map(function (setterArray) {\n    return setterArray[0];\n  });\n  var date = toDate(dirtyReferenceDate);\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37\n\n\n  var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));\n  var flags = {};\n\n  for (i = 0; i < uniquePrioritySetters.length; i++) {\n    var setter = uniquePrioritySetters[i];\n\n    if (setter.validate && !setter.validate(utcDate, setter.value, subFnOptions)) {\n      return new Date(NaN);\n    }\n\n    var result = setter.set(utcDate, flags, setter.value, subFnOptions); // Result is tuple (date, flags)\n\n    if (result[0]) {\n      utcDate = result[0];\n      assign(flags, result[1]); // Result is date\n    } else {\n      utcDate = result;\n    }\n  }\n\n  return utcDate;\n}\n\nfunction dateToSystemTimezone(date, flags) {\n  if (flags.timestampIsSet) {\n    return date;\n  }\n\n  var convertedDate = new Date(0);\n  convertedDate.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n  convertedDate.setHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());\n  return convertedDate;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","import toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar DEFAULT_ADDITIONAL_DIGITS = 2;\nvar patterns = {\n  dateTimeDelimiter: /[T ]/,\n  timeZoneDelimiter: /[Z ]/i,\n  timezone: /([Z+-].*)$/\n};\nvar dateRegex = /^-?(?:(\\d{3})|(\\d{2})(?:-?(\\d{2}))?|W(\\d{2})(?:-?(\\d{1}))?|)$/;\nvar timeRegex = /^(\\d{2}(?:[.,]\\d*)?)(?::?(\\d{2}(?:[.,]\\d*)?))?(?::?(\\d{2}(?:[.,]\\d*)?))?$/;\nvar timezoneRegex = /^([+-])(\\d{2})(?::?(\\d{2}))?$/;\n/**\n * @name parseISO\n * @category Common Helpers\n * @summary Parse ISO string\n *\n * @description\n * Parse the given string in ISO 8601 format and return an instance of Date.\n *\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n *\n * If the argument isn't a string, the function cannot parse the string or\n * the values are invalid, it returns Invalid Date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The previous `parse` implementation was renamed to `parseISO`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   parse('2016-01-01')\n *\n *   // v2.0.0 onward\n *   parseISO('2016-01-01')\n *   ```\n *\n * - `parseISO` now validates separate date and time values in ISO-8601 strings\n *   and returns `Invalid Date` if the date is invalid.\n *\n *   ```javascript\n *   parseISO('2018-13-32')\n *   //=> Invalid Date\n *   ```\n *\n * - `parseISO` now doesn't fall back to `new Date` constructor\n *   if it fails to parse a string argument. Instead, it returns `Invalid Date`.\n *\n * @param {String} argument - the value to convert\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * var result = parseISO('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * var result = parseISO('+02014101', { additionalDigits: 1 })\n * //=> Fri Apr 11 2014 00:00:00\n */\n\nexport default function parseISO(argument, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var additionalDigits = options.additionalDigits == null ? DEFAULT_ADDITIONAL_DIGITS : toInteger(options.additionalDigits);\n\n  if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {\n    throw new RangeError('additionalDigits must be 0, 1 or 2');\n  }\n\n  if (!(typeof argument === 'string' || Object.prototype.toString.call(argument) === '[object String]')) {\n    return new Date(NaN);\n  }\n\n  var dateStrings = splitDateString(argument);\n  var date;\n\n  if (dateStrings.date) {\n    var parseYearResult = parseYear(dateStrings.date, additionalDigits);\n    date = parseDate(parseYearResult.restDateString, parseYearResult.year);\n  }\n\n  if (isNaN(date) || !date) {\n    return new Date(NaN);\n  }\n\n  var timestamp = date.getTime();\n  var time = 0;\n  var offset;\n\n  if (dateStrings.time) {\n    time = parseTime(dateStrings.time);\n\n    if (isNaN(time) || time === null) {\n      return new Date(NaN);\n    }\n  }\n\n  if (dateStrings.timezone) {\n    offset = parseTimezone(dateStrings.timezone);\n\n    if (isNaN(offset)) {\n      return new Date(NaN);\n    }\n  } else {\n    var dirtyDate = new Date(timestamp + time); // js parsed string assuming it's in UTC timezone\n    // but we need it to be parsed in our timezone\n    // so we use utc values to build date in our timezone.\n    // Year values from 0 to 99 map to the years 1900 to 1999\n    // so set year explicitly with setFullYear.\n\n    var result = new Date(dirtyDate.getUTCFullYear(), dirtyDate.getUTCMonth(), dirtyDate.getUTCDate(), dirtyDate.getUTCHours(), dirtyDate.getUTCMinutes(), dirtyDate.getUTCSeconds(), dirtyDate.getUTCMilliseconds());\n    result.setFullYear(dirtyDate.getUTCFullYear());\n    return result;\n  }\n\n  return new Date(timestamp + time + offset);\n}\n\nfunction splitDateString(dateString) {\n  var dateStrings = {};\n  var array = dateString.split(patterns.dateTimeDelimiter);\n  var timeString; // The regex match should only return at maximum two array elements.\n  // [date], [time], or [date, time].\n\n  if (array.length > 2) {\n    return dateStrings;\n  }\n\n  if (/:/.test(array[0])) {\n    dateStrings.date = null;\n    timeString = array[0];\n  } else {\n    dateStrings.date = array[0];\n    timeString = array[1];\n\n    if (patterns.timeZoneDelimiter.test(dateStrings.date)) {\n      dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];\n      timeString = dateString.substr(dateStrings.date.length, dateString.length);\n    }\n  }\n\n  if (timeString) {\n    var token = patterns.timezone.exec(timeString);\n\n    if (token) {\n      dateStrings.time = timeString.replace(token[1], '');\n      dateStrings.timezone = token[1];\n    } else {\n      dateStrings.time = timeString;\n    }\n  }\n\n  return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n  var regex = new RegExp('^(?:(\\\\d{4}|[+-]\\\\d{' + (4 + additionalDigits) + '})|(\\\\d{2}|[+-]\\\\d{' + (2 + additionalDigits) + '})$)');\n  var captures = dateString.match(regex); // Invalid ISO-formatted year\n\n  if (!captures) return {\n    year: null\n  };\n  var year = captures[1] && parseInt(captures[1]);\n  var century = captures[2] && parseInt(captures[2]);\n  return {\n    year: century == null ? year : century * 100,\n    restDateString: dateString.slice((captures[1] || captures[2]).length)\n  };\n}\n\nfunction parseDate(dateString, year) {\n  // Invalid ISO-formatted year\n  if (year === null) return null;\n  var captures = dateString.match(dateRegex); // Invalid ISO-formatted string\n\n  if (!captures) return null;\n  var isWeekDate = !!captures[4];\n  var dayOfYear = parseDateUnit(captures[1]);\n  var month = parseDateUnit(captures[2]) - 1;\n  var day = parseDateUnit(captures[3]);\n  var week = parseDateUnit(captures[4]);\n  var dayOfWeek = parseDateUnit(captures[5]) - 1;\n\n  if (isWeekDate) {\n    if (!validateWeekDate(year, week, dayOfWeek)) {\n      return new Date(NaN);\n    }\n\n    return dayOfISOWeekYear(year, week, dayOfWeek);\n  } else {\n    var date = new Date(0);\n\n    if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) {\n      return new Date(NaN);\n    }\n\n    date.setUTCFullYear(year, month, Math.max(dayOfYear, day));\n    return date;\n  }\n}\n\nfunction parseDateUnit(value) {\n  return value ? parseInt(value) : 1;\n}\n\nfunction parseTime(timeString) {\n  var captures = timeString.match(timeRegex);\n  if (!captures) return null; // Invalid ISO-formatted time\n\n  var hours = parseTimeUnit(captures[1]);\n  var minutes = parseTimeUnit(captures[2]);\n  var seconds = parseTimeUnit(captures[3]);\n\n  if (!validateTime(hours, minutes, seconds)) {\n    return NaN;\n  }\n\n  return hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * 1000;\n}\n\nfunction parseTimeUnit(value) {\n  return value && parseFloat(value.replace(',', '.')) || 0;\n}\n\nfunction parseTimezone(timezoneString) {\n  if (timezoneString === 'Z') return 0;\n  var captures = timezoneString.match(timezoneRegex);\n  if (!captures) return 0;\n  var sign = captures[1] === '+' ? -1 : 1;\n  var hours = parseInt(captures[2]);\n  var minutes = captures[3] && parseInt(captures[3]) || 0;\n\n  if (!validateTimezone(hours, minutes)) {\n    return NaN;\n  }\n\n  return sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE);\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n  var date = new Date(0);\n  date.setUTCFullYear(isoWeekYear, 0, 4);\n  var fourthOfJanuaryDay = date.getUTCDay() || 7;\n  var diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n} // Validation functions\n// February is null to handle the leap year (using ||)\n\n\nvar daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n  return year % 400 === 0 || year % 4 === 0 && year % 100;\n}\n\nfunction validateDate(year, month, date) {\n  return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28));\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n  return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);\n}\n\nfunction validateWeekDate(_year, week, day) {\n  return week >= 1 && week <= 53 && day >= 0 && day <= 6;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n  if (hours === 24) {\n    return minutes === 0 && seconds === 0;\n  }\n\n  return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25;\n}\n\nfunction validateTimezone(_hours, minutes) {\n  return minutes >= 0 && minutes <= 59;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name parseJSON\n * @category Common Helpers\n * @summary Parse a JSON date string\n *\n * @description\n * Converts a complete ISO date string in UTC time, the typical format for transmitting\n * a date in JSON, to a JavaScript `Date` instance.\n *\n * This is a minimal implementation for converting dates retrieved from a JSON API to\n * a `Date` instance which can be used with other functions in the `date-fns` library.\n * The following formats are supported:\n *\n * - `2000-03-15T05:20:10.123Z`: The output of `.toISOString()` and `JSON.stringify(new Date())`\n * - `2000-03-15T05:20:10Z`: Without milliseconds\n * - `2000-03-15T05:20:10+00:00`: With a zero offset, the default JSON encoded format in some other languages\n * - `2000-03-15T05:20:10+0000`: With a zero offset without a colon\n * - `2000-03-15T05:20:10`: Without a trailing 'Z' symbol\n * - `2000-03-15T05:20:10.1234567`: Up to 7 digits in milliseconds field. Only first 3 are taken into account since JS does not allow fractional milliseconds\n * - `2000-03-15 05:20:10`: With a space instead of a 'T' separator for APIs returning a SQL date without reformatting\n *\n * For convenience and ease of use these other input types are also supported\n * via [toDate]{@link https://date-fns.org/docs/toDate}:\n *\n * - A `Date` instance will be cloned\n * - A `number` will be treated as a timestamp\n *\n * Any other input type or invalid date strings will return an `Invalid Date`.\n *\n * @param {String|Number|Date} argument A fully formed ISO8601 date string to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n */\n\nexport default function parseJSON(argument) {\n  requiredArgs(1, arguments);\n\n  if (typeof argument === 'string') {\n    var parts = argument.match(/(\\d{4})-(\\d{2})-(\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{0,7}))?(?:Z|\\+00:?00)?/);\n\n    if (parts) {\n      return new Date(Date.UTC(+parts[1], parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6], +((parts[7] || '0') + '00').substring(0, 3)));\n    }\n\n    return new Date(NaN);\n  }\n\n  return toDate(argument);\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name roundToNearestMinutes\n * @category Minute Helpers\n * @summary Rounds the given date to the nearest minute\n *\n * @description\n * Rounds the given date to the nearest minute (or number of minutes).\n * Rounds up when the given date is exactly between the nearest round minutes.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to round\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.nearestTo=1] - nearest number of minutes to round to. E.g. `15` to round to quarter hours.\n * @returns {Date} the new date rounded to the closest minute\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.nearestTo` must be between 1 and 30\n *\n * @example\n * // Round 10 July 2014 12:12:34 to nearest minute:\n * var result = roundToNearestMinutes(new Date(2014, 6, 10, 12, 12, 34))\n * //=> Thu Jul 10 2014 12:13:00\n *\n * @example\n * // Round 10 July 2014 12:07:30 to nearest quarter hour:\n * var result = roundToNearestMinutes(new Date(2014, 6, 10, 12, 12, 34), { nearestTo: 15 })\n * // rounds up because given date is exactly between 12:00:00 and 12:15:00\n * //=> Thu Jul 10 2014 12:15:00\n */\n\nexport default function roundToNearestMinutes(dirtyDate, options) {\n  if (arguments.length < 1) {\n    throw new TypeError('1 argument required, but only none provided present');\n  }\n\n  var nearestTo = options && 'nearestTo' in options ? toInteger(options.nearestTo) : 1;\n\n  if (nearestTo < 1 || nearestTo > 30) {\n    throw new RangeError('`options.nearestTo` must be between 1 and 30');\n  }\n\n  var date = toDate(dirtyDate);\n  var seconds = date.getSeconds(); // relevant if nearestTo is 1, which is the default case\n\n  var minutes = date.getMinutes() + seconds / 60;\n  var roundedMinutes = Math.floor(minutes / nearestTo) * nearestTo;\n  var remainderMinutes = minutes % nearestTo;\n  var addedMinutes = Math.round(remainderMinutes / nearestTo) * nearestTo;\n  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), roundedMinutes + addedMinutes);\n}","import toDate from '../toDate/index.js';\nimport setMonth from '../setMonth/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name set\n * @category Common Helpers\n * @summary Set date values to a given date.\n *\n * @description\n * Set date values to a given date.\n *\n * Sets time values to date from object `values`.\n * A value is not set if it is undefined or null or doesn't exist in `values`.\n *\n * Note about bundle size: `set` does not internally use `setX` functions from date-fns but instead opts\n * to use native `Date#setX` methods. If you use this function, you may not want to include the\n * other `setX` functions that date-fns provides if you are concerned about the bundle size.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Object} values - an object with options\n * @param {Number} [values.year] - the number of years to be set\n * @param {Number} [values.month] - the number of months to be set\n * @param {Number} [values.date] - the number of days to be set\n * @param {Number} [values.hours] - the number of hours to be set\n * @param {Number} [values.minutes] - the number of minutes to be set\n * @param {Number} [values.seconds] - the number of seconds to be set\n * @param {Number} [values.milliseconds] - the number of milliseconds to be set\n * @returns {Date} the new date with options set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `values` must be an object\n *\n * @example\n * // Transform 1 September 2014 into 20 October 2015 in a single line:\n * var result = set(new Date(2014, 8, 20), { year: 2015, month: 9, date: 20 })\n * //=> Tue Oct 20 2015 00:00:00\n *\n * @example\n * // Set 12 PM to 1 September 2014 01:23:45 to 1 September 2014 12:00:00:\n * var result = set(new Date(2014, 8, 1, 1, 23, 45), { hours: 12 })\n * //=> Mon Sep 01 2014 12:23:45\n */\n\nexport default function set(dirtyDate, values) {\n  requiredArgs(2, arguments);\n\n  if (typeof values !== 'object' || values === null) {\n    throw new RangeError('values parameter must be an object');\n  }\n\n  var date = toDate(dirtyDate); // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  }\n\n  if (values.year != null) {\n    date.setFullYear(values.year);\n  }\n\n  if (values.month != null) {\n    date = setMonth(date, values.month);\n  }\n\n  if (values.date != null) {\n    date.setDate(toInteger(values.date));\n  }\n\n  if (values.hours != null) {\n    date.setHours(toInteger(values.hours));\n  }\n\n  if (values.minutes != null) {\n    date.setMinutes(toInteger(values.minutes));\n  }\n\n  if (values.seconds != null) {\n    date.setSeconds(toInteger(values.seconds));\n  }\n\n  if (values.milliseconds != null) {\n    date.setMilliseconds(toInteger(values.milliseconds));\n  }\n\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDate\n * @category Day Helpers\n * @summary Set the day of the month to the given date.\n *\n * @description\n * Set the day of the month to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} dayOfMonth - the day of the month of the new date\n * @returns {Date} the new date with the day of the month set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 30th day of the month to 1 September 2014:\n * var result = setDate(new Date(2014, 8, 1), 30)\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function setDate(dirtyDate, dirtyDayOfMonth) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfMonth = toInteger(dirtyDayOfMonth);\n  date.setDate(dayOfMonth);\n  return date;\n}","import addDays from '../addDays/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDay\n * @category Weekday Helpers\n * @summary Set the day of the week to the given date.\n *\n * @description\n * Set the day of the week to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} day - the day of the week of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the new date with the day of the week set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Set week day to Sunday, with the default weekStartsOn of Sunday:\n * var result = setDay(new Date(2014, 8, 1), 0)\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // Set week day to Sunday, with a weekStartsOn of Monday:\n * var result = setDay(new Date(2014, 8, 1), 0, { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function setDay(dirtyDate, dirtyDay, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate, options);\n  var day = toInteger(dirtyDay);\n  var currentDay = date.getDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var delta = 7 - weekStartsOn;\n  var diff = day < 0 || day > 6 ? day - (currentDay + delta) % 7 : (dayIndex + delta) % 7 - (currentDay + delta) % 7;\n  return addDays(date, diff, options);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDayOfYear\n * @category Day Helpers\n * @summary Set the day of the year to the given date.\n *\n * @description\n * Set the day of the year to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} dayOfYear - the day of the year of the new date\n * @returns {Date} the new date with the day of the year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 2nd day of the year to 2 July 2014:\n * var result = setDayOfYear(new Date(2014, 6, 2), 2)\n * //=> Thu Jan 02 2014 00:00:00\n */\n\nexport default function setDayOfYear(dirtyDate, dirtyDayOfYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfYear = toInteger(dirtyDayOfYear);\n  date.setMonth(0);\n  date.setDate(dayOfYear);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setHours\n * @category Hour Helpers\n * @summary Set the hours to the given date.\n *\n * @description\n * Set the hours to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} hours - the hours of the new date\n * @returns {Date} the new date with the hours set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 4 hours to 1 September 2014 11:30:00:\n * var result = setHours(new Date(2014, 8, 1, 11, 30), 4)\n * //=> Mon Sep 01 2014 04:30:00\n */\n\nexport default function setHours(dirtyDate, dirtyHours) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var hours = toInteger(dirtyHours);\n  date.setHours(hours);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport addDays from '../addDays/index.js';\nimport getISODay from '../getISODay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISODay\n * @category Weekday Helpers\n * @summary Set the day of the ISO week to the given date.\n *\n * @description\n * Set the day of the ISO week to the given date.\n * ISO week starts with Monday.\n * 7 is the index of Sunday, 1 is the index of Monday etc.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} day - the day of the ISO week of the new date\n * @returns {Date} the new date with the day of the ISO week set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set Sunday to 1 September 2014:\n * var result = setISODay(new Date(2014, 8, 1), 7)\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function setISODay(dirtyDate, dirtyDay) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var day = toInteger(dirtyDay);\n  var currentDay = getISODay(date);\n  var diff = day - currentDay;\n  return addDays(date, diff);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport getISOWeek from '../getISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISOWeek\n * @category ISO Week Helpers\n * @summary Set the ISO week to the given date.\n *\n * @description\n * Set the ISO week to the given date, saving the weekday number.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} isoWeek - the ISO week of the new date\n * @returns {Date} the new date with the ISO week set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 53rd ISO week to 7 August 2004:\n * var result = setISOWeek(new Date(2004, 7, 7), 53)\n * //=> Sat Jan 01 2005 00:00:00\n */\n\nexport default function setISOWeek(dirtyDate, dirtyISOWeek) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeek = toInteger(dirtyISOWeek);\n  var diff = getISOWeek(date) - isoWeek;\n  date.setDate(date.getDate() - diff * 7);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Set the ISO week-numbering year to the given date.\n *\n * @description\n * Set the ISO week-numbering year to the given date,\n * saving the week number and the weekday number.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `setISOYear` to `setISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `setWeekYear`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} isoWeekYear - the ISO week-numbering year of the new date\n * @returns {Date} the new date with the ISO week-numbering year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set ISO week-numbering year 2007 to 29 December 2008:\n * var result = setISOWeekYear(new Date(2008, 11, 29), 2007)\n * //=> Mon Jan 01 2007 00:00:00\n */\n\nexport default function setISOWeekYear(dirtyDate, dirtyISOWeekYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeekYear = toInteger(dirtyISOWeekYear);\n  var diff = differenceInCalendarDays(date, startOfISOWeekYear(date));\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(isoWeekYear, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  date = startOfISOWeekYear(fourthOfJanuary);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMilliseconds\n * @category Millisecond Helpers\n * @summary Set the milliseconds to the given date.\n *\n * @description\n * Set the milliseconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} milliseconds - the milliseconds of the new date\n * @returns {Date} the new date with the milliseconds set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 300 milliseconds to 1 September 2014 11:30:40.500:\n * var result = setMilliseconds(new Date(2014, 8, 1, 11, 30, 40, 500), 300)\n * //=> Mon Sep 01 2014 11:30:40.300\n */\n\nexport default function setMilliseconds(dirtyDate, dirtyMilliseconds) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var milliseconds = toInteger(dirtyMilliseconds);\n  date.setMilliseconds(milliseconds);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMinutes\n * @category Minute Helpers\n * @summary Set the minutes to the given date.\n *\n * @description\n * Set the minutes to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} minutes - the minutes of the new date\n * @returns {Date} the new date with the minutes set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 45 minutes to 1 September 2014 11:30:40:\n * var result = setMinutes(new Date(2014, 8, 1, 11, 30, 40), 45)\n * //=> Mon Sep 01 2014 11:45:40\n */\n\nexport default function setMinutes(dirtyDate, dirtyMinutes) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var minutes = toInteger(dirtyMinutes);\n  date.setMinutes(minutes);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport getDaysInMonth from '../getDaysInMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMonth\n * @category Month Helpers\n * @summary Set the month to the given date.\n *\n * @description\n * Set the month to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} month - the month of the new date\n * @returns {Date} the new date with the month set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set February to 1 September 2014:\n * var result = setMonth(new Date(2014, 8, 1), 1)\n * //=> Sat Feb 01 2014 00:00:00\n */\n\nexport default function setMonth(dirtyDate, dirtyMonth) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var month = toInteger(dirtyMonth);\n  var year = date.getFullYear();\n  var day = date.getDate();\n  var dateWithDesiredMonth = new Date(0);\n  dateWithDesiredMonth.setFullYear(year, month, 15);\n  dateWithDesiredMonth.setHours(0, 0, 0, 0);\n  var daysInMonth = getDaysInMonth(dateWithDesiredMonth); // Set the last day of the new month\n  // if the original date was the last day of the longer month\n\n  date.setMonth(month, Math.min(day, daysInMonth));\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport setMonth from '../setMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setQuarter\n * @category Quarter Helpers\n * @summary Set the year quarter to the given date.\n *\n * @description\n * Set the year quarter to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} quarter - the quarter of the new date\n * @returns {Date} the new date with the quarter set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 2nd quarter to 2 July 2014:\n * var result = setQuarter(new Date(2014, 6, 2), 2)\n * //=> Wed Apr 02 2014 00:00:00\n */\n\nexport default function setQuarter(dirtyDate, dirtyQuarter) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var quarter = toInteger(dirtyQuarter);\n  var oldQuarter = Math.floor(date.getMonth() / 3) + 1;\n  var diff = quarter - oldQuarter;\n  return setMonth(date, date.getMonth() + diff * 3);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setSeconds\n * @category Second Helpers\n * @summary Set the seconds to the given date.\n *\n * @description\n * Set the seconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} seconds - the seconds of the new date\n * @returns {Date} the new date with the seconds set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 45 seconds to 1 September 2014 11:30:40:\n * var result = setSeconds(new Date(2014, 8, 1, 11, 30, 40), 45)\n * //=> Mon Sep 01 2014 11:30:45\n */\n\nexport default function setSeconds(dirtyDate, dirtySeconds) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var seconds = toInteger(dirtySeconds);\n  date.setSeconds(seconds);\n  return date;\n}","import getWeek from '../getWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setWeek\n * @category Week Helpers\n * @summary Set the local week to the given date.\n *\n * @description\n * Set the local week to the given date, saving the weekday number.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} week - the week of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the new date with the local week set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Set the 1st week to 2 January 2005 with default options:\n * var result = setWeek(new Date(2005, 0, 2), 1)\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // Set the 1st week to 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January:\n * var result = setWeek(new Date(2005, 0, 2), 1, {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Sun Jan 4 2004 00:00:00\n */\n\nexport default function setWeek(dirtyDate, dirtyWeek, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var week = toInteger(dirtyWeek);\n  var diff = getWeek(date, dirtyOptions) - week;\n  date.setDate(date.getDate() - diff * 7);\n  return date;\n}","import differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport startOfWeekYear from '../startOfWeekYear/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Set the local week-numbering year to the given date.\n *\n * @description\n * Set the local week-numbering year to the given date,\n * saving the week number and the weekday number.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} weekYear - the local week-numbering year of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the new date with the local week-numbering year set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Set the local week-numbering year 2004 to 2 January 2010 with default options:\n * var result = setWeekYear(new Date(2010, 0, 2), 2004)\n * //=> Sat Jan 03 2004 00:00:00\n *\n * @example\n * // Set the local week-numbering year 2004 to 2 January 2010,\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * var result = setWeekYear(new Date(2010, 0, 2), 2004, {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Sat Jan 01 2005 00:00:00\n */\n\nexport default function setWeekYear(dirtyDate, dirtyWeekYear, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var date = toDate(dirtyDate);\n  var weekYear = toInteger(dirtyWeekYear);\n  var diff = differenceInCalendarDays(date, startOfWeekYear(date, dirtyOptions));\n  var firstWeek = new Date(0);\n  firstWeek.setFullYear(weekYear, 0, firstWeekContainsDate);\n  firstWeek.setHours(0, 0, 0, 0);\n  date = startOfWeekYear(firstWeek, dirtyOptions);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setYear\n * @category Year Helpers\n * @summary Set the year to the given date.\n *\n * @description\n * Set the year to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} year - the year of the new date\n * @returns {Date} the new date with the year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set year 2013 to 1 September 2014:\n * var result = setYear(new Date(2014, 8, 1), 2013)\n * //=> Sun Sep 01 2013 00:00:00\n */\n\nexport default function setYear(dirtyDate, dirtyYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var year = toInteger(dirtyYear); // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  }\n\n  date.setFullYear(year);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfDay\n * @category Day Helpers\n * @summary Return the start of a day for the given date.\n *\n * @description\n * Return the start of a day for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a day\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a day for 2 September 2014 11:55:00:\n * var result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 00:00:00\n */\n\nexport default function startOfDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfDecade\n * @category Decade Helpers\n * @summary Return the start of a decade for the given date.\n *\n * @description\n * Return the start of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a decade for 21 October 2015 00:00:00:\n * var result = startOfDecade(new Date(2015, 9, 21, 00, 00, 00))\n * //=> Jan 01 2010 00:00:00\n */\n\nexport default function startOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = Math.floor(year / 10) * 10;\n  date.setFullYear(decade, 0, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfHour\n * @category Hour Helpers\n * @summary Return the start of an hour for the given date.\n *\n * @description\n * Return the start of an hour for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an hour for 2 September 2014 11:55:00:\n * var result = startOfHour(new Date(2014, 8, 2, 11, 55))\n * //=> Tue Sep 02 2014 11:00:00\n */\n\nexport default function startOfHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMinutes(0, 0, 0);\n  return date;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the start of an ISO week for the given date.\n *\n * @description\n * Return the start of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week for 2 September 2014 11:55:00:\n * var result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return startOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the start of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the start of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week-numbering year for 2 July 2005:\n * var result = startOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(year, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuary);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfMinute\n * @category Minute Helpers\n * @summary Return the start of a minute for the given date.\n *\n * @description\n * Return the start of a minute for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a minute for 1 December 2014 22:15:45.400:\n * var result = startOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:00\n */\n\nexport default function startOfMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setSeconds(0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfMonth\n * @category Month Helpers\n * @summary Return the start of a month for the given date.\n *\n * @description\n * Return the start of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a month for 2 September 2014 11:55:00:\n * var result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setDate(1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfQuarter\n * @category Quarter Helpers\n * @summary Return the start of a year quarter for the given date.\n *\n * @description\n * Return the start of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a quarter for 2 September 2014 11:55:00:\n * var result = startOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Jul 01 2014 00:00:00\n */\n\nexport default function startOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3;\n  date.setMonth(month, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfSecond\n * @category Second Helpers\n * @summary Return the start of a second for the given date.\n *\n * @description\n * Return the start of a second for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a second for 1 December 2014 22:15:45.400:\n * var result = startOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:45.000\n */\n\nexport default function startOfSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMilliseconds(0);\n  return date;\n}","import startOfDay from '../startOfDay/index.js';\n/**\n * @name startOfToday\n * @category Day Helpers\n * @summary Return the start of today.\n * @pure false\n *\n * @description\n * Return the start of today.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of today\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfToday()\n * //=> Mon Oct 6 2014 00:00:00\n */\n\nexport default function startOfToday() {\n  return startOfDay(Date.now());\n}","/**\n * @name startOfTomorrow\n * @category Day Helpers\n * @summary Return the start of tomorrow.\n * @pure false\n *\n * @description\n * Return the start of tomorrow.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of tomorrow\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfTomorrow()\n * //=> Tue Oct 7 2014 00:00:00\n */\nexport default function startOfTomorrow() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day + 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfWeek\n * @category Week Helpers\n * @summary Return the start of a week for the given date.\n *\n * @description\n * Return the start of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the start of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The start of a week for 2 September 2014 11:55:00:\n * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:\n * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setDate(date.getDate() - diff);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import getWeekYear from '../getWeekYear/index.js';\nimport startOfWeek from '../startOfWeek/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Return the start of a local week-numbering year for the given date.\n *\n * @description\n * Return the start of a local week-numbering year.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the start of a week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // The start of an a week-numbering year for 2 July 2005 with default settings:\n * var result = startOfWeekYear(new Date(2005, 6, 2))\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // The start of a week-numbering year for 2 July 2005\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * var result = startOfWeekYear(new Date(2005, 6, 2), {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var year = getWeekYear(dirtyDate, dirtyOptions);\n  var firstWeek = new Date(0);\n  firstWeek.setFullYear(year, 0, firstWeekContainsDate);\n  firstWeek.setHours(0, 0, 0, 0);\n  var date = startOfWeek(firstWeek, dirtyOptions);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfYear\n * @category Year Helpers\n * @summary Return the start of a year for the given date.\n *\n * @description\n * Return the start of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a year for 2 September 2014 11:55:00:\n * var result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Jan 01 2014 00:00:00\n */\n\nexport default function startOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var cleanDate = toDate(dirtyDate);\n  var date = new Date(0);\n  date.setFullYear(cleanDate.getFullYear(), 0, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","/**\n * @name startOfYesterday\n * @category Day Helpers\n * @summary Return the start of yesterday.\n * @pure false\n *\n * @description\n * Return the start of yesterday.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of yesterday\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfYesterday()\n * //=> Sun Oct 5 2014 00:00:00\n */\nexport default function startOfYesterday() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day - 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import subDays from '../subDays/index.js';\nimport subMonths from '../subMonths/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name sub\n * @category Common Helpers\n * @summary Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.\n *\n * @description\n * Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Duration} duration - the object with years, months, weeks, days, hours, minutes and seconds to be subtracted\n *\n * | Key     | Description                        |\n * |---------|------------------------------------|\n * | years   | Amount of years to be subtracted   |\n * | months  | Amount of months to be subtracted  |\n * | weeks   | Amount of weeks to be subtracted   |\n * | days    | Amount of days to be subtracted    |\n * | hours   | Amount of hours to be subtracted   |\n * | minutes | Amount of minutes to be subtracted |\n * | seconds | Amount of seconds to be subtracted |\n *\n * All values default to 0\n *\n * @returns {Date} the new date with the seconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract the following duration from 15 June 2017 15:29:20\n * const result = sub(new Date(2017, 5, 15, 15, 29, 20), {\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30\n * })\n * //=> Mon Sep 1 2014 10:19:50\n */\n\nexport default function sub(dirtyDate, duration) {\n  requiredArgs(2, arguments);\n  if (!duration || typeof duration !== 'object') return new Date(NaN);\n  var years = 'years' in duration ? toInteger(duration.years) : 0;\n  var months = 'months' in duration ? toInteger(duration.months) : 0;\n  var weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0;\n  var days = 'days' in duration ? toInteger(duration.days) : 0;\n  var hours = 'hours' in duration ? toInteger(duration.hours) : 0;\n  var minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0;\n  var seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0; // Subtract years and months\n\n  var dateWithoutMonths = subMonths(toDate(dirtyDate), months + years * 12); // Subtract weeks and days\n\n  var dateWithoutDays = subDays(dateWithoutMonths, days + weeks * 7); // Subtract hours, minutes and seconds\n\n  var minutestoSub = minutes + hours * 60;\n  var secondstoSub = seconds + minutestoSub * 60;\n  var mstoSub = secondstoSub * 1000;\n  var finalDate = new Date(dateWithoutDays.getTime() - mstoSub);\n  return finalDate;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addBusinessDays from '../addBusinessDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subBusinessDays\n * @category Day Helpers\n * @summary Substract the specified number of business days (mon - fri) to the given date.\n *\n * @description\n * Substract the specified number of business days (mon - fri) to the given date, ignoring weekends.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of business days to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the business days subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Substract 10 business days from 1 September 2014:\n * var result = subBusinessDays(new Date(2014, 8, 1), 10)\n * //=> Mon Aug 18 2014 00:00:00 (skipped weekend days)\n */\n\nexport default function subBusinessDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addBusinessDays(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addDays from '../addDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subDays\n * @category Day Helpers\n * @summary Subtract the specified number of days from the given date.\n *\n * @description\n * Subtract the specified number of days from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the days subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 10 days from 1 September 2014:\n * var result = subDays(new Date(2014, 8, 1), 10)\n * //=> Fri Aug 22 2014 00:00:00\n */\n\nexport default function subDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addDays(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addHours from '../addHours/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subHours\n * @category Hour Helpers\n * @summary Subtract the specified number of hours from the given date.\n *\n * @description\n * Subtract the specified number of hours from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of hours to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the hours subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 2 hours from 11 July 2014 01:00:00:\n * var result = subHours(new Date(2014, 6, 11, 1, 0), 2)\n * //=> Thu Jul 10 2014 23:00:00\n */\n\nexport default function subHours(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addHours(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addISOWeekYears from '../addISOWeekYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Subtract the specified number of ISO week-numbering years from the given date.\n *\n * @description\n * Subtract the specified number of ISO week-numbering years from the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `subISOYears` to `subISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `setWeekYear`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of ISO week-numbering years to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the ISO week-numbering years subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 ISO week-numbering years from 1 September 2014:\n * var result = subISOWeekYears(new Date(2014, 8, 1), 5)\n * //=> Mon Aug 31 2009 00:00:00\n */\n\nexport default function subISOWeekYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addISOWeekYears(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMilliseconds\n * @category Millisecond Helpers\n * @summary Subtract the specified number of milliseconds from the given date.\n *\n * @description\n * Subtract the specified number of milliseconds from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of milliseconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the milliseconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 750 milliseconds from 10 July 2014 12:45:30.000:\n * var result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)\n * //=> Thu Jul 10 2014 12:45:29.250\n */\n\nexport default function subMilliseconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMinutes from '../addMinutes/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMinutes\n * @category Minute Helpers\n * @summary Subtract the specified number of minutes from the given date.\n *\n * @description\n * Subtract the specified number of minutes from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of minutes to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the minutes subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 30 minutes from 10 July 2014 12:00:00:\n * var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30)\n * //=> Thu Jul 10 2014 11:30:00\n */\n\nexport default function subMinutes(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMinutes(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMonths\n * @category Month Helpers\n * @summary Subtract the specified number of months from the given date.\n *\n * @description\n * Subtract the specified number of months from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of months to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the months subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 months from 1 February 2015:\n * var result = subMonths(new Date(2015, 1, 1), 5)\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function subMonths(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMonths(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addQuarters from '../addQuarters/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subQuarters\n * @category Quarter Helpers\n * @summary Subtract the specified number of year quarters from the given date.\n *\n * @description\n * Subtract the specified number of year quarters from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of quarters to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the quarters subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 3 quarters from 1 September 2014:\n * var result = subQuarters(new Date(2014, 8, 1), 3)\n * //=> Sun Dec 01 2013 00:00:00\n */\n\nexport default function subQuarters(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addQuarters(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addSeconds from '../addSeconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subSeconds\n * @category Second Helpers\n * @summary Subtract the specified number of seconds from the given date.\n *\n * @description\n * Subtract the specified number of seconds from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 30 seconds from 10 July 2014 12:45:00:\n * var result = subSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:44:30\n */\n\nexport default function subSeconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addSeconds(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addWeeks from '../addWeeks/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subWeeks\n * @category Week Helpers\n * @summary Subtract the specified number of weeks from the given date.\n *\n * @description\n * Subtract the specified number of weeks from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of weeks to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the weeks subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 4 weeks from 1 September 2014:\n * var result = subWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Aug 04 2014 00:00:00\n */\n\nexport default function subWeeks(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addWeeks(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addYears from '../addYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subYears\n * @category Year Helpers\n * @summary Subtract the specified number of years from the given date.\n *\n * @description\n * Subtract the specified number of years from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 years from 1 September 2014:\n * var result = subYears(new Date(2014, 8, 1), 5)\n * //=> Tue Sep 01 2009 00:00:00\n */\n\nexport default function subYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addYears(dirtyDate, -amount);\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @param {Date|Number} argument - the value to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\n\nexport default function toDate(argument) {\n  requiredArgs(1, arguments);\n  var argStr = Object.prototype.toString.call(argument); // Clone the date\n\n  if (argument instanceof Date || typeof argument === 'object' && argStr === '[object Date]') {\n    // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n    return new Date(argument.getTime());\n  } else if (typeof argument === 'number' || argStr === '[object Number]') {\n    return new Date(argument);\n  } else {\n    if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {\n      // eslint-disable-next-line no-console\n      console.warn(\"Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule\"); // eslint-disable-next-line no-console\n\n      console.warn(new Error().stack);\n    }\n\n    return new Date(NaN);\n  }\n}","import { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nfunction _extends() {\n  _extends = Object.assign || function (target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i];\n\n      for (var key in source) {\n        if (Object.prototype.hasOwnProperty.call(source, key)) {\n          target[key] = source[key];\n        }\n      }\n    }\n\n    return target;\n  };\n\n  return _extends.apply(this, arguments);\n}\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n  if (source == null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key, i;\n\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n\n  return target;\n}\n\nfunction toInteger(dirtyNumber) {\n  if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {\n    return NaN;\n  }\n\n  var number = Number(dirtyNumber);\n\n  if (isNaN(number)) {\n    return number;\n  }\n\n  return number < 0 ? Math.ceil(number) : Math.floor(number);\n}\n\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @param {Date|Number} argument - the value to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nfunction toDate(argument) {\n  if (arguments.length < 1) {\n    throw new TypeError('1 argument required, but only ' + arguments.length + ' present');\n  }\n\n  var argStr = Object.prototype.toString.call(argument); // Clone the date\n\n  if (argument instanceof Date || typeof argument === 'object' && argStr === '[object Date]') {\n    // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n    return new Date(argument.getTime());\n  } else if (typeof argument === 'number' || argStr === '[object Number]') {\n    return new Date(argument);\n  } else {\n    if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {\n      // eslint-disable-next-line no-console\n      console.warn(\"Starting with v2.0.0-beta.1 date-fns doesn't accept strings as arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule\"); // eslint-disable-next-line no-console\n\n      console.warn(new Error().stack);\n    }\n\n    return new Date(NaN);\n  }\n}\n\n/**\n * @name addDays\n * @category Day Helpers\n * @summary Add the specified number of days to the given date.\n *\n * @description\n * Add the specified number of days to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be added\n * @returns {Date} the new date with the days added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 10 days to 1 September 2014:\n * var result = addDays(new Date(2014, 8, 1), 10)\n * //=> Thu Sep 11 2014 00:00:00\n */\n\nfunction addDays(dirtyDate, dirtyAmount) {\n  if (arguments.length < 2) {\n    throw new TypeError('2 arguments required, but only ' + arguments.length + ' present');\n  }\n\n  var date = toDate(dirtyDate);\n  var amount = toInteger(dirtyAmount);\n  date.setDate(date.getDate() + amount);\n  return date;\n}\n\n/**\n * @name isBefore\n * @category Common Helpers\n * @summary Is the first date before the second one?\n *\n * @description\n * Is the first date before the second one?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date that should be before the other one to return true\n * @param {Date|Number} dateToCompare - the date to compare with\n * @returns {Boolean} the first date is before the second date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Is 10 July 1989 before 11 February 1987?\n * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))\n * //=> false\n */\n\nfunction isBefore(dirtyDate, dirtyDateToCompare) {\n  if (arguments.length < 2) {\n    throw new TypeError('2 arguments required, but only ' + arguments.length + ' present');\n  }\n\n  var date = toDate(dirtyDate);\n  var dateToCompare = toDate(dirtyDateToCompare);\n  return date.getTime() < dateToCompare.getTime();\n}\n\n/**\n * @name startOfDay\n * @category Day Helpers\n * @summary Return the start of a day for the given date.\n *\n * @description\n * Return the start of a day for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a day\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a day for 2 September 2014 11:55:00:\n * var result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 00:00:00\n */\n\nfunction startOfDay(dirtyDate) {\n  if (arguments.length < 1) {\n    throw new TypeError('1 argument required, but only ' + arguments.length + ' present');\n  }\n\n  var date = toDate(dirtyDate);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}\n\n/**\n * @name isSameDay\n * @category Day Helpers\n * @summary Are the given dates in the same day?\n *\n * @description\n * Are the given dates in the same day?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same day\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?\n * var result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))\n * //=> true\n */\n\nfunction isSameDay(dirtyDateLeft, dirtyDateRight) {\n  if (arguments.length < 2) {\n    throw new TypeError('2 arguments required, but only ' + arguments.length + ' present');\n  }\n\n  var dateLeftStartOfDay = startOfDay(dirtyDateLeft);\n  var dateRightStartOfDay = startOfDay(dirtyDateRight);\n  return dateLeftStartOfDay.getTime() === dateRightStartOfDay.getTime();\n}\n\n/**\n * @name isToday\n * @category Day Helpers\n * @summary Is the given date today?\n * @pure false\n *\n * @description\n * Is the given date today?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is today\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 6 October 14:00:00 today?\n * var result = isToday(new Date(2014, 9, 6, 14, 0))\n * //=> true\n */\n\nfunction isToday(dirtyDate) {\n  if (arguments.length < 1) {\n    throw new TypeError('1 argument required, but only ' + arguments.length + ' present');\n  }\n\n  return isSameDay(dirtyDate, Date.now());\n}\n\n/**\n * @name differenceInCalendarMonths\n * @category Month Helpers\n * @summary Get the number of calendar months between the given dates.\n *\n * @description\n * Get the number of calendar months between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar months\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar months are between 31 January 2014 and 1 September 2014?\n * var result = differenceInCalendarMonths(\n *   new Date(2014, 8, 1),\n *   new Date(2014, 0, 31)\n * )\n * //=> 8\n */\n\nfunction differenceInCalendarMonths(dirtyDateLeft, dirtyDateRight) {\n  if (arguments.length < 2) {\n    throw new TypeError('2 arguments required, but only ' + arguments.length + ' present');\n  }\n\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();\n  var monthDiff = dateLeft.getMonth() - dateRight.getMonth();\n  return yearDiff * 12 + monthDiff;\n}\n\n/**\n * This is intended to be used to compose event handlers\n * They are executed in order until one of them calls\n * `event.preventDefault()`. Not sure this is the best\n * way to do this, but it seems legit...\n * @param {Function} fns the event hanlder functions\n * @return {Function} the event handler to add to an element\n */\n\nfunction composeEventHandlers() {\n  for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {\n    fns[_key] = arguments[_key];\n  }\n\n  return function (event) {\n    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n      args[_key2 - 1] = arguments[_key2];\n    }\n\n    return fns.some(function (fn) {\n      fn && fn.apply(void 0, [event].concat(args));\n      return event.defaultPrevented;\n    });\n  };\n}\n/**\n * Throws a helpful error message for required properties. Useful\n * to be used as a default in destructuring or object params.\n * @param {String} fnName the function name\n * @param {String} propName the prop name\n */\n\nfunction requiredProp(fnName, propName) {\n  throw new Error(\"The property \\\"\" + propName + \"\\\" is required in \\\"\" + fnName + \"\\\"\");\n}\n/**\n * Takes an argument and if it's an array, returns the first item in the array\n * otherwise returns the argument.\n * @param {*} arg the maybe-array\n * @return {*} the arg or it's first item\n */\n\nfunction unwrapChildrenForPreact(arg) {\n  arg = Array.isArray(arg) ?\n  /* istanbul ignore next (preact) */\n  arg[0] : arg;\n  return arg || noop;\n}\n\nfunction noop() {}\n/**\n * Takes a calendars array and figures out the number of months to subtract\n * based on the current offset and the minDate allowed.\n * @param {Object} param The param object\n * @param {Array} param.calendars The calendars array created by the getCalendars function\n * @param {Number} param.offset The num of months to be subtracted\n * @param {Date} param.minDate The earliest date we are allow to subtract back to\n * @returns {Number} The number of months to subtract\n */\n\n\nfunction subtractMonth(_ref) {\n  var calendars = _ref.calendars,\n      offset = _ref.offset,\n      minDate = _ref.minDate;\n\n  if (offset > 1 && minDate) {\n    var firstDayOfMonth = calendars[0].firstDayOfMonth;\n    var diffInMonths = differenceInCalendarMonths(firstDayOfMonth, minDate);\n\n    if (diffInMonths < offset) {\n      offset = diffInMonths;\n    }\n  }\n\n  return offset;\n}\n/**\n * Takes a calendars array and figures out the number of months to add\n * based on the current offset and the maxDate allowed.\n * @param {Object} param The param object\n * @param {Array} param.calendars The calendars array created by the getCalendars function\n * @param {Number} param.offset The num of months to be added\n * @param {Date} param.maxDate The furthest date we are allow to add forward to\n * @returns {Number} The number of months to add\n */\n\nfunction addMonth(_ref2) {\n  var calendars = _ref2.calendars,\n      offset = _ref2.offset,\n      maxDate = _ref2.maxDate;\n\n  if (offset > 1 && maxDate) {\n    var lastDayOfMonth = calendars[calendars.length - 1].lastDayOfMonth;\n    var diffInMonths = differenceInCalendarMonths(maxDate, lastDayOfMonth);\n\n    if (diffInMonths < offset) {\n      offset = diffInMonths;\n    }\n  }\n\n  return offset;\n}\n/**\n * Takes a calendars array and figures out if the back button should be\n * disabled based on the minDate allowed.\n * @param {Object} param The param object\n * @param {Array} param.calendars The calendars array created by the getCalendars function\n * @param {Date} param.minDate The earliest date available\n * @returns {Boolean} Whether the back button should be disabled.\n */\n\nfunction isBackDisabled(_ref3) {\n  var calendars = _ref3.calendars,\n      minDate = _ref3.minDate;\n\n  if (!minDate) {\n    return false;\n  }\n\n  var firstDayOfMonth = calendars[0].firstDayOfMonth;\n  var firstDayOfMonthMinusOne = addDays(firstDayOfMonth, -1);\n\n  if (isBefore(firstDayOfMonthMinusOne, minDate)) {\n    return true;\n  }\n\n  return false;\n}\n/**\n * Takes a calendars array and figures out if the forward button should be\n * disabled based on the maxDate allowed.\n * @param {Object} param The param object\n * @param {Array} param.calendars The calendars array created by the getCalendars function\n * @param {Date} param.maxDate The furthest date available\n * @returns {Boolean} Whether the forward button should be disabled.\n */\n\nfunction isForwardDisabled(_ref4) {\n  var calendars = _ref4.calendars,\n      maxDate = _ref4.maxDate;\n\n  if (!maxDate) {\n    return false;\n  }\n\n  var lastDayOfMonth = calendars[calendars.length - 1].lastDayOfMonth;\n  var lastDayOfMonthPlusOne = addDays(lastDayOfMonth, 1);\n\n  if (isBefore(maxDate, lastDayOfMonthPlusOne)) {\n    return true;\n  }\n\n  return false;\n}\n/**\n * Figures out the months data needed based off the number of monthsToDisplay\n * and other options provided.\n * @param {Object} param The param object\n * @param {Date} param.date The date to start the calendar at\n * @param {Array.<Date>} param.selected An array of dates currently selected\n * @param {Number} param.monthsToDisplay The number of months to return in the calendar view\n * @param {Number} param.offset The number of months to offset based off the param.date given\n * @param {Date} param.minDate The earliest date available\n * @param {Date} param.maxDate The furthest date available\n * @param {Number} param.firstDayOfWeek First day of week, 0-6 (Sunday to Saturday)\n * @param {Bool} param.showOutsideDays Flag to fill front and back weeks with dates from adjacent months\n * @returns {Array.<Object>} An array of objects with month data\n */\n\nfunction getCalendars(_ref5) {\n  var date = _ref5.date,\n      selected = _ref5.selected,\n      monthsToDisplay = _ref5.monthsToDisplay,\n      offset = _ref5.offset,\n      minDate = _ref5.minDate,\n      maxDate = _ref5.maxDate,\n      firstDayOfWeek = _ref5.firstDayOfWeek,\n      showOutsideDays = _ref5.showOutsideDays;\n  var months = [];\n  var startDate = getStartDate(date, minDate, maxDate);\n\n  for (var i = 0; i < monthsToDisplay; i++) {\n    var calendarDates = getMonths({\n      month: startDate.getMonth() + i + offset,\n      year: startDate.getFullYear(),\n      selectedDates: selected,\n      minDate: minDate,\n      maxDate: maxDate,\n      firstDayOfWeek: firstDayOfWeek,\n      showOutsideDays: showOutsideDays\n    });\n    months.push(calendarDates);\n  }\n\n  return months;\n}\n/**\n * Figures out the actual start date based on\n * the min and max dates available.\n * @param {Date} date The we want to start the calendar at\n * @param {Date} minDate The earliest date available to start at\n * @param {Date} maxDate The latest date available to start at\n * @returns {Date} The actual start date\n */\n\nfunction getStartDate(date, minDate, maxDate) {\n  var startDate = startOfDay(date);\n\n  if (minDate) {\n    var minDateNormalized = startOfDay(minDate);\n\n    if (isBefore(startDate, minDateNormalized)) {\n      startDate = minDateNormalized;\n    }\n  }\n\n  if (maxDate) {\n    var maxDateNormalized = startOfDay(maxDate);\n\n    if (isBefore(maxDateNormalized, startDate)) {\n      startDate = maxDateNormalized;\n    }\n  }\n\n  return startDate;\n}\n/**\n * Figures what week/day data to return for the given month\n * and year. Adds flags to day data if found in the given selectedDates,\n * if is selectable inside the given min and max dates, or is today.\n * @param {Object} param The param object\n * @param {Number} param.month The month to grab data for\n * @param {Number} param.year The year to grab data for\n * @param {Array.<Date>} sparam.electedDates An array of dates currently selected\n * @param {Date} param.minDate The earliest date available\n * @param {Date} param.maxDate The furthest date available\n * @param {Number} param.firstDayOfWeek First day of week, 0-6 (Sunday to Saturday)\n * @param {Bool} param.showOutsideDays Flag to fill front and back weeks with dates from adjacent months\n * @returns {Object} The data for the selected month/year\n */\n\n\nfunction getMonths(_ref6) {\n  var month = _ref6.month,\n      year = _ref6.year,\n      selectedDates = _ref6.selectedDates,\n      minDate = _ref6.minDate,\n      maxDate = _ref6.maxDate,\n      firstDayOfWeek = _ref6.firstDayOfWeek,\n      showOutsideDays = _ref6.showOutsideDays;\n  // Get the normalized month and year, along with days in the month.\n  var daysMonthYear = getNumDaysMonthYear(month, year);\n  var daysInMonth = daysMonthYear.daysInMonth;\n  month = daysMonthYear.month;\n  year = daysMonthYear.year; // Fill out the dates for the month.\n\n  var dates = [];\n\n  for (var day = 1; day <= daysInMonth; day++) {\n    var date = new Date(year, month, day);\n    var dateObj = {\n      date: date,\n      selected: isSelected(selectedDates, date),\n      selectable: isSelectable(minDate, maxDate, date),\n      today: isToday(date),\n      prevMonth: false,\n      nextMonth: false\n    };\n    dates.push(dateObj);\n  }\n\n  var firstDayOfMonth = new Date(year, month, 1);\n  var lastDayOfMonth = new Date(year, month, daysInMonth);\n  var frontWeekBuffer = fillFrontWeek({\n    firstDayOfMonth: firstDayOfMonth,\n    minDate: minDate,\n    maxDate: maxDate,\n    selectedDates: selectedDates,\n    firstDayOfWeek: firstDayOfWeek,\n    showOutsideDays: showOutsideDays\n  });\n  var backWeekBuffer = fillBackWeek({\n    lastDayOfMonth: lastDayOfMonth,\n    minDate: minDate,\n    maxDate: maxDate,\n    selectedDates: selectedDates,\n    firstDayOfWeek: firstDayOfWeek,\n    showOutsideDays: showOutsideDays\n  });\n  dates.unshift.apply(dates, frontWeekBuffer);\n  dates.push.apply(dates, backWeekBuffer); // Get the filled out weeks for the\n  // given dates.\n\n  var weeks = getWeeks(dates); // return the calendar data.\n\n  return {\n    firstDayOfMonth: firstDayOfMonth,\n    lastDayOfMonth: lastDayOfMonth,\n    month: month,\n    year: year,\n    weeks: weeks\n  };\n}\n/**\n * Fill front week with either empty buffer or dates from previous month,\n * depending on showOutsideDays flag\n * @param {Object} param The param object\n * @param {Array.<Date>} param.selectedDates An array of dates currently selected\n * @param {Date} param.minDate The earliest date available\n * @param {Date} param.maxDate The furthest date available\n * @param {Date} param.firstDayOfMonth First day of the month\n * @param {Number} param.firstDayOfWeek First day of week, 0-6 (Sunday to Saturday)\n * @param {Bool} param.showOutsideDays Flag to fill front and back weeks with dates from adjacent months\n * @returns {Array.<Date>} Buffer to fill front week\n */\n\n\nfunction fillFrontWeek(_ref7) {\n  var firstDayOfMonth = _ref7.firstDayOfMonth,\n      minDate = _ref7.minDate,\n      maxDate = _ref7.maxDate,\n      selectedDates = _ref7.selectedDates,\n      firstDayOfWeek = _ref7.firstDayOfWeek,\n      showOutsideDays = _ref7.showOutsideDays;\n  var dates = [];\n  var firstDay = (firstDayOfMonth.getDay() + 7 - firstDayOfWeek) % 7;\n\n  if (showOutsideDays) {\n    var lastDayOfPrevMonth = addDays(firstDayOfMonth, -1);\n    var prevDate = lastDayOfPrevMonth.getDate();\n    var prevDateMonth = lastDayOfPrevMonth.getMonth();\n    var prevDateYear = lastDayOfPrevMonth.getFullYear(); // Fill out front week for days from\n    // preceding month with dates from previous month.\n\n    var counter = 0;\n\n    while (counter < firstDay) {\n      var date = new Date(prevDateYear, prevDateMonth, prevDate - counter);\n      var dateObj = {\n        date: date,\n        selected: isSelected(selectedDates, date),\n        selectable: isSelectable(minDate, maxDate, date),\n        today: false,\n        prevMonth: true,\n        nextMonth: false\n      };\n      dates.unshift(dateObj);\n      counter++;\n    }\n  } else {\n    // Fill out front week for days from\n    // preceding month with buffer.\n    while (firstDay > 0) {\n      dates.unshift('');\n      firstDay--;\n    }\n  }\n\n  return dates;\n}\n/**\n * Fill back weeks with either empty buffer or dates from next month,\n * depending on showOutsideDays flag\n * @param {Object} param The param object\n * @param {Array.<Date>} param.selectedDates An array of dates currently selected\n * @param {Date} param.minDate The earliest date available\n * @param {Date} param.maxDate The furthest date available\n * @param {Date} param.lastDayOfMonth Last day of the month\n * @param {Number} param.firstDayOfWeek First day of week, 0-6 (Sunday to Saturday)\n * @param {Bool} param.showOutsideDays Flag to fill front and back weeks with dates from adjacent months\n * @returns {Array.<Date>} Buffer to fill back week\n */\n\n\nfunction fillBackWeek(_ref8) {\n  var lastDayOfMonth = _ref8.lastDayOfMonth,\n      minDate = _ref8.minDate,\n      maxDate = _ref8.maxDate,\n      selectedDates = _ref8.selectedDates,\n      firstDayOfWeek = _ref8.firstDayOfWeek,\n      showOutsideDays = _ref8.showOutsideDays;\n  var dates = [];\n  var lastDay = (lastDayOfMonth.getDay() + 7 - firstDayOfWeek) % 7;\n\n  if (showOutsideDays) {\n    var firstDayOfNextMonth = addDays(lastDayOfMonth, 1);\n    var nextDateMonth = firstDayOfNextMonth.getMonth();\n    var nextDateYear = firstDayOfNextMonth.getFullYear(); // Fill out back week for days from\n    // following month with dates from next month.\n\n    var counter = 0;\n\n    while (counter < 6 - lastDay) {\n      var date = new Date(nextDateYear, nextDateMonth, 1 + counter);\n      var dateObj = {\n        date: date,\n        selected: isSelected(selectedDates, date),\n        selectable: isSelectable(minDate, maxDate, date),\n        today: false,\n        prevMonth: false,\n        nextMonth: true\n      };\n      dates.push(dateObj);\n      counter++;\n    }\n  } else {\n    // Fill out back week for days from\n    // following month with buffer.\n    while (lastDay < 6) {\n      dates.push('');\n      lastDay++;\n    }\n  }\n\n  return dates;\n}\n/**\n * Normalizes month (could be overflow) and year pairs and returns the\n * normalized month and year along with the number of days in the month.\n * @param {Number} month The month to normalize\n * @param {Number} year The year to normalize\n * @returns {Object} The normalized month and year along with the number of days in the month\n */\n\n\nfunction getNumDaysMonthYear(month, year) {\n  // If a parameter you specify is outside of the expected range for Month or Day,\n  // JS Date attempts to update the date information in the Date object accordingly!\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate\n  // Let Date handle the overflow of the month,\n  // which should return the normalized month and year.\n  var normalizedMonthYear = new Date(year, month, 1);\n  month = normalizedMonthYear.getMonth();\n  year = normalizedMonthYear.getFullYear(); // Overflow the date to the next month, then subtract the difference\n  // to get the number of days in the previous month.\n  // This will also account for leap years!\n\n  var daysInMonth = 32 - new Date(year, month, 32).getDate();\n  return {\n    daysInMonth: daysInMonth,\n    month: month,\n    year: year\n  };\n}\n/**\n * Takes an array of dates, and turns them into a multi dimensional\n * array with 7 entries for each week.\n * @param {Array.<Object>} dates An array of dates\n * @returns {Array} The weeks as a multi dimensional array\n */\n\n\nfunction getWeeks(dates) {\n  var weeksLength = Math.ceil(dates.length / 7);\n  var weeks = [];\n\n  for (var i = 0; i < weeksLength; i++) {\n    weeks[i] = [];\n\n    for (var x = 0; x < 7; x++) {\n      weeks[i].push(dates[i * 7 + x]);\n    }\n  }\n\n  return weeks;\n}\n/**\n * Normalizes dates to the beginning of the day,\n * then checks to see if the day given is found\n * in the selectedDates.\n * @param {Array.<Date>} selectedDates An array of dates currently selected\n * @param {Date} date The date to search with against selectedDates\n * @returns {Boolean} Whether day is found in selectedDates\n */\n\n\nfunction isSelected(selectedDates, date) {\n  selectedDates = Array.isArray(selectedDates) ? selectedDates : [selectedDates];\n  return selectedDates.some(function (selectedDate) {\n    if (selectedDate instanceof Date && startOfDay(selectedDate).getTime() === startOfDay(date).getTime()) {\n      return true;\n    }\n\n    return false;\n  });\n}\n/**\n * Checks to see if the date given is\n * between the min and max dates.\n * @param {Date} minDate The earliest date available\n * @param {Date} maxDate The furthest date available\n * @param {Date} date The date to compare with\n * @returns {Boolean} Whether the date is between min and max date\n */\n\n\nfunction isSelectable(minDate, maxDate, date) {\n  if (minDate && isBefore(date, minDate) || maxDate && isBefore(maxDate, date)) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction isOffsetControlled(propOffset) {\n  return propOffset !== undefined;\n}\n\nfunction getOffset(prop, state) {\n  return isOffsetControlled(prop) ? prop : state;\n}\n\nfunction getDateProps(onDateSelected, _temp) {\n  var _ref = _temp === void 0 ? {} : _temp,\n      onClick = _ref.onClick,\n      _ref$dateObj = _ref.dateObj,\n      dateObj = _ref$dateObj === void 0 ? requiredProp('getDateProps', 'dateObj') : _ref$dateObj,\n      rest = _objectWithoutPropertiesLoose(_ref, [\"onClick\", \"dateObj\"]);\n\n  return _extends({\n    onClick: composeEventHandlers(onClick, function (event) {\n      onDateSelected(dateObj, event);\n    }),\n    disabled: !dateObj.selectable,\n    'aria-label': dateObj.date.toDateString(),\n    'aria-pressed': dateObj.selected,\n    role: 'button'\n  }, rest);\n}\n\nfunction getBackProps(_ref2, _temp2) {\n  var minDate = _ref2.minDate,\n      offsetMonth = _ref2.offsetMonth,\n      handleOffsetChanged = _ref2.handleOffsetChanged;\n\n  var _ref3 = _temp2 === void 0 ? {} : _temp2,\n      onClick = _ref3.onClick,\n      _ref3$offset = _ref3.offset,\n      offset = _ref3$offset === void 0 ? 1 : _ref3$offset,\n      _ref3$calendars = _ref3.calendars,\n      calendars = _ref3$calendars === void 0 ? requiredProp('getBackProps', 'calendars') : _ref3$calendars,\n      rest = _objectWithoutPropertiesLoose(_ref3, [\"onClick\", \"offset\", \"calendars\"]);\n\n  return _extends({\n    onClick: composeEventHandlers(onClick, function () {\n      handleOffsetChanged(offsetMonth - subtractMonth({\n        calendars: calendars,\n        offset: offset,\n        minDate: minDate\n      }));\n    }),\n    disabled: isBackDisabled({\n      calendars: calendars,\n      offset: offset,\n      minDate: minDate\n    }),\n    'aria-label': \"Go back \" + offset + \" month\" + (offset === 1 ? '' : 's')\n  }, rest);\n}\n\nfunction getForwardProps(_ref4, _temp3) {\n  var maxDate = _ref4.maxDate,\n      offsetMonth = _ref4.offsetMonth,\n      handleOffsetChanged = _ref4.handleOffsetChanged;\n\n  var _ref5 = _temp3 === void 0 ? {} : _temp3,\n      onClick = _ref5.onClick,\n      _ref5$offset = _ref5.offset,\n      offset = _ref5$offset === void 0 ? 1 : _ref5$offset,\n      _ref5$calendars = _ref5.calendars,\n      calendars = _ref5$calendars === void 0 ? requiredProp('getForwardProps', 'calendars') : _ref5$calendars,\n      rest = _objectWithoutPropertiesLoose(_ref5, [\"onClick\", \"offset\", \"calendars\"]);\n\n  return _extends({\n    onClick: composeEventHandlers(onClick, function () {\n      handleOffsetChanged(offsetMonth + addMonth({\n        calendars: calendars,\n        offset: offset,\n        maxDate: maxDate\n      }));\n    }),\n    disabled: isForwardDisabled({\n      calendars: calendars,\n      offset: offset,\n      maxDate: maxDate\n    }),\n    'aria-label': \"Go forward \" + offset + \" month\" + (offset === 1 ? '' : 's')\n  }, rest);\n}\n\nfunction useDayzed(_ref6) {\n  var _ref6$date = _ref6.date,\n      date = _ref6$date === void 0 ? new Date() : _ref6$date,\n      maxDate = _ref6.maxDate,\n      minDate = _ref6.minDate,\n      _ref6$monthsToDisplay = _ref6.monthsToDisplay,\n      monthsToDisplay = _ref6$monthsToDisplay === void 0 ? 1 : _ref6$monthsToDisplay,\n      _ref6$firstDayOfWeek = _ref6.firstDayOfWeek,\n      firstDayOfWeek = _ref6$firstDayOfWeek === void 0 ? 0 : _ref6$firstDayOfWeek,\n      _ref6$showOutsideDays = _ref6.showOutsideDays,\n      showOutsideDays = _ref6$showOutsideDays === void 0 ? false : _ref6$showOutsideDays,\n      offset = _ref6.offset,\n      onDateSelected = _ref6.onDateSelected,\n      _ref6$onOffsetChanged = _ref6.onOffsetChanged,\n      onOffsetChanged = _ref6$onOffsetChanged === void 0 ? function () {} : _ref6$onOffsetChanged,\n      selected = _ref6.selected;\n\n  var _useState = useState(0),\n      stateOffset = _useState[0],\n      setStateOffset = _useState[1];\n\n  var offsetMonth = getOffset(offset, stateOffset);\n\n  function handleOffsetChanged(newOffset) {\n    if (!isOffsetControlled(offset)) {\n      setStateOffset(newOffset);\n    }\n\n    onOffsetChanged(newOffset);\n  }\n\n  var calendars = getCalendars({\n    date: date,\n    selected: selected,\n    monthsToDisplay: monthsToDisplay,\n    minDate: minDate,\n    maxDate: maxDate,\n    offset: offsetMonth,\n    firstDayOfWeek: firstDayOfWeek,\n    showOutsideDays: showOutsideDays\n  });\n  return {\n    calendars: calendars,\n    getDateProps: getDateProps.bind(null, onDateSelected),\n    getBackProps: getBackProps.bind(null, {\n      minDate: minDate,\n      offsetMonth: offsetMonth,\n      handleOffsetChanged: handleOffsetChanged\n    }),\n    getForwardProps: getForwardProps.bind(null, {\n      maxDate: maxDate,\n      offsetMonth: offsetMonth,\n      handleOffsetChanged: handleOffsetChanged\n    })\n  };\n}\n\nfunction Dayzed(props) {\n  var dayzedCalendar = useDayzed(props);\n  var children = unwrapChildrenForPreact(props.render || props.children);\n  return children(dayzedCalendar);\n}\n\nDayzed.defaultProps = {\n  date: new Date(),\n  monthsToDisplay: 1,\n  onOffsetChanged: function onOffsetChanged() {},\n  firstDayOfWeek: 0,\n  showOutsideDays: false\n};\nDayzed.propTypes = {\n  render: PropTypes.func,\n  children: PropTypes.func,\n  date: PropTypes.instanceOf(Date),\n  maxDate: PropTypes.instanceOf(Date),\n  minDate: PropTypes.instanceOf(Date),\n  monthsToDisplay: PropTypes.number,\n  firstDayOfWeek: PropTypes.number,\n  showOutsideDays: PropTypes.bool,\n  offset: PropTypes.number,\n  onDateSelected: PropTypes.func.isRequired,\n  onOffsetChanged: PropTypes.func,\n  selected: PropTypes.oneOfType([PropTypes.arrayOf(Date), PropTypes.instanceOf(Date)])\n};\n\nexport default Dayzed;\nexport { useDayzed };\n","var objectKeys = require('object-keys');\nvar isArguments = require('is-arguments');\nvar is = require('object-is');\nvar isRegex = require('is-regex');\nvar flags = require('regexp.prototype.flags');\nvar isDate = require('is-date-object');\n\nvar getTime = Date.prototype.getTime;\n\nfunction deepEqual(actual, expected, options) {\n  var opts = options || {};\n\n  // 7.1. All identical values are equivalent, as determined by ===.\n  if (opts.strict ? is(actual, expected) : actual === expected) {\n    return true;\n  }\n\n  // 7.3. Other pairs that do not both pass typeof value == 'object', equivalence is determined by ==.\n  if (!actual || !expected || (typeof actual !== 'object' && typeof expected !== 'object')) {\n    return opts.strict ? is(actual, expected) : actual == expected;\n  }\n\n  /*\n   * 7.4. For all other Object pairs, including Array objects, equivalence is\n   * determined by having the same number of owned properties (as verified\n   * with Object.prototype.hasOwnProperty.call), the same set of keys\n   * (although not necessarily the same order), equivalent values for every\n   * corresponding key, and an identical 'prototype' property. Note: this\n   * accounts for both named and indexed properties on Arrays.\n   */\n  // eslint-disable-next-line no-use-before-define\n  return objEquiv(actual, expected, opts);\n}\n\nfunction isUndefinedOrNull(value) {\n  return value === null || value === undefined;\n}\n\nfunction isBuffer(x) {\n  if (!x || typeof x !== 'object' || typeof x.length !== 'number') {\n    return false;\n  }\n  if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {\n    return false;\n  }\n  if (x.length > 0 && typeof x[0] !== 'number') {\n    return false;\n  }\n  return true;\n}\n\nfunction objEquiv(a, b, opts) {\n  /* eslint max-statements: [2, 50] */\n  var i, key;\n  if (typeof a !== typeof b) { return false; }\n  if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) { return false; }\n\n  // an identical 'prototype' property.\n  if (a.prototype !== b.prototype) { return false; }\n\n  if (isArguments(a) !== isArguments(b)) { return false; }\n\n  var aIsRegex = isRegex(a);\n  var bIsRegex = isRegex(b);\n  if (aIsRegex !== bIsRegex) { return false; }\n  if (aIsRegex || bIsRegex) {\n    return a.source === b.source && flags(a) === flags(b);\n  }\n\n  if (isDate(a) && isDate(b)) {\n    return getTime.call(a) === getTime.call(b);\n  }\n\n  var aIsBuffer = isBuffer(a);\n  var bIsBuffer = isBuffer(b);\n  if (aIsBuffer !== bIsBuffer) { return false; }\n  if (aIsBuffer || bIsBuffer) { // && would work too, because both are true or both false here\n    if (a.length !== b.length) { return false; }\n    for (i = 0; i < a.length; i++) {\n      if (a[i] !== b[i]) { return false; }\n    }\n    return true;\n  }\n\n  if (typeof a !== typeof b) { return false; }\n\n  try {\n    var ka = objectKeys(a);\n    var kb = objectKeys(b);\n  } catch (e) { // happens when one is a string literal and the other isn't\n    return false;\n  }\n  // having the same number of owned properties (keys incorporates hasOwnProperty)\n  if (ka.length !== kb.length) { return false; }\n\n  // the same set of keys (although not necessarily the same order),\n  ka.sort();\n  kb.sort();\n  // ~~~cheap key test\n  for (i = ka.length - 1; i >= 0; i--) {\n    if (ka[i] != kb[i]) { return false; }\n  }\n  // equivalent values for every corresponding key, and ~~~possibly expensive deep test\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], opts)) { return false; }\n  }\n\n  return true;\n}\n\nmodule.exports = deepEqual;\n","'use strict';\n\nvar keys = require('object-keys');\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n","'use strict';\n\n/* globals\n\tAtomics,\n\tSharedArrayBuffer,\n*/\n\nvar undefined;\n\nvar $TypeError = TypeError;\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () { throw new $TypeError(); };\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = require('has-symbols')();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar generator; // = function * () {};\nvar generatorFunction = generator ? getProto(generator) : undefined;\nvar asyncFn; // async function() {};\nvar asyncFunction = asyncFn ? asyncFn.constructor : undefined;\nvar asyncGen; // async function * () {};\nvar asyncGenFunction = asyncGen ? getProto(asyncGen) : undefined;\nvar asyncGenIterator = asyncGen ? asyncGen() : undefined;\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayBufferPrototype%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer.prototype,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%ArrayPrototype%': Array.prototype,\n\t'%ArrayProto_entries%': Array.prototype.entries,\n\t'%ArrayProto_forEach%': Array.prototype.forEach,\n\t'%ArrayProto_keys%': Array.prototype.keys,\n\t'%ArrayProto_values%': Array.prototype.values,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': asyncFunction,\n\t'%AsyncFunctionPrototype%': asyncFunction ? asyncFunction.prototype : undefined,\n\t'%AsyncGenerator%': asyncGen ? getProto(asyncGenIterator) : undefined,\n\t'%AsyncGeneratorFunction%': asyncGenFunction,\n\t'%AsyncGeneratorPrototype%': asyncGenFunction ? asyncGenFunction.prototype : undefined,\n\t'%AsyncIteratorPrototype%': asyncGenIterator && hasSymbols && Symbol.asyncIterator ? asyncGenIterator[Symbol.asyncIterator]() : undefined,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%Boolean%': Boolean,\n\t'%BooleanPrototype%': Boolean.prototype,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%DataViewPrototype%': typeof DataView === 'undefined' ? undefined : DataView.prototype,\n\t'%Date%': Date,\n\t'%DatePrototype%': Date.prototype,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%ErrorPrototype%': Error.prototype,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%EvalErrorPrototype%': EvalError.prototype,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float32ArrayPrototype%': typeof Float32Array === 'undefined' ? undefined : Float32Array.prototype,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%Float64ArrayPrototype%': typeof Float64Array === 'undefined' ? undefined : Float64Array.prototype,\n\t'%Function%': Function,\n\t'%FunctionPrototype%': Function.prototype,\n\t'%Generator%': generator ? getProto(generator()) : undefined,\n\t'%GeneratorFunction%': generatorFunction,\n\t'%GeneratorPrototype%': generatorFunction ? generatorFunction.prototype : undefined,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int8ArrayPrototype%': typeof Int8Array === 'undefined' ? undefined : Int8Array.prototype,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int16ArrayPrototype%': typeof Int16Array === 'undefined' ? undefined : Int8Array.prototype,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%Int32ArrayPrototype%': typeof Int32Array === 'undefined' ? undefined : Int32Array.prototype,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%JSONParse%': typeof JSON === 'object' ? JSON.parse : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%MapPrototype%': typeof Map === 'undefined' ? undefined : Map.prototype,\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%NumberPrototype%': Number.prototype,\n\t'%Object%': Object,\n\t'%ObjectPrototype%': Object.prototype,\n\t'%ObjProto_toString%': Object.prototype.toString,\n\t'%ObjProto_valueOf%': Object.prototype.valueOf,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%PromisePrototype%': typeof Promise === 'undefined' ? undefined : Promise.prototype,\n\t'%PromiseProto_then%': typeof Promise === 'undefined' ? undefined : Promise.prototype.then,\n\t'%Promise_all%': typeof Promise === 'undefined' ? undefined : Promise.all,\n\t'%Promise_reject%': typeof Promise === 'undefined' ? undefined : Promise.reject,\n\t'%Promise_resolve%': typeof Promise === 'undefined' ? undefined : Promise.resolve,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%RangeErrorPrototype%': RangeError.prototype,\n\t'%ReferenceError%': ReferenceError,\n\t'%ReferenceErrorPrototype%': ReferenceError.prototype,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%RegExpPrototype%': RegExp.prototype,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SetPrototype%': typeof Set === 'undefined' ? undefined : Set.prototype,\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%SharedArrayBufferPrototype%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer.prototype,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%StringPrototype%': String.prototype,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SymbolPrototype%': hasSymbols ? Symbol.prototype : undefined,\n\t'%SyntaxError%': SyntaxError,\n\t'%SyntaxErrorPrototype%': SyntaxError.prototype,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypedArrayPrototype%': TypedArray ? TypedArray.prototype : undefined,\n\t'%TypeError%': $TypeError,\n\t'%TypeErrorPrototype%': $TypeError.prototype,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ArrayPrototype%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array.prototype,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint8ClampedArrayPrototype%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray.prototype,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint16ArrayPrototype%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array.prototype,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%Uint32ArrayPrototype%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array.prototype,\n\t'%URIError%': URIError,\n\t'%URIErrorPrototype%': URIError.prototype,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakMapPrototype%': typeof WeakMap === 'undefined' ? undefined : WeakMap.prototype,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,\n\t'%WeakSetPrototype%': typeof WeakSet === 'undefined' ? undefined : WeakSet.prototype\n};\n\nvar bind = require('function-bind');\nvar $replace = bind.call(Function.call, String.prototype.replace);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : (number || match);\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tif (!(name in INTRINSICS)) {\n\t\tthrow new SyntaxError('intrinsic ' + name + ' does not exist!');\n\t}\n\n\t// istanbul ignore if // hopefully this is impossible to test :-)\n\tif (typeof INTRINSICS[name] === 'undefined' && !allowMissing) {\n\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t}\n\n\treturn INTRINSICS[name];\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\n\tvar value = getBaseIntrinsic('%' + (parts.length > 0 ? parts[0] : '') + '%', allowMissing);\n\tfor (var i = 1; i < parts.length; i += 1) {\n\t\tif (value != null) {\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, parts[i]);\n\t\t\t\tif (!allowMissing && !(parts[i] in value)) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\tvalue = desc ? (desc.get || desc.value) : value[parts[i]];\n\t\t\t} else {\n\t\t\t\tvalue = value[parts[i]];\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n","'use strict';\n\nvar bind = require('function-bind');\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nmodule.exports = function callBind() {\n\treturn $reflectApply(bind, $call, arguments);\n};\n\nmodule.exports.apply = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n","/*!\n  Copyright (c) 2015 Jed Watson.\n  Based on code that is Copyright 2013-2015, Facebook, Inc.\n  All rights reserved.\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar canUseDOM = !!(\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.document &&\n\t\twindow.document.createElement\n\t);\n\n\tvar ExecutionEnvironment = {\n\n\t\tcanUseDOM: canUseDOM,\n\n\t\tcanUseWorkers: typeof Worker !== 'undefined',\n\n\t\tcanUseEventListeners:\n\t\t\tcanUseDOM && !!(window.addEventListener || window.attachEvent),\n\n\t\tcanUseViewport: canUseDOM && !!window.screen\n\n\t};\n\n\tif (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\tdefine(function () {\n\t\t\treturn ExecutionEnvironment;\n\t\t});\n\t} else if (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = ExecutionEnvironment;\n\t} else {\n\t\twindow.ExecutionEnvironment = ExecutionEnvironment;\n\t}\n\n}());\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 from '@firebase/app';\nimport { name, version } from '../package.json';\n\nfirebase.registerVersion(name, version, 'app');\n\nexport default firebase;\n","'use strict';\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n    var target = this;\n    if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n        throw new TypeError(ERROR_MESSAGE + target);\n    }\n    var args = slice.call(arguments, 1);\n\n    var bound;\n    var binder = function () {\n        if (this instanceof bound) {\n            var result = target.apply(\n                this,\n                args.concat(slice.call(arguments))\n            );\n            if (Object(result) === result) {\n                return result;\n            }\n            return this;\n        } else {\n            return target.apply(\n                that,\n                args.concat(slice.call(arguments))\n            );\n        }\n    };\n\n    var boundLength = Math.max(0, target.length - args.length);\n    var boundArgs = [];\n    for (var i = 0; i < boundLength; i++) {\n        boundArgs.push('$' + i);\n    }\n\n    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n    if (target.prototype) {\n        var Empty = function Empty() {};\n        Empty.prototype = target.prototype;\n        bound.prototype = new Empty();\n        Empty.prototype = null;\n    }\n\n    return bound;\n};\n","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = Function.prototype.bind || implementation;\n","// @flow\n'use strict';\n\nvar key = '__global_unique_id__';\n\nmodule.exports = function() {\n  return global[key] = (global[key] || 0) + 1;\n};\n","'use strict';\n\nvar origSymbol = global.Symbol;\nvar hasSymbolSham = require('./shams');\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n","'use strict';\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n","import _extends from '@babel/runtime/helpers/esm/extends';\nimport resolvePathname from 'resolve-pathname';\nimport valueEqual from 'value-equal';\nimport warning from 'tiny-warning';\nimport invariant from 'tiny-invariant';\n\nfunction addLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path : '/' + path;\n}\nfunction stripLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path.substr(1) : path;\n}\nfunction hasBasename(path, prefix) {\n  return path.toLowerCase().indexOf(prefix.toLowerCase()) === 0 && '/?#'.indexOf(path.charAt(prefix.length)) !== -1;\n}\nfunction stripBasename(path, prefix) {\n  return hasBasename(path, prefix) ? path.substr(prefix.length) : path;\n}\nfunction stripTrailingSlash(path) {\n  return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path;\n}\nfunction parsePath(path) {\n  var pathname = path || '/';\n  var search = '';\n  var hash = '';\n  var hashIndex = pathname.indexOf('#');\n\n  if (hashIndex !== -1) {\n    hash = pathname.substr(hashIndex);\n    pathname = pathname.substr(0, hashIndex);\n  }\n\n  var searchIndex = pathname.indexOf('?');\n\n  if (searchIndex !== -1) {\n    search = pathname.substr(searchIndex);\n    pathname = pathname.substr(0, searchIndex);\n  }\n\n  return {\n    pathname: pathname,\n    search: search === '?' ? '' : search,\n    hash: hash === '#' ? '' : hash\n  };\n}\nfunction createPath(location) {\n  var pathname = location.pathname,\n      search = location.search,\n      hash = location.hash;\n  var path = pathname || '/';\n  if (search && search !== '?') path += search.charAt(0) === '?' ? search : \"?\" + search;\n  if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : \"#\" + hash;\n  return path;\n}\n\nfunction createLocation(path, state, key, currentLocation) {\n  var location;\n\n  if (typeof path === 'string') {\n    // Two-arg form: push(path, state)\n    location = parsePath(path);\n    location.state = state;\n  } else {\n    // One-arg form: push(location)\n    location = _extends({}, path);\n    if (location.pathname === undefined) location.pathname = '';\n\n    if (location.search) {\n      if (location.search.charAt(0) !== '?') location.search = '?' + location.search;\n    } else {\n      location.search = '';\n    }\n\n    if (location.hash) {\n      if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash;\n    } else {\n      location.hash = '';\n    }\n\n    if (state !== undefined && location.state === undefined) location.state = state;\n  }\n\n  try {\n    location.pathname = decodeURI(location.pathname);\n  } catch (e) {\n    if (e instanceof URIError) {\n      throw new URIError('Pathname \"' + location.pathname + '\" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.');\n    } else {\n      throw e;\n    }\n  }\n\n  if (key) location.key = key;\n\n  if (currentLocation) {\n    // Resolve incomplete/relative pathname relative to current location.\n    if (!location.pathname) {\n      location.pathname = currentLocation.pathname;\n    } else if (location.pathname.charAt(0) !== '/') {\n      location.pathname = resolvePathname(location.pathname, currentLocation.pathname);\n    }\n  } else {\n    // When there is no prior location and pathname is empty, set it to /\n    if (!location.pathname) {\n      location.pathname = '/';\n    }\n  }\n\n  return location;\n}\nfunction locationsAreEqual(a, b) {\n  return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && valueEqual(a.state, b.state);\n}\n\nfunction createTransitionManager() {\n  var prompt = null;\n\n  function setPrompt(nextPrompt) {\n    process.env.NODE_ENV !== \"production\" ? warning(prompt == null, 'A history supports only one prompt at a time') : void 0;\n    prompt = nextPrompt;\n    return function () {\n      if (prompt === nextPrompt) prompt = null;\n    };\n  }\n\n  function confirmTransitionTo(location, action, getUserConfirmation, callback) {\n    // TODO: If another transition starts while we're still confirming\n    // the previous one, we may end up in a weird state. Figure out the\n    // best way to handle this.\n    if (prompt != null) {\n      var result = typeof prompt === 'function' ? prompt(location, action) : prompt;\n\n      if (typeof result === 'string') {\n        if (typeof getUserConfirmation === 'function') {\n          getUserConfirmation(result, callback);\n        } else {\n          process.env.NODE_ENV !== \"production\" ? warning(false, 'A history needs a getUserConfirmation function in order to use a prompt message') : void 0;\n          callback(true);\n        }\n      } else {\n        // Return false from a transition hook to cancel the transition.\n        callback(result !== false);\n      }\n    } else {\n      callback(true);\n    }\n  }\n\n  var listeners = [];\n\n  function appendListener(fn) {\n    var isActive = true;\n\n    function listener() {\n      if (isActive) fn.apply(void 0, arguments);\n    }\n\n    listeners.push(listener);\n    return function () {\n      isActive = false;\n      listeners = listeners.filter(function (item) {\n        return item !== listener;\n      });\n    };\n  }\n\n  function notifyListeners() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    listeners.forEach(function (listener) {\n      return listener.apply(void 0, args);\n    });\n  }\n\n  return {\n    setPrompt: setPrompt,\n    confirmTransitionTo: confirmTransitionTo,\n    appendListener: appendListener,\n    notifyListeners: notifyListeners\n  };\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\nfunction getConfirmation(message, callback) {\n  callback(window.confirm(message)); // eslint-disable-line no-alert\n}\n/**\n * Returns true if the HTML5 history API is supported. Taken from Modernizr.\n *\n * https://github.com/Modernizr/Modernizr/blob/master/LICENSE\n * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js\n * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586\n */\n\nfunction supportsHistory() {\n  var ua = window.navigator.userAgent;\n  if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false;\n  return window.history && 'pushState' in window.history;\n}\n/**\n * Returns true if browser fires popstate on hash change.\n * IE10 and IE11 do not.\n */\n\nfunction supportsPopStateOnHashChange() {\n  return window.navigator.userAgent.indexOf('Trident') === -1;\n}\n/**\n * Returns false if using go(n) with hash history causes a full page reload.\n */\n\nfunction supportsGoWithoutReloadUsingHash() {\n  return window.navigator.userAgent.indexOf('Firefox') === -1;\n}\n/**\n * Returns true if a given popstate event is an extraneous WebKit event.\n * Accounts for the fact that Chrome on iOS fires real popstate events\n * containing undefined state when pressing the back button.\n */\n\nfunction isExtraneousPopstateEvent(event) {\n  return event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1;\n}\n\nvar PopStateEvent = 'popstate';\nvar HashChangeEvent = 'hashchange';\n\nfunction getHistoryState() {\n  try {\n    return window.history.state || {};\n  } catch (e) {\n    // IE 11 sometimes throws when accessing window.history.state\n    // See https://github.com/ReactTraining/history/pull/289\n    return {};\n  }\n}\n/**\n * Creates a history object that uses the HTML5 history API including\n * pushState, replaceState, and the popstate event.\n */\n\n\nfunction createBrowserHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ? process.env.NODE_ENV !== \"production\" ? invariant(false, 'Browser history needs a DOM') : invariant(false) : void 0;\n  var globalHistory = window.history;\n  var canUseHistory = supportsHistory();\n  var needsHashChangeListener = !supportsPopStateOnHashChange();\n  var _props = props,\n      _props$forceRefresh = _props.forceRefresh,\n      forceRefresh = _props$forceRefresh === void 0 ? false : _props$forceRefresh,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n\n  function getDOMLocation(historyState) {\n    var _ref = historyState || {},\n        key = _ref.key,\n        state = _ref.state;\n\n    var _window$location = window.location,\n        pathname = _window$location.pathname,\n        search = _window$location.search,\n        hash = _window$location.hash;\n    var path = pathname + search + hash;\n    process.env.NODE_ENV !== \"production\" ? warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path \"' + path + '\" to begin with \"' + basename + '\".') : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path, state, key);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    _extends(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function handlePopState(event) {\n    // Ignore extraneous popstate events in WebKit.\n    if (isExtraneousPopstateEvent(event)) return;\n    handlePop(getDOMLocation(event.state));\n  }\n\n  function handleHashChange() {\n    handlePop(getDOMLocation(getHistoryState()));\n  }\n\n  var forceNextPop = false;\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of keys we've seen in sessionStorage.\n    // Instead, we just default to 0 for keys we don't know.\n\n    var toIndex = allKeys.indexOf(toLocation.key);\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allKeys.indexOf(fromLocation.key);\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  }\n\n  var initialLocation = getDOMLocation(getHistoryState());\n  var allKeys = [initialLocation.key]; // Public interface\n\n  function createHref(location) {\n    return basename + createPath(location);\n  }\n\n  function push(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored') : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.pushState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.href = href;\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          var nextKeys = allKeys.slice(0, prevIndex + 1);\n          nextKeys.push(location.key);\n          allKeys = nextKeys;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n        process.env.NODE_ENV !== \"production\" ? warning(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history') : void 0;\n        window.location.href = href;\n      }\n    });\n  }\n\n  function replace(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored') : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.replaceState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.replace(href);\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          if (prevIndex !== -1) allKeys[prevIndex] = location.key;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n        process.env.NODE_ENV !== \"production\" ? warning(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history') : void 0;\n        window.location.replace(href);\n      }\n    });\n  }\n\n  function go(n) {\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.addEventListener(HashChangeEvent, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.removeEventListener(HashChangeEvent, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nvar HashChangeEvent$1 = 'hashchange';\nvar HashPathCoders = {\n  hashbang: {\n    encodePath: function encodePath(path) {\n      return path.charAt(0) === '!' ? path : '!/' + stripLeadingSlash(path);\n    },\n    decodePath: function decodePath(path) {\n      return path.charAt(0) === '!' ? path.substr(1) : path;\n    }\n  },\n  noslash: {\n    encodePath: stripLeadingSlash,\n    decodePath: addLeadingSlash\n  },\n  slash: {\n    encodePath: addLeadingSlash,\n    decodePath: addLeadingSlash\n  }\n};\n\nfunction stripHash(url) {\n  var hashIndex = url.indexOf('#');\n  return hashIndex === -1 ? url : url.slice(0, hashIndex);\n}\n\nfunction getHashPath() {\n  // We can't use window.location.hash here because it's not\n  // consistent across browsers - Firefox will pre-decode it!\n  var href = window.location.href;\n  var hashIndex = href.indexOf('#');\n  return hashIndex === -1 ? '' : href.substring(hashIndex + 1);\n}\n\nfunction pushHashPath(path) {\n  window.location.hash = path;\n}\n\nfunction replaceHashPath(path) {\n  window.location.replace(stripHash(window.location.href) + '#' + path);\n}\n\nfunction createHashHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ? process.env.NODE_ENV !== \"production\" ? invariant(false, 'Hash history needs a DOM') : invariant(false) : void 0;\n  var globalHistory = window.history;\n  var canGoWithoutReload = supportsGoWithoutReloadUsingHash();\n  var _props = props,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$hashType = _props.hashType,\n      hashType = _props$hashType === void 0 ? 'slash' : _props$hashType;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n  var _HashPathCoders$hashT = HashPathCoders[hashType],\n      encodePath = _HashPathCoders$hashT.encodePath,\n      decodePath = _HashPathCoders$hashT.decodePath;\n\n  function getDOMLocation() {\n    var path = decodePath(getHashPath());\n    process.env.NODE_ENV !== \"production\" ? warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path \"' + path + '\" to begin with \"' + basename + '\".') : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    _extends(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  var forceNextPop = false;\n  var ignorePath = null;\n\n  function locationsAreEqual$$1(a, b) {\n    return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash;\n  }\n\n  function handleHashChange() {\n    var path = getHashPath();\n    var encodedPath = encodePath(path);\n\n    if (path !== encodedPath) {\n      // Ensure we always have a properly-encoded hash.\n      replaceHashPath(encodedPath);\n    } else {\n      var location = getDOMLocation();\n      var prevLocation = history.location;\n      if (!forceNextPop && locationsAreEqual$$1(prevLocation, location)) return; // A hashchange doesn't always == location change.\n\n      if (ignorePath === createPath(location)) return; // Ignore this change; we already setState in push/replace.\n\n      ignorePath = null;\n      handlePop(location);\n    }\n  }\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of paths we've seen in sessionStorage.\n    // Instead, we just default to 0 for paths we don't know.\n\n    var toIndex = allPaths.lastIndexOf(createPath(toLocation));\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allPaths.lastIndexOf(createPath(fromLocation));\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  } // Ensure the hash is encoded properly before doing anything else.\n\n\n  var path = getHashPath();\n  var encodedPath = encodePath(path);\n  if (path !== encodedPath) replaceHashPath(encodedPath);\n  var initialLocation = getDOMLocation();\n  var allPaths = [createPath(initialLocation)]; // Public interface\n\n  function createHref(location) {\n    var baseTag = document.querySelector('base');\n    var href = '';\n\n    if (baseTag && baseTag.getAttribute('href')) {\n      href = stripHash(window.location.href);\n    }\n\n    return href + '#' + encodePath(basename + createPath(location));\n  }\n\n  function push(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(state === undefined, 'Hash history cannot push state; it is ignored') : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a PUSH, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        pushHashPath(encodedPath);\n        var prevIndex = allPaths.lastIndexOf(createPath(history.location));\n        var nextPaths = allPaths.slice(0, prevIndex + 1);\n        nextPaths.push(path);\n        allPaths = nextPaths;\n        setState({\n          action: action,\n          location: location\n        });\n      } else {\n        process.env.NODE_ENV !== \"production\" ? warning(false, 'Hash history cannot PUSH the same path; a new entry will not be added to the history stack') : void 0;\n        setState();\n      }\n    });\n  }\n\n  function replace(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(state === undefined, 'Hash history cannot replace state; it is ignored') : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a REPLACE, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        replaceHashPath(encodedPath);\n      }\n\n      var prevIndex = allPaths.indexOf(createPath(history.location));\n      if (prevIndex !== -1) allPaths[prevIndex] = path;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n    process.env.NODE_ENV !== \"production\" ? warning(canGoWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : void 0;\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(HashChangeEvent$1, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(HashChangeEvent$1, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nfunction clamp(n, lowerBound, upperBound) {\n  return Math.min(Math.max(n, lowerBound), upperBound);\n}\n/**\n * Creates a history object that stores locations in memory.\n */\n\n\nfunction createMemoryHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  var _props = props,\n      getUserConfirmation = _props.getUserConfirmation,\n      _props$initialEntries = _props.initialEntries,\n      initialEntries = _props$initialEntries === void 0 ? ['/'] : _props$initialEntries,\n      _props$initialIndex = _props.initialIndex,\n      initialIndex = _props$initialIndex === void 0 ? 0 : _props$initialIndex,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    _extends(history, nextState);\n\n    history.length = history.entries.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var index = clamp(initialIndex, 0, initialEntries.length - 1);\n  var entries = initialEntries.map(function (entry) {\n    return typeof entry === 'string' ? createLocation(entry, undefined, createKey()) : createLocation(entry, undefined, entry.key || createKey());\n  }); // Public interface\n\n  var createHref = createPath;\n\n  function push(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored') : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var prevIndex = history.index;\n      var nextIndex = prevIndex + 1;\n      var nextEntries = history.entries.slice(0);\n\n      if (nextEntries.length > nextIndex) {\n        nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location);\n      } else {\n        nextEntries.push(location);\n      }\n\n      setState({\n        action: action,\n        location: location,\n        index: nextIndex,\n        entries: nextEntries\n      });\n    });\n  }\n\n  function replace(path, state) {\n    process.env.NODE_ENV !== \"production\" ? warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored') : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      history.entries[history.index] = location;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n    var nextIndex = clamp(history.index + n, 0, history.entries.length - 1);\n    var action = 'POP';\n    var location = history.entries[nextIndex];\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (ok) {\n        setState({\n          action: action,\n          location: location,\n          index: nextIndex\n        });\n      } else {\n        // Mimic the behavior of DOM histories by\n        // causing a render after a cancelled POP.\n        setState();\n      }\n    });\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  function canGo(n) {\n    var nextIndex = history.index + n;\n    return nextIndex >= 0 && nextIndex < history.entries.length;\n  }\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    return transitionManager.setPrompt(prompt);\n  }\n\n  function listen(listener) {\n    return transitionManager.appendListener(listener);\n  }\n\n  var history = {\n    length: entries.length,\n    action: 'POP',\n    location: entries[index],\n    index: index,\n    entries: entries,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    canGo: canGo,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nexport { createBrowserHistory, createHashHistory, createMemoryHistory, createLocation, locationsAreEqual, parsePath, createPath };\n","'use strict';\n\nvar reactIs = require('react-is');\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar REACT_STATICS = {\n  childContextTypes: true,\n  contextType: true,\n  contextTypes: true,\n  defaultProps: true,\n  displayName: true,\n  getDefaultProps: true,\n  getDerivedStateFromError: true,\n  getDerivedStateFromProps: true,\n  mixins: true,\n  propTypes: true,\n  type: true\n};\nvar KNOWN_STATICS = {\n  name: true,\n  length: true,\n  prototype: true,\n  caller: true,\n  callee: true,\n  arguments: true,\n  arity: true\n};\nvar FORWARD_REF_STATICS = {\n  '$$typeof': true,\n  render: true,\n  defaultProps: true,\n  displayName: true,\n  propTypes: true\n};\nvar MEMO_STATICS = {\n  '$$typeof': true,\n  compare: true,\n  defaultProps: true,\n  displayName: true,\n  propTypes: true,\n  type: true\n};\nvar TYPE_STATICS = {};\nTYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;\nTYPE_STATICS[reactIs.Memo] = MEMO_STATICS;\n\nfunction getStatics(component) {\n  // React v16.11 and below\n  if (reactIs.isMemo(component)) {\n    return MEMO_STATICS;\n  } // React v16.12 and above\n\n\n  return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n  if (typeof sourceComponent !== 'string') {\n    // don't hoist over string (html) components\n    if (objectPrototype) {\n      var inheritedComponent = getPrototypeOf(sourceComponent);\n\n      if (inheritedComponent && inheritedComponent !== objectPrototype) {\n        hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n      }\n    }\n\n    var keys = getOwnPropertyNames(sourceComponent);\n\n    if (getOwnPropertySymbols) {\n      keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n    }\n\n    var targetStatics = getStatics(targetComponent);\n    var sourceStatics = getStatics(sourceComponent);\n\n    for (var i = 0; i < keys.length; ++i) {\n      var key = keys[i];\n\n      if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n        var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n        try {\n          // Avoid failures from read-only properties\n          defineProperty(targetComponent, key, descriptor);\n        } catch (e) {}\n      }\n    }\n  }\n\n  return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n","(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = global || self, factory(global.idb = {}));\n}(this, function (exports) { 'use strict';\n\n  function toArray(arr) {\n    return Array.prototype.slice.call(arr);\n  }\n\n  function promisifyRequest(request) {\n    return new Promise(function(resolve, reject) {\n      request.onsuccess = function() {\n        resolve(request.result);\n      };\n\n      request.onerror = function() {\n        reject(request.error);\n      };\n    });\n  }\n\n  function promisifyRequestCall(obj, method, args) {\n    var request;\n    var p = new Promise(function(resolve, reject) {\n      request = obj[method].apply(obj, args);\n      promisifyRequest(request).then(resolve, reject);\n    });\n\n    p.request = request;\n    return p;\n  }\n\n  function promisifyCursorRequestCall(obj, method, args) {\n    var p = promisifyRequestCall(obj, method, args);\n    return p.then(function(value) {\n      if (!value) return;\n      return new Cursor(value, p.request);\n    });\n  }\n\n  function proxyProperties(ProxyClass, targetProp, properties) {\n    properties.forEach(function(prop) {\n      Object.defineProperty(ProxyClass.prototype, prop, {\n        get: function() {\n          return this[targetProp][prop];\n        },\n        set: function(val) {\n          this[targetProp][prop] = val;\n        }\n      });\n    });\n  }\n\n  function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n    properties.forEach(function(prop) {\n      if (!(prop in Constructor.prototype)) return;\n      ProxyClass.prototype[prop] = function() {\n        return promisifyRequestCall(this[targetProp], prop, arguments);\n      };\n    });\n  }\n\n  function proxyMethods(ProxyClass, targetProp, Constructor, properties) {\n    properties.forEach(function(prop) {\n      if (!(prop in Constructor.prototype)) return;\n      ProxyClass.prototype[prop] = function() {\n        return this[targetProp][prop].apply(this[targetProp], arguments);\n      };\n    });\n  }\n\n  function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n    properties.forEach(function(prop) {\n      if (!(prop in Constructor.prototype)) return;\n      ProxyClass.prototype[prop] = function() {\n        return promisifyCursorRequestCall(this[targetProp], prop, arguments);\n      };\n    });\n  }\n\n  function Index(index) {\n    this._index = index;\n  }\n\n  proxyProperties(Index, '_index', [\n    'name',\n    'keyPath',\n    'multiEntry',\n    'unique'\n  ]);\n\n  proxyRequestMethods(Index, '_index', IDBIndex, [\n    'get',\n    'getKey',\n    'getAll',\n    'getAllKeys',\n    'count'\n  ]);\n\n  proxyCursorRequestMethods(Index, '_index', IDBIndex, [\n    'openCursor',\n    'openKeyCursor'\n  ]);\n\n  function Cursor(cursor, request) {\n    this._cursor = cursor;\n    this._request = request;\n  }\n\n  proxyProperties(Cursor, '_cursor', [\n    'direction',\n    'key',\n    'primaryKey',\n    'value'\n  ]);\n\n  proxyRequestMethods(Cursor, '_cursor', IDBCursor, [\n    'update',\n    'delete'\n  ]);\n\n  // proxy 'next' methods\n  ['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) {\n    if (!(methodName in IDBCursor.prototype)) return;\n    Cursor.prototype[methodName] = function() {\n      var cursor = this;\n      var args = arguments;\n      return Promise.resolve().then(function() {\n        cursor._cursor[methodName].apply(cursor._cursor, args);\n        return promisifyRequest(cursor._request).then(function(value) {\n          if (!value) return;\n          return new Cursor(value, cursor._request);\n        });\n      });\n    };\n  });\n\n  function ObjectStore(store) {\n    this._store = store;\n  }\n\n  ObjectStore.prototype.createIndex = function() {\n    return new Index(this._store.createIndex.apply(this._store, arguments));\n  };\n\n  ObjectStore.prototype.index = function() {\n    return new Index(this._store.index.apply(this._store, arguments));\n  };\n\n  proxyProperties(ObjectStore, '_store', [\n    'name',\n    'keyPath',\n    'indexNames',\n    'autoIncrement'\n  ]);\n\n  proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n    'put',\n    'add',\n    'delete',\n    'clear',\n    'get',\n    'getAll',\n    'getKey',\n    'getAllKeys',\n    'count'\n  ]);\n\n  proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n    'openCursor',\n    'openKeyCursor'\n  ]);\n\n  proxyMethods(ObjectStore, '_store', IDBObjectStore, [\n    'deleteIndex'\n  ]);\n\n  function Transaction(idbTransaction) {\n    this._tx = idbTransaction;\n    this.complete = new Promise(function(resolve, reject) {\n      idbTransaction.oncomplete = function() {\n        resolve();\n      };\n      idbTransaction.onerror = function() {\n        reject(idbTransaction.error);\n      };\n      idbTransaction.onabort = function() {\n        reject(idbTransaction.error);\n      };\n    });\n  }\n\n  Transaction.prototype.objectStore = function() {\n    return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments));\n  };\n\n  proxyProperties(Transaction, '_tx', [\n    'objectStoreNames',\n    'mode'\n  ]);\n\n  proxyMethods(Transaction, '_tx', IDBTransaction, [\n    'abort'\n  ]);\n\n  function UpgradeDB(db, oldVersion, transaction) {\n    this._db = db;\n    this.oldVersion = oldVersion;\n    this.transaction = new Transaction(transaction);\n  }\n\n  UpgradeDB.prototype.createObjectStore = function() {\n    return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments));\n  };\n\n  proxyProperties(UpgradeDB, '_db', [\n    'name',\n    'version',\n    'objectStoreNames'\n  ]);\n\n  proxyMethods(UpgradeDB, '_db', IDBDatabase, [\n    'deleteObjectStore',\n    'close'\n  ]);\n\n  function DB(db) {\n    this._db = db;\n  }\n\n  DB.prototype.transaction = function() {\n    return new Transaction(this._db.transaction.apply(this._db, arguments));\n  };\n\n  proxyProperties(DB, '_db', [\n    'name',\n    'version',\n    'objectStoreNames'\n  ]);\n\n  proxyMethods(DB, '_db', IDBDatabase, [\n    'close'\n  ]);\n\n  // Add cursor iterators\n  // TODO: remove this once browsers do the right thing with promises\n  ['openCursor', 'openKeyCursor'].forEach(function(funcName) {\n    [ObjectStore, Index].forEach(function(Constructor) {\n      // Don't create iterateKeyCursor if openKeyCursor doesn't exist.\n      if (!(funcName in Constructor.prototype)) return;\n\n      Constructor.prototype[funcName.replace('open', 'iterate')] = function() {\n        var args = toArray(arguments);\n        var callback = args[args.length - 1];\n        var nativeObject = this._store || this._index;\n        var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1));\n        request.onsuccess = function() {\n          callback(request.result);\n        };\n      };\n    });\n  });\n\n  // polyfill getAll\n  [Index, ObjectStore].forEach(function(Constructor) {\n    if (Constructor.prototype.getAll) return;\n    Constructor.prototype.getAll = function(query, count) {\n      var instance = this;\n      var items = [];\n\n      return new Promise(function(resolve) {\n        instance.iterateCursor(query, function(cursor) {\n          if (!cursor) {\n            resolve(items);\n            return;\n          }\n          items.push(cursor.value);\n\n          if (count !== undefined && items.length == count) {\n            resolve(items);\n            return;\n          }\n          cursor.continue();\n        });\n      });\n    };\n  });\n\n  function openDb(name, version, upgradeCallback) {\n    var p = promisifyRequestCall(indexedDB, 'open', [name, version]);\n    var request = p.request;\n\n    if (request) {\n      request.onupgradeneeded = function(event) {\n        if (upgradeCallback) {\n          upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction));\n        }\n      };\n    }\n\n    return p.then(function(db) {\n      return new DB(db);\n    });\n  }\n\n  function deleteDb(name) {\n    return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]);\n  }\n\n  exports.openDb = openDb;\n  exports.deleteDb = deleteDb;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n","'use strict';\n\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\nvar toStr = Object.prototype.toString;\n\nvar isStandardArguments = function isArguments(value) {\n\tif (hasToStringTag && value && typeof value === 'object' && Symbol.toStringTag in value) {\n\t\treturn false;\n\t}\n\treturn toStr.call(value) === '[object Arguments]';\n};\n\nvar isLegacyArguments = function isArguments(value) {\n\tif (isStandardArguments(value)) {\n\t\treturn true;\n\t}\n\treturn value !== null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.length === 'number' &&\n\t\tvalue.length >= 0 &&\n\t\ttoStr.call(value) !== '[object Array]' &&\n\t\ttoStr.call(value.callee) === '[object Function]';\n};\n\nvar supportsStandardArguments = (function () {\n\treturn isStandardArguments(arguments);\n}());\n\nisStandardArguments.isLegacyArguments = isLegacyArguments; // for tests\n\nmodule.exports = supportsStandardArguments ? isStandardArguments : isLegacyArguments;\n","'use strict';\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n","'use strict';\n\nvar hasSymbols = require('has-symbols')();\nvar hasToStringTag = hasSymbols && typeof Symbol.toStringTag === 'symbol';\nvar hasOwnProperty;\nvar regexExec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);\n\tregexExec = Function.call.bind(RegExp.prototype.exec);\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar toStr = Object.prototype.toString;\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && hasOwnProperty(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tregexExec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn toStr.call(value) === regexClass;\n\t};\n","'use strict'\n\nvar isObject = function isObject(val) {\n  return val !== null && !Array.isArray(val) && typeof val === 'object'\n}\n\nvar codes = {\n  // ----------------------------------------\n  // By Code\n  // ----------------------------------------\n  3: 'Cancel',\n  6: 'Help',\n  8: 'Backspace',\n  9: 'Tab',\n  12: 'Clear',\n  13: 'Enter',\n  16: 'Shift',\n  17: 'Control',\n  18: 'Alt',\n  19: 'Pause',\n  20: 'CapsLock',\n  27: 'Escape',\n  28: 'Convert',\n  29: 'NonConvert',\n  30: 'Accept',\n  31: 'ModeChange',\n  32: ' ',\n  33: 'PageUp',\n  34: 'PageDown',\n  35: 'End',\n  36: 'Home',\n  37: 'ArrowLeft',\n  38: 'ArrowUp',\n  39: 'ArrowRight',\n  40: 'ArrowDown',\n  41: 'Select',\n  42: 'Print',\n  43: 'Execute',\n  44: 'PrintScreen',\n  45: 'Insert',\n  46: 'Delete',\n  48: ['0', ')'],\n  49: ['1', '!'],\n  50: ['2', '@'],\n  51: ['3', '#'],\n  52: ['4', '$'],\n  53: ['5', '%'],\n  54: ['6', '^'],\n  55: ['7', '&'],\n  56: ['8', '*'],\n  57: ['9', '('],\n  91: 'OS',\n  93: 'ContextMenu',\n  144: 'NumLock',\n  145: 'ScrollLock',\n  181: 'VolumeMute',\n  182: 'VolumeDown',\n  183: 'VolumeUp',\n  186: [';', ':'],\n  187: ['=', '+'],\n  188: [',', '<'],\n  189: ['-', '_'],\n  190: ['.', '>'],\n  191: ['/', '?'],\n  192: ['`', '~'],\n  219: ['[', '{'],\n  220: ['\\\\', '|'],\n  221: [']', '}'],\n  222: [\"'\", '\"'],\n  224: 'Meta',\n  225: 'AltGraph',\n  246: 'Attn',\n  247: 'CrSel',\n  248: 'ExSel',\n  249: 'EraseEof',\n  250: 'Play',\n  251: 'ZoomOut',\n}\n\n// Function Keys (F1-24)\nfor (var i = 0; i < 24; i += 1) {\n  codes[112 + i] = 'F' + (i + 1)\n}\n\n// Alphabet (a-Z)\nfor (var j = 0; j < 26; j += 1) {\n  var n = j + 65\n  codes[n] = [String.fromCharCode(n + 32), String.fromCharCode(n)]\n}\n\nvar keyboardKey = {\n  codes: codes,\n\n  /**\n   * Get the `keyCode` or `which` value from a keyboard event or `key` name.\n   * @param {string|object} eventOrKey A keyboard event-like object or `key` name.\n   * @param {string} [eventOrKey.key] If object, it must have one of these keys.\n   * @param {number} [eventOrKey.keyCode] If object, it must have one of these keys.\n   * @param {number} [eventOrKey.which] If object, it must have one of these keys.\n   * @returns {number|undefined}\n   */\n  getCode: function getCode(eventOrKey) {\n    if (isObject(eventOrKey)) {\n      return eventOrKey.keyCode || eventOrKey.which || this[eventOrKey.key]\n    }\n    return this[eventOrKey]\n  },\n\n  /**\n   * Get the key name from a keyboard event, `keyCode`, or `which` value.\n   * @param {number|object} eventOrCode A keyboard event-like object or key code.\n   * @param {string} [eventOrCode.key] If object with a `key` name, it will be returned.\n   * @param {number} [eventOrCode.keyCode] If object, it must have one of these keys.\n   * @param {number} [eventOrCode.which] If object, it must have one of these keys.\n   * @param {boolean} [eventOrCode.shiftKey] If object, it must have one of these keys.\n   * @returns {string|undefined}\n   */\n  getKey: function getKey(eventOrCode) {\n    var isEvent = isObject(eventOrCode)\n\n    // handle events with a `key` already defined\n    if (isEvent && eventOrCode.key) {\n      return eventOrCode.key\n    }\n\n    var name = codes[isEvent ? eventOrCode.keyCode || eventOrCode.which : eventOrCode]\n\n    if (Array.isArray(name)) {\n      if (isEvent) {\n        name = name[eventOrCode.shiftKey ? 1 : 0]\n      } else {\n        name = name[0]\n      }\n    }\n\n    return name\n  },\n\n  // ----------------------------------------\n  // By Name\n  // ----------------------------------------\n  // declare these manually for static analysis\n  Cancel: 3,\n  Help: 6,\n  Backspace: 8,\n  Tab: 9,\n  Clear: 12,\n  Enter: 13,\n  Shift: 16,\n  Control: 17,\n  Alt: 18,\n  Pause: 19,\n  CapsLock: 20,\n  Escape: 27,\n  Convert: 28,\n  NonConvert: 29,\n  Accept: 30,\n  ModeChange: 31,\n  ' ': 32,\n  PageUp: 33,\n  PageDown: 34,\n  End: 35,\n  Home: 36,\n  ArrowLeft: 37,\n  ArrowUp: 38,\n  ArrowRight: 39,\n  ArrowDown: 40,\n  Select: 41,\n  Print: 42,\n  Execute: 43,\n  PrintScreen: 44,\n  Insert: 45,\n  Delete: 46,\n  0: 48,\n  ')': 48,\n  1: 49,\n  '!': 49,\n  2: 50,\n  '@': 50,\n  3: 51,\n  '#': 51,\n  4: 52,\n  $: 52,\n  5: 53,\n  '%': 53,\n  6: 54,\n  '^': 54,\n  7: 55,\n  '&': 55,\n  8: 56,\n  '*': 56,\n  9: 57,\n  '(': 57,\n  a: 65,\n  A: 65,\n  b: 66,\n  B: 66,\n  c: 67,\n  C: 67,\n  d: 68,\n  D: 68,\n  e: 69,\n  E: 69,\n  f: 70,\n  F: 70,\n  g: 71,\n  G: 71,\n  h: 72,\n  H: 72,\n  i: 73,\n  I: 73,\n  j: 74,\n  J: 74,\n  k: 75,\n  K: 75,\n  l: 76,\n  L: 76,\n  m: 77,\n  M: 77,\n  n: 78,\n  N: 78,\n  o: 79,\n  O: 79,\n  p: 80,\n  P: 80,\n  q: 81,\n  Q: 81,\n  r: 82,\n  R: 82,\n  s: 83,\n  S: 83,\n  t: 84,\n  T: 84,\n  u: 85,\n  U: 85,\n  v: 86,\n  V: 86,\n  w: 87,\n  W: 87,\n  x: 88,\n  X: 88,\n  y: 89,\n  Y: 89,\n  z: 90,\n  Z: 90,\n  OS: 91,\n  ContextMenu: 93,\n  F1: 112,\n  F2: 113,\n  F3: 114,\n  F4: 115,\n  F5: 116,\n  F6: 117,\n  F7: 118,\n  F8: 119,\n  F9: 120,\n  F10: 121,\n  F11: 122,\n  F12: 123,\n  F13: 124,\n  F14: 125,\n  F15: 126,\n  F16: 127,\n  F17: 128,\n  F18: 129,\n  F19: 130,\n  F20: 131,\n  F21: 132,\n  F22: 133,\n  F23: 134,\n  F24: 135,\n  NumLock: 144,\n  ScrollLock: 145,\n  VolumeMute: 181,\n  VolumeDown: 182,\n  VolumeUp: 183,\n  ';': 186,\n  ':': 186,\n  '=': 187,\n  '+': 187,\n  ',': 188,\n  '<': 188,\n  '-': 189,\n  _: 189,\n  '.': 190,\n  '>': 190,\n  '/': 191,\n  '?': 191,\n  '`': 192,\n  '~': 192,\n  '[': 219,\n  '{': 219,\n  '\\\\': 220,\n  '|': 220,\n  ']': 221,\n  '}': 221,\n  \"'\": 222,\n  '\"': 222,\n  Meta: 224,\n  AltGraph: 225,\n  Attn: 246,\n  CrSel: 247,\n  ExSel: 248,\n  EraseEof: 249,\n  Play: 250,\n  ZoomOut: 251,\n}\n\n// ----------------------------------------\n// By Alias\n// ----------------------------------------\n// provide dot-notation accessible keys for all key names\nkeyboardKey.Spacebar = keyboardKey[' ']\nkeyboardKey.Digit0 = keyboardKey['0']\nkeyboardKey.Digit1 = keyboardKey['1']\nkeyboardKey.Digit2 = keyboardKey['2']\nkeyboardKey.Digit3 = keyboardKey['3']\nkeyboardKey.Digit4 = keyboardKey['4']\nkeyboardKey.Digit5 = keyboardKey['5']\nkeyboardKey.Digit6 = keyboardKey['6']\nkeyboardKey.Digit7 = keyboardKey['7']\nkeyboardKey.Digit8 = keyboardKey['8']\nkeyboardKey.Digit9 = keyboardKey['9']\nkeyboardKey.Tilde = keyboardKey['~']\nkeyboardKey.GraveAccent = keyboardKey['`']\nkeyboardKey.ExclamationPoint = keyboardKey['!']\nkeyboardKey.AtSign = keyboardKey['@']\nkeyboardKey.PoundSign = keyboardKey['#']\nkeyboardKey.PercentSign = keyboardKey['%']\nkeyboardKey.Caret = keyboardKey['^']\nkeyboardKey.Ampersand = keyboardKey['&']\nkeyboardKey.PlusSign = keyboardKey['+']\nkeyboardKey.MinusSign = keyboardKey['-']\nkeyboardKey.EqualsSign = keyboardKey['=']\nkeyboardKey.DivisionSign = keyboardKey['/']\nkeyboardKey.MultiplicationSign = keyboardKey['*']\nkeyboardKey.Comma = keyboardKey[',']\nkeyboardKey.Decimal = keyboardKey['.']\nkeyboardKey.Colon = keyboardKey[':']\nkeyboardKey.Semicolon = keyboardKey[';']\nkeyboardKey.Pipe = keyboardKey['|']\nkeyboardKey.BackSlash = keyboardKey['\\\\']\nkeyboardKey.QuestionMark = keyboardKey['?']\nkeyboardKey.SingleQuote = keyboardKey[\"'\"]\nkeyboardKey.DoubleQuote = keyboardKey['\"']\nkeyboardKey.LeftCurlyBrace = keyboardKey['{']\nkeyboardKey.RightCurlyBrace = keyboardKey['}']\nkeyboardKey.LeftParenthesis = keyboardKey['(']\nkeyboardKey.RightParenthesis = keyboardKey[')']\nkeyboardKey.LeftAngleBracket = keyboardKey['<']\nkeyboardKey.RightAngleBracket = keyboardKey['>']\nkeyboardKey.LeftSquareBracket = keyboardKey['[']\nkeyboardKey.RightSquareBracket = keyboardKey[']']\n\nmodule.exports = keyboardKey\n","var getNative = require('./_getNative'),\n    root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var hashClear = require('./_hashClear'),\n    hashDelete = require('./_hashDelete'),\n    hashGet = require('./_hashGet'),\n    hashHas = require('./_hashHas'),\n    hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var baseCreate = require('./_baseCreate'),\n    baseLodash = require('./_baseLodash');\n\n/** Used as references for the maximum length and index of an array. */\nvar MAX_ARRAY_LENGTH = 4294967295;\n\n/**\n * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n *\n * @private\n * @constructor\n * @param {*} value The value to wrap.\n */\nfunction LazyWrapper(value) {\n  this.__wrapped__ = value;\n  this.__actions__ = [];\n  this.__dir__ = 1;\n  this.__filtered__ = false;\n  this.__iteratees__ = [];\n  this.__takeCount__ = MAX_ARRAY_LENGTH;\n  this.__views__ = [];\n}\n\n// Ensure `LazyWrapper` is an instance of `baseLodash`.\nLazyWrapper.prototype = baseCreate(baseLodash.prototype);\nLazyWrapper.prototype.constructor = LazyWrapper;\n\nmodule.exports = LazyWrapper;\n","var listCacheClear = require('./_listCacheClear'),\n    listCacheDelete = require('./_listCacheDelete'),\n    listCacheGet = require('./_listCacheGet'),\n    listCacheHas = require('./_listCacheHas'),\n    listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","var baseCreate = require('./_baseCreate'),\n    baseLodash = require('./_baseLodash');\n\n/**\n * The base constructor for creating `lodash` wrapper objects.\n *\n * @private\n * @param {*} value The value to wrap.\n * @param {boolean} [chainAll] Enable explicit method chain sequences.\n */\nfunction LodashWrapper(value, chainAll) {\n  this.__wrapped__ = value;\n  this.__actions__ = [];\n  this.__chain__ = !!chainAll;\n  this.__index__ = 0;\n  this.__values__ = undefined;\n}\n\nLodashWrapper.prototype = baseCreate(baseLodash.prototype);\nLodashWrapper.prototype.constructor = LodashWrapper;\n\nmodule.exports = LodashWrapper;\n","var getNative = require('./_getNative'),\n    root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n    mapCacheDelete = require('./_mapCacheDelete'),\n    mapCacheGet = require('./_mapCacheGet'),\n    mapCacheHas = require('./_mapCacheHas'),\n    mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var getNative = require('./_getNative'),\n    root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n    root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var MapCache = require('./_MapCache'),\n    setCacheAdd = require('./_setCacheAdd'),\n    setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n  var index = -1,\n      length = values == null ? 0 : values.length;\n\n  this.__data__ = new MapCache;\n  while (++index < length) {\n    this.add(values[index]);\n  }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","var ListCache = require('./_ListCache'),\n    stackClear = require('./_stackClear'),\n    stackDelete = require('./_stackDelete'),\n    stackGet = require('./_stackGet'),\n    stackHas = require('./_stackHas'),\n    stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n  var data = this.__data__ = new ListCache(entries);\n  this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","var getNative = require('./_getNative'),\n    root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n  switch (args.length) {\n    case 0: return func.call(thisArg);\n    case 1: return func.call(thisArg, args[0]);\n    case 2: return func.call(thisArg, args[0], args[1]);\n    case 3: return func.call(thisArg, args[0], args[1], args[2]);\n  }\n  return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","/**\n * A specialized version of `baseAggregator` for arrays.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\nfunction arrayAggregator(array, setter, iteratee, accumulator) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    var value = array[index];\n    setter(accumulator, value, iteratee(value), array);\n  }\n  return accumulator;\n}\n\nmodule.exports = arrayAggregator;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (iteratee(array[index], index, array) === false) {\n      break;\n    }\n  }\n  return array;\n}\n\nmodule.exports = arrayEach;\n","/**\n * A specialized version of `_.every` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n *  else `false`.\n */\nfunction arrayEvery(array, predicate) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (!predicate(array[index], index, array)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nmodule.exports = arrayEvery;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n  var index = -1,\n      length = array == null ? 0 : array.length,\n      resIndex = 0,\n      result = [];\n\n  while (++index < length) {\n    var value = array[index];\n    if (predicate(value, index, array)) {\n      result[resIndex++] = value;\n    }\n  }\n  return result;\n}\n\nmodule.exports = arrayFilter;\n","var baseIndexOf = require('./_baseIndexOf');\n\n/**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludes(array, value) {\n  var length = array == null ? 0 : array.length;\n  return !!length && baseIndexOf(array, value, 0) > -1;\n}\n\nmodule.exports = arrayIncludes;\n","/**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludesWith(array, value, comparator) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (comparator(value, array[index])) {\n      return true;\n    }\n  }\n  return false;\n}\n\nmodule.exports = arrayIncludesWith;\n","var baseTimes = require('./_baseTimes'),\n    isArguments = require('./isArguments'),\n    isArray = require('./isArray'),\n    isBuffer = require('./isBuffer'),\n    isIndex = require('./_isIndex'),\n    isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n  var isArr = isArray(value),\n      isArg = !isArr && isArguments(value),\n      isBuff = !isArr && !isArg && isBuffer(value),\n      isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n      skipIndexes = isArr || isArg || isBuff || isType,\n      result = skipIndexes ? baseTimes(value.length, String) : [],\n      length = result.length;\n\n  for (var key in value) {\n    if ((inherited || hasOwnProperty.call(value, key)) &&\n        !(skipIndexes && (\n           // Safari 9 has enumerable `arguments.length` in strict mode.\n           key == 'length' ||\n           // Node.js 0.10 has enumerable non-index properties on buffers.\n           (isBuff && (key == 'offset' || key == 'parent')) ||\n           // PhantomJS 2 has enumerable non-index properties on typed arrays.\n           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n           // Skip index properties.\n           isIndex(key, length)\n        ))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n  var index = -1,\n      length = array == null ? 0 : array.length,\n      result = Array(length);\n\n  while (++index < length) {\n    result[index] = iteratee(array[index], index, array);\n  }\n  return result;\n}\n\nmodule.exports = arrayMap;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n  var index = -1,\n      length = values.length,\n      offset = array.length;\n\n  while (++index < length) {\n    array[offset + index] = values[index];\n  }\n  return array;\n}\n\nmodule.exports = arrayPush;\n","/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n *  the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  if (initAccum && length) {\n    accumulator = array[++index];\n  }\n  while (++index < length) {\n    accumulator = iteratee(accumulator, array[index], index, array);\n  }\n  return accumulator;\n}\n\nmodule.exports = arrayReduce;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n *  else `false`.\n */\nfunction arraySome(array, predicate) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (predicate(array[index], index, array)) {\n      return true;\n    }\n  }\n  return false;\n}\n\nmodule.exports = arraySome;\n","var baseProperty = require('./_baseProperty');\n\n/**\n * Gets the size of an ASCII `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\nvar asciiSize = baseProperty('length');\n\nmodule.exports = asciiSize;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n  return string.split('');\n}\n\nmodule.exports = asciiToArray;\n","/** Used to match words composed of alphanumeric characters. */\nvar reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n/**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction asciiWords(string) {\n  return string.match(reAsciiWord) || [];\n}\n\nmodule.exports = asciiWords;\n","var baseAssignValue = require('./_baseAssignValue'),\n    eq = require('./eq');\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n  if ((value !== undefined && !eq(object[key], value)) ||\n      (value === undefined && !(key in object))) {\n    baseAssignValue(object, key, value);\n  }\n}\n\nmodule.exports = assignMergeValue;\n","var baseAssignValue = require('./_baseAssignValue'),\n    eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n  var objValue = object[key];\n  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n      (value === undefined && !(key in object))) {\n    baseAssignValue(object, key, value);\n  }\n}\n\nmodule.exports = assignValue;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n  var length = array.length;\n  while (length--) {\n    if (eq(array[length][0], key)) {\n      return length;\n    }\n  }\n  return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var baseEach = require('./_baseEach');\n\n/**\n * Aggregates elements of `collection` on `accumulator` with keys transformed\n * by `iteratee` and values set by `setter`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\nfunction baseAggregator(collection, setter, iteratee, accumulator) {\n  baseEach(collection, function(value, key, collection) {\n    setter(accumulator, value, iteratee(value), collection);\n  });\n  return accumulator;\n}\n\nmodule.exports = baseAggregator;\n","var copyObject = require('./_copyObject'),\n    keys = require('./keys');\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return object && copyObject(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n","var copyObject = require('./_copyObject'),\n    keysIn = require('./keysIn');\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n  return object && copyObject(source, keysIn(source), object);\n}\n\nmodule.exports = baseAssignIn;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n  if (key == '__proto__' && defineProperty) {\n    defineProperty(object, key, {\n      'configurable': true,\n      'enumerable': true,\n      'value': value,\n      'writable': true\n    });\n  } else {\n    object[key] = value;\n  }\n}\n\nmodule.exports = baseAssignValue;\n","/**\n * The base implementation of `_.clamp` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n */\nfunction baseClamp(number, lower, upper) {\n  if (number === number) {\n    if (upper !== undefined) {\n      number = number <= upper ? number : upper;\n    }\n    if (lower !== undefined) {\n      number = number >= lower ? number : lower;\n    }\n  }\n  return number;\n}\n\nmodule.exports = baseClamp;\n","var Stack = require('./_Stack'),\n    arrayEach = require('./_arrayEach'),\n    assignValue = require('./_assignValue'),\n    baseAssign = require('./_baseAssign'),\n    baseAssignIn = require('./_baseAssignIn'),\n    cloneBuffer = require('./_cloneBuffer'),\n    copyArray = require('./_copyArray'),\n    copySymbols = require('./_copySymbols'),\n    copySymbolsIn = require('./_copySymbolsIn'),\n    getAllKeys = require('./_getAllKeys'),\n    getAllKeysIn = require('./_getAllKeysIn'),\n    getTag = require('./_getTag'),\n    initCloneArray = require('./_initCloneArray'),\n    initCloneByTag = require('./_initCloneByTag'),\n    initCloneObject = require('./_initCloneObject'),\n    isArray = require('./isArray'),\n    isBuffer = require('./isBuffer'),\n    isMap = require('./isMap'),\n    isObject = require('./isObject'),\n    isSet = require('./isSet'),\n    keys = require('./keys'),\n    keysIn = require('./keysIn');\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n    CLONE_FLAT_FLAG = 2,\n    CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    objectTag = '[object Object]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]',\n    weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n *  1 - Deep clone\n *  2 - Flatten inherited properties\n *  4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n  var result,\n      isDeep = bitmask & CLONE_DEEP_FLAG,\n      isFlat = bitmask & CLONE_FLAT_FLAG,\n      isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n  if (customizer) {\n    result = object ? customizer(value, key, object, stack) : customizer(value);\n  }\n  if (result !== undefined) {\n    return result;\n  }\n  if (!isObject(value)) {\n    return value;\n  }\n  var isArr = isArray(value);\n  if (isArr) {\n    result = initCloneArray(value);\n    if (!isDeep) {\n      return copyArray(value, result);\n    }\n  } else {\n    var tag = getTag(value),\n        isFunc = tag == funcTag || tag == genTag;\n\n    if (isBuffer(value)) {\n      return cloneBuffer(value, isDeep);\n    }\n    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n      result = (isFlat || isFunc) ? {} : initCloneObject(value);\n      if (!isDeep) {\n        return isFlat\n          ? copySymbolsIn(value, baseAssignIn(result, value))\n          : copySymbols(value, baseAssign(result, value));\n      }\n    } else {\n      if (!cloneableTags[tag]) {\n        return object ? value : {};\n      }\n      result = initCloneByTag(value, tag, isDeep);\n    }\n  }\n  // Check for circular references and return its corresponding clone.\n  stack || (stack = new Stack);\n  var stacked = stack.get(value);\n  if (stacked) {\n    return stacked;\n  }\n  stack.set(value, result);\n\n  if (isSet(value)) {\n    value.forEach(function(subValue) {\n      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n    });\n  } else if (isMap(value)) {\n    value.forEach(function(subValue, key) {\n      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n    });\n  }\n\n  var keysFunc = isFull\n    ? (isFlat ? getAllKeysIn : getAllKeys)\n    : (isFlat ? keysIn : keys);\n\n  var props = isArr ? undefined : keysFunc(value);\n  arrayEach(props || value, function(subValue, key) {\n    if (props) {\n      key = subValue;\n      subValue = value[key];\n    }\n    // Recursively populate clone (susceptible to call stack limits).\n    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n  });\n  return result;\n}\n\nmodule.exports = baseClone;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(proto) {\n    if (!isObject(proto)) {\n      return {};\n    }\n    if (objectCreate) {\n      return objectCreate(proto);\n    }\n    object.prototype = proto;\n    var result = new object;\n    object.prototype = undefined;\n    return result;\n  };\n}());\n\nmodule.exports = baseCreate;\n","var SetCache = require('./_SetCache'),\n    arrayIncludes = require('./_arrayIncludes'),\n    arrayIncludesWith = require('./_arrayIncludesWith'),\n    arrayMap = require('./_arrayMap'),\n    baseUnary = require('./_baseUnary'),\n    cacheHas = require('./_cacheHas');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of methods like `_.difference` without support\n * for excluding multiple arrays or iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Array} values The values to exclude.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n */\nfunction baseDifference(array, values, iteratee, comparator) {\n  var index = -1,\n      includes = arrayIncludes,\n      isCommon = true,\n      length = array.length,\n      result = [],\n      valuesLength = values.length;\n\n  if (!length) {\n    return result;\n  }\n  if (iteratee) {\n    values = arrayMap(values, baseUnary(iteratee));\n  }\n  if (comparator) {\n    includes = arrayIncludesWith;\n    isCommon = false;\n  }\n  else if (values.length >= LARGE_ARRAY_SIZE) {\n    includes = cacheHas;\n    isCommon = false;\n    values = new SetCache(values);\n  }\n  outer:\n  while (++index < length) {\n    var value = array[index],\n        computed = iteratee == null ? value : iteratee(value);\n\n    value = (comparator || value !== 0) ? value : 0;\n    if (isCommon && computed === computed) {\n      var valuesIndex = valuesLength;\n      while (valuesIndex--) {\n        if (values[valuesIndex] === computed) {\n          continue outer;\n        }\n      }\n      result.push(value);\n    }\n    else if (!includes(values, computed, comparator)) {\n      result.push(value);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseDifference;\n","var baseForOwn = require('./_baseForOwn'),\n    createBaseEach = require('./_createBaseEach');\n\n/**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\nvar baseEach = createBaseEach(baseForOwn);\n\nmodule.exports = baseEach;\n","var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of `_.every` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n *  else `false`\n */\nfunction baseEvery(collection, predicate) {\n  var result = true;\n  baseEach(collection, function(value, index, collection) {\n    result = !!predicate(value, index, collection);\n    return result;\n  });\n  return result;\n}\n\nmodule.exports = baseEvery;\n","var isSymbol = require('./isSymbol');\n\n/**\n * The base implementation of methods like `_.max` and `_.min` which accepts a\n * `comparator` to determine the extremum value.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The iteratee invoked per iteration.\n * @param {Function} comparator The comparator used to compare values.\n * @returns {*} Returns the extremum value.\n */\nfunction baseExtremum(array, iteratee, comparator) {\n  var index = -1,\n      length = array.length;\n\n  while (++index < length) {\n    var value = array[index],\n        current = iteratee(value);\n\n    if (current != null && (computed === undefined\n          ? (current === current && !isSymbol(current))\n          : comparator(current, computed)\n        )) {\n      var computed = current,\n          result = value;\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseExtremum;\n","var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of `_.filter` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction baseFilter(collection, predicate) {\n  var result = [];\n  baseEach(collection, function(value, index, collection) {\n    if (predicate(value, index, collection)) {\n      result.push(value);\n    }\n  });\n  return result;\n}\n\nmodule.exports = baseFilter;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n  var length = array.length,\n      index = fromIndex + (fromRight ? 1 : -1);\n\n  while ((fromRight ? index-- : ++index < length)) {\n    if (predicate(array[index], index, array)) {\n      return index;\n    }\n  }\n  return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var arrayPush = require('./_arrayPush'),\n    isFlattenable = require('./_isFlattenable');\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n  var index = -1,\n      length = array.length;\n\n  predicate || (predicate = isFlattenable);\n  result || (result = []);\n\n  while (++index < length) {\n    var value = array[index];\n    if (depth > 0 && predicate(value)) {\n      if (depth > 1) {\n        // Recursively flatten arrays (susceptible to call stack limits).\n        baseFlatten(value, depth - 1, predicate, isStrict, result);\n      } else {\n        arrayPush(result, value);\n      }\n    } else if (!isStrict) {\n      result[result.length] = value;\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseFlatten;\n","var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n","var baseFor = require('./_baseFor'),\n    keys = require('./keys');\n\n/**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\nfunction baseForOwn(object, iteratee) {\n  return object && baseFor(object, iteratee, keys);\n}\n\nmodule.exports = baseForOwn;\n","var castPath = require('./_castPath'),\n    toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n  path = castPath(path, object);\n\n  var index = 0,\n      length = path.length;\n\n  while (object != null && index < length) {\n    object = object[toKey(path[index++])];\n  }\n  return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var arrayPush = require('./_arrayPush'),\n    isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n  var result = keysFunc(object);\n  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","var Symbol = require('./_Symbol'),\n    getRawTag = require('./_getRawTag'),\n    objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n    undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n  if (value == null) {\n    return value === undefined ? undefinedTag : nullTag;\n  }\n  return (symToStringTag && symToStringTag in Object(value))\n    ? getRawTag(value)\n    : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHas(object, key) {\n  return object != null && hasOwnProperty.call(object, key);\n}\n\nmodule.exports = baseHas;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n  return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n    nativeMin = Math.min;\n\n/**\n * The base implementation of `_.inRange` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to check.\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n */\nfunction baseInRange(number, start, end) {\n  return number >= nativeMin(start, end) && number < nativeMax(start, end);\n}\n\nmodule.exports = baseInRange;\n","var baseFindIndex = require('./_baseFindIndex'),\n    baseIsNaN = require('./_baseIsNaN'),\n    strictIndexOf = require('./_strictIndexOf');\n\n/**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseIndexOf(array, value, fromIndex) {\n  return value === value\n    ? strictIndexOf(array, value, fromIndex)\n    : baseFindIndex(array, baseIsNaN, fromIndex);\n}\n\nmodule.exports = baseIndexOf;\n","var SetCache = require('./_SetCache'),\n    arrayIncludes = require('./_arrayIncludes'),\n    arrayIncludesWith = require('./_arrayIncludesWith'),\n    arrayMap = require('./_arrayMap'),\n    baseUnary = require('./_baseUnary'),\n    cacheHas = require('./_cacheHas');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMin = Math.min;\n\n/**\n * The base implementation of methods like `_.intersection`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\nfunction baseIntersection(arrays, iteratee, comparator) {\n  var includes = comparator ? arrayIncludesWith : arrayIncludes,\n      length = arrays[0].length,\n      othLength = arrays.length,\n      othIndex = othLength,\n      caches = Array(othLength),\n      maxLength = Infinity,\n      result = [];\n\n  while (othIndex--) {\n    var array = arrays[othIndex];\n    if (othIndex && iteratee) {\n      array = arrayMap(array, baseUnary(iteratee));\n    }\n    maxLength = nativeMin(array.length, maxLength);\n    caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n      ? new SetCache(othIndex && array)\n      : undefined;\n  }\n  array = arrays[0];\n\n  var index = -1,\n      seen = caches[0];\n\n  outer:\n  while (++index < length && result.length < maxLength) {\n    var value = array[index],\n        computed = iteratee ? iteratee(value) : value;\n\n    value = (comparator || value !== 0) ? value : 0;\n    if (!(seen\n          ? cacheHas(seen, computed)\n          : includes(result, computed, comparator)\n        )) {\n      othIndex = othLength;\n      while (--othIndex) {\n        var cache = caches[othIndex];\n        if (!(cache\n              ? cacheHas(cache, computed)\n              : includes(arrays[othIndex], computed, comparator))\n            ) {\n          continue outer;\n        }\n      }\n      if (seen) {\n        seen.push(computed);\n      }\n      result.push(value);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseIntersection;\n","var baseForOwn = require('./_baseForOwn');\n\n/**\n * The base implementation of `_.invert` and `_.invertBy` which inverts\n * `object` with values transformed by `iteratee` and set by `setter`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform values.\n * @param {Object} accumulator The initial inverted object.\n * @returns {Function} Returns `accumulator`.\n */\nfunction baseInverter(object, setter, iteratee, accumulator) {\n  baseForOwn(object, function(value, key, object) {\n    setter(accumulator, iteratee(value), key, object);\n  });\n  return accumulator;\n}\n\nmodule.exports = baseInverter;\n","var apply = require('./_apply'),\n    castPath = require('./_castPath'),\n    last = require('./last'),\n    parent = require('./_parent'),\n    toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.invoke` without support for individual\n * method arguments.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {Array} args The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n */\nfunction baseInvoke(object, path, args) {\n  path = castPath(path, object);\n  object = parent(object, path);\n  var func = object == null ? object : object[toKey(last(path))];\n  return func == null ? undefined : apply(func, object, args);\n}\n\nmodule.exports = baseInvoke;\n","var baseGetTag = require('./_baseGetTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n  return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n    isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n *  1 - Unordered comparison\n *  2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n  if (value === other) {\n    return true;\n  }\n  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n    return value !== value && other !== other;\n  }\n  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n    equalArrays = require('./_equalArrays'),\n    equalByTag = require('./_equalByTag'),\n    equalObjects = require('./_equalObjects'),\n    getTag = require('./_getTag'),\n    isArray = require('./isArray'),\n    isBuffer = require('./isBuffer'),\n    isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n  var objIsArr = isArray(object),\n      othIsArr = isArray(other),\n      objTag = objIsArr ? arrayTag : getTag(object),\n      othTag = othIsArr ? arrayTag : getTag(other);\n\n  objTag = objTag == argsTag ? objectTag : objTag;\n  othTag = othTag == argsTag ? objectTag : othTag;\n\n  var objIsObj = objTag == objectTag,\n      othIsObj = othTag == objectTag,\n      isSameTag = objTag == othTag;\n\n  if (isSameTag && isBuffer(object)) {\n    if (!isBuffer(other)) {\n      return false;\n    }\n    objIsArr = true;\n    objIsObj = false;\n  }\n  if (isSameTag && !objIsObj) {\n    stack || (stack = new Stack);\n    return (objIsArr || isTypedArray(object))\n      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n  }\n  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n    if (objIsWrapped || othIsWrapped) {\n      var objUnwrapped = objIsWrapped ? object.value() : object,\n          othUnwrapped = othIsWrapped ? other.value() : other;\n\n      stack || (stack = new Stack);\n      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n    }\n  }\n  if (!isSameTag) {\n    return false;\n  }\n  stack || (stack = new Stack);\n  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var getTag = require('./_getTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n  return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nmodule.exports = baseIsMap;\n","var Stack = require('./_Stack'),\n    baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n  var index = matchData.length,\n      length = index,\n      noCustomizer = !customizer;\n\n  if (object == null) {\n    return !length;\n  }\n  object = Object(object);\n  while (index--) {\n    var data = matchData[index];\n    if ((noCustomizer && data[2])\n          ? data[1] !== object[data[0]]\n          : !(data[0] in object)\n        ) {\n      return false;\n    }\n  }\n  while (++index < length) {\n    data = matchData[index];\n    var key = data[0],\n        objValue = object[key],\n        srcValue = data[1];\n\n    if (noCustomizer && data[2]) {\n      if (objValue === undefined && !(key in object)) {\n        return false;\n      }\n    } else {\n      var stack = new Stack;\n      if (customizer) {\n        var result = customizer(objValue, srcValue, key, object, source, stack);\n      }\n      if (!(result === undefined\n            ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n            : result\n          )) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nmodule.exports = baseIsMatch;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n  return value !== value;\n}\n\nmodule.exports = baseIsNaN;\n","var isFunction = require('./isFunction'),\n    isMasked = require('./_isMasked'),\n    isObject = require('./isObject'),\n    toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n    objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n *  else `false`.\n */\nfunction baseIsNative(value) {\n  if (!isObject(value) || isMasked(value)) {\n    return false;\n  }\n  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n  return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var getTag = require('./_getTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n  return isObjectLike(value) && getTag(value) == setTag;\n}\n\nmodule.exports = baseIsSet;\n","var baseGetTag = require('./_baseGetTag'),\n    isLength = require('./isLength'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    funcTag = '[object Function]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    objectTag = '[object Object]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n  return isObjectLike(value) &&\n    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","var baseMatches = require('./_baseMatches'),\n    baseMatchesProperty = require('./_baseMatchesProperty'),\n    identity = require('./identity'),\n    isArray = require('./isArray'),\n    property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n  if (typeof value == 'function') {\n    return value;\n  }\n  if (value == null) {\n    return identity;\n  }\n  if (typeof value == 'object') {\n    return isArray(value)\n      ? baseMatchesProperty(value[0], value[1])\n      : baseMatches(value);\n  }\n  return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var isPrototype = require('./_isPrototype'),\n    nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n  if (!isPrototype(object)) {\n    return nativeKeys(object);\n  }\n  var result = [];\n  for (var key in Object(object)) {\n    if (hasOwnProperty.call(object, key) && key != 'constructor') {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseKeys;\n","var isObject = require('./isObject'),\n    isPrototype = require('./_isPrototype'),\n    nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n  if (!isObject(object)) {\n    return nativeKeysIn(object);\n  }\n  var isProto = isPrototype(object),\n      result = [];\n\n  for (var key in object) {\n    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseKeysIn;\n","/**\n * The function whose prototype chain sequence wrappers inherit from.\n *\n * @private\n */\nfunction baseLodash() {\n  // No operation performed.\n}\n\nmodule.exports = baseLodash;\n","/**\n * The base implementation of `_.lt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n *  else `false`.\n */\nfunction baseLt(value, other) {\n  return value < other;\n}\n\nmodule.exports = baseLt;\n","var baseEach = require('./_baseEach'),\n    isArrayLike = require('./isArrayLike');\n\n/**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction baseMap(collection, iteratee) {\n  var index = -1,\n      result = isArrayLike(collection) ? Array(collection.length) : [];\n\n  baseEach(collection, function(value, key, collection) {\n    result[++index] = iteratee(value, key, collection);\n  });\n  return result;\n}\n\nmodule.exports = baseMap;\n","var baseIsMatch = require('./_baseIsMatch'),\n    getMatchData = require('./_getMatchData'),\n    matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n  var matchData = getMatchData(source);\n  if (matchData.length == 1 && matchData[0][2]) {\n    return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n  }\n  return function(object) {\n    return object === source || baseIsMatch(object, source, matchData);\n  };\n}\n\nmodule.exports = baseMatches;\n","var baseIsEqual = require('./_baseIsEqual'),\n    get = require('./get'),\n    hasIn = require('./hasIn'),\n    isKey = require('./_isKey'),\n    isStrictComparable = require('./_isStrictComparable'),\n    matchesStrictComparable = require('./_matchesStrictComparable'),\n    toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n  if (isKey(path) && isStrictComparable(srcValue)) {\n    return matchesStrictComparable(toKey(path), srcValue);\n  }\n  return function(object) {\n    var objValue = get(object, path);\n    return (objValue === undefined && objValue === srcValue)\n      ? hasIn(object, path)\n      : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n  };\n}\n\nmodule.exports = baseMatchesProperty;\n","var Stack = require('./_Stack'),\n    assignMergeValue = require('./_assignMergeValue'),\n    baseFor = require('./_baseFor'),\n    baseMergeDeep = require('./_baseMergeDeep'),\n    isObject = require('./isObject'),\n    keysIn = require('./keysIn'),\n    safeGet = require('./_safeGet');\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n *  counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n  if (object === source) {\n    return;\n  }\n  baseFor(source, function(srcValue, key) {\n    stack || (stack = new Stack);\n    if (isObject(srcValue)) {\n      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n    }\n    else {\n      var newValue = customizer\n        ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n        : undefined;\n\n      if (newValue === undefined) {\n        newValue = srcValue;\n      }\n      assignMergeValue(object, key, newValue);\n    }\n  }, keysIn);\n}\n\nmodule.exports = baseMerge;\n","var assignMergeValue = require('./_assignMergeValue'),\n    cloneBuffer = require('./_cloneBuffer'),\n    cloneTypedArray = require('./_cloneTypedArray'),\n    copyArray = require('./_copyArray'),\n    initCloneObject = require('./_initCloneObject'),\n    isArguments = require('./isArguments'),\n    isArray = require('./isArray'),\n    isArrayLikeObject = require('./isArrayLikeObject'),\n    isBuffer = require('./isBuffer'),\n    isFunction = require('./isFunction'),\n    isObject = require('./isObject'),\n    isPlainObject = require('./isPlainObject'),\n    isTypedArray = require('./isTypedArray'),\n    safeGet = require('./_safeGet'),\n    toPlainObject = require('./toPlainObject');\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n *  counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n  var objValue = safeGet(object, key),\n      srcValue = safeGet(source, key),\n      stacked = stack.get(srcValue);\n\n  if (stacked) {\n    assignMergeValue(object, key, stacked);\n    return;\n  }\n  var newValue = customizer\n    ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n    : undefined;\n\n  var isCommon = newValue === undefined;\n\n  if (isCommon) {\n    var isArr = isArray(srcValue),\n        isBuff = !isArr && isBuffer(srcValue),\n        isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n    newValue = srcValue;\n    if (isArr || isBuff || isTyped) {\n      if (isArray(objValue)) {\n        newValue = objValue;\n      }\n      else if (isArrayLikeObject(objValue)) {\n        newValue = copyArray(objValue);\n      }\n      else if (isBuff) {\n        isCommon = false;\n        newValue = cloneBuffer(srcValue, true);\n      }\n      else if (isTyped) {\n        isCommon = false;\n        newValue = cloneTypedArray(srcValue, true);\n      }\n      else {\n        newValue = [];\n      }\n    }\n    else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n      newValue = objValue;\n      if (isArguments(objValue)) {\n        newValue = toPlainObject(objValue);\n      }\n      else if (!isObject(objValue) || isFunction(objValue)) {\n        newValue = initCloneObject(srcValue);\n      }\n    }\n    else {\n      isCommon = false;\n    }\n  }\n  if (isCommon) {\n    // Recursively merge objects and arrays (susceptible to call stack limits).\n    stack.set(srcValue, newValue);\n    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n    stack['delete'](srcValue);\n  }\n  assignMergeValue(object, key, newValue);\n}\n\nmodule.exports = baseMergeDeep;\n","var arrayMap = require('./_arrayMap'),\n    baseGet = require('./_baseGet'),\n    baseIteratee = require('./_baseIteratee'),\n    baseMap = require('./_baseMap'),\n    baseSortBy = require('./_baseSortBy'),\n    baseUnary = require('./_baseUnary'),\n    compareMultiple = require('./_compareMultiple'),\n    identity = require('./identity'),\n    isArray = require('./isArray');\n\n/**\n * The base implementation of `_.orderBy` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `iteratees`.\n * @returns {Array} Returns the new sorted array.\n */\nfunction baseOrderBy(collection, iteratees, orders) {\n  if (iteratees.length) {\n    iteratees = arrayMap(iteratees, function(iteratee) {\n      if (isArray(iteratee)) {\n        return function(value) {\n          return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);\n        }\n      }\n      return iteratee;\n    });\n  } else {\n    iteratees = [identity];\n  }\n\n  var index = -1;\n  iteratees = arrayMap(iteratees, baseUnary(baseIteratee));\n\n  var result = baseMap(collection, function(value, key, collection) {\n    var criteria = arrayMap(iteratees, function(iteratee) {\n      return iteratee(value);\n    });\n    return { 'criteria': criteria, 'index': ++index, 'value': value };\n  });\n\n  return baseSortBy(result, function(object, other) {\n    return compareMultiple(object, other, orders);\n  });\n}\n\nmodule.exports = baseOrderBy;\n","var basePickBy = require('./_basePickBy'),\n    hasIn = require('./hasIn');\n\n/**\n * The base implementation of `_.pick` without support for individual\n * property identifiers.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @returns {Object} Returns the new object.\n */\nfunction basePick(object, paths) {\n  return basePickBy(object, paths, function(value, path) {\n    return hasIn(object, path);\n  });\n}\n\nmodule.exports = basePick;\n","var baseGet = require('./_baseGet'),\n    baseSet = require('./_baseSet'),\n    castPath = require('./_castPath');\n\n/**\n * The base implementation of  `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\nfunction basePickBy(object, paths, predicate) {\n  var index = -1,\n      length = paths.length,\n      result = {};\n\n  while (++index < length) {\n    var path = paths[index],\n        value = baseGet(object, path);\n\n    if (predicate(value, path)) {\n      baseSet(result, castPath(path, object), value);\n    }\n  }\n  return result;\n}\n\nmodule.exports = basePickBy;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n  return function(object) {\n    return baseGet(object, path);\n  };\n}\n\nmodule.exports = basePropertyDeep;\n","/**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyOf(object) {\n  return function(key) {\n    return object == null ? undefined : object[key];\n  };\n}\n\nmodule.exports = basePropertyOf;\n","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeCeil = Math.ceil,\n    nativeMax = Math.max;\n\n/**\n * The base implementation of `_.range` and `_.rangeRight` which doesn't\n * coerce arguments.\n *\n * @private\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @param {number} step The value to increment or decrement by.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the range of numbers.\n */\nfunction baseRange(start, end, step, fromRight) {\n  var index = -1,\n      length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n      result = Array(length);\n\n  while (length--) {\n    result[fromRight ? length : ++index] = start;\n    start += step;\n  }\n  return result;\n}\n\nmodule.exports = baseRange;\n","/**\n * The base implementation of `_.reduce` and `_.reduceRight`, without support\n * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} accumulator The initial value.\n * @param {boolean} initAccum Specify using the first or last element of\n *  `collection` as the initial value.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the accumulated value.\n */\nfunction baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n  eachFunc(collection, function(value, index, collection) {\n    accumulator = initAccum\n      ? (initAccum = false, value)\n      : iteratee(accumulator, value, index, collection);\n  });\n  return accumulator;\n}\n\nmodule.exports = baseReduce;\n","var identity = require('./identity'),\n    overRest = require('./_overRest'),\n    setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n  return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","var assignValue = require('./_assignValue'),\n    castPath = require('./_castPath'),\n    isIndex = require('./_isIndex'),\n    isObject = require('./isObject'),\n    toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n  if (!isObject(object)) {\n    return object;\n  }\n  path = castPath(path, object);\n\n  var index = -1,\n      length = path.length,\n      lastIndex = length - 1,\n      nested = object;\n\n  while (nested != null && ++index < length) {\n    var key = toKey(path[index]),\n        newValue = value;\n\n    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n      return object;\n    }\n\n    if (index != lastIndex) {\n      var objValue = nested[key];\n      newValue = customizer ? customizer(objValue, key, nested) : undefined;\n      if (newValue === undefined) {\n        newValue = isObject(objValue)\n          ? objValue\n          : (isIndex(path[index + 1]) ? [] : {});\n      }\n    }\n    assignValue(nested, key, newValue);\n    nested = nested[key];\n  }\n  return object;\n}\n\nmodule.exports = baseSet;\n","var identity = require('./identity'),\n    metaMap = require('./_metaMap');\n\n/**\n * The base implementation of `setData` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\nvar baseSetData = !metaMap ? identity : function(func, data) {\n  metaMap.set(func, data);\n  return func;\n};\n\nmodule.exports = baseSetData;\n","var constant = require('./constant'),\n    defineProperty = require('./_defineProperty'),\n    identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n  return defineProperty(func, 'toString', {\n    'configurable': true,\n    'enumerable': false,\n    'value': constant(string),\n    'writable': true\n  });\n};\n\nmodule.exports = baseSetToString;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n  var index = -1,\n      length = array.length;\n\n  if (start < 0) {\n    start = -start > length ? 0 : (length + start);\n  }\n  end = end > length ? length : end;\n  if (end < 0) {\n    end += length;\n  }\n  length = start > end ? 0 : ((end - start) >>> 0);\n  start >>>= 0;\n\n  var result = Array(length);\n  while (++index < length) {\n    result[index] = array[index + start];\n  }\n  return result;\n}\n\nmodule.exports = baseSlice;\n","var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of `_.some` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n *  else `false`.\n */\nfunction baseSome(collection, predicate) {\n  var result;\n\n  baseEach(collection, function(value, index, collection) {\n    result = predicate(value, index, collection);\n    return !result;\n  });\n  return !!result;\n}\n\nmodule.exports = baseSome;\n","/**\n * The base implementation of `_.sortBy` which uses `comparer` to define the\n * sort order of `array` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `array`.\n */\nfunction baseSortBy(array, comparer) {\n  var length = array.length;\n\n  array.sort(comparer);\n  while (length--) {\n    array[length] = array[length].value;\n  }\n  return array;\n}\n\nmodule.exports = baseSortBy;\n","/**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\nfunction baseSum(array, iteratee) {\n  var result,\n      index = -1,\n      length = array.length;\n\n  while (++index < length) {\n    var current = iteratee(array[index]);\n    if (current !== undefined) {\n      result = result === undefined ? current : (result + current);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseSum;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n  var index = -1,\n      result = Array(n);\n\n  while (++index < n) {\n    result[index] = iteratee(index);\n  }\n  return result;\n}\n\nmodule.exports = baseTimes;\n","var Symbol = require('./_Symbol'),\n    arrayMap = require('./_arrayMap'),\n    isArray = require('./isArray'),\n    isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n  // Exit early for strings to avoid a performance hit in some environments.\n  if (typeof value == 'string') {\n    return value;\n  }\n  if (isArray(value)) {\n    // Recursively convert values (susceptible to call stack limits).\n    return arrayMap(value, baseToString) + '';\n  }\n  if (isSymbol(value)) {\n    return symbolToString ? symbolToString.call(value) : '';\n  }\n  var result = (value + '');\n  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n  return function(value) {\n    return func(value);\n  };\n}\n\nmodule.exports = baseUnary;\n","var SetCache = require('./_SetCache'),\n    arrayIncludes = require('./_arrayIncludes'),\n    arrayIncludesWith = require('./_arrayIncludesWith'),\n    cacheHas = require('./_cacheHas'),\n    createSet = require('./_createSet'),\n    setToArray = require('./_setToArray');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseUniq(array, iteratee, comparator) {\n  var index = -1,\n      includes = arrayIncludes,\n      length = array.length,\n      isCommon = true,\n      result = [],\n      seen = result;\n\n  if (comparator) {\n    isCommon = false;\n    includes = arrayIncludesWith;\n  }\n  else if (length >= LARGE_ARRAY_SIZE) {\n    var set = iteratee ? null : createSet(array);\n    if (set) {\n      return setToArray(set);\n    }\n    isCommon = false;\n    includes = cacheHas;\n    seen = new SetCache;\n  }\n  else {\n    seen = iteratee ? [] : result;\n  }\n  outer:\n  while (++index < length) {\n    var value = array[index],\n        computed = iteratee ? iteratee(value) : value;\n\n    value = (comparator || value !== 0) ? value : 0;\n    if (isCommon && computed === computed) {\n      var seenIndex = seen.length;\n      while (seenIndex--) {\n        if (seen[seenIndex] === computed) {\n          continue outer;\n        }\n      }\n      if (iteratee) {\n        seen.push(computed);\n      }\n      result.push(value);\n    }\n    else if (!includes(seen, computed, comparator)) {\n      if (seen !== result) {\n        seen.push(computed);\n      }\n      result.push(value);\n    }\n  }\n  return result;\n}\n\nmodule.exports = baseUniq;\n","var arrayMap = require('./_arrayMap');\n\n/**\n * The base implementation of `_.values` and `_.valuesIn` which creates an\n * array of `object` property values corresponding to the property names\n * of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the array of property values.\n */\nfunction baseValues(object, props) {\n  return arrayMap(props, function(key) {\n    return object[key];\n  });\n}\n\nmodule.exports = baseValues;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n  return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var isArrayLikeObject = require('./isArrayLikeObject');\n\n/**\n * Casts `value` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\nfunction castArrayLikeObject(value) {\n  return isArrayLikeObject(value) ? value : [];\n}\n\nmodule.exports = castArrayLikeObject;\n","var identity = require('./identity');\n\n/**\n * Casts `value` to `identity` if it's not a function.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Function} Returns cast function.\n */\nfunction castFunction(value) {\n  return typeof value == 'function' ? value : identity;\n}\n\nmodule.exports = castFunction;\n","var isArray = require('./isArray'),\n    isKey = require('./_isKey'),\n    stringToPath = require('./_stringToPath'),\n    toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n  if (isArray(value)) {\n    return value;\n  }\n  return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var baseSlice = require('./_baseSlice');\n\n/**\n * Casts `array` to a slice if it's needed.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {number} start The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the cast slice.\n */\nfunction castSlice(array, start, end) {\n  var length = array.length;\n  end = end === undefined ? length : end;\n  return (!start && end >= length) ? array : baseSlice(array, start, end);\n}\n\nmodule.exports = castSlice;\n","var baseIndexOf = require('./_baseIndexOf');\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the last unmatched string symbol.\n */\nfunction charsEndIndex(strSymbols, chrSymbols) {\n  var index = strSymbols.length;\n\n  while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n  return index;\n}\n\nmodule.exports = charsEndIndex;\n","var baseIndexOf = require('./_baseIndexOf');\n\n/**\n * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the first unmatched string symbol.\n */\nfunction charsStartIndex(strSymbols, chrSymbols) {\n  var index = -1,\n      length = strSymbols.length;\n\n  while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n  return index;\n}\n\nmodule.exports = charsStartIndex;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n  new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n  return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of  `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n  if (isDeep) {\n    return buffer.slice();\n  }\n  var length = buffer.length,\n      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n  buffer.copy(result);\n  return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n  var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nmodule.exports = cloneDataView;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n  result.lastIndex = regexp.lastIndex;\n  return result;\n}\n\nmodule.exports = cloneRegExp;\n","var Symbol = require('./_Symbol');\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nmodule.exports = cloneSymbol;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","var isSymbol = require('./isSymbol');\n\n/**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\nfunction compareAscending(value, other) {\n  if (value !== other) {\n    var valIsDefined = value !== undefined,\n        valIsNull = value === null,\n        valIsReflexive = value === value,\n        valIsSymbol = isSymbol(value);\n\n    var othIsDefined = other !== undefined,\n        othIsNull = other === null,\n        othIsReflexive = other === other,\n        othIsSymbol = isSymbol(other);\n\n    if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n        (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n        (valIsNull && othIsDefined && othIsReflexive) ||\n        (!valIsDefined && othIsReflexive) ||\n        !valIsReflexive) {\n      return 1;\n    }\n    if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n        (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n        (othIsNull && valIsDefined && valIsReflexive) ||\n        (!othIsDefined && valIsReflexive) ||\n        !othIsReflexive) {\n      return -1;\n    }\n  }\n  return 0;\n}\n\nmodule.exports = compareAscending;\n","var compareAscending = require('./_compareAscending');\n\n/**\n * Used by `_.orderBy` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `object`.\n */\nfunction compareMultiple(object, other, orders) {\n  var index = -1,\n      objCriteria = object.criteria,\n      othCriteria = other.criteria,\n      length = objCriteria.length,\n      ordersLength = orders.length;\n\n  while (++index < length) {\n    var result = compareAscending(objCriteria[index], othCriteria[index]);\n    if (result) {\n      if (index >= ordersLength) {\n        return result;\n      }\n      var order = orders[index];\n      return result * (order == 'desc' ? -1 : 1);\n    }\n  }\n  // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n  // that causes it, under certain circumstances, to provide the same value for\n  // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n  // for more details.\n  //\n  // This also ensures a stable sort in V8 and other engines.\n  // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n  return object.index - other.index;\n}\n\nmodule.exports = compareMultiple;\n","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates an array that is the composition of partially applied arguments,\n * placeholders, and provided arguments into a single array of arguments.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to prepend to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\nfunction composeArgs(args, partials, holders, isCurried) {\n  var argsIndex = -1,\n      argsLength = args.length,\n      holdersLength = holders.length,\n      leftIndex = -1,\n      leftLength = partials.length,\n      rangeLength = nativeMax(argsLength - holdersLength, 0),\n      result = Array(leftLength + rangeLength),\n      isUncurried = !isCurried;\n\n  while (++leftIndex < leftLength) {\n    result[leftIndex] = partials[leftIndex];\n  }\n  while (++argsIndex < holdersLength) {\n    if (isUncurried || argsIndex < argsLength) {\n      result[holders[argsIndex]] = args[argsIndex];\n    }\n  }\n  while (rangeLength--) {\n    result[leftIndex++] = args[argsIndex++];\n  }\n  return result;\n}\n\nmodule.exports = composeArgs;\n","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This function is like `composeArgs` except that the arguments composition\n * is tailored for `_.partialRight`.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to append to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\nfunction composeArgsRight(args, partials, holders, isCurried) {\n  var argsIndex = -1,\n      argsLength = args.length,\n      holdersIndex = -1,\n      holdersLength = holders.length,\n      rightIndex = -1,\n      rightLength = partials.length,\n      rangeLength = nativeMax(argsLength - holdersLength, 0),\n      result = Array(rangeLength + rightLength),\n      isUncurried = !isCurried;\n\n  while (++argsIndex < rangeLength) {\n    result[argsIndex] = args[argsIndex];\n  }\n  var offset = argsIndex;\n  while (++rightIndex < rightLength) {\n    result[offset + rightIndex] = partials[rightIndex];\n  }\n  while (++holdersIndex < holdersLength) {\n    if (isUncurried || argsIndex < argsLength) {\n      result[offset + holders[holdersIndex]] = args[argsIndex++];\n    }\n  }\n  return result;\n}\n\nmodule.exports = composeArgsRight;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n  var index = -1,\n      length = source.length;\n\n  array || (array = Array(length));\n  while (++index < length) {\n    array[index] = source[index];\n  }\n  return array;\n}\n\nmodule.exports = copyArray;\n","var assignValue = require('./_assignValue'),\n    baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n  var isNew = !object;\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n\n    var newValue = customizer\n      ? customizer(object[key], source[key], key, object, source)\n      : undefined;\n\n    if (newValue === undefined) {\n      newValue = source[key];\n    }\n    if (isNew) {\n      baseAssignValue(object, key, newValue);\n    } else {\n      assignValue(object, key, newValue);\n    }\n  }\n  return object;\n}\n\nmodule.exports = copyObject;\n","var copyObject = require('./_copyObject'),\n    getSymbols = require('./_getSymbols');\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n  return copyObject(source, getSymbols(source), object);\n}\n\nmodule.exports = copySymbols;\n","var copyObject = require('./_copyObject'),\n    getSymbolsIn = require('./_getSymbolsIn');\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n  return copyObject(source, getSymbolsIn(source), object);\n}\n\nmodule.exports = copySymbolsIn;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/**\n * Gets the number of `placeholder` occurrences in `array`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} placeholder The placeholder to search for.\n * @returns {number} Returns the placeholder count.\n */\nfunction countHolders(array, placeholder) {\n  var length = array.length,\n      result = 0;\n\n  while (length--) {\n    if (array[length] === placeholder) {\n      ++result;\n    }\n  }\n  return result;\n}\n\nmodule.exports = countHolders;\n","var arrayAggregator = require('./_arrayAggregator'),\n    baseAggregator = require('./_baseAggregator'),\n    baseIteratee = require('./_baseIteratee'),\n    isArray = require('./isArray');\n\n/**\n * Creates a function like `_.groupBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} [initializer] The accumulator object initializer.\n * @returns {Function} Returns the new aggregator function.\n */\nfunction createAggregator(setter, initializer) {\n  return function(collection, iteratee) {\n    var func = isArray(collection) ? arrayAggregator : baseAggregator,\n        accumulator = initializer ? initializer() : {};\n\n    return func(collection, setter, baseIteratee(iteratee, 2), accumulator);\n  };\n}\n\nmodule.exports = createAggregator;\n","var baseRest = require('./_baseRest'),\n    isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n  return baseRest(function(object, sources) {\n    var index = -1,\n        length = sources.length,\n        customizer = length > 1 ? sources[length - 1] : undefined,\n        guard = length > 2 ? sources[2] : undefined;\n\n    customizer = (assigner.length > 3 && typeof customizer == 'function')\n      ? (length--, customizer)\n      : undefined;\n\n    if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n      customizer = length < 3 ? undefined : customizer;\n      length = 1;\n    }\n    object = Object(object);\n    while (++index < length) {\n      var source = sources[index];\n      if (source) {\n        assigner(object, source, index, customizer);\n      }\n    }\n    return object;\n  });\n}\n\nmodule.exports = createAssigner;\n","var isArrayLike = require('./isArrayLike');\n\n/**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseEach(eachFunc, fromRight) {\n  return function(collection, iteratee) {\n    if (collection == null) {\n      return collection;\n    }\n    if (!isArrayLike(collection)) {\n      return eachFunc(collection, iteratee);\n    }\n    var length = collection.length,\n        index = fromRight ? length : -1,\n        iterable = Object(collection);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (iteratee(iterable[index], index, iterable) === false) {\n        break;\n      }\n    }\n    return collection;\n  };\n}\n\nmodule.exports = createBaseEach;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n  return function(object, iteratee, keysFunc) {\n    var index = -1,\n        iterable = Object(object),\n        props = keysFunc(object),\n        length = props.length;\n\n    while (length--) {\n      var key = props[fromRight ? length : ++index];\n      if (iteratee(iterable[key], key, iterable) === false) {\n        break;\n      }\n    }\n    return object;\n  };\n}\n\nmodule.exports = createBaseFor;\n","var createCtor = require('./_createCtor'),\n    root = require('./_root');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1;\n\n/**\n * Creates a function that wraps `func` to invoke it with the optional `this`\n * binding of `thisArg`.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createBind(func, bitmask, thisArg) {\n  var isBind = bitmask & WRAP_BIND_FLAG,\n      Ctor = createCtor(func);\n\n  function wrapper() {\n    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n    return fn.apply(isBind ? thisArg : this, arguments);\n  }\n  return wrapper;\n}\n\nmodule.exports = createBind;\n","var castSlice = require('./_castSlice'),\n    hasUnicode = require('./_hasUnicode'),\n    stringToArray = require('./_stringToArray'),\n    toString = require('./toString');\n\n/**\n * Creates a function like `_.lowerFirst`.\n *\n * @private\n * @param {string} methodName The name of the `String` case method to use.\n * @returns {Function} Returns the new case function.\n */\nfunction createCaseFirst(methodName) {\n  return function(string) {\n    string = toString(string);\n\n    var strSymbols = hasUnicode(string)\n      ? stringToArray(string)\n      : undefined;\n\n    var chr = strSymbols\n      ? strSymbols[0]\n      : string.charAt(0);\n\n    var trailing = strSymbols\n      ? castSlice(strSymbols, 1).join('')\n      : string.slice(1);\n\n    return chr[methodName]() + trailing;\n  };\n}\n\nmodule.exports = createCaseFirst;\n","var arrayReduce = require('./_arrayReduce'),\n    deburr = require('./deburr'),\n    words = require('./words');\n\n/** Used to compose unicode capture groups. */\nvar rsApos = \"['\\u2019]\";\n\n/** Used to match apostrophes. */\nvar reApos = RegExp(rsApos, 'g');\n\n/**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\nfunction createCompounder(callback) {\n  return function(string) {\n    return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n  };\n}\n\nmodule.exports = createCompounder;\n","var baseCreate = require('./_baseCreate'),\n    isObject = require('./isObject');\n\n/**\n * Creates a function that produces an instance of `Ctor` regardless of\n * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n *\n * @private\n * @param {Function} Ctor The constructor to wrap.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createCtor(Ctor) {\n  return function() {\n    // Use a `switch` statement to work with class constructors. See\n    // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n    // for more details.\n    var args = arguments;\n    switch (args.length) {\n      case 0: return new Ctor;\n      case 1: return new Ctor(args[0]);\n      case 2: return new Ctor(args[0], args[1]);\n      case 3: return new Ctor(args[0], args[1], args[2]);\n      case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n    }\n    var thisBinding = baseCreate(Ctor.prototype),\n        result = Ctor.apply(thisBinding, args);\n\n    // Mimic the constructor's `return` behavior.\n    // See https://es5.github.io/#x13.2.2 for more details.\n    return isObject(result) ? result : thisBinding;\n  };\n}\n\nmodule.exports = createCtor;\n","var apply = require('./_apply'),\n    createCtor = require('./_createCtor'),\n    createHybrid = require('./_createHybrid'),\n    createRecurry = require('./_createRecurry'),\n    getHolder = require('./_getHolder'),\n    replaceHolders = require('./_replaceHolders'),\n    root = require('./_root');\n\n/**\n * Creates a function that wraps `func` to enable currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {number} arity The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createCurry(func, bitmask, arity) {\n  var Ctor = createCtor(func);\n\n  function wrapper() {\n    var length = arguments.length,\n        args = Array(length),\n        index = length,\n        placeholder = getHolder(wrapper);\n\n    while (index--) {\n      args[index] = arguments[index];\n    }\n    var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n      ? []\n      : replaceHolders(args, placeholder);\n\n    length -= holders.length;\n    if (length < arity) {\n      return createRecurry(\n        func, bitmask, createHybrid, wrapper.placeholder, undefined,\n        args, holders, undefined, undefined, arity - length);\n    }\n    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n    return apply(fn, this, args);\n  }\n  return wrapper;\n}\n\nmodule.exports = createCurry;\n","var baseIteratee = require('./_baseIteratee'),\n    isArrayLike = require('./isArrayLike'),\n    keys = require('./keys');\n\n/**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n  return function(collection, predicate, fromIndex) {\n    var iterable = Object(collection);\n    if (!isArrayLike(collection)) {\n      var iteratee = baseIteratee(predicate, 3);\n      collection = keys(collection);\n      predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n    }\n    var index = findIndexFunc(collection, predicate, fromIndex);\n    return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n  };\n}\n\nmodule.exports = createFind;\n","var LodashWrapper = require('./_LodashWrapper'),\n    flatRest = require('./_flatRest'),\n    getData = require('./_getData'),\n    getFuncName = require('./_getFuncName'),\n    isArray = require('./isArray'),\n    isLaziable = require('./_isLaziable');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_CURRY_FLAG = 8,\n    WRAP_PARTIAL_FLAG = 32,\n    WRAP_ARY_FLAG = 128,\n    WRAP_REARG_FLAG = 256;\n\n/**\n * Creates a `_.flow` or `_.flowRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new flow function.\n */\nfunction createFlow(fromRight) {\n  return flatRest(function(funcs) {\n    var length = funcs.length,\n        index = length,\n        prereq = LodashWrapper.prototype.thru;\n\n    if (fromRight) {\n      funcs.reverse();\n    }\n    while (index--) {\n      var func = funcs[index];\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n        var wrapper = new LodashWrapper([], true);\n      }\n    }\n    index = wrapper ? index : length;\n    while (++index < length) {\n      func = funcs[index];\n\n      var funcName = getFuncName(func),\n          data = funcName == 'wrapper' ? getData(func) : undefined;\n\n      if (data && isLaziable(data[0]) &&\n            data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n            !data[4].length && data[9] == 1\n          ) {\n        wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n      } else {\n        wrapper = (func.length == 1 && isLaziable(func))\n          ? wrapper[funcName]()\n          : wrapper.thru(func);\n      }\n    }\n    return function() {\n      var args = arguments,\n          value = args[0];\n\n      if (wrapper && args.length == 1 && isArray(value)) {\n        return wrapper.plant(value).value();\n      }\n      var index = 0,\n          result = length ? funcs[index].apply(this, args) : value;\n\n      while (++index < length) {\n        result = funcs[index].call(this, result);\n      }\n      return result;\n    };\n  });\n}\n\nmodule.exports = createFlow;\n","var composeArgs = require('./_composeArgs'),\n    composeArgsRight = require('./_composeArgsRight'),\n    countHolders = require('./_countHolders'),\n    createCtor = require('./_createCtor'),\n    createRecurry = require('./_createRecurry'),\n    getHolder = require('./_getHolder'),\n    reorder = require('./_reorder'),\n    replaceHolders = require('./_replaceHolders'),\n    root = require('./_root');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1,\n    WRAP_BIND_KEY_FLAG = 2,\n    WRAP_CURRY_FLAG = 8,\n    WRAP_CURRY_RIGHT_FLAG = 16,\n    WRAP_ARY_FLAG = 128,\n    WRAP_FLIP_FLAG = 512;\n\n/**\n * Creates a function that wraps `func` to invoke it with optional `this`\n * binding of `thisArg`, partial application, and currying.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n *  the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [partialsRight] The arguments to append to those provided\n *  to the new function.\n * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n  var isAry = bitmask & WRAP_ARY_FLAG,\n      isBind = bitmask & WRAP_BIND_FLAG,\n      isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n      isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n      isFlip = bitmask & WRAP_FLIP_FLAG,\n      Ctor = isBindKey ? undefined : createCtor(func);\n\n  function wrapper() {\n    var length = arguments.length,\n        args = Array(length),\n        index = length;\n\n    while (index--) {\n      args[index] = arguments[index];\n    }\n    if (isCurried) {\n      var placeholder = getHolder(wrapper),\n          holdersCount = countHolders(args, placeholder);\n    }\n    if (partials) {\n      args = composeArgs(args, partials, holders, isCurried);\n    }\n    if (partialsRight) {\n      args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n    }\n    length -= holdersCount;\n    if (isCurried && length < arity) {\n      var newHolders = replaceHolders(args, placeholder);\n      return createRecurry(\n        func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n        args, newHolders, argPos, ary, arity - length\n      );\n    }\n    var thisBinding = isBind ? thisArg : this,\n        fn = isBindKey ? thisBinding[func] : func;\n\n    length = args.length;\n    if (argPos) {\n      args = reorder(args, argPos);\n    } else if (isFlip && length > 1) {\n      args.reverse();\n    }\n    if (isAry && ary < length) {\n      args.length = ary;\n    }\n    if (this && this !== root && this instanceof wrapper) {\n      fn = Ctor || createCtor(fn);\n    }\n    return fn.apply(thisBinding, args);\n  }\n  return wrapper;\n}\n\nmodule.exports = createHybrid;\n","var baseInverter = require('./_baseInverter');\n\n/**\n * Creates a function like `_.invertBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} toIteratee The function to resolve iteratees.\n * @returns {Function} Returns the new inverter function.\n */\nfunction createInverter(setter, toIteratee) {\n  return function(object, iteratee) {\n    return baseInverter(object, setter, toIteratee(iteratee), {});\n  };\n}\n\nmodule.exports = createInverter;\n","var apply = require('./_apply'),\n    createCtor = require('./_createCtor'),\n    root = require('./_root');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1;\n\n/**\n * Creates a function that wraps `func` to invoke it with the `this` binding\n * of `thisArg` and `partials` prepended to the arguments it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} partials The arguments to prepend to those provided to\n *  the new function.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createPartial(func, bitmask, thisArg, partials) {\n  var isBind = bitmask & WRAP_BIND_FLAG,\n      Ctor = createCtor(func);\n\n  function wrapper() {\n    var argsIndex = -1,\n        argsLength = arguments.length,\n        leftIndex = -1,\n        leftLength = partials.length,\n        args = Array(leftLength + argsLength),\n        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n    while (++leftIndex < leftLength) {\n      args[leftIndex] = partials[leftIndex];\n    }\n    while (argsLength--) {\n      args[leftIndex++] = arguments[++argsIndex];\n    }\n    return apply(fn, isBind ? thisArg : this, args);\n  }\n  return wrapper;\n}\n\nmodule.exports = createPartial;\n","var baseRange = require('./_baseRange'),\n    isIterateeCall = require('./_isIterateeCall'),\n    toFinite = require('./toFinite');\n\n/**\n * Creates a `_.range` or `_.rangeRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new range function.\n */\nfunction createRange(fromRight) {\n  return function(start, end, step) {\n    if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n      end = step = undefined;\n    }\n    // Ensure the sign of `-0` is preserved.\n    start = toFinite(start);\n    if (end === undefined) {\n      end = start;\n      start = 0;\n    } else {\n      end = toFinite(end);\n    }\n    step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n    return baseRange(start, end, step, fromRight);\n  };\n}\n\nmodule.exports = createRange;\n","var isLaziable = require('./_isLaziable'),\n    setData = require('./_setData'),\n    setWrapToString = require('./_setWrapToString');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1,\n    WRAP_BIND_KEY_FLAG = 2,\n    WRAP_CURRY_BOUND_FLAG = 4,\n    WRAP_CURRY_FLAG = 8,\n    WRAP_PARTIAL_FLAG = 32,\n    WRAP_PARTIAL_RIGHT_FLAG = 64;\n\n/**\n * Creates a function that wraps `func` to continue currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {Function} wrapFunc The function to create the `func` wrapper.\n * @param {*} placeholder The placeholder value.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n *  the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n  var isCurry = bitmask & WRAP_CURRY_FLAG,\n      newHolders = isCurry ? holders : undefined,\n      newHoldersRight = isCurry ? undefined : holders,\n      newPartials = isCurry ? partials : undefined,\n      newPartialsRight = isCurry ? undefined : partials;\n\n  bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n  bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n  if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n    bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n  }\n  var newData = [\n    func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n    newHoldersRight, argPos, ary, arity\n  ];\n\n  var result = wrapFunc.apply(undefined, newData);\n  if (isLaziable(func)) {\n    setData(result, newData);\n  }\n  result.placeholder = placeholder;\n  return setWrapToString(result, func, bitmask);\n}\n\nmodule.exports = createRecurry;\n","var root = require('./_root'),\n    toInteger = require('./toInteger'),\n    toNumber = require('./toNumber'),\n    toString = require('./toString');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsFinite = root.isFinite,\n    nativeMin = Math.min;\n\n/**\n * Creates a function like `_.round`.\n *\n * @private\n * @param {string} methodName The name of the `Math` method to use when rounding.\n * @returns {Function} Returns the new round function.\n */\nfunction createRound(methodName) {\n  var func = Math[methodName];\n  return function(number, precision) {\n    number = toNumber(number);\n    precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n    if (precision && nativeIsFinite(number)) {\n      // Shift with exponential notation to avoid floating-point issues.\n      // See [MDN](https://mdn.io/round#Examples) for more details.\n      var pair = (toString(number) + 'e').split('e'),\n          value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n      pair = (toString(value) + 'e').split('e');\n      return +(pair[0] + 'e' + (+pair[1] - precision));\n    }\n    return func(number);\n  };\n}\n\nmodule.exports = createRound;\n","var Set = require('./_Set'),\n    noop = require('./noop'),\n    setToArray = require('./_setToArray');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\nvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n  return new Set(values);\n};\n\nmodule.exports = createSet;\n","var baseSetData = require('./_baseSetData'),\n    createBind = require('./_createBind'),\n    createCurry = require('./_createCurry'),\n    createHybrid = require('./_createHybrid'),\n    createPartial = require('./_createPartial'),\n    getData = require('./_getData'),\n    mergeData = require('./_mergeData'),\n    setData = require('./_setData'),\n    setWrapToString = require('./_setWrapToString'),\n    toInteger = require('./toInteger');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1,\n    WRAP_BIND_KEY_FLAG = 2,\n    WRAP_CURRY_FLAG = 8,\n    WRAP_CURRY_RIGHT_FLAG = 16,\n    WRAP_PARTIAL_FLAG = 32,\n    WRAP_PARTIAL_RIGHT_FLAG = 64;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates a function that either curries or invokes `func` with optional\n * `this` binding and partially applied arguments.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags.\n *    1 - `_.bind`\n *    2 - `_.bindKey`\n *    4 - `_.curry` or `_.curryRight` of a bound function\n *    8 - `_.curry`\n *   16 - `_.curryRight`\n *   32 - `_.partial`\n *   64 - `_.partialRight`\n *  128 - `_.rearg`\n *  256 - `_.ary`\n *  512 - `_.flip`\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to be partially applied.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\nfunction createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n  var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n  if (!isBindKey && typeof func != 'function') {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  var length = partials ? partials.length : 0;\n  if (!length) {\n    bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n    partials = holders = undefined;\n  }\n  ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n  arity = arity === undefined ? arity : toInteger(arity);\n  length -= holders ? holders.length : 0;\n\n  if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n    var partialsRight = partials,\n        holdersRight = holders;\n\n    partials = holders = undefined;\n  }\n  var data = isBindKey ? undefined : getData(func);\n\n  var newData = [\n    func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n    argPos, ary, arity\n  ];\n\n  if (data) {\n    mergeData(newData, data);\n  }\n  func = newData[0];\n  bitmask = newData[1];\n  thisArg = newData[2];\n  partials = newData[3];\n  holders = newData[4];\n  arity = newData[9] = newData[9] === undefined\n    ? (isBindKey ? 0 : func.length)\n    : nativeMax(newData[9] - length, 0);\n\n  if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n    bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n  }\n  if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n    var result = createBind(func, bitmask, thisArg);\n  } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n    result = createCurry(func, bitmask, arity);\n  } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n    result = createPartial(func, bitmask, thisArg, partials);\n  } else {\n    result = createHybrid.apply(undefined, newData);\n  }\n  var setter = data ? baseSetData : setData;\n  return setWrapToString(setter(result, newData), func, bitmask);\n}\n\nmodule.exports = createWrap;\n","var basePropertyOf = require('./_basePropertyOf');\n\n/** Used to map Latin Unicode letters to basic Latin letters. */\nvar deburredLetters = {\n  // Latin-1 Supplement block.\n  '\\xc0': 'A',  '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n  '\\xe0': 'a',  '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n  '\\xc7': 'C',  '\\xe7': 'c',\n  '\\xd0': 'D',  '\\xf0': 'd',\n  '\\xc8': 'E',  '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n  '\\xe8': 'e',  '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n  '\\xcc': 'I',  '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n  '\\xec': 'i',  '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n  '\\xd1': 'N',  '\\xf1': 'n',\n  '\\xd2': 'O',  '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n  '\\xf2': 'o',  '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n  '\\xd9': 'U',  '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n  '\\xf9': 'u',  '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n  '\\xdd': 'Y',  '\\xfd': 'y', '\\xff': 'y',\n  '\\xc6': 'Ae', '\\xe6': 'ae',\n  '\\xde': 'Th', '\\xfe': 'th',\n  '\\xdf': 'ss',\n  // Latin Extended-A block.\n  '\\u0100': 'A',  '\\u0102': 'A', '\\u0104': 'A',\n  '\\u0101': 'a',  '\\u0103': 'a', '\\u0105': 'a',\n  '\\u0106': 'C',  '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n  '\\u0107': 'c',  '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n  '\\u010e': 'D',  '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n  '\\u0112': 'E',  '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n  '\\u0113': 'e',  '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n  '\\u011c': 'G',  '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n  '\\u011d': 'g',  '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n  '\\u0124': 'H',  '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n  '\\u0128': 'I',  '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n  '\\u0129': 'i',  '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n  '\\u0134': 'J',  '\\u0135': 'j',\n  '\\u0136': 'K',  '\\u0137': 'k', '\\u0138': 'k',\n  '\\u0139': 'L',  '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n  '\\u013a': 'l',  '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n  '\\u0143': 'N',  '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n  '\\u0144': 'n',  '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n  '\\u014c': 'O',  '\\u014e': 'O', '\\u0150': 'O',\n  '\\u014d': 'o',  '\\u014f': 'o', '\\u0151': 'o',\n  '\\u0154': 'R',  '\\u0156': 'R', '\\u0158': 'R',\n  '\\u0155': 'r',  '\\u0157': 'r', '\\u0159': 'r',\n  '\\u015a': 'S',  '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n  '\\u015b': 's',  '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n  '\\u0162': 'T',  '\\u0164': 'T', '\\u0166': 'T',\n  '\\u0163': 't',  '\\u0165': 't', '\\u0167': 't',\n  '\\u0168': 'U',  '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n  '\\u0169': 'u',  '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n  '\\u0174': 'W',  '\\u0175': 'w',\n  '\\u0176': 'Y',  '\\u0177': 'y', '\\u0178': 'Y',\n  '\\u0179': 'Z',  '\\u017b': 'Z', '\\u017d': 'Z',\n  '\\u017a': 'z',  '\\u017c': 'z', '\\u017e': 'z',\n  '\\u0132': 'IJ', '\\u0133': 'ij',\n  '\\u0152': 'Oe', '\\u0153': 'oe',\n  '\\u0149': \"'n\", '\\u017f': 's'\n};\n\n/**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\nvar deburrLetter = basePropertyOf(deburredLetters);\n\nmodule.exports = deburrLetter;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n  try {\n    var func = getNative(Object, 'defineProperty');\n    func({}, '', {});\n    return func;\n  } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var SetCache = require('./_SetCache'),\n    arraySome = require('./_arraySome'),\n    cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n      arrLength = array.length,\n      othLength = other.length;\n\n  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n    return false;\n  }\n  // Check that cyclic values are equal.\n  var arrStacked = stack.get(array);\n  var othStacked = stack.get(other);\n  if (arrStacked && othStacked) {\n    return arrStacked == other && othStacked == array;\n  }\n  var index = -1,\n      result = true,\n      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n  stack.set(array, other);\n  stack.set(other, array);\n\n  // Ignore non-index properties.\n  while (++index < arrLength) {\n    var arrValue = array[index],\n        othValue = other[index];\n\n    if (customizer) {\n      var compared = isPartial\n        ? customizer(othValue, arrValue, index, other, array, stack)\n        : customizer(arrValue, othValue, index, array, other, stack);\n    }\n    if (compared !== undefined) {\n      if (compared) {\n        continue;\n      }\n      result = false;\n      break;\n    }\n    // Recursively compare arrays (susceptible to call stack limits).\n    if (seen) {\n      if (!arraySome(other, function(othValue, othIndex) {\n            if (!cacheHas(seen, othIndex) &&\n                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n              return seen.push(othIndex);\n            }\n          })) {\n        result = false;\n        break;\n      }\n    } else if (!(\n          arrValue === othValue ||\n            equalFunc(arrValue, othValue, bitmask, customizer, stack)\n        )) {\n      result = false;\n      break;\n    }\n  }\n  stack['delete'](array);\n  stack['delete'](other);\n  return result;\n}\n\nmodule.exports = equalArrays;\n","var Symbol = require('./_Symbol'),\n    Uint8Array = require('./_Uint8Array'),\n    eq = require('./eq'),\n    equalArrays = require('./_equalArrays'),\n    mapToArray = require('./_mapToArray'),\n    setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n  switch (tag) {\n    case dataViewTag:\n      if ((object.byteLength != other.byteLength) ||\n          (object.byteOffset != other.byteOffset)) {\n        return false;\n      }\n      object = object.buffer;\n      other = other.buffer;\n\n    case arrayBufferTag:\n      if ((object.byteLength != other.byteLength) ||\n          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n        return false;\n      }\n      return true;\n\n    case boolTag:\n    case dateTag:\n    case numberTag:\n      // Coerce booleans to `1` or `0` and dates to milliseconds.\n      // Invalid dates are coerced to `NaN`.\n      return eq(+object, +other);\n\n    case errorTag:\n      return object.name == other.name && object.message == other.message;\n\n    case regexpTag:\n    case stringTag:\n      // Coerce regexes to strings and treat strings, primitives and objects,\n      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n      // for more details.\n      return object == (other + '');\n\n    case mapTag:\n      var convert = mapToArray;\n\n    case setTag:\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n      convert || (convert = setToArray);\n\n      if (object.size != other.size && !isPartial) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(object);\n      if (stacked) {\n        return stacked == other;\n      }\n      bitmask |= COMPARE_UNORDERED_FLAG;\n\n      // Recursively compare objects (susceptible to call stack limits).\n      stack.set(object, other);\n      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n      stack['delete'](object);\n      return result;\n\n    case symbolTag:\n      if (symbolValueOf) {\n        return symbolValueOf.call(object) == symbolValueOf.call(other);\n      }\n  }\n  return false;\n}\n\nmodule.exports = equalByTag;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n      objProps = getAllKeys(object),\n      objLength = objProps.length,\n      othProps = getAllKeys(other),\n      othLength = othProps.length;\n\n  if (objLength != othLength && !isPartial) {\n    return false;\n  }\n  var index = objLength;\n  while (index--) {\n    var key = objProps[index];\n    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n      return false;\n    }\n  }\n  // Check that cyclic values are equal.\n  var objStacked = stack.get(object);\n  var othStacked = stack.get(other);\n  if (objStacked && othStacked) {\n    return objStacked == other && othStacked == object;\n  }\n  var result = true;\n  stack.set(object, other);\n  stack.set(other, object);\n\n  var skipCtor = isPartial;\n  while (++index < objLength) {\n    key = objProps[index];\n    var objValue = object[key],\n        othValue = other[key];\n\n    if (customizer) {\n      var compared = isPartial\n        ? customizer(othValue, objValue, key, other, object, stack)\n        : customizer(objValue, othValue, key, object, other, stack);\n    }\n    // Recursively compare objects (susceptible to call stack limits).\n    if (!(compared === undefined\n          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n          : compared\n        )) {\n      result = false;\n      break;\n    }\n    skipCtor || (skipCtor = key == 'constructor');\n  }\n  if (result && !skipCtor) {\n    var objCtor = object.constructor,\n        othCtor = other.constructor;\n\n    // Non `Object` object instances with different constructors are not equal.\n    if (objCtor != othCtor &&\n        ('constructor' in object && 'constructor' in other) &&\n        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n          typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n      result = false;\n    }\n  }\n  stack['delete'](object);\n  stack['delete'](other);\n  return result;\n}\n\nmodule.exports = equalObjects;\n","var flatten = require('./flatten'),\n    overRest = require('./_overRest'),\n    setToString = require('./_setToString');\n\n/**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\nfunction flatRest(func) {\n  return setToString(overRest(func, undefined, flatten), func + '');\n}\n\nmodule.exports = flatRest;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n    getSymbols = require('./_getSymbols'),\n    keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n  return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n    getSymbolsIn = require('./_getSymbolsIn'),\n    keysIn = require('./keysIn');\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n  return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nmodule.exports = getAllKeysIn;\n","var metaMap = require('./_metaMap'),\n    noop = require('./noop');\n\n/**\n * Gets metadata for `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {*} Returns the metadata for `func`.\n */\nvar getData = !metaMap ? noop : function(func) {\n  return metaMap.get(func);\n};\n\nmodule.exports = getData;\n","var realNames = require('./_realNames');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the name of `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {string} Returns the function name.\n */\nfunction getFuncName(func) {\n  var result = (func.name + ''),\n      array = realNames[result],\n      length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n  while (length--) {\n    var data = array[length],\n        otherFunc = data.func;\n    if (otherFunc == null || otherFunc == func) {\n      return data.name;\n    }\n  }\n  return result;\n}\n\nmodule.exports = getFuncName;\n","/**\n * Gets the argument placeholder value for `func`.\n *\n * @private\n * @param {Function} func The function to inspect.\n * @returns {*} Returns the placeholder value.\n */\nfunction getHolder(func) {\n  var object = func;\n  return object.placeholder;\n}\n\nmodule.exports = getHolder;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n  var data = map.__data__;\n  return isKeyable(key)\n    ? data[typeof key == 'string' ? 'string' : 'hash']\n    : data.map;\n}\n\nmodule.exports = getMapData;\n","var isStrictComparable = require('./_isStrictComparable'),\n    keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n  var result = keys(object),\n      length = result.length;\n\n  while (length--) {\n    var key = result[length],\n        value = object[key];\n\n    result[length] = [key, value, isStrictComparable(value)];\n  }\n  return result;\n}\n\nmodule.exports = getMatchData;\n","var baseIsNative = require('./_baseIsNative'),\n    getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = getValue(object, key);\n  return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n  var isOwn = hasOwnProperty.call(value, symToStringTag),\n      tag = value[symToStringTag];\n\n  try {\n    value[symToStringTag] = undefined;\n    var unmasked = true;\n  } catch (e) {}\n\n  var result = nativeObjectToString.call(value);\n  if (unmasked) {\n    if (isOwn) {\n      value[symToStringTag] = tag;\n    } else {\n      delete value[symToStringTag];\n    }\n  }\n  return result;\n}\n\nmodule.exports = getRawTag;\n","var arrayFilter = require('./_arrayFilter'),\n    stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n  if (object == null) {\n    return [];\n  }\n  object = Object(object);\n  return arrayFilter(nativeGetSymbols(object), function(symbol) {\n    return propertyIsEnumerable.call(object, symbol);\n  });\n};\n\nmodule.exports = getSymbols;\n","var arrayPush = require('./_arrayPush'),\n    getPrototype = require('./_getPrototype'),\n    getSymbols = require('./_getSymbols'),\n    stubArray = require('./stubArray');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n  var result = [];\n  while (object) {\n    arrayPush(result, getSymbols(object));\n    object = getPrototype(object);\n  }\n  return result;\n};\n\nmodule.exports = getSymbolsIn;\n","var DataView = require('./_DataView'),\n    Map = require('./_Map'),\n    Promise = require('./_Promise'),\n    Set = require('./_Set'),\n    WeakMap = require('./_WeakMap'),\n    baseGetTag = require('./_baseGetTag'),\n    toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n    objectTag = '[object Object]',\n    promiseTag = '[object Promise]',\n    setTag = '[object Set]',\n    weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n    mapCtorString = toSource(Map),\n    promiseCtorString = toSource(Promise),\n    setCtorString = toSource(Set),\n    weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n    (Map && getTag(new Map) != mapTag) ||\n    (Promise && getTag(Promise.resolve()) != promiseTag) ||\n    (Set && getTag(new Set) != setTag) ||\n    (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n  getTag = function(value) {\n    var result = baseGetTag(value),\n        Ctor = result == objectTag ? value.constructor : undefined,\n        ctorString = Ctor ? toSource(Ctor) : '';\n\n    if (ctorString) {\n      switch (ctorString) {\n        case dataViewCtorString: return dataViewTag;\n        case mapCtorString: return mapTag;\n        case promiseCtorString: return promiseTag;\n        case setCtorString: return setTag;\n        case weakMapCtorString: return weakMapTag;\n      }\n    }\n    return result;\n  };\n}\n\nmodule.exports = getTag;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n  return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","/** Used to match wrap detail comments. */\nvar reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n    reSplitDetails = /,? & /;\n\n/**\n * Extracts wrapper details from the `source` body comment.\n *\n * @private\n * @param {string} source The source to inspect.\n * @returns {Array} Returns the wrapper details.\n */\nfunction getWrapDetails(source) {\n  var match = source.match(reWrapDetails);\n  return match ? match[1].split(reSplitDetails) : [];\n}\n\nmodule.exports = getWrapDetails;\n","var castPath = require('./_castPath'),\n    isArguments = require('./isArguments'),\n    isArray = require('./isArray'),\n    isIndex = require('./_isIndex'),\n    isLength = require('./isLength'),\n    toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n  path = castPath(path, object);\n\n  var index = -1,\n      length = path.length,\n      result = false;\n\n  while (++index < length) {\n    var key = toKey(path[index]);\n    if (!(result = object != null && hasFunc(object, key))) {\n      break;\n    }\n    object = object[key];\n  }\n  if (result || ++index != length) {\n    return result;\n  }\n  length = object == null ? 0 : object.length;\n  return !!length && isLength(length) && isIndex(key, length) &&\n    (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n  return reHasUnicode.test(string);\n}\n\nmodule.exports = hasUnicode;\n","/** Used to detect strings that need a more robust regexp to match words. */\nvar reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n/**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\nfunction hasUnicodeWord(string) {\n  return reHasUnicodeWord.test(string);\n}\n\nmodule.exports = hasUnicodeWord;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n  this.__data__ = nativeCreate ? nativeCreate(null) : {};\n  this.size = 0;\n}\n\nmodule.exports = hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n  var result = this.has(key) && delete this.__data__[key];\n  this.size -= result ? 1 : 0;\n  return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n  var data = this.__data__;\n  if (nativeCreate) {\n    var result = data[key];\n    return result === HASH_UNDEFINED ? undefined : result;\n  }\n  return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n  var data = this.__data__;\n  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n  var data = this.__data__;\n  this.size += this.has(key) ? 0 : 1;\n  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n  return this;\n}\n\nmodule.exports = hashSet;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n  var length = array.length,\n      result = new array.constructor(length);\n\n  // Add properties assigned by `RegExp#exec`.\n  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n    result.index = array.index;\n    result.input = array.input;\n  }\n  return result;\n}\n\nmodule.exports = initCloneArray;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer'),\n    cloneDataView = require('./_cloneDataView'),\n    cloneRegExp = require('./_cloneRegExp'),\n    cloneSymbol = require('./_cloneSymbol'),\n    cloneTypedArray = require('./_cloneTypedArray');\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n  var Ctor = object.constructor;\n  switch (tag) {\n    case arrayBufferTag:\n      return cloneArrayBuffer(object);\n\n    case boolTag:\n    case dateTag:\n      return new Ctor(+object);\n\n    case dataViewTag:\n      return cloneDataView(object, isDeep);\n\n    case float32Tag: case float64Tag:\n    case int8Tag: case int16Tag: case int32Tag:\n    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n      return cloneTypedArray(object, isDeep);\n\n    case mapTag:\n      return new Ctor;\n\n    case numberTag:\n    case stringTag:\n      return new Ctor(object);\n\n    case regexpTag:\n      return cloneRegExp(object);\n\n    case setTag:\n      return new Ctor;\n\n    case symbolTag:\n      return cloneSymbol(object);\n  }\n}\n\nmodule.exports = initCloneByTag;\n","var baseCreate = require('./_baseCreate'),\n    getPrototype = require('./_getPrototype'),\n    isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n  return (typeof object.constructor == 'function' && !isPrototype(object))\n    ? baseCreate(getPrototype(object))\n    : {};\n}\n\nmodule.exports = initCloneObject;\n","/** Used to match wrap detail comments. */\nvar reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/;\n\n/**\n * Inserts wrapper `details` in a comment at the top of the `source` body.\n *\n * @private\n * @param {string} source The source to modify.\n * @returns {Array} details The details to insert.\n * @returns {string} Returns the modified source.\n */\nfunction insertWrapDetails(source, details) {\n  var length = details.length;\n  if (!length) {\n    return source;\n  }\n  var lastIndex = length - 1;\n  details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n  details = details.join(length > 2 ? ', ' : ' ');\n  return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n}\n\nmodule.exports = insertWrapDetails;\n","var Symbol = require('./_Symbol'),\n    isArguments = require('./isArguments'),\n    isArray = require('./isArray');\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n  return isArray(value) || isArguments(value) ||\n    !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nmodule.exports = isFlattenable;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  var type = typeof value;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n\n  return !!length &&\n    (type == 'number' ||\n      (type != 'symbol' && reIsUint.test(value))) &&\n        (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","var eq = require('./eq'),\n    isArrayLike = require('./isArrayLike'),\n    isIndex = require('./_isIndex'),\n    isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n *  else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n        ? (isArrayLike(object) && isIndex(index, object.length))\n        : (type == 'string' && index in object)\n      ) {\n    return eq(object[index], value);\n  }\n  return false;\n}\n\nmodule.exports = isIterateeCall;\n","var isArray = require('./isArray'),\n    isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n    reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n  if (isArray(value)) {\n    return false;\n  }\n  var type = typeof value;\n  if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n      value == null || isSymbol(value)) {\n    return true;\n  }\n  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n    (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n  var type = typeof value;\n  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n    ? (value !== '__proto__')\n    : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var LazyWrapper = require('./_LazyWrapper'),\n    getData = require('./_getData'),\n    getFuncName = require('./_getFuncName'),\n    lodash = require('./wrapperLodash');\n\n/**\n * Checks if `func` has a lazy counterpart.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n *  else `false`.\n */\nfunction isLaziable(func) {\n  var funcName = getFuncName(func),\n      other = lodash[funcName];\n\n  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n    return false;\n  }\n  if (func === other) {\n    return true;\n  }\n  var data = getData(other);\n  return !!data && func === data[0];\n}\n\nmodule.exports = isLaziable;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n  return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n  return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n  var Ctor = value && value.constructor,\n      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n  return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n *  equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n  return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n  this.__data__ = [];\n  this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  if (index < 0) {\n    return false;\n  }\n  var lastIndex = data.length - 1;\n  if (index == lastIndex) {\n    data.pop();\n  } else {\n    splice.call(data, index, 1);\n  }\n  --this.size;\n  return true;\n}\n\nmodule.exports = listCacheDelete;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n  return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  if (index < 0) {\n    ++this.size;\n    data.push([key, value]);\n  } else {\n    data[index][1] = value;\n  }\n  return this;\n}\n\nmodule.exports = listCacheSet;\n","var Hash = require('./_Hash'),\n    ListCache = require('./_ListCache'),\n    Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n  this.size = 0;\n  this.__data__ = {\n    'hash': new Hash,\n    'map': new (Map || ListCache),\n    'string': new Hash\n  };\n}\n\nmodule.exports = mapCacheClear;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n  var result = getMapData(this, key)['delete'](key);\n  this.size -= result ? 1 : 0;\n  return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n  return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n  return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n  var data = getMapData(this, key),\n      size = data.size;\n\n  data.set(key, value);\n  this.size += data.size == size ? 0 : 1;\n  return this;\n}\n\nmodule.exports = mapCacheSet;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n  var index = -1,\n      result = Array(map.size);\n\n  map.forEach(function(value, key) {\n    result[++index] = [key, value];\n  });\n  return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n  return function(object) {\n    if (object == null) {\n      return false;\n    }\n    return object[key] === srcValue &&\n      (srcValue !== undefined || (key in Object(object)));\n  };\n}\n\nmodule.exports = matchesStrictComparable;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n  var result = memoize(func, function(key) {\n    if (cache.size === MAX_MEMOIZE_SIZE) {\n      cache.clear();\n    }\n    return key;\n  });\n\n  var cache = result.cache;\n  return result;\n}\n\nmodule.exports = memoizeCapped;\n","var composeArgs = require('./_composeArgs'),\n    composeArgsRight = require('./_composeArgsRight'),\n    replaceHolders = require('./_replaceHolders');\n\n/** Used as the internal argument placeholder. */\nvar PLACEHOLDER = '__lodash_placeholder__';\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1,\n    WRAP_BIND_KEY_FLAG = 2,\n    WRAP_CURRY_BOUND_FLAG = 4,\n    WRAP_CURRY_FLAG = 8,\n    WRAP_ARY_FLAG = 128,\n    WRAP_REARG_FLAG = 256;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMin = Math.min;\n\n/**\n * Merges the function metadata of `source` into `data`.\n *\n * Merging metadata reduces the number of wrappers used to invoke a function.\n * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n * may be applied regardless of execution order. Methods like `_.ary` and\n * `_.rearg` modify function arguments, making the order in which they are\n * executed important, preventing the merging of metadata. However, we make\n * an exception for a safe combined case where curried functions have `_.ary`\n * and or `_.rearg` applied.\n *\n * @private\n * @param {Array} data The destination metadata.\n * @param {Array} source The source metadata.\n * @returns {Array} Returns `data`.\n */\nfunction mergeData(data, source) {\n  var bitmask = data[1],\n      srcBitmask = source[1],\n      newBitmask = bitmask | srcBitmask,\n      isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n  var isCombo =\n    ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n    ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n    ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n  // Exit early if metadata can't be merged.\n  if (!(isCommon || isCombo)) {\n    return data;\n  }\n  // Use source `thisArg` if available.\n  if (srcBitmask & WRAP_BIND_FLAG) {\n    data[2] = source[2];\n    // Set when currying a bound function.\n    newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n  }\n  // Compose partial arguments.\n  var value = source[3];\n  if (value) {\n    var partials = data[3];\n    data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n    data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n  }\n  // Compose partial right arguments.\n  value = source[5];\n  if (value) {\n    partials = data[5];\n    data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n    data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n  }\n  // Use source `argPos` if available.\n  value = source[7];\n  if (value) {\n    data[7] = value;\n  }\n  // Use source `ary` if it's smaller.\n  if (srcBitmask & WRAP_ARY_FLAG) {\n    data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n  }\n  // Use source `arity` if one is not provided.\n  if (data[9] == null) {\n    data[9] = source[9];\n  }\n  // Use source `func` and merge bitmasks.\n  data[0] = source[0];\n  data[1] = newBitmask;\n\n  return data;\n}\n\nmodule.exports = mergeData;\n","var WeakMap = require('./_WeakMap');\n\n/** Used to store function metadata. */\nvar metaMap = WeakMap && new WeakMap;\n\nmodule.exports = metaMap;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n  var result = [];\n  if (object != null) {\n    for (var key in Object(object)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n  try {\n    // Use `util.types` for Node.js 10+.\n    var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n    if (types) {\n      return types;\n    }\n\n    // Legacy `process.binding('util')` for Node.js < 10.\n    return freeProcess && freeProcess.binding && freeProcess.binding('util');\n  } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n  return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n  return function(arg) {\n    return func(transform(arg));\n  };\n}\n\nmodule.exports = overArg;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n  return function() {\n    var args = arguments,\n        index = -1,\n        length = nativeMax(args.length - start, 0),\n        array = Array(length);\n\n    while (++index < length) {\n      array[index] = args[start + index];\n    }\n    index = -1;\n    var otherArgs = Array(start + 1);\n    while (++index < start) {\n      otherArgs[index] = args[index];\n    }\n    otherArgs[start] = transform(array);\n    return apply(func, this, otherArgs);\n  };\n}\n\nmodule.exports = overRest;\n","var baseGet = require('./_baseGet'),\n    baseSlice = require('./_baseSlice');\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n  return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nmodule.exports = parent;\n","/** Used to lookup unminified function names. */\nvar realNames = {};\n\nmodule.exports = realNames;\n","var copyArray = require('./_copyArray'),\n    isIndex = require('./_isIndex');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMin = Math.min;\n\n/**\n * Reorder `array` according to the specified indexes where the element at\n * the first index is assigned as the first element, the element at\n * the second index is assigned as the second element, and so on.\n *\n * @private\n * @param {Array} array The array to reorder.\n * @param {Array} indexes The arranged array indexes.\n * @returns {Array} Returns `array`.\n */\nfunction reorder(array, indexes) {\n  var arrLength = array.length,\n      length = nativeMin(indexes.length, arrLength),\n      oldArray = copyArray(array);\n\n  while (length--) {\n    var index = indexes[length];\n    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n  }\n  return array;\n}\n\nmodule.exports = reorder;\n","/** Used as the internal argument placeholder. */\nvar PLACEHOLDER = '__lodash_placeholder__';\n\n/**\n * Replaces all `placeholder` elements in `array` with an internal placeholder\n * and returns an array of their indexes.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {*} placeholder The placeholder to replace.\n * @returns {Array} Returns the new array of placeholder indexes.\n */\nfunction replaceHolders(array, placeholder) {\n  var index = -1,\n      length = array.length,\n      resIndex = 0,\n      result = [];\n\n  while (++index < length) {\n    var value = array[index];\n    if (value === placeholder || value === PLACEHOLDER) {\n      array[index] = PLACEHOLDER;\n      result[resIndex++] = index;\n    }\n  }\n  return result;\n}\n\nmodule.exports = replaceHolders;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n  if (key === 'constructor' && typeof object[key] === 'function') {\n    return;\n  }\n\n  if (key == '__proto__') {\n    return;\n  }\n\n  return object[key];\n}\n\nmodule.exports = safeGet;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n  this.__data__.set(value, HASH_UNDEFINED);\n  return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n  return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","var baseSetData = require('./_baseSetData'),\n    shortOut = require('./_shortOut');\n\n/**\n * Sets metadata for `func`.\n *\n * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n * period of time, it will trip its breaker and transition to an identity\n * function to avoid garbage collection pauses in V8. See\n * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n * for more details.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\nvar setData = shortOut(baseSetData);\n\nmodule.exports = setData;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n  var index = -1,\n      result = Array(set.size);\n\n  set.forEach(function(value) {\n    result[++index] = value;\n  });\n  return result;\n}\n\nmodule.exports = setToArray;\n","var baseSetToString = require('./_baseSetToString'),\n    shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var getWrapDetails = require('./_getWrapDetails'),\n    insertWrapDetails = require('./_insertWrapDetails'),\n    setToString = require('./_setToString'),\n    updateWrapDetails = require('./_updateWrapDetails');\n\n/**\n * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n * with wrapper details in a comment at the top of the source body.\n *\n * @private\n * @param {Function} wrapper The function to modify.\n * @param {Function} reference The reference function.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Function} Returns `wrapper`.\n */\nfunction setWrapToString(wrapper, reference, bitmask) {\n  var source = (reference + '');\n  return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n}\n\nmodule.exports = setWrapToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n    HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n  var count = 0,\n      lastCalled = 0;\n\n  return function() {\n    var stamp = nativeNow(),\n        remaining = HOT_SPAN - (stamp - lastCalled);\n\n    lastCalled = stamp;\n    if (remaining > 0) {\n      if (++count >= HOT_COUNT) {\n        return arguments[0];\n      }\n    } else {\n      count = 0;\n    }\n    return func.apply(undefined, arguments);\n  };\n}\n\nmodule.exports = shortOut;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n  this.__data__ = new ListCache;\n  this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n  var data = this.__data__,\n      result = data['delete'](key);\n\n  this.size = data.size;\n  return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n  return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n  return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n    Map = require('./_Map'),\n    MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n  var data = this.__data__;\n  if (data instanceof ListCache) {\n    var pairs = data.__data__;\n    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n      pairs.push([key, value]);\n      this.size = ++data.size;\n      return this;\n    }\n    data = this.__data__ = new MapCache(pairs);\n  }\n  data.set(key, value);\n  this.size = data.size;\n  return this;\n}\n\nmodule.exports = stackSet;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n  var index = fromIndex - 1,\n      length = array.length;\n\n  while (++index < length) {\n    if (array[index] === value) {\n      return index;\n    }\n  }\n  return -1;\n}\n\nmodule.exports = strictIndexOf;\n","var asciiSize = require('./_asciiSize'),\n    hasUnicode = require('./_hasUnicode'),\n    unicodeSize = require('./_unicodeSize');\n\n/**\n * Gets the number of symbols in `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the string size.\n */\nfunction stringSize(string) {\n  return hasUnicode(string)\n    ? unicodeSize(string)\n    : asciiSize(string);\n}\n\nmodule.exports = stringSize;\n","var asciiToArray = require('./_asciiToArray'),\n    hasUnicode = require('./_hasUnicode'),\n    unicodeToArray = require('./_unicodeToArray');\n\n/**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction stringToArray(string) {\n  return hasUnicode(string)\n    ? unicodeToArray(string)\n    : asciiToArray(string);\n}\n\nmodule.exports = stringToArray;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n  var result = [];\n  if (string.charCodeAt(0) === 46 /* . */) {\n    result.push('');\n  }\n  string.replace(rePropName, function(match, number, quote, subString) {\n    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n  });\n  return result;\n});\n\nmodule.exports = stringToPath;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n  if (typeof value == 'string' || isSymbol(value)) {\n    return value;\n  }\n  var result = (value + '');\n  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n  if (func != null) {\n    try {\n      return funcToString.call(func);\n    } catch (e) {}\n    try {\n      return (func + '');\n    } catch (e) {}\n  }\n  return '';\n}\n\nmodule.exports = toSource;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n    rsCombo = '[' + rsComboRange + ']',\n    rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n    rsNonAstral = '[^' + rsAstralRange + ']',\n    rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n    rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n    rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n    rsOptVar = '[' + rsVarRange + ']?',\n    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n    rsSeq = rsOptVar + reOptMod + rsOptJoin,\n    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Gets the size of a Unicode `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\nfunction unicodeSize(string) {\n  var result = reUnicode.lastIndex = 0;\n  while (reUnicode.test(string)) {\n    ++result;\n  }\n  return result;\n}\n\nmodule.exports = unicodeSize;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n    rsCombo = '[' + rsComboRange + ']',\n    rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n    rsNonAstral = '[^' + rsAstralRange + ']',\n    rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n    rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n    rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n    rsOptVar = '[' + rsVarRange + ']?',\n    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n    rsSeq = rsOptVar + reOptMod + rsOptJoin,\n    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n  return string.match(reUnicode) || [];\n}\n\nmodule.exports = unicodeToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsDingbatRange = '\\\\u2700-\\\\u27bf',\n    rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n    rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n    rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n    rsPunctuationRange = '\\\\u2000-\\\\u206f',\n    rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n    rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n    rsVarRange = '\\\\ufe0e\\\\ufe0f',\n    rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n/** Used to compose unicode capture groups. */\nvar rsApos = \"['\\u2019]\",\n    rsBreak = '[' + rsBreakRange + ']',\n    rsCombo = '[' + rsComboRange + ']',\n    rsDigits = '\\\\d+',\n    rsDingbat = '[' + rsDingbatRange + ']',\n    rsLower = '[' + rsLowerRange + ']',\n    rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n    rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n    rsNonAstral = '[^' + rsAstralRange + ']',\n    rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n    rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n    rsUpper = '[' + rsUpperRange + ']',\n    rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n    rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n    rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n    rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n    reOptMod = rsModifier + '?',\n    rsOptVar = '[' + rsVarRange + ']?',\n    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n    rsOrdLower = '\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])',\n    rsOrdUpper = '\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])',\n    rsSeq = rsOptVar + reOptMod + rsOptJoin,\n    rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;\n\n/** Used to match complex or compound words. */\nvar reUnicodeWord = RegExp([\n  rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n  rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n  rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n  rsUpper + '+' + rsOptContrUpper,\n  rsOrdUpper,\n  rsOrdLower,\n  rsDigits,\n  rsEmoji\n].join('|'), 'g');\n\n/**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction unicodeWords(string) {\n  return string.match(reUnicodeWord) || [];\n}\n\nmodule.exports = unicodeWords;\n","var arrayEach = require('./_arrayEach'),\n    arrayIncludes = require('./_arrayIncludes');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_BIND_FLAG = 1,\n    WRAP_BIND_KEY_FLAG = 2,\n    WRAP_CURRY_FLAG = 8,\n    WRAP_CURRY_RIGHT_FLAG = 16,\n    WRAP_PARTIAL_FLAG = 32,\n    WRAP_PARTIAL_RIGHT_FLAG = 64,\n    WRAP_ARY_FLAG = 128,\n    WRAP_REARG_FLAG = 256,\n    WRAP_FLIP_FLAG = 512;\n\n/** Used to associate wrap methods with their bit flags. */\nvar wrapFlags = [\n  ['ary', WRAP_ARY_FLAG],\n  ['bind', WRAP_BIND_FLAG],\n  ['bindKey', WRAP_BIND_KEY_FLAG],\n  ['curry', WRAP_CURRY_FLAG],\n  ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n  ['flip', WRAP_FLIP_FLAG],\n  ['partial', WRAP_PARTIAL_FLAG],\n  ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n  ['rearg', WRAP_REARG_FLAG]\n];\n\n/**\n * Updates wrapper `details` based on `bitmask` flags.\n *\n * @private\n * @returns {Array} details The details to modify.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Array} Returns `details`.\n */\nfunction updateWrapDetails(details, bitmask) {\n  arrayEach(wrapFlags, function(pair) {\n    var value = '_.' + pair[0];\n    if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n      details.push(value);\n    }\n  });\n  return details.sort();\n}\n\nmodule.exports = updateWrapDetails;\n","var LazyWrapper = require('./_LazyWrapper'),\n    LodashWrapper = require('./_LodashWrapper'),\n    copyArray = require('./_copyArray');\n\n/**\n * Creates a clone of `wrapper`.\n *\n * @private\n * @param {Object} wrapper The wrapper to clone.\n * @returns {Object} Returns the cloned wrapper.\n */\nfunction wrapperClone(wrapper) {\n  if (wrapper instanceof LazyWrapper) {\n    return wrapper.clone();\n  }\n  var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n  result.__actions__ = copyArray(wrapper.__actions__);\n  result.__index__  = wrapper.__index__;\n  result.__values__ = wrapper.__values__;\n  return result;\n}\n\nmodule.exports = wrapperClone;\n","var createWrap = require('./_createWrap');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_ARY_FLAG = 128;\n\n/**\n * Creates a function that invokes `func`, with up to `n` arguments,\n * ignoring any additional arguments.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @param {number} [n=func.length] The arity cap.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n * // => [6, 8, 10]\n */\nfunction ary(func, n, guard) {\n  n = guard ? undefined : n;\n  n = (func && n == null) ? func.length : n;\n  return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n}\n\nmodule.exports = ary;\n","var baseClamp = require('./_baseClamp'),\n    toNumber = require('./toNumber');\n\n/**\n * Clamps `number` within the inclusive `lower` and `upper` bounds.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Number\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n * @example\n *\n * _.clamp(-10, -5, 5);\n * // => -5\n *\n * _.clamp(10, -5, 5);\n * // => 5\n */\nfunction clamp(number, lower, upper) {\n  if (upper === undefined) {\n    upper = lower;\n    lower = undefined;\n  }\n  if (upper !== undefined) {\n    upper = toNumber(upper);\n    upper = upper === upper ? upper : 0;\n  }\n  if (lower !== undefined) {\n    lower = toNumber(lower);\n    lower = lower === lower ? lower : 0;\n  }\n  return baseClamp(toNumber(number), lower, upper);\n}\n\nmodule.exports = clamp;\n","var baseClone = require('./_baseClone');\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\nfunction clone(value) {\n  return baseClone(value, CLONE_SYMBOLS_FLAG);\n}\n\nmodule.exports = clone;\n","/**\n * Creates an array with all falsey values removed. The values `false`, `null`,\n * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to compact.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.compact([0, 1, false, 2, '', 3]);\n * // => [1, 2, 3]\n */\nfunction compact(array) {\n  var index = -1,\n      length = array == null ? 0 : array.length,\n      resIndex = 0,\n      result = [];\n\n  while (++index < length) {\n    var value = array[index];\n    if (value) {\n      result[resIndex++] = value;\n    }\n  }\n  return result;\n}\n\nmodule.exports = compact;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n  return function() {\n    return value;\n  };\n}\n\nmodule.exports = constant;\n","var createWrap = require('./_createWrap');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_CURRY_FLAG = 8;\n\n/**\n * Creates a function that accepts arguments of `func` and either invokes\n * `func` returning its result, if at least `arity` number of arguments have\n * been provided, or returns a function that accepts the remaining `func`\n * arguments, and so on. The arity of `func` may be specified if `func.length`\n * is not sufficient.\n *\n * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n *   return [a, b, c];\n * };\n *\n * var curried = _.curry(abc);\n *\n * curried(1)(2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(1)(_, 3)(2);\n * // => [1, 2, 3]\n */\nfunction curry(func, arity, guard) {\n  arity = guard ? undefined : arity;\n  var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n  result.placeholder = curry.placeholder;\n  return result;\n}\n\n// Assign default placeholders.\ncurry.placeholder = {};\n\nmodule.exports = curry;\n","var deburrLetter = require('./_deburrLetter'),\n    toString = require('./toString');\n\n/** Used to match Latin Unicode letters (excluding mathematical operators). */\nvar reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n/** Used to compose unicode character classes. */\nvar rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange;\n\n/** Used to compose unicode capture groups. */\nvar rsCombo = '[' + rsComboRange + ']';\n\n/**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\nvar reComboMark = RegExp(rsCombo, 'g');\n\n/**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('déjà vu');\n * // => 'deja vu'\n */\nfunction deburr(string) {\n  string = toString(string);\n  return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n}\n\nmodule.exports = deburr;\n","var baseDifference = require('./_baseDifference'),\n    baseFlatten = require('./_baseFlatten'),\n    baseRest = require('./_baseRest'),\n    isArrayLikeObject = require('./isArrayLikeObject');\n\n/**\n * Creates an array of `array` values not included in the other given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * **Note:** Unlike `_.pullAll`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.without, _.xor\n * @example\n *\n * _.difference([2, 1], [2, 3]);\n * // => [1]\n */\nvar difference = baseRest(function(array, values) {\n  return isArrayLikeObject(array)\n    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n    : [];\n});\n\nmodule.exports = difference;\n","var baseSlice = require('./_baseSlice'),\n    toInteger = require('./toInteger');\n\n/**\n * Creates a slice of `array` with `n` elements dropped from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.dropRight([1, 2, 3]);\n * // => [1, 2]\n *\n * _.dropRight([1, 2, 3], 2);\n * // => [1]\n *\n * _.dropRight([1, 2, 3], 5);\n * // => []\n *\n * _.dropRight([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\nfunction dropRight(array, n, guard) {\n  var length = array == null ? 0 : array.length;\n  if (!length) {\n    return [];\n  }\n  n = (guard || n === undefined) ? 1 : toInteger(n);\n  n = length - n;\n  return baseSlice(array, 0, n < 0 ? 0 : n);\n}\n\nmodule.exports = dropRight;\n","module.exports = require('./forEach');\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n  return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var toString = require('./toString');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n    reHasRegExpChar = RegExp(reRegExpChar.source);\n\n/**\n * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escapeRegExp('[lodash](https://lodash.com/)');\n * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n */\nfunction escapeRegExp(string) {\n  string = toString(string);\n  return (string && reHasRegExpChar.test(string))\n    ? string.replace(reRegExpChar, '\\\\$&')\n    : string;\n}\n\nmodule.exports = escapeRegExp;\n","var arrayEvery = require('./_arrayEvery'),\n    baseEvery = require('./_baseEvery'),\n    baseIteratee = require('./_baseIteratee'),\n    isArray = require('./isArray'),\n    isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Checks if `predicate` returns truthy for **all** elements of `collection`.\n * Iteration is stopped once `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * **Note:** This method returns `true` for\n * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n * elements of empty collections.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n *  else `false`.\n * @example\n *\n * _.every([true, 1, null, 'yes'], Boolean);\n * // => false\n *\n * var users = [\n *   { 'user': 'barney', 'age': 36, 'active': false },\n *   { 'user': 'fred',   'age': 40, 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.every(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.every(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.every(users, 'active');\n * // => false\n */\nfunction every(collection, predicate, guard) {\n  var func = isArray(collection) ? arrayEvery : baseEvery;\n  if (guard && isIterateeCall(collection, predicate, guard)) {\n    predicate = undefined;\n  }\n  return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = every;\n","var arrayFilter = require('./_arrayFilter'),\n    baseFilter = require('./_baseFilter'),\n    baseIteratee = require('./_baseIteratee'),\n    isArray = require('./isArray');\n\n/**\n * Iterates over elements of `collection`, returning an array of all elements\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike `_.remove`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n *   { 'user': 'barney', 'age': 36, 'active': true },\n *   { 'user': 'fred',   'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n *\n * // Combining several predicates using `_.overEvery` or `_.overSome`.\n * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));\n * // => objects for ['fred', 'barney']\n */\nfunction filter(collection, predicate) {\n  var func = isArray(collection) ? arrayFilter : baseFilter;\n  return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = filter;\n","var createFind = require('./_createFind'),\n    findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n *   { 'user': 'barney',  'age': 36, 'active': true },\n *   { 'user': 'fred',    'age': 40, 'active': false },\n *   { 'user': 'pebbles', 'age': 1,  'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n","var baseFindIndex = require('./_baseFindIndex'),\n    baseIteratee = require('./_baseIteratee'),\n    toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n *   { 'user': 'barney',  'active': false },\n *   { 'user': 'fred',    'active': false },\n *   { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n  var length = array == null ? 0 : array.length;\n  if (!length) {\n    return -1;\n  }\n  var index = fromIndex == null ? 0 : toInteger(fromIndex);\n  if (index < 0) {\n    index = nativeMax(length + index, 0);\n  }\n  return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","module.exports = require('./head');\n","var baseFlatten = require('./_baseFlatten');\n\n/**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\nfunction flatten(array) {\n  var length = array == null ? 0 : array.length;\n  return length ? baseFlatten(array, 1) : [];\n}\n\nmodule.exports = flatten;\n","var createFlow = require('./_createFlow');\n\n/**\n * Creates a function that returns the result of invoking the given functions\n * with the `this` binding of the created function, where each successive\n * invocation is supplied the return value of the previous.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Util\n * @param {...(Function|Function[])} [funcs] The functions to invoke.\n * @returns {Function} Returns the new composite function.\n * @see _.flowRight\n * @example\n *\n * function square(n) {\n *   return n * n;\n * }\n *\n * var addSquare = _.flow([_.add, square]);\n * addSquare(1, 2);\n * // => 9\n */\nvar flow = createFlow();\n\nmodule.exports = flow;\n","var arrayEach = require('./_arrayEach'),\n    baseEach = require('./_baseEach'),\n    castFunction = require('./_castFunction'),\n    isArray = require('./isArray');\n\n/**\n * Iterates over elements of `collection` and invokes `iteratee` for each element.\n * The iteratee is invoked with three arguments: (value, index|key, collection).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n * property are iterated like arrays. To avoid this behavior use `_.forIn`\n * or `_.forOwn` for object iteration.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias each\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEachRight\n * @example\n *\n * _.forEach([1, 2], function(value) {\n *   console.log(value);\n * });\n * // => Logs `1` then `2`.\n *\n * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n *   console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\nfunction forEach(collection, iteratee) {\n  var func = isArray(collection) ? arrayEach : baseEach;\n  return func(collection, castFunction(iteratee));\n}\n\nmodule.exports = forEach;\n","var mapping = require('./_mapping'),\n    fallbackHolder = require('./placeholder');\n\n/** Built-in value reference. */\nvar push = Array.prototype.push;\n\n/**\n * Creates a function, with an arity of `n`, that invokes `func` with the\n * arguments it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} n The arity of the new function.\n * @returns {Function} Returns the new function.\n */\nfunction baseArity(func, n) {\n  return n == 2\n    ? function(a, b) { return func.apply(undefined, arguments); }\n    : function(a) { return func.apply(undefined, arguments); };\n}\n\n/**\n * Creates a function that invokes `func`, with up to `n` arguments, ignoring\n * any additional arguments.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @param {number} n The arity cap.\n * @returns {Function} Returns the new function.\n */\nfunction baseAry(func, n) {\n  return n == 2\n    ? function(a, b) { return func(a, b); }\n    : function(a) { return func(a); };\n}\n\n/**\n * Creates a clone of `array`.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the cloned array.\n */\nfunction cloneArray(array) {\n  var length = array ? array.length : 0,\n      result = Array(length);\n\n  while (length--) {\n    result[length] = array[length];\n  }\n  return result;\n}\n\n/**\n * Creates a function that clones a given object using the assignment `func`.\n *\n * @private\n * @param {Function} func The assignment function.\n * @returns {Function} Returns the new cloner function.\n */\nfunction createCloner(func) {\n  return function(object) {\n    return func({}, object);\n  };\n}\n\n/**\n * A specialized version of `_.spread` which flattens the spread array into\n * the arguments of the invoked `func`.\n *\n * @private\n * @param {Function} func The function to spread arguments over.\n * @param {number} start The start position of the spread.\n * @returns {Function} Returns the new function.\n */\nfunction flatSpread(func, start) {\n  return function() {\n    var length = arguments.length,\n        lastIndex = length - 1,\n        args = Array(length);\n\n    while (length--) {\n      args[length] = arguments[length];\n    }\n    var array = args[start],\n        otherArgs = args.slice(0, start);\n\n    if (array) {\n      push.apply(otherArgs, array);\n    }\n    if (start != lastIndex) {\n      push.apply(otherArgs, args.slice(start + 1));\n    }\n    return func.apply(this, otherArgs);\n  };\n}\n\n/**\n * Creates a function that wraps `func` and uses `cloner` to clone the first\n * argument it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} cloner The function to clone arguments.\n * @returns {Function} Returns the new immutable function.\n */\nfunction wrapImmutable(func, cloner) {\n  return function() {\n    var length = arguments.length;\n    if (!length) {\n      return;\n    }\n    var args = Array(length);\n    while (length--) {\n      args[length] = arguments[length];\n    }\n    var result = args[0] = cloner.apply(undefined, args);\n    func.apply(undefined, args);\n    return result;\n  };\n}\n\n/**\n * The base implementation of `convert` which accepts a `util` object of methods\n * required to perform conversions.\n *\n * @param {Object} util The util object.\n * @param {string} name The name of the function to convert.\n * @param {Function} func The function to convert.\n * @param {Object} [options] The options object.\n * @param {boolean} [options.cap=true] Specify capping iteratee arguments.\n * @param {boolean} [options.curry=true] Specify currying.\n * @param {boolean} [options.fixed=true] Specify fixed arity.\n * @param {boolean} [options.immutable=true] Specify immutable operations.\n * @param {boolean} [options.rearg=true] Specify rearranging arguments.\n * @returns {Function|Object} Returns the converted function or object.\n */\nfunction baseConvert(util, name, func, options) {\n  var isLib = typeof name == 'function',\n      isObj = name === Object(name);\n\n  if (isObj) {\n    options = func;\n    func = name;\n    name = undefined;\n  }\n  if (func == null) {\n    throw new TypeError;\n  }\n  options || (options = {});\n\n  var config = {\n    'cap': 'cap' in options ? options.cap : true,\n    'curry': 'curry' in options ? options.curry : true,\n    'fixed': 'fixed' in options ? options.fixed : true,\n    'immutable': 'immutable' in options ? options.immutable : true,\n    'rearg': 'rearg' in options ? options.rearg : true\n  };\n\n  var defaultHolder = isLib ? func : fallbackHolder,\n      forceCurry = ('curry' in options) && options.curry,\n      forceFixed = ('fixed' in options) && options.fixed,\n      forceRearg = ('rearg' in options) && options.rearg,\n      pristine = isLib ? func.runInContext() : undefined;\n\n  var helpers = isLib ? func : {\n    'ary': util.ary,\n    'assign': util.assign,\n    'clone': util.clone,\n    'curry': util.curry,\n    'forEach': util.forEach,\n    'isArray': util.isArray,\n    'isError': util.isError,\n    'isFunction': util.isFunction,\n    'isWeakMap': util.isWeakMap,\n    'iteratee': util.iteratee,\n    'keys': util.keys,\n    'rearg': util.rearg,\n    'toInteger': util.toInteger,\n    'toPath': util.toPath\n  };\n\n  var ary = helpers.ary,\n      assign = helpers.assign,\n      clone = helpers.clone,\n      curry = helpers.curry,\n      each = helpers.forEach,\n      isArray = helpers.isArray,\n      isError = helpers.isError,\n      isFunction = helpers.isFunction,\n      isWeakMap = helpers.isWeakMap,\n      keys = helpers.keys,\n      rearg = helpers.rearg,\n      toInteger = helpers.toInteger,\n      toPath = helpers.toPath;\n\n  var aryMethodKeys = keys(mapping.aryMethod);\n\n  var wrappers = {\n    'castArray': function(castArray) {\n      return function() {\n        var value = arguments[0];\n        return isArray(value)\n          ? castArray(cloneArray(value))\n          : castArray.apply(undefined, arguments);\n      };\n    },\n    'iteratee': function(iteratee) {\n      return function() {\n        var func = arguments[0],\n            arity = arguments[1],\n            result = iteratee(func, arity),\n            length = result.length;\n\n        if (config.cap && typeof arity == 'number') {\n          arity = arity > 2 ? (arity - 2) : 1;\n          return (length && length <= arity) ? result : baseAry(result, arity);\n        }\n        return result;\n      };\n    },\n    'mixin': function(mixin) {\n      return function(source) {\n        var func = this;\n        if (!isFunction(func)) {\n          return mixin(func, Object(source));\n        }\n        var pairs = [];\n        each(keys(source), function(key) {\n          if (isFunction(source[key])) {\n            pairs.push([key, func.prototype[key]]);\n          }\n        });\n\n        mixin(func, Object(source));\n\n        each(pairs, function(pair) {\n          var value = pair[1];\n          if (isFunction(value)) {\n            func.prototype[pair[0]] = value;\n          } else {\n            delete func.prototype[pair[0]];\n          }\n        });\n        return func;\n      };\n    },\n    'nthArg': function(nthArg) {\n      return function(n) {\n        var arity = n < 0 ? 1 : (toInteger(n) + 1);\n        return curry(nthArg(n), arity);\n      };\n    },\n    'rearg': function(rearg) {\n      return function(func, indexes) {\n        var arity = indexes ? indexes.length : 0;\n        return curry(rearg(func, indexes), arity);\n      };\n    },\n    'runInContext': function(runInContext) {\n      return function(context) {\n        return baseConvert(util, runInContext(context), options);\n      };\n    }\n  };\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Casts `func` to a function with an arity capped iteratee if needed.\n   *\n   * @private\n   * @param {string} name The name of the function to inspect.\n   * @param {Function} func The function to inspect.\n   * @returns {Function} Returns the cast function.\n   */\n  function castCap(name, func) {\n    if (config.cap) {\n      var indexes = mapping.iterateeRearg[name];\n      if (indexes) {\n        return iterateeRearg(func, indexes);\n      }\n      var n = !isLib && mapping.iterateeAry[name];\n      if (n) {\n        return iterateeAry(func, n);\n      }\n    }\n    return func;\n  }\n\n  /**\n   * Casts `func` to a curried function if needed.\n   *\n   * @private\n   * @param {string} name The name of the function to inspect.\n   * @param {Function} func The function to inspect.\n   * @param {number} n The arity of `func`.\n   * @returns {Function} Returns the cast function.\n   */\n  function castCurry(name, func, n) {\n    return (forceCurry || (config.curry && n > 1))\n      ? curry(func, n)\n      : func;\n  }\n\n  /**\n   * Casts `func` to a fixed arity function if needed.\n   *\n   * @private\n   * @param {string} name The name of the function to inspect.\n   * @param {Function} func The function to inspect.\n   * @param {number} n The arity cap.\n   * @returns {Function} Returns the cast function.\n   */\n  function castFixed(name, func, n) {\n    if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {\n      var data = mapping.methodSpread[name],\n          start = data && data.start;\n\n      return start  === undefined ? ary(func, n) : flatSpread(func, start);\n    }\n    return func;\n  }\n\n  /**\n   * Casts `func` to an rearged function if needed.\n   *\n   * @private\n   * @param {string} name The name of the function to inspect.\n   * @param {Function} func The function to inspect.\n   * @param {number} n The arity of `func`.\n   * @returns {Function} Returns the cast function.\n   */\n  function castRearg(name, func, n) {\n    return (config.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name]))\n      ? rearg(func, mapping.methodRearg[name] || mapping.aryRearg[n])\n      : func;\n  }\n\n  /**\n   * Creates a clone of `object` by `path`.\n   *\n   * @private\n   * @param {Object} object The object to clone.\n   * @param {Array|string} path The path to clone by.\n   * @returns {Object} Returns the cloned object.\n   */\n  function cloneByPath(object, path) {\n    path = toPath(path);\n\n    var index = -1,\n        length = path.length,\n        lastIndex = length - 1,\n        result = clone(Object(object)),\n        nested = result;\n\n    while (nested != null && ++index < length) {\n      var key = path[index],\n          value = nested[key];\n\n      if (value != null &&\n          !(isFunction(value) || isError(value) || isWeakMap(value))) {\n        nested[key] = clone(index == lastIndex ? value : Object(value));\n      }\n      nested = nested[key];\n    }\n    return result;\n  }\n\n  /**\n   * Converts `lodash` to an immutable auto-curried iteratee-first data-last\n   * version with conversion `options` applied.\n   *\n   * @param {Object} [options] The options object. See `baseConvert` for more details.\n   * @returns {Function} Returns the converted `lodash`.\n   */\n  function convertLib(options) {\n    return _.runInContext.convert(options)(undefined);\n  }\n\n  /**\n   * Create a converter function for `func` of `name`.\n   *\n   * @param {string} name The name of the function to convert.\n   * @param {Function} func The function to convert.\n   * @returns {Function} Returns the new converter function.\n   */\n  function createConverter(name, func) {\n    var realName = mapping.aliasToReal[name] || name,\n        methodName = mapping.remap[realName] || realName,\n        oldOptions = options;\n\n    return function(options) {\n      var newUtil = isLib ? pristine : helpers,\n          newFunc = isLib ? pristine[methodName] : func,\n          newOptions = assign(assign({}, oldOptions), options);\n\n      return baseConvert(newUtil, realName, newFunc, newOptions);\n    };\n  }\n\n  /**\n   * Creates a function that wraps `func` to invoke its iteratee, with up to `n`\n   * arguments, ignoring any additional arguments.\n   *\n   * @private\n   * @param {Function} func The function to cap iteratee arguments for.\n   * @param {number} n The arity cap.\n   * @returns {Function} Returns the new function.\n   */\n  function iterateeAry(func, n) {\n    return overArg(func, function(func) {\n      return typeof func == 'function' ? baseAry(func, n) : func;\n    });\n  }\n\n  /**\n   * Creates a function that wraps `func` to invoke its iteratee with arguments\n   * arranged according to the specified `indexes` where the argument value at\n   * the first index is provided as the first argument, the argument value at\n   * the second index is provided as the second argument, and so on.\n   *\n   * @private\n   * @param {Function} func The function to rearrange iteratee arguments for.\n   * @param {number[]} indexes The arranged argument indexes.\n   * @returns {Function} Returns the new function.\n   */\n  function iterateeRearg(func, indexes) {\n    return overArg(func, function(func) {\n      var n = indexes.length;\n      return baseArity(rearg(baseAry(func, n), indexes), n);\n    });\n  }\n\n  /**\n   * Creates a function that invokes `func` with its first argument transformed.\n   *\n   * @private\n   * @param {Function} func The function to wrap.\n   * @param {Function} transform The argument transform.\n   * @returns {Function} Returns the new function.\n   */\n  function overArg(func, transform) {\n    return function() {\n      var length = arguments.length;\n      if (!length) {\n        return func();\n      }\n      var args = Array(length);\n      while (length--) {\n        args[length] = arguments[length];\n      }\n      var index = config.rearg ? 0 : (length - 1);\n      args[index] = transform(args[index]);\n      return func.apply(undefined, args);\n    };\n  }\n\n  /**\n   * Creates a function that wraps `func` and applys the conversions\n   * rules by `name`.\n   *\n   * @private\n   * @param {string} name The name of the function to wrap.\n   * @param {Function} func The function to wrap.\n   * @returns {Function} Returns the converted function.\n   */\n  function wrap(name, func, placeholder) {\n    var result,\n        realName = mapping.aliasToReal[name] || name,\n        wrapped = func,\n        wrapper = wrappers[realName];\n\n    if (wrapper) {\n      wrapped = wrapper(func);\n    }\n    else if (config.immutable) {\n      if (mapping.mutate.array[realName]) {\n        wrapped = wrapImmutable(func, cloneArray);\n      }\n      else if (mapping.mutate.object[realName]) {\n        wrapped = wrapImmutable(func, createCloner(func));\n      }\n      else if (mapping.mutate.set[realName]) {\n        wrapped = wrapImmutable(func, cloneByPath);\n      }\n    }\n    each(aryMethodKeys, function(aryKey) {\n      each(mapping.aryMethod[aryKey], function(otherName) {\n        if (realName == otherName) {\n          var data = mapping.methodSpread[realName],\n              afterRearg = data && data.afterRearg;\n\n          result = afterRearg\n            ? castFixed(realName, castRearg(realName, wrapped, aryKey), aryKey)\n            : castRearg(realName, castFixed(realName, wrapped, aryKey), aryKey);\n\n          result = castCap(realName, result);\n          result = castCurry(realName, result, aryKey);\n          return false;\n        }\n      });\n      return !result;\n    });\n\n    result || (result = wrapped);\n    if (result == func) {\n      result = forceCurry ? curry(result, 1) : function() {\n        return func.apply(this, arguments);\n      };\n    }\n    result.convert = createConverter(realName, func);\n    result.placeholder = func.placeholder = placeholder;\n\n    return result;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  if (!isObj) {\n    return wrap(name, func, defaultHolder);\n  }\n  var _ = func;\n\n  // Convert methods by ary cap.\n  var pairs = [];\n  each(aryMethodKeys, function(aryKey) {\n    each(mapping.aryMethod[aryKey], function(key) {\n      var func = _[mapping.remap[key] || key];\n      if (func) {\n        pairs.push([key, wrap(key, func, _)]);\n      }\n    });\n  });\n\n  // Convert remaining methods.\n  each(keys(_), function(key) {\n    var func = _[key];\n    if (typeof func == 'function') {\n      var length = pairs.length;\n      while (length--) {\n        if (pairs[length][0] == key) {\n          return;\n        }\n      }\n      func.convert = createConverter(key, func);\n      pairs.push([key, func]);\n    }\n  });\n\n  // Assign to `_` leaving `_.prototype` unchanged to allow chaining.\n  each(pairs, function(pair) {\n    _[pair[0]] = pair[1];\n  });\n\n  _.convert = convertLib;\n  _.placeholder = _;\n\n  // Assign aliases.\n  each(keys(_), function(key) {\n    each(mapping.realToAlias[key] || [], function(alias) {\n      _[alias] = _[key];\n    });\n  });\n\n  return _;\n}\n\nmodule.exports = baseConvert;\n","module.exports = {\n  'cap': false,\n  'curry': false,\n  'fixed': false,\n  'immutable': false,\n  'rearg': false\n};\n","/** Used to map aliases to their real names. */\nexports.aliasToReal = {\n\n  // Lodash aliases.\n  'each': 'forEach',\n  'eachRight': 'forEachRight',\n  'entries': 'toPairs',\n  'entriesIn': 'toPairsIn',\n  'extend': 'assignIn',\n  'extendAll': 'assignInAll',\n  'extendAllWith': 'assignInAllWith',\n  'extendWith': 'assignInWith',\n  'first': 'head',\n\n  // Methods that are curried variants of others.\n  'conforms': 'conformsTo',\n  'matches': 'isMatch',\n  'property': 'get',\n\n  // Ramda aliases.\n  '__': 'placeholder',\n  'F': 'stubFalse',\n  'T': 'stubTrue',\n  'all': 'every',\n  'allPass': 'overEvery',\n  'always': 'constant',\n  'any': 'some',\n  'anyPass': 'overSome',\n  'apply': 'spread',\n  'assoc': 'set',\n  'assocPath': 'set',\n  'complement': 'negate',\n  'compose': 'flowRight',\n  'contains': 'includes',\n  'dissoc': 'unset',\n  'dissocPath': 'unset',\n  'dropLast': 'dropRight',\n  'dropLastWhile': 'dropRightWhile',\n  'equals': 'isEqual',\n  'identical': 'eq',\n  'indexBy': 'keyBy',\n  'init': 'initial',\n  'invertObj': 'invert',\n  'juxt': 'over',\n  'omitAll': 'omit',\n  'nAry': 'ary',\n  'path': 'get',\n  'pathEq': 'matchesProperty',\n  'pathOr': 'getOr',\n  'paths': 'at',\n  'pickAll': 'pick',\n  'pipe': 'flow',\n  'pluck': 'map',\n  'prop': 'get',\n  'propEq': 'matchesProperty',\n  'propOr': 'getOr',\n  'props': 'at',\n  'symmetricDifference': 'xor',\n  'symmetricDifferenceBy': 'xorBy',\n  'symmetricDifferenceWith': 'xorWith',\n  'takeLast': 'takeRight',\n  'takeLastWhile': 'takeRightWhile',\n  'unapply': 'rest',\n  'unnest': 'flatten',\n  'useWith': 'overArgs',\n  'where': 'conformsTo',\n  'whereEq': 'isMatch',\n  'zipObj': 'zipObject'\n};\n\n/** Used to map ary to method names. */\nexports.aryMethod = {\n  '1': [\n    'assignAll', 'assignInAll', 'attempt', 'castArray', 'ceil', 'create',\n    'curry', 'curryRight', 'defaultsAll', 'defaultsDeepAll', 'floor', 'flow',\n    'flowRight', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'mergeAll',\n    'methodOf', 'mixin', 'nthArg', 'over', 'overEvery', 'overSome','rest', 'reverse',\n    'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart',\n    'uniqueId', 'words', 'zipAll'\n  ],\n  '2': [\n    'add', 'after', 'ary', 'assign', 'assignAllWith', 'assignIn', 'assignInAllWith',\n    'at', 'before', 'bind', 'bindAll', 'bindKey', 'chunk', 'cloneDeepWith',\n    'cloneWith', 'concat', 'conformsTo', 'countBy', 'curryN', 'curryRightN',\n    'debounce', 'defaults', 'defaultsDeep', 'defaultTo', 'delay', 'difference',\n    'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq',\n    'every', 'filter', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',\n    'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth', 'forEach',\n    'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'get',\n    'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'intersection',\n    'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy',\n    'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'matchesProperty',\n    'maxBy', 'meanBy', 'merge', 'mergeAllWith', 'minBy', 'multiply', 'nth', 'omit',\n    'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial',\n    'partialRight', 'partition', 'pick', 'pickBy', 'propertyOf', 'pull', 'pullAll',\n    'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',\n    'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',\n    'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',\n    'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',\n    'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',\n    'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',\n    'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',\n    'zipObjectDeep'\n  ],\n  '3': [\n    'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',\n    'findFrom', 'findIndexFrom', 'findLastFrom', 'findLastIndexFrom', 'getOr',\n    'includesFrom', 'indexOfFrom', 'inRange', 'intersectionBy', 'intersectionWith',\n    'invokeArgs', 'invokeArgsMap', 'isEqualWith', 'isMatchWith', 'flatMapDepth',\n    'lastIndexOfFrom', 'mergeWith', 'orderBy', 'padChars', 'padCharsEnd',\n    'padCharsStart', 'pullAllBy', 'pullAllWith', 'rangeStep', 'rangeStepRight',\n    'reduce', 'reduceRight', 'replace', 'set', 'slice', 'sortedIndexBy',\n    'sortedLastIndexBy', 'transform', 'unionBy', 'unionWith', 'update', 'xorBy',\n    'xorWith', 'zipWith'\n  ],\n  '4': [\n    'fill', 'setWith', 'updateWith'\n  ]\n};\n\n/** Used to map ary to rearg configs. */\nexports.aryRearg = {\n  '2': [1, 0],\n  '3': [2, 0, 1],\n  '4': [3, 2, 0, 1]\n};\n\n/** Used to map method names to their iteratee ary. */\nexports.iterateeAry = {\n  'dropRightWhile': 1,\n  'dropWhile': 1,\n  'every': 1,\n  'filter': 1,\n  'find': 1,\n  'findFrom': 1,\n  'findIndex': 1,\n  'findIndexFrom': 1,\n  'findKey': 1,\n  'findLast': 1,\n  'findLastFrom': 1,\n  'findLastIndex': 1,\n  'findLastIndexFrom': 1,\n  'findLastKey': 1,\n  'flatMap': 1,\n  'flatMapDeep': 1,\n  'flatMapDepth': 1,\n  'forEach': 1,\n  'forEachRight': 1,\n  'forIn': 1,\n  'forInRight': 1,\n  'forOwn': 1,\n  'forOwnRight': 1,\n  'map': 1,\n  'mapKeys': 1,\n  'mapValues': 1,\n  'partition': 1,\n  'reduce': 2,\n  'reduceRight': 2,\n  'reject': 1,\n  'remove': 1,\n  'some': 1,\n  'takeRightWhile': 1,\n  'takeWhile': 1,\n  'times': 1,\n  'transform': 2\n};\n\n/** Used to map method names to iteratee rearg configs. */\nexports.iterateeRearg = {\n  'mapKeys': [1],\n  'reduceRight': [1, 0]\n};\n\n/** Used to map method names to rearg configs. */\nexports.methodRearg = {\n  'assignInAllWith': [1, 0],\n  'assignInWith': [1, 2, 0],\n  'assignAllWith': [1, 0],\n  'assignWith': [1, 2, 0],\n  'differenceBy': [1, 2, 0],\n  'differenceWith': [1, 2, 0],\n  'getOr': [2, 1, 0],\n  'intersectionBy': [1, 2, 0],\n  'intersectionWith': [1, 2, 0],\n  'isEqualWith': [1, 2, 0],\n  'isMatchWith': [2, 1, 0],\n  'mergeAllWith': [1, 0],\n  'mergeWith': [1, 2, 0],\n  'padChars': [2, 1, 0],\n  'padCharsEnd': [2, 1, 0],\n  'padCharsStart': [2, 1, 0],\n  'pullAllBy': [2, 1, 0],\n  'pullAllWith': [2, 1, 0],\n  'rangeStep': [1, 2, 0],\n  'rangeStepRight': [1, 2, 0],\n  'setWith': [3, 1, 2, 0],\n  'sortedIndexBy': [2, 1, 0],\n  'sortedLastIndexBy': [2, 1, 0],\n  'unionBy': [1, 2, 0],\n  'unionWith': [1, 2, 0],\n  'updateWith': [3, 1, 2, 0],\n  'xorBy': [1, 2, 0],\n  'xorWith': [1, 2, 0],\n  'zipWith': [1, 2, 0]\n};\n\n/** Used to map method names to spread configs. */\nexports.methodSpread = {\n  'assignAll': { 'start': 0 },\n  'assignAllWith': { 'start': 0 },\n  'assignInAll': { 'start': 0 },\n  'assignInAllWith': { 'start': 0 },\n  'defaultsAll': { 'start': 0 },\n  'defaultsDeepAll': { 'start': 0 },\n  'invokeArgs': { 'start': 2 },\n  'invokeArgsMap': { 'start': 2 },\n  'mergeAll': { 'start': 0 },\n  'mergeAllWith': { 'start': 0 },\n  'partial': { 'start': 1 },\n  'partialRight': { 'start': 1 },\n  'without': { 'start': 1 },\n  'zipAll': { 'start': 0 }\n};\n\n/** Used to identify methods which mutate arrays or objects. */\nexports.mutate = {\n  'array': {\n    'fill': true,\n    'pull': true,\n    'pullAll': true,\n    'pullAllBy': true,\n    'pullAllWith': true,\n    'pullAt': true,\n    'remove': true,\n    'reverse': true\n  },\n  'object': {\n    'assign': true,\n    'assignAll': true,\n    'assignAllWith': true,\n    'assignIn': true,\n    'assignInAll': true,\n    'assignInAllWith': true,\n    'assignInWith': true,\n    'assignWith': true,\n    'defaults': true,\n    'defaultsAll': true,\n    'defaultsDeep': true,\n    'defaultsDeepAll': true,\n    'merge': true,\n    'mergeAll': true,\n    'mergeAllWith': true,\n    'mergeWith': true,\n  },\n  'set': {\n    'set': true,\n    'setWith': true,\n    'unset': true,\n    'update': true,\n    'updateWith': true\n  }\n};\n\n/** Used to map real names to their aliases. */\nexports.realToAlias = (function() {\n  var hasOwnProperty = Object.prototype.hasOwnProperty,\n      object = exports.aliasToReal,\n      result = {};\n\n  for (var key in object) {\n    var value = object[key];\n    if (hasOwnProperty.call(result, value)) {\n      result[value].push(key);\n    } else {\n      result[value] = [key];\n    }\n  }\n  return result;\n}());\n\n/** Used to map method names to other names. */\nexports.remap = {\n  'assignAll': 'assign',\n  'assignAllWith': 'assignWith',\n  'assignInAll': 'assignIn',\n  'assignInAllWith': 'assignInWith',\n  'curryN': 'curry',\n  'curryRightN': 'curryRight',\n  'defaultsAll': 'defaults',\n  'defaultsDeepAll': 'defaultsDeep',\n  'findFrom': 'find',\n  'findIndexFrom': 'findIndex',\n  'findLastFrom': 'findLast',\n  'findLastIndexFrom': 'findLastIndex',\n  'getOr': 'get',\n  'includesFrom': 'includes',\n  'indexOfFrom': 'indexOf',\n  'invokeArgs': 'invoke',\n  'invokeArgsMap': 'invokeMap',\n  'lastIndexOfFrom': 'lastIndexOf',\n  'mergeAll': 'merge',\n  'mergeAllWith': 'mergeWith',\n  'padChars': 'pad',\n  'padCharsEnd': 'padEnd',\n  'padCharsStart': 'padStart',\n  'propertyOf': 'get',\n  'rangeStep': 'range',\n  'rangeStepRight': 'rangeRight',\n  'restFrom': 'rest',\n  'spreadFrom': 'spread',\n  'trimChars': 'trim',\n  'trimCharsEnd': 'trimEnd',\n  'trimCharsStart': 'trimStart',\n  'zipAll': 'zip'\n};\n\n/** Used to track methods that skip fixing their arity. */\nexports.skipFixed = {\n  'castArray': true,\n  'flow': true,\n  'flowRight': true,\n  'iteratee': true,\n  'mixin': true,\n  'rearg': true,\n  'runInContext': true\n};\n\n/** Used to track methods that skip rearranging arguments. */\nexports.skipRearg = {\n  'add': true,\n  'assign': true,\n  'assignIn': true,\n  'bind': true,\n  'bindKey': true,\n  'concat': true,\n  'difference': true,\n  'divide': true,\n  'eq': true,\n  'gt': true,\n  'gte': true,\n  'isEqual': true,\n  'lt': true,\n  'lte': true,\n  'matchesProperty': true,\n  'merge': true,\n  'multiply': true,\n  'overArgs': true,\n  'partial': true,\n  'partialRight': true,\n  'propertyOf': true,\n  'random': true,\n  'range': true,\n  'rangeRight': true,\n  'subtract': true,\n  'zip': true,\n  'zipObject': true,\n  'zipObjectDeep': true\n};\n","module.exports = {\n  'ary': require('../ary'),\n  'assign': require('../_baseAssign'),\n  'clone': require('../clone'),\n  'curry': require('../curry'),\n  'forEach': require('../_arrayEach'),\n  'isArray': require('../isArray'),\n  'isError': require('../isError'),\n  'isFunction': require('../isFunction'),\n  'isWeakMap': require('../isWeakMap'),\n  'iteratee': require('../iteratee'),\n  'keys': require('../_baseKeys'),\n  'rearg': require('../rearg'),\n  'toInteger': require('../toInteger'),\n  'toPath': require('../toPath')\n};\n","var convert = require('./convert'),\n    func = convert('compact', require('../compact'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var baseConvert = require('./_baseConvert'),\n    util = require('./_util');\n\n/**\n * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last\n * version with conversion `options` applied. If `name` is an object its methods\n * will be converted.\n *\n * @param {string} name The name of the function to wrap.\n * @param {Function} [func] The function to wrap.\n * @param {Object} [options] The options object. See `baseConvert` for more details.\n * @returns {Function|Object} Returns the converted function or object.\n */\nfunction convert(name, func, options) {\n  return baseConvert(util, name, func, options);\n}\n\nmodule.exports = convert;\n","var convert = require('./convert'),\n    func = convert('difference', require('../difference'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('flow', require('../flow'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('isFunction', require('../isFunction'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('isNil', require('../isNil'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('isObject', require('../isObject'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('isPlainObject', require('../isPlainObject'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('keys', require('../keys'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('map', require('../map'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('memoize', require('../memoize'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('min', require('../min'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('pick', require('../pick'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","/**\n * The default argument placeholder value for methods.\n *\n * @type {Object}\n */\nmodule.exports = {};\n","var convert = require('./convert'),\n    func = convert('sortBy', require('../sortBy'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('sum', require('../sum'), require('./_falseOptions'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('take', require('../take'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var convert = require('./convert'),\n    func = convert('trim', require('../trim'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n  var result = object == null ? undefined : baseGet(object, path);\n  return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var baseHas = require('./_baseHas'),\n    hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct property of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = { 'a': { 'b': 2 } };\n * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.has(object, 'a');\n * // => true\n *\n * _.has(object, 'a.b');\n * // => true\n *\n * _.has(object, ['a', 'b']);\n * // => true\n *\n * _.has(other, 'a');\n * // => false\n */\nfunction has(object, path) {\n  return object != null && hasPath(object, path, baseHas);\n}\n\nmodule.exports = has;\n","var baseHasIn = require('./_baseHasIn'),\n    hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n  return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * Gets the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias first\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the first element of `array`.\n * @example\n *\n * _.head([1, 2, 3]);\n * // => 1\n *\n * _.head([]);\n * // => undefined\n */\nfunction head(array) {\n  return (array && array.length) ? array[0] : undefined;\n}\n\nmodule.exports = head;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n  return value;\n}\n\nmodule.exports = identity;\n","var baseInRange = require('./_baseInRange'),\n    toFinite = require('./toFinite'),\n    toNumber = require('./toNumber');\n\n/**\n * Checks if `n` is between `start` and up to, but not including, `end`. If\n * `end` is not specified, it's set to `start` with `start` then set to `0`.\n * If `start` is greater than `end` the params are swapped to support\n * negative ranges.\n *\n * @static\n * @memberOf _\n * @since 3.3.0\n * @category Number\n * @param {number} number The number to check.\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n * @see _.range, _.rangeRight\n * @example\n *\n * _.inRange(3, 2, 4);\n * // => true\n *\n * _.inRange(4, 8);\n * // => true\n *\n * _.inRange(4, 2);\n * // => false\n *\n * _.inRange(2, 2);\n * // => false\n *\n * _.inRange(1.2, 2);\n * // => true\n *\n * _.inRange(5.2, 4);\n * // => false\n *\n * _.inRange(-3, -2, -6);\n * // => true\n */\nfunction inRange(number, start, end) {\n  start = toFinite(start);\n  if (end === undefined) {\n    end = start;\n    start = 0;\n  } else {\n    end = toFinite(end);\n  }\n  number = toNumber(number);\n  return baseInRange(number, start, end);\n}\n\nmodule.exports = inRange;\n","var baseIndexOf = require('./_baseIndexOf'),\n    isArrayLike = require('./isArrayLike'),\n    isString = require('./isString'),\n    toInteger = require('./toInteger'),\n    values = require('./values');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Checks if `value` is in `collection`. If `collection` is a string, it's\n * checked for a substring of `value`, otherwise\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * is used for equality comparisons. If `fromIndex` is negative, it's used as\n * the offset from the end of `collection`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {boolean} Returns `true` if `value` is found, else `false`.\n * @example\n *\n * _.includes([1, 2, 3], 1);\n * // => true\n *\n * _.includes([1, 2, 3], 1, 2);\n * // => false\n *\n * _.includes({ 'a': 1, 'b': 2 }, 1);\n * // => true\n *\n * _.includes('abcd', 'bc');\n * // => true\n */\nfunction includes(collection, value, fromIndex, guard) {\n  collection = isArrayLike(collection) ? collection : values(collection);\n  fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n  var length = collection.length;\n  if (fromIndex < 0) {\n    fromIndex = nativeMax(length + fromIndex, 0);\n  }\n  return isString(collection)\n    ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n    : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n}\n\nmodule.exports = includes;\n","var arrayMap = require('./_arrayMap'),\n    baseIntersection = require('./_baseIntersection'),\n    baseRest = require('./_baseRest'),\n    castArrayLikeObject = require('./_castArrayLikeObject');\n\n/**\n * Creates an array of unique values that are included in all given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [2, 3]);\n * // => [2]\n */\nvar intersection = baseRest(function(arrays) {\n  var mapped = arrayMap(arrays, castArrayLikeObject);\n  return (mapped.length && mapped[0] === arrays[0])\n    ? baseIntersection(mapped)\n    : [];\n});\n\nmodule.exports = intersection;\n","var constant = require('./constant'),\n    createInverter = require('./_createInverter'),\n    identity = require('./identity');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Creates an object composed of the inverted keys and values of `object`.\n * If `object` contains duplicate values, subsequent values overwrite\n * property assignments of previous values.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Object\n * @param {Object} object The object to invert.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invert(object);\n * // => { '1': 'c', '2': 'b' }\n */\nvar invert = createInverter(function(result, value, key) {\n  if (value != null &&\n      typeof value.toString != 'function') {\n    value = nativeObjectToString.call(value);\n  }\n\n  result[value] = key;\n}, constant(identity));\n\nmodule.exports = invert;\n","var baseInvoke = require('./_baseInvoke'),\n    baseRest = require('./_baseRest');\n\n/**\n * Invokes the method at `path` of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {...*} [args] The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n *\n * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n * // => [2, 3]\n */\nvar invoke = baseRest(baseInvoke);\n\nmodule.exports = invoke;\n","var baseIsArguments = require('./_baseIsArguments'),\n    isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n    !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var isFunction = require('./isFunction'),\n    isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","var isArrayLike = require('./isArrayLike'),\n    isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n","var baseGetTag = require('./_baseGetTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]';\n\n/**\n * Checks if `value` is classified as a boolean primitive or object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n * @example\n *\n * _.isBoolean(false);\n * // => true\n *\n * _.isBoolean(null);\n * // => false\n */\nfunction isBoolean(value) {\n  return value === true || value === false ||\n    (isObjectLike(value) && baseGetTag(value) == boolTag);\n}\n\nmodule.exports = isBoolean;\n","var root = require('./_root'),\n    stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","var baseKeys = require('./_baseKeys'),\n    getTag = require('./_getTag'),\n    isArguments = require('./isArguments'),\n    isArray = require('./isArray'),\n    isArrayLike = require('./isArrayLike'),\n    isBuffer = require('./isBuffer'),\n    isPrototype = require('./_isPrototype'),\n    isTypedArray = require('./isTypedArray');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n    setTag = '[object Set]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\nfunction isEmpty(value) {\n  if (value == null) {\n    return true;\n  }\n  if (isArrayLike(value) &&\n      (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n        isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n    return !value.length;\n  }\n  var tag = getTag(value);\n  if (tag == mapTag || tag == setTag) {\n    return !value.size;\n  }\n  if (isPrototype(value)) {\n    return !baseKeys(value).length;\n  }\n  for (var key in value) {\n    if (hasOwnProperty.call(value, key)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nmodule.exports = isEmpty;\n","var baseIsEqual = require('./_baseIsEqual');\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n  return baseIsEqual(value, other);\n}\n\nmodule.exports = isEqual;\n","var baseGetTag = require('./_baseGetTag'),\n    isObjectLike = require('./isObjectLike'),\n    isPlainObject = require('./isPlainObject');\n\n/** `Object#toString` result references. */\nvar domExcTag = '[object DOMException]',\n    errorTag = '[object Error]';\n\n/**\n * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n * `SyntaxError`, `TypeError`, or `URIError` object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n * @example\n *\n * _.isError(new Error);\n * // => true\n *\n * _.isError(Error);\n * // => false\n */\nfunction isError(value) {\n  if (!isObjectLike(value)) {\n    return false;\n  }\n  var tag = baseGetTag(value);\n  return tag == errorTag || tag == domExcTag ||\n    (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n}\n\nmodule.exports = isError;\n","var baseGetTag = require('./_baseGetTag'),\n    isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]',\n    proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  if (!isObject(value)) {\n    return false;\n  }\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 9 which returns 'object' for typed arrays and other constructors.\n  var tag = baseGetTag(value);\n  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","var baseIsMap = require('./_baseIsMap'),\n    baseUnary = require('./_baseUnary'),\n    nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nmodule.exports = isMap;\n","/**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\nfunction isNil(value) {\n  return value == null;\n}\n\nmodule.exports = isNil;\n","var baseGetTag = require('./_baseGetTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar numberTag = '[object Number]';\n\n/**\n * Checks if `value` is classified as a `Number` primitive or object.\n *\n * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n * classified as numbers, use the `_.isFinite` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\nfunction isNumber(value) {\n  return typeof value == 'number' ||\n    (isObjectLike(value) && baseGetTag(value) == numberTag);\n}\n\nmodule.exports = isNumber;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n    getPrototype = require('./_getPrototype'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n    objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n    return false;\n  }\n  var proto = getPrototype(value);\n  if (proto === null) {\n    return true;\n  }\n  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n  return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n    funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n","var baseIsSet = require('./_baseIsSet'),\n    baseUnary = require('./_baseUnary'),\n    nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nmodule.exports = isSet;\n","var baseGetTag = require('./_baseGetTag'),\n    isArray = require('./isArray'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar stringTag = '[object String]';\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n  return typeof value == 'string' ||\n    (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n}\n\nmodule.exports = isString;\n","var baseGetTag = require('./_baseGetTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n  return typeof value == 'symbol' ||\n    (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n    baseUnary = require('./_baseUnary'),\n    nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n  return value === undefined;\n}\n\nmodule.exports = isUndefined;\n","var getTag = require('./_getTag'),\n    isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar weakMapTag = '[object WeakMap]';\n\n/**\n * Checks if `value` is classified as a `WeakMap` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n * @example\n *\n * _.isWeakMap(new WeakMap);\n * // => true\n *\n * _.isWeakMap(new Map);\n * // => false\n */\nfunction isWeakMap(value) {\n  return isObjectLike(value) && getTag(value) == weakMapTag;\n}\n\nmodule.exports = isWeakMap;\n","var baseClone = require('./_baseClone'),\n    baseIteratee = require('./_baseIteratee');\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1;\n\n/**\n * Creates a function that invokes `func` with the arguments of the created\n * function. If `func` is a property name, the created function returns the\n * property value for a given element. If `func` is an array or object, the\n * created function returns `true` for elements that contain the equivalent\n * source properties, otherwise it returns `false`.\n *\n * @static\n * @since 4.0.0\n * @memberOf _\n * @category Util\n * @param {*} [func=_.identity] The value to convert to a callback.\n * @returns {Function} Returns the callback.\n * @example\n *\n * var users = [\n *   { 'user': 'barney', 'age': 36, 'active': true },\n *   { 'user': 'fred',   'age': 40, 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));\n * // => [{ 'user': 'barney', 'age': 36, 'active': true }]\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, _.iteratee(['user', 'fred']));\n * // => [{ 'user': 'fred', 'age': 40 }]\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, _.iteratee('user'));\n * // => ['barney', 'fred']\n *\n * // Create custom iteratee shorthands.\n * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {\n *   return !_.isRegExp(func) ? iteratee(func) : function(string) {\n *     return func.test(string);\n *   };\n * });\n *\n * _.filter(['abc', 'def'], /ef/);\n * // => ['def']\n */\nfunction iteratee(func) {\n  return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));\n}\n\nmodule.exports = iteratee;\n","var baseAssignValue = require('./_baseAssignValue'),\n    createAggregator = require('./_createAggregator');\n\n/**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the last element responsible for generating the key. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * var array = [\n *   { 'dir': 'left', 'code': 97 },\n *   { 'dir': 'right', 'code': 100 }\n * ];\n *\n * _.keyBy(array, function(o) {\n *   return String.fromCharCode(o.code);\n * });\n * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n *\n * _.keyBy(array, 'dir');\n * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n */\nvar keyBy = createAggregator(function(result, value, key) {\n  baseAssignValue(result, key, value);\n});\n\nmodule.exports = keyBy;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n    baseKeys = require('./_baseKeys'),\n    isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n    baseKeysIn = require('./_baseKeysIn'),\n    isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n  var length = array == null ? 0 : array.length;\n  return length ? array[length - 1] : undefined;\n}\n\nmodule.exports = last;\n","var arrayMap = require('./_arrayMap'),\n    baseIteratee = require('./_baseIteratee'),\n    baseMap = require('./_baseMap'),\n    isArray = require('./isArray');\n\n/**\n * Creates an array of values by running each element in `collection` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n *\n * The guarded methods are:\n * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n *   return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n *   { 'user': 'barney' },\n *   { 'user': 'fred' }\n * ];\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\nfunction map(collection, iteratee) {\n  var func = isArray(collection) ? arrayMap : baseMap;\n  return func(collection, baseIteratee(iteratee, 3));\n}\n\nmodule.exports = map;\n","var baseAssignValue = require('./_baseAssignValue'),\n    baseForOwn = require('./_baseForOwn'),\n    baseIteratee = require('./_baseIteratee');\n\n/**\n * Creates an object with the same keys as `object` and values generated\n * by running each own enumerable string keyed property of `object` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n *   'fred':    { 'user': 'fred',    'age': 40 },\n *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The `_.property` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\nfunction mapValues(object, iteratee) {\n  var result = {};\n  iteratee = baseIteratee(iteratee, 3);\n\n  baseForOwn(object, function(value, key, object) {\n    baseAssignValue(result, key, iteratee(value, key, object));\n  });\n  return result;\n}\n\nmodule.exports = mapValues;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  var memoized = function() {\n    var args = arguments,\n        key = resolver ? resolver.apply(this, args) : args[0],\n        cache = memoized.cache;\n\n    if (cache.has(key)) {\n      return cache.get(key);\n    }\n    var result = func.apply(this, args);\n    memoized.cache = cache.set(key, result) || cache;\n    return result;\n  };\n  memoized.cache = new (memoize.Cache || MapCache);\n  return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseMerge = require('./_baseMerge'),\n    createAssigner = require('./_createAssigner');\n\n/**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n *   'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n *   'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\nvar merge = createAssigner(function(object, source, srcIndex) {\n  baseMerge(object, source, srcIndex);\n});\n\nmodule.exports = merge;\n","var baseExtremum = require('./_baseExtremum'),\n    baseLt = require('./_baseLt'),\n    identity = require('./identity');\n\n/**\n * Computes the minimum value of `array`. If `array` is empty or falsey,\n * `undefined` is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {*} Returns the minimum value.\n * @example\n *\n * _.min([4, 2, 8, 6]);\n * // => 2\n *\n * _.min([]);\n * // => undefined\n */\nfunction min(array) {\n  return (array && array.length)\n    ? baseExtremum(array, identity, baseLt)\n    : undefined;\n}\n\nmodule.exports = min;\n","/**\n * This method returns `undefined`.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Util\n * @example\n *\n * _.times(2, _.noop);\n * // => [undefined, undefined]\n */\nfunction noop() {\n  // No operation performed.\n}\n\nmodule.exports = noop;\n","var baseRest = require('./_baseRest'),\n    createWrap = require('./_createWrap'),\n    getHolder = require('./_getHolder'),\n    replaceHolders = require('./_replaceHolders');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_PARTIAL_RIGHT_FLAG = 64;\n\n/**\n * This method is like `_.partial` except that partially applied arguments\n * are appended to the arguments it receives.\n *\n * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n *   return greeting + ' ' + name;\n * }\n *\n * var greetFred = _.partialRight(greet, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n *\n * // Partially applied with placeholders.\n * var sayHelloTo = _.partialRight(greet, 'hello', _);\n * sayHelloTo('fred');\n * // => 'hello fred'\n */\nvar partialRight = baseRest(function(func, partials) {\n  var holders = replaceHolders(partials, getHolder(partialRight));\n  return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n});\n\n// Assign default placeholders.\npartialRight.placeholder = {};\n\nmodule.exports = partialRight;\n","var basePick = require('./_basePick'),\n    flatRest = require('./_flatRest');\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pick(object, ['a', 'c']);\n * // => { 'a': 1, 'c': 3 }\n */\nvar pick = flatRest(function(object, paths) {\n  return object == null ? {} : basePick(object, paths);\n});\n\nmodule.exports = pick;\n","var arrayMap = require('./_arrayMap'),\n    baseIteratee = require('./_baseIteratee'),\n    basePickBy = require('./_basePickBy'),\n    getAllKeysIn = require('./_getAllKeysIn');\n\n/**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\nfunction pickBy(object, predicate) {\n  if (object == null) {\n    return {};\n  }\n  var props = arrayMap(getAllKeysIn(object), function(prop) {\n    return [prop];\n  });\n  predicate = baseIteratee(predicate);\n  return basePickBy(object, props, function(value, path) {\n    return predicate(value, path[0]);\n  });\n}\n\nmodule.exports = pickBy;\n","var baseProperty = require('./_baseProperty'),\n    basePropertyDeep = require('./_basePropertyDeep'),\n    isKey = require('./_isKey'),\n    toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n *   { 'a': { 'b': 2 } },\n *   { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","var createRange = require('./_createRange');\n\n/**\n * Creates an array of numbers (positive and/or negative) progressing from\n * `start` up to, but not including, `end`. A step of `-1` is used if a negative\n * `start` is specified without an `end` or `step`. If `end` is not specified,\n * it's set to `start` with `start` then set to `0`.\n *\n * **Note:** JavaScript follows the IEEE-754 standard for resolving\n * floating-point values which can produce unexpected results.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @param {number} [step=1] The value to increment or decrement by.\n * @returns {Array} Returns the range of numbers.\n * @see _.inRange, _.rangeRight\n * @example\n *\n * _.range(4);\n * // => [0, 1, 2, 3]\n *\n * _.range(-4);\n * // => [0, -1, -2, -3]\n *\n * _.range(1, 5);\n * // => [1, 2, 3, 4]\n *\n * _.range(0, 20, 5);\n * // => [0, 5, 10, 15]\n *\n * _.range(0, -4, -1);\n * // => [0, -1, -2, -3]\n *\n * _.range(1, 4, 0);\n * // => [1, 1, 1]\n *\n * _.range(0);\n * // => []\n */\nvar range = createRange();\n\nmodule.exports = range;\n","var createWrap = require('./_createWrap'),\n    flatRest = require('./_flatRest');\n\n/** Used to compose bitmasks for function metadata. */\nvar WRAP_REARG_FLAG = 256;\n\n/**\n * Creates a function that invokes `func` with arguments arranged according\n * to the specified `indexes` where the argument value at the first index is\n * provided as the first argument, the argument value at the second index is\n * provided as the second argument, and so on.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to rearrange arguments for.\n * @param {...(number|number[])} indexes The arranged argument indexes.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var rearged = _.rearg(function(a, b, c) {\n *   return [a, b, c];\n * }, [2, 0, 1]);\n *\n * rearged('b', 'c', 'a')\n * // => ['a', 'b', 'c']\n */\nvar rearg = flatRest(function(func, indexes) {\n  return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n});\n\nmodule.exports = rearg;\n","var arrayReduce = require('./_arrayReduce'),\n    baseEach = require('./_baseEach'),\n    baseIteratee = require('./_baseIteratee'),\n    baseReduce = require('./_baseReduce'),\n    isArray = require('./isArray');\n\n/**\n * Reduces `collection` to a value which is the accumulated result of running\n * each element in `collection` thru `iteratee`, where each successive\n * invocation is supplied the return value of the previous. If `accumulator`\n * is not given, the first element of `collection` is used as the initial\n * value. The iteratee is invoked with four arguments:\n * (accumulator, value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.reduce`, `_.reduceRight`, and `_.transform`.\n *\n * The guarded methods are:\n * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n * and `sortBy`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduceRight\n * @example\n *\n * _.reduce([1, 2], function(sum, n) {\n *   return sum + n;\n * }, 0);\n * // => 3\n *\n * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n *   (result[value] || (result[value] = [])).push(key);\n *   return result;\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n */\nfunction reduce(collection, iteratee, accumulator) {\n  var func = isArray(collection) ? arrayReduce : baseReduce,\n      initAccum = arguments.length < 3;\n\n  return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n}\n\nmodule.exports = reduce;\n","var createRound = require('./_createRound');\n\n/**\n * Computes `number` rounded to `precision`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Math\n * @param {number} number The number to round.\n * @param {number} [precision=0] The precision to round to.\n * @returns {number} Returns the rounded number.\n * @example\n *\n * _.round(4.006);\n * // => 4\n *\n * _.round(4.006, 2);\n * // => 4.01\n *\n * _.round(4060, -2);\n * // => 4100\n */\nvar round = createRound('round');\n\nmodule.exports = round;\n","var baseSet = require('./_baseSet');\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n  return object == null ? object : baseSet(object, path, value);\n}\n\nmodule.exports = set;\n","var baseKeys = require('./_baseKeys'),\n    getTag = require('./_getTag'),\n    isArrayLike = require('./isArrayLike'),\n    isString = require('./isString'),\n    stringSize = require('./_stringSize');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n    setTag = '[object Set]';\n\n/**\n * Gets the size of `collection` by returning its length for array-like\n * values or the number of own enumerable string keyed properties for objects.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @returns {number} Returns the collection size.\n * @example\n *\n * _.size([1, 2, 3]);\n * // => 3\n *\n * _.size({ 'a': 1, 'b': 2 });\n * // => 2\n *\n * _.size('pebbles');\n * // => 7\n */\nfunction size(collection) {\n  if (collection == null) {\n    return 0;\n  }\n  if (isArrayLike(collection)) {\n    return isString(collection) ? stringSize(collection) : collection.length;\n  }\n  var tag = getTag(collection);\n  if (tag == mapTag || tag == setTag) {\n    return collection.size;\n  }\n  return baseKeys(collection).length;\n}\n\nmodule.exports = size;\n","var arraySome = require('./_arraySome'),\n    baseIteratee = require('./_baseIteratee'),\n    baseSome = require('./_baseSome'),\n    isArray = require('./isArray'),\n    isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Checks if `predicate` returns truthy for **any** element of `collection`.\n * Iteration is stopped once `predicate` returns truthy. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n *  else `false`.\n * @example\n *\n * _.some([null, 0, 'yes', false], Boolean);\n * // => true\n *\n * var users = [\n *   { 'user': 'barney', 'active': true },\n *   { 'user': 'fred',   'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.some(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.some(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.some(users, 'active');\n * // => true\n */\nfunction some(collection, predicate, guard) {\n  var func = isArray(collection) ? arraySome : baseSome;\n  if (guard && isIterateeCall(collection, predicate, guard)) {\n    predicate = undefined;\n  }\n  return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = some;\n","var baseFlatten = require('./_baseFlatten'),\n    baseOrderBy = require('./_baseOrderBy'),\n    baseRest = require('./_baseRest'),\n    isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n *  The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n *   { 'user': 'fred',   'age': 48 },\n *   { 'user': 'barney', 'age': 36 },\n *   { 'user': 'fred',   'age': 30 },\n *   { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]\n */\nvar sortBy = baseRest(function(collection, iteratees) {\n  if (collection == null) {\n    return [];\n  }\n  var length = iteratees.length;\n  if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n    iteratees = [];\n  } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n    iteratees = [iteratees[0]];\n  }\n  return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n});\n\nmodule.exports = sortBy;\n","var createCompounder = require('./_createCompounder'),\n    upperFirst = require('./upperFirst');\n\n/**\n * Converts `string` to\n * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n *\n * @static\n * @memberOf _\n * @since 3.1.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the start cased string.\n * @example\n *\n * _.startCase('--foo-bar--');\n * // => 'Foo Bar'\n *\n * _.startCase('fooBar');\n * // => 'Foo Bar'\n *\n * _.startCase('__FOO_BAR__');\n * // => 'FOO BAR'\n */\nvar startCase = createCompounder(function(result, word, index) {\n  return result + (index ? ' ' : '') + upperFirst(word);\n});\n\nmodule.exports = startCase;\n","var baseClamp = require('./_baseClamp'),\n    baseToString = require('./_baseToString'),\n    toInteger = require('./toInteger'),\n    toString = require('./toString');\n\n/**\n * Checks if `string` starts with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=0] The position to search from.\n * @returns {boolean} Returns `true` if `string` starts with `target`,\n *  else `false`.\n * @example\n *\n * _.startsWith('abc', 'a');\n * // => true\n *\n * _.startsWith('abc', 'b');\n * // => false\n *\n * _.startsWith('abc', 'b', 1);\n * // => true\n */\nfunction startsWith(string, target, position) {\n  string = toString(string);\n  position = position == null\n    ? 0\n    : baseClamp(toInteger(position), 0, string.length);\n\n  target = baseToString(target);\n  return string.slice(position, position + target.length) == target;\n}\n\nmodule.exports = startsWith;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n  return [];\n}\n\nmodule.exports = stubArray;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n  return false;\n}\n\nmodule.exports = stubFalse;\n","var baseSum = require('./_baseSum'),\n    identity = require('./identity');\n\n/**\n * Computes the sum of the values in `array`.\n *\n * @static\n * @memberOf _\n * @since 3.4.0\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {number} Returns the sum.\n * @example\n *\n * _.sum([4, 2, 8, 6]);\n * // => 20\n */\nfunction sum(array) {\n  return (array && array.length)\n    ? baseSum(array, identity)\n    : 0;\n}\n\nmodule.exports = sum;\n","var baseSlice = require('./_baseSlice'),\n    toInteger = require('./toInteger');\n\n/**\n * Creates a slice of `array` with `n` elements taken from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.take([1, 2, 3]);\n * // => [1]\n *\n * _.take([1, 2, 3], 2);\n * // => [1, 2]\n *\n * _.take([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.take([1, 2, 3], 0);\n * // => []\n */\nfunction take(array, n, guard) {\n  if (!(array && array.length)) {\n    return [];\n  }\n  n = (guard || n === undefined) ? 1 : toInteger(n);\n  return baseSlice(array, 0, n < 0 ? 0 : n);\n}\n\nmodule.exports = take;\n","var baseTimes = require('./_baseTimes'),\n    castFunction = require('./_castFunction'),\n    toInteger = require('./toInteger');\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used as references for the maximum length and index of an array. */\nvar MAX_ARRAY_LENGTH = 4294967295;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMin = Math.min;\n\n/**\n * Invokes the iteratee `n` times, returning an array of the results of\n * each invocation. The iteratee is invoked with one argument; (index).\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n * @example\n *\n * _.times(3, String);\n * // => ['0', '1', '2']\n *\n *  _.times(4, _.constant(0));\n * // => [0, 0, 0, 0]\n */\nfunction times(n, iteratee) {\n  n = toInteger(n);\n  if (n < 1 || n > MAX_SAFE_INTEGER) {\n    return [];\n  }\n  var index = MAX_ARRAY_LENGTH,\n      length = nativeMin(n, MAX_ARRAY_LENGTH);\n\n  iteratee = castFunction(iteratee);\n  n -= MAX_ARRAY_LENGTH;\n\n  var result = baseTimes(length, iteratee);\n  while (++index < n) {\n    iteratee(index);\n  }\n  return result;\n}\n\nmodule.exports = times;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n    MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n  if (!value) {\n    return value === 0 ? value : 0;\n  }\n  value = toNumber(value);\n  if (value === INFINITY || value === -INFINITY) {\n    var sign = (value < 0 ? -1 : 1);\n    return sign * MAX_INTEGER;\n  }\n  return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n  var result = toFinite(value),\n      remainder = result % 1;\n\n  return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var isObject = require('./isObject'),\n    isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n  if (typeof value == 'number') {\n    return value;\n  }\n  if (isSymbol(value)) {\n    return NAN;\n  }\n  if (isObject(value)) {\n    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n    value = isObject(other) ? (other + '') : other;\n  }\n  if (typeof value != 'string') {\n    return value === 0 ? value : +value;\n  }\n  value = value.replace(reTrim, '');\n  var isBinary = reIsBinary.test(value);\n  return (isBinary || reIsOctal.test(value))\n    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n    : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var arrayMap = require('./_arrayMap'),\n    copyArray = require('./_copyArray'),\n    isArray = require('./isArray'),\n    isSymbol = require('./isSymbol'),\n    stringToPath = require('./_stringToPath'),\n    toKey = require('./_toKey'),\n    toString = require('./toString');\n\n/**\n * Converts `value` to a property path array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Util\n * @param {*} value The value to convert.\n * @returns {Array} Returns the new property path array.\n * @example\n *\n * _.toPath('a.b.c');\n * // => ['a', 'b', 'c']\n *\n * _.toPath('a[0].b.c');\n * // => ['a', '0', 'b', 'c']\n */\nfunction toPath(value) {\n  if (isArray(value)) {\n    return arrayMap(value, toKey);\n  }\n  return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));\n}\n\nmodule.exports = toPath;\n","var copyObject = require('./_copyObject'),\n    keysIn = require('./keysIn');\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n  return copyObject(value, keysIn(value));\n}\n\nmodule.exports = toPlainObject;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n  return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","var arrayEach = require('./_arrayEach'),\n    baseCreate = require('./_baseCreate'),\n    baseForOwn = require('./_baseForOwn'),\n    baseIteratee = require('./_baseIteratee'),\n    getPrototype = require('./_getPrototype'),\n    isArray = require('./isArray'),\n    isBuffer = require('./isBuffer'),\n    isFunction = require('./isFunction'),\n    isObject = require('./isObject'),\n    isTypedArray = require('./isTypedArray');\n\n/**\n * An alternative to `_.reduce`; this method transforms `object` to a new\n * `accumulator` object which is the result of running each of its own\n * enumerable string keyed properties thru `iteratee`, with each invocation\n * potentially mutating the `accumulator` object. If `accumulator` is not\n * provided, a new object with the same `[[Prototype]]` will be used. The\n * iteratee is invoked with four arguments: (accumulator, value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The custom accumulator value.\n * @returns {*} Returns the accumulated value.\n * @example\n *\n * _.transform([2, 3, 4], function(result, n) {\n *   result.push(n *= n);\n *   return n % 2 == 0;\n * }, []);\n * // => [4, 9]\n *\n * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n *   (result[value] || (result[value] = [])).push(key);\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] }\n */\nfunction transform(object, iteratee, accumulator) {\n  var isArr = isArray(object),\n      isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n  iteratee = baseIteratee(iteratee, 4);\n  if (accumulator == null) {\n    var Ctor = object && object.constructor;\n    if (isArrLike) {\n      accumulator = isArr ? new Ctor : [];\n    }\n    else if (isObject(object)) {\n      accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n    }\n    else {\n      accumulator = {};\n    }\n  }\n  (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n    return iteratee(accumulator, value, index, object);\n  });\n  return accumulator;\n}\n\nmodule.exports = transform;\n","var baseToString = require('./_baseToString'),\n    castSlice = require('./_castSlice'),\n    charsEndIndex = require('./_charsEndIndex'),\n    charsStartIndex = require('./_charsStartIndex'),\n    stringToArray = require('./_stringToArray'),\n    toString = require('./toString');\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/**\n * Removes leading and trailing whitespace or specified characters from `string`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to trim.\n * @param {string} [chars=whitespace] The characters to trim.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {string} Returns the trimmed string.\n * @example\n *\n * _.trim('  abc  ');\n * // => 'abc'\n *\n * _.trim('-_-abc-_-', '_-');\n * // => 'abc'\n *\n * _.map(['  foo  ', '  bar  '], _.trim);\n * // => ['foo', 'bar']\n */\nfunction trim(string, chars, guard) {\n  string = toString(string);\n  if (string && (guard || chars === undefined)) {\n    return string.replace(reTrim, '');\n  }\n  if (!string || !(chars = baseToString(chars))) {\n    return string;\n  }\n  var strSymbols = stringToArray(string),\n      chrSymbols = stringToArray(chars),\n      start = charsStartIndex(strSymbols, chrSymbols),\n      end = charsEndIndex(strSymbols, chrSymbols) + 1;\n\n  return castSlice(strSymbols, start, end).join('');\n}\n\nmodule.exports = trim;\n","var baseFlatten = require('./_baseFlatten'),\n    baseRest = require('./_baseRest'),\n    baseUniq = require('./_baseUniq'),\n    isArrayLikeObject = require('./isArrayLikeObject');\n\n/**\n * Creates an array of unique values, in order, from all given arrays using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.union([2], [1, 2]);\n * // => [2, 1]\n */\nvar union = baseRest(function(arrays) {\n  return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n});\n\nmodule.exports = union;\n","var baseUniq = require('./_baseUniq');\n\n/**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each element\n * is kept. The order of result values is determined by the order they occur\n * in the array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\nfunction uniq(array) {\n  return (array && array.length) ? baseUniq(array) : [];\n}\n\nmodule.exports = uniq;\n","var createCaseFirst = require('./_createCaseFirst');\n\n/**\n * Converts the first character of `string` to upper case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.upperFirst('fred');\n * // => 'Fred'\n *\n * _.upperFirst('FRED');\n * // => 'FRED'\n */\nvar upperFirst = createCaseFirst('toUpperCase');\n\nmodule.exports = upperFirst;\n","var baseValues = require('./_baseValues'),\n    keys = require('./keys');\n\n/**\n * Creates an array of the own enumerable string keyed property values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.values(new Foo);\n * // => [1, 2] (iteration order is not guaranteed)\n *\n * _.values('hi');\n * // => ['h', 'i']\n */\nfunction values(object) {\n  return object == null ? [] : baseValues(object, keys(object));\n}\n\nmodule.exports = values;\n","var baseDifference = require('./_baseDifference'),\n    baseRest = require('./_baseRest'),\n    isArrayLikeObject = require('./isArrayLikeObject');\n\n/**\n * Creates an array excluding all given values using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.pull`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...*} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.xor\n * @example\n *\n * _.without([2, 1, 2, 3], 1, 2);\n * // => [3]\n */\nvar without = baseRest(function(array, values) {\n  return isArrayLikeObject(array)\n    ? baseDifference(array, values)\n    : [];\n});\n\nmodule.exports = without;\n","var asciiWords = require('./_asciiWords'),\n    hasUnicodeWord = require('./_hasUnicodeWord'),\n    toString = require('./toString'),\n    unicodeWords = require('./_unicodeWords');\n\n/**\n * Splits `string` into an array of its words.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {RegExp|string} [pattern] The pattern to match words.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the words of `string`.\n * @example\n *\n * _.words('fred, barney, & pebbles');\n * // => ['fred', 'barney', 'pebbles']\n *\n * _.words('fred, barney, & pebbles', /[^, ]+/g);\n * // => ['fred', 'barney', '&', 'pebbles']\n */\nfunction words(string, pattern, guard) {\n  string = toString(string);\n  pattern = guard ? undefined : pattern;\n\n  if (pattern === undefined) {\n    return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n  }\n  return string.match(pattern) || [];\n}\n\nmodule.exports = words;\n","var LazyWrapper = require('./_LazyWrapper'),\n    LodashWrapper = require('./_LodashWrapper'),\n    baseLodash = require('./_baseLodash'),\n    isArray = require('./isArray'),\n    isObjectLike = require('./isObjectLike'),\n    wrapperClone = require('./_wrapperClone');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates a `lodash` object which wraps `value` to enable implicit method\n * chain sequences. Methods that operate on and return arrays, collections,\n * and functions can be chained together. Methods that retrieve a single value\n * or may return a primitive value will automatically end the chain sequence\n * and return the unwrapped value. Otherwise, the value must be unwrapped\n * with `_#value`.\n *\n * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n * enabled using `_.chain`.\n *\n * The execution of chained methods is lazy, that is, it's deferred until\n * `_#value` is implicitly or explicitly called.\n *\n * Lazy evaluation allows several methods to support shortcut fusion.\n * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n * the creation of intermediate arrays and can greatly reduce the number of\n * iteratee executions. Sections of a chain sequence qualify for shortcut\n * fusion if the section is applied to an array and iteratees accept only\n * one argument. The heuristic for whether a section qualifies for shortcut\n * fusion is subject to change.\n *\n * Chaining is supported in custom builds as long as the `_#value` method is\n * directly or indirectly included in the build.\n *\n * In addition to lodash methods, wrappers have `Array` and `String` methods.\n *\n * The wrapper `Array` methods are:\n * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n *\n * The wrapper `String` methods are:\n * `replace` and `split`\n *\n * The wrapper methods that support shortcut fusion are:\n * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n *\n * The chainable wrapper methods are:\n * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n * `zipObject`, `zipObjectDeep`, and `zipWith`\n *\n * The wrapper methods that are **not** chainable by default are:\n * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n * `upperFirst`, `value`, and `words`\n *\n * @name _\n * @constructor\n * @category Seq\n * @param {*} value The value to wrap in a `lodash` instance.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n *   return n * n;\n * }\n *\n * var wrapped = _([1, 2, 3]);\n *\n * // Returns an unwrapped value.\n * wrapped.reduce(_.add);\n * // => 6\n *\n * // Returns a wrapped value.\n * var squares = wrapped.map(square);\n *\n * _.isArray(squares);\n * // => false\n *\n * _.isArray(squares.value());\n * // => true\n */\nfunction lodash(value) {\n  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n    if (value instanceof LodashWrapper) {\n      return value;\n    }\n    if (hasOwnProperty.call(value, '__wrapped__')) {\n      return wrapperClone(value);\n    }\n  }\n  return new LodashWrapper(value);\n}\n\n// Ensure wrappers are instances of `baseLodash`.\nlodash.prototype = baseLodash.prototype;\nlodash.prototype.constructor = lodash;\n\nmodule.exports = lodash;\n","import React, { Component } from 'react';\nimport _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';\nimport PropTypes from 'prop-types';\nimport warning from 'tiny-warning';\n\nvar MAX_SIGNED_31_BIT_INT = 1073741823;\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {};\n\nfunction getUniqueId() {\n  var key = '__global_unique_id__';\n  return commonjsGlobal[key] = (commonjsGlobal[key] || 0) + 1;\n}\n\nfunction objectIs(x, y) {\n  if (x === y) {\n    return x !== 0 || 1 / x === 1 / y;\n  } else {\n    return x !== x && y !== y;\n  }\n}\n\nfunction createEventEmitter(value) {\n  var handlers = [];\n  return {\n    on: function on(handler) {\n      handlers.push(handler);\n    },\n    off: function off(handler) {\n      handlers = handlers.filter(function (h) {\n        return h !== handler;\n      });\n    },\n    get: function get() {\n      return value;\n    },\n    set: function set(newValue, changedBits) {\n      value = newValue;\n      handlers.forEach(function (handler) {\n        return handler(value, changedBits);\n      });\n    }\n  };\n}\n\nfunction onlyChild(children) {\n  return Array.isArray(children) ? children[0] : children;\n}\n\nfunction createReactContext(defaultValue, calculateChangedBits) {\n  var _Provider$childContex, _Consumer$contextType;\n\n  var contextProp = '__create-react-context-' + getUniqueId() + '__';\n\n  var Provider = /*#__PURE__*/function (_Component) {\n    _inheritsLoose(Provider, _Component);\n\n    function Provider() {\n      var _this;\n\n      _this = _Component.apply(this, arguments) || this;\n      _this.emitter = createEventEmitter(_this.props.value);\n      return _this;\n    }\n\n    var _proto = Provider.prototype;\n\n    _proto.getChildContext = function getChildContext() {\n      var _ref;\n\n      return _ref = {}, _ref[contextProp] = this.emitter, _ref;\n    };\n\n    _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {\n      if (this.props.value !== nextProps.value) {\n        var oldValue = this.props.value;\n        var newValue = nextProps.value;\n        var changedBits;\n\n        if (objectIs(oldValue, newValue)) {\n          changedBits = 0;\n        } else {\n          changedBits = typeof calculateChangedBits === 'function' ? calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;\n\n          if (process.env.NODE_ENV !== 'production') {\n            warning((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: ' + changedBits);\n          }\n\n          changedBits |= 0;\n\n          if (changedBits !== 0) {\n            this.emitter.set(nextProps.value, changedBits);\n          }\n        }\n      }\n    };\n\n    _proto.render = function render() {\n      return this.props.children;\n    };\n\n    return Provider;\n  }(Component);\n\n  Provider.childContextTypes = (_Provider$childContex = {}, _Provider$childContex[contextProp] = PropTypes.object.isRequired, _Provider$childContex);\n\n  var Consumer = /*#__PURE__*/function (_Component2) {\n    _inheritsLoose(Consumer, _Component2);\n\n    function Consumer() {\n      var _this2;\n\n      _this2 = _Component2.apply(this, arguments) || this;\n      _this2.state = {\n        value: _this2.getValue()\n      };\n\n      _this2.onUpdate = function (newValue, changedBits) {\n        var observedBits = _this2.observedBits | 0;\n\n        if ((observedBits & changedBits) !== 0) {\n          _this2.setState({\n            value: _this2.getValue()\n          });\n        }\n      };\n\n      return _this2;\n    }\n\n    var _proto2 = Consumer.prototype;\n\n    _proto2.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {\n      var observedBits = nextProps.observedBits;\n      this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT : observedBits;\n    };\n\n    _proto2.componentDidMount = function componentDidMount() {\n      if (this.context[contextProp]) {\n        this.context[contextProp].on(this.onUpdate);\n      }\n\n      var observedBits = this.props.observedBits;\n      this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT : observedBits;\n    };\n\n    _proto2.componentWillUnmount = function componentWillUnmount() {\n      if (this.context[contextProp]) {\n        this.context[contextProp].off(this.onUpdate);\n      }\n    };\n\n    _proto2.getValue = function getValue() {\n      if (this.context[contextProp]) {\n        return this.context[contextProp].get();\n      } else {\n        return defaultValue;\n      }\n    };\n\n    _proto2.render = function render() {\n      return onlyChild(this.props.children)(this.state.value);\n    };\n\n    return Consumer;\n  }(Component);\n\n  Consumer.contextTypes = (_Consumer$contextType = {}, _Consumer$contextType[contextProp] = PropTypes.object, _Consumer$contextType);\n  return {\n    Provider: Provider,\n    Consumer: Consumer\n  };\n}\n\nvar index = React.createContext || createReactContext;\n\nexport default index;\n","/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc');  // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n","'use strict';\n\nvar numberIsNaN = function (value) {\n\treturn value !== value;\n};\n\nmodule.exports = function is(a, b) {\n\tif (a === 0 && b === 0) {\n\t\treturn 1 / a === 1 / b;\n\t}\n\tif (a === b) {\n\t\treturn true;\n\t}\n\tif (numberIsNaN(a) && numberIsNaN(b)) {\n\t\treturn true;\n\t}\n\treturn false;\n};\n\n","'use strict';\n\nvar define = require('define-properties');\nvar callBind = require('es-abstract/helpers/callBind');\n\nvar implementation = require('./implementation');\nvar getPolyfill = require('./polyfill');\nvar shim = require('./shim');\n\nvar polyfill = callBind(getPolyfill(), Object);\n\ndefine(polyfill, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = polyfill;\n","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = function getPolyfill() {\n\treturn typeof Object.is === 'function' ? Object.is : implementation;\n};\n","'use strict';\n\nvar getPolyfill = require('./polyfill');\nvar define = require('define-properties');\n\nmodule.exports = function shimObjectIs() {\n\tvar polyfill = getPolyfill();\n\tdefine(Object, { is: polyfill }, {\n\t\tis: function testObjectIs() {\n\t\t\treturn Object.is !== polyfill;\n\t\t}\n\t});\n\treturn polyfill;\n};\n","'use strict';\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = require('./isArguments'); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n","'use strict';\n\nvar slice = Array.prototype.slice;\nvar isArgs = require('./isArguments');\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : require('./implementation');\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n","'use strict';\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n","export default typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';\n","import isBrowser from './isBrowser';\n\nconst timeoutDuration = (function(){\n  const longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\n  for (let i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n    if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n      return 1;\n    }\n  }\n  return 0;\n}());\n\nexport function microtaskDebounce(fn) {\n  let called = false\n  return () => {\n    if (called) {\n      return\n    }\n    called = true\n    window.Promise.resolve().then(() => {\n      called = false\n      fn()\n    })\n  }\n}\n\nexport function taskDebounce(fn) {\n  let scheduled = false;\n  return () => {\n    if (!scheduled) {\n      scheduled = true;\n      setTimeout(() => {\n        scheduled = false;\n        fn();\n      }, timeoutDuration);\n    }\n  };\n}\n\nconst supportsMicroTasks = isBrowser && window.Promise\n\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nexport default (supportsMicroTasks\n  ? microtaskDebounce\n  : taskDebounce);\n","/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nexport default function isFunction(functionToCheck) {\n  const getType = {};\n  return (\n    functionToCheck &&\n    getType.toString.call(functionToCheck) === '[object Function]'\n  );\n}\n","/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nexport default function getStyleComputedProperty(element, property) {\n  if (element.nodeType !== 1) {\n    return [];\n  }\n  // NOTE: 1 DOM access here\n  const window = element.ownerDocument.defaultView;\n  const css = window.getComputedStyle(element, null);\n  return property ? css[property] : css;\n}\n","/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nexport default function getParentNode(element) {\n  if (element.nodeName === 'HTML') {\n    return element;\n  }\n  return element.parentNode || element.host;\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport getParentNode from './getParentNode';\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nexport default function getScrollParent(element) {\n  // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n  if (!element) {\n    return document.body\n  }\n\n  switch (element.nodeName) {\n    case 'HTML':\n    case 'BODY':\n      return element.ownerDocument.body\n    case '#document':\n      return element.body\n  }\n\n  // Firefox want us to check `-x` and `-y` variations as well\n  const { overflow, overflowX, overflowY } = getStyleComputedProperty(element);\n  if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n    return element;\n  }\n\n  return getScrollParent(getParentNode(element));\n}\n","/**\n * Returns the reference node of the reference object, or the reference object itself.\n * @method\n * @memberof Popper.Utils\n * @param {Element|Object} reference - the reference element (the popper will be relative to this)\n * @returns {Element} parent\n */\nexport default function getReferenceNode(reference) {\n  return reference && reference.referenceNode ? reference.referenceNode : reference;\n}\n","import isBrowser from './isBrowser';\n\nconst isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nconst isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nexport default function isIE(version) {\n  if (version === 11) {\n    return isIE11;\n  }\n  if (version === 10) {\n    return isIE10;\n  }\n  return isIE11 || isIE10;\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport isIE from './isIE';\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nexport default function getOffsetParent(element) {\n  if (!element) {\n    return document.documentElement;\n  }\n\n  const noOffsetParent = isIE(10) ? document.body : null;\n\n  // NOTE: 1 DOM access here\n  let offsetParent = element.offsetParent || null;\n  // Skip hidden elements which don't have an offsetParent\n  while (offsetParent === noOffsetParent && element.nextElementSibling) {\n    offsetParent = (element = element.nextElementSibling).offsetParent;\n  }\n\n  const nodeName = offsetParent && offsetParent.nodeName;\n\n  if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n    return element ? element.ownerDocument.documentElement : document.documentElement;\n  }\n\n  // .offsetParent will return the closest TH, TD or TABLE in case\n  // no offsetParent is present, I hate this job...\n  if (\n    ['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 &&\n    getStyleComputedProperty(offsetParent, 'position') === 'static'\n  ) {\n    return getOffsetParent(offsetParent);\n  }\n\n  return offsetParent;\n}\n","import getOffsetParent from './getOffsetParent';\n\nexport default function isOffsetContainer(element) {\n  const { nodeName } = element;\n  if (nodeName === 'BODY') {\n    return false;\n  }\n  return (\n    nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element\n  );\n}\n","/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nexport default function getRoot(node) {\n  if (node.parentNode !== null) {\n    return getRoot(node.parentNode);\n  }\n\n  return node;\n}\n","import isOffsetContainer from './isOffsetContainer';\nimport getRoot from './getRoot';\nimport getOffsetParent from './getOffsetParent';\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nexport default function findCommonOffsetParent(element1, element2) {\n  // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n  if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n    return document.documentElement;\n  }\n\n  // Here we make sure to give as \"start\" the element that comes first in the DOM\n  const order =\n    element1.compareDocumentPosition(element2) &\n    Node.DOCUMENT_POSITION_FOLLOWING;\n  const start = order ? element1 : element2;\n  const end = order ? element2 : element1;\n\n  // Get common ancestor container\n  const range = document.createRange();\n  range.setStart(start, 0);\n  range.setEnd(end, 0);\n  const { commonAncestorContainer } = range;\n\n  // Both nodes are inside #document\n  if (\n    (element1 !== commonAncestorContainer &&\n      element2 !== commonAncestorContainer) ||\n    start.contains(end)\n  ) {\n    if (isOffsetContainer(commonAncestorContainer)) {\n      return commonAncestorContainer;\n    }\n\n    return getOffsetParent(commonAncestorContainer);\n  }\n\n  // one of the nodes is inside shadowDOM, find which one\n  const element1root = getRoot(element1);\n  if (element1root.host) {\n    return findCommonOffsetParent(element1root.host, element2);\n  } else {\n    return findCommonOffsetParent(element1, getRoot(element2).host);\n  }\n}\n","/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nexport default function getScroll(element, side = 'top') {\n  const upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n  const nodeName = element.nodeName;\n\n  if (nodeName === 'BODY' || nodeName === 'HTML') {\n    const html = element.ownerDocument.documentElement;\n    const scrollingElement = element.ownerDocument.scrollingElement || html;\n    return scrollingElement[upperSide];\n  }\n\n  return element[upperSide];\n}\n","import getScroll from './getScroll';\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nexport default function includeScroll(rect, element, subtract = false) {\n  const scrollTop = getScroll(element, 'top');\n  const scrollLeft = getScroll(element, 'left');\n  const modifier = subtract ? -1 : 1;\n  rect.top += scrollTop * modifier;\n  rect.bottom += scrollTop * modifier;\n  rect.left += scrollLeft * modifier;\n  rect.right += scrollLeft * modifier;\n  return rect;\n}\n","/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nexport default function getBordersSize(styles, axis) {\n  const sideA = axis === 'x' ? 'Left' : 'Top';\n  const sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n  return (\n    parseFloat(styles[`border${sideA}Width`]) +\n    parseFloat(styles[`border${sideB}Width`])\n  );\n}\n","import isIE from './isIE';\n\nfunction getSize(axis, body, html, computedStyle) {\n  return Math.max(\n    body[`offset${axis}`],\n    body[`scroll${axis}`],\n    html[`client${axis}`],\n    html[`offset${axis}`],\n    html[`scroll${axis}`],\n    isIE(10)\n      ? (parseInt(html[`offset${axis}`]) + \n      parseInt(computedStyle[`margin${axis === 'Height' ? 'Top' : 'Left'}`]) + \n      parseInt(computedStyle[`margin${axis === 'Height' ? 'Bottom' : 'Right'}`]))\n    : 0 \n  );\n}\n\nexport default function getWindowSizes(document) {\n  const body = document.body;\n  const html = document.documentElement;\n  const computedStyle = isIE(10) && getComputedStyle(html);\n\n  return {\n    height: getSize('Height', body, html, computedStyle),\n    width: getSize('Width', body, html, computedStyle),\n  };\n}\n","/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nexport default function getClientRect(offsets) {\n  return {\n    ...offsets,\n    right: offsets.left + offsets.width,\n    bottom: offsets.top + offsets.height,\n  };\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport getBordersSize from './getBordersSize';\nimport getWindowSizes from './getWindowSizes';\nimport getScroll from './getScroll';\nimport getClientRect from './getClientRect';\nimport isIE from './isIE';\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nexport default function getBoundingClientRect(element) {\n  let rect = {};\n\n  // IE10 10 FIX: Please, don't ask, the element isn't\n  // considered in DOM in some circumstances...\n  // This isn't reproducible in IE10 compatibility mode of IE11\n  try {\n    if (isIE(10)) {\n      rect = element.getBoundingClientRect();\n      const scrollTop = getScroll(element, 'top');\n      const scrollLeft = getScroll(element, 'left');\n      rect.top += scrollTop;\n      rect.left += scrollLeft;\n      rect.bottom += scrollTop;\n      rect.right += scrollLeft;\n    }\n    else {\n      rect = element.getBoundingClientRect();\n    }\n  }\n  catch(e){}\n\n  const result = {\n    left: rect.left,\n    top: rect.top,\n    width: rect.right - rect.left,\n    height: rect.bottom - rect.top,\n  };\n\n  // subtract scrollbar size from sizes\n  const sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};\n  const width =\n    sizes.width || element.clientWidth || result.width;\n  const height =\n    sizes.height || element.clientHeight || result.height;\n\n  let horizScrollbar = element.offsetWidth - width;\n  let vertScrollbar = element.offsetHeight - height;\n\n  // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n  // we make this check conditional for performance reasons\n  if (horizScrollbar || vertScrollbar) {\n    const styles = getStyleComputedProperty(element);\n    horizScrollbar -= getBordersSize(styles, 'x');\n    vertScrollbar -= getBordersSize(styles, 'y');\n\n    result.width -= horizScrollbar;\n    result.height -= vertScrollbar;\n  }\n\n  return getClientRect(result);\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport includeScroll from './includeScroll';\nimport getScrollParent from './getScrollParent';\nimport getBoundingClientRect from './getBoundingClientRect';\nimport runIsIE from './isIE';\nimport getClientRect from './getClientRect';\n\nexport default function getOffsetRectRelativeToArbitraryNode(children, parent, fixedPosition = false) {\n  const isIE10 = runIsIE(10);\n  const isHTML = parent.nodeName === 'HTML';\n  const childrenRect = getBoundingClientRect(children);\n  const parentRect = getBoundingClientRect(parent);\n  const scrollParent = getScrollParent(children);\n\n  const styles = getStyleComputedProperty(parent);\n  const borderTopWidth = parseFloat(styles.borderTopWidth);\n  const borderLeftWidth = parseFloat(styles.borderLeftWidth);\n\n  // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n  if(fixedPosition && isHTML) {\n    parentRect.top = Math.max(parentRect.top, 0);\n    parentRect.left = Math.max(parentRect.left, 0);\n  }\n  let offsets = getClientRect({\n    top: childrenRect.top - parentRect.top - borderTopWidth,\n    left: childrenRect.left - parentRect.left - borderLeftWidth,\n    width: childrenRect.width,\n    height: childrenRect.height,\n  });\n  offsets.marginTop = 0;\n  offsets.marginLeft = 0;\n\n  // Subtract margins of documentElement in case it's being used as parent\n  // we do this only on HTML because it's the only element that behaves\n  // differently when margins are applied to it. The margins are included in\n  // the box of the documentElement, in the other cases not.\n  if (!isIE10 && isHTML) {\n    const marginTop = parseFloat(styles.marginTop);\n    const marginLeft = parseFloat(styles.marginLeft);\n\n    offsets.top -= borderTopWidth - marginTop;\n    offsets.bottom -= borderTopWidth - marginTop;\n    offsets.left -= borderLeftWidth - marginLeft;\n    offsets.right -= borderLeftWidth - marginLeft;\n\n    // Attach marginTop and marginLeft because in some circumstances we may need them\n    offsets.marginTop = marginTop;\n    offsets.marginLeft = marginLeft;\n  }\n\n  if (\n    isIE10 && !fixedPosition\n      ? parent.contains(scrollParent)\n      : parent === scrollParent && scrollParent.nodeName !== 'BODY'\n  ) {\n    offsets = includeScroll(offsets, parent);\n  }\n\n  return offsets;\n}\n","import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode';\nimport getScroll from './getScroll';\nimport getClientRect from './getClientRect';\n\nexport default function getViewportOffsetRectRelativeToArtbitraryNode(element, excludeScroll = false) {\n  const html = element.ownerDocument.documentElement;\n  const relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n  const width = Math.max(html.clientWidth, window.innerWidth || 0);\n  const height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n  const scrollTop = !excludeScroll ? getScroll(html) : 0;\n  const scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n  const offset = {\n    top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n    left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n    width,\n    height,\n  };\n\n  return getClientRect(offset);\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport getParentNode from './getParentNode';\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nexport default function isFixed(element) {\n  const nodeName = element.nodeName;\n  if (nodeName === 'BODY' || nodeName === 'HTML') {\n    return false;\n  }\n  if (getStyleComputedProperty(element, 'position') === 'fixed') {\n    return true;\n  }\n  const parentNode = getParentNode(element);\n  if (!parentNode) {\n    return false;\n  }\n  return isFixed(parentNode);\n}\n","import getStyleComputedProperty from './getStyleComputedProperty';\nimport isIE from './isIE';\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nexport default function getFixedPositionOffsetParent(element) {\n  // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n   if (!element || !element.parentElement || isIE()) {\n    return document.documentElement;\n  }\n  let el = element.parentElement;\n  while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n    el = el.parentElement;\n  }\n  return el || document.documentElement;\n\n}\n","import getScrollParent from './getScrollParent';\nimport getParentNode from './getParentNode';\nimport getReferenceNode from './getReferenceNode';\nimport findCommonOffsetParent from './findCommonOffsetParent';\nimport getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode';\nimport getViewportOffsetRectRelativeToArtbitraryNode from './getViewportOffsetRectRelativeToArtbitraryNode';\nimport getWindowSizes from './getWindowSizes';\nimport isFixed from './isFixed';\nimport getFixedPositionOffsetParent from './getFixedPositionOffsetParent';\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nexport default function getBoundaries(\n  popper,\n  reference,\n  padding,\n  boundariesElement,\n  fixedPosition = false\n) {\n  // NOTE: 1 DOM access here\n\n  let boundaries = { top: 0, left: 0 };\n  const offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n\n  // Handle viewport case\n  if (boundariesElement === 'viewport' ) {\n    boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n  }\n\n  else {\n    // Handle other cases based on DOM element used as boundaries\n    let boundariesNode;\n    if (boundariesElement === 'scrollParent') {\n      boundariesNode = getScrollParent(getParentNode(reference));\n      if (boundariesNode.nodeName === 'BODY') {\n        boundariesNode = popper.ownerDocument.documentElement;\n      }\n    } else if (boundariesElement === 'window') {\n      boundariesNode = popper.ownerDocument.documentElement;\n    } else {\n      boundariesNode = boundariesElement;\n    }\n\n    const offsets = getOffsetRectRelativeToArbitraryNode(\n      boundariesNode,\n      offsetParent,\n      fixedPosition\n    );\n\n    // In case of HTML, we need a different computation\n    if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n      const { height, width } = getWindowSizes(popper.ownerDocument);\n      boundaries.top += offsets.top - offsets.marginTop;\n      boundaries.bottom = height + offsets.top;\n      boundaries.left += offsets.left - offsets.marginLeft;\n      boundaries.right = width + offsets.left;\n    } else {\n      // for all the other DOM elements, this one is good\n      boundaries = offsets;\n    }\n  }\n\n  // Add paddings\n  padding = padding || 0;\n  const isPaddingNumber = typeof padding === 'number';\n  boundaries.left += isPaddingNumber ? padding : padding.left || 0; \n  boundaries.top += isPaddingNumber ? padding : padding.top || 0; \n  boundaries.right -= isPaddingNumber ? padding : padding.right || 0; \n  boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; \n\n  return boundaries;\n}\n","import getBoundaries from '../utils/getBoundaries';\n\nfunction getArea({ width, height }) {\n  return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function computeAutoPlacement(\n  placement,\n  refRect,\n  popper,\n  reference,\n  boundariesElement,\n  padding = 0\n) {\n  if (placement.indexOf('auto') === -1) {\n    return placement;\n  }\n\n  const boundaries = getBoundaries(\n    popper,\n    reference,\n    padding,\n    boundariesElement\n  );\n\n  const rects = {\n    top: {\n      width: boundaries.width,\n      height: refRect.top - boundaries.top,\n    },\n    right: {\n      width: boundaries.right - refRect.right,\n      height: boundaries.height,\n    },\n    bottom: {\n      width: boundaries.width,\n      height: boundaries.bottom - refRect.bottom,\n    },\n    left: {\n      width: refRect.left - boundaries.left,\n      height: boundaries.height,\n    },\n  };\n\n  const sortedAreas = Object.keys(rects)\n    .map(key => ({\n      key,\n      ...rects[key],\n      area: getArea(rects[key]),\n    }))\n    .sort((a, b) => b.area - a.area);\n\n  const filteredAreas = sortedAreas.filter(\n    ({ width, height }) =>\n      width >= popper.clientWidth && height >= popper.clientHeight\n  );\n\n  const computedPlacement = filteredAreas.length > 0\n    ? filteredAreas[0].key\n    : sortedAreas[0].key;\n\n  const variation = placement.split('-')[1];\n\n  return computedPlacement + (variation ? `-${variation}` : '');\n}\n","import findCommonOffsetParent from './findCommonOffsetParent';\nimport getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode';\nimport getFixedPositionOffsetParent from './getFixedPositionOffsetParent';\nimport getReferenceNode from './getReferenceNode';\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nexport default function getReferenceOffsets(state, popper, reference, fixedPosition = null) {\n  const commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n  return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n","/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nexport default function getOuterSizes(element) {\n  const window = element.ownerDocument.defaultView;\n  const styles = window.getComputedStyle(element);\n  const x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);\n  const y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);\n  const result = {\n    width: element.offsetWidth + y,\n    height: element.offsetHeight + x,\n  };\n  return result;\n}\n","/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nexport default function getOppositePlacement(placement) {\n  const hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n  return placement.replace(/left|right|bottom|top/g, matched => hash[matched]);\n}\n","import getOuterSizes from './getOuterSizes';\nimport getOppositePlacement from './getOppositePlacement';\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nexport default function getPopperOffsets(popper, referenceOffsets, placement) {\n  placement = placement.split('-')[0];\n\n  // Get popper node sizes\n  const popperRect = getOuterSizes(popper);\n\n  // Add position, width and height to our offsets object\n  const popperOffsets = {\n    width: popperRect.width,\n    height: popperRect.height,\n  };\n\n  // depending by the popper placement we have to compute its offsets slightly differently\n  const isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n  const mainSide = isHoriz ? 'top' : 'left';\n  const secondarySide = isHoriz ? 'left' : 'top';\n  const measurement = isHoriz ? 'height' : 'width';\n  const secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n  popperOffsets[mainSide] =\n    referenceOffsets[mainSide] +\n    referenceOffsets[measurement] / 2 -\n    popperRect[measurement] / 2;\n  if (placement === secondarySide) {\n    popperOffsets[secondarySide] =\n      referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n  } else {\n    popperOffsets[secondarySide] =\n      referenceOffsets[getOppositePlacement(secondarySide)];\n  }\n\n  return popperOffsets;\n}\n","/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nexport default function find(arr, check) {\n  // use native find if supported\n  if (Array.prototype.find) {\n    return arr.find(check);\n  }\n\n  // use `filter` to obtain the same behavior of `find`\n  return arr.filter(check)[0];\n}\n","import find from './find';\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nexport default function findIndex(arr, prop, value) {\n  // use native findIndex if supported\n  if (Array.prototype.findIndex) {\n    return arr.findIndex(cur => cur[prop] === value);\n  }\n\n  // use `find` + `indexOf` if `findIndex` isn't supported\n  const match = find(arr, obj => obj[prop] === value);\n  return arr.indexOf(match);\n}\n","import isFunction from './isFunction';\nimport findIndex from './findIndex';\nimport getClientRect from '../utils/getClientRect';\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nexport default function runModifiers(modifiers, data, ends) {\n  const modifiersToRun = ends === undefined\n    ? modifiers\n    : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n  modifiersToRun.forEach(modifier => {\n    if (modifier['function']) { // eslint-disable-line dot-notation\n      console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n    }\n    const fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n    if (modifier.enabled && isFunction(fn)) {\n      // Add properties to offsets to make them a complete clientRect object\n      // we do this before each modifier to make sure the previous one doesn't\n      // mess with these values\n      data.offsets.popper = getClientRect(data.offsets.popper);\n      data.offsets.reference = getClientRect(data.offsets.reference);\n\n      data = fn(data, modifier);\n    }\n  });\n\n  return data;\n}\n","import computeAutoPlacement from '../utils/computeAutoPlacement';\nimport getReferenceOffsets from '../utils/getReferenceOffsets';\nimport getPopperOffsets from '../utils/getPopperOffsets';\nimport runModifiers from '../utils/runModifiers';\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nexport default function update() {\n  // if popper is destroyed, don't perform any further update\n  if (this.state.isDestroyed) {\n    return;\n  }\n\n  let data = {\n    instance: this,\n    styles: {},\n    arrowStyles: {},\n    attributes: {},\n    flipped: false,\n    offsets: {},\n  };\n\n  // compute reference element offsets\n  data.offsets.reference = getReferenceOffsets(\n    this.state,\n    this.popper,\n    this.reference,\n    this.options.positionFixed\n  );\n\n  // compute auto placement, store placement inside the data object,\n  // modifiers will be able to edit `placement` if needed\n  // and refer to originalPlacement to know the original value\n  data.placement = computeAutoPlacement(\n    this.options.placement,\n    data.offsets.reference,\n    this.popper,\n    this.reference,\n    this.options.modifiers.flip.boundariesElement,\n    this.options.modifiers.flip.padding\n  );\n\n  // store the computed placement inside `originalPlacement`\n  data.originalPlacement = data.placement;\n\n  data.positionFixed = this.options.positionFixed;\n\n  // compute the popper offsets\n  data.offsets.popper = getPopperOffsets(\n    this.popper,\n    data.offsets.reference,\n    data.placement\n  );\n\n  data.offsets.popper.position = this.options.positionFixed\n    ? 'fixed'\n    : 'absolute';\n\n  // run the modifiers\n  data = runModifiers(this.modifiers, data);\n\n  // the first `update` will call `onCreate` callback\n  // the other ones will call `onUpdate` callback\n  if (!this.state.isCreated) {\n    this.state.isCreated = true;\n    this.options.onCreate(data);\n  } else {\n    this.options.onUpdate(data);\n  }\n}\n","/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nexport default function isModifierEnabled(modifiers, modifierName) {\n  return modifiers.some(\n    ({ name, enabled }) => enabled && name === modifierName\n  );\n}\n","/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nexport default function getSupportedPropertyName(property) {\n  const prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n  const upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n  for (let i = 0; i < prefixes.length; i++) {\n    const prefix = prefixes[i];\n    const toCheck = prefix ? `${prefix}${upperProp}` : property;\n    if (typeof document.body.style[toCheck] !== 'undefined') {\n      return toCheck;\n    }\n  }\n  return null;\n}\n","import isModifierEnabled from '../utils/isModifierEnabled';\nimport getSupportedPropertyName from '../utils/getSupportedPropertyName';\n\n/**\n * Destroys the popper.\n * @method\n * @memberof Popper\n */\nexport default function destroy() {\n  this.state.isDestroyed = true;\n\n  // touch DOM only if `applyStyle` modifier is enabled\n  if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n    this.popper.removeAttribute('x-placement');\n    this.popper.style.position = '';\n    this.popper.style.top = '';\n    this.popper.style.left = '';\n    this.popper.style.right = '';\n    this.popper.style.bottom = '';\n    this.popper.style.willChange = '';\n    this.popper.style[getSupportedPropertyName('transform')] = '';\n  }\n\n  this.disableEventListeners();\n\n  // remove the popper if user explicitly asked for the deletion on destroy\n  // do not use `remove` because IE11 doesn't support it\n  if (this.options.removeOnDestroy) {\n    this.popper.parentNode.removeChild(this.popper);\n  }\n  return this;\n}\n","/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nexport default function getWindow(element) {\n  const ownerDocument = element.ownerDocument;\n  return ownerDocument ? ownerDocument.defaultView : window;\n}\n","import getScrollParent from './getScrollParent';\nimport getWindow from './getWindow';\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n  const isBody = scrollParent.nodeName === 'BODY';\n  const target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n  target.addEventListener(event, callback, { passive: true });\n\n  if (!isBody) {\n    attachToScrollParents(\n      getScrollParent(target.parentNode),\n      event,\n      callback,\n      scrollParents\n    );\n  }\n  scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nexport default function setupEventListeners(\n  reference,\n  options,\n  state,\n  updateBound\n) {\n  // Resize event listener on window\n  state.updateBound = updateBound;\n  getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n  // Scroll event listener on scroll parents\n  const scrollElement = getScrollParent(reference);\n  attachToScrollParents(\n    scrollElement,\n    'scroll',\n    state.updateBound,\n    state.scrollParents\n  );\n  state.scrollElement = scrollElement;\n  state.eventsEnabled = true;\n\n  return state;\n}\n","import setupEventListeners from '../utils/setupEventListeners';\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nexport default function enableEventListeners() {\n  if (!this.state.eventsEnabled) {\n    this.state = setupEventListeners(\n      this.reference,\n      this.options,\n      this.state,\n      this.scheduleUpdate\n    );\n  }\n}\n","import getWindow from './getWindow';\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nexport default function removeEventListeners(reference, state) {\n  // Remove resize event listener on window\n  getWindow(reference).removeEventListener('resize', state.updateBound);\n\n  // Remove scroll event listener on scroll parents\n  state.scrollParents.forEach(target => {\n    target.removeEventListener('scroll', state.updateBound);\n  });\n\n  // Reset state\n  state.updateBound = null;\n  state.scrollParents = [];\n  state.scrollElement = null;\n  state.eventsEnabled = false;\n  return state;\n}\n","import removeEventListeners from '../utils/removeEventListeners';\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger `onUpdate` callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nexport default function disableEventListeners() {\n  if (this.state.eventsEnabled) {\n    cancelAnimationFrame(this.scheduleUpdate);\n    this.state = removeEventListeners(this.reference, this.state);\n  }\n}\n","/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nexport default function isNumeric(n) {\n  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n","import isNumeric from './isNumeric';\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nexport default function setStyles(element, styles) {\n  Object.keys(styles).forEach(prop => {\n    let unit = '';\n    // add unit if the value is numeric and is one of the following\n    if (\n      ['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !==\n        -1 &&\n      isNumeric(styles[prop])\n    ) {\n      unit = 'px';\n    }\n    element.style[prop] = styles[prop] + unit;\n  });\n}\n","/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nexport default function setAttributes(element, attributes) {\n  Object.keys(attributes).forEach(function(prop) {\n    const value = attributes[prop];\n    if (value !== false) {\n      element.setAttribute(prop, attributes[prop]);\n    } else {\n      element.removeAttribute(prop);\n    }\n  });\n}\n","import setStyles from '../utils/setStyles';\nimport setAttributes from '../utils/setAttributes';\nimport getReferenceOffsets from '../utils/getReferenceOffsets';\nimport computeAutoPlacement from '../utils/computeAutoPlacement';\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nexport default function applyStyle(data) {\n  // any property present in `data.styles` will be applied to the popper,\n  // in this way we can make the 3rd party modifiers add custom styles to it\n  // Be aware, modifiers could override the properties defined in the previous\n  // lines of this modifier!\n  setStyles(data.instance.popper, data.styles);\n\n  // any property present in `data.attributes` will be applied to the popper,\n  // they will be set as HTML attributes of the element\n  setAttributes(data.instance.popper, data.attributes);\n\n  // if arrowElement is defined and arrowStyles has some properties\n  if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n    setStyles(data.arrowElement, data.arrowStyles);\n  }\n\n  return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nexport function applyStyleOnLoad(\n  reference,\n  popper,\n  options,\n  modifierOptions,\n  state\n) {\n  // compute reference element offsets\n  const referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n  // compute auto placement, store placement inside the data object,\n  // modifiers will be able to edit `placement` if needed\n  // and refer to originalPlacement to know the original value\n  const placement = computeAutoPlacement(\n    options.placement,\n    referenceOffsets,\n    popper,\n    reference,\n    options.modifiers.flip.boundariesElement,\n    options.modifiers.flip.padding\n  );\n\n  popper.setAttribute('x-placement', placement);\n\n  // Apply `position` to popper before anything else because\n  // without the position applied we can't guarantee correct computations\n  setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n  return options;\n}\n","/**\n * @function\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Boolean} shouldRound - If the offsets should be rounded at all\n * @returns {Object} The popper's position offsets rounded\n *\n * The tale of pixel-perfect positioning. It's still not 100% perfect, but as\n * good as it can be within reason.\n * Discussion here: https://github.com/FezVrasta/popper.js/pull/715\n *\n * Low DPI screens cause a popper to be blurry if not using full pixels (Safari\n * as well on High DPI screens).\n *\n * Firefox prefers no rounding for positioning and does not have blurriness on\n * high DPI screens.\n *\n * Only horizontal placement and left/right values need to be considered.\n */\nexport default function getRoundedOffsets(data, shouldRound) {\n  const { popper, reference } = data.offsets;\n  const { round, floor } = Math;\n  const noRound = v => v;\n  \n  const referenceWidth = round(reference.width);\n  const popperWidth = round(popper.width);\n  \n  const isVertical = ['left', 'right'].indexOf(data.placement) !== -1;\n  const isVariation = data.placement.indexOf('-') !== -1;\n  const sameWidthParity = referenceWidth % 2 === popperWidth % 2;\n  const bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;\n\n  const horizontalToInteger = !shouldRound\n    ? noRound\n    : isVertical || isVariation || sameWidthParity\n    ? round\n    : floor;\n  const verticalToInteger = !shouldRound ? noRound : round;\n\n  return {\n    left: horizontalToInteger(\n      bothOddWidth && !isVariation && shouldRound\n        ? popper.left - 1\n        : popper.left\n    ),\n    top: verticalToInteger(popper.top),\n    bottom: verticalToInteger(popper.bottom),\n    right: horizontalToInteger(popper.right),\n  };\n}\n","import getSupportedPropertyName from '../utils/getSupportedPropertyName';\nimport find from '../utils/find';\nimport getOffsetParent from '../utils/getOffsetParent';\nimport getBoundingClientRect from '../utils/getBoundingClientRect';\nimport getRoundedOffsets from '../utils/getRoundedOffsets';\nimport isBrowser from '../utils/isBrowser';\n\nconst isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function computeStyle(data, options) {\n  const { x, y } = options;\n  const { popper } = data.offsets;\n\n  // Remove this legacy support in Popper.js v2\n  const legacyGpuAccelerationOption = find(\n    data.instance.modifiers,\n    modifier => modifier.name === 'applyStyle'\n  ).gpuAcceleration;\n  if (legacyGpuAccelerationOption !== undefined) {\n    console.warn(\n      'WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'\n    );\n  }\n  const gpuAcceleration =\n    legacyGpuAccelerationOption !== undefined\n      ? legacyGpuAccelerationOption\n      : options.gpuAcceleration;\n\n  const offsetParent = getOffsetParent(data.instance.popper);\n  const offsetParentRect = getBoundingClientRect(offsetParent);\n\n  // Styles\n  const styles = {\n    position: popper.position,\n  };\n\n  const offsets = getRoundedOffsets(\n    data,\n    window.devicePixelRatio < 2 || !isFirefox\n  );\n\n  const sideA = x === 'bottom' ? 'top' : 'bottom';\n  const sideB = y === 'right' ? 'left' : 'right';\n\n  // if gpuAcceleration is set to `true` and transform is supported,\n  //  we use `translate3d` to apply the position to the popper we\n  // automatically use the supported prefixed version if needed\n  const prefixedProperty = getSupportedPropertyName('transform');\n\n  // now, let's make a step back and look at this code closely (wtf?)\n  // If the content of the popper grows once it's been positioned, it\n  // may happen that the popper gets misplaced because of the new content\n  // overflowing its reference element\n  // To avoid this problem, we provide two options (x and y), which allow\n  // the consumer to define the offset origin.\n  // If we position a popper on top of a reference element, we can set\n  // `x` to `top` to make the popper grow towards its top instead of\n  // its bottom.\n  let left, top;\n  if (sideA === 'bottom') {\n    // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)\n    // and not the bottom of the html element\n    if (offsetParent.nodeName === 'HTML') {\n      top = -offsetParent.clientHeight + offsets.bottom;\n    } else {\n      top = -offsetParentRect.height + offsets.bottom;\n    }\n  } else {\n    top = offsets.top;\n  }\n  if (sideB === 'right') {\n    if (offsetParent.nodeName === 'HTML') {\n      left = -offsetParent.clientWidth + offsets.right;\n    } else {\n      left = -offsetParentRect.width + offsets.right;\n    }\n  } else {\n    left = offsets.left;\n  }\n  if (gpuAcceleration && prefixedProperty) {\n    styles[prefixedProperty] = `translate3d(${left}px, ${top}px, 0)`;\n    styles[sideA] = 0;\n    styles[sideB] = 0;\n    styles.willChange = 'transform';\n  } else {\n    // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n    const invertTop = sideA === 'bottom' ? -1 : 1;\n    const invertLeft = sideB === 'right' ? -1 : 1;\n    styles[sideA] = top * invertTop;\n    styles[sideB] = left * invertLeft;\n    styles.willChange = `${sideA}, ${sideB}`;\n  }\n\n  // Attributes\n  const attributes = {\n    'x-placement': data.placement,\n  };\n\n  // Update `data` attributes, styles and arrowStyles\n  data.attributes = { ...attributes, ...data.attributes };\n  data.styles = { ...styles, ...data.styles };\n  data.arrowStyles = { ...data.offsets.arrow, ...data.arrowStyles };\n\n  return data;\n}\n","import find from './find';\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nexport default function isModifierRequired(\n  modifiers,\n  requestingName,\n  requestedName\n) {\n  const requesting = find(modifiers, ({ name }) => name === requestingName);\n\n  const isRequired =\n    !!requesting &&\n    modifiers.some(modifier => {\n      return (\n        modifier.name === requestedName &&\n        modifier.enabled &&\n        modifier.order < requesting.order\n      );\n    });\n\n  if (!isRequired) {\n    const requesting = `\\`${requestingName}\\``;\n    const requested = `\\`${requestedName}\\``;\n    console.warn(\n      `${requested} modifier is required by ${requesting} modifier in order to work, be sure to include it before ${requesting}!`\n    );\n  }\n  return isRequired;\n}\n","import getClientRect from '../utils/getClientRect';\nimport getOuterSizes from '../utils/getOuterSizes';\nimport isModifierRequired from '../utils/isModifierRequired';\nimport getStyleComputedProperty from '../utils/getStyleComputedProperty';\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function arrow(data, options) {\n  // arrow depends on keepTogether in order to work\n  if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n    return data;\n  }\n\n  let arrowElement = options.element;\n\n  // if arrowElement is a string, suppose it's a CSS selector\n  if (typeof arrowElement === 'string') {\n    arrowElement = data.instance.popper.querySelector(arrowElement);\n\n    // if arrowElement is not found, don't run the modifier\n    if (!arrowElement) {\n      return data;\n    }\n  } else {\n    // if the arrowElement isn't a query selector we must check that the\n    // provided DOM node is child of its popper node\n    if (!data.instance.popper.contains(arrowElement)) {\n      console.warn(\n        'WARNING: `arrow.element` must be child of its popper element!'\n      );\n      return data;\n    }\n  }\n\n  const placement = data.placement.split('-')[0];\n  const { popper, reference } = data.offsets;\n  const isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n  const len = isVertical ? 'height' : 'width';\n  const sideCapitalized = isVertical ? 'Top' : 'Left';\n  const side = sideCapitalized.toLowerCase();\n  const altSide = isVertical ? 'left' : 'top';\n  const opSide = isVertical ? 'bottom' : 'right';\n  const arrowElementSize = getOuterSizes(arrowElement)[len];\n\n  //\n  // extends keepTogether behavior making sure the popper and its\n  // reference have enough pixels in conjunction\n  //\n\n  // top/left side\n  if (reference[opSide] - arrowElementSize < popper[side]) {\n    data.offsets.popper[side] -=\n      popper[side] - (reference[opSide] - arrowElementSize);\n  }\n  // bottom/right side\n  if (reference[side] + arrowElementSize > popper[opSide]) {\n    data.offsets.popper[side] +=\n      reference[side] + arrowElementSize - popper[opSide];\n  }\n  data.offsets.popper = getClientRect(data.offsets.popper);\n\n  // compute center of the popper\n  const center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n  // Compute the sideValue using the updated popper offsets\n  // take popper margin in account because we don't have this info available\n  const css = getStyleComputedProperty(data.instance.popper);\n  const popperMarginSide = parseFloat(css[`margin${sideCapitalized}`]);\n  const popperBorderSide = parseFloat(css[`border${sideCapitalized}Width`]);\n  let sideValue =\n    center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n  // prevent arrowElement from being placed not contiguously to its popper\n  sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n  data.arrowElement = arrowElement;\n  data.offsets.arrow = {\n    [side]: Math.round(sideValue),\n    [altSide]: '', // make sure to unset any eventual altSide value from the DOM node\n  };\n\n  return data;\n}\n","/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nexport default function getOppositeVariation(variation) {\n  if (variation === 'end') {\n    return 'start';\n  } else if (variation === 'start') {\n    return 'end';\n  }\n  return variation;\n}\n","/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-end` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nexport default [\n  'auto-start',\n  'auto',\n  'auto-end',\n  'top-start',\n  'top',\n  'top-end',\n  'right-start',\n  'right',\n  'right-end',\n  'bottom-end',\n  'bottom',\n  'bottom-start',\n  'left-end',\n  'left',\n  'left-start',\n];\n","import placements from '../methods/placements';\n\n// Get rid of `auto` `auto-start` and `auto-end`\nconst validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nexport default function clockwise(placement, counter = false) {\n  const index = validPlacements.indexOf(placement);\n  const arr = validPlacements\n    .slice(index + 1)\n    .concat(validPlacements.slice(0, index));\n  return counter ? arr.reverse() : arr;\n}\n","import getOppositePlacement from '../utils/getOppositePlacement';\nimport getOppositeVariation from '../utils/getOppositeVariation';\nimport getPopperOffsets from '../utils/getPopperOffsets';\nimport runModifiers from '../utils/runModifiers';\nimport getBoundaries from '../utils/getBoundaries';\nimport isModifierEnabled from '../utils/isModifierEnabled';\nimport clockwise from '../utils/clockwise';\n\nconst BEHAVIORS = {\n  FLIP: 'flip',\n  CLOCKWISE: 'clockwise',\n  COUNTERCLOCKWISE: 'counterclockwise',\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function flip(data, options) {\n  // if `inner` modifier is enabled, we can't use the `flip` modifier\n  if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n    return data;\n  }\n\n  if (data.flipped && data.placement === data.originalPlacement) {\n    // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n    return data;\n  }\n\n  const boundaries = getBoundaries(\n    data.instance.popper,\n    data.instance.reference,\n    options.padding,\n    options.boundariesElement,\n    data.positionFixed\n  );\n\n  let placement = data.placement.split('-')[0];\n  let placementOpposite = getOppositePlacement(placement);\n  let variation = data.placement.split('-')[1] || '';\n\n  let flipOrder = [];\n\n  switch (options.behavior) {\n    case BEHAVIORS.FLIP:\n      flipOrder = [placement, placementOpposite];\n      break;\n    case BEHAVIORS.CLOCKWISE:\n      flipOrder = clockwise(placement);\n      break;\n    case BEHAVIORS.COUNTERCLOCKWISE:\n      flipOrder = clockwise(placement, true);\n      break;\n    default:\n      flipOrder = options.behavior;\n  }\n\n  flipOrder.forEach((step, index) => {\n    if (placement !== step || flipOrder.length === index + 1) {\n      return data;\n    }\n\n    placement = data.placement.split('-')[0];\n    placementOpposite = getOppositePlacement(placement);\n\n    const popperOffsets = data.offsets.popper;\n    const refOffsets = data.offsets.reference;\n\n    // using floor because the reference offsets may contain decimals we are not going to consider here\n    const floor = Math.floor;\n    const overlapsRef =\n      (placement === 'left' &&\n        floor(popperOffsets.right) > floor(refOffsets.left)) ||\n      (placement === 'right' &&\n        floor(popperOffsets.left) < floor(refOffsets.right)) ||\n      (placement === 'top' &&\n        floor(popperOffsets.bottom) > floor(refOffsets.top)) ||\n      (placement === 'bottom' &&\n        floor(popperOffsets.top) < floor(refOffsets.bottom));\n\n    const overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n    const overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n    const overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n    const overflowsBottom =\n      floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n    const overflowsBoundaries =\n      (placement === 'left' && overflowsLeft) ||\n      (placement === 'right' && overflowsRight) ||\n      (placement === 'top' && overflowsTop) ||\n      (placement === 'bottom' && overflowsBottom);\n\n    // flip the variation if required\n    const isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n\n    // flips variation if reference element overflows boundaries\n    const flippedVariationByRef =\n      !!options.flipVariations &&\n      ((isVertical && variation === 'start' && overflowsLeft) ||\n        (isVertical && variation === 'end' && overflowsRight) ||\n        (!isVertical && variation === 'start' && overflowsTop) ||\n        (!isVertical && variation === 'end' && overflowsBottom));\n\n    // flips variation if popper content overflows boundaries\n    const flippedVariationByContent =\n      !!options.flipVariationsByContent &&\n      ((isVertical && variation === 'start' && overflowsRight) ||\n        (isVertical && variation === 'end' && overflowsLeft) ||\n        (!isVertical && variation === 'start' && overflowsBottom) ||\n        (!isVertical && variation === 'end' && overflowsTop));\n\n    const flippedVariation = flippedVariationByRef || flippedVariationByContent;\n\n    if (overlapsRef || overflowsBoundaries || flippedVariation) {\n      // this boolean to detect any flip loop\n      data.flipped = true;\n\n      if (overlapsRef || overflowsBoundaries) {\n        placement = flipOrder[index + 1];\n      }\n\n      if (flippedVariation) {\n        variation = getOppositeVariation(variation);\n      }\n\n      data.placement = placement + (variation ? '-' + variation : '');\n\n      // this object contains `position`, we want to preserve it along with\n      // any additional property we may add in the future\n      data.offsets.popper = {\n        ...data.offsets.popper,\n        ...getPopperOffsets(\n          data.instance.popper,\n          data.offsets.reference,\n          data.placement\n        ),\n      };\n\n      data = runModifiers(data.instance.modifiers, data, 'flip');\n    }\n  });\n  return data;\n}\n","/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function keepTogether(data) {\n  const { popper, reference } = data.offsets;\n  const placement = data.placement.split('-')[0];\n  const floor = Math.floor;\n  const isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n  const side = isVertical ? 'right' : 'bottom';\n  const opSide = isVertical ? 'left' : 'top';\n  const measurement = isVertical ? 'width' : 'height';\n\n  if (popper[side] < floor(reference[opSide])) {\n    data.offsets.popper[opSide] =\n      floor(reference[opSide]) - popper[measurement];\n  }\n  if (popper[opSide] > floor(reference[side])) {\n    data.offsets.popper[opSide] = floor(reference[side]);\n  }\n\n  return data;\n}\n","import isNumeric from '../utils/isNumeric';\nimport getClientRect from '../utils/getClientRect';\nimport find from '../utils/find';\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nexport function toValue(str, measurement, popperOffsets, referenceOffsets) {\n  // separate value from unit\n  const split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n  const value = +split[1];\n  const unit = split[2];\n\n  // If it's not a number it's an operator, I guess\n  if (!value) {\n    return str;\n  }\n\n  if (unit.indexOf('%') === 0) {\n    let element;\n    switch (unit) {\n      case '%p':\n        element = popperOffsets;\n        break;\n      case '%':\n      case '%r':\n      default:\n        element = referenceOffsets;\n    }\n\n    const rect = getClientRect(element);\n    return rect[measurement] / 100 * value;\n  } else if (unit === 'vh' || unit === 'vw') {\n    // if is a vh or vw, we calculate the size based on the viewport\n    let size;\n    if (unit === 'vh') {\n      size = Math.max(\n        document.documentElement.clientHeight,\n        window.innerHeight || 0\n      );\n    } else {\n      size = Math.max(\n        document.documentElement.clientWidth,\n        window.innerWidth || 0\n      );\n    }\n    return size / 100 * value;\n  } else {\n    // if is an explicit pixel unit, we get rid of the unit and keep the value\n    // if is an implicit unit, it's px, and we return just the value\n    return value;\n  }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nexport function parseOffset(\n  offset,\n  popperOffsets,\n  referenceOffsets,\n  basePlacement\n) {\n  const offsets = [0, 0];\n\n  // Use height if placement is left or right and index is 0 otherwise use width\n  // in this way the first offset will use an axis and the second one\n  // will use the other one\n  const useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n  // Split the offset string to obtain a list of values and operands\n  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n  const fragments = offset.split(/(\\+|\\-)/).map(frag => frag.trim());\n\n  // Detect if the offset string contains a pair of values or a single one\n  // they could be separated by comma or space\n  const divider = fragments.indexOf(\n    find(fragments, frag => frag.search(/,|\\s/) !== -1)\n  );\n\n  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n    console.warn(\n      'Offsets separated by white space(s) are deprecated, use a comma (,) instead.'\n    );\n  }\n\n  // If divider is found, we divide the list of values and operands to divide\n  // them by ofset X and Y.\n  const splitRegex = /\\s*,\\s*|\\s+/;\n  let ops = divider !== -1\n    ? [\n        fragments\n          .slice(0, divider)\n          .concat([fragments[divider].split(splitRegex)[0]]),\n        [fragments[divider].split(splitRegex)[1]].concat(\n          fragments.slice(divider + 1)\n        ),\n      ]\n    : [fragments];\n\n  // Convert the values with units to absolute pixels to allow our computations\n  ops = ops.map((op, index) => {\n    // Most of the units rely on the orientation of the popper\n    const measurement = (index === 1 ? !useHeight : useHeight)\n      ? 'height'\n      : 'width';\n    let mergeWithPrevious = false;\n    return (\n      op\n        // This aggregates any `+` or `-` sign that aren't considered operators\n        // e.g.: 10 + +5 => [10, +, +5]\n        .reduce((a, b) => {\n          if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n            a[a.length - 1] = b;\n            mergeWithPrevious = true;\n            return a;\n          } else if (mergeWithPrevious) {\n            a[a.length - 1] += b;\n            mergeWithPrevious = false;\n            return a;\n          } else {\n            return a.concat(b);\n          }\n        }, [])\n        // Here we convert the string values into number values (in px)\n        .map(str => toValue(str, measurement, popperOffsets, referenceOffsets))\n    );\n  });\n\n  // Loop trough the offsets arrays and execute the operations\n  ops.forEach((op, index) => {\n    op.forEach((frag, index2) => {\n      if (isNumeric(frag)) {\n        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n      }\n    });\n  });\n  return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nexport default function offset(data, { offset }) {\n  const { placement, offsets: { popper, reference } } = data;\n  const basePlacement = placement.split('-')[0];\n\n  let offsets;\n  if (isNumeric(+offset)) {\n    offsets = [+offset, 0];\n  } else {\n    offsets = parseOffset(offset, popper, reference, basePlacement);\n  }\n\n  if (basePlacement === 'left') {\n    popper.top += offsets[0];\n    popper.left -= offsets[1];\n  } else if (basePlacement === 'right') {\n    popper.top += offsets[0];\n    popper.left += offsets[1];\n  } else if (basePlacement === 'top') {\n    popper.left += offsets[0];\n    popper.top -= offsets[1];\n  } else if (basePlacement === 'bottom') {\n    popper.left += offsets[0];\n    popper.top += offsets[1];\n  }\n\n  data.popper = popper;\n  return data;\n}\n","import getOffsetParent from '../utils/getOffsetParent';\nimport getBoundaries from '../utils/getBoundaries';\nimport getSupportedPropertyName from '../utils/getSupportedPropertyName';\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function preventOverflow(data, options) {\n  let boundariesElement =\n    options.boundariesElement || getOffsetParent(data.instance.popper);\n\n  // If offsetParent is the reference element, we really want to\n  // go one step up and use the next offsetParent as reference to\n  // avoid to make this modifier completely useless and look like broken\n  if (data.instance.reference === boundariesElement) {\n    boundariesElement = getOffsetParent(boundariesElement);\n  }\n\n  // NOTE: DOM access here\n  // resets the popper's position so that the document size can be calculated excluding\n  // the size of the popper element itself\n  const transformProp = getSupportedPropertyName('transform');\n  const popperStyles = data.instance.popper.style; // assignment to help minification\n  const { top, left, [transformProp]: transform } = popperStyles;\n  popperStyles.top = '';\n  popperStyles.left = '';\n  popperStyles[transformProp] = '';\n\n  const boundaries = getBoundaries(\n    data.instance.popper,\n    data.instance.reference,\n    options.padding,\n    boundariesElement,\n    data.positionFixed\n  );\n\n  // NOTE: DOM access here\n  // restores the original style properties after the offsets have been computed\n  popperStyles.top = top;\n  popperStyles.left = left;\n  popperStyles[transformProp] = transform;\n\n  options.boundaries = boundaries;\n\n  const order = options.priority;\n  let popper = data.offsets.popper;\n\n  const check = {\n    primary(placement) {\n      let value = popper[placement];\n      if (\n        popper[placement] < boundaries[placement] &&\n        !options.escapeWithReference\n      ) {\n        value = Math.max(popper[placement], boundaries[placement]);\n      }\n      return { [placement]: value };\n    },\n    secondary(placement) {\n      const mainSide = placement === 'right' ? 'left' : 'top';\n      let value = popper[mainSide];\n      if (\n        popper[placement] > boundaries[placement] &&\n        !options.escapeWithReference\n      ) {\n        value = Math.min(\n          popper[mainSide],\n          boundaries[placement] -\n            (placement === 'right' ? popper.width : popper.height)\n        );\n      }\n      return { [mainSide]: value };\n    },\n  };\n\n  order.forEach(placement => {\n    const side =\n      ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n    popper = { ...popper, ...check[side](placement) };\n  });\n\n  data.offsets.popper = popper;\n\n  return data;\n}\n","/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function shift(data) {\n  const placement = data.placement;\n  const basePlacement = placement.split('-')[0];\n  const shiftvariation = placement.split('-')[1];\n\n  // if shift shiftvariation is specified, run the modifier\n  if (shiftvariation) {\n    const { reference, popper } = data.offsets;\n    const isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n    const side = isVertical ? 'left' : 'top';\n    const measurement = isVertical ? 'width' : 'height';\n\n    const shiftOffsets = {\n      start: { [side]: reference[side] },\n      end: {\n        [side]: reference[side] + reference[measurement] - popper[measurement],\n      },\n    };\n\n    data.offsets.popper = { ...popper, ...shiftOffsets[shiftvariation] };\n  }\n\n  return data;\n}\n","import isModifierRequired from '../utils/isModifierRequired';\nimport find from '../utils/find';\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function hide(data) {\n  if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n    return data;\n  }\n\n  const refRect = data.offsets.reference;\n  const bound = find(\n    data.instance.modifiers,\n    modifier => modifier.name === 'preventOverflow'\n  ).boundaries;\n\n  if (\n    refRect.bottom < bound.top ||\n    refRect.left > bound.right ||\n    refRect.top > bound.bottom ||\n    refRect.right < bound.left\n  ) {\n    // Avoid unnecessary DOM access if visibility hasn't changed\n    if (data.hide === true) {\n      return data;\n    }\n\n    data.hide = true;\n    data.attributes['x-out-of-boundaries'] = '';\n  } else {\n    // Avoid unnecessary DOM access if visibility hasn't changed\n    if (data.hide === false) {\n      return data;\n    }\n\n    data.hide = false;\n    data.attributes['x-out-of-boundaries'] = false;\n  }\n\n  return data;\n}\n","import getClientRect from '../utils/getClientRect';\nimport getOppositePlacement from '../utils/getOppositePlacement';\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nexport default function inner(data) {\n  const placement = data.placement;\n  const basePlacement = placement.split('-')[0];\n  const { popper, reference } = data.offsets;\n  const isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n  const subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n  popper[isHoriz ? 'left' : 'top'] =\n    reference[basePlacement] -\n    (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n  data.placement = getOppositePlacement(placement);\n  data.offsets.popper = getClientRect(popper);\n\n  return data;\n}\n","import applyStyle, { applyStyleOnLoad } from './applyStyle';\nimport computeStyle from './computeStyle';\nimport arrow from './arrow';\nimport flip from './flip';\nimport keepTogether from './keepTogether';\nimport offset from './offset';\nimport preventOverflow from './preventOverflow';\nimport shift from './shift';\nimport hide from './hide';\nimport inner from './inner';\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nexport default {\n  /**\n   * Modifier used to shift the popper on the start or end of its reference\n   * element.<br />\n   * It will read the variation of the `placement` property.<br />\n   * It can be one either `-end` or `-start`.\n   * @memberof modifiers\n   * @inner\n   */\n  shift: {\n    /** @prop {number} order=100 - Index used to define the order of execution */\n    order: 100,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: shift,\n  },\n\n  /**\n   * The `offset` modifier can shift your popper on both its axis.\n   *\n   * It accepts the following units:\n   * - `px` or unit-less, interpreted as pixels\n   * - `%` or `%r`, percentage relative to the length of the reference element\n   * - `%p`, percentage relative to the length of the popper element\n   * - `vw`, CSS viewport width unit\n   * - `vh`, CSS viewport height unit\n   *\n   * For length is intended the main axis relative to the placement of the popper.<br />\n   * This means that if the placement is `top` or `bottom`, the length will be the\n   * `width`. In case of `left` or `right`, it will be the `height`.\n   *\n   * You can provide a single value (as `Number` or `String`), or a pair of values\n   * as `String` divided by a comma or one (or more) white spaces.<br />\n   * The latter is a deprecated method because it leads to confusion and will be\n   * removed in v2.<br />\n   * Additionally, it accepts additions and subtractions between different units.\n   * Note that multiplications and divisions aren't supported.\n   *\n   * Valid examples are:\n   * ```\n   * 10\n   * '10%'\n   * '10, 10'\n   * '10%, 10'\n   * '10 + 10%'\n   * '10 - 5vh + 3%'\n   * '-10px + 5vh, 5px - 6%'\n   * ```\n   * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n   * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n   * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).\n   *\n   * @memberof modifiers\n   * @inner\n   */\n  offset: {\n    /** @prop {number} order=200 - Index used to define the order of execution */\n    order: 200,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: offset,\n    /** @prop {Number|String} offset=0\n     * The offset value as described in the modifier description\n     */\n    offset: 0,\n  },\n\n  /**\n   * Modifier used to prevent the popper from being positioned outside the boundary.\n   *\n   * A scenario exists where the reference itself is not within the boundaries.<br />\n   * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n   * In this case we need to decide whether the popper should either:\n   *\n   * - detach from the reference and remain \"trapped\" in the boundaries, or\n   * - if it should ignore the boundary and \"escape with its reference\"\n   *\n   * When `escapeWithReference` is set to`true` and reference is completely\n   * outside its boundaries, the popper will overflow (or completely leave)\n   * the boundaries in order to remain attached to the edge of the reference.\n   *\n   * @memberof modifiers\n   * @inner\n   */\n  preventOverflow: {\n    /** @prop {number} order=300 - Index used to define the order of execution */\n    order: 300,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: preventOverflow,\n    /**\n     * @prop {Array} [priority=['left','right','top','bottom']]\n     * Popper will try to prevent overflow following these priorities by default,\n     * then, it could overflow on the left and on top of the `boundariesElement`\n     */\n    priority: ['left', 'right', 'top', 'bottom'],\n    /**\n     * @prop {number} padding=5\n     * Amount of pixel used to define a minimum distance between the boundaries\n     * and the popper. This makes sure the popper always has a little padding\n     * between the edges of its container\n     */\n    padding: 5,\n    /**\n     * @prop {String|HTMLElement} boundariesElement='scrollParent'\n     * Boundaries used by the modifier. Can be `scrollParent`, `window`,\n     * `viewport` or any DOM element.\n     */\n    boundariesElement: 'scrollParent',\n  },\n\n  /**\n   * Modifier used to make sure the reference and its popper stay near each other\n   * without leaving any gap between the two. Especially useful when the arrow is\n   * enabled and you want to ensure that it points to its reference element.\n   * It cares only about the first axis. You can still have poppers with margin\n   * between the popper and its reference element.\n   * @memberof modifiers\n   * @inner\n   */\n  keepTogether: {\n    /** @prop {number} order=400 - Index used to define the order of execution */\n    order: 400,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: keepTogether,\n  },\n\n  /**\n   * This modifier is used to move the `arrowElement` of the popper to make\n   * sure it is positioned between the reference element and its popper element.\n   * It will read the outer size of the `arrowElement` node to detect how many\n   * pixels of conjunction are needed.\n   *\n   * It has no effect if no `arrowElement` is provided.\n   * @memberof modifiers\n   * @inner\n   */\n  arrow: {\n    /** @prop {number} order=500 - Index used to define the order of execution */\n    order: 500,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: arrow,\n    /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n    element: '[x-arrow]',\n  },\n\n  /**\n   * Modifier used to flip the popper's placement when it starts to overlap its\n   * reference element.\n   *\n   * Requires the `preventOverflow` modifier before it in order to work.\n   *\n   * **NOTE:** this modifier will interrupt the current update cycle and will\n   * restart it if it detects the need to flip the placement.\n   * @memberof modifiers\n   * @inner\n   */\n  flip: {\n    /** @prop {number} order=600 - Index used to define the order of execution */\n    order: 600,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: flip,\n    /**\n     * @prop {String|Array} behavior='flip'\n     * The behavior used to change the popper's placement. It can be one of\n     * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n     * placements (with optional variations)\n     */\n    behavior: 'flip',\n    /**\n     * @prop {number} padding=5\n     * The popper will flip if it hits the edges of the `boundariesElement`\n     */\n    padding: 5,\n    /**\n     * @prop {String|HTMLElement} boundariesElement='viewport'\n     * The element which will define the boundaries of the popper position.\n     * The popper will never be placed outside of the defined boundaries\n     * (except if `keepTogether` is enabled)\n     */\n    boundariesElement: 'viewport',\n    /**\n     * @prop {Boolean} flipVariations=false\n     * The popper will switch placement variation between `-start` and `-end` when\n     * the reference element overlaps its boundaries.\n     *\n     * The original placement should have a set variation.\n     */\n    flipVariations: false,\n    /**\n     * @prop {Boolean} flipVariationsByContent=false\n     * The popper will switch placement variation between `-start` and `-end` when\n     * the popper element overlaps its reference boundaries.\n     *\n     * The original placement should have a set variation.\n     */\n    flipVariationsByContent: false,\n  },\n\n  /**\n   * Modifier used to make the popper flow toward the inner of the reference element.\n   * By default, when this modifier is disabled, the popper will be placed outside\n   * the reference element.\n   * @memberof modifiers\n   * @inner\n   */\n  inner: {\n    /** @prop {number} order=700 - Index used to define the order of execution */\n    order: 700,\n    /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n    enabled: false,\n    /** @prop {ModifierFn} */\n    fn: inner,\n  },\n\n  /**\n   * Modifier used to hide the popper when its reference element is outside of the\n   * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n   * be used to hide with a CSS selector the popper when its reference is\n   * out of boundaries.\n   *\n   * Requires the `preventOverflow` modifier before it in order to work.\n   * @memberof modifiers\n   * @inner\n   */\n  hide: {\n    /** @prop {number} order=800 - Index used to define the order of execution */\n    order: 800,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: hide,\n  },\n\n  /**\n   * Computes the style that will be applied to the popper element to gets\n   * properly positioned.\n   *\n   * Note that this modifier will not touch the DOM, it just prepares the styles\n   * so that `applyStyle` modifier can apply it. This separation is useful\n   * in case you need to replace `applyStyle` with a custom implementation.\n   *\n   * This modifier has `850` as `order` value to maintain backward compatibility\n   * with previous versions of Popper.js. Expect the modifiers ordering method\n   * to change in future major versions of the library.\n   *\n   * @memberof modifiers\n   * @inner\n   */\n  computeStyle: {\n    /** @prop {number} order=850 - Index used to define the order of execution */\n    order: 850,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: computeStyle,\n    /**\n     * @prop {Boolean} gpuAcceleration=true\n     * If true, it uses the CSS 3D transformation to position the popper.\n     * Otherwise, it will use the `top` and `left` properties\n     */\n    gpuAcceleration: true,\n    /**\n     * @prop {string} [x='bottom']\n     * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n     * Change this if your popper should grow in a direction different from `bottom`\n     */\n    x: 'bottom',\n    /**\n     * @prop {string} [x='left']\n     * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n     * Change this if your popper should grow in a direction different from `right`\n     */\n    y: 'right',\n  },\n\n  /**\n   * Applies the computed styles to the popper element.\n   *\n   * All the DOM manipulations are limited to this modifier. This is useful in case\n   * you want to integrate Popper.js inside a framework or view library and you\n   * want to delegate all the DOM manipulations to it.\n   *\n   * Note that if you disable this modifier, you must make sure the popper element\n   * has its position set to `absolute` before Popper.js can do its work!\n   *\n   * Just disable this modifier and define your own to achieve the desired effect.\n   *\n   * @memberof modifiers\n   * @inner\n   */\n  applyStyle: {\n    /** @prop {number} order=900 - Index used to define the order of execution */\n    order: 900,\n    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n    enabled: true,\n    /** @prop {ModifierFn} */\n    fn: applyStyle,\n    /** @prop {Function} */\n    onLoad: applyStyleOnLoad,\n    /**\n     * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n     * @prop {Boolean} gpuAcceleration=true\n     * If true, it uses the CSS 3D transformation to position the popper.\n     * Otherwise, it will use the `top` and `left` properties\n     */\n    gpuAcceleration: undefined,\n  },\n};\n\n/**\n * The `dataObject` is an object containing all the information used by Popper.js.\n * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n","import modifiers from '../modifiers/index';\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overridden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass an object with the same\n * structure of the `options` object, as the 3rd argument. For example:\n * ```\n * new Popper(ref, pop, {\n *   modifiers: {\n *     preventOverflow: { enabled: false }\n *   }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nexport default {\n  /**\n   * Popper's placement.\n   * @prop {Popper.placements} placement='bottom'\n   */\n  placement: 'bottom',\n\n  /**\n   * Set this to true if you want popper to position it self in 'fixed' mode\n   * @prop {Boolean} positionFixed=false\n   */\n  positionFixed: false,\n\n  /**\n   * Whether events (resize, scroll) are initially enabled.\n   * @prop {Boolean} eventsEnabled=true\n   */\n  eventsEnabled: true,\n\n  /**\n   * Set to true if you want to automatically remove the popper when\n   * you call the `destroy` method.\n   * @prop {Boolean} removeOnDestroy=false\n   */\n  removeOnDestroy: false,\n\n  /**\n   * Callback called when the popper is created.<br />\n   * By default, it is set to no-op.<br />\n   * Access Popper.js instance with `data.instance`.\n   * @prop {onCreate}\n   */\n  onCreate: () => {},\n\n  /**\n   * Callback called when the popper is updated. This callback is not called\n   * on the initialization/creation of the popper, but only on subsequent\n   * updates.<br />\n   * By default, it is set to no-op.<br />\n   * Access Popper.js instance with `data.instance`.\n   * @prop {onUpdate}\n   */\n  onUpdate: () => {},\n\n  /**\n   * List of modifiers used to modify the offsets before they are applied to the popper.\n   * They provide most of the functionalities of Popper.js.\n   * @prop {modifiers}\n   */\n  modifiers,\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n","// Utils\nimport debounce from './utils/debounce';\nimport isFunction from './utils/isFunction';\n\n// Methods\nimport update from './methods/update';\nimport destroy from './methods/destroy';\nimport enableEventListeners from './methods/enableEventListeners';\nimport disableEventListeners from './methods/disableEventListeners';\nimport Defaults from './methods/defaults';\nimport placements from './methods/placements';\n\nexport default class Popper {\n  /**\n   * Creates a new Popper.js instance.\n   * @class Popper\n   * @param {Element|referenceObject} reference - The reference element used to position the popper\n   * @param {Element} popper - The HTML / XML element used as the popper\n   * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n   * @return {Object} instance - The generated Popper.js instance\n   */\n  constructor(reference, popper, options = {}) {\n    // make update() debounced, so that it only runs at most once-per-tick\n    this.update = debounce(this.update.bind(this));\n\n    // with {} we create a new object with the options inside it\n    this.options = { ...Popper.Defaults, ...options };\n\n    // init state\n    this.state = {\n      isDestroyed: false,\n      isCreated: false,\n      scrollParents: [],\n    };\n\n    // get reference and popper elements (allow jQuery wrappers)\n    this.reference = reference && reference.jquery ? reference[0] : reference;\n    this.popper = popper && popper.jquery ? popper[0] : popper;\n\n    // Deep merge modifiers options\n    this.options.modifiers = {};\n    Object.keys({\n      ...Popper.Defaults.modifiers,\n      ...options.modifiers,\n    }).forEach(name => {\n      this.options.modifiers[name] = {\n        // If it's a built-in modifier, use it as base\n        ...(Popper.Defaults.modifiers[name] || {}),\n        // If there are custom options, override and merge with default ones\n        ...(options.modifiers ? options.modifiers[name] : {}),\n      };\n    });\n\n    // Refactoring modifiers' list (Object => Array)\n    this.modifiers = Object.keys(this.options.modifiers)\n      .map(name => ({\n        name,\n        ...this.options.modifiers[name],\n      }))\n      // sort the modifiers by order\n      .sort((a, b) => a.order - b.order);\n\n    // modifiers have the ability to execute arbitrary code when Popper.js get inited\n    // such code is executed in the same order of its modifier\n    // they could add new properties to their options configuration\n    // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n    this.modifiers.forEach(modifierOptions => {\n      if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n        modifierOptions.onLoad(\n          this.reference,\n          this.popper,\n          this.options,\n          modifierOptions,\n          this.state\n        );\n      }\n    });\n\n    // fire the first update to position the popper in the right place\n    this.update();\n\n    const eventsEnabled = this.options.eventsEnabled;\n    if (eventsEnabled) {\n      // setup event listeners, they will take care of update the position in specific situations\n      this.enableEventListeners();\n    }\n\n    this.state.eventsEnabled = eventsEnabled;\n  }\n\n  // We can't use class properties because they don't get listed in the\n  // class prototype and break stuff like Sinon stubs\n  update() {\n    return update.call(this);\n  }\n  destroy() {\n    return destroy.call(this);\n  }\n  enableEventListeners() {\n    return enableEventListeners.call(this);\n  }\n  disableEventListeners() {\n    return disableEventListeners.call(this);\n  }\n\n  /**\n   * Schedules an update. It will run on the next UI update available.\n   * @method scheduleUpdate\n   * @memberof Popper\n   */\n  scheduleUpdate = () => requestAnimationFrame(this.update);\n\n  /**\n   * Collection of utilities useful when writing custom modifiers.\n   * Starting from version 1.7, this method is available only if you\n   * include `popper-utils.js` before `popper.js`.\n   *\n   * **DEPRECATION**: This way to access PopperUtils is deprecated\n   * and will be removed in v2! Use the PopperUtils module directly instead.\n   * Due to the high instability of the methods contained in Utils, we can't\n   * guarantee them to follow semver. Use them at your own risk!\n   * @static\n   * @private\n   * @type {Object}\n   * @deprecated since version 1.8\n   * @member Utils\n   * @memberof Popper\n   */\n  static Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\n\n  static placements = placements;\n\n  static Defaults = Defaults;\n}\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10.\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar printWarning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n  var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n  var loggedTypeFailures = {};\n  var has = Function.call.bind(Object.prototype.hasOwnProperty);\n\n  printWarning = function(text) {\n    var message = 'Warning: ' + text;\n    if (typeof console !== 'undefined') {\n      console.error(message);\n    }\n    try {\n      // --- Welcome to debugging React ---\n      // This error was thrown as a convenience so that you can use this stack\n      // to find the callsite that caused this warning to fire.\n      throw new Error(message);\n    } catch (x) {}\n  };\n}\n\n/**\n * Assert that the values match with the type specs.\n * Error messages are memorized and will only be shown once.\n *\n * @param {object} typeSpecs Map of name to a ReactPropType\n * @param {object} values Runtime values that need to be type-checked\n * @param {string} location e.g. \"prop\", \"context\", \"child context\"\n * @param {string} componentName Name of the component for error messages.\n * @param {?Function} getStack Returns the component stack.\n * @private\n */\nfunction checkPropTypes(typeSpecs, values, location, componentName, getStack) {\n  if (process.env.NODE_ENV !== 'production') {\n    for (var typeSpecName in typeSpecs) {\n      if (has(typeSpecs, typeSpecName)) {\n        var error;\n        // Prop type validation may throw. In case they do, we don't want to\n        // fail the render phase where it didn't fail before. So we log it.\n        // After these have been cleaned up, we'll let them throw.\n        try {\n          // This is intentionally an invariant that gets caught. It's the same\n          // behavior as without this statement except with a better message.\n          if (typeof typeSpecs[typeSpecName] !== 'function') {\n            var err = Error(\n              (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +\n              'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'\n            );\n            err.name = 'Invariant Violation';\n            throw err;\n          }\n          error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);\n        } catch (ex) {\n          error = ex;\n        }\n        if (error && !(error instanceof Error)) {\n          printWarning(\n            (componentName || 'React class') + ': type specification of ' +\n            location + ' `' + typeSpecName + '` is invalid; the type checker ' +\n            'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +\n            'You may have forgotten to pass an argument to the type checker ' +\n            'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +\n            'shape all require an argument).'\n          );\n        }\n        if (error instanceof Error && !(error.message in loggedTypeFailures)) {\n          // Only monitor this failure once because there tends to be a lot of the\n          // same error.\n          loggedTypeFailures[error.message] = true;\n\n          var stack = getStack ? getStack() : '';\n\n          printWarning(\n            'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')\n          );\n        }\n      }\n    }\n  }\n}\n\n/**\n * Resets warning cache when testing.\n *\n * @private\n */\ncheckPropTypes.resetWarningCache = function() {\n  if (process.env.NODE_ENV !== 'production') {\n    loggedTypeFailures = {};\n  }\n}\n\nmodule.exports = checkPropTypes;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactIs = require('react-is');\nvar assign = require('object-assign');\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\nvar checkPropTypes = require('./checkPropTypes');\n\nvar has = Function.call.bind(Object.prototype.hasOwnProperty);\nvar printWarning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n  printWarning = function(text) {\n    var message = 'Warning: ' + text;\n    if (typeof console !== 'undefined') {\n      console.error(message);\n    }\n    try {\n      // --- Welcome to debugging React ---\n      // This error was thrown as a convenience so that you can use this stack\n      // to find the callsite that caused this warning to fire.\n      throw new Error(message);\n    } catch (x) {}\n  };\n}\n\nfunction emptyFunctionThatReturnsNull() {\n  return null;\n}\n\nmodule.exports = function(isValidElement, throwOnDirectAccess) {\n  /* global Symbol */\n  var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\n  var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.\n\n  /**\n   * Returns the iterator method function contained on the iterable object.\n   *\n   * Be sure to invoke the function with the iterable as context:\n   *\n   *     var iteratorFn = getIteratorFn(myIterable);\n   *     if (iteratorFn) {\n   *       var iterator = iteratorFn.call(myIterable);\n   *       ...\n   *     }\n   *\n   * @param {?object} maybeIterable\n   * @return {?function}\n   */\n  function getIteratorFn(maybeIterable) {\n    var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);\n    if (typeof iteratorFn === 'function') {\n      return iteratorFn;\n    }\n  }\n\n  /**\n   * Collection of methods that allow declaration and validation of props that are\n   * supplied to React components. Example usage:\n   *\n   *   var Props = require('ReactPropTypes');\n   *   var MyArticle = React.createClass({\n   *     propTypes: {\n   *       // An optional string prop named \"description\".\n   *       description: Props.string,\n   *\n   *       // A required enum prop named \"category\".\n   *       category: Props.oneOf(['News','Photos']).isRequired,\n   *\n   *       // A prop named \"dialog\" that requires an instance of Dialog.\n   *       dialog: Props.instanceOf(Dialog).isRequired\n   *     },\n   *     render: function() { ... }\n   *   });\n   *\n   * A more formal specification of how these methods are used:\n   *\n   *   type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)\n   *   decl := ReactPropTypes.{type}(.isRequired)?\n   *\n   * Each and every declaration produces a function with the same signature. This\n   * allows the creation of custom validation functions. For example:\n   *\n   *  var MyLink = React.createClass({\n   *    propTypes: {\n   *      // An optional string or URI prop named \"href\".\n   *      href: function(props, propName, componentName) {\n   *        var propValue = props[propName];\n   *        if (propValue != null && typeof propValue !== 'string' &&\n   *            !(propValue instanceof URI)) {\n   *          return new Error(\n   *            'Expected a string or an URI for ' + propName + ' in ' +\n   *            componentName\n   *          );\n   *        }\n   *      }\n   *    },\n   *    render: function() {...}\n   *  });\n   *\n   * @internal\n   */\n\n  var ANONYMOUS = '<<anonymous>>';\n\n  // Important!\n  // Keep this list in sync with production version in `./factoryWithThrowingShims.js`.\n  var ReactPropTypes = {\n    array: createPrimitiveTypeChecker('array'),\n    bool: createPrimitiveTypeChecker('boolean'),\n    func: createPrimitiveTypeChecker('function'),\n    number: createPrimitiveTypeChecker('number'),\n    object: createPrimitiveTypeChecker('object'),\n    string: createPrimitiveTypeChecker('string'),\n    symbol: createPrimitiveTypeChecker('symbol'),\n\n    any: createAnyTypeChecker(),\n    arrayOf: createArrayOfTypeChecker,\n    element: createElementTypeChecker(),\n    elementType: createElementTypeTypeChecker(),\n    instanceOf: createInstanceTypeChecker,\n    node: createNodeChecker(),\n    objectOf: createObjectOfTypeChecker,\n    oneOf: createEnumTypeChecker,\n    oneOfType: createUnionTypeChecker,\n    shape: createShapeTypeChecker,\n    exact: createStrictShapeTypeChecker,\n  };\n\n  /**\n   * inlined Object.is polyfill to avoid requiring consumers ship their own\n   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n   */\n  /*eslint-disable no-self-compare*/\n  function is(x, y) {\n    // SameValue algorithm\n    if (x === y) {\n      // Steps 1-5, 7-10\n      // Steps 6.b-6.e: +0 != -0\n      return x !== 0 || 1 / x === 1 / y;\n    } else {\n      // Step 6.a: NaN == NaN\n      return x !== x && y !== y;\n    }\n  }\n  /*eslint-enable no-self-compare*/\n\n  /**\n   * We use an Error-like object for backward compatibility as people may call\n   * PropTypes directly and inspect their output. However, we don't use real\n   * Errors anymore. We don't inspect their stack anyway, and creating them\n   * is prohibitively expensive if they are created too often, such as what\n   * happens in oneOfType() for any type before the one that matched.\n   */\n  function PropTypeError(message) {\n    this.message = message;\n    this.stack = '';\n  }\n  // Make `instanceof Error` still work for returned errors.\n  PropTypeError.prototype = Error.prototype;\n\n  function createChainableTypeChecker(validate) {\n    if (process.env.NODE_ENV !== 'production') {\n      var manualPropTypeCallCache = {};\n      var manualPropTypeWarningCount = 0;\n    }\n    function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {\n      componentName = componentName || ANONYMOUS;\n      propFullName = propFullName || propName;\n\n      if (secret !== ReactPropTypesSecret) {\n        if (throwOnDirectAccess) {\n          // New behavior only for users of `prop-types` package\n          var err = new Error(\n            'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n            'Use `PropTypes.checkPropTypes()` to call them. ' +\n            'Read more at http://fb.me/use-check-prop-types'\n          );\n          err.name = 'Invariant Violation';\n          throw err;\n        } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') {\n          // Old behavior for people using React.PropTypes\n          var cacheKey = componentName + ':' + propName;\n          if (\n            !manualPropTypeCallCache[cacheKey] &&\n            // Avoid spamming the console because they are often not actionable except for lib authors\n            manualPropTypeWarningCount < 3\n          ) {\n            printWarning(\n              'You are manually calling a React.PropTypes validation ' +\n              'function for the `' + propFullName + '` prop on `' + componentName  + '`. This is deprecated ' +\n              'and will throw in the standalone `prop-types` package. ' +\n              'You may be seeing this warning due to a third-party PropTypes ' +\n              'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.'\n            );\n            manualPropTypeCallCache[cacheKey] = true;\n            manualPropTypeWarningCount++;\n          }\n        }\n      }\n      if (props[propName] == null) {\n        if (isRequired) {\n          if (props[propName] === null) {\n            return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));\n          }\n          return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));\n        }\n        return null;\n      } else {\n        return validate(props, propName, componentName, location, propFullName);\n      }\n    }\n\n    var chainedCheckType = checkType.bind(null, false);\n    chainedCheckType.isRequired = checkType.bind(null, true);\n\n    return chainedCheckType;\n  }\n\n  function createPrimitiveTypeChecker(expectedType) {\n    function validate(props, propName, componentName, location, propFullName, secret) {\n      var propValue = props[propName];\n      var propType = getPropType(propValue);\n      if (propType !== expectedType) {\n        // `propValue` being instance of, say, date/regexp, pass the 'object'\n        // check, but we can offer a more precise error message here rather than\n        // 'of type `object`'.\n        var preciseType = getPreciseType(propValue);\n\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createAnyTypeChecker() {\n    return createChainableTypeChecker(emptyFunctionThatReturnsNull);\n  }\n\n  function createArrayOfTypeChecker(typeChecker) {\n    function validate(props, propName, componentName, location, propFullName) {\n      if (typeof typeChecker !== 'function') {\n        return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');\n      }\n      var propValue = props[propName];\n      if (!Array.isArray(propValue)) {\n        var propType = getPropType(propValue);\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));\n      }\n      for (var i = 0; i < propValue.length; i++) {\n        var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);\n        if (error instanceof Error) {\n          return error;\n        }\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createElementTypeChecker() {\n    function validate(props, propName, componentName, location, propFullName) {\n      var propValue = props[propName];\n      if (!isValidElement(propValue)) {\n        var propType = getPropType(propValue);\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createElementTypeTypeChecker() {\n    function validate(props, propName, componentName, location, propFullName) {\n      var propValue = props[propName];\n      if (!ReactIs.isValidElementType(propValue)) {\n        var propType = getPropType(propValue);\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createInstanceTypeChecker(expectedClass) {\n    function validate(props, propName, componentName, location, propFullName) {\n      if (!(props[propName] instanceof expectedClass)) {\n        var expectedClassName = expectedClass.name || ANONYMOUS;\n        var actualClassName = getClassName(props[propName]);\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createEnumTypeChecker(expectedValues) {\n    if (!Array.isArray(expectedValues)) {\n      if (process.env.NODE_ENV !== 'production') {\n        if (arguments.length > 1) {\n          printWarning(\n            'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' +\n            'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).'\n          );\n        } else {\n          printWarning('Invalid argument supplied to oneOf, expected an array.');\n        }\n      }\n      return emptyFunctionThatReturnsNull;\n    }\n\n    function validate(props, propName, componentName, location, propFullName) {\n      var propValue = props[propName];\n      for (var i = 0; i < expectedValues.length; i++) {\n        if (is(propValue, expectedValues[i])) {\n          return null;\n        }\n      }\n\n      var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {\n        var type = getPreciseType(value);\n        if (type === 'symbol') {\n          return String(value);\n        }\n        return value;\n      });\n      return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createObjectOfTypeChecker(typeChecker) {\n    function validate(props, propName, componentName, location, propFullName) {\n      if (typeof typeChecker !== 'function') {\n        return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');\n      }\n      var propValue = props[propName];\n      var propType = getPropType(propValue);\n      if (propType !== 'object') {\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));\n      }\n      for (var key in propValue) {\n        if (has(propValue, key)) {\n          var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n          if (error instanceof Error) {\n            return error;\n          }\n        }\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createUnionTypeChecker(arrayOfTypeCheckers) {\n    if (!Array.isArray(arrayOfTypeCheckers)) {\n      process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;\n      return emptyFunctionThatReturnsNull;\n    }\n\n    for (var i = 0; i < arrayOfTypeCheckers.length; i++) {\n      var checker = arrayOfTypeCheckers[i];\n      if (typeof checker !== 'function') {\n        printWarning(\n          'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' +\n          'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.'\n        );\n        return emptyFunctionThatReturnsNull;\n      }\n    }\n\n    function validate(props, propName, componentName, location, propFullName) {\n      for (var i = 0; i < arrayOfTypeCheckers.length; i++) {\n        var checker = arrayOfTypeCheckers[i];\n        if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) {\n          return null;\n        }\n      }\n\n      return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createNodeChecker() {\n    function validate(props, propName, componentName, location, propFullName) {\n      if (!isNode(props[propName])) {\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createShapeTypeChecker(shapeTypes) {\n    function validate(props, propName, componentName, location, propFullName) {\n      var propValue = props[propName];\n      var propType = getPropType(propValue);\n      if (propType !== 'object') {\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));\n      }\n      for (var key in shapeTypes) {\n        var checker = shapeTypes[key];\n        if (!checker) {\n          continue;\n        }\n        var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n        if (error) {\n          return error;\n        }\n      }\n      return null;\n    }\n    return createChainableTypeChecker(validate);\n  }\n\n  function createStrictShapeTypeChecker(shapeTypes) {\n    function validate(props, propName, componentName, location, propFullName) {\n      var propValue = props[propName];\n      var propType = getPropType(propValue);\n      if (propType !== 'object') {\n        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));\n      }\n      // We need to check all keys in case some are required but missing from\n      // props.\n      var allKeys = assign({}, props[propName], shapeTypes);\n      for (var key in allKeys) {\n        var checker = shapeTypes[key];\n        if (!checker) {\n          return new PropTypeError(\n            'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' +\n            '\\nBad object: ' + JSON.stringify(props[propName], null, '  ') +\n            '\\nValid keys: ' +  JSON.stringify(Object.keys(shapeTypes), null, '  ')\n          );\n        }\n        var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n        if (error) {\n          return error;\n        }\n      }\n      return null;\n    }\n\n    return createChainableTypeChecker(validate);\n  }\n\n  function isNode(propValue) {\n    switch (typeof propValue) {\n      case 'number':\n      case 'string':\n      case 'undefined':\n        return true;\n      case 'boolean':\n        return !propValue;\n      case 'object':\n        if (Array.isArray(propValue)) {\n          return propValue.every(isNode);\n        }\n        if (propValue === null || isValidElement(propValue)) {\n          return true;\n        }\n\n        var iteratorFn = getIteratorFn(propValue);\n        if (iteratorFn) {\n          var iterator = iteratorFn.call(propValue);\n          var step;\n          if (iteratorFn !== propValue.entries) {\n            while (!(step = iterator.next()).done) {\n              if (!isNode(step.value)) {\n                return false;\n              }\n            }\n          } else {\n            // Iterator will provide entry [k,v] tuples rather than values.\n            while (!(step = iterator.next()).done) {\n              var entry = step.value;\n              if (entry) {\n                if (!isNode(entry[1])) {\n                  return false;\n                }\n              }\n            }\n          }\n        } else {\n          return false;\n        }\n\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  function isSymbol(propType, propValue) {\n    // Native Symbol.\n    if (propType === 'symbol') {\n      return true;\n    }\n\n    // falsy value can't be a Symbol\n    if (!propValue) {\n      return false;\n    }\n\n    // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'\n    if (propValue['@@toStringTag'] === 'Symbol') {\n      return true;\n    }\n\n    // Fallback for non-spec compliant Symbols which are polyfilled.\n    if (typeof Symbol === 'function' && propValue instanceof Symbol) {\n      return true;\n    }\n\n    return false;\n  }\n\n  // Equivalent of `typeof` but with special handling for array and regexp.\n  function getPropType(propValue) {\n    var propType = typeof propValue;\n    if (Array.isArray(propValue)) {\n      return 'array';\n    }\n    if (propValue instanceof RegExp) {\n      // Old webkits (at least until Android 4.0) return 'function' rather than\n      // 'object' for typeof a RegExp. We'll normalize this here so that /bla/\n      // passes PropTypes.object.\n      return 'object';\n    }\n    if (isSymbol(propType, propValue)) {\n      return 'symbol';\n    }\n    return propType;\n  }\n\n  // This handles more types than `getPropType`. Only used for error messages.\n  // See `createPrimitiveTypeChecker`.\n  function getPreciseType(propValue) {\n    if (typeof propValue === 'undefined' || propValue === null) {\n      return '' + propValue;\n    }\n    var propType = getPropType(propValue);\n    if (propType === 'object') {\n      if (propValue instanceof Date) {\n        return 'date';\n      } else if (propValue instanceof RegExp) {\n        return 'regexp';\n      }\n    }\n    return propType;\n  }\n\n  // Returns a string that is postfixed to a warning about an invalid type.\n  // For example, \"undefined\" or \"of type array\"\n  function getPostfixForTypeWarning(value) {\n    var type = getPreciseType(value);\n    switch (type) {\n      case 'array':\n      case 'object':\n        return 'an ' + type;\n      case 'boolean':\n      case 'date':\n      case 'regexp':\n        return 'a ' + type;\n      default:\n        return type;\n    }\n  }\n\n  // Returns class name of the object, if any.\n  function getClassName(propValue) {\n    if (!propValue.constructor || !propValue.constructor.name) {\n      return ANONYMOUS;\n    }\n    return propValue.constructor.name;\n  }\n\n  ReactPropTypes.checkPropTypes = checkPropTypes;\n  ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;\n  ReactPropTypes.PropTypes = ReactPropTypes;\n\n  return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n  var ReactIs = require('react-is');\n\n  // By explicitly using `prop-types` you are opting into new development behavior.\n  // http://fb.me/prop-types-in-prod\n  var throwOnDirectAccess = true;\n  module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n  // By explicitly using `prop-types` you are opting into new production behavior.\n  // http://fb.me/prop-types-in-prod\n  module.exports = require('./factoryWithThrowingShims')();\n}\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","/** @license React v16.13.1\n * react-dom.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\nvar React = require('react');\nvar _assign = require('object-assign');\nvar Scheduler = require('scheduler');\nvar checkPropTypes = require('prop-types/checkPropTypes');\nvar tracing = require('scheduler/tracing');\n\nvar ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.\n// Current owner and dispatcher used to share the same ref,\n// but PR #14548 split them out to better support the react-debug-tools package.\n\nif (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {\n  ReactSharedInternals.ReactCurrentDispatcher = {\n    current: null\n  };\n}\n\nif (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {\n  ReactSharedInternals.ReactCurrentBatchConfig = {\n    suspense: null\n  };\n}\n\n// by calls to these methods by a Babel plugin.\n//\n// In PROD (or in packages without access to React internals),\n// they are left as they are instead.\n\nfunction warn(format) {\n  {\n    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    printWarning('warn', format, args);\n  }\n}\nfunction error(format) {\n  {\n    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n      args[_key2 - 1] = arguments[_key2];\n    }\n\n    printWarning('error', format, args);\n  }\n}\n\nfunction printWarning(level, format, args) {\n  // When changing this logic, you might want to also\n  // update consoleWithStackDev.www.js as well.\n  {\n    var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\\n    in') === 0;\n\n    if (!hasExistingStack) {\n      var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n      var stack = ReactDebugCurrentFrame.getStackAddendum();\n\n      if (stack !== '') {\n        format += '%s';\n        args = args.concat([stack]);\n      }\n    }\n\n    var argsWithFormat = args.map(function (item) {\n      return '' + item;\n    }); // Careful: RN currently depends on this prefix\n\n    argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it\n    // breaks IE9: https://github.com/facebook/react/issues/13610\n    // eslint-disable-next-line react-internal/no-production-logging\n\n    Function.prototype.apply.call(console[level], console, argsWithFormat);\n\n    try {\n      // --- Welcome to debugging React ---\n      // This error was thrown as a convenience so that you can use this stack\n      // to find the callsite that caused this warning to fire.\n      var argIndex = 0;\n      var message = 'Warning: ' + format.replace(/%s/g, function () {\n        return args[argIndex++];\n      });\n      throw new Error(message);\n    } catch (x) {}\n  }\n}\n\nif (!React) {\n  {\n    throw Error( \"ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.\" );\n  }\n}\n\nvar invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {\n  var funcArgs = Array.prototype.slice.call(arguments, 3);\n\n  try {\n    func.apply(context, funcArgs);\n  } catch (error) {\n    this.onError(error);\n  }\n};\n\n{\n  // In DEV mode, we swap out invokeGuardedCallback for a special version\n  // that plays more nicely with the browser's DevTools. The idea is to preserve\n  // \"Pause on exceptions\" behavior. Because React wraps all user-provided\n  // functions in invokeGuardedCallback, and the production version of\n  // invokeGuardedCallback uses a try-catch, all user exceptions are treated\n  // like caught exceptions, and the DevTools won't pause unless the developer\n  // takes the extra step of enabling pause on caught exceptions. This is\n  // unintuitive, though, because even though React has caught the error, from\n  // the developer's perspective, the error is uncaught.\n  //\n  // To preserve the expected \"Pause on exceptions\" behavior, we don't use a\n  // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake\n  // DOM node, and call the user-provided callback from inside an event handler\n  // for that fake event. If the callback throws, the error is \"captured\" using\n  // a global event handler. But because the error happens in a different\n  // event loop context, it does not interrupt the normal program flow.\n  // Effectively, this gives us try-catch behavior without actually using\n  // try-catch. Neat!\n  // Check that the browser supports the APIs we need to implement our special\n  // DEV version of invokeGuardedCallback\n  if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {\n    var fakeNode = document.createElement('react');\n\n    var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {\n      // If document doesn't exist we know for sure we will crash in this method\n      // when we call document.createEvent(). However this can cause confusing\n      // errors: https://github.com/facebookincubator/create-react-app/issues/3482\n      // So we preemptively throw with a better message instead.\n      if (!(typeof document !== 'undefined')) {\n        {\n          throw Error( \"The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.\" );\n        }\n      }\n\n      var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We\n      // set this to true at the beginning, then set it to false right after\n      // calling the function. If the function errors, `didError` will never be\n      // set to false. This strategy works even if the browser is flaky and\n      // fails to call our global error handler, because it doesn't rely on\n      // the error event at all.\n\n      var didError = true; // Keeps track of the value of window.event so that we can reset it\n      // during the callback to let user code access window.event in the\n      // browsers that support it.\n\n      var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event\n      // dispatching: https://github.com/facebook/react/issues/13688\n\n      var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously\n      // dispatch our fake event using `dispatchEvent`. Inside the handler, we\n      // call the user-provided callback.\n\n      var funcArgs = Array.prototype.slice.call(arguments, 3);\n\n      function callCallback() {\n        // We immediately remove the callback from event listeners so that\n        // nested `invokeGuardedCallback` calls do not clash. Otherwise, a\n        // nested call would trigger the fake event handlers of any call higher\n        // in the stack.\n        fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the\n        // window.event assignment in both IE <= 10 as they throw an error\n        // \"Member not found\" in strict mode, and in Firefox which does not\n        // support window.event.\n\n        if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {\n          window.event = windowEvent;\n        }\n\n        func.apply(context, funcArgs);\n        didError = false;\n      } // Create a global error event handler. We use this to capture the value\n      // that was thrown. It's possible that this error handler will fire more\n      // than once; for example, if non-React code also calls `dispatchEvent`\n      // and a handler for that event throws. We should be resilient to most of\n      // those cases. Even if our error event handler fires more than once, the\n      // last error event is always used. If the callback actually does error,\n      // we know that the last error event is the correct one, because it's not\n      // possible for anything else to have happened in between our callback\n      // erroring and the code that follows the `dispatchEvent` call below. If\n      // the callback doesn't error, but the error event was fired, we know to\n      // ignore it because `didError` will be false, as described above.\n\n\n      var error; // Use this to track whether the error event is ever called.\n\n      var didSetError = false;\n      var isCrossOriginError = false;\n\n      function handleWindowError(event) {\n        error = event.error;\n        didSetError = true;\n\n        if (error === null && event.colno === 0 && event.lineno === 0) {\n          isCrossOriginError = true;\n        }\n\n        if (event.defaultPrevented) {\n          // Some other error handler has prevented default.\n          // Browsers silence the error report if this happens.\n          // We'll remember this to later decide whether to log it or not.\n          if (error != null && typeof error === 'object') {\n            try {\n              error._suppressLogging = true;\n            } catch (inner) {// Ignore.\n            }\n          }\n        }\n      } // Create a fake event type.\n\n\n      var evtType = \"react-\" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers\n\n      window.addEventListener('error', handleWindowError);\n      fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function\n      // errors, it will trigger our global error handler.\n\n      evt.initEvent(evtType, false, false);\n      fakeNode.dispatchEvent(evt);\n\n      if (windowEventDescriptor) {\n        Object.defineProperty(window, 'event', windowEventDescriptor);\n      }\n\n      if (didError) {\n        if (!didSetError) {\n          // The callback errored, but the error event never fired.\n          error = new Error('An error was thrown inside one of your components, but React ' + \"doesn't know what it was. This is likely due to browser \" + 'flakiness. React does its best to preserve the \"Pause on ' + 'exceptions\" behavior of the DevTools, which requires some ' + \"DEV-mode only tricks. It's possible that these don't work in \" + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');\n        } else if (isCrossOriginError) {\n          error = new Error(\"A cross-origin error was thrown. React doesn't have access to \" + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');\n        }\n\n        this.onError(error);\n      } // Remove our event listeners\n\n\n      window.removeEventListener('error', handleWindowError);\n    };\n\n    invokeGuardedCallbackImpl = invokeGuardedCallbackDev;\n  }\n}\n\nvar invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;\n\nvar hasError = false;\nvar caughtError = null; // Used by event system to capture/rethrow the first error.\n\nvar hasRethrowError = false;\nvar rethrowError = null;\nvar reporter = {\n  onError: function (error) {\n    hasError = true;\n    caughtError = error;\n  }\n};\n/**\n * Call a function while guarding against errors that happens within it.\n * Returns an error if it throws, otherwise null.\n *\n * In production, this is implemented using a try-catch. The reason we don't\n * use a try-catch directly is so that we can swap out a different\n * implementation in DEV mode.\n *\n * @param {String} name of the guard to use for logging or debugging\n * @param {Function} func The function to invoke\n * @param {*} context The context to use when calling the function\n * @param {...*} args Arguments for function\n */\n\nfunction invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {\n  hasError = false;\n  caughtError = null;\n  invokeGuardedCallbackImpl$1.apply(reporter, arguments);\n}\n/**\n * Same as invokeGuardedCallback, but instead of returning an error, it stores\n * it in a global so it can be rethrown by `rethrowCaughtError` later.\n * TODO: See if caughtError and rethrowError can be unified.\n *\n * @param {String} name of the guard to use for logging or debugging\n * @param {Function} func The function to invoke\n * @param {*} context The context to use when calling the function\n * @param {...*} args Arguments for function\n */\n\nfunction invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {\n  invokeGuardedCallback.apply(this, arguments);\n\n  if (hasError) {\n    var error = clearCaughtError();\n\n    if (!hasRethrowError) {\n      hasRethrowError = true;\n      rethrowError = error;\n    }\n  }\n}\n/**\n * During execution of guarded functions we will capture the first error which\n * we will rethrow to be handled by the top level error handler.\n */\n\nfunction rethrowCaughtError() {\n  if (hasRethrowError) {\n    var error = rethrowError;\n    hasRethrowError = false;\n    rethrowError = null;\n    throw error;\n  }\n}\nfunction hasCaughtError() {\n  return hasError;\n}\nfunction clearCaughtError() {\n  if (hasError) {\n    var error = caughtError;\n    hasError = false;\n    caughtError = null;\n    return error;\n  } else {\n    {\n      {\n        throw Error( \"clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n  }\n}\n\nvar getFiberCurrentPropsFromNode = null;\nvar getInstanceFromNode = null;\nvar getNodeFromInstance = null;\nfunction setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {\n  getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;\n  getInstanceFromNode = getInstanceFromNodeImpl;\n  getNodeFromInstance = getNodeFromInstanceImpl;\n\n  {\n    if (!getNodeFromInstance || !getInstanceFromNode) {\n      error('EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');\n    }\n  }\n}\nvar validateEventDispatches;\n\n{\n  validateEventDispatches = function (event) {\n    var dispatchListeners = event._dispatchListeners;\n    var dispatchInstances = event._dispatchInstances;\n    var listenersIsArr = Array.isArray(dispatchListeners);\n    var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;\n    var instancesIsArr = Array.isArray(dispatchInstances);\n    var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;\n\n    if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {\n      error('EventPluginUtils: Invalid `event`.');\n    }\n  };\n}\n/**\n * Dispatch the event to the listener.\n * @param {SyntheticEvent} event SyntheticEvent to handle\n * @param {function} listener Application-level callback\n * @param {*} inst Internal component instance\n */\n\n\nfunction executeDispatch(event, listener, inst) {\n  var type = event.type || 'unknown-event';\n  event.currentTarget = getNodeFromInstance(inst);\n  invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);\n  event.currentTarget = null;\n}\n/**\n * Standard/simple iteration through an event's collected dispatches.\n */\n\nfunction executeDispatchesInOrder(event) {\n  var dispatchListeners = event._dispatchListeners;\n  var dispatchInstances = event._dispatchInstances;\n\n  {\n    validateEventDispatches(event);\n  }\n\n  if (Array.isArray(dispatchListeners)) {\n    for (var i = 0; i < dispatchListeners.length; i++) {\n      if (event.isPropagationStopped()) {\n        break;\n      } // Listeners and Instances are two parallel arrays that are always in sync.\n\n\n      executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);\n    }\n  } else if (dispatchListeners) {\n    executeDispatch(event, dispatchListeners, dispatchInstances);\n  }\n\n  event._dispatchListeners = null;\n  event._dispatchInstances = null;\n}\n\nvar FunctionComponent = 0;\nvar ClassComponent = 1;\nvar IndeterminateComponent = 2; // Before we know whether it is function or class\n\nvar HostRoot = 3; // Root of a host tree. Could be nested inside another node.\n\nvar HostPortal = 4; // A subtree. Could be an entry point to a different renderer.\n\nvar HostComponent = 5;\nvar HostText = 6;\nvar Fragment = 7;\nvar Mode = 8;\nvar ContextConsumer = 9;\nvar ContextProvider = 10;\nvar ForwardRef = 11;\nvar Profiler = 12;\nvar SuspenseComponent = 13;\nvar MemoComponent = 14;\nvar SimpleMemoComponent = 15;\nvar LazyComponent = 16;\nvar IncompleteClassComponent = 17;\nvar DehydratedFragment = 18;\nvar SuspenseListComponent = 19;\nvar FundamentalComponent = 20;\nvar ScopeComponent = 21;\nvar Block = 22;\n\n/**\n * Injectable ordering of event plugins.\n */\nvar eventPluginOrder = null;\n/**\n * Injectable mapping from names to event plugin modules.\n */\n\nvar namesToPlugins = {};\n/**\n * Recomputes the plugin list using the injected plugins and plugin ordering.\n *\n * @private\n */\n\nfunction recomputePluginOrdering() {\n  if (!eventPluginOrder) {\n    // Wait until an `eventPluginOrder` is injected.\n    return;\n  }\n\n  for (var pluginName in namesToPlugins) {\n    var pluginModule = namesToPlugins[pluginName];\n    var pluginIndex = eventPluginOrder.indexOf(pluginName);\n\n    if (!(pluginIndex > -1)) {\n      {\n        throw Error( \"EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `\" + pluginName + \"`.\" );\n      }\n    }\n\n    if (plugins[pluginIndex]) {\n      continue;\n    }\n\n    if (!pluginModule.extractEvents) {\n      {\n        throw Error( \"EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `\" + pluginName + \"` does not.\" );\n      }\n    }\n\n    plugins[pluginIndex] = pluginModule;\n    var publishedEvents = pluginModule.eventTypes;\n\n    for (var eventName in publishedEvents) {\n      if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {\n        {\n          throw Error( \"EventPluginRegistry: Failed to publish event `\" + eventName + \"` for plugin `\" + pluginName + \"`.\" );\n        }\n      }\n    }\n  }\n}\n/**\n * Publishes an event so that it can be dispatched by the supplied plugin.\n *\n * @param {object} dispatchConfig Dispatch configuration for the event.\n * @param {object} PluginModule Plugin publishing the event.\n * @return {boolean} True if the event was successfully published.\n * @private\n */\n\n\nfunction publishEventForPlugin(dispatchConfig, pluginModule, eventName) {\n  if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {\n    {\n      throw Error( \"EventPluginRegistry: More than one plugin attempted to publish the same event name, `\" + eventName + \"`.\" );\n    }\n  }\n\n  eventNameDispatchConfigs[eventName] = dispatchConfig;\n  var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;\n\n  if (phasedRegistrationNames) {\n    for (var phaseName in phasedRegistrationNames) {\n      if (phasedRegistrationNames.hasOwnProperty(phaseName)) {\n        var phasedRegistrationName = phasedRegistrationNames[phaseName];\n        publishRegistrationName(phasedRegistrationName, pluginModule, eventName);\n      }\n    }\n\n    return true;\n  } else if (dispatchConfig.registrationName) {\n    publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);\n    return true;\n  }\n\n  return false;\n}\n/**\n * Publishes a registration name that is used to identify dispatched events.\n *\n * @param {string} registrationName Registration name to add.\n * @param {object} PluginModule Plugin publishing the event.\n * @private\n */\n\n\nfunction publishRegistrationName(registrationName, pluginModule, eventName) {\n  if (!!registrationNameModules[registrationName]) {\n    {\n      throw Error( \"EventPluginRegistry: More than one plugin attempted to publish the same registration name, `\" + registrationName + \"`.\" );\n    }\n  }\n\n  registrationNameModules[registrationName] = pluginModule;\n  registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;\n\n  {\n    var lowerCasedName = registrationName.toLowerCase();\n    possibleRegistrationNames[lowerCasedName] = registrationName;\n\n    if (registrationName === 'onDoubleClick') {\n      possibleRegistrationNames.ondblclick = registrationName;\n    }\n  }\n}\n/**\n * Registers plugins so that they can extract and dispatch events.\n */\n\n/**\n * Ordered list of injected plugins.\n */\n\n\nvar plugins = [];\n/**\n * Mapping from event name to dispatch config\n */\n\nvar eventNameDispatchConfigs = {};\n/**\n * Mapping from registration name to plugin module\n */\n\nvar registrationNameModules = {};\n/**\n * Mapping from registration name to event name\n */\n\nvar registrationNameDependencies = {};\n/**\n * Mapping from lowercase registration names to the properly cased version,\n * used to warn in the case of missing event handlers. Available\n * only in true.\n * @type {Object}\n */\n\nvar possibleRegistrationNames =  {} ; // Trust the developer to only use possibleRegistrationNames in true\n\n/**\n * Injects an ordering of plugins (by plugin name). This allows the ordering\n * to be decoupled from injection of the actual plugins so that ordering is\n * always deterministic regardless of packaging, on-the-fly injection, etc.\n *\n * @param {array} InjectedEventPluginOrder\n * @internal\n */\n\nfunction injectEventPluginOrder(injectedEventPluginOrder) {\n  if (!!eventPluginOrder) {\n    {\n      throw Error( \"EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.\" );\n    }\n  } // Clone the ordering so it cannot be dynamically mutated.\n\n\n  eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);\n  recomputePluginOrdering();\n}\n/**\n * Injects plugins to be used by plugin event system. The plugin names must be\n * in the ordering injected by `injectEventPluginOrder`.\n *\n * Plugins can be injected as part of page initialization or on-the-fly.\n *\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n * @internal\n */\n\nfunction injectEventPluginsByName(injectedNamesToPlugins) {\n  var isOrderingDirty = false;\n\n  for (var pluginName in injectedNamesToPlugins) {\n    if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {\n      continue;\n    }\n\n    var pluginModule = injectedNamesToPlugins[pluginName];\n\n    if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {\n      if (!!namesToPlugins[pluginName]) {\n        {\n          throw Error( \"EventPluginRegistry: Cannot inject two different event plugins using the same name, `\" + pluginName + \"`.\" );\n        }\n      }\n\n      namesToPlugins[pluginName] = pluginModule;\n      isOrderingDirty = true;\n    }\n  }\n\n  if (isOrderingDirty) {\n    recomputePluginOrdering();\n  }\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');\n\nvar PLUGIN_EVENT_SYSTEM = 1;\nvar IS_REPLAYED = 1 << 5;\nvar IS_FIRST_ANCESTOR = 1 << 6;\n\nvar restoreImpl = null;\nvar restoreTarget = null;\nvar restoreQueue = null;\n\nfunction restoreStateOfTarget(target) {\n  // We perform this translation at the end of the event loop so that we\n  // always receive the correct fiber here\n  var internalInstance = getInstanceFromNode(target);\n\n  if (!internalInstance) {\n    // Unmounted\n    return;\n  }\n\n  if (!(typeof restoreImpl === 'function')) {\n    {\n      throw Error( \"setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n\n  var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.\n\n  if (stateNode) {\n    var _props = getFiberCurrentPropsFromNode(stateNode);\n\n    restoreImpl(internalInstance.stateNode, internalInstance.type, _props);\n  }\n}\n\nfunction setRestoreImplementation(impl) {\n  restoreImpl = impl;\n}\nfunction enqueueStateRestore(target) {\n  if (restoreTarget) {\n    if (restoreQueue) {\n      restoreQueue.push(target);\n    } else {\n      restoreQueue = [target];\n    }\n  } else {\n    restoreTarget = target;\n  }\n}\nfunction needsStateRestore() {\n  return restoreTarget !== null || restoreQueue !== null;\n}\nfunction restoreStateIfNeeded() {\n  if (!restoreTarget) {\n    return;\n  }\n\n  var target = restoreTarget;\n  var queuedTargets = restoreQueue;\n  restoreTarget = null;\n  restoreQueue = null;\n  restoreStateOfTarget(target);\n\n  if (queuedTargets) {\n    for (var i = 0; i < queuedTargets.length; i++) {\n      restoreStateOfTarget(queuedTargets[i]);\n    }\n  }\n}\n\nvar enableProfilerTimer = true; // Trace which interactions trigger each commit.\n\nvar enableDeprecatedFlareAPI = false; // Experimental Host Component support.\n\nvar enableFundamentalAPI = false; // Experimental Scope support.\nvar warnAboutStringRefs = false;\n\n// the renderer. Such as when we're dispatching events or if third party\n// libraries need to call batchedUpdates. Eventually, this API will go away when\n// everything is batched by default. We'll then have a similar API to opt-out of\n// scheduled work and instead do synchronous work.\n// Defaults\n\nvar batchedUpdatesImpl = function (fn, bookkeeping) {\n  return fn(bookkeeping);\n};\n\nvar discreteUpdatesImpl = function (fn, a, b, c, d) {\n  return fn(a, b, c, d);\n};\n\nvar flushDiscreteUpdatesImpl = function () {};\n\nvar batchedEventUpdatesImpl = batchedUpdatesImpl;\nvar isInsideEventHandler = false;\nvar isBatchingEventUpdates = false;\n\nfunction finishEventHandler() {\n  // Here we wait until all updates have propagated, which is important\n  // when using controlled components within layers:\n  // https://github.com/facebook/react/issues/1698\n  // Then we restore state of any controlled component.\n  var controlledComponentsHavePendingUpdates = needsStateRestore();\n\n  if (controlledComponentsHavePendingUpdates) {\n    // If a controlled event was fired, we may need to restore the state of\n    // the DOM node back to the controlled value. This is necessary when React\n    // bails out of the update without touching the DOM.\n    flushDiscreteUpdatesImpl();\n    restoreStateIfNeeded();\n  }\n}\n\nfunction batchedUpdates(fn, bookkeeping) {\n  if (isInsideEventHandler) {\n    // If we are currently inside another batch, we need to wait until it\n    // fully completes before restoring state.\n    return fn(bookkeeping);\n  }\n\n  isInsideEventHandler = true;\n\n  try {\n    return batchedUpdatesImpl(fn, bookkeeping);\n  } finally {\n    isInsideEventHandler = false;\n    finishEventHandler();\n  }\n}\nfunction batchedEventUpdates(fn, a, b) {\n  if (isBatchingEventUpdates) {\n    // If we are currently inside another batch, we need to wait until it\n    // fully completes before restoring state.\n    return fn(a, b);\n  }\n\n  isBatchingEventUpdates = true;\n\n  try {\n    return batchedEventUpdatesImpl(fn, a, b);\n  } finally {\n    isBatchingEventUpdates = false;\n    finishEventHandler();\n  }\n} // This is for the React Flare event system\nfunction discreteUpdates(fn, a, b, c, d) {\n  var prevIsInsideEventHandler = isInsideEventHandler;\n  isInsideEventHandler = true;\n\n  try {\n    return discreteUpdatesImpl(fn, a, b, c, d);\n  } finally {\n    isInsideEventHandler = prevIsInsideEventHandler;\n\n    if (!isInsideEventHandler) {\n      finishEventHandler();\n    }\n  }\n}\nfunction flushDiscreteUpdatesIfNeeded(timeStamp) {\n  // event.timeStamp isn't overly reliable due to inconsistencies in\n  // how different browsers have historically provided the time stamp.\n  // Some browsers provide high-resolution time stamps for all events,\n  // some provide low-resolution time stamps for all events. FF < 52\n  // even mixes both time stamps together. Some browsers even report\n  // negative time stamps or time stamps that are 0 (iOS9) in some cases.\n  // Given we are only comparing two time stamps with equality (!==),\n  // we are safe from the resolution differences. If the time stamp is 0\n  // we bail-out of preventing the flush, which can affect semantics,\n  // such as if an earlier flush removes or adds event listeners that\n  // are fired in the subsequent flush. However, this is the same\n  // behaviour as we had before this change, so the risks are low.\n  if (!isInsideEventHandler && (!enableDeprecatedFlareAPI  )) {\n    flushDiscreteUpdatesImpl();\n  }\n}\nfunction setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {\n  batchedUpdatesImpl = _batchedUpdatesImpl;\n  discreteUpdatesImpl = _discreteUpdatesImpl;\n  flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;\n  batchedEventUpdatesImpl = _batchedEventUpdatesImpl;\n}\n\nvar DiscreteEvent = 0;\nvar UserBlockingEvent = 1;\nvar ContinuousEvent = 2;\n\n// A reserved attribute.\n// It is handled by React separately and shouldn't be written to the DOM.\nvar RESERVED = 0; // A simple string attribute.\n// Attributes that aren't in the whitelist are presumed to have this type.\n\nvar STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called\n// \"enumerated\" attributes with \"true\" and \"false\" as possible values.\n// When true, it should be set to a \"true\" string.\n// When false, it should be set to a \"false\" string.\n\nvar BOOLEANISH_STRING = 2; // A real boolean attribute.\n// When true, it should be present (set either to an empty string or its name).\n// When false, it should be omitted.\n\nvar BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.\n// When true, it should be present (set either to an empty string or its name).\n// When false, it should be omitted.\n// For any other value, should be present with that value.\n\nvar OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.\n// When falsy, it should be removed.\n\nvar NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.\n// When falsy, it should be removed.\n\nvar POSITIVE_NUMERIC = 6;\n\n/* eslint-disable max-len */\nvar ATTRIBUTE_NAME_START_CHAR = \":A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\";\n/* eslint-enable max-len */\n\nvar ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + \"\\\\-.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040\";\nvar ROOT_ATTRIBUTE_NAME = 'data-reactroot';\nvar VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar illegalAttributeNameCache = {};\nvar validatedAttributeNameCache = {};\nfunction isAttributeNameSafe(attributeName) {\n  if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {\n    return true;\n  }\n\n  if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {\n    return false;\n  }\n\n  if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {\n    validatedAttributeNameCache[attributeName] = true;\n    return true;\n  }\n\n  illegalAttributeNameCache[attributeName] = true;\n\n  {\n    error('Invalid attribute name: `%s`', attributeName);\n  }\n\n  return false;\n}\nfunction shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {\n  if (propertyInfo !== null) {\n    return propertyInfo.type === RESERVED;\n  }\n\n  if (isCustomComponentTag) {\n    return false;\n  }\n\n  if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {\n    return true;\n  }\n\n  return false;\n}\nfunction shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {\n  if (propertyInfo !== null && propertyInfo.type === RESERVED) {\n    return false;\n  }\n\n  switch (typeof value) {\n    case 'function': // $FlowIssue symbol is perfectly valid here\n\n    case 'symbol':\n      // eslint-disable-line\n      return true;\n\n    case 'boolean':\n      {\n        if (isCustomComponentTag) {\n          return false;\n        }\n\n        if (propertyInfo !== null) {\n          return !propertyInfo.acceptsBooleans;\n        } else {\n          var prefix = name.toLowerCase().slice(0, 5);\n          return prefix !== 'data-' && prefix !== 'aria-';\n        }\n      }\n\n    default:\n      return false;\n  }\n}\nfunction shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {\n  if (value === null || typeof value === 'undefined') {\n    return true;\n  }\n\n  if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {\n    return true;\n  }\n\n  if (isCustomComponentTag) {\n    return false;\n  }\n\n  if (propertyInfo !== null) {\n    switch (propertyInfo.type) {\n      case BOOLEAN:\n        return !value;\n\n      case OVERLOADED_BOOLEAN:\n        return value === false;\n\n      case NUMERIC:\n        return isNaN(value);\n\n      case POSITIVE_NUMERIC:\n        return isNaN(value) || value < 1;\n    }\n  }\n\n  return false;\n}\nfunction getPropertyInfo(name) {\n  return properties.hasOwnProperty(name) ? properties[name] : null;\n}\n\nfunction PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {\n  this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;\n  this.attributeName = attributeName;\n  this.attributeNamespace = attributeNamespace;\n  this.mustUseProperty = mustUseProperty;\n  this.propertyName = name;\n  this.type = type;\n  this.sanitizeURL = sanitizeURL;\n} // When adding attributes to this list, be sure to also add them to\n// the `possibleStandardNames` module to ensure casing and incorrect\n// name warnings.\n\n\nvar properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.\n\nvar reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular\n// elements (not just inputs). Now that ReactDOMInput assigns to the\n// defaultValue property -- do we need this?\n'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];\n\nreservedProps.forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty\n  name, // attributeName\n  null, // attributeNamespace\n  false);\n}); // A few React string attributes have a different name.\n// This is a mapping from React prop names to the attribute names.\n\n[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {\n  var name = _ref[0],\n      attributeName = _ref[1];\n  properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n  attributeName, // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are \"enumerated\" HTML attributes that accept \"true\" and \"false\".\n// In React, we let users pass `true` and `false` even though technically\n// these aren't boolean attributes (they are coerced to strings).\n\n['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty\n  name.toLowerCase(), // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are \"enumerated\" SVG attributes that accept \"true\" and \"false\".\n// In React, we let users pass `true` and `false` even though technically\n// these aren't boolean attributes (they are coerced to strings).\n// Since these are SVG attributes, their attribute names are case-sensitive.\n\n['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty\n  name, // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are HTML boolean attributes.\n\n['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM\n// on the client side because the browsers are inconsistent. Instead we call focus().\n'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata\n'itemScope'].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty\n  name.toLowerCase(), // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are the few React props that we set as DOM properties\n// rather than attributes. These are all booleans.\n\n['checked', // Note: `option.selected` is not updated if `select.multiple` is\n// disabled with `removeAttribute`. We have special logic for handling this.\n'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty\n  name, // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are HTML attributes that are \"overloaded booleans\": they behave like\n// booleans, but can also accept a string value.\n\n['capture', 'download' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty\n  name, // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are HTML attributes that must be positive numbers.\n\n['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty\n  name, // attributeName\n  null, // attributeNamespace\n  false);\n}); // These are HTML attributes that must be numbers.\n\n['rowSpan', 'start'].forEach(function (name) {\n  properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty\n  name.toLowerCase(), // attributeName\n  null, // attributeNamespace\n  false);\n});\nvar CAMELIZE = /[\\-\\:]([a-z])/g;\n\nvar capitalize = function (token) {\n  return token[1].toUpperCase();\n}; // This is a list of all SVG attributes that need special casing, namespacing,\n// or boolean value assignment. Regular attributes that just accept strings\n// and have the same names are omitted, just like in the HTML whitelist.\n// Some of these attributes can be hard to find. This list was created by\n// scraping the MDN documentation.\n\n\n['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (attributeName) {\n  var name = attributeName.replace(CAMELIZE, capitalize);\n  properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n  attributeName, null, // attributeNamespace\n  false);\n}); // String SVG attributes with the xlink namespace.\n\n['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (attributeName) {\n  var name = attributeName.replace(CAMELIZE, capitalize);\n  properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n  attributeName, 'http://www.w3.org/1999/xlink', false);\n}); // String SVG attributes with the xml namespace.\n\n['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,\n// you'll need to set attributeName to name.toLowerCase()\n// instead in the assignment below.\n].forEach(function (attributeName) {\n  var name = attributeName.replace(CAMELIZE, capitalize);\n  properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n  attributeName, 'http://www.w3.org/XML/1998/namespace', false);\n}); // These attribute exists both in HTML and SVG.\n// The attribute name is case-sensitive in SVG so we can't just use\n// the React name like we do for attributes that exist only in HTML.\n\n['tabIndex', 'crossOrigin'].forEach(function (attributeName) {\n  properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty\n  attributeName.toLowerCase(), // attributeName\n  null, // attributeNamespace\n  false);\n}); // These attributes accept URLs. These must not allow javascript: URLS.\n// These will also need to accept Trusted Types object in the future.\n\nvar xlinkHref = 'xlinkHref';\nproperties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty\n'xlink:href', 'http://www.w3.org/1999/xlink', true);\n['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {\n  properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty\n  attributeName.toLowerCase(), // attributeName\n  null, // attributeNamespace\n  true);\n});\n\nvar ReactDebugCurrentFrame = null;\n\n{\n  ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n} // A javascript: URL can contain leading C0 control or \\u0020 SPACE,\n// and any newline or tab are filtered out as if they're not part of the URL.\n// https://url.spec.whatwg.org/#url-parsing\n// Tab or newline are defined as \\r\\n\\t:\n// https://infra.spec.whatwg.org/#ascii-tab-or-newline\n// A C0 control is a code point in the range \\u0000 NULL to \\u001F\n// INFORMATION SEPARATOR ONE, inclusive:\n// https://infra.spec.whatwg.org/#c0-control-or-space\n\n/* eslint-disable max-len */\n\n\nvar isJavaScriptProtocol = /^[\\u0000-\\u001F ]*j[\\r\\n\\t]*a[\\r\\n\\t]*v[\\r\\n\\t]*a[\\r\\n\\t]*s[\\r\\n\\t]*c[\\r\\n\\t]*r[\\r\\n\\t]*i[\\r\\n\\t]*p[\\r\\n\\t]*t[\\r\\n\\t]*\\:/i;\nvar didWarn = false;\n\nfunction sanitizeURL(url) {\n  {\n    if (!didWarn && isJavaScriptProtocol.test(url)) {\n      didWarn = true;\n\n      error('A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url));\n    }\n  }\n}\n\n/**\n * Get the value for a property on a node. Only used in DEV for SSR validation.\n * The \"expected\" argument is used as a hint of what the expected value is.\n * Some properties have multiple equivalent values.\n */\nfunction getValueForProperty(node, name, expected, propertyInfo) {\n  {\n    if (propertyInfo.mustUseProperty) {\n      var propertyName = propertyInfo.propertyName;\n      return node[propertyName];\n    } else {\n      if ( propertyInfo.sanitizeURL) {\n        // If we haven't fully disabled javascript: URLs, and if\n        // the hydration is successful of a javascript: URL, we\n        // still want to warn on the client.\n        sanitizeURL('' + expected);\n      }\n\n      var attributeName = propertyInfo.attributeName;\n      var stringValue = null;\n\n      if (propertyInfo.type === OVERLOADED_BOOLEAN) {\n        if (node.hasAttribute(attributeName)) {\n          var value = node.getAttribute(attributeName);\n\n          if (value === '') {\n            return true;\n          }\n\n          if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n            return value;\n          }\n\n          if (value === '' + expected) {\n            return expected;\n          }\n\n          return value;\n        }\n      } else if (node.hasAttribute(attributeName)) {\n        if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n          // We had an attribute but shouldn't have had one, so read it\n          // for the error message.\n          return node.getAttribute(attributeName);\n        }\n\n        if (propertyInfo.type === BOOLEAN) {\n          // If this was a boolean, it doesn't matter what the value is\n          // the fact that we have it is the same as the expected.\n          return expected;\n        } // Even if this property uses a namespace we use getAttribute\n        // because we assume its namespaced name is the same as our config.\n        // To use getAttributeNS we need the local name which we don't have\n        // in our config atm.\n\n\n        stringValue = node.getAttribute(attributeName);\n      }\n\n      if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n        return stringValue === null ? expected : stringValue;\n      } else if (stringValue === '' + expected) {\n        return expected;\n      } else {\n        return stringValue;\n      }\n    }\n  }\n}\n/**\n * Get the value for a attribute on a node. Only used in DEV for SSR validation.\n * The third argument is used as a hint of what the expected value is. Some\n * attributes have multiple equivalent values.\n */\n\nfunction getValueForAttribute(node, name, expected) {\n  {\n    if (!isAttributeNameSafe(name)) {\n      return;\n    }\n\n    if (!node.hasAttribute(name)) {\n      return expected === undefined ? undefined : null;\n    }\n\n    var value = node.getAttribute(name);\n\n    if (value === '' + expected) {\n      return expected;\n    }\n\n    return value;\n  }\n}\n/**\n * Sets the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n * @param {*} value\n */\n\nfunction setValueForProperty(node, name, value, isCustomComponentTag) {\n  var propertyInfo = getPropertyInfo(name);\n\n  if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {\n    return;\n  }\n\n  if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {\n    value = null;\n  } // If the prop isn't in the special list, treat it as a simple attribute.\n\n\n  if (isCustomComponentTag || propertyInfo === null) {\n    if (isAttributeNameSafe(name)) {\n      var _attributeName = name;\n\n      if (value === null) {\n        node.removeAttribute(_attributeName);\n      } else {\n        node.setAttribute(_attributeName,  '' + value);\n      }\n    }\n\n    return;\n  }\n\n  var mustUseProperty = propertyInfo.mustUseProperty;\n\n  if (mustUseProperty) {\n    var propertyName = propertyInfo.propertyName;\n\n    if (value === null) {\n      var type = propertyInfo.type;\n      node[propertyName] = type === BOOLEAN ? false : '';\n    } else {\n      // Contrary to `setAttribute`, object properties are properly\n      // `toString`ed by IE8/9.\n      node[propertyName] = value;\n    }\n\n    return;\n  } // The rest are treated as attributes with special cases.\n\n\n  var attributeName = propertyInfo.attributeName,\n      attributeNamespace = propertyInfo.attributeNamespace;\n\n  if (value === null) {\n    node.removeAttribute(attributeName);\n  } else {\n    var _type = propertyInfo.type;\n    var attributeValue;\n\n    if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {\n      // If attribute type is boolean, we know for sure it won't be an execution sink\n      // and we won't require Trusted Type here.\n      attributeValue = '';\n    } else {\n      // `setAttribute` with objects becomes only `[object]` in IE8/9,\n      // ('' + value) makes it output the correct toString()-value.\n      {\n        attributeValue = '' + value;\n      }\n\n      if (propertyInfo.sanitizeURL) {\n        sanitizeURL(attributeValue.toString());\n      }\n    }\n\n    if (attributeNamespace) {\n      node.setAttributeNS(attributeNamespace, attributeName, attributeValue);\n    } else {\n      node.setAttribute(attributeName, attributeValue);\n    }\n  }\n}\n\nvar BEFORE_SLASH_RE = /^(.*)[\\\\\\/]/;\nfunction describeComponentFrame (name, source, ownerName) {\n  var sourceInfo = '';\n\n  if (source) {\n    var path = source.fileName;\n    var fileName = path.replace(BEFORE_SLASH_RE, '');\n\n    {\n      // In DEV, include code for a common special case:\n      // prefer \"folder/index.js\" instead of just \"index.js\".\n      if (/^index\\./.test(fileName)) {\n        var match = path.match(BEFORE_SLASH_RE);\n\n        if (match) {\n          var pathBeforeSlash = match[1];\n\n          if (pathBeforeSlash) {\n            var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');\n            fileName = folderName + '/' + fileName;\n          }\n        }\n      }\n    }\n\n    sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';\n  } else if (ownerName) {\n    sourceInfo = ' (created by ' + ownerName + ')';\n  }\n\n  return '\\n    in ' + (name || 'Unknown') + sourceInfo;\n}\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\nvar REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;\nvar MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\nvar FAUX_ITERATOR_SYMBOL = '@@iterator';\nfunction getIteratorFn(maybeIterable) {\n  if (maybeIterable === null || typeof maybeIterable !== 'object') {\n    return null;\n  }\n\n  var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];\n\n  if (typeof maybeIterator === 'function') {\n    return maybeIterator;\n  }\n\n  return null;\n}\n\nvar Uninitialized = -1;\nvar Pending = 0;\nvar Resolved = 1;\nvar Rejected = 2;\nfunction refineResolvedLazyComponent(lazyComponent) {\n  return lazyComponent._status === Resolved ? lazyComponent._result : null;\n}\nfunction initializeLazyComponentType(lazyComponent) {\n  if (lazyComponent._status === Uninitialized) {\n    lazyComponent._status = Pending;\n    var ctor = lazyComponent._ctor;\n    var thenable = ctor();\n    lazyComponent._result = thenable;\n    thenable.then(function (moduleObject) {\n      if (lazyComponent._status === Pending) {\n        var defaultExport = moduleObject.default;\n\n        {\n          if (defaultExport === undefined) {\n            error('lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\\n\\nYour code should look like: \\n  ' + \"const MyComponent = lazy(() => import('./MyComponent'))\", moduleObject);\n          }\n        }\n\n        lazyComponent._status = Resolved;\n        lazyComponent._result = defaultExport;\n      }\n    }, function (error) {\n      if (lazyComponent._status === Pending) {\n        lazyComponent._status = Rejected;\n        lazyComponent._result = error;\n      }\n    });\n  }\n}\n\nfunction getWrappedName(outerType, innerType, wrapperName) {\n  var functionName = innerType.displayName || innerType.name || '';\n  return outerType.displayName || (functionName !== '' ? wrapperName + \"(\" + functionName + \")\" : wrapperName);\n}\n\nfunction getComponentName(type) {\n  if (type == null) {\n    // Host root, text node or just invalid type.\n    return null;\n  }\n\n  {\n    if (typeof type.tag === 'number') {\n      error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');\n    }\n  }\n\n  if (typeof type === 'function') {\n    return type.displayName || type.name || null;\n  }\n\n  if (typeof type === 'string') {\n    return type;\n  }\n\n  switch (type) {\n    case REACT_FRAGMENT_TYPE:\n      return 'Fragment';\n\n    case REACT_PORTAL_TYPE:\n      return 'Portal';\n\n    case REACT_PROFILER_TYPE:\n      return \"Profiler\";\n\n    case REACT_STRICT_MODE_TYPE:\n      return 'StrictMode';\n\n    case REACT_SUSPENSE_TYPE:\n      return 'Suspense';\n\n    case REACT_SUSPENSE_LIST_TYPE:\n      return 'SuspenseList';\n  }\n\n  if (typeof type === 'object') {\n    switch (type.$$typeof) {\n      case REACT_CONTEXT_TYPE:\n        return 'Context.Consumer';\n\n      case REACT_PROVIDER_TYPE:\n        return 'Context.Provider';\n\n      case REACT_FORWARD_REF_TYPE:\n        return getWrappedName(type, type.render, 'ForwardRef');\n\n      case REACT_MEMO_TYPE:\n        return getComponentName(type.type);\n\n      case REACT_BLOCK_TYPE:\n        return getComponentName(type.render);\n\n      case REACT_LAZY_TYPE:\n        {\n          var thenable = type;\n          var resolvedThenable = refineResolvedLazyComponent(thenable);\n\n          if (resolvedThenable) {\n            return getComponentName(resolvedThenable);\n          }\n\n          break;\n        }\n    }\n  }\n\n  return null;\n}\n\nvar ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;\n\nfunction describeFiber(fiber) {\n  switch (fiber.tag) {\n    case HostRoot:\n    case HostPortal:\n    case HostText:\n    case Fragment:\n    case ContextProvider:\n    case ContextConsumer:\n      return '';\n\n    default:\n      var owner = fiber._debugOwner;\n      var source = fiber._debugSource;\n      var name = getComponentName(fiber.type);\n      var ownerName = null;\n\n      if (owner) {\n        ownerName = getComponentName(owner.type);\n      }\n\n      return describeComponentFrame(name, source, ownerName);\n  }\n}\n\nfunction getStackByFiberInDevAndProd(workInProgress) {\n  var info = '';\n  var node = workInProgress;\n\n  do {\n    info += describeFiber(node);\n    node = node.return;\n  } while (node);\n\n  return info;\n}\nvar current = null;\nvar isRendering = false;\nfunction getCurrentFiberOwnerNameInDevOrNull() {\n  {\n    if (current === null) {\n      return null;\n    }\n\n    var owner = current._debugOwner;\n\n    if (owner !== null && typeof owner !== 'undefined') {\n      return getComponentName(owner.type);\n    }\n  }\n\n  return null;\n}\nfunction getCurrentFiberStackInDev() {\n  {\n    if (current === null) {\n      return '';\n    } // Safe because if current fiber exists, we are reconciling,\n    // and it is guaranteed to be the work-in-progress version.\n\n\n    return getStackByFiberInDevAndProd(current);\n  }\n}\nfunction resetCurrentFiber() {\n  {\n    ReactDebugCurrentFrame$1.getCurrentStack = null;\n    current = null;\n    isRendering = false;\n  }\n}\nfunction setCurrentFiber(fiber) {\n  {\n    ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev;\n    current = fiber;\n    isRendering = false;\n  }\n}\nfunction setIsRendering(rendering) {\n  {\n    isRendering = rendering;\n  }\n}\n\n// Flow does not allow string concatenation of most non-string types. To work\n// around this limitation, we use an opaque type that can only be obtained by\n// passing the value through getToStringValue first.\nfunction toString(value) {\n  return '' + value;\n}\nfunction getToStringValue(value) {\n  switch (typeof value) {\n    case 'boolean':\n    case 'number':\n    case 'object':\n    case 'string':\n    case 'undefined':\n      return value;\n\n    default:\n      // function, symbol are assigned as empty strings\n      return '';\n  }\n}\n\nvar ReactDebugCurrentFrame$2 = null;\nvar ReactControlledValuePropTypes = {\n  checkPropTypes: null\n};\n\n{\n  ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;\n  var hasReadOnlyValue = {\n    button: true,\n    checkbox: true,\n    image: true,\n    hidden: true,\n    radio: true,\n    reset: true,\n    submit: true\n  };\n  var propTypes = {\n    value: function (props, propName, componentName) {\n      if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {\n        return null;\n      }\n\n      return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n    },\n    checked: function (props, propName, componentName) {\n      if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {\n        return null;\n      }\n\n      return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n    }\n  };\n  /**\n   * Provide a linked `value` attribute for controlled forms. You should not use\n   * this outside of the ReactDOM controlled form components.\n   */\n\n  ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {\n    checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);\n  };\n}\n\nfunction isCheckable(elem) {\n  var type = elem.type;\n  var nodeName = elem.nodeName;\n  return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');\n}\n\nfunction getTracker(node) {\n  return node._valueTracker;\n}\n\nfunction detachTracker(node) {\n  node._valueTracker = null;\n}\n\nfunction getValueFromNode(node) {\n  var value = '';\n\n  if (!node) {\n    return value;\n  }\n\n  if (isCheckable(node)) {\n    value = node.checked ? 'true' : 'false';\n  } else {\n    value = node.value;\n  }\n\n  return value;\n}\n\nfunction trackValueOnNode(node) {\n  var valueField = isCheckable(node) ? 'checked' : 'value';\n  var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);\n  var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail\n  // and don't track value will cause over reporting of changes,\n  // but it's better then a hard failure\n  // (needed for certain tests that spyOn input values and Safari)\n\n  if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {\n    return;\n  }\n\n  var get = descriptor.get,\n      set = descriptor.set;\n  Object.defineProperty(node, valueField, {\n    configurable: true,\n    get: function () {\n      return get.call(this);\n    },\n    set: function (value) {\n      currentValue = '' + value;\n      set.call(this, value);\n    }\n  }); // We could've passed this the first time\n  // but it triggers a bug in IE11 and Edge 14/15.\n  // Calling defineProperty() again should be equivalent.\n  // https://github.com/facebook/react/issues/11768\n\n  Object.defineProperty(node, valueField, {\n    enumerable: descriptor.enumerable\n  });\n  var tracker = {\n    getValue: function () {\n      return currentValue;\n    },\n    setValue: function (value) {\n      currentValue = '' + value;\n    },\n    stopTracking: function () {\n      detachTracker(node);\n      delete node[valueField];\n    }\n  };\n  return tracker;\n}\n\nfunction track(node) {\n  if (getTracker(node)) {\n    return;\n  } // TODO: Once it's just Fiber we can move this to node._wrapperState\n\n\n  node._valueTracker = trackValueOnNode(node);\n}\nfunction updateValueIfChanged(node) {\n  if (!node) {\n    return false;\n  }\n\n  var tracker = getTracker(node); // if there is no tracker at this point it's unlikely\n  // that trying again will succeed\n\n  if (!tracker) {\n    return true;\n  }\n\n  var lastValue = tracker.getValue();\n  var nextValue = getValueFromNode(node);\n\n  if (nextValue !== lastValue) {\n    tracker.setValue(nextValue);\n    return true;\n  }\n\n  return false;\n}\n\nvar didWarnValueDefaultValue = false;\nvar didWarnCheckedDefaultChecked = false;\nvar didWarnControlledToUncontrolled = false;\nvar didWarnUncontrolledToControlled = false;\n\nfunction isControlled(props) {\n  var usesChecked = props.type === 'checkbox' || props.type === 'radio';\n  return usesChecked ? props.checked != null : props.value != null;\n}\n/**\n * Implements an <input> host component that allows setting these optional\n * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.\n *\n * If `checked` or `value` are not supplied (or null/undefined), user actions\n * that affect the checked state or value will trigger updates to the element.\n *\n * If they are supplied (and not null/undefined), the rendered element will not\n * trigger updates to the element. Instead, the props must change in order for\n * the rendered element to be updated.\n *\n * The rendered element will be initialized as unchecked (or `defaultChecked`)\n * with an empty value (or `defaultValue`).\n *\n * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html\n */\n\n\nfunction getHostProps(element, props) {\n  var node = element;\n  var checked = props.checked;\n\n  var hostProps = _assign({}, props, {\n    defaultChecked: undefined,\n    defaultValue: undefined,\n    value: undefined,\n    checked: checked != null ? checked : node._wrapperState.initialChecked\n  });\n\n  return hostProps;\n}\nfunction initWrapperState(element, props) {\n  {\n    ReactControlledValuePropTypes.checkPropTypes('input', props);\n\n    if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {\n      error('%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);\n\n      didWarnCheckedDefaultChecked = true;\n    }\n\n    if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {\n      error('%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);\n\n      didWarnValueDefaultValue = true;\n    }\n  }\n\n  var node = element;\n  var defaultValue = props.defaultValue == null ? '' : props.defaultValue;\n  node._wrapperState = {\n    initialChecked: props.checked != null ? props.checked : props.defaultChecked,\n    initialValue: getToStringValue(props.value != null ? props.value : defaultValue),\n    controlled: isControlled(props)\n  };\n}\nfunction updateChecked(element, props) {\n  var node = element;\n  var checked = props.checked;\n\n  if (checked != null) {\n    setValueForProperty(node, 'checked', checked, false);\n  }\n}\nfunction updateWrapper(element, props) {\n  var node = element;\n\n  {\n    var controlled = isControlled(props);\n\n    if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {\n      error('A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);\n\n      didWarnUncontrolledToControlled = true;\n    }\n\n    if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {\n      error('A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);\n\n      didWarnControlledToUncontrolled = true;\n    }\n  }\n\n  updateChecked(element, props);\n  var value = getToStringValue(props.value);\n  var type = props.type;\n\n  if (value != null) {\n    if (type === 'number') {\n      if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.\n      // eslint-disable-next-line\n      node.value != value) {\n        node.value = toString(value);\n      }\n    } else if (node.value !== toString(value)) {\n      node.value = toString(value);\n    }\n  } else if (type === 'submit' || type === 'reset') {\n    // Submit/reset inputs need the attribute removed completely to avoid\n    // blank-text buttons.\n    node.removeAttribute('value');\n    return;\n  }\n\n  {\n    // When syncing the value attribute, the value comes from a cascade of\n    // properties:\n    //  1. The value React property\n    //  2. The defaultValue React property\n    //  3. Otherwise there should be no change\n    if (props.hasOwnProperty('value')) {\n      setDefaultValue(node, props.type, value);\n    } else if (props.hasOwnProperty('defaultValue')) {\n      setDefaultValue(node, props.type, getToStringValue(props.defaultValue));\n    }\n  }\n\n  {\n    // When syncing the checked attribute, it only changes when it needs\n    // to be removed, such as transitioning from a checkbox into a text input\n    if (props.checked == null && props.defaultChecked != null) {\n      node.defaultChecked = !!props.defaultChecked;\n    }\n  }\n}\nfunction postMountWrapper(element, props, isHydrating) {\n  var node = element; // Do not assign value if it is already set. This prevents user text input\n  // from being lost during SSR hydration.\n\n  if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {\n    var type = props.type;\n    var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the\n    // default value provided by the browser. See: #12872\n\n    if (isButton && (props.value === undefined || props.value === null)) {\n      return;\n    }\n\n    var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input\n    // from being lost during SSR hydration.\n\n    if (!isHydrating) {\n      {\n        // When syncing the value attribute, the value property should use\n        // the wrapperState._initialValue property. This uses:\n        //\n        //   1. The value React property when present\n        //   2. The defaultValue React property when present\n        //   3. An empty string\n        if (initialValue !== node.value) {\n          node.value = initialValue;\n        }\n      }\n    }\n\n    {\n      // Otherwise, the value attribute is synchronized to the property,\n      // so we assign defaultValue to the same thing as the value property\n      // assignment step above.\n      node.defaultValue = initialValue;\n    }\n  } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug\n  // this is needed to work around a chrome bug where setting defaultChecked\n  // will sometimes influence the value of checked (even after detachment).\n  // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416\n  // We need to temporarily unset name to avoid disrupting radio button groups.\n\n\n  var name = node.name;\n\n  if (name !== '') {\n    node.name = '';\n  }\n\n  {\n    // When syncing the checked attribute, both the checked property and\n    // attribute are assigned at the same time using defaultChecked. This uses:\n    //\n    //   1. The checked React property when present\n    //   2. The defaultChecked React property when present\n    //   3. Otherwise, false\n    node.defaultChecked = !node.defaultChecked;\n    node.defaultChecked = !!node._wrapperState.initialChecked;\n  }\n\n  if (name !== '') {\n    node.name = name;\n  }\n}\nfunction restoreControlledState(element, props) {\n  var node = element;\n  updateWrapper(node, props);\n  updateNamedCousins(node, props);\n}\n\nfunction updateNamedCousins(rootNode, props) {\n  var name = props.name;\n\n  if (props.type === 'radio' && name != null) {\n    var queryRoot = rootNode;\n\n    while (queryRoot.parentNode) {\n      queryRoot = queryRoot.parentNode;\n    } // If `rootNode.form` was non-null, then we could try `form.elements`,\n    // but that sometimes behaves strangely in IE8. We could also try using\n    // `form.getElementsByName`, but that will only return direct children\n    // and won't include inputs that use the HTML5 `form=` attribute. Since\n    // the input might not even be in a form. It might not even be in the\n    // document. Let's just use the local `querySelectorAll` to ensure we don't\n    // miss anything.\n\n\n    var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type=\"radio\"]');\n\n    for (var i = 0; i < group.length; i++) {\n      var otherNode = group[i];\n\n      if (otherNode === rootNode || otherNode.form !== rootNode.form) {\n        continue;\n      } // This will throw if radio buttons rendered by different copies of React\n      // and the same name are rendered into the same form (same as #1939).\n      // That's probably okay; we don't support it just as we don't support\n      // mixing React radio buttons with non-React ones.\n\n\n      var otherProps = getFiberCurrentPropsFromNode$1(otherNode);\n\n      if (!otherProps) {\n        {\n          throw Error( \"ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.\" );\n        }\n      } // We need update the tracked value on the named cousin since the value\n      // was changed but the input saw no event or value set\n\n\n      updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that\n      // was previously checked to update will cause it to be come re-checked\n      // as appropriate.\n\n      updateWrapper(otherNode, otherProps);\n    }\n  }\n} // In Chrome, assigning defaultValue to certain input types triggers input validation.\n// For number inputs, the display value loses trailing decimal points. For email inputs,\n// Chrome raises \"The specified value <x> is not a valid email address\".\n//\n// Here we check to see if the defaultValue has actually changed, avoiding these problems\n// when the user is inputting text\n//\n// https://github.com/facebook/react/issues/7253\n\n\nfunction setDefaultValue(node, type, value) {\n  if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js\n  type !== 'number' || node.ownerDocument.activeElement !== node) {\n    if (value == null) {\n      node.defaultValue = toString(node._wrapperState.initialValue);\n    } else if (node.defaultValue !== toString(value)) {\n      node.defaultValue = toString(value);\n    }\n  }\n}\n\nvar didWarnSelectedSetOnOption = false;\nvar didWarnInvalidChild = false;\n\nfunction flattenChildren(children) {\n  var content = ''; // Flatten children. We'll warn if they are invalid\n  // during validateProps() which runs for hydration too.\n  // Note that this would throw on non-element objects.\n  // Elements are stringified (which is normally irrelevant\n  // but matters for <fbt>).\n\n  React.Children.forEach(children, function (child) {\n    if (child == null) {\n      return;\n    }\n\n    content += child; // Note: we don't warn about invalid children here.\n    // Instead, this is done separately below so that\n    // it happens during the hydration codepath too.\n  });\n  return content;\n}\n/**\n * Implements an <option> host component that warns when `selected` is set.\n */\n\n\nfunction validateProps(element, props) {\n  {\n    // This mirrors the codepath above, but runs for hydration too.\n    // Warn about invalid children here so that client and hydration are consistent.\n    // TODO: this seems like it could cause a DEV-only throw for hydration\n    // if children contains a non-element object. We should try to avoid that.\n    if (typeof props.children === 'object' && props.children !== null) {\n      React.Children.forEach(props.children, function (child) {\n        if (child == null) {\n          return;\n        }\n\n        if (typeof child === 'string' || typeof child === 'number') {\n          return;\n        }\n\n        if (typeof child.type !== 'string') {\n          return;\n        }\n\n        if (!didWarnInvalidChild) {\n          didWarnInvalidChild = true;\n\n          error('Only strings and numbers are supported as <option> children.');\n        }\n      });\n    } // TODO: Remove support for `selected` in <option>.\n\n\n    if (props.selected != null && !didWarnSelectedSetOnOption) {\n      error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');\n\n      didWarnSelectedSetOnOption = true;\n    }\n  }\n}\nfunction postMountWrapper$1(element, props) {\n  // value=\"\" should make a value attribute (#6219)\n  if (props.value != null) {\n    element.setAttribute('value', toString(getToStringValue(props.value)));\n  }\n}\nfunction getHostProps$1(element, props) {\n  var hostProps = _assign({\n    children: undefined\n  }, props);\n\n  var content = flattenChildren(props.children);\n\n  if (content) {\n    hostProps.children = content;\n  }\n\n  return hostProps;\n}\n\nvar didWarnValueDefaultValue$1;\n\n{\n  didWarnValueDefaultValue$1 = false;\n}\n\nfunction getDeclarationErrorAddendum() {\n  var ownerName = getCurrentFiberOwnerNameInDevOrNull();\n\n  if (ownerName) {\n    return '\\n\\nCheck the render method of `' + ownerName + '`.';\n  }\n\n  return '';\n}\n\nvar valuePropNames = ['value', 'defaultValue'];\n/**\n * Validation function for `value` and `defaultValue`.\n */\n\nfunction checkSelectPropTypes(props) {\n  {\n    ReactControlledValuePropTypes.checkPropTypes('select', props);\n\n    for (var i = 0; i < valuePropNames.length; i++) {\n      var propName = valuePropNames[i];\n\n      if (props[propName] == null) {\n        continue;\n      }\n\n      var isArray = Array.isArray(props[propName]);\n\n      if (props.multiple && !isArray) {\n        error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());\n      } else if (!props.multiple && isArray) {\n        error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());\n      }\n    }\n  }\n}\n\nfunction updateOptions(node, multiple, propValue, setDefaultSelected) {\n  var options = node.options;\n\n  if (multiple) {\n    var selectedValues = propValue;\n    var selectedValue = {};\n\n    for (var i = 0; i < selectedValues.length; i++) {\n      // Prefix to avoid chaos with special keys.\n      selectedValue['$' + selectedValues[i]] = true;\n    }\n\n    for (var _i = 0; _i < options.length; _i++) {\n      var selected = selectedValue.hasOwnProperty('$' + options[_i].value);\n\n      if (options[_i].selected !== selected) {\n        options[_i].selected = selected;\n      }\n\n      if (selected && setDefaultSelected) {\n        options[_i].defaultSelected = true;\n      }\n    }\n  } else {\n    // Do not set `select.value` as exact behavior isn't consistent across all\n    // browsers for all cases.\n    var _selectedValue = toString(getToStringValue(propValue));\n\n    var defaultSelected = null;\n\n    for (var _i2 = 0; _i2 < options.length; _i2++) {\n      if (options[_i2].value === _selectedValue) {\n        options[_i2].selected = true;\n\n        if (setDefaultSelected) {\n          options[_i2].defaultSelected = true;\n        }\n\n        return;\n      }\n\n      if (defaultSelected === null && !options[_i2].disabled) {\n        defaultSelected = options[_i2];\n      }\n    }\n\n    if (defaultSelected !== null) {\n      defaultSelected.selected = true;\n    }\n  }\n}\n/**\n * Implements a <select> host component that allows optionally setting the\n * props `value` and `defaultValue`. If `multiple` is false, the prop must be a\n * stringable. If `multiple` is true, the prop must be an array of stringables.\n *\n * If `value` is not supplied (or null/undefined), user actions that change the\n * selected option will trigger updates to the rendered options.\n *\n * If it is supplied (and not null/undefined), the rendered options will not\n * update in response to user actions. Instead, the `value` prop must change in\n * order for the rendered options to update.\n *\n * If `defaultValue` is provided, any options with the supplied values will be\n * selected.\n */\n\n\nfunction getHostProps$2(element, props) {\n  return _assign({}, props, {\n    value: undefined\n  });\n}\nfunction initWrapperState$1(element, props) {\n  var node = element;\n\n  {\n    checkSelectPropTypes(props);\n  }\n\n  node._wrapperState = {\n    wasMultiple: !!props.multiple\n  };\n\n  {\n    if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {\n      error('Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');\n\n      didWarnValueDefaultValue$1 = true;\n    }\n  }\n}\nfunction postMountWrapper$2(element, props) {\n  var node = element;\n  node.multiple = !!props.multiple;\n  var value = props.value;\n\n  if (value != null) {\n    updateOptions(node, !!props.multiple, value, false);\n  } else if (props.defaultValue != null) {\n    updateOptions(node, !!props.multiple, props.defaultValue, true);\n  }\n}\nfunction postUpdateWrapper(element, props) {\n  var node = element;\n  var wasMultiple = node._wrapperState.wasMultiple;\n  node._wrapperState.wasMultiple = !!props.multiple;\n  var value = props.value;\n\n  if (value != null) {\n    updateOptions(node, !!props.multiple, value, false);\n  } else if (wasMultiple !== !!props.multiple) {\n    // For simplicity, reapply `defaultValue` if `multiple` is toggled.\n    if (props.defaultValue != null) {\n      updateOptions(node, !!props.multiple, props.defaultValue, true);\n    } else {\n      // Revert the select back to its default unselected state.\n      updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);\n    }\n  }\n}\nfunction restoreControlledState$1(element, props) {\n  var node = element;\n  var value = props.value;\n\n  if (value != null) {\n    updateOptions(node, !!props.multiple, value, false);\n  }\n}\n\nvar didWarnValDefaultVal = false;\n\n/**\n * Implements a <textarea> host component that allows setting `value`, and\n * `defaultValue`. This differs from the traditional DOM API because value is\n * usually set as PCDATA children.\n *\n * If `value` is not supplied (or null/undefined), user actions that affect the\n * value will trigger updates to the element.\n *\n * If `value` is supplied (and not null/undefined), the rendered element will\n * not trigger updates to the element. Instead, the `value` prop must change in\n * order for the rendered element to be updated.\n *\n * The rendered element will be initialized with an empty value, the prop\n * `defaultValue` if specified, or the children content (deprecated).\n */\nfunction getHostProps$3(element, props) {\n  var node = element;\n\n  if (!(props.dangerouslySetInnerHTML == null)) {\n    {\n      throw Error( \"`dangerouslySetInnerHTML` does not make sense on <textarea>.\" );\n    }\n  } // Always set children to the same thing. In IE9, the selection range will\n  // get reset if `textContent` is mutated.  We could add a check in setTextContent\n  // to only set the value if/when the value differs from the node value (which would\n  // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this\n  // solution. The value can be a boolean or object so that's why it's forced\n  // to be a string.\n\n\n  var hostProps = _assign({}, props, {\n    value: undefined,\n    defaultValue: undefined,\n    children: toString(node._wrapperState.initialValue)\n  });\n\n  return hostProps;\n}\nfunction initWrapperState$2(element, props) {\n  var node = element;\n\n  {\n    ReactControlledValuePropTypes.checkPropTypes('textarea', props);\n\n    if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {\n      error('%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');\n\n      didWarnValDefaultVal = true;\n    }\n  }\n\n  var initialValue = props.value; // Only bother fetching default value if we're going to use it\n\n  if (initialValue == null) {\n    var children = props.children,\n        defaultValue = props.defaultValue;\n\n    if (children != null) {\n      {\n        error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');\n      }\n\n      {\n        if (!(defaultValue == null)) {\n          {\n            throw Error( \"If you supply `defaultValue` on a <textarea>, do not pass children.\" );\n          }\n        }\n\n        if (Array.isArray(children)) {\n          if (!(children.length <= 1)) {\n            {\n              throw Error( \"<textarea> can only have at most one child.\" );\n            }\n          }\n\n          children = children[0];\n        }\n\n        defaultValue = children;\n      }\n    }\n\n    if (defaultValue == null) {\n      defaultValue = '';\n    }\n\n    initialValue = defaultValue;\n  }\n\n  node._wrapperState = {\n    initialValue: getToStringValue(initialValue)\n  };\n}\nfunction updateWrapper$1(element, props) {\n  var node = element;\n  var value = getToStringValue(props.value);\n  var defaultValue = getToStringValue(props.defaultValue);\n\n  if (value != null) {\n    // Cast `value` to a string to ensure the value is set correctly. While\n    // browsers typically do this as necessary, jsdom doesn't.\n    var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed\n\n    if (newValue !== node.value) {\n      node.value = newValue;\n    }\n\n    if (props.defaultValue == null && node.defaultValue !== newValue) {\n      node.defaultValue = newValue;\n    }\n  }\n\n  if (defaultValue != null) {\n    node.defaultValue = toString(defaultValue);\n  }\n}\nfunction postMountWrapper$3(element, props) {\n  var node = element; // This is in postMount because we need access to the DOM node, which is not\n  // available until after the component has mounted.\n\n  var textContent = node.textContent; // Only set node.value if textContent is equal to the expected\n  // initial value. In IE10/IE11 there is a bug where the placeholder attribute\n  // will populate textContent as well.\n  // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/\n\n  if (textContent === node._wrapperState.initialValue) {\n    if (textContent !== '' && textContent !== null) {\n      node.value = textContent;\n    }\n  }\n}\nfunction restoreControlledState$2(element, props) {\n  // DOM component is still mounted; update\n  updateWrapper$1(element, props);\n}\n\nvar HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\nvar MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\nvar SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nvar Namespaces = {\n  html: HTML_NAMESPACE,\n  mathml: MATH_NAMESPACE,\n  svg: SVG_NAMESPACE\n}; // Assumes there is no parent namespace.\n\nfunction getIntrinsicNamespace(type) {\n  switch (type) {\n    case 'svg':\n      return SVG_NAMESPACE;\n\n    case 'math':\n      return MATH_NAMESPACE;\n\n    default:\n      return HTML_NAMESPACE;\n  }\n}\nfunction getChildNamespace(parentNamespace, type) {\n  if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {\n    // No (or default) parent namespace: potential entry point.\n    return getIntrinsicNamespace(type);\n  }\n\n  if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {\n    // We're leaving SVG.\n    return HTML_NAMESPACE;\n  } // By default, pass namespace below.\n\n\n  return parentNamespace;\n}\n\n/* globals MSApp */\n\n/**\n * Create a function which has 'unsafe' privileges (required by windows8 apps)\n */\nvar createMicrosoftUnsafeLocalFunction = function (func) {\n  if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {\n    return function (arg0, arg1, arg2, arg3) {\n      MSApp.execUnsafeLocalFunction(function () {\n        return func(arg0, arg1, arg2, arg3);\n      });\n    };\n  } else {\n    return func;\n  }\n};\n\nvar reusableSVGContainer;\n/**\n * Set the innerHTML property of a node\n *\n * @param {DOMElement} node\n * @param {string} html\n * @internal\n */\n\nvar setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {\n  if (node.namespaceURI === Namespaces.svg) {\n\n    if (!('innerHTML' in node)) {\n      // IE does not have innerHTML for SVG nodes, so instead we inject the\n      // new markup in a temp node and then move the child nodes across into\n      // the target node\n      reusableSVGContainer = reusableSVGContainer || document.createElement('div');\n      reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';\n      var svgNode = reusableSVGContainer.firstChild;\n\n      while (node.firstChild) {\n        node.removeChild(node.firstChild);\n      }\n\n      while (svgNode.firstChild) {\n        node.appendChild(svgNode.firstChild);\n      }\n\n      return;\n    }\n  }\n\n  node.innerHTML = html;\n});\n\n/**\n * HTML nodeType values that represent the type of the node\n */\nvar ELEMENT_NODE = 1;\nvar TEXT_NODE = 3;\nvar COMMENT_NODE = 8;\nvar DOCUMENT_NODE = 9;\nvar DOCUMENT_FRAGMENT_NODE = 11;\n\n/**\n * Set the textContent property of a node. For text updates, it's faster\n * to set the `nodeValue` of the Text node directly instead of using\n * `.textContent` which will remove the existing node and create a new one.\n *\n * @param {DOMElement} node\n * @param {string} text\n * @internal\n */\n\nvar setTextContent = function (node, text) {\n  if (text) {\n    var firstChild = node.firstChild;\n\n    if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {\n      firstChild.nodeValue = text;\n      return;\n    }\n  }\n\n  node.textContent = text;\n};\n\n// Do not use the below two methods directly!\n// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.\n// (It is the only module that is allowed to access these methods.)\nfunction unsafeCastStringToDOMTopLevelType(topLevelType) {\n  return topLevelType;\n}\nfunction unsafeCastDOMTopLevelTypeToString(topLevelType) {\n  return topLevelType;\n}\n\n/**\n * Generate a mapping of standard vendor prefixes using the defined style property and event name.\n *\n * @param {string} styleProp\n * @param {string} eventName\n * @returns {object}\n */\n\nfunction makePrefixMap(styleProp, eventName) {\n  var prefixes = {};\n  prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n  prefixes['Webkit' + styleProp] = 'webkit' + eventName;\n  prefixes['Moz' + styleProp] = 'moz' + eventName;\n  return prefixes;\n}\n/**\n * A list of event names to a configurable list of vendor prefixes.\n */\n\n\nvar vendorPrefixes = {\n  animationend: makePrefixMap('Animation', 'AnimationEnd'),\n  animationiteration: makePrefixMap('Animation', 'AnimationIteration'),\n  animationstart: makePrefixMap('Animation', 'AnimationStart'),\n  transitionend: makePrefixMap('Transition', 'TransitionEnd')\n};\n/**\n * Event names that have already been detected and prefixed (if applicable).\n */\n\nvar prefixedEventNames = {};\n/**\n * Element to check for prefixes on.\n */\n\nvar style = {};\n/**\n * Bootstrap if a DOM exists.\n */\n\nif (canUseDOM) {\n  style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,\n  // the un-prefixed \"animation\" and \"transition\" properties are defined on the\n  // style object but the events that fire will still be prefixed, so we need\n  // to check if the un-prefixed events are usable, and if not remove them from the map.\n\n  if (!('AnimationEvent' in window)) {\n    delete vendorPrefixes.animationend.animation;\n    delete vendorPrefixes.animationiteration.animation;\n    delete vendorPrefixes.animationstart.animation;\n  } // Same as above\n\n\n  if (!('TransitionEvent' in window)) {\n    delete vendorPrefixes.transitionend.transition;\n  }\n}\n/**\n * Attempts to determine the correct vendor prefixed event name.\n *\n * @param {string} eventName\n * @returns {string}\n */\n\n\nfunction getVendorPrefixedEventName(eventName) {\n  if (prefixedEventNames[eventName]) {\n    return prefixedEventNames[eventName];\n  } else if (!vendorPrefixes[eventName]) {\n    return eventName;\n  }\n\n  var prefixMap = vendorPrefixes[eventName];\n\n  for (var styleProp in prefixMap) {\n    if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {\n      return prefixedEventNames[eventName] = prefixMap[styleProp];\n    }\n  }\n\n  return eventName;\n}\n\n/**\n * To identify top level events in ReactDOM, we use constants defined by this\n * module. This is the only module that uses the unsafe* methods to express\n * that the constants actually correspond to the browser event names. This lets\n * us save some bundle size by avoiding a top level type -> event name map.\n * The rest of ReactDOM code should import top level types from this file.\n */\n\nvar TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');\nvar TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));\nvar TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));\nvar TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));\nvar TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');\nvar TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');\nvar TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');\nvar TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');\nvar TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');\nvar TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');\nvar TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');\nvar TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');\nvar TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');\nvar TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');\nvar TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');\nvar TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');\nvar TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');\nvar TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');\nvar TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');\nvar TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');\nvar TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');\nvar TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');\nvar TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');\nvar TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');\nvar TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');\nvar TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');\nvar TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');\nvar TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');\nvar TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');\nvar TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');\nvar TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');\nvar TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');\nvar TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');\nvar TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');\nvar TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');\nvar TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');\nvar TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');\nvar TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');\nvar TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');\nvar TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');\nvar TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');\nvar TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');\nvar TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');\nvar TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');\nvar TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');\nvar TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');\nvar TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');\nvar TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');\nvar TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');\nvar TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');\nvar TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');\nvar TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');\nvar TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');\nvar TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');\nvar TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');\nvar TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');\nvar TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');\nvar TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');\nvar TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');\nvar TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');\nvar TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');\nvar TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');\nvar TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');\nvar TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');\nvar TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');\nvar TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');\nvar TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');\nvar TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');\nvar TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');\nvar TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');\nvar TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');\nvar TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');\nvar TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');\nvar TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');\nvar TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');\nvar TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');\nvar TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));\nvar TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');\nvar TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');\nvar TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); // List of events that need to be individually attached to media elements.\n// Note that events in this list will *not* be listened to at the top level\n// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.\n\nvar mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];\nfunction getRawEventName(topLevelType) {\n  return unsafeCastDOMTopLevelTypeToString(topLevelType);\n}\n\nvar PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; // prettier-ignore\n\nvar elementListenerMap = new PossiblyWeakMap();\nfunction getListenerMapForElement(element) {\n  var listenerMap = elementListenerMap.get(element);\n\n  if (listenerMap === undefined) {\n    listenerMap = new Map();\n    elementListenerMap.set(element, listenerMap);\n  }\n\n  return listenerMap;\n}\n\n/**\n * `ReactInstanceMap` maintains a mapping from a public facing stateful\n * instance (key) and the internal representation (value). This allows public\n * methods to accept the user facing instance as an argument and map them back\n * to internal methods.\n *\n * Note that this module is currently shared and assumed to be stateless.\n * If this becomes an actual Map, that will break.\n */\nfunction get(key) {\n  return key._reactInternalFiber;\n}\nfunction has(key) {\n  return key._reactInternalFiber !== undefined;\n}\nfunction set(key, value) {\n  key._reactInternalFiber = value;\n}\n\n// Don't change these two values. They're used by React Dev Tools.\nvar NoEffect =\n/*              */\n0;\nvar PerformedWork =\n/*         */\n1; // You can change the rest (and add more).\n\nvar Placement =\n/*             */\n2;\nvar Update =\n/*                */\n4;\nvar PlacementAndUpdate =\n/*    */\n6;\nvar Deletion =\n/*              */\n8;\nvar ContentReset =\n/*          */\n16;\nvar Callback =\n/*              */\n32;\nvar DidCapture =\n/*            */\n64;\nvar Ref =\n/*                   */\n128;\nvar Snapshot =\n/*              */\n256;\nvar Passive =\n/*               */\n512;\nvar Hydrating =\n/*             */\n1024;\nvar HydratingAndUpdate =\n/*    */\n1028; // Passive & Update & Callback & Ref & Snapshot\n\nvar LifecycleEffectMask =\n/*   */\n932; // Union of all host effects\n\nvar HostEffectMask =\n/*        */\n2047;\nvar Incomplete =\n/*            */\n2048;\nvar ShouldCapture =\n/*         */\n4096;\n\nvar ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;\nfunction getNearestMountedFiber(fiber) {\n  var node = fiber;\n  var nearestMounted = fiber;\n\n  if (!fiber.alternate) {\n    // If there is no alternate, this might be a new tree that isn't inserted\n    // yet. If it is, then it will have a pending insertion effect on it.\n    var nextNode = node;\n\n    do {\n      node = nextNode;\n\n      if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {\n        // This is an insertion or in-progress hydration. The nearest possible\n        // mounted fiber is the parent but we need to continue to figure out\n        // if that one is still mounted.\n        nearestMounted = node.return;\n      }\n\n      nextNode = node.return;\n    } while (nextNode);\n  } else {\n    while (node.return) {\n      node = node.return;\n    }\n  }\n\n  if (node.tag === HostRoot) {\n    // TODO: Check if this was a nested HostRoot when used with\n    // renderContainerIntoSubtree.\n    return nearestMounted;\n  } // If we didn't hit the root, that means that we're in an disconnected tree\n  // that has been unmounted.\n\n\n  return null;\n}\nfunction getSuspenseInstanceFromFiber(fiber) {\n  if (fiber.tag === SuspenseComponent) {\n    var suspenseState = fiber.memoizedState;\n\n    if (suspenseState === null) {\n      var current = fiber.alternate;\n\n      if (current !== null) {\n        suspenseState = current.memoizedState;\n      }\n    }\n\n    if (suspenseState !== null) {\n      return suspenseState.dehydrated;\n    }\n  }\n\n  return null;\n}\nfunction getContainerFromFiber(fiber) {\n  return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;\n}\nfunction isFiberMounted(fiber) {\n  return getNearestMountedFiber(fiber) === fiber;\n}\nfunction isMounted(component) {\n  {\n    var owner = ReactCurrentOwner.current;\n\n    if (owner !== null && owner.tag === ClassComponent) {\n      var ownerFiber = owner;\n      var instance = ownerFiber.stateNode;\n\n      if (!instance._warnedAboutRefsInRender) {\n        error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');\n      }\n\n      instance._warnedAboutRefsInRender = true;\n    }\n  }\n\n  var fiber = get(component);\n\n  if (!fiber) {\n    return false;\n  }\n\n  return getNearestMountedFiber(fiber) === fiber;\n}\n\nfunction assertIsMounted(fiber) {\n  if (!(getNearestMountedFiber(fiber) === fiber)) {\n    {\n      throw Error( \"Unable to find node on an unmounted component.\" );\n    }\n  }\n}\n\nfunction findCurrentFiberUsingSlowPath(fiber) {\n  var alternate = fiber.alternate;\n\n  if (!alternate) {\n    // If there is no alternate, then we only need to check if it is mounted.\n    var nearestMounted = getNearestMountedFiber(fiber);\n\n    if (!(nearestMounted !== null)) {\n      {\n        throw Error( \"Unable to find node on an unmounted component.\" );\n      }\n    }\n\n    if (nearestMounted !== fiber) {\n      return null;\n    }\n\n    return fiber;\n  } // If we have two possible branches, we'll walk backwards up to the root\n  // to see what path the root points to. On the way we may hit one of the\n  // special cases and we'll deal with them.\n\n\n  var a = fiber;\n  var b = alternate;\n\n  while (true) {\n    var parentA = a.return;\n\n    if (parentA === null) {\n      // We're at the root.\n      break;\n    }\n\n    var parentB = parentA.alternate;\n\n    if (parentB === null) {\n      // There is no alternate. This is an unusual case. Currently, it only\n      // happens when a Suspense component is hidden. An extra fragment fiber\n      // is inserted in between the Suspense fiber and its children. Skip\n      // over this extra fragment fiber and proceed to the next parent.\n      var nextParent = parentA.return;\n\n      if (nextParent !== null) {\n        a = b = nextParent;\n        continue;\n      } // If there's no parent, we're at the root.\n\n\n      break;\n    } // If both copies of the parent fiber point to the same child, we can\n    // assume that the child is current. This happens when we bailout on low\n    // priority: the bailed out fiber's child reuses the current child.\n\n\n    if (parentA.child === parentB.child) {\n      var child = parentA.child;\n\n      while (child) {\n        if (child === a) {\n          // We've determined that A is the current branch.\n          assertIsMounted(parentA);\n          return fiber;\n        }\n\n        if (child === b) {\n          // We've determined that B is the current branch.\n          assertIsMounted(parentA);\n          return alternate;\n        }\n\n        child = child.sibling;\n      } // We should never have an alternate for any mounting node. So the only\n      // way this could possibly happen is if this was unmounted, if at all.\n\n\n      {\n        {\n          throw Error( \"Unable to find node on an unmounted component.\" );\n        }\n      }\n    }\n\n    if (a.return !== b.return) {\n      // The return pointer of A and the return pointer of B point to different\n      // fibers. We assume that return pointers never criss-cross, so A must\n      // belong to the child set of A.return, and B must belong to the child\n      // set of B.return.\n      a = parentA;\n      b = parentB;\n    } else {\n      // The return pointers point to the same fiber. We'll have to use the\n      // default, slow path: scan the child sets of each parent alternate to see\n      // which child belongs to which set.\n      //\n      // Search parent A's child set\n      var didFindChild = false;\n      var _child = parentA.child;\n\n      while (_child) {\n        if (_child === a) {\n          didFindChild = true;\n          a = parentA;\n          b = parentB;\n          break;\n        }\n\n        if (_child === b) {\n          didFindChild = true;\n          b = parentA;\n          a = parentB;\n          break;\n        }\n\n        _child = _child.sibling;\n      }\n\n      if (!didFindChild) {\n        // Search parent B's child set\n        _child = parentB.child;\n\n        while (_child) {\n          if (_child === a) {\n            didFindChild = true;\n            a = parentB;\n            b = parentA;\n            break;\n          }\n\n          if (_child === b) {\n            didFindChild = true;\n            b = parentB;\n            a = parentA;\n            break;\n          }\n\n          _child = _child.sibling;\n        }\n\n        if (!didFindChild) {\n          {\n            throw Error( \"Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.\" );\n          }\n        }\n      }\n    }\n\n    if (!(a.alternate === b)) {\n      {\n        throw Error( \"Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n  } // If the root is not a host container, we're in a disconnected tree. I.e.\n  // unmounted.\n\n\n  if (!(a.tag === HostRoot)) {\n    {\n      throw Error( \"Unable to find node on an unmounted component.\" );\n    }\n  }\n\n  if (a.stateNode.current === a) {\n    // We've determined that A is the current branch.\n    return fiber;\n  } // Otherwise B has to be current branch.\n\n\n  return alternate;\n}\nfunction findCurrentHostFiber(parent) {\n  var currentParent = findCurrentFiberUsingSlowPath(parent);\n\n  if (!currentParent) {\n    return null;\n  } // Next we'll drill down this component to find the first HostComponent/Text.\n\n\n  var node = currentParent;\n\n  while (true) {\n    if (node.tag === HostComponent || node.tag === HostText) {\n      return node;\n    } else if (node.child) {\n      node.child.return = node;\n      node = node.child;\n      continue;\n    }\n\n    if (node === currentParent) {\n      return null;\n    }\n\n    while (!node.sibling) {\n      if (!node.return || node.return === currentParent) {\n        return null;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  } // Flow needs the return null here, but ESLint complains about it.\n  // eslint-disable-next-line no-unreachable\n\n\n  return null;\n}\nfunction findCurrentHostFiberWithNoPortals(parent) {\n  var currentParent = findCurrentFiberUsingSlowPath(parent);\n\n  if (!currentParent) {\n    return null;\n  } // Next we'll drill down this component to find the first HostComponent/Text.\n\n\n  var node = currentParent;\n\n  while (true) {\n    if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {\n      return node;\n    } else if (node.child && node.tag !== HostPortal) {\n      node.child.return = node;\n      node = node.child;\n      continue;\n    }\n\n    if (node === currentParent) {\n      return null;\n    }\n\n    while (!node.sibling) {\n      if (!node.return || node.return === currentParent) {\n        return null;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  } // Flow needs the return null here, but ESLint complains about it.\n  // eslint-disable-next-line no-unreachable\n\n\n  return null;\n}\n\n/**\n * Accumulates items that must not be null or undefined into the first one. This\n * is used to conserve memory by avoiding array allocations, and thus sacrifices\n * API cleanness. Since `current` can be null before being passed in and not\n * null after this function, make sure to assign it back to `current`:\n *\n * `a = accumulateInto(a, b);`\n *\n * This API should be sparingly used. Try `accumulate` for something cleaner.\n *\n * @return {*|array<*>} An accumulation of items.\n */\n\nfunction accumulateInto(current, next) {\n  if (!(next != null)) {\n    {\n      throw Error( \"accumulateInto(...): Accumulated items must not be null or undefined.\" );\n    }\n  }\n\n  if (current == null) {\n    return next;\n  } // Both are not empty. Warning: Never call x.concat(y) when you are not\n  // certain that x is an Array (x could be a string with concat method).\n\n\n  if (Array.isArray(current)) {\n    if (Array.isArray(next)) {\n      current.push.apply(current, next);\n      return current;\n    }\n\n    current.push(next);\n    return current;\n  }\n\n  if (Array.isArray(next)) {\n    // A bit too dangerous to mutate `next`.\n    return [current].concat(next);\n  }\n\n  return [current, next];\n}\n\n/**\n * @param {array} arr an \"accumulation\" of items which is either an Array or\n * a single item. Useful when paired with the `accumulate` module. This is a\n * simple utility that allows us to reason about a collection of items, but\n * handling the case when there is exactly one item (and we do not need to\n * allocate an array).\n * @param {function} cb Callback invoked with each element or a collection.\n * @param {?} [scope] Scope used as `this` in a callback.\n */\nfunction forEachAccumulated(arr, cb, scope) {\n  if (Array.isArray(arr)) {\n    arr.forEach(cb, scope);\n  } else if (arr) {\n    cb.call(scope, arr);\n  }\n}\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\n\nvar eventQueue = null;\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @private\n */\n\nvar executeDispatchesAndRelease = function (event) {\n  if (event) {\n    executeDispatchesInOrder(event);\n\n    if (!event.isPersistent()) {\n      event.constructor.release(event);\n    }\n  }\n};\n\nvar executeDispatchesAndReleaseTopLevel = function (e) {\n  return executeDispatchesAndRelease(e);\n};\n\nfunction runEventsInBatch(events) {\n  if (events !== null) {\n    eventQueue = accumulateInto(eventQueue, events);\n  } // Set `eventQueue` to null before processing it so that we can tell if more\n  // events get enqueued while processing.\n\n\n  var processingEventQueue = eventQueue;\n  eventQueue = null;\n\n  if (!processingEventQueue) {\n    return;\n  }\n\n  forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);\n\n  if (!!eventQueue) {\n    {\n      throw Error( \"processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.\" );\n    }\n  } // This would be a good time to rethrow if any of the event handlers threw.\n\n\n  rethrowCaughtError();\n}\n\n/**\n * Gets the target node from a native browser event by accounting for\n * inconsistencies in browser DOM APIs.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {DOMEventTarget} Target node.\n */\n\nfunction getEventTarget(nativeEvent) {\n  // Fallback to nativeEvent.srcElement for IE9\n  // https://github.com/facebook/react/issues/12506\n  var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963\n\n  if (target.correspondingUseElement) {\n    target = target.correspondingUseElement;\n  } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).\n  // @see http://www.quirksmode.org/js/events_properties.html\n\n\n  return target.nodeType === TEXT_NODE ? target.parentNode : target;\n}\n\n/**\n * Checks if an event is supported in the current execution environment.\n *\n * NOTE: This will not work correctly for non-generic events such as `change`,\n * `reset`, `load`, `error`, and `select`.\n *\n * Borrows from Modernizr.\n *\n * @param {string} eventNameSuffix Event name, e.g. \"click\".\n * @return {boolean} True if the event is supported.\n * @internal\n * @license Modernizr 3.0.0pre (Custom Build) | MIT\n */\n\nfunction isEventSupported(eventNameSuffix) {\n  if (!canUseDOM) {\n    return false;\n  }\n\n  var eventName = 'on' + eventNameSuffix;\n  var isSupported = eventName in document;\n\n  if (!isSupported) {\n    var element = document.createElement('div');\n    element.setAttribute(eventName, 'return;');\n    isSupported = typeof element[eventName] === 'function';\n  }\n\n  return isSupported;\n}\n\n/**\n * Summary of `DOMEventPluginSystem` event handling:\n *\n *  - Top-level delegation is used to trap most native browser events. This\n *    may only occur in the main thread and is the responsibility of\n *    ReactDOMEventListener, which is injected and can therefore support\n *    pluggable event sources. This is the only work that occurs in the main\n *    thread.\n *\n *  - We normalize and de-duplicate events to account for browser quirks. This\n *    may be done in the worker thread.\n *\n *  - Forward these native events (with the associated top-level type used to\n *    trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want\n *    to extract any synthetic events.\n *\n *  - The `EventPluginRegistry` will then process each event by annotating them with\n *    \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n *  - The `EventPluginRegistry` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * +------------+    .\n * |    DOM     |    .\n * +------------+    .\n *       |           .\n *       v           .\n * +------------+    .\n * | ReactEvent |    .\n * |  Listener  |    .\n * +------------+    .                         +-----------+\n *       |           .               +--------+|SimpleEvent|\n *       |           .               |         |Plugin     |\n * +-----|------+    .               v         +-----------+\n * |     |      |    .    +--------------+                    +------------+\n * |     +-----------.--->|PluginRegistry|                    |    Event   |\n * |            |    .    |              |     +-----------+  | Propagators|\n * | ReactEvent |    .    |              |     |TapEvent   |  |------------|\n * |  Emitter   |    .    |              |<---+|Plugin     |  |other plugin|\n * |            |    .    |              |     +-----------+  |  utilities |\n * |     +-----------.--->|              |                    +------------+\n * |     |      |    .    +--------------+\n * +-----|------+    .                ^        +-----------+\n *       |           .                |        |Enter/Leave|\n *       +           .                +-------+|Plugin     |\n * +-------------+   .                         +-----------+\n * | application |   .\n * |-------------|   .\n * |             |   .\n * |             |   .\n * +-------------+   .\n *                   .\n *    React Core     .  General Purpose Event Plugin System\n */\n\nvar CALLBACK_BOOKKEEPING_POOL_SIZE = 10;\nvar callbackBookkeepingPool = [];\n\nfunction releaseTopLevelCallbackBookKeeping(instance) {\n  instance.topLevelType = null;\n  instance.nativeEvent = null;\n  instance.targetInst = null;\n  instance.ancestors.length = 0;\n\n  if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {\n    callbackBookkeepingPool.push(instance);\n  }\n} // Used to store ancestor hierarchy in top level callback\n\n\nfunction getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags) {\n  if (callbackBookkeepingPool.length) {\n    var instance = callbackBookkeepingPool.pop();\n    instance.topLevelType = topLevelType;\n    instance.eventSystemFlags = eventSystemFlags;\n    instance.nativeEvent = nativeEvent;\n    instance.targetInst = targetInst;\n    return instance;\n  }\n\n  return {\n    topLevelType: topLevelType,\n    eventSystemFlags: eventSystemFlags,\n    nativeEvent: nativeEvent,\n    targetInst: targetInst,\n    ancestors: []\n  };\n}\n/**\n * Find the deepest React component completely containing the root of the\n * passed-in instance (for use when entire React trees are nested within each\n * other). If React trees are not nested, returns null.\n */\n\n\nfunction findRootContainerNode(inst) {\n  if (inst.tag === HostRoot) {\n    return inst.stateNode.containerInfo;\n  } // TODO: It may be a good idea to cache this to prevent unnecessary DOM\n  // traversal, but caching is difficult to do correctly without using a\n  // mutation observer to listen for all DOM changes.\n\n\n  while (inst.return) {\n    inst = inst.return;\n  }\n\n  if (inst.tag !== HostRoot) {\n    // This can happen if we're in a detached tree.\n    return null;\n  }\n\n  return inst.stateNode.containerInfo;\n}\n/**\n * Allows registered plugins an opportunity to extract events from top-level\n * native browser events.\n *\n * @return {*} An accumulation of synthetic events.\n * @internal\n */\n\n\nfunction extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n  var events = null;\n\n  for (var i = 0; i < plugins.length; i++) {\n    // Not every plugin in the ordering may be loaded at runtime.\n    var possiblePlugin = plugins[i];\n\n    if (possiblePlugin) {\n      var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);\n\n      if (extractedEvents) {\n        events = accumulateInto(events, extractedEvents);\n      }\n    }\n  }\n\n  return events;\n}\n\nfunction runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n  var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);\n  runEventsInBatch(events);\n}\n\nfunction handleTopLevel(bookKeeping) {\n  var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components.\n  // It's important that we build the array of ancestors before calling any\n  // event handlers, because event handlers can modify the DOM, leading to\n  // inconsistencies with ReactMount's node cache. See #1105.\n\n  var ancestor = targetInst;\n\n  do {\n    if (!ancestor) {\n      var ancestors = bookKeeping.ancestors;\n      ancestors.push(ancestor);\n      break;\n    }\n\n    var root = findRootContainerNode(ancestor);\n\n    if (!root) {\n      break;\n    }\n\n    var tag = ancestor.tag;\n\n    if (tag === HostComponent || tag === HostText) {\n      bookKeeping.ancestors.push(ancestor);\n    }\n\n    ancestor = getClosestInstanceFromNode(root);\n  } while (ancestor);\n\n  for (var i = 0; i < bookKeeping.ancestors.length; i++) {\n    targetInst = bookKeeping.ancestors[i];\n    var eventTarget = getEventTarget(bookKeeping.nativeEvent);\n    var topLevelType = bookKeeping.topLevelType;\n    var nativeEvent = bookKeeping.nativeEvent;\n    var eventSystemFlags = bookKeeping.eventSystemFlags; // If this is the first ancestor, we mark it on the system flags\n\n    if (i === 0) {\n      eventSystemFlags |= IS_FIRST_ANCESTOR;\n    }\n\n    runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, eventTarget, eventSystemFlags);\n  }\n}\n\nfunction dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {\n  var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags);\n\n  try {\n    // Event queue being processed in the same cycle allows\n    // `preventDefault`.\n    batchedEventUpdates(handleTopLevel, bookKeeping);\n  } finally {\n    releaseTopLevelCallbackBookKeeping(bookKeeping);\n  }\n}\n/**\n * We listen for bubbled touch events on the document object.\n *\n * Firefox v8.01 (and possibly others) exhibited strange behavior when\n * mounting `onmousemove` events at some node that was not the document\n * element. The symptoms were that if your mouse is not moving over something\n * contained within that mount point (for example on the background) the\n * top-level listeners for `onmousemove` won't be called. However, if you\n * register the `mousemove` on the document object, then it will of course\n * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n * top-level listeners to the document object only, at least for these\n * movement types of events and possibly all events.\n *\n * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n *\n * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n * they bubble to document.\n *\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @param {object} mountAt Container where to mount the listener\n */\n\nfunction legacyListenToEvent(registrationName, mountAt) {\n  var listenerMap = getListenerMapForElement(mountAt);\n  var dependencies = registrationNameDependencies[registrationName];\n\n  for (var i = 0; i < dependencies.length; i++) {\n    var dependency = dependencies[i];\n    legacyListenToTopLevelEvent(dependency, mountAt, listenerMap);\n  }\n}\nfunction legacyListenToTopLevelEvent(topLevelType, mountAt, listenerMap) {\n  if (!listenerMap.has(topLevelType)) {\n    switch (topLevelType) {\n      case TOP_SCROLL:\n        trapCapturedEvent(TOP_SCROLL, mountAt);\n        break;\n\n      case TOP_FOCUS:\n      case TOP_BLUR:\n        trapCapturedEvent(TOP_FOCUS, mountAt);\n        trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,\n        // but this ensures we mark both as attached rather than just one.\n\n        listenerMap.set(TOP_BLUR, null);\n        listenerMap.set(TOP_FOCUS, null);\n        break;\n\n      case TOP_CANCEL:\n      case TOP_CLOSE:\n        if (isEventSupported(getRawEventName(topLevelType))) {\n          trapCapturedEvent(topLevelType, mountAt);\n        }\n\n        break;\n\n      case TOP_INVALID:\n      case TOP_SUBMIT:\n      case TOP_RESET:\n        // We listen to them on the target DOM elements.\n        // Some of them bubble so we don't want them to fire twice.\n        break;\n\n      default:\n        // By default, listen on the top level to all non-media events.\n        // Media events don't bubble so adding the listener wouldn't do anything.\n        var isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;\n\n        if (!isMediaEvent) {\n          trapBubbledEvent(topLevelType, mountAt);\n        }\n\n        break;\n    }\n\n    listenerMap.set(topLevelType, null);\n  }\n}\nfunction isListeningToAllDependencies(registrationName, mountAt) {\n  var listenerMap = getListenerMapForElement(mountAt);\n  var dependencies = registrationNameDependencies[registrationName];\n\n  for (var i = 0; i < dependencies.length; i++) {\n    var dependency = dependencies[i];\n\n    if (!listenerMap.has(dependency)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nvar attemptUserBlockingHydration;\nfunction setAttemptUserBlockingHydration(fn) {\n  attemptUserBlockingHydration = fn;\n}\nvar attemptContinuousHydration;\nfunction setAttemptContinuousHydration(fn) {\n  attemptContinuousHydration = fn;\n}\nvar attemptHydrationAtCurrentPriority;\nfunction setAttemptHydrationAtCurrentPriority(fn) {\n  attemptHydrationAtCurrentPriority = fn;\n} // TODO: Upgrade this definition once we're on a newer version of Flow that\nvar hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.\n\nvar queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.\n// if the last target was dehydrated.\n\nvar queuedFocus = null;\nvar queuedDrag = null;\nvar queuedMouse = null; // For pointer events there can be one latest event per pointerId.\n\nvar queuedPointers = new Map();\nvar queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.\n\nvar queuedExplicitHydrationTargets = [];\nfunction hasQueuedDiscreteEvents() {\n  return queuedDiscreteEvents.length > 0;\n}\nvar discreteReplayableEvents = [TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_TOUCH_START, TOP_AUX_CLICK, TOP_DOUBLE_CLICK, TOP_POINTER_CANCEL, TOP_POINTER_DOWN, TOP_POINTER_UP, TOP_DRAG_END, TOP_DRAG_START, TOP_DROP, TOP_COMPOSITION_END, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_INPUT, TOP_TEXT_INPUT, TOP_CLOSE, TOP_CANCEL, TOP_COPY, TOP_CUT, TOP_PASTE, TOP_CLICK, TOP_CHANGE, TOP_CONTEXT_MENU, TOP_RESET, TOP_SUBMIT];\nvar continuousReplayableEvents = [TOP_FOCUS, TOP_BLUR, TOP_DRAG_ENTER, TOP_DRAG_LEAVE, TOP_MOUSE_OVER, TOP_MOUSE_OUT, TOP_POINTER_OVER, TOP_POINTER_OUT, TOP_GOT_POINTER_CAPTURE, TOP_LOST_POINTER_CAPTURE];\nfunction isReplayableDiscreteEvent(eventType) {\n  return discreteReplayableEvents.indexOf(eventType) > -1;\n}\n\nfunction trapReplayableEventForDocument(topLevelType, document, listenerMap) {\n  legacyListenToTopLevelEvent(topLevelType, document, listenerMap);\n}\n\nfunction eagerlyTrapReplayableEvents(container, document) {\n  var listenerMapForDoc = getListenerMapForElement(document); // Discrete\n\n  discreteReplayableEvents.forEach(function (topLevelType) {\n    trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);\n  }); // Continuous\n\n  continuousReplayableEvents.forEach(function (topLevelType) {\n    trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);\n  });\n}\n\nfunction createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {\n  return {\n    blockedOn: blockedOn,\n    topLevelType: topLevelType,\n    eventSystemFlags: eventSystemFlags | IS_REPLAYED,\n    nativeEvent: nativeEvent,\n    container: container\n  };\n}\n\nfunction queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {\n  var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);\n  queuedDiscreteEvents.push(queuedEvent);\n} // Resets the replaying for this type of continuous event to no event.\n\nfunction clearIfContinuousEvent(topLevelType, nativeEvent) {\n  switch (topLevelType) {\n    case TOP_FOCUS:\n    case TOP_BLUR:\n      queuedFocus = null;\n      break;\n\n    case TOP_DRAG_ENTER:\n    case TOP_DRAG_LEAVE:\n      queuedDrag = null;\n      break;\n\n    case TOP_MOUSE_OVER:\n    case TOP_MOUSE_OUT:\n      queuedMouse = null;\n      break;\n\n    case TOP_POINTER_OVER:\n    case TOP_POINTER_OUT:\n      {\n        var pointerId = nativeEvent.pointerId;\n        queuedPointers.delete(pointerId);\n        break;\n      }\n\n    case TOP_GOT_POINTER_CAPTURE:\n    case TOP_LOST_POINTER_CAPTURE:\n      {\n        var _pointerId = nativeEvent.pointerId;\n        queuedPointerCaptures.delete(_pointerId);\n        break;\n      }\n  }\n}\n\nfunction accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {\n  if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {\n    var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);\n\n    if (blockedOn !== null) {\n      var _fiber2 = getInstanceFromNode$1(blockedOn);\n\n      if (_fiber2 !== null) {\n        // Attempt to increase the priority of this target.\n        attemptContinuousHydration(_fiber2);\n      }\n    }\n\n    return queuedEvent;\n  } // If we have already queued this exact event, then it's because\n  // the different event systems have different DOM event listeners.\n  // We can accumulate the flags and store a single event to be\n  // replayed.\n\n\n  existingQueuedEvent.eventSystemFlags |= eventSystemFlags;\n  return existingQueuedEvent;\n}\n\nfunction queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {\n  // These set relatedTarget to null because the replayed event will be treated as if we\n  // moved from outside the window (no target) onto the target once it hydrates.\n  // Instead of mutating we could clone the event.\n  switch (topLevelType) {\n    case TOP_FOCUS:\n      {\n        var focusEvent = nativeEvent;\n        queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, topLevelType, eventSystemFlags, container, focusEvent);\n        return true;\n      }\n\n    case TOP_DRAG_ENTER:\n      {\n        var dragEvent = nativeEvent;\n        queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, topLevelType, eventSystemFlags, container, dragEvent);\n        return true;\n      }\n\n    case TOP_MOUSE_OVER:\n      {\n        var mouseEvent = nativeEvent;\n        queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, topLevelType, eventSystemFlags, container, mouseEvent);\n        return true;\n      }\n\n    case TOP_POINTER_OVER:\n      {\n        var pointerEvent = nativeEvent;\n        var pointerId = pointerEvent.pointerId;\n        queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, topLevelType, eventSystemFlags, container, pointerEvent));\n        return true;\n      }\n\n    case TOP_GOT_POINTER_CAPTURE:\n      {\n        var _pointerEvent = nativeEvent;\n        var _pointerId2 = _pointerEvent.pointerId;\n        queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, topLevelType, eventSystemFlags, container, _pointerEvent));\n        return true;\n      }\n  }\n\n  return false;\n} // Check if this target is unblocked. Returns true if it's unblocked.\n\nfunction attemptExplicitHydrationTarget(queuedTarget) {\n  // TODO: This function shares a lot of logic with attemptToDispatchEvent.\n  // Try to unify them. It's a bit tricky since it would require two return\n  // values.\n  var targetInst = getClosestInstanceFromNode(queuedTarget.target);\n\n  if (targetInst !== null) {\n    var nearestMounted = getNearestMountedFiber(targetInst);\n\n    if (nearestMounted !== null) {\n      var tag = nearestMounted.tag;\n\n      if (tag === SuspenseComponent) {\n        var instance = getSuspenseInstanceFromFiber(nearestMounted);\n\n        if (instance !== null) {\n          // We're blocked on hydrating this boundary.\n          // Increase its priority.\n          queuedTarget.blockedOn = instance;\n          Scheduler.unstable_runWithPriority(queuedTarget.priority, function () {\n            attemptHydrationAtCurrentPriority(nearestMounted);\n          });\n          return;\n        }\n      } else if (tag === HostRoot) {\n        var root = nearestMounted.stateNode;\n\n        if (root.hydrate) {\n          queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of\n          // a root other than sync.\n\n          return;\n        }\n      }\n    }\n  }\n\n  queuedTarget.blockedOn = null;\n}\n\nfunction attemptReplayContinuousQueuedEvent(queuedEvent) {\n  if (queuedEvent.blockedOn !== null) {\n    return false;\n  }\n\n  var nextBlockedOn = attemptToDispatchEvent(queuedEvent.topLevelType, queuedEvent.eventSystemFlags, queuedEvent.container, queuedEvent.nativeEvent);\n\n  if (nextBlockedOn !== null) {\n    // We're still blocked. Try again later.\n    var _fiber3 = getInstanceFromNode$1(nextBlockedOn);\n\n    if (_fiber3 !== null) {\n      attemptContinuousHydration(_fiber3);\n    }\n\n    queuedEvent.blockedOn = nextBlockedOn;\n    return false;\n  }\n\n  return true;\n}\n\nfunction attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {\n  if (attemptReplayContinuousQueuedEvent(queuedEvent)) {\n    map.delete(key);\n  }\n}\n\nfunction replayUnblockedEvents() {\n  hasScheduledReplayAttempt = false; // First replay discrete events.\n\n  while (queuedDiscreteEvents.length > 0) {\n    var nextDiscreteEvent = queuedDiscreteEvents[0];\n\n    if (nextDiscreteEvent.blockedOn !== null) {\n      // We're still blocked.\n      // Increase the priority of this boundary to unblock\n      // the next discrete event.\n      var _fiber4 = getInstanceFromNode$1(nextDiscreteEvent.blockedOn);\n\n      if (_fiber4 !== null) {\n        attemptUserBlockingHydration(_fiber4);\n      }\n\n      break;\n    }\n\n    var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, nextDiscreteEvent.container, nextDiscreteEvent.nativeEvent);\n\n    if (nextBlockedOn !== null) {\n      // We're still blocked. Try again later.\n      nextDiscreteEvent.blockedOn = nextBlockedOn;\n    } else {\n      // We've successfully replayed the first event. Let's try the next one.\n      queuedDiscreteEvents.shift();\n    }\n  } // Next replay any continuous events.\n\n\n  if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {\n    queuedFocus = null;\n  }\n\n  if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {\n    queuedDrag = null;\n  }\n\n  if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {\n    queuedMouse = null;\n  }\n\n  queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);\n  queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);\n}\n\nfunction scheduleCallbackIfUnblocked(queuedEvent, unblocked) {\n  if (queuedEvent.blockedOn === unblocked) {\n    queuedEvent.blockedOn = null;\n\n    if (!hasScheduledReplayAttempt) {\n      hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are\n      // now unblocked. This first might not actually be unblocked yet.\n      // We could check it early to avoid scheduling an unnecessary callback.\n\n      Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);\n    }\n  }\n}\n\nfunction retryIfBlockedOn(unblocked) {\n  // Mark anything that was blocked on this as no longer blocked\n  // and eligible for a replay.\n  if (queuedDiscreteEvents.length > 0) {\n    scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's\n    // worth it because we expect very few discrete events to queue up and once\n    // we are actually fully unblocked it will be fast to replay them.\n\n    for (var i = 1; i < queuedDiscreteEvents.length; i++) {\n      var queuedEvent = queuedDiscreteEvents[i];\n\n      if (queuedEvent.blockedOn === unblocked) {\n        queuedEvent.blockedOn = null;\n      }\n    }\n  }\n\n  if (queuedFocus !== null) {\n    scheduleCallbackIfUnblocked(queuedFocus, unblocked);\n  }\n\n  if (queuedDrag !== null) {\n    scheduleCallbackIfUnblocked(queuedDrag, unblocked);\n  }\n\n  if (queuedMouse !== null) {\n    scheduleCallbackIfUnblocked(queuedMouse, unblocked);\n  }\n\n  var unblock = function (queuedEvent) {\n    return scheduleCallbackIfUnblocked(queuedEvent, unblocked);\n  };\n\n  queuedPointers.forEach(unblock);\n  queuedPointerCaptures.forEach(unblock);\n\n  for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {\n    var queuedTarget = queuedExplicitHydrationTargets[_i];\n\n    if (queuedTarget.blockedOn === unblocked) {\n      queuedTarget.blockedOn = null;\n    }\n  }\n\n  while (queuedExplicitHydrationTargets.length > 0) {\n    var nextExplicitTarget = queuedExplicitHydrationTargets[0];\n\n    if (nextExplicitTarget.blockedOn !== null) {\n      // We're still blocked.\n      break;\n    } else {\n      attemptExplicitHydrationTarget(nextExplicitTarget);\n\n      if (nextExplicitTarget.blockedOn === null) {\n        // We're unblocked.\n        queuedExplicitHydrationTargets.shift();\n      }\n    }\n  }\n}\n\nfunction addEventBubbleListener(element, eventType, listener) {\n  element.addEventListener(eventType, listener, false);\n}\nfunction addEventCaptureListener(element, eventType, listener) {\n  element.addEventListener(eventType, listener, true);\n}\n\n// do it in two places, which duplicates logic\n// and increases the bundle size, we do it all\n// here once. If we remove or refactor the\n// SimpleEventPlugin, we should also remove or\n// update the below line.\n\nvar simpleEventPluginEventTypes = {};\nvar topLevelEventsToDispatchConfig = new Map();\nvar eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use\n// the code required to apply the same logic for event prioritization and that of the\n// SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code\n// duplication (for which there would be quite a bit). For the events that are not needed\n// for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an\n// array of top level events.\n// Lastly, we ignore prettier so we can keep the formatting sane.\n// prettier-ignore\n\nvar discreteEventPairsForSimpleEventPlugin = [TOP_BLUR, 'blur', TOP_CANCEL, 'cancel', TOP_CLICK, 'click', TOP_CLOSE, 'close', TOP_CONTEXT_MENU, 'contextMenu', TOP_COPY, 'copy', TOP_CUT, 'cut', TOP_AUX_CLICK, 'auxClick', TOP_DOUBLE_CLICK, 'doubleClick', TOP_DRAG_END, 'dragEnd', TOP_DRAG_START, 'dragStart', TOP_DROP, 'drop', TOP_FOCUS, 'focus', TOP_INPUT, 'input', TOP_INVALID, 'invalid', TOP_KEY_DOWN, 'keyDown', TOP_KEY_PRESS, 'keyPress', TOP_KEY_UP, 'keyUp', TOP_MOUSE_DOWN, 'mouseDown', TOP_MOUSE_UP, 'mouseUp', TOP_PASTE, 'paste', TOP_PAUSE, 'pause', TOP_PLAY, 'play', TOP_POINTER_CANCEL, 'pointerCancel', TOP_POINTER_DOWN, 'pointerDown', TOP_POINTER_UP, 'pointerUp', TOP_RATE_CHANGE, 'rateChange', TOP_RESET, 'reset', TOP_SEEKED, 'seeked', TOP_SUBMIT, 'submit', TOP_TOUCH_CANCEL, 'touchCancel', TOP_TOUCH_END, 'touchEnd', TOP_TOUCH_START, 'touchStart', TOP_VOLUME_CHANGE, 'volumeChange'];\nvar otherDiscreteEvents = [TOP_CHANGE, TOP_SELECTION_CHANGE, TOP_TEXT_INPUT, TOP_COMPOSITION_START, TOP_COMPOSITION_END, TOP_COMPOSITION_UPDATE]; // prettier-ignore\n\nvar userBlockingPairsForSimpleEventPlugin = [TOP_DRAG, 'drag', TOP_DRAG_ENTER, 'dragEnter', TOP_DRAG_EXIT, 'dragExit', TOP_DRAG_LEAVE, 'dragLeave', TOP_DRAG_OVER, 'dragOver', TOP_MOUSE_MOVE, 'mouseMove', TOP_MOUSE_OUT, 'mouseOut', TOP_MOUSE_OVER, 'mouseOver', TOP_POINTER_MOVE, 'pointerMove', TOP_POINTER_OUT, 'pointerOut', TOP_POINTER_OVER, 'pointerOver', TOP_SCROLL, 'scroll', TOP_TOGGLE, 'toggle', TOP_TOUCH_MOVE, 'touchMove', TOP_WHEEL, 'wheel']; // prettier-ignore\n\nvar continuousPairsForSimpleEventPlugin = [TOP_ABORT, 'abort', TOP_ANIMATION_END, 'animationEnd', TOP_ANIMATION_ITERATION, 'animationIteration', TOP_ANIMATION_START, 'animationStart', TOP_CAN_PLAY, 'canPlay', TOP_CAN_PLAY_THROUGH, 'canPlayThrough', TOP_DURATION_CHANGE, 'durationChange', TOP_EMPTIED, 'emptied', TOP_ENCRYPTED, 'encrypted', TOP_ENDED, 'ended', TOP_ERROR, 'error', TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', TOP_LOAD, 'load', TOP_LOADED_DATA, 'loadedData', TOP_LOADED_METADATA, 'loadedMetadata', TOP_LOAD_START, 'loadStart', TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', TOP_PLAYING, 'playing', TOP_PROGRESS, 'progress', TOP_SEEKING, 'seeking', TOP_STALLED, 'stalled', TOP_SUSPEND, 'suspend', TOP_TIME_UPDATE, 'timeUpdate', TOP_TRANSITION_END, 'transitionEnd', TOP_WAITING, 'waiting'];\n/**\n * Turns\n * ['abort', ...]\n * into\n * eventTypes = {\n *   'abort': {\n *     phasedRegistrationNames: {\n *       bubbled: 'onAbort',\n *       captured: 'onAbortCapture',\n *     },\n *     dependencies: [TOP_ABORT],\n *   },\n *   ...\n * };\n * topLevelEventsToDispatchConfig = new Map([\n *   [TOP_ABORT, { sameConfig }],\n * ]);\n */\n\nfunction processSimpleEventPluginPairsByPriority(eventTypes, priority) {\n  // As the event types are in pairs of two, we need to iterate\n  // through in twos. The events are in pairs of two to save code\n  // and improve init perf of processing this array, as it will\n  // result in far fewer object allocations and property accesses\n  // if we only use three arrays to process all the categories of\n  // instead of tuples.\n  for (var i = 0; i < eventTypes.length; i += 2) {\n    var topEvent = eventTypes[i];\n    var event = eventTypes[i + 1];\n    var capitalizedEvent = event[0].toUpperCase() + event.slice(1);\n    var onEvent = 'on' + capitalizedEvent;\n    var config = {\n      phasedRegistrationNames: {\n        bubbled: onEvent,\n        captured: onEvent + 'Capture'\n      },\n      dependencies: [topEvent],\n      eventPriority: priority\n    };\n    eventPriorities.set(topEvent, priority);\n    topLevelEventsToDispatchConfig.set(topEvent, config);\n    simpleEventPluginEventTypes[event] = config;\n  }\n}\n\nfunction processTopEventPairsByPriority(eventTypes, priority) {\n  for (var i = 0; i < eventTypes.length; i++) {\n    eventPriorities.set(eventTypes[i], priority);\n  }\n} // SimpleEventPlugin\n\n\nprocessSimpleEventPluginPairsByPriority(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);\nprocessSimpleEventPluginPairsByPriority(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);\nprocessSimpleEventPluginPairsByPriority(continuousPairsForSimpleEventPlugin, ContinuousEvent); // Not used by SimpleEventPlugin\n\nprocessTopEventPairsByPriority(otherDiscreteEvents, DiscreteEvent);\nfunction getEventPriorityForPluginSystem(topLevelType) {\n  var priority = eventPriorities.get(topLevelType); // Default to a ContinuousEvent. Note: we might\n  // want to warn if we can't detect the priority\n  // for the event.\n\n  return priority === undefined ? ContinuousEvent : priority;\n}\n\n// Intentionally not named imports because Rollup would use dynamic dispatch for\nvar UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,\n    runWithPriority = Scheduler.unstable_runWithPriority; // TODO: can we stop exporting these?\n\nvar _enabled = true;\nfunction setEnabled(enabled) {\n  _enabled = !!enabled;\n}\nfunction isEnabled() {\n  return _enabled;\n}\nfunction trapBubbledEvent(topLevelType, element) {\n  trapEventForPluginEventSystem(element, topLevelType, false);\n}\nfunction trapCapturedEvent(topLevelType, element) {\n  trapEventForPluginEventSystem(element, topLevelType, true);\n}\n\nfunction trapEventForPluginEventSystem(container, topLevelType, capture) {\n  var listener;\n\n  switch (getEventPriorityForPluginSystem(topLevelType)) {\n    case DiscreteEvent:\n      listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);\n      break;\n\n    case UserBlockingEvent:\n      listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);\n      break;\n\n    case ContinuousEvent:\n    default:\n      listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);\n      break;\n  }\n\n  var rawEventName = getRawEventName(topLevelType);\n\n  if (capture) {\n    addEventCaptureListener(container, rawEventName, listener);\n  } else {\n    addEventBubbleListener(container, rawEventName, listener);\n  }\n}\n\nfunction dispatchDiscreteEvent(topLevelType, eventSystemFlags, container, nativeEvent) {\n  flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);\n  discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, container, nativeEvent);\n}\n\nfunction dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, container, nativeEvent) {\n  runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, container, nativeEvent));\n}\n\nfunction dispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {\n  if (!_enabled) {\n    return;\n  }\n\n  if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {\n    // If we already have a queue of discrete events, and this is another discrete\n    // event, then we can't dispatch it regardless of its target, since they\n    // need to dispatch in order.\n    queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.\n    topLevelType, eventSystemFlags, container, nativeEvent);\n    return;\n  }\n\n  var blockedOn = attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent);\n\n  if (blockedOn === null) {\n    // We successfully dispatched this event.\n    clearIfContinuousEvent(topLevelType, nativeEvent);\n    return;\n  }\n\n  if (isReplayableDiscreteEvent(topLevelType)) {\n    // This this to be replayed later once the target is available.\n    queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);\n    return;\n  }\n\n  if (queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent)) {\n    return;\n  } // We need to clear only if we didn't queue because\n  // queueing is accummulative.\n\n\n  clearIfContinuousEvent(topLevelType, nativeEvent); // This is not replayable so we'll invoke it but without a target,\n  // in case the event system needs to trace it.\n\n  {\n    dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);\n  }\n} // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.\n\nfunction attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {\n  // TODO: Warn if _enabled is false.\n  var nativeEventTarget = getEventTarget(nativeEvent);\n  var targetInst = getClosestInstanceFromNode(nativeEventTarget);\n\n  if (targetInst !== null) {\n    var nearestMounted = getNearestMountedFiber(targetInst);\n\n    if (nearestMounted === null) {\n      // This tree has been unmounted already. Dispatch without a target.\n      targetInst = null;\n    } else {\n      var tag = nearestMounted.tag;\n\n      if (tag === SuspenseComponent) {\n        var instance = getSuspenseInstanceFromFiber(nearestMounted);\n\n        if (instance !== null) {\n          // Queue the event to be replayed later. Abort dispatching since we\n          // don't want this event dispatched twice through the event system.\n          // TODO: If this is the first discrete event in the queue. Schedule an increased\n          // priority for this boundary.\n          return instance;\n        } // This shouldn't happen, something went wrong but to avoid blocking\n        // the whole system, dispatch the event without a target.\n        // TODO: Warn.\n\n\n        targetInst = null;\n      } else if (tag === HostRoot) {\n        var root = nearestMounted.stateNode;\n\n        if (root.hydrate) {\n          // If this happens during a replay something went wrong and it might block\n          // the whole system.\n          return getContainerFromFiber(nearestMounted);\n        }\n\n        targetInst = null;\n      } else if (nearestMounted !== targetInst) {\n        // If we get an event (ex: img onload) before committing that\n        // component's mount, ignore it for now (that is, treat it as if it was an\n        // event on a non-React tree). We might also consider queueing events and\n        // dispatching them after the mount.\n        targetInst = null;\n      }\n    }\n  }\n\n  {\n    dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);\n  } // We're not blocked on anything.\n\n\n  return null;\n}\n\n// List derived from Gecko source code:\n// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js\nvar shorthandToLonghand = {\n  animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],\n  background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],\n  backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],\n  border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],\n  borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],\n  borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],\n  borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],\n  borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],\n  borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],\n  borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],\n  borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],\n  borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],\n  borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],\n  borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],\n  borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],\n  borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],\n  borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],\n  columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],\n  columns: ['columnCount', 'columnWidth'],\n  flex: ['flexBasis', 'flexGrow', 'flexShrink'],\n  flexFlow: ['flexDirection', 'flexWrap'],\n  font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],\n  fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],\n  gap: ['columnGap', 'rowGap'],\n  grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],\n  gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],\n  gridColumn: ['gridColumnEnd', 'gridColumnStart'],\n  gridColumnGap: ['columnGap'],\n  gridGap: ['columnGap', 'rowGap'],\n  gridRow: ['gridRowEnd', 'gridRowStart'],\n  gridRowGap: ['rowGap'],\n  gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],\n  listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],\n  margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],\n  marker: ['markerEnd', 'markerMid', 'markerStart'],\n  mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],\n  maskPosition: ['maskPositionX', 'maskPositionY'],\n  outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],\n  overflow: ['overflowX', 'overflowY'],\n  padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],\n  placeContent: ['alignContent', 'justifyContent'],\n  placeItems: ['alignItems', 'justifyItems'],\n  placeSelf: ['alignSelf', 'justifySelf'],\n  textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],\n  textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],\n  transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],\n  wordWrap: ['overflowWrap']\n};\n\n/**\n * CSS properties which accept numbers but are not in units of \"px\".\n */\nvar isUnitlessNumber = {\n  animationIterationCount: true,\n  borderImageOutset: true,\n  borderImageSlice: true,\n  borderImageWidth: true,\n  boxFlex: true,\n  boxFlexGroup: true,\n  boxOrdinalGroup: true,\n  columnCount: true,\n  columns: true,\n  flex: true,\n  flexGrow: true,\n  flexPositive: true,\n  flexShrink: true,\n  flexNegative: true,\n  flexOrder: true,\n  gridArea: true,\n  gridRow: true,\n  gridRowEnd: true,\n  gridRowSpan: true,\n  gridRowStart: true,\n  gridColumn: true,\n  gridColumnEnd: true,\n  gridColumnSpan: true,\n  gridColumnStart: true,\n  fontWeight: true,\n  lineClamp: true,\n  lineHeight: true,\n  opacity: true,\n  order: true,\n  orphans: true,\n  tabSize: true,\n  widows: true,\n  zIndex: true,\n  zoom: true,\n  // SVG-related properties\n  fillOpacity: true,\n  floodOpacity: true,\n  stopOpacity: true,\n  strokeDasharray: true,\n  strokeDashoffset: true,\n  strokeMiterlimit: true,\n  strokeOpacity: true,\n  strokeWidth: true\n};\n/**\n * @param {string} prefix vendor-specific prefix, eg: Webkit\n * @param {string} key style name, eg: transitionDuration\n * @return {string} style name prefixed with `prefix`, properly camelCased, eg:\n * WebkitTransitionDuration\n */\n\nfunction prefixKey(prefix, key) {\n  return prefix + key.charAt(0).toUpperCase() + key.substring(1);\n}\n/**\n * Support style names that may come passed in prefixed by adding permutations\n * of vendor prefixes.\n */\n\n\nvar prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an\n// infinite loop, because it iterates over the newly added props too.\n\nObject.keys(isUnitlessNumber).forEach(function (prop) {\n  prefixes.forEach(function (prefix) {\n    isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];\n  });\n});\n\n/**\n * Convert a value into the proper css writable value. The style name `name`\n * should be logical (no hyphens), as specified\n * in `CSSProperty.isUnitlessNumber`.\n *\n * @param {string} name CSS property name such as `topMargin`.\n * @param {*} value CSS property value such as `10px`.\n * @return {string} Normalized style value with dimensions applied.\n */\n\nfunction dangerousStyleValue(name, value, isCustomProperty) {\n  // Note that we've removed escapeTextForBrowser() calls here since the\n  // whole string will be escaped when the attribute is injected into\n  // the markup. If you provide unsafe user data here they can inject\n  // arbitrary CSS which may be problematic (I couldn't repro this):\n  // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet\n  // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/\n  // This is not an XSS hole but instead a potential CSS injection issue\n  // which has lead to a greater discussion about how we're going to\n  // trust URLs moving forward. See #2115901\n  var isEmpty = value == null || typeof value === 'boolean' || value === '';\n\n  if (isEmpty) {\n    return '';\n  }\n\n  if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {\n    return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers\n  }\n\n  return ('' + value).trim();\n}\n\nvar uppercasePattern = /([A-Z])/g;\nvar msPattern = /^ms-/;\n/**\n * Hyphenates a camelcased CSS property name, for example:\n *\n *   > hyphenateStyleName('backgroundColor')\n *   < \"background-color\"\n *   > hyphenateStyleName('MozTransition')\n *   < \"-moz-transition\"\n *   > hyphenateStyleName('msTransition')\n *   < \"-ms-transition\"\n *\n * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix\n * is converted to `-ms-`.\n */\n\nfunction hyphenateStyleName(name) {\n  return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');\n}\n\nvar warnValidStyle = function () {};\n\n{\n  // 'msTransform' is correct, but the other prefixes should be capitalized\n  var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;\n  var msPattern$1 = /^-ms-/;\n  var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon\n\n  var badStyleValueWithSemicolonPattern = /;\\s*$/;\n  var warnedStyleNames = {};\n  var warnedStyleValues = {};\n  var warnedForNaNValue = false;\n  var warnedForInfinityValue = false;\n\n  var camelize = function (string) {\n    return string.replace(hyphenPattern, function (_, character) {\n      return character.toUpperCase();\n    });\n  };\n\n  var warnHyphenatedStyleName = function (name) {\n    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {\n      return;\n    }\n\n    warnedStyleNames[name] = true;\n\n    error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests\n    // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix\n    // is converted to lowercase `ms`.\n    camelize(name.replace(msPattern$1, 'ms-')));\n  };\n\n  var warnBadVendoredStyleName = function (name) {\n    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {\n      return;\n    }\n\n    warnedStyleNames[name] = true;\n\n    error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));\n  };\n\n  var warnStyleValueWithSemicolon = function (name, value) {\n    if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {\n      return;\n    }\n\n    warnedStyleValues[value] = true;\n\n    error(\"Style property values shouldn't contain a semicolon. \" + 'Try \"%s: %s\" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));\n  };\n\n  var warnStyleValueIsNaN = function (name, value) {\n    if (warnedForNaNValue) {\n      return;\n    }\n\n    warnedForNaNValue = true;\n\n    error('`NaN` is an invalid value for the `%s` css style property.', name);\n  };\n\n  var warnStyleValueIsInfinity = function (name, value) {\n    if (warnedForInfinityValue) {\n      return;\n    }\n\n    warnedForInfinityValue = true;\n\n    error('`Infinity` is an invalid value for the `%s` css style property.', name);\n  };\n\n  warnValidStyle = function (name, value) {\n    if (name.indexOf('-') > -1) {\n      warnHyphenatedStyleName(name);\n    } else if (badVendoredStyleNamePattern.test(name)) {\n      warnBadVendoredStyleName(name);\n    } else if (badStyleValueWithSemicolonPattern.test(value)) {\n      warnStyleValueWithSemicolon(name, value);\n    }\n\n    if (typeof value === 'number') {\n      if (isNaN(value)) {\n        warnStyleValueIsNaN(name, value);\n      } else if (!isFinite(value)) {\n        warnStyleValueIsInfinity(name, value);\n      }\n    }\n  };\n}\n\nvar warnValidStyle$1 = warnValidStyle;\n\n/**\n * Operations for dealing with CSS properties.\n */\n\n/**\n * This creates a string that is expected to be equivalent to the style\n * attribute generated by server-side rendering. It by-passes warnings and\n * security checks so it's not safe to use this value for anything other than\n * comparison. It is only used in DEV for SSR validation.\n */\n\nfunction createDangerousStringForStyles(styles) {\n  {\n    var serialized = '';\n    var delimiter = '';\n\n    for (var styleName in styles) {\n      if (!styles.hasOwnProperty(styleName)) {\n        continue;\n      }\n\n      var styleValue = styles[styleName];\n\n      if (styleValue != null) {\n        var isCustomProperty = styleName.indexOf('--') === 0;\n        serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';\n        serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);\n        delimiter = ';';\n      }\n    }\n\n    return serialized || null;\n  }\n}\n/**\n * Sets the value for multiple styles on a node.  If a value is specified as\n * '' (empty string), the corresponding style property will be unset.\n *\n * @param {DOMElement} node\n * @param {object} styles\n */\n\nfunction setValueForStyles(node, styles) {\n  var style = node.style;\n\n  for (var styleName in styles) {\n    if (!styles.hasOwnProperty(styleName)) {\n      continue;\n    }\n\n    var isCustomProperty = styleName.indexOf('--') === 0;\n\n    {\n      if (!isCustomProperty) {\n        warnValidStyle$1(styleName, styles[styleName]);\n      }\n    }\n\n    var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);\n\n    if (styleName === 'float') {\n      styleName = 'cssFloat';\n    }\n\n    if (isCustomProperty) {\n      style.setProperty(styleName, styleValue);\n    } else {\n      style[styleName] = styleValue;\n    }\n  }\n}\n\nfunction isValueEmpty(value) {\n  return value == null || typeof value === 'boolean' || value === '';\n}\n/**\n * Given {color: 'red', overflow: 'hidden'} returns {\n *   color: 'color',\n *   overflowX: 'overflow',\n *   overflowY: 'overflow',\n * }. This can be read as \"the overflowY property was set by the overflow\n * shorthand\". That is, the values are the property that each was derived from.\n */\n\n\nfunction expandShorthandMap(styles) {\n  var expanded = {};\n\n  for (var key in styles) {\n    var longhands = shorthandToLonghand[key] || [key];\n\n    for (var i = 0; i < longhands.length; i++) {\n      expanded[longhands[i]] = key;\n    }\n  }\n\n  return expanded;\n}\n/**\n * When mixing shorthand and longhand property names, we warn during updates if\n * we expect an incorrect result to occur. In particular, we warn for:\n *\n * Updating a shorthand property (longhand gets overwritten):\n *   {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}\n *   becomes .style.font = 'baz'\n * Removing a shorthand property (longhand gets lost too):\n *   {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}\n *   becomes .style.font = ''\n * Removing a longhand property (should revert to shorthand; doesn't):\n *   {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}\n *   becomes .style.fontVariant = ''\n */\n\n\nfunction validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {\n  {\n\n    if (!nextStyles) {\n      return;\n    }\n\n    var expandedUpdates = expandShorthandMap(styleUpdates);\n    var expandedStyles = expandShorthandMap(nextStyles);\n    var warnedAbout = {};\n\n    for (var key in expandedUpdates) {\n      var originalKey = expandedUpdates[key];\n      var correctOriginalKey = expandedStyles[key];\n\n      if (correctOriginalKey && originalKey !== correctOriginalKey) {\n        var warningKey = originalKey + ',' + correctOriginalKey;\n\n        if (warnedAbout[warningKey]) {\n          continue;\n        }\n\n        warnedAbout[warningKey] = true;\n\n        error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + \"avoid this, don't mix shorthand and non-shorthand properties \" + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);\n      }\n    }\n  }\n}\n\n// For HTML, certain tags should omit their close tag. We keep a whitelist for\n// those special-case tags.\nvar omittedCloseTags = {\n  area: true,\n  base: true,\n  br: true,\n  col: true,\n  embed: true,\n  hr: true,\n  img: true,\n  input: true,\n  keygen: true,\n  link: true,\n  meta: true,\n  param: true,\n  source: true,\n  track: true,\n  wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.\n\n};\n\n// `omittedCloseTags` except that `menuitem` should still have its closing tag.\n\nvar voidElementTags = _assign({\n  menuitem: true\n}, omittedCloseTags);\n\nvar HTML = '__html';\nvar ReactDebugCurrentFrame$3 = null;\n\n{\n  ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;\n}\n\nfunction assertValidProps(tag, props) {\n  if (!props) {\n    return;\n  } // Note the use of `==` which checks for null or undefined.\n\n\n  if (voidElementTags[tag]) {\n    if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {\n      {\n        throw Error( tag + \" is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.\" + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );\n      }\n    }\n  }\n\n  if (props.dangerouslySetInnerHTML != null) {\n    if (!(props.children == null)) {\n      {\n        throw Error( \"Can only set one of `children` or `props.dangerouslySetInnerHTML`.\" );\n      }\n    }\n\n    if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {\n      {\n        throw Error( \"`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.\" );\n      }\n    }\n  }\n\n  {\n    if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {\n      error('A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.');\n    }\n  }\n\n  if (!(props.style == null || typeof props.style === 'object')) {\n    {\n      throw Error( \"The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.\" + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );\n    }\n  }\n}\n\nfunction isCustomComponent(tagName, props) {\n  if (tagName.indexOf('-') === -1) {\n    return typeof props.is === 'string';\n  }\n\n  switch (tagName) {\n    // These are reserved SVG and MathML elements.\n    // We don't mind this whitelist too much because we expect it to never grow.\n    // The alternative is to track the namespace in a few places which is convoluted.\n    // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts\n    case 'annotation-xml':\n    case 'color-profile':\n    case 'font-face':\n    case 'font-face-src':\n    case 'font-face-uri':\n    case 'font-face-format':\n    case 'font-face-name':\n    case 'missing-glyph':\n      return false;\n\n    default:\n      return true;\n  }\n}\n\n// When adding attributes to the HTML or SVG whitelist, be sure to\n// also add them to this module to ensure casing and incorrect name\n// warnings.\nvar possibleStandardNames = {\n  // HTML\n  accept: 'accept',\n  acceptcharset: 'acceptCharset',\n  'accept-charset': 'acceptCharset',\n  accesskey: 'accessKey',\n  action: 'action',\n  allowfullscreen: 'allowFullScreen',\n  alt: 'alt',\n  as: 'as',\n  async: 'async',\n  autocapitalize: 'autoCapitalize',\n  autocomplete: 'autoComplete',\n  autocorrect: 'autoCorrect',\n  autofocus: 'autoFocus',\n  autoplay: 'autoPlay',\n  autosave: 'autoSave',\n  capture: 'capture',\n  cellpadding: 'cellPadding',\n  cellspacing: 'cellSpacing',\n  challenge: 'challenge',\n  charset: 'charSet',\n  checked: 'checked',\n  children: 'children',\n  cite: 'cite',\n  class: 'className',\n  classid: 'classID',\n  classname: 'className',\n  cols: 'cols',\n  colspan: 'colSpan',\n  content: 'content',\n  contenteditable: 'contentEditable',\n  contextmenu: 'contextMenu',\n  controls: 'controls',\n  controlslist: 'controlsList',\n  coords: 'coords',\n  crossorigin: 'crossOrigin',\n  dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',\n  data: 'data',\n  datetime: 'dateTime',\n  default: 'default',\n  defaultchecked: 'defaultChecked',\n  defaultvalue: 'defaultValue',\n  defer: 'defer',\n  dir: 'dir',\n  disabled: 'disabled',\n  disablepictureinpicture: 'disablePictureInPicture',\n  download: 'download',\n  draggable: 'draggable',\n  enctype: 'encType',\n  for: 'htmlFor',\n  form: 'form',\n  formmethod: 'formMethod',\n  formaction: 'formAction',\n  formenctype: 'formEncType',\n  formnovalidate: 'formNoValidate',\n  formtarget: 'formTarget',\n  frameborder: 'frameBorder',\n  headers: 'headers',\n  height: 'height',\n  hidden: 'hidden',\n  high: 'high',\n  href: 'href',\n  hreflang: 'hrefLang',\n  htmlfor: 'htmlFor',\n  httpequiv: 'httpEquiv',\n  'http-equiv': 'httpEquiv',\n  icon: 'icon',\n  id: 'id',\n  innerhtml: 'innerHTML',\n  inputmode: 'inputMode',\n  integrity: 'integrity',\n  is: 'is',\n  itemid: 'itemID',\n  itemprop: 'itemProp',\n  itemref: 'itemRef',\n  itemscope: 'itemScope',\n  itemtype: 'itemType',\n  keyparams: 'keyParams',\n  keytype: 'keyType',\n  kind: 'kind',\n  label: 'label',\n  lang: 'lang',\n  list: 'list',\n  loop: 'loop',\n  low: 'low',\n  manifest: 'manifest',\n  marginwidth: 'marginWidth',\n  marginheight: 'marginHeight',\n  max: 'max',\n  maxlength: 'maxLength',\n  media: 'media',\n  mediagroup: 'mediaGroup',\n  method: 'method',\n  min: 'min',\n  minlength: 'minLength',\n  multiple: 'multiple',\n  muted: 'muted',\n  name: 'name',\n  nomodule: 'noModule',\n  nonce: 'nonce',\n  novalidate: 'noValidate',\n  open: 'open',\n  optimum: 'optimum',\n  pattern: 'pattern',\n  placeholder: 'placeholder',\n  playsinline: 'playsInline',\n  poster: 'poster',\n  preload: 'preload',\n  profile: 'profile',\n  radiogroup: 'radioGroup',\n  readonly: 'readOnly',\n  referrerpolicy: 'referrerPolicy',\n  rel: 'rel',\n  required: 'required',\n  reversed: 'reversed',\n  role: 'role',\n  rows: 'rows',\n  rowspan: 'rowSpan',\n  sandbox: 'sandbox',\n  scope: 'scope',\n  scoped: 'scoped',\n  scrolling: 'scrolling',\n  seamless: 'seamless',\n  selected: 'selected',\n  shape: 'shape',\n  size: 'size',\n  sizes: 'sizes',\n  span: 'span',\n  spellcheck: 'spellCheck',\n  src: 'src',\n  srcdoc: 'srcDoc',\n  srclang: 'srcLang',\n  srcset: 'srcSet',\n  start: 'start',\n  step: 'step',\n  style: 'style',\n  summary: 'summary',\n  tabindex: 'tabIndex',\n  target: 'target',\n  title: 'title',\n  type: 'type',\n  usemap: 'useMap',\n  value: 'value',\n  width: 'width',\n  wmode: 'wmode',\n  wrap: 'wrap',\n  // SVG\n  about: 'about',\n  accentheight: 'accentHeight',\n  'accent-height': 'accentHeight',\n  accumulate: 'accumulate',\n  additive: 'additive',\n  alignmentbaseline: 'alignmentBaseline',\n  'alignment-baseline': 'alignmentBaseline',\n  allowreorder: 'allowReorder',\n  alphabetic: 'alphabetic',\n  amplitude: 'amplitude',\n  arabicform: 'arabicForm',\n  'arabic-form': 'arabicForm',\n  ascent: 'ascent',\n  attributename: 'attributeName',\n  attributetype: 'attributeType',\n  autoreverse: 'autoReverse',\n  azimuth: 'azimuth',\n  basefrequency: 'baseFrequency',\n  baselineshift: 'baselineShift',\n  'baseline-shift': 'baselineShift',\n  baseprofile: 'baseProfile',\n  bbox: 'bbox',\n  begin: 'begin',\n  bias: 'bias',\n  by: 'by',\n  calcmode: 'calcMode',\n  capheight: 'capHeight',\n  'cap-height': 'capHeight',\n  clip: 'clip',\n  clippath: 'clipPath',\n  'clip-path': 'clipPath',\n  clippathunits: 'clipPathUnits',\n  cliprule: 'clipRule',\n  'clip-rule': 'clipRule',\n  color: 'color',\n  colorinterpolation: 'colorInterpolation',\n  'color-interpolation': 'colorInterpolation',\n  colorinterpolationfilters: 'colorInterpolationFilters',\n  'color-interpolation-filters': 'colorInterpolationFilters',\n  colorprofile: 'colorProfile',\n  'color-profile': 'colorProfile',\n  colorrendering: 'colorRendering',\n  'color-rendering': 'colorRendering',\n  contentscripttype: 'contentScriptType',\n  contentstyletype: 'contentStyleType',\n  cursor: 'cursor',\n  cx: 'cx',\n  cy: 'cy',\n  d: 'd',\n  datatype: 'datatype',\n  decelerate: 'decelerate',\n  descent: 'descent',\n  diffuseconstant: 'diffuseConstant',\n  direction: 'direction',\n  display: 'display',\n  divisor: 'divisor',\n  dominantbaseline: 'dominantBaseline',\n  'dominant-baseline': 'dominantBaseline',\n  dur: 'dur',\n  dx: 'dx',\n  dy: 'dy',\n  edgemode: 'edgeMode',\n  elevation: 'elevation',\n  enablebackground: 'enableBackground',\n  'enable-background': 'enableBackground',\n  end: 'end',\n  exponent: 'exponent',\n  externalresourcesrequired: 'externalResourcesRequired',\n  fill: 'fill',\n  fillopacity: 'fillOpacity',\n  'fill-opacity': 'fillOpacity',\n  fillrule: 'fillRule',\n  'fill-rule': 'fillRule',\n  filter: 'filter',\n  filterres: 'filterRes',\n  filterunits: 'filterUnits',\n  floodopacity: 'floodOpacity',\n  'flood-opacity': 'floodOpacity',\n  floodcolor: 'floodColor',\n  'flood-color': 'floodColor',\n  focusable: 'focusable',\n  fontfamily: 'fontFamily',\n  'font-family': 'fontFamily',\n  fontsize: 'fontSize',\n  'font-size': 'fontSize',\n  fontsizeadjust: 'fontSizeAdjust',\n  'font-size-adjust': 'fontSizeAdjust',\n  fontstretch: 'fontStretch',\n  'font-stretch': 'fontStretch',\n  fontstyle: 'fontStyle',\n  'font-style': 'fontStyle',\n  fontvariant: 'fontVariant',\n  'font-variant': 'fontVariant',\n  fontweight: 'fontWeight',\n  'font-weight': 'fontWeight',\n  format: 'format',\n  from: 'from',\n  fx: 'fx',\n  fy: 'fy',\n  g1: 'g1',\n  g2: 'g2',\n  glyphname: 'glyphName',\n  'glyph-name': 'glyphName',\n  glyphorientationhorizontal: 'glyphOrientationHorizontal',\n  'glyph-orientation-horizontal': 'glyphOrientationHorizontal',\n  glyphorientationvertical: 'glyphOrientationVertical',\n  'glyph-orientation-vertical': 'glyphOrientationVertical',\n  glyphref: 'glyphRef',\n  gradienttransform: 'gradientTransform',\n  gradientunits: 'gradientUnits',\n  hanging: 'hanging',\n  horizadvx: 'horizAdvX',\n  'horiz-adv-x': 'horizAdvX',\n  horizoriginx: 'horizOriginX',\n  'horiz-origin-x': 'horizOriginX',\n  ideographic: 'ideographic',\n  imagerendering: 'imageRendering',\n  'image-rendering': 'imageRendering',\n  in2: 'in2',\n  in: 'in',\n  inlist: 'inlist',\n  intercept: 'intercept',\n  k1: 'k1',\n  k2: 'k2',\n  k3: 'k3',\n  k4: 'k4',\n  k: 'k',\n  kernelmatrix: 'kernelMatrix',\n  kernelunitlength: 'kernelUnitLength',\n  kerning: 'kerning',\n  keypoints: 'keyPoints',\n  keysplines: 'keySplines',\n  keytimes: 'keyTimes',\n  lengthadjust: 'lengthAdjust',\n  letterspacing: 'letterSpacing',\n  'letter-spacing': 'letterSpacing',\n  lightingcolor: 'lightingColor',\n  'lighting-color': 'lightingColor',\n  limitingconeangle: 'limitingConeAngle',\n  local: 'local',\n  markerend: 'markerEnd',\n  'marker-end': 'markerEnd',\n  markerheight: 'markerHeight',\n  markermid: 'markerMid',\n  'marker-mid': 'markerMid',\n  markerstart: 'markerStart',\n  'marker-start': 'markerStart',\n  markerunits: 'markerUnits',\n  markerwidth: 'markerWidth',\n  mask: 'mask',\n  maskcontentunits: 'maskContentUnits',\n  maskunits: 'maskUnits',\n  mathematical: 'mathematical',\n  mode: 'mode',\n  numoctaves: 'numOctaves',\n  offset: 'offset',\n  opacity: 'opacity',\n  operator: 'operator',\n  order: 'order',\n  orient: 'orient',\n  orientation: 'orientation',\n  origin: 'origin',\n  overflow: 'overflow',\n  overlineposition: 'overlinePosition',\n  'overline-position': 'overlinePosition',\n  overlinethickness: 'overlineThickness',\n  'overline-thickness': 'overlineThickness',\n  paintorder: 'paintOrder',\n  'paint-order': 'paintOrder',\n  panose1: 'panose1',\n  'panose-1': 'panose1',\n  pathlength: 'pathLength',\n  patterncontentunits: 'patternContentUnits',\n  patterntransform: 'patternTransform',\n  patternunits: 'patternUnits',\n  pointerevents: 'pointerEvents',\n  'pointer-events': 'pointerEvents',\n  points: 'points',\n  pointsatx: 'pointsAtX',\n  pointsaty: 'pointsAtY',\n  pointsatz: 'pointsAtZ',\n  prefix: 'prefix',\n  preservealpha: 'preserveAlpha',\n  preserveaspectratio: 'preserveAspectRatio',\n  primitiveunits: 'primitiveUnits',\n  property: 'property',\n  r: 'r',\n  radius: 'radius',\n  refx: 'refX',\n  refy: 'refY',\n  renderingintent: 'renderingIntent',\n  'rendering-intent': 'renderingIntent',\n  repeatcount: 'repeatCount',\n  repeatdur: 'repeatDur',\n  requiredextensions: 'requiredExtensions',\n  requiredfeatures: 'requiredFeatures',\n  resource: 'resource',\n  restart: 'restart',\n  result: 'result',\n  results: 'results',\n  rotate: 'rotate',\n  rx: 'rx',\n  ry: 'ry',\n  scale: 'scale',\n  security: 'security',\n  seed: 'seed',\n  shaperendering: 'shapeRendering',\n  'shape-rendering': 'shapeRendering',\n  slope: 'slope',\n  spacing: 'spacing',\n  specularconstant: 'specularConstant',\n  specularexponent: 'specularExponent',\n  speed: 'speed',\n  spreadmethod: 'spreadMethod',\n  startoffset: 'startOffset',\n  stddeviation: 'stdDeviation',\n  stemh: 'stemh',\n  stemv: 'stemv',\n  stitchtiles: 'stitchTiles',\n  stopcolor: 'stopColor',\n  'stop-color': 'stopColor',\n  stopopacity: 'stopOpacity',\n  'stop-opacity': 'stopOpacity',\n  strikethroughposition: 'strikethroughPosition',\n  'strikethrough-position': 'strikethroughPosition',\n  strikethroughthickness: 'strikethroughThickness',\n  'strikethrough-thickness': 'strikethroughThickness',\n  string: 'string',\n  stroke: 'stroke',\n  strokedasharray: 'strokeDasharray',\n  'stroke-dasharray': 'strokeDasharray',\n  strokedashoffset: 'strokeDashoffset',\n  'stroke-dashoffset': 'strokeDashoffset',\n  strokelinecap: 'strokeLinecap',\n  'stroke-linecap': 'strokeLinecap',\n  strokelinejoin: 'strokeLinejoin',\n  'stroke-linejoin': 'strokeLinejoin',\n  strokemiterlimit: 'strokeMiterlimit',\n  'stroke-miterlimit': 'strokeMiterlimit',\n  strokewidth: 'strokeWidth',\n  'stroke-width': 'strokeWidth',\n  strokeopacity: 'strokeOpacity',\n  'stroke-opacity': 'strokeOpacity',\n  suppresscontenteditablewarning: 'suppressContentEditableWarning',\n  suppresshydrationwarning: 'suppressHydrationWarning',\n  surfacescale: 'surfaceScale',\n  systemlanguage: 'systemLanguage',\n  tablevalues: 'tableValues',\n  targetx: 'targetX',\n  targety: 'targetY',\n  textanchor: 'textAnchor',\n  'text-anchor': 'textAnchor',\n  textdecoration: 'textDecoration',\n  'text-decoration': 'textDecoration',\n  textlength: 'textLength',\n  textrendering: 'textRendering',\n  'text-rendering': 'textRendering',\n  to: 'to',\n  transform: 'transform',\n  typeof: 'typeof',\n  u1: 'u1',\n  u2: 'u2',\n  underlineposition: 'underlinePosition',\n  'underline-position': 'underlinePosition',\n  underlinethickness: 'underlineThickness',\n  'underline-thickness': 'underlineThickness',\n  unicode: 'unicode',\n  unicodebidi: 'unicodeBidi',\n  'unicode-bidi': 'unicodeBidi',\n  unicoderange: 'unicodeRange',\n  'unicode-range': 'unicodeRange',\n  unitsperem: 'unitsPerEm',\n  'units-per-em': 'unitsPerEm',\n  unselectable: 'unselectable',\n  valphabetic: 'vAlphabetic',\n  'v-alphabetic': 'vAlphabetic',\n  values: 'values',\n  vectoreffect: 'vectorEffect',\n  'vector-effect': 'vectorEffect',\n  version: 'version',\n  vertadvy: 'vertAdvY',\n  'vert-adv-y': 'vertAdvY',\n  vertoriginx: 'vertOriginX',\n  'vert-origin-x': 'vertOriginX',\n  vertoriginy: 'vertOriginY',\n  'vert-origin-y': 'vertOriginY',\n  vhanging: 'vHanging',\n  'v-hanging': 'vHanging',\n  videographic: 'vIdeographic',\n  'v-ideographic': 'vIdeographic',\n  viewbox: 'viewBox',\n  viewtarget: 'viewTarget',\n  visibility: 'visibility',\n  vmathematical: 'vMathematical',\n  'v-mathematical': 'vMathematical',\n  vocab: 'vocab',\n  widths: 'widths',\n  wordspacing: 'wordSpacing',\n  'word-spacing': 'wordSpacing',\n  writingmode: 'writingMode',\n  'writing-mode': 'writingMode',\n  x1: 'x1',\n  x2: 'x2',\n  x: 'x',\n  xchannelselector: 'xChannelSelector',\n  xheight: 'xHeight',\n  'x-height': 'xHeight',\n  xlinkactuate: 'xlinkActuate',\n  'xlink:actuate': 'xlinkActuate',\n  xlinkarcrole: 'xlinkArcrole',\n  'xlink:arcrole': 'xlinkArcrole',\n  xlinkhref: 'xlinkHref',\n  'xlink:href': 'xlinkHref',\n  xlinkrole: 'xlinkRole',\n  'xlink:role': 'xlinkRole',\n  xlinkshow: 'xlinkShow',\n  'xlink:show': 'xlinkShow',\n  xlinktitle: 'xlinkTitle',\n  'xlink:title': 'xlinkTitle',\n  xlinktype: 'xlinkType',\n  'xlink:type': 'xlinkType',\n  xmlbase: 'xmlBase',\n  'xml:base': 'xmlBase',\n  xmllang: 'xmlLang',\n  'xml:lang': 'xmlLang',\n  xmlns: 'xmlns',\n  'xml:space': 'xmlSpace',\n  xmlnsxlink: 'xmlnsXlink',\n  'xmlns:xlink': 'xmlnsXlink',\n  xmlspace: 'xmlSpace',\n  y1: 'y1',\n  y2: 'y2',\n  y: 'y',\n  ychannelselector: 'yChannelSelector',\n  z: 'z',\n  zoomandpan: 'zoomAndPan'\n};\n\nvar ariaProperties = {\n  'aria-current': 0,\n  // state\n  'aria-details': 0,\n  'aria-disabled': 0,\n  // state\n  'aria-hidden': 0,\n  // state\n  'aria-invalid': 0,\n  // state\n  'aria-keyshortcuts': 0,\n  'aria-label': 0,\n  'aria-roledescription': 0,\n  // Widget Attributes\n  'aria-autocomplete': 0,\n  'aria-checked': 0,\n  'aria-expanded': 0,\n  'aria-haspopup': 0,\n  'aria-level': 0,\n  'aria-modal': 0,\n  'aria-multiline': 0,\n  'aria-multiselectable': 0,\n  'aria-orientation': 0,\n  'aria-placeholder': 0,\n  'aria-pressed': 0,\n  'aria-readonly': 0,\n  'aria-required': 0,\n  'aria-selected': 0,\n  'aria-sort': 0,\n  'aria-valuemax': 0,\n  'aria-valuemin': 0,\n  'aria-valuenow': 0,\n  'aria-valuetext': 0,\n  // Live Region Attributes\n  'aria-atomic': 0,\n  'aria-busy': 0,\n  'aria-live': 0,\n  'aria-relevant': 0,\n  // Drag-and-Drop Attributes\n  'aria-dropeffect': 0,\n  'aria-grabbed': 0,\n  // Relationship Attributes\n  'aria-activedescendant': 0,\n  'aria-colcount': 0,\n  'aria-colindex': 0,\n  'aria-colspan': 0,\n  'aria-controls': 0,\n  'aria-describedby': 0,\n  'aria-errormessage': 0,\n  'aria-flowto': 0,\n  'aria-labelledby': 0,\n  'aria-owns': 0,\n  'aria-posinset': 0,\n  'aria-rowcount': 0,\n  'aria-rowindex': 0,\n  'aria-rowspan': 0,\n  'aria-setsize': 0\n};\n\nvar warnedProperties = {};\nvar rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');\nvar rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');\nvar hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\nfunction validateProperty(tagName, name) {\n  {\n    if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {\n      return true;\n    }\n\n    if (rARIACamel.test(name)) {\n      var ariaName = 'aria-' + name.slice(4).toLowerCase();\n      var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM\n      // DOM properties, then it is an invalid aria-* attribute.\n\n      if (correctName == null) {\n        error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);\n\n        warnedProperties[name] = true;\n        return true;\n      } // aria-* attributes should be lowercase; suggest the lowercase version.\n\n\n      if (name !== correctName) {\n        error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);\n\n        warnedProperties[name] = true;\n        return true;\n      }\n    }\n\n    if (rARIA.test(name)) {\n      var lowerCasedName = name.toLowerCase();\n      var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM\n      // DOM properties, then it is an invalid aria-* attribute.\n\n      if (standardName == null) {\n        warnedProperties[name] = true;\n        return false;\n      } // aria-* attributes should be lowercase; suggest the lowercase version.\n\n\n      if (name !== standardName) {\n        error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);\n\n        warnedProperties[name] = true;\n        return true;\n      }\n    }\n  }\n\n  return true;\n}\n\nfunction warnInvalidARIAProps(type, props) {\n  {\n    var invalidProps = [];\n\n    for (var key in props) {\n      var isValid = validateProperty(type, key);\n\n      if (!isValid) {\n        invalidProps.push(key);\n      }\n    }\n\n    var unknownPropString = invalidProps.map(function (prop) {\n      return '`' + prop + '`';\n    }).join(', ');\n\n    if (invalidProps.length === 1) {\n      error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);\n    } else if (invalidProps.length > 1) {\n      error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);\n    }\n  }\n}\n\nfunction validateProperties(type, props) {\n  if (isCustomComponent(type, props)) {\n    return;\n  }\n\n  warnInvalidARIAProps(type, props);\n}\n\nvar didWarnValueNull = false;\nfunction validateProperties$1(type, props) {\n  {\n    if (type !== 'input' && type !== 'textarea' && type !== 'select') {\n      return;\n    }\n\n    if (props != null && props.value === null && !didWarnValueNull) {\n      didWarnValueNull = true;\n\n      if (type === 'select' && props.multiple) {\n        error('`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);\n      } else {\n        error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);\n      }\n    }\n  }\n}\n\nvar validateProperty$1 = function () {};\n\n{\n  var warnedProperties$1 = {};\n  var _hasOwnProperty = Object.prototype.hasOwnProperty;\n  var EVENT_NAME_REGEX = /^on./;\n  var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;\n  var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');\n  var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');\n\n  validateProperty$1 = function (tagName, name, value, canUseEventSystem) {\n    if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {\n      return true;\n    }\n\n    var lowerCasedName = name.toLowerCase();\n\n    if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {\n      error('React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');\n\n      warnedProperties$1[name] = true;\n      return true;\n    } // We can't rely on the event system being injected on the server.\n\n\n    if (canUseEventSystem) {\n      if (registrationNameModules.hasOwnProperty(name)) {\n        return true;\n      }\n\n      var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;\n\n      if (registrationName != null) {\n        error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);\n\n        warnedProperties$1[name] = true;\n        return true;\n      }\n\n      if (EVENT_NAME_REGEX.test(name)) {\n        error('Unknown event handler property `%s`. It will be ignored.', name);\n\n        warnedProperties$1[name] = true;\n        return true;\n      }\n    } else if (EVENT_NAME_REGEX.test(name)) {\n      // If no event plugins have been injected, we are in a server environment.\n      // So we can't tell if the event name is correct for sure, but we can filter\n      // out known bad ones like `onclick`. We can't suggest a specific replacement though.\n      if (INVALID_EVENT_NAME_REGEX.test(name)) {\n        error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);\n      }\n\n      warnedProperties$1[name] = true;\n      return true;\n    } // Let the ARIA attribute hook validate ARIA attributes\n\n\n    if (rARIA$1.test(name) || rARIACamel$1.test(name)) {\n      return true;\n    }\n\n    if (lowerCasedName === 'innerhtml') {\n      error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    if (lowerCasedName === 'aria') {\n      error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {\n      error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    if (typeof value === 'number' && isNaN(value)) {\n      error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    var propertyInfo = getPropertyInfo(name);\n    var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.\n\n    if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {\n      var standardName = possibleStandardNames[lowerCasedName];\n\n      if (standardName !== name) {\n        error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);\n\n        warnedProperties$1[name] = true;\n        return true;\n      }\n    } else if (!isReserved && name !== lowerCasedName) {\n      // Unknown attributes should have lowercase casing since that's how they\n      // will be cased anyway with server rendering.\n      error('React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {\n      if (value) {\n        error('Received `%s` for a non-boolean attribute `%s`.\\n\\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s=\"%s\" or %s={value.toString()}.', value, name, name, value, name);\n      } else {\n        error('Received `%s` for a non-boolean attribute `%s`.\\n\\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s=\"%s\" or %s={value.toString()}.\\n\\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);\n      }\n\n      warnedProperties$1[name] = true;\n      return true;\n    } // Now that we've validated casing, do not validate\n    // data types for reserved props\n\n\n    if (isReserved) {\n      return true;\n    } // Warn when a known attribute is a bad type\n\n\n    if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {\n      warnedProperties$1[name] = true;\n      return false;\n    } // Warn when passing the strings 'false' or 'true' into a boolean prop\n\n\n    if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {\n      error('Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string \"false\".', name, value);\n\n      warnedProperties$1[name] = true;\n      return true;\n    }\n\n    return true;\n  };\n}\n\nvar warnUnknownProperties = function (type, props, canUseEventSystem) {\n  {\n    var unknownProps = [];\n\n    for (var key in props) {\n      var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);\n\n      if (!isValid) {\n        unknownProps.push(key);\n      }\n    }\n\n    var unknownPropString = unknownProps.map(function (prop) {\n      return '`' + prop + '`';\n    }).join(', ');\n\n    if (unknownProps.length === 1) {\n      error('Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);\n    } else if (unknownProps.length > 1) {\n      error('Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);\n    }\n  }\n};\n\nfunction validateProperties$2(type, props, canUseEventSystem) {\n  if (isCustomComponent(type, props)) {\n    return;\n  }\n\n  warnUnknownProperties(type, props, canUseEventSystem);\n}\n\nvar didWarnInvalidHydration = false;\nvar DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';\nvar SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';\nvar SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';\nvar AUTOFOCUS = 'autoFocus';\nvar CHILDREN = 'children';\nvar STYLE = 'style';\nvar HTML$1 = '__html';\nvar HTML_NAMESPACE$1 = Namespaces.html;\nvar warnedUnknownTags;\nvar suppressHydrationWarning;\nvar validatePropertiesInDevelopment;\nvar warnForTextDifference;\nvar warnForPropDifference;\nvar warnForExtraAttributes;\nvar warnForInvalidEventListener;\nvar canDiffStyleForHydrationWarning;\nvar normalizeMarkupForTextOrAttribute;\nvar normalizeHTML;\n\n{\n  warnedUnknownTags = {\n    // Chrome is the only major browser not shipping <time>. But as of July\n    // 2017 it intends to ship it due to widespread usage. We intentionally\n    // *don't* warn for <time> even if it's unrecognized by Chrome because\n    // it soon will be, and many apps have been using it anyway.\n    time: true,\n    // There are working polyfills for <dialog>. Let people use it.\n    dialog: true,\n    // Electron ships a custom <webview> tag to display external web content in\n    // an isolated frame and process.\n    // This tag is not present in non Electron environments such as JSDom which\n    // is often used for testing purposes.\n    // @see https://electronjs.org/docs/api/webview-tag\n    webview: true\n  };\n\n  validatePropertiesInDevelopment = function (type, props) {\n    validateProperties(type, props);\n    validateProperties$1(type, props);\n    validateProperties$2(type, props,\n    /* canUseEventSystem */\n    true);\n  }; // IE 11 parses & normalizes the style attribute as opposed to other\n  // browsers. It adds spaces and sorts the properties in some\n  // non-alphabetical order. Handling that would require sorting CSS\n  // properties in the client & server versions or applying\n  // `expectedStyle` to a temporary DOM node to read its `style` attribute\n  // normalized. Since it only affects IE, we're skipping style warnings\n  // in that browser completely in favor of doing all that work.\n  // See https://github.com/facebook/react/issues/11807\n\n\n  canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.\n  // It also can turn \\u0000 into \\uFFFD inside attributes.\n  // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream\n  // If we have a mismatch, it might be caused by that.\n  // We will still patch up in this case but not fire the warning.\n\n  var NORMALIZE_NEWLINES_REGEX = /\\r\\n?/g;\n  var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\\u0000|\\uFFFD/g;\n\n  normalizeMarkupForTextOrAttribute = function (markup) {\n    var markupString = typeof markup === 'string' ? markup : '' + markup;\n    return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');\n  };\n\n  warnForTextDifference = function (serverText, clientText) {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);\n    var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);\n\n    if (normalizedServerText === normalizedClientText) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Text content did not match. Server: \"%s\" Client: \"%s\"', normalizedServerText, normalizedClientText);\n  };\n\n  warnForPropDifference = function (propName, serverValue, clientValue) {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);\n    var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);\n\n    if (normalizedServerValue === normalizedClientValue) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));\n  };\n\n  warnForExtraAttributes = function (attributeNames) {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n    var names = [];\n    attributeNames.forEach(function (name) {\n      names.push(name);\n    });\n\n    error('Extra attributes from the server: %s', names);\n  };\n\n  warnForInvalidEventListener = function (registrationName, listener) {\n    if (listener === false) {\n      error('Expected `%s` listener to be a function, instead got `false`.\\n\\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);\n    } else {\n      error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);\n    }\n  }; // Parse the HTML and read it back to normalize the HTML string so that it\n  // can be used for comparison.\n\n\n  normalizeHTML = function (parent, html) {\n    // We could have created a separate document here to avoid\n    // re-initializing custom elements if they exist. But this breaks\n    // how <noscript> is being handled. So we use the same document.\n    // See the discussion in https://github.com/facebook/react/pull/11157.\n    var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);\n    testElement.innerHTML = html;\n    return testElement.innerHTML;\n  };\n}\n\nfunction ensureListeningTo(rootContainerElement, registrationName) {\n  var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;\n  var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;\n  legacyListenToEvent(registrationName, doc);\n}\n\nfunction getOwnerDocumentFromRootContainer(rootContainerElement) {\n  return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;\n}\n\nfunction noop() {}\n\nfunction trapClickOnNonInteractiveElement(node) {\n  // Mobile Safari does not fire properly bubble click events on\n  // non-interactive elements, which means delegated click listeners do not\n  // fire. The workaround for this bug involves attaching an empty click\n  // listener on the target node.\n  // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n  // Just set it using the onclick property so that we don't have to manage any\n  // bookkeeping for it. Not sure if we need to clear it when the listener is\n  // removed.\n  // TODO: Only do this for the relevant Safaris maybe?\n  node.onclick = noop;\n}\n\nfunction setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {\n  for (var propKey in nextProps) {\n    if (!nextProps.hasOwnProperty(propKey)) {\n      continue;\n    }\n\n    var nextProp = nextProps[propKey];\n\n    if (propKey === STYLE) {\n      {\n        if (nextProp) {\n          // Freeze the next style object so that we can assume it won't be\n          // mutated. We have already warned for this in the past.\n          Object.freeze(nextProp);\n        }\n      } // Relies on `updateStylesByID` not mutating `styleUpdates`.\n\n\n      setValueForStyles(domElement, nextProp);\n    } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {\n      var nextHtml = nextProp ? nextProp[HTML$1] : undefined;\n\n      if (nextHtml != null) {\n        setInnerHTML(domElement, nextHtml);\n      }\n    } else if (propKey === CHILDREN) {\n      if (typeof nextProp === 'string') {\n        // Avoid setting initial textContent when the text is empty. In IE11 setting\n        // textContent on a <textarea> will cause the placeholder to not\n        // show within the <textarea> until it has been focused and blurred again.\n        // https://github.com/facebook/react/issues/6731#issuecomment-254874553\n        var canSetTextContent = tag !== 'textarea' || nextProp !== '';\n\n        if (canSetTextContent) {\n          setTextContent(domElement, nextProp);\n        }\n      } else if (typeof nextProp === 'number') {\n        setTextContent(domElement, '' + nextProp);\n      }\n    } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {\n      if (nextProp != null) {\n        if ( typeof nextProp !== 'function') {\n          warnForInvalidEventListener(propKey, nextProp);\n        }\n\n        ensureListeningTo(rootContainerElement, propKey);\n      }\n    } else if (nextProp != null) {\n      setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);\n    }\n  }\n}\n\nfunction updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {\n  // TODO: Handle wasCustomComponentTag\n  for (var i = 0; i < updatePayload.length; i += 2) {\n    var propKey = updatePayload[i];\n    var propValue = updatePayload[i + 1];\n\n    if (propKey === STYLE) {\n      setValueForStyles(domElement, propValue);\n    } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {\n      setInnerHTML(domElement, propValue);\n    } else if (propKey === CHILDREN) {\n      setTextContent(domElement, propValue);\n    } else {\n      setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);\n    }\n  }\n}\n\nfunction createElement(type, props, rootContainerElement, parentNamespace) {\n  var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML\n  // tags get no namespace.\n\n  var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);\n  var domElement;\n  var namespaceURI = parentNamespace;\n\n  if (namespaceURI === HTML_NAMESPACE$1) {\n    namespaceURI = getIntrinsicNamespace(type);\n  }\n\n  if (namespaceURI === HTML_NAMESPACE$1) {\n    {\n      isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to\n      // allow <SVG> or <mATH>.\n\n      if (!isCustomComponentTag && type !== type.toLowerCase()) {\n        error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);\n      }\n    }\n\n    if (type === 'script') {\n      // Create the script via .innerHTML so its \"parser-inserted\" flag is\n      // set to true and it does not execute\n      var div = ownerDocument.createElement('div');\n\n      div.innerHTML = '<script><' + '/script>'; // eslint-disable-line\n      // This is guaranteed to yield a script element.\n\n      var firstChild = div.firstChild;\n      domElement = div.removeChild(firstChild);\n    } else if (typeof props.is === 'string') {\n      // $FlowIssue `createElement` should be updated for Web Components\n      domElement = ownerDocument.createElement(type, {\n        is: props.is\n      });\n    } else {\n      // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.\n      // See discussion in https://github.com/facebook/react/pull/6896\n      // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240\n      domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`\n      // attributes on `select`s needs to be added before `option`s are inserted.\n      // This prevents:\n      // - a bug where the `select` does not scroll to the correct option because singular\n      //  `select` elements automatically pick the first item #13222\n      // - a bug where the `select` set the first item as selected despite the `size` attribute #14239\n      // See https://github.com/facebook/react/issues/13222\n      // and https://github.com/facebook/react/issues/14239\n\n      if (type === 'select') {\n        var node = domElement;\n\n        if (props.multiple) {\n          node.multiple = true;\n        } else if (props.size) {\n          // Setting a size greater than 1 causes a select to behave like `multiple=true`, where\n          // it is possible that no option is selected.\n          //\n          // This is only necessary when a select in \"single selection mode\".\n          node.size = props.size;\n        }\n      }\n    }\n  } else {\n    domElement = ownerDocument.createElementNS(namespaceURI, type);\n  }\n\n  {\n    if (namespaceURI === HTML_NAMESPACE$1) {\n      if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {\n        warnedUnknownTags[type] = true;\n\n        error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);\n      }\n    }\n  }\n\n  return domElement;\n}\nfunction createTextNode(text, rootContainerElement) {\n  return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);\n}\nfunction setInitialProperties(domElement, tag, rawProps, rootContainerElement) {\n  var isCustomComponentTag = isCustomComponent(tag, rawProps);\n\n  {\n    validatePropertiesInDevelopment(tag, rawProps);\n  } // TODO: Make sure that we check isMounted before firing any of these events.\n\n\n  var props;\n\n  switch (tag) {\n    case 'iframe':\n    case 'object':\n    case 'embed':\n      trapBubbledEvent(TOP_LOAD, domElement);\n      props = rawProps;\n      break;\n\n    case 'video':\n    case 'audio':\n      // Create listener for each media event\n      for (var i = 0; i < mediaEventTypes.length; i++) {\n        trapBubbledEvent(mediaEventTypes[i], domElement);\n      }\n\n      props = rawProps;\n      break;\n\n    case 'source':\n      trapBubbledEvent(TOP_ERROR, domElement);\n      props = rawProps;\n      break;\n\n    case 'img':\n    case 'image':\n    case 'link':\n      trapBubbledEvent(TOP_ERROR, domElement);\n      trapBubbledEvent(TOP_LOAD, domElement);\n      props = rawProps;\n      break;\n\n    case 'form':\n      trapBubbledEvent(TOP_RESET, domElement);\n      trapBubbledEvent(TOP_SUBMIT, domElement);\n      props = rawProps;\n      break;\n\n    case 'details':\n      trapBubbledEvent(TOP_TOGGLE, domElement);\n      props = rawProps;\n      break;\n\n    case 'input':\n      initWrapperState(domElement, rawProps);\n      props = getHostProps(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n\n    case 'option':\n      validateProps(domElement, rawProps);\n      props = getHostProps$1(domElement, rawProps);\n      break;\n\n    case 'select':\n      initWrapperState$1(domElement, rawProps);\n      props = getHostProps$2(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n\n    case 'textarea':\n      initWrapperState$2(domElement, rawProps);\n      props = getHostProps$3(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n\n    default:\n      props = rawProps;\n  }\n\n  assertValidProps(tag, props);\n  setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);\n\n  switch (tag) {\n    case 'input':\n      // TODO: Make sure we check if this is still unmounted or do any clean\n      // up necessary since we never stop tracking anymore.\n      track(domElement);\n      postMountWrapper(domElement, rawProps, false);\n      break;\n\n    case 'textarea':\n      // TODO: Make sure we check if this is still unmounted or do any clean\n      // up necessary since we never stop tracking anymore.\n      track(domElement);\n      postMountWrapper$3(domElement);\n      break;\n\n    case 'option':\n      postMountWrapper$1(domElement, rawProps);\n      break;\n\n    case 'select':\n      postMountWrapper$2(domElement, rawProps);\n      break;\n\n    default:\n      if (typeof props.onClick === 'function') {\n        // TODO: This cast may not be sound for SVG, MathML or custom elements.\n        trapClickOnNonInteractiveElement(domElement);\n      }\n\n      break;\n  }\n} // Calculate the diff between the two objects.\n\nfunction diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {\n  {\n    validatePropertiesInDevelopment(tag, nextRawProps);\n  }\n\n  var updatePayload = null;\n  var lastProps;\n  var nextProps;\n\n  switch (tag) {\n    case 'input':\n      lastProps = getHostProps(domElement, lastRawProps);\n      nextProps = getHostProps(domElement, nextRawProps);\n      updatePayload = [];\n      break;\n\n    case 'option':\n      lastProps = getHostProps$1(domElement, lastRawProps);\n      nextProps = getHostProps$1(domElement, nextRawProps);\n      updatePayload = [];\n      break;\n\n    case 'select':\n      lastProps = getHostProps$2(domElement, lastRawProps);\n      nextProps = getHostProps$2(domElement, nextRawProps);\n      updatePayload = [];\n      break;\n\n    case 'textarea':\n      lastProps = getHostProps$3(domElement, lastRawProps);\n      nextProps = getHostProps$3(domElement, nextRawProps);\n      updatePayload = [];\n      break;\n\n    default:\n      lastProps = lastRawProps;\n      nextProps = nextRawProps;\n\n      if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {\n        // TODO: This cast may not be sound for SVG, MathML or custom elements.\n        trapClickOnNonInteractiveElement(domElement);\n      }\n\n      break;\n  }\n\n  assertValidProps(tag, nextProps);\n  var propKey;\n  var styleName;\n  var styleUpdates = null;\n\n  for (propKey in lastProps) {\n    if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {\n      continue;\n    }\n\n    if (propKey === STYLE) {\n      var lastStyle = lastProps[propKey];\n\n      for (styleName in lastStyle) {\n        if (lastStyle.hasOwnProperty(styleName)) {\n          if (!styleUpdates) {\n            styleUpdates = {};\n          }\n\n          styleUpdates[styleName] = '';\n        }\n      }\n    } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {\n      // This is a special case. If any listener updates we need to ensure\n      // that the \"current\" fiber pointer gets updated so we need a commit\n      // to update this element.\n      if (!updatePayload) {\n        updatePayload = [];\n      }\n    } else {\n      // For all other deleted properties we add it to the queue. We use\n      // the whitelist in the commit phase instead.\n      (updatePayload = updatePayload || []).push(propKey, null);\n    }\n  }\n\n  for (propKey in nextProps) {\n    var nextProp = nextProps[propKey];\n    var lastProp = lastProps != null ? lastProps[propKey] : undefined;\n\n    if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {\n      continue;\n    }\n\n    if (propKey === STYLE) {\n      {\n        if (nextProp) {\n          // Freeze the next style object so that we can assume it won't be\n          // mutated. We have already warned for this in the past.\n          Object.freeze(nextProp);\n        }\n      }\n\n      if (lastProp) {\n        // Unset styles on `lastProp` but not on `nextProp`.\n        for (styleName in lastProp) {\n          if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {\n            if (!styleUpdates) {\n              styleUpdates = {};\n            }\n\n            styleUpdates[styleName] = '';\n          }\n        } // Update styles that changed since `lastProp`.\n\n\n        for (styleName in nextProp) {\n          if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {\n            if (!styleUpdates) {\n              styleUpdates = {};\n            }\n\n            styleUpdates[styleName] = nextProp[styleName];\n          }\n        }\n      } else {\n        // Relies on `updateStylesByID` not mutating `styleUpdates`.\n        if (!styleUpdates) {\n          if (!updatePayload) {\n            updatePayload = [];\n          }\n\n          updatePayload.push(propKey, styleUpdates);\n        }\n\n        styleUpdates = nextProp;\n      }\n    } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {\n      var nextHtml = nextProp ? nextProp[HTML$1] : undefined;\n      var lastHtml = lastProp ? lastProp[HTML$1] : undefined;\n\n      if (nextHtml != null) {\n        if (lastHtml !== nextHtml) {\n          (updatePayload = updatePayload || []).push(propKey, nextHtml);\n        }\n      }\n    } else if (propKey === CHILDREN) {\n      if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {\n        (updatePayload = updatePayload || []).push(propKey, '' + nextProp);\n      }\n    } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameModules.hasOwnProperty(propKey)) {\n      if (nextProp != null) {\n        // We eagerly listen to this even though we haven't committed yet.\n        if ( typeof nextProp !== 'function') {\n          warnForInvalidEventListener(propKey, nextProp);\n        }\n\n        ensureListeningTo(rootContainerElement, propKey);\n      }\n\n      if (!updatePayload && lastProp !== nextProp) {\n        // This is a special case. If any listener updates we need to ensure\n        // that the \"current\" props pointer gets updated so we need a commit\n        // to update this element.\n        updatePayload = [];\n      }\n    } else {\n      // For any other property we always add it to the queue and then we\n      // filter it out using the whitelist during the commit.\n      (updatePayload = updatePayload || []).push(propKey, nextProp);\n    }\n  }\n\n  if (styleUpdates) {\n    {\n      validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);\n    }\n\n    (updatePayload = updatePayload || []).push(STYLE, styleUpdates);\n  }\n\n  return updatePayload;\n} // Apply the diff.\n\nfunction updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {\n  // Update checked *before* name.\n  // In the middle of an update, it is possible to have multiple checked.\n  // When a checked radio tries to change name, browser makes another radio's checked false.\n  if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {\n    updateChecked(domElement, nextRawProps);\n  }\n\n  var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);\n  var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.\n\n  updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props\n  // changed.\n\n  switch (tag) {\n    case 'input':\n      // Update the wrapper around inputs *after* updating props. This has to\n      // happen after `updateDOMProperties`. Otherwise HTML5 input validations\n      // raise warnings and prevent the new value from being assigned.\n      updateWrapper(domElement, nextRawProps);\n      break;\n\n    case 'textarea':\n      updateWrapper$1(domElement, nextRawProps);\n      break;\n\n    case 'select':\n      // <select> value update needs to occur after <option> children\n      // reconciliation\n      postUpdateWrapper(domElement, nextRawProps);\n      break;\n  }\n}\n\nfunction getPossibleStandardName(propName) {\n  {\n    var lowerCasedName = propName.toLowerCase();\n\n    if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {\n      return null;\n    }\n\n    return possibleStandardNames[lowerCasedName] || null;\n  }\n}\n\nfunction diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {\n  var isCustomComponentTag;\n  var extraAttributeNames;\n\n  {\n    suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;\n    isCustomComponentTag = isCustomComponent(tag, rawProps);\n    validatePropertiesInDevelopment(tag, rawProps);\n  } // TODO: Make sure that we check isMounted before firing any of these events.\n\n\n  switch (tag) {\n    case 'iframe':\n    case 'object':\n    case 'embed':\n      trapBubbledEvent(TOP_LOAD, domElement);\n      break;\n\n    case 'video':\n    case 'audio':\n      // Create listener for each media event\n      for (var i = 0; i < mediaEventTypes.length; i++) {\n        trapBubbledEvent(mediaEventTypes[i], domElement);\n      }\n\n      break;\n\n    case 'source':\n      trapBubbledEvent(TOP_ERROR, domElement);\n      break;\n\n    case 'img':\n    case 'image':\n    case 'link':\n      trapBubbledEvent(TOP_ERROR, domElement);\n      trapBubbledEvent(TOP_LOAD, domElement);\n      break;\n\n    case 'form':\n      trapBubbledEvent(TOP_RESET, domElement);\n      trapBubbledEvent(TOP_SUBMIT, domElement);\n      break;\n\n    case 'details':\n      trapBubbledEvent(TOP_TOGGLE, domElement);\n      break;\n\n    case 'input':\n      initWrapperState(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n\n    case 'option':\n      validateProps(domElement, rawProps);\n      break;\n\n    case 'select':\n      initWrapperState$1(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n\n    case 'textarea':\n      initWrapperState$2(domElement, rawProps);\n      trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening\n      // to onChange. Even if there is no listener.\n\n      ensureListeningTo(rootContainerElement, 'onChange');\n      break;\n  }\n\n  assertValidProps(tag, rawProps);\n\n  {\n    extraAttributeNames = new Set();\n    var attributes = domElement.attributes;\n\n    for (var _i = 0; _i < attributes.length; _i++) {\n      var name = attributes[_i].name.toLowerCase();\n\n      switch (name) {\n        // Built-in SSR attribute is whitelisted\n        case 'data-reactroot':\n          break;\n        // Controlled attributes are not validated\n        // TODO: Only ignore them on controlled tags.\n\n        case 'value':\n          break;\n\n        case 'checked':\n          break;\n\n        case 'selected':\n          break;\n\n        default:\n          // Intentionally use the original name.\n          // See discussion in https://github.com/facebook/react/pull/10676.\n          extraAttributeNames.add(attributes[_i].name);\n      }\n    }\n  }\n\n  var updatePayload = null;\n\n  for (var propKey in rawProps) {\n    if (!rawProps.hasOwnProperty(propKey)) {\n      continue;\n    }\n\n    var nextProp = rawProps[propKey];\n\n    if (propKey === CHILDREN) {\n      // For text content children we compare against textContent. This\n      // might match additional HTML that is hidden when we read it using\n      // textContent. E.g. \"foo\" will match \"f<span>oo</span>\" but that still\n      // satisfies our requirement. Our requirement is not to produce perfect\n      // HTML and attributes. Ideally we should preserve structure but it's\n      // ok not to if the visible content is still enough to indicate what\n      // even listeners these nodes might be wired up to.\n      // TODO: Warn if there is more than a single textNode as a child.\n      // TODO: Should we use domElement.firstChild.nodeValue to compare?\n      if (typeof nextProp === 'string') {\n        if (domElement.textContent !== nextProp) {\n          if ( !suppressHydrationWarning) {\n            warnForTextDifference(domElement.textContent, nextProp);\n          }\n\n          updatePayload = [CHILDREN, nextProp];\n        }\n      } else if (typeof nextProp === 'number') {\n        if (domElement.textContent !== '' + nextProp) {\n          if ( !suppressHydrationWarning) {\n            warnForTextDifference(domElement.textContent, nextProp);\n          }\n\n          updatePayload = [CHILDREN, '' + nextProp];\n        }\n      }\n    } else if (registrationNameModules.hasOwnProperty(propKey)) {\n      if (nextProp != null) {\n        if ( typeof nextProp !== 'function') {\n          warnForInvalidEventListener(propKey, nextProp);\n        }\n\n        ensureListeningTo(rootContainerElement, propKey);\n      }\n    } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)\n    typeof isCustomComponentTag === 'boolean') {\n      // Validate that the properties correspond to their expected values.\n      var serverValue = void 0;\n      var propertyInfo = getPropertyInfo(propKey);\n\n      if (suppressHydrationWarning) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated\n      // TODO: Only ignore them on controlled tags.\n      propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {\n        var serverHTML = domElement.innerHTML;\n        var nextHtml = nextProp ? nextProp[HTML$1] : undefined;\n        var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');\n\n        if (expectedHTML !== serverHTML) {\n          warnForPropDifference(propKey, serverHTML, expectedHTML);\n        }\n      } else if (propKey === STYLE) {\n        // $FlowFixMe - Should be inferred as not undefined.\n        extraAttributeNames.delete(propKey);\n\n        if (canDiffStyleForHydrationWarning) {\n          var expectedStyle = createDangerousStringForStyles(nextProp);\n          serverValue = domElement.getAttribute('style');\n\n          if (expectedStyle !== serverValue) {\n            warnForPropDifference(propKey, serverValue, expectedStyle);\n          }\n        }\n      } else if (isCustomComponentTag) {\n        // $FlowFixMe - Should be inferred as not undefined.\n        extraAttributeNames.delete(propKey.toLowerCase());\n        serverValue = getValueForAttribute(domElement, propKey, nextProp);\n\n        if (nextProp !== serverValue) {\n          warnForPropDifference(propKey, serverValue, nextProp);\n        }\n      } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {\n        var isMismatchDueToBadCasing = false;\n\n        if (propertyInfo !== null) {\n          // $FlowFixMe - Should be inferred as not undefined.\n          extraAttributeNames.delete(propertyInfo.attributeName);\n          serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);\n        } else {\n          var ownNamespace = parentNamespace;\n\n          if (ownNamespace === HTML_NAMESPACE$1) {\n            ownNamespace = getIntrinsicNamespace(tag);\n          }\n\n          if (ownNamespace === HTML_NAMESPACE$1) {\n            // $FlowFixMe - Should be inferred as not undefined.\n            extraAttributeNames.delete(propKey.toLowerCase());\n          } else {\n            var standardName = getPossibleStandardName(propKey);\n\n            if (standardName !== null && standardName !== propKey) {\n              // If an SVG prop is supplied with bad casing, it will\n              // be successfully parsed from HTML, but will produce a mismatch\n              // (and would be incorrectly rendered on the client).\n              // However, we already warn about bad casing elsewhere.\n              // So we'll skip the misleading extra mismatch warning in this case.\n              isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.\n\n              extraAttributeNames.delete(standardName);\n            } // $FlowFixMe - Should be inferred as not undefined.\n\n\n            extraAttributeNames.delete(propKey);\n          }\n\n          serverValue = getValueForAttribute(domElement, propKey, nextProp);\n        }\n\n        if (nextProp !== serverValue && !isMismatchDueToBadCasing) {\n          warnForPropDifference(propKey, serverValue, nextProp);\n        }\n      }\n    }\n  }\n\n  {\n    // $FlowFixMe - Should be inferred as not undefined.\n    if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {\n      // $FlowFixMe - Should be inferred as not undefined.\n      warnForExtraAttributes(extraAttributeNames);\n    }\n  }\n\n  switch (tag) {\n    case 'input':\n      // TODO: Make sure we check if this is still unmounted or do any clean\n      // up necessary since we never stop tracking anymore.\n      track(domElement);\n      postMountWrapper(domElement, rawProps, true);\n      break;\n\n    case 'textarea':\n      // TODO: Make sure we check if this is still unmounted or do any clean\n      // up necessary since we never stop tracking anymore.\n      track(domElement);\n      postMountWrapper$3(domElement);\n      break;\n\n    case 'select':\n    case 'option':\n      // For input and textarea we current always set the value property at\n      // post mount to force it to diverge from attributes. However, for\n      // option and select we don't quite do the same thing and select\n      // is not resilient to the DOM state changing so we don't do that here.\n      // TODO: Consider not doing this for input and textarea.\n      break;\n\n    default:\n      if (typeof rawProps.onClick === 'function') {\n        // TODO: This cast may not be sound for SVG, MathML or custom elements.\n        trapClickOnNonInteractiveElement(domElement);\n      }\n\n      break;\n  }\n\n  return updatePayload;\n}\nfunction diffHydratedText(textNode, text) {\n  var isDifferent = textNode.nodeValue !== text;\n  return isDifferent;\n}\nfunction warnForUnmatchedText(textNode, text) {\n  {\n    warnForTextDifference(textNode.nodeValue, text);\n  }\n}\nfunction warnForDeletedHydratableElement(parentNode, child) {\n  {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());\n  }\n}\nfunction warnForDeletedHydratableText(parentNode, child) {\n  {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Did not expect server HTML to contain the text node \"%s\" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());\n  }\n}\nfunction warnForInsertedHydratedElement(parentNode, tag, props) {\n  {\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());\n  }\n}\nfunction warnForInsertedHydratedText(parentNode, text) {\n  {\n    if (text === '') {\n      // We expect to insert empty text nodes since they're not represented in\n      // the HTML.\n      // TODO: Remove this special case if we can just avoid inserting empty\n      // text nodes.\n      return;\n    }\n\n    if (didWarnInvalidHydration) {\n      return;\n    }\n\n    didWarnInvalidHydration = true;\n\n    error('Expected server HTML to contain a matching text node for \"%s\" in <%s>.', text, parentNode.nodeName.toLowerCase());\n  }\n}\nfunction restoreControlledState$3(domElement, tag, props) {\n  switch (tag) {\n    case 'input':\n      restoreControlledState(domElement, props);\n      return;\n\n    case 'textarea':\n      restoreControlledState$2(domElement, props);\n      return;\n\n    case 'select':\n      restoreControlledState$1(domElement, props);\n      return;\n  }\n}\n\nfunction getActiveElement(doc) {\n  doc = doc || (typeof document !== 'undefined' ? document : undefined);\n\n  if (typeof doc === 'undefined') {\n    return null;\n  }\n\n  try {\n    return doc.activeElement || doc.body;\n  } catch (e) {\n    return doc.body;\n  }\n}\n\n/**\n * Given any node return the first leaf node without children.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {DOMElement|DOMTextNode}\n */\n\nfunction getLeafNode(node) {\n  while (node && node.firstChild) {\n    node = node.firstChild;\n  }\n\n  return node;\n}\n/**\n * Get the next sibling within a container. This will walk up the\n * DOM if a node's siblings have been exhausted.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {?DOMElement|DOMTextNode}\n */\n\n\nfunction getSiblingNode(node) {\n  while (node) {\n    if (node.nextSibling) {\n      return node.nextSibling;\n    }\n\n    node = node.parentNode;\n  }\n}\n/**\n * Get object describing the nodes which contain characters at offset.\n *\n * @param {DOMElement|DOMTextNode} root\n * @param {number} offset\n * @return {?object}\n */\n\n\nfunction getNodeForCharacterOffset(root, offset) {\n  var node = getLeafNode(root);\n  var nodeStart = 0;\n  var nodeEnd = 0;\n\n  while (node) {\n    if (node.nodeType === TEXT_NODE) {\n      nodeEnd = nodeStart + node.textContent.length;\n\n      if (nodeStart <= offset && nodeEnd >= offset) {\n        return {\n          node: node,\n          offset: offset - nodeStart\n        };\n      }\n\n      nodeStart = nodeEnd;\n    }\n\n    node = getLeafNode(getSiblingNode(node));\n  }\n}\n\n/**\n * @param {DOMElement} outerNode\n * @return {?object}\n */\n\nfunction getOffsets(outerNode) {\n  var ownerDocument = outerNode.ownerDocument;\n  var win = ownerDocument && ownerDocument.defaultView || window;\n  var selection = win.getSelection && win.getSelection();\n\n  if (!selection || selection.rangeCount === 0) {\n    return null;\n  }\n\n  var anchorNode = selection.anchorNode,\n      anchorOffset = selection.anchorOffset,\n      focusNode = selection.focusNode,\n      focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be \"anonymous divs\", e.g. the\n  // up/down buttons on an <input type=\"number\">. Anonymous divs do not seem to\n  // expose properties, triggering a \"Permission denied error\" if any of its\n  // properties are accessed. The only seemingly possible way to avoid erroring\n  // is to access a property that typically works for non-anonymous divs and\n  // catch any error that may otherwise arise. See\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=208427\n\n  try {\n    /* eslint-disable no-unused-expressions */\n    anchorNode.nodeType;\n    focusNode.nodeType;\n    /* eslint-enable no-unused-expressions */\n  } catch (e) {\n    return null;\n  }\n\n  return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);\n}\n/**\n * Returns {start, end} where `start` is the character/codepoint index of\n * (anchorNode, anchorOffset) within the textContent of `outerNode`, and\n * `end` is the index of (focusNode, focusOffset).\n *\n * Returns null if you pass in garbage input but we should probably just crash.\n *\n * Exported only for testing.\n */\n\nfunction getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {\n  var length = 0;\n  var start = -1;\n  var end = -1;\n  var indexWithinAnchor = 0;\n  var indexWithinFocus = 0;\n  var node = outerNode;\n  var parentNode = null;\n\n  outer: while (true) {\n    var next = null;\n\n    while (true) {\n      if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {\n        start = length + anchorOffset;\n      }\n\n      if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {\n        end = length + focusOffset;\n      }\n\n      if (node.nodeType === TEXT_NODE) {\n        length += node.nodeValue.length;\n      }\n\n      if ((next = node.firstChild) === null) {\n        break;\n      } // Moving from `node` to its first child `next`.\n\n\n      parentNode = node;\n      node = next;\n    }\n\n    while (true) {\n      if (node === outerNode) {\n        // If `outerNode` has children, this is always the second time visiting\n        // it. If it has no children, this is still the first loop, and the only\n        // valid selection is anchorNode and focusNode both equal to this node\n        // and both offsets 0, in which case we will have handled above.\n        break outer;\n      }\n\n      if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {\n        start = length;\n      }\n\n      if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {\n        end = length;\n      }\n\n      if ((next = node.nextSibling) !== null) {\n        break;\n      }\n\n      node = parentNode;\n      parentNode = node.parentNode;\n    } // Moving from `node` to its next sibling `next`.\n\n\n    node = next;\n  }\n\n  if (start === -1 || end === -1) {\n    // This should never happen. (Would happen if the anchor/focus nodes aren't\n    // actually inside the passed-in node.)\n    return null;\n  }\n\n  return {\n    start: start,\n    end: end\n  };\n}\n/**\n * In modern non-IE browsers, we can support both forward and backward\n * selections.\n *\n * Note: IE10+ supports the Selection object, but it does not support\n * the `extend` method, which means that even in modern IE, it's not possible\n * to programmatically create a backward selection. Thus, for all IE\n * versions, we use the old IE API to create our selections.\n *\n * @param {DOMElement|DOMTextNode} node\n * @param {object} offsets\n */\n\nfunction setOffsets(node, offsets) {\n  var doc = node.ownerDocument || document;\n  var win = doc && doc.defaultView || window; // Edge fails with \"Object expected\" in some scenarios.\n  // (For instance: TinyMCE editor used in a list component that supports pasting to add more,\n  // fails when pasting 100+ items)\n\n  if (!win.getSelection) {\n    return;\n  }\n\n  var selection = win.getSelection();\n  var length = node.textContent.length;\n  var start = Math.min(offsets.start, length);\n  var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.\n  // Flip backward selections, so we can set with a single range.\n\n  if (!selection.extend && start > end) {\n    var temp = end;\n    end = start;\n    start = temp;\n  }\n\n  var startMarker = getNodeForCharacterOffset(node, start);\n  var endMarker = getNodeForCharacterOffset(node, end);\n\n  if (startMarker && endMarker) {\n    if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {\n      return;\n    }\n\n    var range = doc.createRange();\n    range.setStart(startMarker.node, startMarker.offset);\n    selection.removeAllRanges();\n\n    if (start > end) {\n      selection.addRange(range);\n      selection.extend(endMarker.node, endMarker.offset);\n    } else {\n      range.setEnd(endMarker.node, endMarker.offset);\n      selection.addRange(range);\n    }\n  }\n}\n\nfunction isTextNode(node) {\n  return node && node.nodeType === TEXT_NODE;\n}\n\nfunction containsNode(outerNode, innerNode) {\n  if (!outerNode || !innerNode) {\n    return false;\n  } else if (outerNode === innerNode) {\n    return true;\n  } else if (isTextNode(outerNode)) {\n    return false;\n  } else if (isTextNode(innerNode)) {\n    return containsNode(outerNode, innerNode.parentNode);\n  } else if ('contains' in outerNode) {\n    return outerNode.contains(innerNode);\n  } else if (outerNode.compareDocumentPosition) {\n    return !!(outerNode.compareDocumentPosition(innerNode) & 16);\n  } else {\n    return false;\n  }\n}\n\nfunction isInDocument(node) {\n  return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);\n}\n\nfunction isSameOriginFrame(iframe) {\n  try {\n    // Accessing the contentDocument of a HTMLIframeElement can cause the browser\n    // to throw, e.g. if it has a cross-origin src attribute.\n    // Safari will show an error in the console when the access results in \"Blocked a frame with origin\". e.g:\n    // iframe.contentDocument.defaultView;\n    // A safety way is to access one of the cross origin properties: Window or Location\n    // Which might result in \"SecurityError\" DOM Exception and it is compatible to Safari.\n    // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl\n    return typeof iframe.contentWindow.location.href === 'string';\n  } catch (err) {\n    return false;\n  }\n}\n\nfunction getActiveElementDeep() {\n  var win = window;\n  var element = getActiveElement();\n\n  while (element instanceof win.HTMLIFrameElement) {\n    if (isSameOriginFrame(element)) {\n      win = element.contentWindow;\n    } else {\n      return element;\n    }\n\n    element = getActiveElement(win.document);\n  }\n\n  return element;\n}\n/**\n * @ReactInputSelection: React input selection module. Based on Selection.js,\n * but modified to be suitable for react and has a couple of bug fixes (doesn't\n * assume buttons have range selections allowed).\n * Input selection module for React.\n */\n\n/**\n * @hasSelectionCapabilities: we get the element types that support selection\n * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`\n * and `selectionEnd` rows.\n */\n\n\nfunction hasSelectionCapabilities(elem) {\n  var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n  return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');\n}\nfunction getSelectionInformation() {\n  var focusedElem = getActiveElementDeep();\n  return {\n    // Used by Flare\n    activeElementDetached: null,\n    focusedElem: focusedElem,\n    selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null\n  };\n}\n/**\n * @restoreSelection: If any selection information was potentially lost,\n * restore it. This is useful when performing operations that could remove dom\n * nodes and place them back in, resulting in focus being lost.\n */\n\nfunction restoreSelection(priorSelectionInformation) {\n  var curFocusedElem = getActiveElementDeep();\n  var priorFocusedElem = priorSelectionInformation.focusedElem;\n  var priorSelectionRange = priorSelectionInformation.selectionRange;\n\n  if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {\n    if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {\n      setSelection(priorFocusedElem, priorSelectionRange);\n    } // Focusing a node can change the scroll position, which is undesirable\n\n\n    var ancestors = [];\n    var ancestor = priorFocusedElem;\n\n    while (ancestor = ancestor.parentNode) {\n      if (ancestor.nodeType === ELEMENT_NODE) {\n        ancestors.push({\n          element: ancestor,\n          left: ancestor.scrollLeft,\n          top: ancestor.scrollTop\n        });\n      }\n    }\n\n    if (typeof priorFocusedElem.focus === 'function') {\n      priorFocusedElem.focus();\n    }\n\n    for (var i = 0; i < ancestors.length; i++) {\n      var info = ancestors[i];\n      info.element.scrollLeft = info.left;\n      info.element.scrollTop = info.top;\n    }\n  }\n}\n/**\n * @getSelection: Gets the selection bounds of a focused textarea, input or\n * contentEditable node.\n * -@input: Look up selection bounds of this input\n * -@return {start: selectionStart, end: selectionEnd}\n */\n\nfunction getSelection(input) {\n  var selection;\n\n  if ('selectionStart' in input) {\n    // Modern browser with input or textarea.\n    selection = {\n      start: input.selectionStart,\n      end: input.selectionEnd\n    };\n  } else {\n    // Content editable or old IE textarea.\n    selection = getOffsets(input);\n  }\n\n  return selection || {\n    start: 0,\n    end: 0\n  };\n}\n/**\n * @setSelection: Sets the selection bounds of a textarea or input and focuses\n * the input.\n * -@input     Set selection bounds of this input or textarea\n * -@offsets   Object of same form that is returned from get*\n */\n\nfunction setSelection(input, offsets) {\n  var start = offsets.start,\n      end = offsets.end;\n\n  if (end === undefined) {\n    end = start;\n  }\n\n  if ('selectionStart' in input) {\n    input.selectionStart = start;\n    input.selectionEnd = Math.min(end, input.value.length);\n  } else {\n    setOffsets(input, offsets);\n  }\n}\n\nvar validateDOMNesting = function () {};\n\nvar updatedAncestorInfo = function () {};\n\n{\n  // This validation code was written based on the HTML5 parsing spec:\n  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope\n  //\n  // Note: this does not catch all invalid nesting, nor does it try to (as it's\n  // not clear what practical benefit doing so provides); instead, we warn only\n  // for cases where the parser will give a parse tree differing from what React\n  // intended. For example, <b><div></div></b> is invalid but we don't warn\n  // because it still parses correctly; we do warn for other cases like nested\n  // <p> tags where the beginning of the second element implicitly closes the\n  // first, causing a confusing mess.\n  // https://html.spec.whatwg.org/multipage/syntax.html#special\n  var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope\n\n  var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point\n  // TODO: Distinguish by namespace here -- for <title>, including it here\n  // errs on the side of fewer warnings\n  'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope\n\n  var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags\n\n  var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];\n  var emptyAncestorInfo = {\n    current: null,\n    formTag: null,\n    aTagInScope: null,\n    buttonTagInScope: null,\n    nobrTagInScope: null,\n    pTagInButtonScope: null,\n    listItemTagAutoclosing: null,\n    dlItemTagAutoclosing: null\n  };\n\n  updatedAncestorInfo = function (oldInfo, tag) {\n    var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);\n\n    var info = {\n      tag: tag\n    };\n\n    if (inScopeTags.indexOf(tag) !== -1) {\n      ancestorInfo.aTagInScope = null;\n      ancestorInfo.buttonTagInScope = null;\n      ancestorInfo.nobrTagInScope = null;\n    }\n\n    if (buttonScopeTags.indexOf(tag) !== -1) {\n      ancestorInfo.pTagInButtonScope = null;\n    } // See rules for 'li', 'dd', 'dt' start tags in\n    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody\n\n\n    if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {\n      ancestorInfo.listItemTagAutoclosing = null;\n      ancestorInfo.dlItemTagAutoclosing = null;\n    }\n\n    ancestorInfo.current = info;\n\n    if (tag === 'form') {\n      ancestorInfo.formTag = info;\n    }\n\n    if (tag === 'a') {\n      ancestorInfo.aTagInScope = info;\n    }\n\n    if (tag === 'button') {\n      ancestorInfo.buttonTagInScope = info;\n    }\n\n    if (tag === 'nobr') {\n      ancestorInfo.nobrTagInScope = info;\n    }\n\n    if (tag === 'p') {\n      ancestorInfo.pTagInButtonScope = info;\n    }\n\n    if (tag === 'li') {\n      ancestorInfo.listItemTagAutoclosing = info;\n    }\n\n    if (tag === 'dd' || tag === 'dt') {\n      ancestorInfo.dlItemTagAutoclosing = info;\n    }\n\n    return ancestorInfo;\n  };\n  /**\n   * Returns whether\n   */\n\n\n  var isTagValidWithParent = function (tag, parentTag) {\n    // First, let's check if we're in an unusual parsing mode...\n    switch (parentTag) {\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect\n      case 'select':\n        return tag === 'option' || tag === 'optgroup' || tag === '#text';\n\n      case 'optgroup':\n        return tag === 'option' || tag === '#text';\n      // Strictly speaking, seeing an <option> doesn't mean we're in a <select>\n      // but\n\n      case 'option':\n        return tag === '#text';\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption\n      // No special behavior since these rules fall back to \"in body\" mode for\n      // all except special table nodes which cause bad parsing behavior anyway.\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr\n\n      case 'tr':\n        return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody\n\n      case 'tbody':\n      case 'thead':\n      case 'tfoot':\n        return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup\n\n      case 'colgroup':\n        return tag === 'col' || tag === 'template';\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable\n\n      case 'table':\n        return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead\n\n      case 'head':\n        return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';\n      // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element\n\n      case 'html':\n        return tag === 'head' || tag === 'body' || tag === 'frameset';\n\n      case 'frameset':\n        return tag === 'frame';\n\n      case '#document':\n        return tag === 'html';\n    } // Probably in the \"in body\" parsing mode, so we outlaw only tag combos\n    // where the parsing rules cause implicit opens or closes to be added.\n    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody\n\n\n    switch (tag) {\n      case 'h1':\n      case 'h2':\n      case 'h3':\n      case 'h4':\n      case 'h5':\n      case 'h6':\n        return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';\n\n      case 'rp':\n      case 'rt':\n        return impliedEndTags.indexOf(parentTag) === -1;\n\n      case 'body':\n      case 'caption':\n      case 'col':\n      case 'colgroup':\n      case 'frameset':\n      case 'frame':\n      case 'head':\n      case 'html':\n      case 'tbody':\n      case 'td':\n      case 'tfoot':\n      case 'th':\n      case 'thead':\n      case 'tr':\n        // These tags are only valid with a few parents that have special child\n        // parsing rules -- if we're down here, then none of those matched and\n        // so we allow it only if we don't know what the parent is, as all other\n        // cases are invalid.\n        return parentTag == null;\n    }\n\n    return true;\n  };\n  /**\n   * Returns whether\n   */\n\n\n  var findInvalidAncestorForTag = function (tag, ancestorInfo) {\n    switch (tag) {\n      case 'address':\n      case 'article':\n      case 'aside':\n      case 'blockquote':\n      case 'center':\n      case 'details':\n      case 'dialog':\n      case 'dir':\n      case 'div':\n      case 'dl':\n      case 'fieldset':\n      case 'figcaption':\n      case 'figure':\n      case 'footer':\n      case 'header':\n      case 'hgroup':\n      case 'main':\n      case 'menu':\n      case 'nav':\n      case 'ol':\n      case 'p':\n      case 'section':\n      case 'summary':\n      case 'ul':\n      case 'pre':\n      case 'listing':\n      case 'table':\n      case 'hr':\n      case 'xmp':\n      case 'h1':\n      case 'h2':\n      case 'h3':\n      case 'h4':\n      case 'h5':\n      case 'h6':\n        return ancestorInfo.pTagInButtonScope;\n\n      case 'form':\n        return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;\n\n      case 'li':\n        return ancestorInfo.listItemTagAutoclosing;\n\n      case 'dd':\n      case 'dt':\n        return ancestorInfo.dlItemTagAutoclosing;\n\n      case 'button':\n        return ancestorInfo.buttonTagInScope;\n\n      case 'a':\n        // Spec says something about storing a list of markers, but it sounds\n        // equivalent to this check.\n        return ancestorInfo.aTagInScope;\n\n      case 'nobr':\n        return ancestorInfo.nobrTagInScope;\n    }\n\n    return null;\n  };\n\n  var didWarn$1 = {};\n\n  validateDOMNesting = function (childTag, childText, ancestorInfo) {\n    ancestorInfo = ancestorInfo || emptyAncestorInfo;\n    var parentInfo = ancestorInfo.current;\n    var parentTag = parentInfo && parentInfo.tag;\n\n    if (childText != null) {\n      if (childTag != null) {\n        error('validateDOMNesting: when childText is passed, childTag should be null');\n      }\n\n      childTag = '#text';\n    }\n\n    var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;\n    var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);\n    var invalidParentOrAncestor = invalidParent || invalidAncestor;\n\n    if (!invalidParentOrAncestor) {\n      return;\n    }\n\n    var ancestorTag = invalidParentOrAncestor.tag;\n    var addendum = getCurrentFiberStackInDev();\n    var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;\n\n    if (didWarn$1[warnKey]) {\n      return;\n    }\n\n    didWarn$1[warnKey] = true;\n    var tagDisplayName = childTag;\n    var whitespaceInfo = '';\n\n    if (childTag === '#text') {\n      if (/\\S/.test(childText)) {\n        tagDisplayName = 'Text nodes';\n      } else {\n        tagDisplayName = 'Whitespace text nodes';\n        whitespaceInfo = \" Make sure you don't have any extra whitespace between tags on \" + 'each line of your source code.';\n      }\n    } else {\n      tagDisplayName = '<' + childTag + '>';\n    }\n\n    if (invalidParent) {\n      var info = '';\n\n      if (ancestorTag === 'table' && childTag === 'tr') {\n        info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';\n      }\n\n      error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);\n    } else {\n      error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);\n    }\n  };\n}\n\nvar SUPPRESS_HYDRATION_WARNING$1;\n\n{\n  SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';\n}\n\nvar SUSPENSE_START_DATA = '$';\nvar SUSPENSE_END_DATA = '/$';\nvar SUSPENSE_PENDING_START_DATA = '$?';\nvar SUSPENSE_FALLBACK_START_DATA = '$!';\nvar STYLE$1 = 'style';\nvar eventsEnabled = null;\nvar selectionInformation = null;\n\nfunction shouldAutoFocusHostComponent(type, props) {\n  switch (type) {\n    case 'button':\n    case 'input':\n    case 'select':\n    case 'textarea':\n      return !!props.autoFocus;\n  }\n\n  return false;\n}\nfunction getRootHostContext(rootContainerInstance) {\n  var type;\n  var namespace;\n  var nodeType = rootContainerInstance.nodeType;\n\n  switch (nodeType) {\n    case DOCUMENT_NODE:\n    case DOCUMENT_FRAGMENT_NODE:\n      {\n        type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';\n        var root = rootContainerInstance.documentElement;\n        namespace = root ? root.namespaceURI : getChildNamespace(null, '');\n        break;\n      }\n\n    default:\n      {\n        var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;\n        var ownNamespace = container.namespaceURI || null;\n        type = container.tagName;\n        namespace = getChildNamespace(ownNamespace, type);\n        break;\n      }\n  }\n\n  {\n    var validatedTag = type.toLowerCase();\n    var ancestorInfo = updatedAncestorInfo(null, validatedTag);\n    return {\n      namespace: namespace,\n      ancestorInfo: ancestorInfo\n    };\n  }\n}\nfunction getChildHostContext(parentHostContext, type, rootContainerInstance) {\n  {\n    var parentHostContextDev = parentHostContext;\n    var namespace = getChildNamespace(parentHostContextDev.namespace, type);\n    var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);\n    return {\n      namespace: namespace,\n      ancestorInfo: ancestorInfo\n    };\n  }\n}\nfunction getPublicInstance(instance) {\n  return instance;\n}\nfunction prepareForCommit(containerInfo) {\n  eventsEnabled = isEnabled();\n  selectionInformation = getSelectionInformation();\n  setEnabled(false);\n}\nfunction resetAfterCommit(containerInfo) {\n  restoreSelection(selectionInformation);\n  setEnabled(eventsEnabled);\n  eventsEnabled = null;\n\n  selectionInformation = null;\n}\nfunction createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {\n  var parentNamespace;\n\n  {\n    // TODO: take namespace into account when validating.\n    var hostContextDev = hostContext;\n    validateDOMNesting(type, null, hostContextDev.ancestorInfo);\n\n    if (typeof props.children === 'string' || typeof props.children === 'number') {\n      var string = '' + props.children;\n      var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);\n      validateDOMNesting(null, string, ownAncestorInfo);\n    }\n\n    parentNamespace = hostContextDev.namespace;\n  }\n\n  var domElement = createElement(type, props, rootContainerInstance, parentNamespace);\n  precacheFiberNode(internalInstanceHandle, domElement);\n  updateFiberProps(domElement, props);\n  return domElement;\n}\nfunction appendInitialChild(parentInstance, child) {\n  parentInstance.appendChild(child);\n}\nfunction finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {\n  setInitialProperties(domElement, type, props, rootContainerInstance);\n  return shouldAutoFocusHostComponent(type, props);\n}\nfunction prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {\n  {\n    var hostContextDev = hostContext;\n\n    if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {\n      var string = '' + newProps.children;\n      var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);\n      validateDOMNesting(null, string, ownAncestorInfo);\n    }\n  }\n\n  return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);\n}\nfunction shouldSetTextContent(type, props) {\n  return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;\n}\nfunction shouldDeprioritizeSubtree(type, props) {\n  return !!props.hidden;\n}\nfunction createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {\n  {\n    var hostContextDev = hostContext;\n    validateDOMNesting(null, text, hostContextDev.ancestorInfo);\n  }\n\n  var textNode = createTextNode(text, rootContainerInstance);\n  precacheFiberNode(internalInstanceHandle, textNode);\n  return textNode;\n}\n// if a component just imports ReactDOM (e.g. for findDOMNode).\n// Some environments might not have setTimeout or clearTimeout.\n\nvar scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;\nvar cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;\nvar noTimeout = -1; // -------------------\nfunction commitMount(domElement, type, newProps, internalInstanceHandle) {\n  // Despite the naming that might imply otherwise, this method only\n  // fires if there is an `Update` effect scheduled during mounting.\n  // This happens if `finalizeInitialChildren` returns `true` (which it\n  // does to implement the `autoFocus` attribute on the client). But\n  // there are also other cases when this might happen (such as patching\n  // up text content during hydration mismatch). So we'll check this again.\n  if (shouldAutoFocusHostComponent(type, newProps)) {\n    domElement.focus();\n  }\n}\nfunction commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {\n  // Update the props handle so that we know which props are the ones with\n  // with current event handlers.\n  updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.\n\n  updateProperties(domElement, updatePayload, type, oldProps, newProps);\n}\nfunction resetTextContent(domElement) {\n  setTextContent(domElement, '');\n}\nfunction commitTextUpdate(textInstance, oldText, newText) {\n  textInstance.nodeValue = newText;\n}\nfunction appendChild(parentInstance, child) {\n  parentInstance.appendChild(child);\n}\nfunction appendChildToContainer(container, child) {\n  var parentNode;\n\n  if (container.nodeType === COMMENT_NODE) {\n    parentNode = container.parentNode;\n    parentNode.insertBefore(child, container);\n  } else {\n    parentNode = container;\n    parentNode.appendChild(child);\n  } // This container might be used for a portal.\n  // If something inside a portal is clicked, that click should bubble\n  // through the React tree. However, on Mobile Safari the click would\n  // never bubble through the *DOM* tree unless an ancestor with onclick\n  // event exists. So we wouldn't see it and dispatch it.\n  // This is why we ensure that non React root containers have inline onclick\n  // defined.\n  // https://github.com/facebook/react/issues/11918\n\n\n  var reactRootContainer = container._reactRootContainer;\n\n  if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {\n    // TODO: This cast may not be sound for SVG, MathML or custom elements.\n    trapClickOnNonInteractiveElement(parentNode);\n  }\n}\nfunction insertBefore(parentInstance, child, beforeChild) {\n  parentInstance.insertBefore(child, beforeChild);\n}\nfunction insertInContainerBefore(container, child, beforeChild) {\n  if (container.nodeType === COMMENT_NODE) {\n    container.parentNode.insertBefore(child, beforeChild);\n  } else {\n    container.insertBefore(child, beforeChild);\n  }\n}\nfunction removeChild(parentInstance, child) {\n  parentInstance.removeChild(child);\n}\nfunction removeChildFromContainer(container, child) {\n  if (container.nodeType === COMMENT_NODE) {\n    container.parentNode.removeChild(child);\n  } else {\n    container.removeChild(child);\n  }\n}\n\nfunction hideInstance(instance) {\n  // pass host context to this method?\n\n\n  instance = instance;\n  var style = instance.style;\n\n  if (typeof style.setProperty === 'function') {\n    style.setProperty('display', 'none', 'important');\n  } else {\n    style.display = 'none';\n  }\n}\nfunction hideTextInstance(textInstance) {\n  textInstance.nodeValue = '';\n}\nfunction unhideInstance(instance, props) {\n  instance = instance;\n  var styleProp = props[STYLE$1];\n  var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;\n  instance.style.display = dangerousStyleValue('display', display);\n}\nfunction unhideTextInstance(textInstance, text) {\n  textInstance.nodeValue = text;\n} // -------------------\nfunction canHydrateInstance(instance, type, props) {\n  if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {\n    return null;\n  } // This has now been refined to an element node.\n\n\n  return instance;\n}\nfunction canHydrateTextInstance(instance, text) {\n  if (text === '' || instance.nodeType !== TEXT_NODE) {\n    // Empty strings are not parsed by HTML so there won't be a correct match here.\n    return null;\n  } // This has now been refined to a text node.\n\n\n  return instance;\n}\nfunction isSuspenseInstancePending(instance) {\n  return instance.data === SUSPENSE_PENDING_START_DATA;\n}\nfunction isSuspenseInstanceFallback(instance) {\n  return instance.data === SUSPENSE_FALLBACK_START_DATA;\n}\n\nfunction getNextHydratable(node) {\n  // Skip non-hydratable nodes.\n  for (; node != null; node = node.nextSibling) {\n    var nodeType = node.nodeType;\n\n    if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {\n      break;\n    }\n  }\n\n  return node;\n}\n\nfunction getNextHydratableSibling(instance) {\n  return getNextHydratable(instance.nextSibling);\n}\nfunction getFirstHydratableChild(parentInstance) {\n  return getNextHydratable(parentInstance.firstChild);\n}\nfunction hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {\n  precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events\n  // get attached.\n\n  updateFiberProps(instance, props);\n  var parentNamespace;\n\n  {\n    var hostContextDev = hostContext;\n    parentNamespace = hostContextDev.namespace;\n  }\n\n  return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);\n}\nfunction hydrateTextInstance(textInstance, text, internalInstanceHandle) {\n  precacheFiberNode(internalInstanceHandle, textInstance);\n  return diffHydratedText(textInstance, text);\n}\nfunction getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {\n  var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.\n  // There might be nested nodes so we need to keep track of how\n  // deep we are and only break out when we're back on top.\n\n  var depth = 0;\n\n  while (node) {\n    if (node.nodeType === COMMENT_NODE) {\n      var data = node.data;\n\n      if (data === SUSPENSE_END_DATA) {\n        if (depth === 0) {\n          return getNextHydratableSibling(node);\n        } else {\n          depth--;\n        }\n      } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {\n        depth++;\n      }\n    }\n\n    node = node.nextSibling;\n  } // TODO: Warn, we didn't find the end comment boundary.\n\n\n  return null;\n} // Returns the SuspenseInstance if this node is a direct child of a\n// SuspenseInstance. I.e. if its previous sibling is a Comment with\n// SUSPENSE_x_START_DATA. Otherwise, null.\n\nfunction getParentSuspenseInstance(targetInstance) {\n  var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.\n  // There might be nested nodes so we need to keep track of how\n  // deep we are and only break out when we're back on top.\n\n  var depth = 0;\n\n  while (node) {\n    if (node.nodeType === COMMENT_NODE) {\n      var data = node.data;\n\n      if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {\n        if (depth === 0) {\n          return node;\n        } else {\n          depth--;\n        }\n      } else if (data === SUSPENSE_END_DATA) {\n        depth++;\n      }\n    }\n\n    node = node.previousSibling;\n  }\n\n  return null;\n}\nfunction commitHydratedContainer(container) {\n  // Retry if any event replaying was blocked on this.\n  retryIfBlockedOn(container);\n}\nfunction commitHydratedSuspenseInstance(suspenseInstance) {\n  // Retry if any event replaying was blocked on this.\n  retryIfBlockedOn(suspenseInstance);\n}\nfunction didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {\n  {\n    warnForUnmatchedText(textInstance, text);\n  }\n}\nfunction didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {\n  if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {\n    warnForUnmatchedText(textInstance, text);\n  }\n}\nfunction didNotHydrateContainerInstance(parentContainer, instance) {\n  {\n    if (instance.nodeType === ELEMENT_NODE) {\n      warnForDeletedHydratableElement(parentContainer, instance);\n    } else if (instance.nodeType === COMMENT_NODE) ; else {\n      warnForDeletedHydratableText(parentContainer, instance);\n    }\n  }\n}\nfunction didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {\n  if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {\n    if (instance.nodeType === ELEMENT_NODE) {\n      warnForDeletedHydratableElement(parentInstance, instance);\n    } else if (instance.nodeType === COMMENT_NODE) ; else {\n      warnForDeletedHydratableText(parentInstance, instance);\n    }\n  }\n}\nfunction didNotFindHydratableContainerInstance(parentContainer, type, props) {\n  {\n    warnForInsertedHydratedElement(parentContainer, type);\n  }\n}\nfunction didNotFindHydratableContainerTextInstance(parentContainer, text) {\n  {\n    warnForInsertedHydratedText(parentContainer, text);\n  }\n}\nfunction didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {\n  if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {\n    warnForInsertedHydratedElement(parentInstance, type);\n  }\n}\nfunction didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {\n  if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {\n    warnForInsertedHydratedText(parentInstance, text);\n  }\n}\nfunction didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {\n  if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;\n}\n\nvar randomKey = Math.random().toString(36).slice(2);\nvar internalInstanceKey = '__reactInternalInstance$' + randomKey;\nvar internalEventHandlersKey = '__reactEventHandlers$' + randomKey;\nvar internalContainerInstanceKey = '__reactContainere$' + randomKey;\nfunction precacheFiberNode(hostInst, node) {\n  node[internalInstanceKey] = hostInst;\n}\nfunction markContainerAsRoot(hostRoot, node) {\n  node[internalContainerInstanceKey] = hostRoot;\n}\nfunction unmarkContainerAsRoot(node) {\n  node[internalContainerInstanceKey] = null;\n}\nfunction isContainerMarkedAsRoot(node) {\n  return !!node[internalContainerInstanceKey];\n} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.\n// If the target node is part of a hydrated or not yet rendered subtree, then\n// this may also return a SuspenseComponent or HostRoot to indicate that.\n// Conceptually the HostRoot fiber is a child of the Container node. So if you\n// pass the Container node as the targetNode, you will not actually get the\n// HostRoot back. To get to the HostRoot, you need to pass a child of it.\n// The same thing applies to Suspense boundaries.\n\nfunction getClosestInstanceFromNode(targetNode) {\n  var targetInst = targetNode[internalInstanceKey];\n\n  if (targetInst) {\n    // Don't return HostRoot or SuspenseComponent here.\n    return targetInst;\n  } // If the direct event target isn't a React owned DOM node, we need to look\n  // to see if one of its parents is a React owned DOM node.\n\n\n  var parentNode = targetNode.parentNode;\n\n  while (parentNode) {\n    // We'll check if this is a container root that could include\n    // React nodes in the future. We need to check this first because\n    // if we're a child of a dehydrated container, we need to first\n    // find that inner container before moving on to finding the parent\n    // instance. Note that we don't check this field on  the targetNode\n    // itself because the fibers are conceptually between the container\n    // node and the first child. It isn't surrounding the container node.\n    // If it's not a container, we check if it's an instance.\n    targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];\n\n    if (targetInst) {\n      // Since this wasn't the direct target of the event, we might have\n      // stepped past dehydrated DOM nodes to get here. However they could\n      // also have been non-React nodes. We need to answer which one.\n      // If we the instance doesn't have any children, then there can't be\n      // a nested suspense boundary within it. So we can use this as a fast\n      // bailout. Most of the time, when people add non-React children to\n      // the tree, it is using a ref to a child-less DOM node.\n      // Normally we'd only need to check one of the fibers because if it\n      // has ever gone from having children to deleting them or vice versa\n      // it would have deleted the dehydrated boundary nested inside already.\n      // However, since the HostRoot starts out with an alternate it might\n      // have one on the alternate so we need to check in case this was a\n      // root.\n      var alternate = targetInst.alternate;\n\n      if (targetInst.child !== null || alternate !== null && alternate.child !== null) {\n        // Next we need to figure out if the node that skipped past is\n        // nested within a dehydrated boundary and if so, which one.\n        var suspenseInstance = getParentSuspenseInstance(targetNode);\n\n        while (suspenseInstance !== null) {\n          // We found a suspense instance. That means that we haven't\n          // hydrated it yet. Even though we leave the comments in the\n          // DOM after hydrating, and there are boundaries in the DOM\n          // that could already be hydrated, we wouldn't have found them\n          // through this pass since if the target is hydrated it would\n          // have had an internalInstanceKey on it.\n          // Let's get the fiber associated with the SuspenseComponent\n          // as the deepest instance.\n          var targetSuspenseInst = suspenseInstance[internalInstanceKey];\n\n          if (targetSuspenseInst) {\n            return targetSuspenseInst;\n          } // If we don't find a Fiber on the comment, it might be because\n          // we haven't gotten to hydrate it yet. There might still be a\n          // parent boundary that hasn't above this one so we need to find\n          // the outer most that is known.\n\n\n          suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent\n          // host component also hasn't hydrated yet. We can return it\n          // below since it will bail out on the isMounted check later.\n        }\n      }\n\n      return targetInst;\n    }\n\n    targetNode = parentNode;\n    parentNode = targetNode.parentNode;\n  }\n\n  return null;\n}\n/**\n * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent\n * instance, or null if the node was not rendered by this React.\n */\n\nfunction getInstanceFromNode$1(node) {\n  var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];\n\n  if (inst) {\n    if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {\n      return inst;\n    } else {\n      return null;\n    }\n  }\n\n  return null;\n}\n/**\n * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding\n * DOM node.\n */\n\nfunction getNodeFromInstance$1(inst) {\n  if (inst.tag === HostComponent || inst.tag === HostText) {\n    // In Fiber this, is just the state node right now. We assume it will be\n    // a host component or host text.\n    return inst.stateNode;\n  } // Without this first invariant, passing a non-DOM-component triggers the next\n  // invariant for a missing parent, which is super confusing.\n\n\n  {\n    {\n      throw Error( \"getNodeFromInstance: Invalid argument.\" );\n    }\n  }\n}\nfunction getFiberCurrentPropsFromNode$1(node) {\n  return node[internalEventHandlersKey] || null;\n}\nfunction updateFiberProps(node, props) {\n  node[internalEventHandlersKey] = props;\n}\n\nfunction getParent(inst) {\n  do {\n    inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.\n    // That is depending on if we want nested subtrees (layers) to bubble\n    // events to their parent. We could also go through parentNode on the\n    // host node but that wouldn't work for React Native and doesn't let us\n    // do the portal feature.\n  } while (inst && inst.tag !== HostComponent);\n\n  if (inst) {\n    return inst;\n  }\n\n  return null;\n}\n/**\n * Return the lowest common ancestor of A and B, or null if they are in\n * different trees.\n */\n\n\nfunction getLowestCommonAncestor(instA, instB) {\n  var depthA = 0;\n\n  for (var tempA = instA; tempA; tempA = getParent(tempA)) {\n    depthA++;\n  }\n\n  var depthB = 0;\n\n  for (var tempB = instB; tempB; tempB = getParent(tempB)) {\n    depthB++;\n  } // If A is deeper, crawl up.\n\n\n  while (depthA - depthB > 0) {\n    instA = getParent(instA);\n    depthA--;\n  } // If B is deeper, crawl up.\n\n\n  while (depthB - depthA > 0) {\n    instB = getParent(instB);\n    depthB--;\n  } // Walk in lockstep until we find a match.\n\n\n  var depth = depthA;\n\n  while (depth--) {\n    if (instA === instB || instA === instB.alternate) {\n      return instA;\n    }\n\n    instA = getParent(instA);\n    instB = getParent(instB);\n  }\n\n  return null;\n}\n/**\n * Simulates the traversal of a two-phase, capture/bubble event dispatch.\n */\n\nfunction traverseTwoPhase(inst, fn, arg) {\n  var path = [];\n\n  while (inst) {\n    path.push(inst);\n    inst = getParent(inst);\n  }\n\n  var i;\n\n  for (i = path.length; i-- > 0;) {\n    fn(path[i], 'captured', arg);\n  }\n\n  for (i = 0; i < path.length; i++) {\n    fn(path[i], 'bubbled', arg);\n  }\n}\n/**\n * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that\n * should would receive a `mouseEnter` or `mouseLeave` event.\n *\n * Does not invoke the callback on the nearest common ancestor because nothing\n * \"entered\" or \"left\" that element.\n */\n\nfunction traverseEnterLeave(from, to, fn, argFrom, argTo) {\n  var common = from && to ? getLowestCommonAncestor(from, to) : null;\n  var pathFrom = [];\n\n  while (true) {\n    if (!from) {\n      break;\n    }\n\n    if (from === common) {\n      break;\n    }\n\n    var alternate = from.alternate;\n\n    if (alternate !== null && alternate === common) {\n      break;\n    }\n\n    pathFrom.push(from);\n    from = getParent(from);\n  }\n\n  var pathTo = [];\n\n  while (true) {\n    if (!to) {\n      break;\n    }\n\n    if (to === common) {\n      break;\n    }\n\n    var _alternate = to.alternate;\n\n    if (_alternate !== null && _alternate === common) {\n      break;\n    }\n\n    pathTo.push(to);\n    to = getParent(to);\n  }\n\n  for (var i = 0; i < pathFrom.length; i++) {\n    fn(pathFrom[i], 'bubbled', argFrom);\n  }\n\n  for (var _i = pathTo.length; _i-- > 0;) {\n    fn(pathTo[_i], 'captured', argTo);\n  }\n}\n\nfunction isInteractive(tag) {\n  return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';\n}\n\nfunction shouldPreventMouseEvent(name, type, props) {\n  switch (name) {\n    case 'onClick':\n    case 'onClickCapture':\n    case 'onDoubleClick':\n    case 'onDoubleClickCapture':\n    case 'onMouseDown':\n    case 'onMouseDownCapture':\n    case 'onMouseMove':\n    case 'onMouseMoveCapture':\n    case 'onMouseUp':\n    case 'onMouseUpCapture':\n    case 'onMouseEnter':\n      return !!(props.disabled && isInteractive(type));\n\n    default:\n      return false;\n  }\n}\n/**\n * @param {object} inst The instance, which is the source of events.\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @return {?function} The stored callback.\n */\n\n\nfunction getListener(inst, registrationName) {\n  var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not\n  // live here; needs to be moved to a better place soon\n\n  var stateNode = inst.stateNode;\n\n  if (!stateNode) {\n    // Work in progress (ex: onload events in incremental mode).\n    return null;\n  }\n\n  var props = getFiberCurrentPropsFromNode(stateNode);\n\n  if (!props) {\n    // Work in progress.\n    return null;\n  }\n\n  listener = props[registrationName];\n\n  if (shouldPreventMouseEvent(registrationName, inst.type, props)) {\n    return null;\n  }\n\n  if (!(!listener || typeof listener === 'function')) {\n    {\n      throw Error( \"Expected `\" + registrationName + \"` listener to be a function, instead got a value of `\" + typeof listener + \"` type.\" );\n    }\n  }\n\n  return listener;\n}\n\n/**\n * Some event types have a notion of different registration names for different\n * \"phases\" of propagation. This finds listeners by a given phase.\n */\nfunction listenerAtPhase(inst, event, propagationPhase) {\n  var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];\n  return getListener(inst, registrationName);\n}\n/**\n * A small set of propagation patterns, each of which will accept a small amount\n * of information, and generate a set of \"dispatch ready event objects\" - which\n * are sets of events that have already been annotated with a set of dispatched\n * listener functions/ids. The API is designed this way to discourage these\n * propagation strategies from actually executing the dispatches, since we\n * always want to collect the entire set of dispatches before executing even a\n * single one.\n */\n\n/**\n * Tags a `SyntheticEvent` with dispatched listeners. Creating this function\n * here, allows us to not have to bind or create functions for each event.\n * Mutating the event's members allows us to not have to create a wrapping\n * \"dispatch\" object that pairs the event with the listener.\n */\n\n\nfunction accumulateDirectionalDispatches(inst, phase, event) {\n  {\n    if (!inst) {\n      error('Dispatching inst must not be null');\n    }\n  }\n\n  var listener = listenerAtPhase(inst, event, phase);\n\n  if (listener) {\n    event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n    event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n  }\n}\n/**\n * Collect dispatches (must be entirely collected before dispatching - see unit\n * tests). Lazily allocate the array to conserve memory.  We must loop through\n * each event and perform the traversal for each one. We cannot perform a\n * single traversal for the entire collection of events because each event may\n * have a different target.\n */\n\n\nfunction accumulateTwoPhaseDispatchesSingle(event) {\n  if (event && event.dispatchConfig.phasedRegistrationNames) {\n    traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);\n  }\n}\n/**\n * Accumulates without regard to direction, does not look for phased\n * registration names. Same as `accumulateDirectDispatchesSingle` but without\n * requiring that the `dispatchMarker` be the same as the dispatched ID.\n */\n\n\nfunction accumulateDispatches(inst, ignoredDirection, event) {\n  if (inst && event && event.dispatchConfig.registrationName) {\n    var registrationName = event.dispatchConfig.registrationName;\n    var listener = getListener(inst, registrationName);\n\n    if (listener) {\n      event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n      event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n    }\n  }\n}\n/**\n * Accumulates dispatches on an `SyntheticEvent`, but only for the\n * `dispatchMarker`.\n * @param {SyntheticEvent} event\n */\n\n\nfunction accumulateDirectDispatchesSingle(event) {\n  if (event && event.dispatchConfig.registrationName) {\n    accumulateDispatches(event._targetInst, null, event);\n  }\n}\n\nfunction accumulateTwoPhaseDispatches(events) {\n  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);\n}\nfunction accumulateEnterLeaveDispatches(leave, enter, from, to) {\n  traverseEnterLeave(from, to, accumulateDispatches, leave, enter);\n}\nfunction accumulateDirectDispatches(events) {\n  forEachAccumulated(events, accumulateDirectDispatchesSingle);\n}\n\n/**\n * These variables store information about text content of a target node,\n * allowing comparison of content before and after a given event.\n *\n * Identify the node where selection currently begins, then observe\n * both its text content and its current position in the DOM. Since the\n * browser may natively replace the target node during composition, we can\n * use its position to find its replacement.\n *\n *\n */\nvar root = null;\nvar startText = null;\nvar fallbackText = null;\nfunction initialize(nativeEventTarget) {\n  root = nativeEventTarget;\n  startText = getText();\n  return true;\n}\nfunction reset() {\n  root = null;\n  startText = null;\n  fallbackText = null;\n}\nfunction getData() {\n  if (fallbackText) {\n    return fallbackText;\n  }\n\n  var start;\n  var startValue = startText;\n  var startLength = startValue.length;\n  var end;\n  var endValue = getText();\n  var endLength = endValue.length;\n\n  for (start = 0; start < startLength; start++) {\n    if (startValue[start] !== endValue[start]) {\n      break;\n    }\n  }\n\n  var minEnd = startLength - start;\n\n  for (end = 1; end <= minEnd; end++) {\n    if (startValue[startLength - end] !== endValue[endLength - end]) {\n      break;\n    }\n  }\n\n  var sliceTail = end > 1 ? 1 - end : undefined;\n  fallbackText = endValue.slice(start, sliceTail);\n  return fallbackText;\n}\nfunction getText() {\n  if ('value' in root) {\n    return root.value;\n  }\n\n  return root.textContent;\n}\n\nvar EVENT_POOL_SIZE = 10;\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar EventInterface = {\n  type: null,\n  target: null,\n  // currentTarget is set when dispatching; no use in copying it here\n  currentTarget: function () {\n    return null;\n  },\n  eventPhase: null,\n  bubbles: null,\n  cancelable: null,\n  timeStamp: function (event) {\n    return event.timeStamp || Date.now();\n  },\n  defaultPrevented: null,\n  isTrusted: null\n};\n\nfunction functionThatReturnsTrue() {\n  return true;\n}\n\nfunction functionThatReturnsFalse() {\n  return false;\n}\n/**\n * Synthetic events are dispatched by event plugins, typically in response to a\n * top-level event delegation handler.\n *\n * These systems should generally use pooling to reduce the frequency of garbage\n * collection. The system should check `isPersistent` to determine whether the\n * event should be released into the pool after being dispatched. Users that\n * need a persisted event should invoke `persist`.\n *\n * Synthetic events (and subclasses) implement the DOM Level 3 Events API by\n * normalizing browser quirks. Subclasses do not necessarily have to implement a\n * DOM interface; custom application-specific events can also subclass this.\n *\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {*} targetInst Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @param {DOMEventTarget} nativeEventTarget Target node.\n */\n\n\nfunction SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {\n  {\n    // these have a getter/setter for warnings\n    delete this.nativeEvent;\n    delete this.preventDefault;\n    delete this.stopPropagation;\n    delete this.isDefaultPrevented;\n    delete this.isPropagationStopped;\n  }\n\n  this.dispatchConfig = dispatchConfig;\n  this._targetInst = targetInst;\n  this.nativeEvent = nativeEvent;\n  var Interface = this.constructor.Interface;\n\n  for (var propName in Interface) {\n    if (!Interface.hasOwnProperty(propName)) {\n      continue;\n    }\n\n    {\n      delete this[propName]; // this has a getter/setter for warnings\n    }\n\n    var normalize = Interface[propName];\n\n    if (normalize) {\n      this[propName] = normalize(nativeEvent);\n    } else {\n      if (propName === 'target') {\n        this.target = nativeEventTarget;\n      } else {\n        this[propName] = nativeEvent[propName];\n      }\n    }\n  }\n\n  var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;\n\n  if (defaultPrevented) {\n    this.isDefaultPrevented = functionThatReturnsTrue;\n  } else {\n    this.isDefaultPrevented = functionThatReturnsFalse;\n  }\n\n  this.isPropagationStopped = functionThatReturnsFalse;\n  return this;\n}\n\n_assign(SyntheticEvent.prototype, {\n  preventDefault: function () {\n    this.defaultPrevented = true;\n    var event = this.nativeEvent;\n\n    if (!event) {\n      return;\n    }\n\n    if (event.preventDefault) {\n      event.preventDefault();\n    } else if (typeof event.returnValue !== 'unknown') {\n      event.returnValue = false;\n    }\n\n    this.isDefaultPrevented = functionThatReturnsTrue;\n  },\n  stopPropagation: function () {\n    var event = this.nativeEvent;\n\n    if (!event) {\n      return;\n    }\n\n    if (event.stopPropagation) {\n      event.stopPropagation();\n    } else if (typeof event.cancelBubble !== 'unknown') {\n      // The ChangeEventPlugin registers a \"propertychange\" event for\n      // IE. This event does not support bubbling or cancelling, and\n      // any references to cancelBubble throw \"Member not found\".  A\n      // typeof check of \"unknown\" circumvents this issue (and is also\n      // IE specific).\n      event.cancelBubble = true;\n    }\n\n    this.isPropagationStopped = functionThatReturnsTrue;\n  },\n\n  /**\n   * We release all dispatched `SyntheticEvent`s after each event loop, adding\n   * them back into the pool. This allows a way to hold onto a reference that\n   * won't be added back into the pool.\n   */\n  persist: function () {\n    this.isPersistent = functionThatReturnsTrue;\n  },\n\n  /**\n   * Checks if this event should be released back into the pool.\n   *\n   * @return {boolean} True if this should not be released, false otherwise.\n   */\n  isPersistent: functionThatReturnsFalse,\n\n  /**\n   * `PooledClass` looks for `destructor` on each instance it releases.\n   */\n  destructor: function () {\n    var Interface = this.constructor.Interface;\n\n    for (var propName in Interface) {\n      {\n        Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));\n      }\n    }\n\n    this.dispatchConfig = null;\n    this._targetInst = null;\n    this.nativeEvent = null;\n    this.isDefaultPrevented = functionThatReturnsFalse;\n    this.isPropagationStopped = functionThatReturnsFalse;\n    this._dispatchListeners = null;\n    this._dispatchInstances = null;\n\n    {\n      Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));\n      Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));\n      Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));\n      Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));\n      Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));\n    }\n  }\n});\n\nSyntheticEvent.Interface = EventInterface;\n/**\n * Helper to reduce boilerplate when creating subclasses.\n */\n\nSyntheticEvent.extend = function (Interface) {\n  var Super = this;\n\n  var E = function () {};\n\n  E.prototype = Super.prototype;\n  var prototype = new E();\n\n  function Class() {\n    return Super.apply(this, arguments);\n  }\n\n  _assign(prototype, Class.prototype);\n\n  Class.prototype = prototype;\n  Class.prototype.constructor = Class;\n  Class.Interface = _assign({}, Super.Interface, Interface);\n  Class.extend = Super.extend;\n  addEventPoolingTo(Class);\n  return Class;\n};\n\naddEventPoolingTo(SyntheticEvent);\n/**\n * Helper to nullify syntheticEvent instance properties when destructing\n *\n * @param {String} propName\n * @param {?object} getVal\n * @return {object} defineProperty object\n */\n\nfunction getPooledWarningPropertyDefinition(propName, getVal) {\n  var isFunction = typeof getVal === 'function';\n  return {\n    configurable: true,\n    set: set,\n    get: get\n  };\n\n  function set(val) {\n    var action = isFunction ? 'setting the method' : 'setting the property';\n    warn(action, 'This is effectively a no-op');\n    return val;\n  }\n\n  function get() {\n    var action = isFunction ? 'accessing the method' : 'accessing the property';\n    var result = isFunction ? 'This is a no-op function' : 'This is set to null';\n    warn(action, result);\n    return getVal;\n  }\n\n  function warn(action, result) {\n    {\n      error(\"This synthetic event is reused for performance reasons. If you're seeing this, \" + \"you're %s `%s` on a released/nullified synthetic event. %s. \" + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result);\n    }\n  }\n}\n\nfunction getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {\n  var EventConstructor = this;\n\n  if (EventConstructor.eventPool.length) {\n    var instance = EventConstructor.eventPool.pop();\n    EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);\n    return instance;\n  }\n\n  return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);\n}\n\nfunction releasePooledEvent(event) {\n  var EventConstructor = this;\n\n  if (!(event instanceof EventConstructor)) {\n    {\n      throw Error( \"Trying to release an event instance into a pool of a different type.\" );\n    }\n  }\n\n  event.destructor();\n\n  if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {\n    EventConstructor.eventPool.push(event);\n  }\n}\n\nfunction addEventPoolingTo(EventConstructor) {\n  EventConstructor.eventPool = [];\n  EventConstructor.getPooled = getPooledEvent;\n  EventConstructor.release = releasePooledEvent;\n}\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents\n */\n\nvar SyntheticCompositionEvent = SyntheticEvent.extend({\n  data: null\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105\n *      /#events-inputevents\n */\n\nvar SyntheticInputEvent = SyntheticEvent.extend({\n  data: null\n});\n\nvar END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space\n\nvar START_KEYCODE = 229;\nvar canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;\nvar documentMode = null;\n\nif (canUseDOM && 'documentMode' in document) {\n  documentMode = document.documentMode;\n} // Webkit offers a very useful `textInput` event that can be used to\n// directly represent `beforeInput`. The IE `textinput` event is not as\n// useful, so we don't use it.\n\n\nvar canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied\n// by the native compositionend event may be incorrect. Japanese ideographic\n// spaces, for instance (\\u3000) are not recorded correctly.\n\nvar useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);\nvar SPACEBAR_CODE = 32;\nvar SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names.\n\nvar eventTypes = {\n  beforeInput: {\n    phasedRegistrationNames: {\n      bubbled: 'onBeforeInput',\n      captured: 'onBeforeInputCapture'\n    },\n    dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]\n  },\n  compositionEnd: {\n    phasedRegistrationNames: {\n      bubbled: 'onCompositionEnd',\n      captured: 'onCompositionEndCapture'\n    },\n    dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n  },\n  compositionStart: {\n    phasedRegistrationNames: {\n      bubbled: 'onCompositionStart',\n      captured: 'onCompositionStartCapture'\n    },\n    dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n  },\n  compositionUpdate: {\n    phasedRegistrationNames: {\n      bubbled: 'onCompositionUpdate',\n      captured: 'onCompositionUpdateCapture'\n    },\n    dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n  }\n}; // Track whether we've ever handled a keypress on the space key.\n\nvar hasSpaceKeypress = false;\n/**\n * Return whether a native keypress event is assumed to be a command.\n * This is required because Firefox fires `keypress` events for key commands\n * (cut, copy, select-all, etc.) even though no character is inserted.\n */\n\nfunction isKeypressCommand(nativeEvent) {\n  return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.\n  !(nativeEvent.ctrlKey && nativeEvent.altKey);\n}\n/**\n * Translate native top level events into event types.\n *\n * @param {string} topLevelType\n * @return {object}\n */\n\n\nfunction getCompositionEventType(topLevelType) {\n  switch (topLevelType) {\n    case TOP_COMPOSITION_START:\n      return eventTypes.compositionStart;\n\n    case TOP_COMPOSITION_END:\n      return eventTypes.compositionEnd;\n\n    case TOP_COMPOSITION_UPDATE:\n      return eventTypes.compositionUpdate;\n  }\n}\n/**\n * Does our fallback best-guess model think this event signifies that\n * composition has begun?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\n\n\nfunction isFallbackCompositionStart(topLevelType, nativeEvent) {\n  return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;\n}\n/**\n * Does our fallback mode think that this event is the end of composition?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\n\n\nfunction isFallbackCompositionEnd(topLevelType, nativeEvent) {\n  switch (topLevelType) {\n    case TOP_KEY_UP:\n      // Command keys insert or clear IME input.\n      return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;\n\n    case TOP_KEY_DOWN:\n      // Expect IME keyCode on each keydown. If we get any other\n      // code we must have exited earlier.\n      return nativeEvent.keyCode !== START_KEYCODE;\n\n    case TOP_KEY_PRESS:\n    case TOP_MOUSE_DOWN:\n    case TOP_BLUR:\n      // Events are not possible without cancelling IME.\n      return true;\n\n    default:\n      return false;\n  }\n}\n/**\n * Google Input Tools provides composition data via a CustomEvent,\n * with the `data` property populated in the `detail` object. If this\n * is available on the event object, use it. If not, this is a plain\n * composition event and we have nothing special to extract.\n *\n * @param {object} nativeEvent\n * @return {?string}\n */\n\n\nfunction getDataFromCustomEvent(nativeEvent) {\n  var detail = nativeEvent.detail;\n\n  if (typeof detail === 'object' && 'data' in detail) {\n    return detail.data;\n  }\n\n  return null;\n}\n/**\n * Check if a composition event was triggered by Korean IME.\n * Our fallback mode does not work well with IE's Korean IME,\n * so just use native composition events when Korean IME is used.\n * Although CompositionEvent.locale property is deprecated,\n * it is available in IE, where our fallback mode is enabled.\n *\n * @param {object} nativeEvent\n * @return {boolean}\n */\n\n\nfunction isUsingKoreanIME(nativeEvent) {\n  return nativeEvent.locale === 'ko';\n} // Track the current IME composition status, if any.\n\n\nvar isComposing = false;\n/**\n * @return {?object} A SyntheticCompositionEvent.\n */\n\nfunction extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n  var eventType;\n  var fallbackData;\n\n  if (canUseCompositionEvent) {\n    eventType = getCompositionEventType(topLevelType);\n  } else if (!isComposing) {\n    if (isFallbackCompositionStart(topLevelType, nativeEvent)) {\n      eventType = eventTypes.compositionStart;\n    }\n  } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n    eventType = eventTypes.compositionEnd;\n  }\n\n  if (!eventType) {\n    return null;\n  }\n\n  if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {\n    // The current composition is stored statically and must not be\n    // overwritten while composition continues.\n    if (!isComposing && eventType === eventTypes.compositionStart) {\n      isComposing = initialize(nativeEventTarget);\n    } else if (eventType === eventTypes.compositionEnd) {\n      if (isComposing) {\n        fallbackData = getData();\n      }\n    }\n  }\n\n  var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);\n\n  if (fallbackData) {\n    // Inject data generated from fallback path into the synthetic event.\n    // This matches the property of native CompositionEventInterface.\n    event.data = fallbackData;\n  } else {\n    var customData = getDataFromCustomEvent(nativeEvent);\n\n    if (customData !== null) {\n      event.data = customData;\n    }\n  }\n\n  accumulateTwoPhaseDispatches(event);\n  return event;\n}\n/**\n * @param {TopLevelType} topLevelType Number from `TopLevelType`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The string corresponding to this `beforeInput` event.\n */\n\n\nfunction getNativeBeforeInputChars(topLevelType, nativeEvent) {\n  switch (topLevelType) {\n    case TOP_COMPOSITION_END:\n      return getDataFromCustomEvent(nativeEvent);\n\n    case TOP_KEY_PRESS:\n      /**\n       * If native `textInput` events are available, our goal is to make\n       * use of them. However, there is a special case: the spacebar key.\n       * In Webkit, preventing default on a spacebar `textInput` event\n       * cancels character insertion, but it *also* causes the browser\n       * to fall back to its default spacebar behavior of scrolling the\n       * page.\n       *\n       * Tracking at:\n       * https://code.google.com/p/chromium/issues/detail?id=355103\n       *\n       * To avoid this issue, use the keypress event as if no `textInput`\n       * event is available.\n       */\n      var which = nativeEvent.which;\n\n      if (which !== SPACEBAR_CODE) {\n        return null;\n      }\n\n      hasSpaceKeypress = true;\n      return SPACEBAR_CHAR;\n\n    case TOP_TEXT_INPUT:\n      // Record the characters to be added to the DOM.\n      var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled\n      // it at the keypress level and bail immediately. Android Chrome\n      // doesn't give us keycodes, so we need to ignore it.\n\n      if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {\n        return null;\n      }\n\n      return chars;\n\n    default:\n      // For other native event types, do nothing.\n      return null;\n  }\n}\n/**\n * For browsers that do not provide the `textInput` event, extract the\n * appropriate string to use for SyntheticInputEvent.\n *\n * @param {number} topLevelType Number from `TopLevelEventTypes`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The fallback string for this `beforeInput` event.\n */\n\n\nfunction getFallbackBeforeInputChars(topLevelType, nativeEvent) {\n  // If we are currently composing (IME) and using a fallback to do so,\n  // try to extract the composed characters from the fallback object.\n  // If composition event is available, we extract a string only at\n  // compositionevent, otherwise extract it at fallback events.\n  if (isComposing) {\n    if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n      var chars = getData();\n      reset();\n      isComposing = false;\n      return chars;\n    }\n\n    return null;\n  }\n\n  switch (topLevelType) {\n    case TOP_PASTE:\n      // If a paste event occurs after a keypress, throw out the input\n      // chars. Paste events should not lead to BeforeInput events.\n      return null;\n\n    case TOP_KEY_PRESS:\n      /**\n       * As of v27, Firefox may fire keypress events even when no character\n       * will be inserted. A few possibilities:\n       *\n       * - `which` is `0`. Arrow keys, Esc key, etc.\n       *\n       * - `which` is the pressed key code, but no char is available.\n       *   Ex: 'AltGr + d` in Polish. There is no modified character for\n       *   this key combination and no character is inserted into the\n       *   document, but FF fires the keypress for char code `100` anyway.\n       *   No `input` event will occur.\n       *\n       * - `which` is the pressed key code, but a command combination is\n       *   being used. Ex: `Cmd+C`. No character is inserted, and no\n       *   `input` event will occur.\n       */\n      if (!isKeypressCommand(nativeEvent)) {\n        // IE fires the `keypress` event when a user types an emoji via\n        // Touch keyboard of Windows.  In such a case, the `char` property\n        // holds an emoji character like `\\uD83D\\uDE0A`.  Because its length\n        // is 2, the property `which` does not represent an emoji correctly.\n        // In such a case, we directly return the `char` property instead of\n        // using `which`.\n        if (nativeEvent.char && nativeEvent.char.length > 1) {\n          return nativeEvent.char;\n        } else if (nativeEvent.which) {\n          return String.fromCharCode(nativeEvent.which);\n        }\n      }\n\n      return null;\n\n    case TOP_COMPOSITION_END:\n      return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;\n\n    default:\n      return null;\n  }\n}\n/**\n * Extract a SyntheticInputEvent for `beforeInput`, based on either native\n * `textInput` or fallback behavior.\n *\n * @return {?object} A SyntheticInputEvent.\n */\n\n\nfunction extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n  var chars;\n\n  if (canUseTextInputEvent) {\n    chars = getNativeBeforeInputChars(topLevelType, nativeEvent);\n  } else {\n    chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);\n  } // If no characters are being inserted, no BeforeInput event should\n  // be fired.\n\n\n  if (!chars) {\n    return null;\n  }\n\n  var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);\n  event.data = chars;\n  accumulateTwoPhaseDispatches(event);\n  return event;\n}\n/**\n * Create an `onBeforeInput` event to match\n * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.\n *\n * This event plugin is based on the native `textInput` event\n * available in Chrome, Safari, Opera, and IE. This event fires after\n * `onKeyPress` and `onCompositionEnd`, but before `onInput`.\n *\n * `beforeInput` is spec'd but not implemented in any browsers, and\n * the `input` event does not provide any useful information about what has\n * actually been added, contrary to the spec. Thus, `textInput` is the best\n * available event to identify the characters that have actually been inserted\n * into the target node.\n *\n * This plugin is also responsible for emitting `composition` events, thus\n * allowing us to share composition fallback code for both `beforeInput` and\n * `composition` event types.\n */\n\n\nvar BeforeInputEventPlugin = {\n  eventTypes: eventTypes,\n  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n    var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n    var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n\n    if (composition === null) {\n      return beforeInput;\n    }\n\n    if (beforeInput === null) {\n      return composition;\n    }\n\n    return [composition, beforeInput];\n  }\n};\n\n/**\n * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary\n */\nvar supportedInputTypes = {\n  color: true,\n  date: true,\n  datetime: true,\n  'datetime-local': true,\n  email: true,\n  month: true,\n  number: true,\n  password: true,\n  range: true,\n  search: true,\n  tel: true,\n  text: true,\n  time: true,\n  url: true,\n  week: true\n};\n\nfunction isTextInputElement(elem) {\n  var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n\n  if (nodeName === 'input') {\n    return !!supportedInputTypes[elem.type];\n  }\n\n  if (nodeName === 'textarea') {\n    return true;\n  }\n\n  return false;\n}\n\nvar eventTypes$1 = {\n  change: {\n    phasedRegistrationNames: {\n      bubbled: 'onChange',\n      captured: 'onChangeCapture'\n    },\n    dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]\n  }\n};\n\nfunction createAndAccumulateChangeEvent(inst, nativeEvent, target) {\n  var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);\n  event.type = 'change'; // Flag this event loop as needing state restore.\n\n  enqueueStateRestore(target);\n  accumulateTwoPhaseDispatches(event);\n  return event;\n}\n/**\n * For IE shims\n */\n\n\nvar activeElement = null;\nvar activeElementInst = null;\n/**\n * SECTION: handle `change` event\n */\n\nfunction shouldUseChangeEvent(elem) {\n  var nodeName = elem.nodeName && elem.nodeName.toLowerCase();\n  return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';\n}\n\nfunction manualDispatchChangeEvent(nativeEvent) {\n  var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the\n  // other events and have it go through ReactBrowserEventEmitter. Since it\n  // doesn't, we manually listen for the events and so we have to enqueue and\n  // process the abstract event manually.\n  //\n  // Batching is necessary here in order to ensure that all event handlers run\n  // before the next rerender (including event handlers attached to ancestor\n  // elements instead of directly on the input). Without this, controlled\n  // components don't work properly in conjunction with event bubbling because\n  // the component is rerendered and the value reverted before all the event\n  // handlers can run. See https://github.com/facebook/react/issues/708.\n\n  batchedUpdates(runEventInBatch, event);\n}\n\nfunction runEventInBatch(event) {\n  runEventsInBatch(event);\n}\n\nfunction getInstIfValueChanged(targetInst) {\n  var targetNode = getNodeFromInstance$1(targetInst);\n\n  if (updateValueIfChanged(targetNode)) {\n    return targetInst;\n  }\n}\n\nfunction getTargetInstForChangeEvent(topLevelType, targetInst) {\n  if (topLevelType === TOP_CHANGE) {\n    return targetInst;\n  }\n}\n/**\n * SECTION: handle `input` event\n */\n\n\nvar isInputEventSupported = false;\n\nif (canUseDOM) {\n  // IE9 claims to support the input event but fails to trigger it when\n  // deleting text, so we ignore its input events.\n  isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);\n}\n/**\n * (For IE <=9) Starts tracking propertychange events on the passed-in element\n * and override the value property so that we can distinguish user events from\n * value changes in JS.\n */\n\n\nfunction startWatchingForValueChange(target, targetInst) {\n  activeElement = target;\n  activeElementInst = targetInst;\n  activeElement.attachEvent('onpropertychange', handlePropertyChange);\n}\n/**\n * (For IE <=9) Removes the event listeners from the currently-tracked element,\n * if any exists.\n */\n\n\nfunction stopWatchingForValueChange() {\n  if (!activeElement) {\n    return;\n  }\n\n  activeElement.detachEvent('onpropertychange', handlePropertyChange);\n  activeElement = null;\n  activeElementInst = null;\n}\n/**\n * (For IE <=9) Handles a propertychange event, sending a `change` event if\n * the value of the active element has changed.\n */\n\n\nfunction handlePropertyChange(nativeEvent) {\n  if (nativeEvent.propertyName !== 'value') {\n    return;\n  }\n\n  if (getInstIfValueChanged(activeElementInst)) {\n    manualDispatchChangeEvent(nativeEvent);\n  }\n}\n\nfunction handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {\n  if (topLevelType === TOP_FOCUS) {\n    // In IE9, propertychange fires for most input events but is buggy and\n    // doesn't fire when text is deleted, but conveniently, selectionchange\n    // appears to fire in all of the remaining cases so we catch those and\n    // forward the event if the value has changed\n    // In either case, we don't want to call the event handler if the value\n    // is changed from JS so we redefine a setter for `.value` that updates\n    // our activeElementValue variable, allowing us to ignore those changes\n    //\n    // stopWatching() should be a noop here but we call it just in case we\n    // missed a blur event somehow.\n    stopWatchingForValueChange();\n    startWatchingForValueChange(target, targetInst);\n  } else if (topLevelType === TOP_BLUR) {\n    stopWatchingForValueChange();\n  }\n} // For IE8 and IE9.\n\n\nfunction getTargetInstForInputEventPolyfill(topLevelType, targetInst) {\n  if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {\n    // On the selectionchange event, the target is just document which isn't\n    // helpful for us so just check activeElement instead.\n    //\n    // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire\n    // propertychange on the first input event after setting `value` from a\n    // script and fires only keydown, keypress, keyup. Catching keyup usually\n    // gets it and catching keydown lets us fire an event for the first\n    // keystroke if user does a key repeat (it'll be a little delayed: right\n    // before the second keystroke). Other input methods (e.g., paste) seem to\n    // fire selectionchange normally.\n    return getInstIfValueChanged(activeElementInst);\n  }\n}\n/**\n * SECTION: handle `click` event\n */\n\n\nfunction shouldUseClickEvent(elem) {\n  // Use the `click` event to detect changes to checkbox and radio inputs.\n  // This approach works across all browsers, whereas `change` does not fire\n  // until `blur` in IE8.\n  var nodeName = elem.nodeName;\n  return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');\n}\n\nfunction getTargetInstForClickEvent(topLevelType, targetInst) {\n  if (topLevelType === TOP_CLICK) {\n    return getInstIfValueChanged(targetInst);\n  }\n}\n\nfunction getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {\n  if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {\n    return getInstIfValueChanged(targetInst);\n  }\n}\n\nfunction handleControlledInputBlur(node) {\n  var state = node._wrapperState;\n\n  if (!state || !state.controlled || node.type !== 'number') {\n    return;\n  }\n\n  {\n    // If controlled, assign the value attribute to the current value on blur\n    setDefaultValue(node, 'number', node.value);\n  }\n}\n/**\n * This plugin creates an `onChange` event that normalizes change events\n * across form elements. This event fires at a time when it's possible to\n * change the element's value without seeing a flicker.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - select\n */\n\n\nvar ChangeEventPlugin = {\n  eventTypes: eventTypes$1,\n  _isInputEventSupported: isInputEventSupported,\n  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n    var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;\n    var getTargetInstFunc, handleEventFunc;\n\n    if (shouldUseChangeEvent(targetNode)) {\n      getTargetInstFunc = getTargetInstForChangeEvent;\n    } else if (isTextInputElement(targetNode)) {\n      if (isInputEventSupported) {\n        getTargetInstFunc = getTargetInstForInputOrChangeEvent;\n      } else {\n        getTargetInstFunc = getTargetInstForInputEventPolyfill;\n        handleEventFunc = handleEventsForInputEventPolyfill;\n      }\n    } else if (shouldUseClickEvent(targetNode)) {\n      getTargetInstFunc = getTargetInstForClickEvent;\n    }\n\n    if (getTargetInstFunc) {\n      var inst = getTargetInstFunc(topLevelType, targetInst);\n\n      if (inst) {\n        var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);\n        return event;\n      }\n    }\n\n    if (handleEventFunc) {\n      handleEventFunc(topLevelType, targetNode, targetInst);\n    } // When blurring, set the value attribute for number inputs\n\n\n    if (topLevelType === TOP_BLUR) {\n      handleControlledInputBlur(targetNode);\n    }\n  }\n};\n\nvar SyntheticUIEvent = SyntheticEvent.extend({\n  view: null,\n  detail: null\n});\n\n/**\n * Translation from modifier key to the associated property in the event.\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers\n */\nvar modifierKeyToProp = {\n  Alt: 'altKey',\n  Control: 'ctrlKey',\n  Meta: 'metaKey',\n  Shift: 'shiftKey'\n}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support\n// getModifierState. If getModifierState is not supported, we map it to a set of\n// modifier keys exposed by the event. In this case, Lock-keys are not supported.\n\nfunction modifierStateGetter(keyArg) {\n  var syntheticEvent = this;\n  var nativeEvent = syntheticEvent.nativeEvent;\n\n  if (nativeEvent.getModifierState) {\n    return nativeEvent.getModifierState(keyArg);\n  }\n\n  var keyProp = modifierKeyToProp[keyArg];\n  return keyProp ? !!nativeEvent[keyProp] : false;\n}\n\nfunction getEventModifierState(nativeEvent) {\n  return modifierStateGetter;\n}\n\nvar previousScreenX = 0;\nvar previousScreenY = 0; // Use flags to signal movementX/Y has already been set\n\nvar isMovementXSet = false;\nvar isMovementYSet = false;\n/**\n * @interface MouseEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar SyntheticMouseEvent = SyntheticUIEvent.extend({\n  screenX: null,\n  screenY: null,\n  clientX: null,\n  clientY: null,\n  pageX: null,\n  pageY: null,\n  ctrlKey: null,\n  shiftKey: null,\n  altKey: null,\n  metaKey: null,\n  getModifierState: getEventModifierState,\n  button: null,\n  buttons: null,\n  relatedTarget: function (event) {\n    return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);\n  },\n  movementX: function (event) {\n    if ('movementX' in event) {\n      return event.movementX;\n    }\n\n    var screenX = previousScreenX;\n    previousScreenX = event.screenX;\n\n    if (!isMovementXSet) {\n      isMovementXSet = true;\n      return 0;\n    }\n\n    return event.type === 'mousemove' ? event.screenX - screenX : 0;\n  },\n  movementY: function (event) {\n    if ('movementY' in event) {\n      return event.movementY;\n    }\n\n    var screenY = previousScreenY;\n    previousScreenY = event.screenY;\n\n    if (!isMovementYSet) {\n      isMovementYSet = true;\n      return 0;\n    }\n\n    return event.type === 'mousemove' ? event.screenY - screenY : 0;\n  }\n});\n\n/**\n * @interface PointerEvent\n * @see http://www.w3.org/TR/pointerevents/\n */\n\nvar SyntheticPointerEvent = SyntheticMouseEvent.extend({\n  pointerId: null,\n  width: null,\n  height: null,\n  pressure: null,\n  tangentialPressure: null,\n  tiltX: null,\n  tiltY: null,\n  twist: null,\n  pointerType: null,\n  isPrimary: null\n});\n\nvar eventTypes$2 = {\n  mouseEnter: {\n    registrationName: 'onMouseEnter',\n    dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]\n  },\n  mouseLeave: {\n    registrationName: 'onMouseLeave',\n    dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]\n  },\n  pointerEnter: {\n    registrationName: 'onPointerEnter',\n    dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]\n  },\n  pointerLeave: {\n    registrationName: 'onPointerLeave',\n    dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]\n  }\n};\nvar EnterLeaveEventPlugin = {\n  eventTypes: eventTypes$2,\n\n  /**\n   * For almost every interaction we care about, there will be both a top-level\n   * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that\n   * we do not extract duplicate events. However, moving the mouse into the\n   * browser from outside will not fire a `mouseout` event. In this case, we use\n   * the `mouseover` top-level event.\n   */\n  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n    var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;\n    var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;\n\n    if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0 && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {\n      // If this is an over event with a target, then we've already dispatched\n      // the event in the out event of the other target. If this is replayed,\n      // then it's because we couldn't dispatch against this target previously\n      // so we have to do it now instead.\n      return null;\n    }\n\n    if (!isOutEvent && !isOverEvent) {\n      // Must not be a mouse or pointer in or out - ignoring.\n      return null;\n    }\n\n    var win;\n\n    if (nativeEventTarget.window === nativeEventTarget) {\n      // `nativeEventTarget` is probably a window object.\n      win = nativeEventTarget;\n    } else {\n      // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.\n      var doc = nativeEventTarget.ownerDocument;\n\n      if (doc) {\n        win = doc.defaultView || doc.parentWindow;\n      } else {\n        win = window;\n      }\n    }\n\n    var from;\n    var to;\n\n    if (isOutEvent) {\n      from = targetInst;\n      var related = nativeEvent.relatedTarget || nativeEvent.toElement;\n      to = related ? getClosestInstanceFromNode(related) : null;\n\n      if (to !== null) {\n        var nearestMounted = getNearestMountedFiber(to);\n\n        if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {\n          to = null;\n        }\n      }\n    } else {\n      // Moving to a node from outside the window.\n      from = null;\n      to = targetInst;\n    }\n\n    if (from === to) {\n      // Nothing pertains to our managed components.\n      return null;\n    }\n\n    var eventInterface, leaveEventType, enterEventType, eventTypePrefix;\n\n    if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {\n      eventInterface = SyntheticMouseEvent;\n      leaveEventType = eventTypes$2.mouseLeave;\n      enterEventType = eventTypes$2.mouseEnter;\n      eventTypePrefix = 'mouse';\n    } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {\n      eventInterface = SyntheticPointerEvent;\n      leaveEventType = eventTypes$2.pointerLeave;\n      enterEventType = eventTypes$2.pointerEnter;\n      eventTypePrefix = 'pointer';\n    }\n\n    var fromNode = from == null ? win : getNodeFromInstance$1(from);\n    var toNode = to == null ? win : getNodeFromInstance$1(to);\n    var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);\n    leave.type = eventTypePrefix + 'leave';\n    leave.target = fromNode;\n    leave.relatedTarget = toNode;\n    var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);\n    enter.type = eventTypePrefix + 'enter';\n    enter.target = toNode;\n    enter.relatedTarget = fromNode;\n    accumulateEnterLeaveDispatches(leave, enter, from, to); // If we are not processing the first ancestor, then we\n    // should not process the same nativeEvent again, as we\n    // will have already processed it in the first ancestor.\n\n    if ((eventSystemFlags & IS_FIRST_ANCESTOR) === 0) {\n      return [leave];\n    }\n\n    return [leave, enter];\n  }\n};\n\n/**\n * inlined Object.is polyfill to avoid requiring consumers ship their own\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n */\nfunction is(x, y) {\n  return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare\n  ;\n}\n\nvar objectIs = typeof Object.is === 'function' ? Object.is : is;\n\nvar hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n/**\n * Performs equality by iterating through keys on an object and returning false\n * when any key has values which are not strictly equal between the arguments.\n * Returns true when the values of all keys are strictly equal.\n */\n\nfunction shallowEqual(objA, objB) {\n  if (objectIs(objA, objB)) {\n    return true;\n  }\n\n  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n    return false;\n  }\n\n  var keysA = Object.keys(objA);\n  var keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  } // Test for A's keys different from B.\n\n\n  for (var i = 0; i < keysA.length; i++) {\n    if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nvar skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;\nvar eventTypes$3 = {\n  select: {\n    phasedRegistrationNames: {\n      bubbled: 'onSelect',\n      captured: 'onSelectCapture'\n    },\n    dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]\n  }\n};\nvar activeElement$1 = null;\nvar activeElementInst$1 = null;\nvar lastSelection = null;\nvar mouseDown = false;\n/**\n * Get an object which is a unique representation of the current selection.\n *\n * The return value will not be consistent across nodes or browsers, but\n * two identical selections on the same node will return identical objects.\n *\n * @param {DOMElement} node\n * @return {object}\n */\n\nfunction getSelection$1(node) {\n  if ('selectionStart' in node && hasSelectionCapabilities(node)) {\n    return {\n      start: node.selectionStart,\n      end: node.selectionEnd\n    };\n  } else {\n    var win = node.ownerDocument && node.ownerDocument.defaultView || window;\n    var selection = win.getSelection();\n    return {\n      anchorNode: selection.anchorNode,\n      anchorOffset: selection.anchorOffset,\n      focusNode: selection.focusNode,\n      focusOffset: selection.focusOffset\n    };\n  }\n}\n/**\n * Get document associated with the event target.\n *\n * @param {object} nativeEventTarget\n * @return {Document}\n */\n\n\nfunction getEventTargetDocument(eventTarget) {\n  return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;\n}\n/**\n * Poll selection to see whether it's changed.\n *\n * @param {object} nativeEvent\n * @param {object} nativeEventTarget\n * @return {?SyntheticEvent}\n */\n\n\nfunction constructSelectEvent(nativeEvent, nativeEventTarget) {\n  // Ensure we have the right element, and that the user is not dragging a\n  // selection (this matches native `select` event behavior). In HTML5, select\n  // fires only on input and textarea thus if there's no focused element we\n  // won't dispatch.\n  var doc = getEventTargetDocument(nativeEventTarget);\n\n  if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {\n    return null;\n  } // Only fire when selection has actually changed.\n\n\n  var currentSelection = getSelection$1(activeElement$1);\n\n  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {\n    lastSelection = currentSelection;\n    var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);\n    syntheticEvent.type = 'select';\n    syntheticEvent.target = activeElement$1;\n    accumulateTwoPhaseDispatches(syntheticEvent);\n    return syntheticEvent;\n  }\n\n  return null;\n}\n/**\n * This plugin creates an `onSelect` event that normalizes select events\n * across form elements.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - contentEditable\n *\n * This differs from native browser implementations in the following ways:\n * - Fires on contentEditable fields as well as inputs.\n * - Fires for collapsed selection.\n * - Fires after user input.\n */\n\n\nvar SelectEventPlugin = {\n  eventTypes: eventTypes$3,\n  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, container) {\n    var containerOrDoc = container || getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do\n    // not extract events. See #3639.\n\n    if (!containerOrDoc || !isListeningToAllDependencies('onSelect', containerOrDoc)) {\n      return null;\n    }\n\n    var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;\n\n    switch (topLevelType) {\n      // Track the input node that has focus.\n      case TOP_FOCUS:\n        if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {\n          activeElement$1 = targetNode;\n          activeElementInst$1 = targetInst;\n          lastSelection = null;\n        }\n\n        break;\n\n      case TOP_BLUR:\n        activeElement$1 = null;\n        activeElementInst$1 = null;\n        lastSelection = null;\n        break;\n      // Don't fire the event while the user is dragging. This matches the\n      // semantics of the native select event.\n\n      case TOP_MOUSE_DOWN:\n        mouseDown = true;\n        break;\n\n      case TOP_CONTEXT_MENU:\n      case TOP_MOUSE_UP:\n      case TOP_DRAG_END:\n        mouseDown = false;\n        return constructSelectEvent(nativeEvent, nativeEventTarget);\n      // Chrome and IE fire non-standard event when selection is changed (and\n      // sometimes when it hasn't). IE's event fires out of order with respect\n      // to key and input events on deletion, so we discard it.\n      //\n      // Firefox doesn't support selectionchange, so check selection status\n      // after each key entry. The selection changes after keydown and before\n      // keyup, but we check on keydown as well in the case of holding down a\n      // key, when multiple keydown events are fired but only one keyup is.\n      // This is also our approach for IE handling, for the reason above.\n\n      case TOP_SELECTION_CHANGE:\n        if (skipSelectionChangeEvent) {\n          break;\n        }\n\n      // falls through\n\n      case TOP_KEY_DOWN:\n      case TOP_KEY_UP:\n        return constructSelectEvent(nativeEvent, nativeEventTarget);\n    }\n\n    return null;\n  }\n};\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface\n * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent\n */\n\nvar SyntheticAnimationEvent = SyntheticEvent.extend({\n  animationName: null,\n  elapsedTime: null,\n  pseudoElement: null\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/clipboard-apis/\n */\n\nvar SyntheticClipboardEvent = SyntheticEvent.extend({\n  clipboardData: function (event) {\n    return 'clipboardData' in event ? event.clipboardData : window.clipboardData;\n  }\n});\n\n/**\n * @interface FocusEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar SyntheticFocusEvent = SyntheticUIEvent.extend({\n  relatedTarget: null\n});\n\n/**\n * `charCode` represents the actual \"character code\" and is safe to use with\n * `String.fromCharCode`. As such, only keys that correspond to printable\n * characters produce a valid `charCode`, the only exception to this is Enter.\n * The Tab-key is considered non-printable and does not have a `charCode`,\n * presumably because it does not produce a tab-character in browsers.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {number} Normalized `charCode` property.\n */\nfunction getEventCharCode(nativeEvent) {\n  var charCode;\n  var keyCode = nativeEvent.keyCode;\n\n  if ('charCode' in nativeEvent) {\n    charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.\n\n    if (charCode === 0 && keyCode === 13) {\n      charCode = 13;\n    }\n  } else {\n    // IE8 does not implement `charCode`, but `keyCode` has the correct value.\n    charCode = keyCode;\n  } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)\n  // report Enter as charCode 10 when ctrl is pressed.\n\n\n  if (charCode === 10) {\n    charCode = 13;\n  } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.\n  // Must not discard the (non-)printable Enter-key.\n\n\n  if (charCode >= 32 || charCode === 13) {\n    return charCode;\n  }\n\n  return 0;\n}\n\n/**\n * Normalization of deprecated HTML5 `key` values\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\n\nvar normalizeKey = {\n  Esc: 'Escape',\n  Spacebar: ' ',\n  Left: 'ArrowLeft',\n  Up: 'ArrowUp',\n  Right: 'ArrowRight',\n  Down: 'ArrowDown',\n  Del: 'Delete',\n  Win: 'OS',\n  Menu: 'ContextMenu',\n  Apps: 'ContextMenu',\n  Scroll: 'ScrollLock',\n  MozPrintableKey: 'Unidentified'\n};\n/**\n * Translation from legacy `keyCode` to HTML5 `key`\n * Only special keys supported, all others depend on keyboard layout or browser\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\n\nvar translateToKey = {\n  '8': 'Backspace',\n  '9': 'Tab',\n  '12': 'Clear',\n  '13': 'Enter',\n  '16': 'Shift',\n  '17': 'Control',\n  '18': 'Alt',\n  '19': 'Pause',\n  '20': 'CapsLock',\n  '27': 'Escape',\n  '32': ' ',\n  '33': 'PageUp',\n  '34': 'PageDown',\n  '35': 'End',\n  '36': 'Home',\n  '37': 'ArrowLeft',\n  '38': 'ArrowUp',\n  '39': 'ArrowRight',\n  '40': 'ArrowDown',\n  '45': 'Insert',\n  '46': 'Delete',\n  '112': 'F1',\n  '113': 'F2',\n  '114': 'F3',\n  '115': 'F4',\n  '116': 'F5',\n  '117': 'F6',\n  '118': 'F7',\n  '119': 'F8',\n  '120': 'F9',\n  '121': 'F10',\n  '122': 'F11',\n  '123': 'F12',\n  '144': 'NumLock',\n  '145': 'ScrollLock',\n  '224': 'Meta'\n};\n/**\n * @param {object} nativeEvent Native browser event.\n * @return {string} Normalized `key` property.\n */\n\nfunction getEventKey(nativeEvent) {\n  if (nativeEvent.key) {\n    // Normalize inconsistent values reported by browsers due to\n    // implementations of a working draft specification.\n    // FireFox implements `key` but returns `MozPrintableKey` for all\n    // printable characters (normalized to `Unidentified`), ignore it.\n    var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n\n    if (key !== 'Unidentified') {\n      return key;\n    }\n  } // Browser does not implement `key`, polyfill as much of it as we can.\n\n\n  if (nativeEvent.type === 'keypress') {\n    var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can\n    // thus be captured by `keypress`, no other non-printable key should.\n\n    return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);\n  }\n\n  if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {\n    // While user keyboard layout determines the actual meaning of each\n    // `keyCode` value, almost all function keys have a universal value.\n    return translateToKey[nativeEvent.keyCode] || 'Unidentified';\n  }\n\n  return '';\n}\n\n/**\n * @interface KeyboardEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar SyntheticKeyboardEvent = SyntheticUIEvent.extend({\n  key: getEventKey,\n  location: null,\n  ctrlKey: null,\n  shiftKey: null,\n  altKey: null,\n  metaKey: null,\n  repeat: null,\n  locale: null,\n  getModifierState: getEventModifierState,\n  // Legacy Interface\n  charCode: function (event) {\n    // `charCode` is the result of a KeyPress event and represents the value of\n    // the actual printable character.\n    // KeyPress is deprecated, but its replacement is not yet final and not\n    // implemented in any major browser. Only KeyPress has charCode.\n    if (event.type === 'keypress') {\n      return getEventCharCode(event);\n    }\n\n    return 0;\n  },\n  keyCode: function (event) {\n    // `keyCode` is the result of a KeyDown/Up event and represents the value of\n    // physical keyboard key.\n    // The actual meaning of the value depends on the users' keyboard layout\n    // which cannot be detected. Assuming that it is a US keyboard layout\n    // provides a surprisingly accurate mapping for US and European users.\n    // Due to this, it is left to the user to implement at this time.\n    if (event.type === 'keydown' || event.type === 'keyup') {\n      return event.keyCode;\n    }\n\n    return 0;\n  },\n  which: function (event) {\n    // `which` is an alias for either `keyCode` or `charCode` depending on the\n    // type of the event.\n    if (event.type === 'keypress') {\n      return getEventCharCode(event);\n    }\n\n    if (event.type === 'keydown' || event.type === 'keyup') {\n      return event.keyCode;\n    }\n\n    return 0;\n  }\n});\n\n/**\n * @interface DragEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar SyntheticDragEvent = SyntheticMouseEvent.extend({\n  dataTransfer: null\n});\n\n/**\n * @interface TouchEvent\n * @see http://www.w3.org/TR/touch-events/\n */\n\nvar SyntheticTouchEvent = SyntheticUIEvent.extend({\n  touches: null,\n  targetTouches: null,\n  changedTouches: null,\n  altKey: null,\n  metaKey: null,\n  ctrlKey: null,\n  shiftKey: null,\n  getModifierState: getEventModifierState\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-\n * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent\n */\n\nvar SyntheticTransitionEvent = SyntheticEvent.extend({\n  propertyName: null,\n  elapsedTime: null,\n  pseudoElement: null\n});\n\n/**\n * @interface WheelEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\n\nvar SyntheticWheelEvent = SyntheticMouseEvent.extend({\n  deltaX: function (event) {\n    return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).\n    'wheelDeltaX' in event ? -event.wheelDeltaX : 0;\n  },\n  deltaY: function (event) {\n    return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).\n    'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).\n    'wheelDelta' in event ? -event.wheelDelta : 0;\n  },\n  deltaZ: null,\n  // Browsers without \"deltaMode\" is reporting in raw wheel delta where one\n  // notch on the scroll is always +/- 120, roughly equivalent to pixels.\n  // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or\n  // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.\n  deltaMode: null\n});\n\nvar knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];\nvar SimpleEventPlugin = {\n  // simpleEventPluginEventTypes gets populated from\n  // the DOMEventProperties module.\n  eventTypes: simpleEventPluginEventTypes,\n  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {\n    var dispatchConfig = topLevelEventsToDispatchConfig.get(topLevelType);\n\n    if (!dispatchConfig) {\n      return null;\n    }\n\n    var EventConstructor;\n\n    switch (topLevelType) {\n      case TOP_KEY_PRESS:\n        // Firefox creates a keypress event for function keys too. This removes\n        // the unwanted keypress events. Enter is however both printable and\n        // non-printable. One would expect Tab to be as well (but it isn't).\n        if (getEventCharCode(nativeEvent) === 0) {\n          return null;\n        }\n\n      /* falls through */\n\n      case TOP_KEY_DOWN:\n      case TOP_KEY_UP:\n        EventConstructor = SyntheticKeyboardEvent;\n        break;\n\n      case TOP_BLUR:\n      case TOP_FOCUS:\n        EventConstructor = SyntheticFocusEvent;\n        break;\n\n      case TOP_CLICK:\n        // Firefox creates a click event on right mouse clicks. This removes the\n        // unwanted click events.\n        if (nativeEvent.button === 2) {\n          return null;\n        }\n\n      /* falls through */\n\n      case TOP_AUX_CLICK:\n      case TOP_DOUBLE_CLICK:\n      case TOP_MOUSE_DOWN:\n      case TOP_MOUSE_MOVE:\n      case TOP_MOUSE_UP: // TODO: Disabled elements should not respond to mouse events\n\n      /* falls through */\n\n      case TOP_MOUSE_OUT:\n      case TOP_MOUSE_OVER:\n      case TOP_CONTEXT_MENU:\n        EventConstructor = SyntheticMouseEvent;\n        break;\n\n      case TOP_DRAG:\n      case TOP_DRAG_END:\n      case TOP_DRAG_ENTER:\n      case TOP_DRAG_EXIT:\n      case TOP_DRAG_LEAVE:\n      case TOP_DRAG_OVER:\n      case TOP_DRAG_START:\n      case TOP_DROP:\n        EventConstructor = SyntheticDragEvent;\n        break;\n\n      case TOP_TOUCH_CANCEL:\n      case TOP_TOUCH_END:\n      case TOP_TOUCH_MOVE:\n      case TOP_TOUCH_START:\n        EventConstructor = SyntheticTouchEvent;\n        break;\n\n      case TOP_ANIMATION_END:\n      case TOP_ANIMATION_ITERATION:\n      case TOP_ANIMATION_START:\n        EventConstructor = SyntheticAnimationEvent;\n        break;\n\n      case TOP_TRANSITION_END:\n        EventConstructor = SyntheticTransitionEvent;\n        break;\n\n      case TOP_SCROLL:\n        EventConstructor = SyntheticUIEvent;\n        break;\n\n      case TOP_WHEEL:\n        EventConstructor = SyntheticWheelEvent;\n        break;\n\n      case TOP_COPY:\n      case TOP_CUT:\n      case TOP_PASTE:\n        EventConstructor = SyntheticClipboardEvent;\n        break;\n\n      case TOP_GOT_POINTER_CAPTURE:\n      case TOP_LOST_POINTER_CAPTURE:\n      case TOP_POINTER_CANCEL:\n      case TOP_POINTER_DOWN:\n      case TOP_POINTER_MOVE:\n      case TOP_POINTER_OUT:\n      case TOP_POINTER_OVER:\n      case TOP_POINTER_UP:\n        EventConstructor = SyntheticPointerEvent;\n        break;\n\n      default:\n        {\n          if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {\n            error('SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);\n          }\n        } // HTML Events\n        // @see http://www.w3.org/TR/html5/index.html#events-0\n\n\n        EventConstructor = SyntheticEvent;\n        break;\n    }\n\n    var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);\n    accumulateTwoPhaseDispatches(event);\n    return event;\n  }\n};\n\n/**\n * Specifies a deterministic ordering of `EventPlugin`s. A convenient way to\n * reason about plugins, without having to package every one of them. This\n * is better than having plugins be ordered in the same order that they\n * are injected because that ordering would be influenced by the packaging order.\n * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that\n * preventing default on events is convenient in `SimpleEventPlugin` handlers.\n */\n\nvar DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];\n/**\n * Inject modules for resolving DOM hierarchy and plugin ordering.\n */\n\ninjectEventPluginOrder(DOMEventPluginOrder);\nsetComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);\n/**\n * Some important event plugins included by default (without having to require\n * them).\n */\n\ninjectEventPluginsByName({\n  SimpleEventPlugin: SimpleEventPlugin,\n  EnterLeaveEventPlugin: EnterLeaveEventPlugin,\n  ChangeEventPlugin: ChangeEventPlugin,\n  SelectEventPlugin: SelectEventPlugin,\n  BeforeInputEventPlugin: BeforeInputEventPlugin\n});\n\n// Prefix measurements so that it's possible to filter them.\n// Longer prefixes are hard to read in DevTools.\nvar reactEmoji = \"\\u269B\";\nvar warningEmoji = \"\\u26D4\";\nvar supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.\n// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?\n\nvar currentFiber = null; // If we're in the middle of user code, which fiber and method is it?\n// Reusing `currentFiber` would be confusing for this because user code fiber\n// can change during commit phase too, but we don't need to unwind it (since\n// lifecycles in the commit phase don't resemble a tree).\n\nvar currentPhase = null;\nvar currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,\n// so we will keep track of it, and include it in the report.\n// Track commits caused by cascading updates.\n\nvar isCommitting = false;\nvar hasScheduledUpdateInCurrentCommit = false;\nvar hasScheduledUpdateInCurrentPhase = false;\nvar commitCountInCurrentWorkLoop = 0;\nvar effectCountInCurrentCommit = 0;\n// to avoid stretch the commit phase with measurement overhead.\n\nvar labelsInCurrentCommit = new Set();\n\nvar formatMarkName = function (markName) {\n  return reactEmoji + \" \" + markName;\n};\n\nvar formatLabel = function (label, warning) {\n  var prefix = warning ? warningEmoji + \" \" : reactEmoji + \" \";\n  var suffix = warning ? \" Warning: \" + warning : '';\n  return \"\" + prefix + label + suffix;\n};\n\nvar beginMark = function (markName) {\n  performance.mark(formatMarkName(markName));\n};\n\nvar clearMark = function (markName) {\n  performance.clearMarks(formatMarkName(markName));\n};\n\nvar endMark = function (label, markName, warning) {\n  var formattedMarkName = formatMarkName(markName);\n  var formattedLabel = formatLabel(label, warning);\n\n  try {\n    performance.measure(formattedLabel, formattedMarkName);\n  } catch (err) {} // If previous mark was missing for some reason, this will throw.\n  // This could only happen if React crashed in an unexpected place earlier.\n  // Don't pile on with more errors.\n  // Clear marks immediately to avoid growing buffer.\n\n\n  performance.clearMarks(formattedMarkName);\n  performance.clearMeasures(formattedLabel);\n};\n\nvar getFiberMarkName = function (label, debugID) {\n  return label + \" (#\" + debugID + \")\";\n};\n\nvar getFiberLabel = function (componentName, isMounted, phase) {\n  if (phase === null) {\n    // These are composite component total time measurements.\n    return componentName + \" [\" + (isMounted ? 'update' : 'mount') + \"]\";\n  } else {\n    // Composite component methods.\n    return componentName + \".\" + phase;\n  }\n};\n\nvar beginFiberMark = function (fiber, phase) {\n  var componentName = getComponentName(fiber.type) || 'Unknown';\n  var debugID = fiber._debugID;\n  var isMounted = fiber.alternate !== null;\n  var label = getFiberLabel(componentName, isMounted, phase);\n\n  if (isCommitting && labelsInCurrentCommit.has(label)) {\n    // During the commit phase, we don't show duplicate labels because\n    // there is a fixed overhead for every measurement, and we don't\n    // want to stretch the commit phase beyond necessary.\n    return false;\n  }\n\n  labelsInCurrentCommit.add(label);\n  var markName = getFiberMarkName(label, debugID);\n  beginMark(markName);\n  return true;\n};\n\nvar clearFiberMark = function (fiber, phase) {\n  var componentName = getComponentName(fiber.type) || 'Unknown';\n  var debugID = fiber._debugID;\n  var isMounted = fiber.alternate !== null;\n  var label = getFiberLabel(componentName, isMounted, phase);\n  var markName = getFiberMarkName(label, debugID);\n  clearMark(markName);\n};\n\nvar endFiberMark = function (fiber, phase, warning) {\n  var componentName = getComponentName(fiber.type) || 'Unknown';\n  var debugID = fiber._debugID;\n  var isMounted = fiber.alternate !== null;\n  var label = getFiberLabel(componentName, isMounted, phase);\n  var markName = getFiberMarkName(label, debugID);\n  endMark(label, markName, warning);\n};\n\nvar shouldIgnoreFiber = function (fiber) {\n  // Host components should be skipped in the timeline.\n  // We could check typeof fiber.type, but does this work with RN?\n  switch (fiber.tag) {\n    case HostRoot:\n    case HostComponent:\n    case HostText:\n    case HostPortal:\n    case Fragment:\n    case ContextProvider:\n    case ContextConsumer:\n    case Mode:\n      return true;\n\n    default:\n      return false;\n  }\n};\n\nvar clearPendingPhaseMeasurement = function () {\n  if (currentPhase !== null && currentPhaseFiber !== null) {\n    clearFiberMark(currentPhaseFiber, currentPhase);\n  }\n\n  currentPhaseFiber = null;\n  currentPhase = null;\n  hasScheduledUpdateInCurrentPhase = false;\n};\n\nvar pauseTimers = function () {\n  // Stops all currently active measurements so that they can be resumed\n  // if we continue in a later deferred loop from the same unit of work.\n  var fiber = currentFiber;\n\n  while (fiber) {\n    if (fiber._debugIsCurrentlyTiming) {\n      endFiberMark(fiber, null, null);\n    }\n\n    fiber = fiber.return;\n  }\n};\n\nvar resumeTimersRecursively = function (fiber) {\n  if (fiber.return !== null) {\n    resumeTimersRecursively(fiber.return);\n  }\n\n  if (fiber._debugIsCurrentlyTiming) {\n    beginFiberMark(fiber, null);\n  }\n};\n\nvar resumeTimers = function () {\n  // Resumes all measurements that were active during the last deferred loop.\n  if (currentFiber !== null) {\n    resumeTimersRecursively(currentFiber);\n  }\n};\n\nfunction recordEffect() {\n  {\n    effectCountInCurrentCommit++;\n  }\n}\nfunction recordScheduleUpdate() {\n  {\n    if (isCommitting) {\n      hasScheduledUpdateInCurrentCommit = true;\n    }\n\n    if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {\n      hasScheduledUpdateInCurrentPhase = true;\n    }\n  }\n}\nfunction startWorkTimer(fiber) {\n  {\n    if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {\n      return;\n    } // If we pause, this is the fiber to unwind from.\n\n\n    currentFiber = fiber;\n\n    if (!beginFiberMark(fiber, null)) {\n      return;\n    }\n\n    fiber._debugIsCurrentlyTiming = true;\n  }\n}\nfunction cancelWorkTimer(fiber) {\n  {\n    if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {\n      return;\n    } // Remember we shouldn't complete measurement for this fiber.\n    // Otherwise flamechart will be deep even for small updates.\n\n\n    fiber._debugIsCurrentlyTiming = false;\n    clearFiberMark(fiber, null);\n  }\n}\nfunction stopWorkTimer(fiber) {\n  {\n    if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {\n      return;\n    } // If we pause, its parent is the fiber to unwind from.\n\n\n    currentFiber = fiber.return;\n\n    if (!fiber._debugIsCurrentlyTiming) {\n      return;\n    }\n\n    fiber._debugIsCurrentlyTiming = false;\n    endFiberMark(fiber, null, null);\n  }\n}\nfunction stopFailedWorkTimer(fiber) {\n  {\n    if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {\n      return;\n    } // If we pause, its parent is the fiber to unwind from.\n\n\n    currentFiber = fiber.return;\n\n    if (!fiber._debugIsCurrentlyTiming) {\n      return;\n    }\n\n    fiber._debugIsCurrentlyTiming = false;\n    var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';\n    endFiberMark(fiber, null, warning);\n  }\n}\nfunction startPhaseTimer(fiber, phase) {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    clearPendingPhaseMeasurement();\n\n    if (!beginFiberMark(fiber, phase)) {\n      return;\n    }\n\n    currentPhaseFiber = fiber;\n    currentPhase = phase;\n  }\n}\nfunction stopPhaseTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    if (currentPhase !== null && currentPhaseFiber !== null) {\n      var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;\n      endFiberMark(currentPhaseFiber, currentPhase, warning);\n    }\n\n    currentPhase = null;\n    currentPhaseFiber = null;\n  }\n}\nfunction startWorkLoopTimer(nextUnitOfWork) {\n  {\n    currentFiber = nextUnitOfWork;\n\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    commitCountInCurrentWorkLoop = 0; // This is top level call.\n    // Any other measurements are performed within.\n\n    beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.\n\n    resumeTimers();\n  }\n}\nfunction stopWorkLoopTimer(interruptedBy, didCompleteRoot) {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    var warning = null;\n\n    if (interruptedBy !== null) {\n      if (interruptedBy.tag === HostRoot) {\n        warning = 'A top-level update interrupted the previous render';\n      } else {\n        var componentName = getComponentName(interruptedBy.type) || 'Unknown';\n        warning = \"An update to \" + componentName + \" interrupted the previous render\";\n      }\n    } else if (commitCountInCurrentWorkLoop > 1) {\n      warning = 'There were cascading updates';\n    }\n\n    commitCountInCurrentWorkLoop = 0;\n    var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.\n\n    pauseTimers();\n    endMark(label, '(React Tree Reconciliation)', warning);\n  }\n}\nfunction startCommitTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    isCommitting = true;\n    hasScheduledUpdateInCurrentCommit = false;\n    labelsInCurrentCommit.clear();\n    beginMark('(Committing Changes)');\n  }\n}\nfunction stopCommitTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    var warning = null;\n\n    if (hasScheduledUpdateInCurrentCommit) {\n      warning = 'Lifecycle hook scheduled a cascading update';\n    } else if (commitCountInCurrentWorkLoop > 0) {\n      warning = 'Caused by a cascading update in earlier commit';\n    }\n\n    hasScheduledUpdateInCurrentCommit = false;\n    commitCountInCurrentWorkLoop++;\n    isCommitting = false;\n    labelsInCurrentCommit.clear();\n    endMark('(Committing Changes)', '(Committing Changes)', warning);\n  }\n}\nfunction startCommitSnapshotEffectsTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    effectCountInCurrentCommit = 0;\n    beginMark('(Committing Snapshot Effects)');\n  }\n}\nfunction stopCommitSnapshotEffectsTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    var count = effectCountInCurrentCommit;\n    effectCountInCurrentCommit = 0;\n    endMark(\"(Committing Snapshot Effects: \" + count + \" Total)\", '(Committing Snapshot Effects)', null);\n  }\n}\nfunction startCommitHostEffectsTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    effectCountInCurrentCommit = 0;\n    beginMark('(Committing Host Effects)');\n  }\n}\nfunction stopCommitHostEffectsTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    var count = effectCountInCurrentCommit;\n    effectCountInCurrentCommit = 0;\n    endMark(\"(Committing Host Effects: \" + count + \" Total)\", '(Committing Host Effects)', null);\n  }\n}\nfunction startCommitLifeCyclesTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    effectCountInCurrentCommit = 0;\n    beginMark('(Calling Lifecycle Methods)');\n  }\n}\nfunction stopCommitLifeCyclesTimer() {\n  {\n    if (!supportsUserTiming) {\n      return;\n    }\n\n    var count = effectCountInCurrentCommit;\n    effectCountInCurrentCommit = 0;\n    endMark(\"(Calling Lifecycle Methods: \" + count + \" Total)\", '(Calling Lifecycle Methods)', null);\n  }\n}\n\nvar valueStack = [];\nvar fiberStack;\n\n{\n  fiberStack = [];\n}\n\nvar index = -1;\n\nfunction createCursor(defaultValue) {\n  return {\n    current: defaultValue\n  };\n}\n\nfunction pop(cursor, fiber) {\n  if (index < 0) {\n    {\n      error('Unexpected pop.');\n    }\n\n    return;\n  }\n\n  {\n    if (fiber !== fiberStack[index]) {\n      error('Unexpected Fiber popped.');\n    }\n  }\n\n  cursor.current = valueStack[index];\n  valueStack[index] = null;\n\n  {\n    fiberStack[index] = null;\n  }\n\n  index--;\n}\n\nfunction push(cursor, value, fiber) {\n  index++;\n  valueStack[index] = cursor.current;\n\n  {\n    fiberStack[index] = fiber;\n  }\n\n  cursor.current = value;\n}\n\nvar warnedAboutMissingGetChildContext;\n\n{\n  warnedAboutMissingGetChildContext = {};\n}\n\nvar emptyContextObject = {};\n\n{\n  Object.freeze(emptyContextObject);\n} // A cursor to the current merged context object on the stack.\n\n\nvar contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.\n\nvar didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.\n// We use this to get access to the parent context after we have already\n// pushed the next context provider, and now need to merge their contexts.\n\nvar previousContext = emptyContextObject;\n\nfunction getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {\n  {\n    if (didPushOwnContextIfProvider && isContextProvider(Component)) {\n      // If the fiber is a context provider itself, when we read its context\n      // we may have already pushed its own child context on the stack. A context\n      // provider should not \"see\" its own child context. Therefore we read the\n      // previous (parent) context instead for a context provider.\n      return previousContext;\n    }\n\n    return contextStackCursor.current;\n  }\n}\n\nfunction cacheContext(workInProgress, unmaskedContext, maskedContext) {\n  {\n    var instance = workInProgress.stateNode;\n    instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;\n    instance.__reactInternalMemoizedMaskedChildContext = maskedContext;\n  }\n}\n\nfunction getMaskedContext(workInProgress, unmaskedContext) {\n  {\n    var type = workInProgress.type;\n    var contextTypes = type.contextTypes;\n\n    if (!contextTypes) {\n      return emptyContextObject;\n    } // Avoid recreating masked context unless unmasked context has changed.\n    // Failing to do this will result in unnecessary calls to componentWillReceiveProps.\n    // This may trigger infinite loops if componentWillReceiveProps calls setState.\n\n\n    var instance = workInProgress.stateNode;\n\n    if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {\n      return instance.__reactInternalMemoizedMaskedChildContext;\n    }\n\n    var context = {};\n\n    for (var key in contextTypes) {\n      context[key] = unmaskedContext[key];\n    }\n\n    {\n      var name = getComponentName(type) || 'Unknown';\n      checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);\n    } // Cache unmasked context so we can avoid recreating masked context unless necessary.\n    // Context is created before the class component is instantiated so check for instance.\n\n\n    if (instance) {\n      cacheContext(workInProgress, unmaskedContext, context);\n    }\n\n    return context;\n  }\n}\n\nfunction hasContextChanged() {\n  {\n    return didPerformWorkStackCursor.current;\n  }\n}\n\nfunction isContextProvider(type) {\n  {\n    var childContextTypes = type.childContextTypes;\n    return childContextTypes !== null && childContextTypes !== undefined;\n  }\n}\n\nfunction popContext(fiber) {\n  {\n    pop(didPerformWorkStackCursor, fiber);\n    pop(contextStackCursor, fiber);\n  }\n}\n\nfunction popTopLevelContextObject(fiber) {\n  {\n    pop(didPerformWorkStackCursor, fiber);\n    pop(contextStackCursor, fiber);\n  }\n}\n\nfunction pushTopLevelContextObject(fiber, context, didChange) {\n  {\n    if (!(contextStackCursor.current === emptyContextObject)) {\n      {\n        throw Error( \"Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n\n    push(contextStackCursor, context, fiber);\n    push(didPerformWorkStackCursor, didChange, fiber);\n  }\n}\n\nfunction processChildContext(fiber, type, parentContext) {\n  {\n    var instance = fiber.stateNode;\n    var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.\n    // It has only been added in Fiber to match the (unintentional) behavior in Stack.\n\n    if (typeof instance.getChildContext !== 'function') {\n      {\n        var componentName = getComponentName(type) || 'Unknown';\n\n        if (!warnedAboutMissingGetChildContext[componentName]) {\n          warnedAboutMissingGetChildContext[componentName] = true;\n\n          error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);\n        }\n      }\n\n      return parentContext;\n    }\n\n    var childContext;\n    startPhaseTimer(fiber, 'getChildContext');\n    childContext = instance.getChildContext();\n    stopPhaseTimer();\n\n    for (var contextKey in childContext) {\n      if (!(contextKey in childContextTypes)) {\n        {\n          throw Error( (getComponentName(type) || 'Unknown') + \".getChildContext(): key \\\"\" + contextKey + \"\\\" is not defined in childContextTypes.\" );\n        }\n      }\n    }\n\n    {\n      var name = getComponentName(type) || 'Unknown';\n      checkPropTypes(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when\n      // somebody calls unstable_renderSubtreeIntoContainer() and we process\n      // context from the parent component instance. The stack will be missing\n      // because it's outside of the reconciliation, and so the pointer has not\n      // been set. This is rare and doesn't matter. We'll also remove that API.\n      getCurrentFiberStackInDev);\n    }\n\n    return _assign({}, parentContext, {}, childContext);\n  }\n}\n\nfunction pushContextProvider(workInProgress) {\n  {\n    var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.\n    // If the instance does not exist yet, we will push null at first,\n    // and replace it on the stack later when invalidating the context.\n\n    var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.\n    // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.\n\n    previousContext = contextStackCursor.current;\n    push(contextStackCursor, memoizedMergedChildContext, workInProgress);\n    push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);\n    return true;\n  }\n}\n\nfunction invalidateContextProvider(workInProgress, type, didChange) {\n  {\n    var instance = workInProgress.stateNode;\n\n    if (!instance) {\n      {\n        throw Error( \"Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n\n    if (didChange) {\n      // Merge parent and own context.\n      // Skip this if we're not updating due to sCU.\n      // This avoids unnecessarily recomputing memoized values.\n      var mergedContext = processChildContext(workInProgress, type, previousContext);\n      instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.\n      // It is important to unwind the context in the reverse order.\n\n      pop(didPerformWorkStackCursor, workInProgress);\n      pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.\n\n      push(contextStackCursor, mergedContext, workInProgress);\n      push(didPerformWorkStackCursor, didChange, workInProgress);\n    } else {\n      pop(didPerformWorkStackCursor, workInProgress);\n      push(didPerformWorkStackCursor, didChange, workInProgress);\n    }\n  }\n}\n\nfunction findCurrentUnmaskedContext(fiber) {\n  {\n    // Currently this is only used with renderSubtreeIntoContainer; not sure if it\n    // makes sense elsewhere\n    if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {\n      {\n        throw Error( \"Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n\n    var node = fiber;\n\n    do {\n      switch (node.tag) {\n        case HostRoot:\n          return node.stateNode.context;\n\n        case ClassComponent:\n          {\n            var Component = node.type;\n\n            if (isContextProvider(Component)) {\n              return node.stateNode.__reactInternalMemoizedMergedChildContext;\n            }\n\n            break;\n          }\n      }\n\n      node = node.return;\n    } while (node !== null);\n\n    {\n      {\n        throw Error( \"Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n  }\n}\n\nvar LegacyRoot = 0;\nvar BlockingRoot = 1;\nvar ConcurrentRoot = 2;\n\nvar Scheduler_runWithPriority = Scheduler.unstable_runWithPriority,\n    Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback,\n    Scheduler_cancelCallback = Scheduler.unstable_cancelCallback,\n    Scheduler_shouldYield = Scheduler.unstable_shouldYield,\n    Scheduler_requestPaint = Scheduler.unstable_requestPaint,\n    Scheduler_now = Scheduler.unstable_now,\n    Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,\n    Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority,\n    Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,\n    Scheduler_NormalPriority = Scheduler.unstable_NormalPriority,\n    Scheduler_LowPriority = Scheduler.unstable_LowPriority,\n    Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;\n\n{\n  // Provide explicit error message when production+profiling bundle of e.g.\n  // react-dom is used with production (non-profiling) bundle of\n  // scheduler/tracing\n  if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {\n    {\n      throw Error( \"It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling\" );\n    }\n  }\n}\n\nvar fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use\n// ascending numbers so we can compare them like numbers. They start at 90 to\n// avoid clashing with Scheduler's priorities.\n\nvar ImmediatePriority = 99;\nvar UserBlockingPriority$1 = 98;\nvar NormalPriority = 97;\nvar LowPriority = 96;\nvar IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.\n\nvar NoPriority = 90;\nvar shouldYield = Scheduler_shouldYield;\nvar requestPaint = // Fall back gracefully if we're running an older version of Scheduler.\nScheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};\nvar syncQueue = null;\nvar immediateQueueCallbackNode = null;\nvar isFlushingSyncQueue = false;\nvar initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.\n// This will be the case for modern browsers that support `performance.now`. In\n// older browsers, Scheduler falls back to `Date.now`, which returns a Unix\n// timestamp. In that case, subtract the module initialization time to simulate\n// the behavior of performance.now and keep our times small enough to fit\n// within 32 bits.\n// TODO: Consider lifting this into Scheduler.\n\nvar now = initialTimeMs < 10000 ? Scheduler_now : function () {\n  return Scheduler_now() - initialTimeMs;\n};\nfunction getCurrentPriorityLevel() {\n  switch (Scheduler_getCurrentPriorityLevel()) {\n    case Scheduler_ImmediatePriority:\n      return ImmediatePriority;\n\n    case Scheduler_UserBlockingPriority:\n      return UserBlockingPriority$1;\n\n    case Scheduler_NormalPriority:\n      return NormalPriority;\n\n    case Scheduler_LowPriority:\n      return LowPriority;\n\n    case Scheduler_IdlePriority:\n      return IdlePriority;\n\n    default:\n      {\n        {\n          throw Error( \"Unknown priority level.\" );\n        }\n      }\n\n  }\n}\n\nfunction reactPriorityToSchedulerPriority(reactPriorityLevel) {\n  switch (reactPriorityLevel) {\n    case ImmediatePriority:\n      return Scheduler_ImmediatePriority;\n\n    case UserBlockingPriority$1:\n      return Scheduler_UserBlockingPriority;\n\n    case NormalPriority:\n      return Scheduler_NormalPriority;\n\n    case LowPriority:\n      return Scheduler_LowPriority;\n\n    case IdlePriority:\n      return Scheduler_IdlePriority;\n\n    default:\n      {\n        {\n          throw Error( \"Unknown priority level.\" );\n        }\n      }\n\n  }\n}\n\nfunction runWithPriority$1(reactPriorityLevel, fn) {\n  var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);\n  return Scheduler_runWithPriority(priorityLevel, fn);\n}\nfunction scheduleCallback(reactPriorityLevel, callback, options) {\n  var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);\n  return Scheduler_scheduleCallback(priorityLevel, callback, options);\n}\nfunction scheduleSyncCallback(callback) {\n  // Push this callback into an internal queue. We'll flush these either in\n  // the next tick, or earlier if something calls `flushSyncCallbackQueue`.\n  if (syncQueue === null) {\n    syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.\n\n    immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);\n  } else {\n    // Push onto existing queue. Don't need to schedule a callback because\n    // we already scheduled one when we created the queue.\n    syncQueue.push(callback);\n  }\n\n  return fakeCallbackNode;\n}\nfunction cancelCallback(callbackNode) {\n  if (callbackNode !== fakeCallbackNode) {\n    Scheduler_cancelCallback(callbackNode);\n  }\n}\nfunction flushSyncCallbackQueue() {\n  if (immediateQueueCallbackNode !== null) {\n    var node = immediateQueueCallbackNode;\n    immediateQueueCallbackNode = null;\n    Scheduler_cancelCallback(node);\n  }\n\n  flushSyncCallbackQueueImpl();\n}\n\nfunction flushSyncCallbackQueueImpl() {\n  if (!isFlushingSyncQueue && syncQueue !== null) {\n    // Prevent re-entrancy.\n    isFlushingSyncQueue = true;\n    var i = 0;\n\n    try {\n      var _isSync = true;\n      var queue = syncQueue;\n      runWithPriority$1(ImmediatePriority, function () {\n        for (; i < queue.length; i++) {\n          var callback = queue[i];\n\n          do {\n            callback = callback(_isSync);\n          } while (callback !== null);\n        }\n      });\n      syncQueue = null;\n    } catch (error) {\n      // If something throws, leave the remaining callbacks on the queue.\n      if (syncQueue !== null) {\n        syncQueue = syncQueue.slice(i + 1);\n      } // Resume flushing in the next tick\n\n\n      Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);\n      throw error;\n    } finally {\n      isFlushingSyncQueue = false;\n    }\n  }\n}\n\nvar NoMode = 0;\nvar StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root\n// tag instead\n\nvar BlockingMode = 2;\nvar ConcurrentMode = 4;\nvar ProfileMode = 8;\n\n// Max 31 bit integer. The max integer size in V8 for 32-bit systems.\n// Math.pow(2, 30) - 1\n// 0b111111111111111111111111111111\nvar MAX_SIGNED_31_BIT_INT = 1073741823;\n\nvar NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that\n// Never work can be committed in an inconsistent state without tearing the UI.\n// The main example is offscreen content, like a hidden subtree. So one possible\n// name is Offscreen. However, it also includes dehydrated Suspense boundaries,\n// which are inconsistent in the sense that they haven't finished yet, but\n// aren't visibly inconsistent because the server rendered HTML matches what the\n// hydrated tree would look like.\n\nvar Never = 1; // Idle is slightly higher priority than Never. It must completely finish in\n// order to be consistent.\n\nvar Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase\n// priority of hover targets.\n\nvar ContinuousHydration = 3;\nvar Sync = MAX_SIGNED_31_BIT_INT;\nvar Batched = Sync - 1;\nvar UNIT_SIZE = 10;\nvar MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.\n\nfunction msToExpirationTime(ms) {\n  // Always subtract from the offset so that we don't clash with the magic number for NoWork.\n  return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);\n}\nfunction expirationTimeToMs(expirationTime) {\n  return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;\n}\n\nfunction ceiling(num, precision) {\n  return ((num / precision | 0) + 1) * precision;\n}\n\nfunction computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {\n  return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);\n} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update\n// the names to reflect.\n\n\nvar LOW_PRIORITY_EXPIRATION = 5000;\nvar LOW_PRIORITY_BATCH_SIZE = 250;\nfunction computeAsyncExpiration(currentTime) {\n  return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);\n}\nfunction computeSuspenseExpiration(currentTime, timeoutMs) {\n  // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?\n  return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);\n} // We intentionally set a higher expiration time for interactive updates in\n// dev than in production.\n//\n// If the main thread is being blocked so long that you hit the expiration,\n// it's a problem that could be solved with better scheduling.\n//\n// People will be more likely to notice this and fix it with the long\n// expiration time in development.\n//\n// In production we opt for better UX at the risk of masking scheduling\n// problems, by expiring fast.\n\nvar HIGH_PRIORITY_EXPIRATION =  500 ;\nvar HIGH_PRIORITY_BATCH_SIZE = 100;\nfunction computeInteractiveExpiration(currentTime) {\n  return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);\n}\nfunction inferPriorityFromExpirationTime(currentTime, expirationTime) {\n  if (expirationTime === Sync) {\n    return ImmediatePriority;\n  }\n\n  if (expirationTime === Never || expirationTime === Idle) {\n    return IdlePriority;\n  }\n\n  var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);\n\n  if (msUntil <= 0) {\n    return ImmediatePriority;\n  }\n\n  if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {\n    return UserBlockingPriority$1;\n  }\n\n  if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {\n    return NormalPriority;\n  } // TODO: Handle LowPriority\n  // Assume anything lower has idle priority\n\n\n  return IdlePriority;\n}\n\nvar ReactStrictModeWarnings = {\n  recordUnsafeLifecycleWarnings: function (fiber, instance) {},\n  flushPendingUnsafeLifecycleWarnings: function () {},\n  recordLegacyContextWarning: function (fiber, instance) {},\n  flushLegacyContextWarning: function () {},\n  discardPendingWarnings: function () {}\n};\n\n{\n  var findStrictRoot = function (fiber) {\n    var maybeStrictRoot = null;\n    var node = fiber;\n\n    while (node !== null) {\n      if (node.mode & StrictMode) {\n        maybeStrictRoot = node;\n      }\n\n      node = node.return;\n    }\n\n    return maybeStrictRoot;\n  };\n\n  var setToSortedString = function (set) {\n    var array = [];\n    set.forEach(function (value) {\n      array.push(value);\n    });\n    return array.sort().join(', ');\n  };\n\n  var pendingComponentWillMountWarnings = [];\n  var pendingUNSAFE_ComponentWillMountWarnings = [];\n  var pendingComponentWillReceivePropsWarnings = [];\n  var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];\n  var pendingComponentWillUpdateWarnings = [];\n  var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.\n\n  var didWarnAboutUnsafeLifecycles = new Set();\n\n  ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {\n    // Dedup strategy: Warn once per component.\n    if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {\n      return;\n    }\n\n    if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.\n    instance.componentWillMount.__suppressDeprecationWarning !== true) {\n      pendingComponentWillMountWarnings.push(fiber);\n    }\n\n    if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {\n      pendingUNSAFE_ComponentWillMountWarnings.push(fiber);\n    }\n\n    if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {\n      pendingComponentWillReceivePropsWarnings.push(fiber);\n    }\n\n    if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {\n      pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);\n    }\n\n    if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {\n      pendingComponentWillUpdateWarnings.push(fiber);\n    }\n\n    if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {\n      pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);\n    }\n  };\n\n  ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {\n    // We do an initial pass to gather component names\n    var componentWillMountUniqueNames = new Set();\n\n    if (pendingComponentWillMountWarnings.length > 0) {\n      pendingComponentWillMountWarnings.forEach(function (fiber) {\n        componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingComponentWillMountWarnings = [];\n    }\n\n    var UNSAFE_componentWillMountUniqueNames = new Set();\n\n    if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {\n      pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {\n        UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingUNSAFE_ComponentWillMountWarnings = [];\n    }\n\n    var componentWillReceivePropsUniqueNames = new Set();\n\n    if (pendingComponentWillReceivePropsWarnings.length > 0) {\n      pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {\n        componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingComponentWillReceivePropsWarnings = [];\n    }\n\n    var UNSAFE_componentWillReceivePropsUniqueNames = new Set();\n\n    if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {\n      pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {\n        UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingUNSAFE_ComponentWillReceivePropsWarnings = [];\n    }\n\n    var componentWillUpdateUniqueNames = new Set();\n\n    if (pendingComponentWillUpdateWarnings.length > 0) {\n      pendingComponentWillUpdateWarnings.forEach(function (fiber) {\n        componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingComponentWillUpdateWarnings = [];\n    }\n\n    var UNSAFE_componentWillUpdateUniqueNames = new Set();\n\n    if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {\n      pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {\n        UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutUnsafeLifecycles.add(fiber.type);\n      });\n      pendingUNSAFE_ComponentWillUpdateWarnings = [];\n    } // Finally, we flush all the warnings\n    // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'\n\n\n    if (UNSAFE_componentWillMountUniqueNames.size > 0) {\n      var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);\n\n      error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\\n' + '\\nPlease update the following components: %s', sortedNames);\n    }\n\n    if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {\n      var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);\n\n      error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move data fetching code or side effects to componentDidUpdate.\\n' + \"* If you're updating state whenever props change, \" + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\\n' + '\\nPlease update the following components: %s', _sortedNames);\n    }\n\n    if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {\n      var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);\n\n      error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move data fetching code or side effects to componentDidUpdate.\\n' + '\\nPlease update the following components: %s', _sortedNames2);\n    }\n\n    if (componentWillMountUniqueNames.size > 0) {\n      var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);\n\n      warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\\n' + '\\nPlease update the following components: %s', _sortedNames3);\n    }\n\n    if (componentWillReceivePropsUniqueNames.size > 0) {\n      var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);\n\n      warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move data fetching code or side effects to componentDidUpdate.\\n' + \"* If you're updating state whenever props change, refactor your \" + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\\n' + '\\nPlease update the following components: %s', _sortedNames4);\n    }\n\n    if (componentWillUpdateUniqueNames.size > 0) {\n      var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);\n\n      warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\\n\\n' + '* Move data fetching code or side effects to componentDidUpdate.\\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\\n' + '\\nPlease update the following components: %s', _sortedNames5);\n    }\n  };\n\n  var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.\n\n  var didWarnAboutLegacyContext = new Set();\n\n  ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {\n    var strictRoot = findStrictRoot(fiber);\n\n    if (strictRoot === null) {\n      error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');\n\n      return;\n    } // Dedup strategy: Warn once per component.\n\n\n    if (didWarnAboutLegacyContext.has(fiber.type)) {\n      return;\n    }\n\n    var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);\n\n    if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {\n      if (warningsForRoot === undefined) {\n        warningsForRoot = [];\n        pendingLegacyContextWarning.set(strictRoot, warningsForRoot);\n      }\n\n      warningsForRoot.push(fiber);\n    }\n  };\n\n  ReactStrictModeWarnings.flushLegacyContextWarning = function () {\n    pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {\n      if (fiberArray.length === 0) {\n        return;\n      }\n\n      var firstFiber = fiberArray[0];\n      var uniqueNames = new Set();\n      fiberArray.forEach(function (fiber) {\n        uniqueNames.add(getComponentName(fiber.type) || 'Component');\n        didWarnAboutLegacyContext.add(fiber.type);\n      });\n      var sortedNames = setToSortedString(uniqueNames);\n      var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);\n\n      error('Legacy context API has been detected within a strict-mode tree.' + '\\n\\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\\n\\nPlease update the following components: %s' + '\\n\\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);\n    });\n  };\n\n  ReactStrictModeWarnings.discardPendingWarnings = function () {\n    pendingComponentWillMountWarnings = [];\n    pendingUNSAFE_ComponentWillMountWarnings = [];\n    pendingComponentWillReceivePropsWarnings = [];\n    pendingUNSAFE_ComponentWillReceivePropsWarnings = [];\n    pendingComponentWillUpdateWarnings = [];\n    pendingUNSAFE_ComponentWillUpdateWarnings = [];\n    pendingLegacyContextWarning = new Map();\n  };\n}\n\nvar resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.\n\nvar failedBoundaries = null;\nvar setRefreshHandler = function (handler) {\n  {\n    resolveFamily = handler;\n  }\n};\nfunction resolveFunctionForHotReloading(type) {\n  {\n    if (resolveFamily === null) {\n      // Hot reloading is disabled.\n      return type;\n    }\n\n    var family = resolveFamily(type);\n\n    if (family === undefined) {\n      return type;\n    } // Use the latest known implementation.\n\n\n    return family.current;\n  }\n}\nfunction resolveClassForHotReloading(type) {\n  // No implementation differences.\n  return resolveFunctionForHotReloading(type);\n}\nfunction resolveForwardRefForHotReloading(type) {\n  {\n    if (resolveFamily === null) {\n      // Hot reloading is disabled.\n      return type;\n    }\n\n    var family = resolveFamily(type);\n\n    if (family === undefined) {\n      // Check if we're dealing with a real forwardRef. Don't want to crash early.\n      if (type !== null && type !== undefined && typeof type.render === 'function') {\n        // ForwardRef is special because its resolved .type is an object,\n        // but it's possible that we only have its inner render function in the map.\n        // If that inner render function is different, we'll build a new forwardRef type.\n        var currentRender = resolveFunctionForHotReloading(type.render);\n\n        if (type.render !== currentRender) {\n          var syntheticType = {\n            $$typeof: REACT_FORWARD_REF_TYPE,\n            render: currentRender\n          };\n\n          if (type.displayName !== undefined) {\n            syntheticType.displayName = type.displayName;\n          }\n\n          return syntheticType;\n        }\n      }\n\n      return type;\n    } // Use the latest known implementation.\n\n\n    return family.current;\n  }\n}\nfunction isCompatibleFamilyForHotReloading(fiber, element) {\n  {\n    if (resolveFamily === null) {\n      // Hot reloading is disabled.\n      return false;\n    }\n\n    var prevType = fiber.elementType;\n    var nextType = element.type; // If we got here, we know types aren't === equal.\n\n    var needsCompareFamilies = false;\n    var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;\n\n    switch (fiber.tag) {\n      case ClassComponent:\n        {\n          if (typeof nextType === 'function') {\n            needsCompareFamilies = true;\n          }\n\n          break;\n        }\n\n      case FunctionComponent:\n        {\n          if (typeof nextType === 'function') {\n            needsCompareFamilies = true;\n          } else if ($$typeofNextType === REACT_LAZY_TYPE) {\n            // We don't know the inner type yet.\n            // We're going to assume that the lazy inner type is stable,\n            // and so it is sufficient to avoid reconciling it away.\n            // We're not going to unwrap or actually use the new lazy type.\n            needsCompareFamilies = true;\n          }\n\n          break;\n        }\n\n      case ForwardRef:\n        {\n          if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {\n            needsCompareFamilies = true;\n          } else if ($$typeofNextType === REACT_LAZY_TYPE) {\n            needsCompareFamilies = true;\n          }\n\n          break;\n        }\n\n      case MemoComponent:\n      case SimpleMemoComponent:\n        {\n          if ($$typeofNextType === REACT_MEMO_TYPE) {\n            // TODO: if it was but can no longer be simple,\n            // we shouldn't set this.\n            needsCompareFamilies = true;\n          } else if ($$typeofNextType === REACT_LAZY_TYPE) {\n            needsCompareFamilies = true;\n          }\n\n          break;\n        }\n\n      default:\n        return false;\n    } // Check if both types have a family and it's the same one.\n\n\n    if (needsCompareFamilies) {\n      // Note: memo() and forwardRef() we'll compare outer rather than inner type.\n      // This means both of them need to be registered to preserve state.\n      // If we unwrapped and compared the inner types for wrappers instead,\n      // then we would risk falsely saying two separate memo(Foo)\n      // calls are equivalent because they wrap the same Foo function.\n      var prevFamily = resolveFamily(prevType);\n\n      if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n}\nfunction markFailedErrorBoundaryForHotReloading(fiber) {\n  {\n    if (resolveFamily === null) {\n      // Hot reloading is disabled.\n      return;\n    }\n\n    if (typeof WeakSet !== 'function') {\n      return;\n    }\n\n    if (failedBoundaries === null) {\n      failedBoundaries = new WeakSet();\n    }\n\n    failedBoundaries.add(fiber);\n  }\n}\nvar scheduleRefresh = function (root, update) {\n  {\n    if (resolveFamily === null) {\n      // Hot reloading is disabled.\n      return;\n    }\n\n    var staleFamilies = update.staleFamilies,\n        updatedFamilies = update.updatedFamilies;\n    flushPassiveEffects();\n    flushSync(function () {\n      scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);\n    });\n  }\n};\nvar scheduleRoot = function (root, element) {\n  {\n    if (root.context !== emptyContextObject) {\n      // Super edge case: root has a legacy _renderSubtree context\n      // but we don't know the parentComponent so we can't pass it.\n      // Just ignore. We'll delete this with _renderSubtree code path later.\n      return;\n    }\n\n    flushPassiveEffects();\n    syncUpdates(function () {\n      updateContainer(element, root, null, null);\n    });\n  }\n};\n\nfunction scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {\n  {\n    var alternate = fiber.alternate,\n        child = fiber.child,\n        sibling = fiber.sibling,\n        tag = fiber.tag,\n        type = fiber.type;\n    var candidateType = null;\n\n    switch (tag) {\n      case FunctionComponent:\n      case SimpleMemoComponent:\n      case ClassComponent:\n        candidateType = type;\n        break;\n\n      case ForwardRef:\n        candidateType = type.render;\n        break;\n    }\n\n    if (resolveFamily === null) {\n      throw new Error('Expected resolveFamily to be set during hot reload.');\n    }\n\n    var needsRender = false;\n    var needsRemount = false;\n\n    if (candidateType !== null) {\n      var family = resolveFamily(candidateType);\n\n      if (family !== undefined) {\n        if (staleFamilies.has(family)) {\n          needsRemount = true;\n        } else if (updatedFamilies.has(family)) {\n          if (tag === ClassComponent) {\n            needsRemount = true;\n          } else {\n            needsRender = true;\n          }\n        }\n      }\n    }\n\n    if (failedBoundaries !== null) {\n      if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {\n        needsRemount = true;\n      }\n    }\n\n    if (needsRemount) {\n      fiber._debugNeedsRemount = true;\n    }\n\n    if (needsRemount || needsRender) {\n      scheduleWork(fiber, Sync);\n    }\n\n    if (child !== null && !needsRemount) {\n      scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);\n    }\n\n    if (sibling !== null) {\n      scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);\n    }\n  }\n}\n\nvar findHostInstancesForRefresh = function (root, families) {\n  {\n    var hostInstances = new Set();\n    var types = new Set(families.map(function (family) {\n      return family.current;\n    }));\n    findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);\n    return hostInstances;\n  }\n};\n\nfunction findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {\n  {\n    var child = fiber.child,\n        sibling = fiber.sibling,\n        tag = fiber.tag,\n        type = fiber.type;\n    var candidateType = null;\n\n    switch (tag) {\n      case FunctionComponent:\n      case SimpleMemoComponent:\n      case ClassComponent:\n        candidateType = type;\n        break;\n\n      case ForwardRef:\n        candidateType = type.render;\n        break;\n    }\n\n    var didMatch = false;\n\n    if (candidateType !== null) {\n      if (types.has(candidateType)) {\n        didMatch = true;\n      }\n    }\n\n    if (didMatch) {\n      // We have a match. This only drills down to the closest host components.\n      // There's no need to search deeper because for the purpose of giving\n      // visual feedback, \"flashing\" outermost parent rectangles is sufficient.\n      findHostInstancesForFiberShallowly(fiber, hostInstances);\n    } else {\n      // If there's no match, maybe there will be one further down in the child tree.\n      if (child !== null) {\n        findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);\n      }\n    }\n\n    if (sibling !== null) {\n      findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);\n    }\n  }\n}\n\nfunction findHostInstancesForFiberShallowly(fiber, hostInstances) {\n  {\n    var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);\n\n    if (foundHostInstances) {\n      return;\n    } // If we didn't find any host children, fallback to closest host parent.\n\n\n    var node = fiber;\n\n    while (true) {\n      switch (node.tag) {\n        case HostComponent:\n          hostInstances.add(node.stateNode);\n          return;\n\n        case HostPortal:\n          hostInstances.add(node.stateNode.containerInfo);\n          return;\n\n        case HostRoot:\n          hostInstances.add(node.stateNode.containerInfo);\n          return;\n      }\n\n      if (node.return === null) {\n        throw new Error('Expected to reach root first.');\n      }\n\n      node = node.return;\n    }\n  }\n}\n\nfunction findChildHostInstancesForFiberShallowly(fiber, hostInstances) {\n  {\n    var node = fiber;\n    var foundHostInstances = false;\n\n    while (true) {\n      if (node.tag === HostComponent) {\n        // We got a match.\n        foundHostInstances = true;\n        hostInstances.add(node.stateNode); // There may still be more, so keep searching.\n      } else if (node.child !== null) {\n        node.child.return = node;\n        node = node.child;\n        continue;\n      }\n\n      if (node === fiber) {\n        return foundHostInstances;\n      }\n\n      while (node.sibling === null) {\n        if (node.return === null || node.return === fiber) {\n          return foundHostInstances;\n        }\n\n        node = node.return;\n      }\n\n      node.sibling.return = node.return;\n      node = node.sibling;\n    }\n  }\n\n  return false;\n}\n\nfunction resolveDefaultProps(Component, baseProps) {\n  if (Component && Component.defaultProps) {\n    // Resolve default props. Taken from ReactElement\n    var props = _assign({}, baseProps);\n\n    var defaultProps = Component.defaultProps;\n\n    for (var propName in defaultProps) {\n      if (props[propName] === undefined) {\n        props[propName] = defaultProps[propName];\n      }\n    }\n\n    return props;\n  }\n\n  return baseProps;\n}\nfunction readLazyComponentType(lazyComponent) {\n  initializeLazyComponentType(lazyComponent);\n\n  if (lazyComponent._status !== Resolved) {\n    throw lazyComponent._result;\n  }\n\n  return lazyComponent._result;\n}\n\nvar valueCursor = createCursor(null);\nvar rendererSigil;\n\n{\n  // Use this to detect multiple renderers using the same context\n  rendererSigil = {};\n}\n\nvar currentlyRenderingFiber = null;\nvar lastContextDependency = null;\nvar lastContextWithAllBitsObserved = null;\nvar isDisallowedContextReadInDEV = false;\nfunction resetContextDependencies() {\n  // This is called right before React yields execution, to ensure `readContext`\n  // cannot be called outside the render phase.\n  currentlyRenderingFiber = null;\n  lastContextDependency = null;\n  lastContextWithAllBitsObserved = null;\n\n  {\n    isDisallowedContextReadInDEV = false;\n  }\n}\nfunction enterDisallowedContextReadInDEV() {\n  {\n    isDisallowedContextReadInDEV = true;\n  }\n}\nfunction exitDisallowedContextReadInDEV() {\n  {\n    isDisallowedContextReadInDEV = false;\n  }\n}\nfunction pushProvider(providerFiber, nextValue) {\n  var context = providerFiber.type._context;\n\n  {\n    push(valueCursor, context._currentValue, providerFiber);\n    context._currentValue = nextValue;\n\n    {\n      if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {\n        error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');\n      }\n\n      context._currentRenderer = rendererSigil;\n    }\n  }\n}\nfunction popProvider(providerFiber) {\n  var currentValue = valueCursor.current;\n  pop(valueCursor, providerFiber);\n  var context = providerFiber.type._context;\n\n  {\n    context._currentValue = currentValue;\n  }\n}\nfunction calculateChangedBits(context, newValue, oldValue) {\n  if (objectIs(oldValue, newValue)) {\n    // No change\n    return 0;\n  } else {\n    var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;\n\n    {\n      if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {\n        error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);\n      }\n    }\n\n    return changedBits | 0;\n  }\n}\nfunction scheduleWorkOnParentPath(parent, renderExpirationTime) {\n  // Update the child expiration time of all the ancestors, including\n  // the alternates.\n  var node = parent;\n\n  while (node !== null) {\n    var alternate = node.alternate;\n\n    if (node.childExpirationTime < renderExpirationTime) {\n      node.childExpirationTime = renderExpirationTime;\n\n      if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {\n        alternate.childExpirationTime = renderExpirationTime;\n      }\n    } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {\n      alternate.childExpirationTime = renderExpirationTime;\n    } else {\n      // Neither alternate was updated, which means the rest of the\n      // ancestor path already has sufficient priority.\n      break;\n    }\n\n    node = node.return;\n  }\n}\nfunction propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {\n  var fiber = workInProgress.child;\n\n  if (fiber !== null) {\n    // Set the return pointer of the child to the work-in-progress fiber.\n    fiber.return = workInProgress;\n  }\n\n  while (fiber !== null) {\n    var nextFiber = void 0; // Visit this fiber.\n\n    var list = fiber.dependencies;\n\n    if (list !== null) {\n      nextFiber = fiber.child;\n      var dependency = list.firstContext;\n\n      while (dependency !== null) {\n        // Check if the context matches.\n        if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {\n          // Match! Schedule an update on this fiber.\n          if (fiber.tag === ClassComponent) {\n            // Schedule a force update on the work-in-progress.\n            var update = createUpdate(renderExpirationTime, null);\n            update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the\n            // update to the current fiber, too, which means it will persist even if\n            // this render is thrown away. Since it's a race condition, not sure it's\n            // worth fixing.\n\n            enqueueUpdate(fiber, update);\n          }\n\n          if (fiber.expirationTime < renderExpirationTime) {\n            fiber.expirationTime = renderExpirationTime;\n          }\n\n          var alternate = fiber.alternate;\n\n          if (alternate !== null && alternate.expirationTime < renderExpirationTime) {\n            alternate.expirationTime = renderExpirationTime;\n          }\n\n          scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.\n\n          if (list.expirationTime < renderExpirationTime) {\n            list.expirationTime = renderExpirationTime;\n          } // Since we already found a match, we can stop traversing the\n          // dependency list.\n\n\n          break;\n        }\n\n        dependency = dependency.next;\n      }\n    } else if (fiber.tag === ContextProvider) {\n      // Don't scan deeper if this is a matching provider\n      nextFiber = fiber.type === workInProgress.type ? null : fiber.child;\n    } else {\n      // Traverse down.\n      nextFiber = fiber.child;\n    }\n\n    if (nextFiber !== null) {\n      // Set the return pointer of the child to the work-in-progress fiber.\n      nextFiber.return = fiber;\n    } else {\n      // No child. Traverse to next sibling.\n      nextFiber = fiber;\n\n      while (nextFiber !== null) {\n        if (nextFiber === workInProgress) {\n          // We're back to the root of this subtree. Exit.\n          nextFiber = null;\n          break;\n        }\n\n        var sibling = nextFiber.sibling;\n\n        if (sibling !== null) {\n          // Set the return pointer of the sibling to the work-in-progress fiber.\n          sibling.return = nextFiber.return;\n          nextFiber = sibling;\n          break;\n        } // No more siblings. Traverse up.\n\n\n        nextFiber = nextFiber.return;\n      }\n    }\n\n    fiber = nextFiber;\n  }\n}\nfunction prepareToReadContext(workInProgress, renderExpirationTime) {\n  currentlyRenderingFiber = workInProgress;\n  lastContextDependency = null;\n  lastContextWithAllBitsObserved = null;\n  var dependencies = workInProgress.dependencies;\n\n  if (dependencies !== null) {\n    var firstContext = dependencies.firstContext;\n\n    if (firstContext !== null) {\n      if (dependencies.expirationTime >= renderExpirationTime) {\n        // Context list has a pending update. Mark that this fiber performed work.\n        markWorkInProgressReceivedUpdate();\n      } // Reset the work-in-progress list\n\n\n      dependencies.firstContext = null;\n    }\n  }\n}\nfunction readContext(context, observedBits) {\n  {\n    // This warning would fire if you read context inside a Hook like useMemo.\n    // Unlike the class check below, it's not enforced in production for perf.\n    if (isDisallowedContextReadInDEV) {\n      error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');\n    }\n  }\n\n  if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {\n    var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.\n\n    if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {\n      // Observe all updates.\n      lastContextWithAllBitsObserved = context;\n      resolvedObservedBits = MAX_SIGNED_31_BIT_INT;\n    } else {\n      resolvedObservedBits = observedBits;\n    }\n\n    var contextItem = {\n      context: context,\n      observedBits: resolvedObservedBits,\n      next: null\n    };\n\n    if (lastContextDependency === null) {\n      if (!(currentlyRenderingFiber !== null)) {\n        {\n          throw Error( \"Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().\" );\n        }\n      } // This is the first dependency for this component. Create a new list.\n\n\n      lastContextDependency = contextItem;\n      currentlyRenderingFiber.dependencies = {\n        expirationTime: NoWork,\n        firstContext: contextItem,\n        responders: null\n      };\n    } else {\n      // Append a new context item.\n      lastContextDependency = lastContextDependency.next = contextItem;\n    }\n  }\n\n  return  context._currentValue ;\n}\n\nvar UpdateState = 0;\nvar ReplaceState = 1;\nvar ForceUpdate = 2;\nvar CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.\n// It should only be read right after calling `processUpdateQueue`, via\n// `checkHasForceUpdateAfterProcessing`.\n\nvar hasForceUpdate = false;\nvar didWarnUpdateInsideUpdate;\nvar currentlyProcessingQueue;\n\n{\n  didWarnUpdateInsideUpdate = false;\n  currentlyProcessingQueue = null;\n}\n\nfunction initializeUpdateQueue(fiber) {\n  var queue = {\n    baseState: fiber.memoizedState,\n    baseQueue: null,\n    shared: {\n      pending: null\n    },\n    effects: null\n  };\n  fiber.updateQueue = queue;\n}\nfunction cloneUpdateQueue(current, workInProgress) {\n  // Clone the update queue from current. Unless it's already a clone.\n  var queue = workInProgress.updateQueue;\n  var currentQueue = current.updateQueue;\n\n  if (queue === currentQueue) {\n    var clone = {\n      baseState: currentQueue.baseState,\n      baseQueue: currentQueue.baseQueue,\n      shared: currentQueue.shared,\n      effects: currentQueue.effects\n    };\n    workInProgress.updateQueue = clone;\n  }\n}\nfunction createUpdate(expirationTime, suspenseConfig) {\n  var update = {\n    expirationTime: expirationTime,\n    suspenseConfig: suspenseConfig,\n    tag: UpdateState,\n    payload: null,\n    callback: null,\n    next: null\n  };\n  update.next = update;\n\n  {\n    update.priority = getCurrentPriorityLevel();\n  }\n\n  return update;\n}\nfunction enqueueUpdate(fiber, update) {\n  var updateQueue = fiber.updateQueue;\n\n  if (updateQueue === null) {\n    // Only occurs if the fiber has been unmounted.\n    return;\n  }\n\n  var sharedQueue = updateQueue.shared;\n  var pending = sharedQueue.pending;\n\n  if (pending === null) {\n    // This is the first update. Create a circular list.\n    update.next = update;\n  } else {\n    update.next = pending.next;\n    pending.next = update;\n  }\n\n  sharedQueue.pending = update;\n\n  {\n    if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {\n      error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');\n\n      didWarnUpdateInsideUpdate = true;\n    }\n  }\n}\nfunction enqueueCapturedUpdate(workInProgress, update) {\n  var current = workInProgress.alternate;\n\n  if (current !== null) {\n    // Ensure the work-in-progress queue is a clone\n    cloneUpdateQueue(current, workInProgress);\n  } // Captured updates go only on the work-in-progress queue.\n\n\n  var queue = workInProgress.updateQueue; // Append the update to the end of the list.\n\n  var last = queue.baseQueue;\n\n  if (last === null) {\n    queue.baseQueue = update.next = update;\n    update.next = update;\n  } else {\n    update.next = last.next;\n    last.next = update;\n  }\n}\n\nfunction getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {\n  switch (update.tag) {\n    case ReplaceState:\n      {\n        var payload = update.payload;\n\n        if (typeof payload === 'function') {\n          // Updater function\n          {\n            enterDisallowedContextReadInDEV();\n\n            if ( workInProgress.mode & StrictMode) {\n              payload.call(instance, prevState, nextProps);\n            }\n          }\n\n          var nextState = payload.call(instance, prevState, nextProps);\n\n          {\n            exitDisallowedContextReadInDEV();\n          }\n\n          return nextState;\n        } // State object\n\n\n        return payload;\n      }\n\n    case CaptureUpdate:\n      {\n        workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;\n      }\n    // Intentional fallthrough\n\n    case UpdateState:\n      {\n        var _payload = update.payload;\n        var partialState;\n\n        if (typeof _payload === 'function') {\n          // Updater function\n          {\n            enterDisallowedContextReadInDEV();\n\n            if ( workInProgress.mode & StrictMode) {\n              _payload.call(instance, prevState, nextProps);\n            }\n          }\n\n          partialState = _payload.call(instance, prevState, nextProps);\n\n          {\n            exitDisallowedContextReadInDEV();\n          }\n        } else {\n          // Partial state object\n          partialState = _payload;\n        }\n\n        if (partialState === null || partialState === undefined) {\n          // Null and undefined are treated as no-ops.\n          return prevState;\n        } // Merge the partial state and the previous state.\n\n\n        return _assign({}, prevState, partialState);\n      }\n\n    case ForceUpdate:\n      {\n        hasForceUpdate = true;\n        return prevState;\n      }\n  }\n\n  return prevState;\n}\n\nfunction processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {\n  // This is always non-null on a ClassComponent or HostRoot\n  var queue = workInProgress.updateQueue;\n  hasForceUpdate = false;\n\n  {\n    currentlyProcessingQueue = queue.shared;\n  } // The last rebase update that is NOT part of the base state.\n\n\n  var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.\n\n  var pendingQueue = queue.shared.pending;\n\n  if (pendingQueue !== null) {\n    // We have new updates that haven't been processed yet.\n    // We'll add them to the base queue.\n    if (baseQueue !== null) {\n      // Merge the pending queue and the base queue.\n      var baseFirst = baseQueue.next;\n      var pendingFirst = pendingQueue.next;\n      baseQueue.next = pendingFirst;\n      pendingQueue.next = baseFirst;\n    }\n\n    baseQueue = pendingQueue;\n    queue.shared.pending = null; // TODO: Pass `current` as argument\n\n    var current = workInProgress.alternate;\n\n    if (current !== null) {\n      var currentQueue = current.updateQueue;\n\n      if (currentQueue !== null) {\n        currentQueue.baseQueue = pendingQueue;\n      }\n    }\n  } // These values may change as we process the queue.\n\n\n  if (baseQueue !== null) {\n    var first = baseQueue.next; // Iterate through the list of updates to compute the result.\n\n    var newState = queue.baseState;\n    var newExpirationTime = NoWork;\n    var newBaseState = null;\n    var newBaseQueueFirst = null;\n    var newBaseQueueLast = null;\n\n    if (first !== null) {\n      var update = first;\n\n      do {\n        var updateExpirationTime = update.expirationTime;\n\n        if (updateExpirationTime < renderExpirationTime) {\n          // Priority is insufficient. Skip this update. If this is the first\n          // skipped update, the previous update/state is the new base\n          // update/state.\n          var clone = {\n            expirationTime: update.expirationTime,\n            suspenseConfig: update.suspenseConfig,\n            tag: update.tag,\n            payload: update.payload,\n            callback: update.callback,\n            next: null\n          };\n\n          if (newBaseQueueLast === null) {\n            newBaseQueueFirst = newBaseQueueLast = clone;\n            newBaseState = newState;\n          } else {\n            newBaseQueueLast = newBaseQueueLast.next = clone;\n          } // Update the remaining priority in the queue.\n\n\n          if (updateExpirationTime > newExpirationTime) {\n            newExpirationTime = updateExpirationTime;\n          }\n        } else {\n          // This update does have sufficient priority.\n          if (newBaseQueueLast !== null) {\n            var _clone = {\n              expirationTime: Sync,\n              // This update is going to be committed so we never want uncommit it.\n              suspenseConfig: update.suspenseConfig,\n              tag: update.tag,\n              payload: update.payload,\n              callback: update.callback,\n              next: null\n            };\n            newBaseQueueLast = newBaseQueueLast.next = _clone;\n          } // Mark the event time of this update as relevant to this render pass.\n          // TODO: This should ideally use the true event time of this update rather than\n          // its priority which is a derived and not reverseable value.\n          // TODO: We should skip this update if it was already committed but currently\n          // we have no way of detecting the difference between a committed and suspended\n          // update here.\n\n\n          markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.\n\n          newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);\n          var callback = update.callback;\n\n          if (callback !== null) {\n            workInProgress.effectTag |= Callback;\n            var effects = queue.effects;\n\n            if (effects === null) {\n              queue.effects = [update];\n            } else {\n              effects.push(update);\n            }\n          }\n        }\n\n        update = update.next;\n\n        if (update === null || update === first) {\n          pendingQueue = queue.shared.pending;\n\n          if (pendingQueue === null) {\n            break;\n          } else {\n            // An update was scheduled from inside a reducer. Add the new\n            // pending updates to the end of the list and keep processing.\n            update = baseQueue.next = pendingQueue.next;\n            pendingQueue.next = first;\n            queue.baseQueue = baseQueue = pendingQueue;\n            queue.shared.pending = null;\n          }\n        }\n      } while (true);\n    }\n\n    if (newBaseQueueLast === null) {\n      newBaseState = newState;\n    } else {\n      newBaseQueueLast.next = newBaseQueueFirst;\n    }\n\n    queue.baseState = newBaseState;\n    queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.\n    // This should be fine because the only two other things that contribute to\n    // expiration time are props and context. We're already in the middle of the\n    // begin phase by the time we start processing the queue, so we've already\n    // dealt with the props. Context in components that specify\n    // shouldComponentUpdate is tricky; but we'll have to account for\n    // that regardless.\n\n    markUnprocessedUpdateTime(newExpirationTime);\n    workInProgress.expirationTime = newExpirationTime;\n    workInProgress.memoizedState = newState;\n  }\n\n  {\n    currentlyProcessingQueue = null;\n  }\n}\n\nfunction callCallback(callback, context) {\n  if (!(typeof callback === 'function')) {\n    {\n      throw Error( \"Invalid argument passed as callback. Expected a function. Instead received: \" + callback );\n    }\n  }\n\n  callback.call(context);\n}\n\nfunction resetHasForceUpdateBeforeProcessing() {\n  hasForceUpdate = false;\n}\nfunction checkHasForceUpdateAfterProcessing() {\n  return hasForceUpdate;\n}\nfunction commitUpdateQueue(finishedWork, finishedQueue, instance) {\n  // Commit the effects\n  var effects = finishedQueue.effects;\n  finishedQueue.effects = null;\n\n  if (effects !== null) {\n    for (var i = 0; i < effects.length; i++) {\n      var effect = effects[i];\n      var callback = effect.callback;\n\n      if (callback !== null) {\n        effect.callback = null;\n        callCallback(callback, instance);\n      }\n    }\n  }\n}\n\nvar ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;\nfunction requestCurrentSuspenseConfig() {\n  return ReactCurrentBatchConfig.suspense;\n}\n\nvar fakeInternalInstance = {};\nvar isArray = Array.isArray; // React.Component uses a shared frozen object by default.\n// We'll use it to determine whether we need to initialize legacy refs.\n\nvar emptyRefsObject = new React.Component().refs;\nvar didWarnAboutStateAssignmentForComponent;\nvar didWarnAboutUninitializedState;\nvar didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;\nvar didWarnAboutLegacyLifecyclesAndDerivedState;\nvar didWarnAboutUndefinedDerivedState;\nvar warnOnUndefinedDerivedState;\nvar warnOnInvalidCallback;\nvar didWarnAboutDirectlyAssigningPropsToState;\nvar didWarnAboutContextTypeAndContextTypes;\nvar didWarnAboutInvalidateContextType;\n\n{\n  didWarnAboutStateAssignmentForComponent = new Set();\n  didWarnAboutUninitializedState = new Set();\n  didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();\n  didWarnAboutLegacyLifecyclesAndDerivedState = new Set();\n  didWarnAboutDirectlyAssigningPropsToState = new Set();\n  didWarnAboutUndefinedDerivedState = new Set();\n  didWarnAboutContextTypeAndContextTypes = new Set();\n  didWarnAboutInvalidateContextType = new Set();\n  var didWarnOnInvalidCallback = new Set();\n\n  warnOnInvalidCallback = function (callback, callerName) {\n    if (callback === null || typeof callback === 'function') {\n      return;\n    }\n\n    var key = callerName + \"_\" + callback;\n\n    if (!didWarnOnInvalidCallback.has(key)) {\n      didWarnOnInvalidCallback.add(key);\n\n      error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);\n    }\n  };\n\n  warnOnUndefinedDerivedState = function (type, partialState) {\n    if (partialState === undefined) {\n      var componentName = getComponentName(type) || 'Component';\n\n      if (!didWarnAboutUndefinedDerivedState.has(componentName)) {\n        didWarnAboutUndefinedDerivedState.add(componentName);\n\n        error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);\n      }\n    }\n  }; // This is so gross but it's at least non-critical and can be removed if\n  // it causes problems. This is meant to give a nicer error message for\n  // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,\n  // ...)) which otherwise throws a \"_processChildContext is not a function\"\n  // exception.\n\n\n  Object.defineProperty(fakeInternalInstance, '_processChildContext', {\n    enumerable: false,\n    value: function () {\n      {\n        {\n          throw Error( \"_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).\" );\n        }\n      }\n    }\n  });\n  Object.freeze(fakeInternalInstance);\n}\n\nfunction applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {\n  var prevState = workInProgress.memoizedState;\n\n  {\n    if ( workInProgress.mode & StrictMode) {\n      // Invoke the function an extra time to help detect side-effects.\n      getDerivedStateFromProps(nextProps, prevState);\n    }\n  }\n\n  var partialState = getDerivedStateFromProps(nextProps, prevState);\n\n  {\n    warnOnUndefinedDerivedState(ctor, partialState);\n  } // Merge the partial state and the previous state.\n\n\n  var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);\n  workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the\n  // base state.\n\n  if (workInProgress.expirationTime === NoWork) {\n    // Queue is always non-null for classes\n    var updateQueue = workInProgress.updateQueue;\n    updateQueue.baseState = memoizedState;\n  }\n}\nvar classComponentUpdater = {\n  isMounted: isMounted,\n  enqueueSetState: function (inst, payload, callback) {\n    var fiber = get(inst);\n    var currentTime = requestCurrentTimeForUpdate();\n    var suspenseConfig = requestCurrentSuspenseConfig();\n    var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);\n    var update = createUpdate(expirationTime, suspenseConfig);\n    update.payload = payload;\n\n    if (callback !== undefined && callback !== null) {\n      {\n        warnOnInvalidCallback(callback, 'setState');\n      }\n\n      update.callback = callback;\n    }\n\n    enqueueUpdate(fiber, update);\n    scheduleWork(fiber, expirationTime);\n  },\n  enqueueReplaceState: function (inst, payload, callback) {\n    var fiber = get(inst);\n    var currentTime = requestCurrentTimeForUpdate();\n    var suspenseConfig = requestCurrentSuspenseConfig();\n    var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);\n    var update = createUpdate(expirationTime, suspenseConfig);\n    update.tag = ReplaceState;\n    update.payload = payload;\n\n    if (callback !== undefined && callback !== null) {\n      {\n        warnOnInvalidCallback(callback, 'replaceState');\n      }\n\n      update.callback = callback;\n    }\n\n    enqueueUpdate(fiber, update);\n    scheduleWork(fiber, expirationTime);\n  },\n  enqueueForceUpdate: function (inst, callback) {\n    var fiber = get(inst);\n    var currentTime = requestCurrentTimeForUpdate();\n    var suspenseConfig = requestCurrentSuspenseConfig();\n    var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);\n    var update = createUpdate(expirationTime, suspenseConfig);\n    update.tag = ForceUpdate;\n\n    if (callback !== undefined && callback !== null) {\n      {\n        warnOnInvalidCallback(callback, 'forceUpdate');\n      }\n\n      update.callback = callback;\n    }\n\n    enqueueUpdate(fiber, update);\n    scheduleWork(fiber, expirationTime);\n  }\n};\n\nfunction checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {\n  var instance = workInProgress.stateNode;\n\n  if (typeof instance.shouldComponentUpdate === 'function') {\n    {\n      if ( workInProgress.mode & StrictMode) {\n        // Invoke the function an extra time to help detect side-effects.\n        instance.shouldComponentUpdate(newProps, newState, nextContext);\n      }\n    }\n\n    startPhaseTimer(workInProgress, 'shouldComponentUpdate');\n    var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);\n    stopPhaseTimer();\n\n    {\n      if (shouldUpdate === undefined) {\n        error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');\n      }\n    }\n\n    return shouldUpdate;\n  }\n\n  if (ctor.prototype && ctor.prototype.isPureReactComponent) {\n    return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);\n  }\n\n  return true;\n}\n\nfunction checkClassInstance(workInProgress, ctor, newProps) {\n  var instance = workInProgress.stateNode;\n\n  {\n    var name = getComponentName(ctor) || 'Component';\n    var renderPresent = instance.render;\n\n    if (!renderPresent) {\n      if (ctor.prototype && typeof ctor.prototype.render === 'function') {\n        error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);\n      } else {\n        error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);\n      }\n    }\n\n    if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {\n      error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);\n    }\n\n    if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {\n      error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);\n    }\n\n    if (instance.propTypes) {\n      error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);\n    }\n\n    if (instance.contextType) {\n      error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);\n    }\n\n    {\n      if (instance.contextTypes) {\n        error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);\n      }\n\n      if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {\n        didWarnAboutContextTypeAndContextTypes.add(ctor);\n\n        error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);\n      }\n    }\n\n    if (typeof instance.componentShouldUpdate === 'function') {\n      error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);\n    }\n\n    if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {\n      error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');\n    }\n\n    if (typeof instance.componentDidUnmount === 'function') {\n      error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);\n    }\n\n    if (typeof instance.componentDidReceiveProps === 'function') {\n      error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);\n    }\n\n    if (typeof instance.componentWillRecieveProps === 'function') {\n      error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);\n    }\n\n    if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {\n      error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);\n    }\n\n    var hasMutatedProps = instance.props !== newProps;\n\n    if (instance.props !== undefined && hasMutatedProps) {\n      error('%s(...): When calling super() in `%s`, make sure to pass ' + \"up the same props that your component's constructor was passed.\", name, name);\n    }\n\n    if (instance.defaultProps) {\n      error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);\n    }\n\n    if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {\n      didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);\n\n      error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));\n    }\n\n    if (typeof instance.getDerivedStateFromProps === 'function') {\n      error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);\n    }\n\n    if (typeof instance.getDerivedStateFromError === 'function') {\n      error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);\n    }\n\n    if (typeof ctor.getSnapshotBeforeUpdate === 'function') {\n      error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);\n    }\n\n    var _state = instance.state;\n\n    if (_state && (typeof _state !== 'object' || isArray(_state))) {\n      error('%s.state: must be set to an object or null', name);\n    }\n\n    if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {\n      error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);\n    }\n  }\n}\n\nfunction adoptClassInstance(workInProgress, instance) {\n  instance.updater = classComponentUpdater;\n  workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates\n\n  set(instance, workInProgress);\n\n  {\n    instance._reactInternalInstance = fakeInternalInstance;\n  }\n}\n\nfunction constructClassInstance(workInProgress, ctor, props) {\n  var isLegacyContextConsumer = false;\n  var unmaskedContext = emptyContextObject;\n  var context = emptyContextObject;\n  var contextType = ctor.contextType;\n\n  {\n    if ('contextType' in ctor) {\n      var isValid = // Allow null for conditional declaration\n      contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>\n\n      if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {\n        didWarnAboutInvalidateContextType.add(ctor);\n        var addendum = '';\n\n        if (contextType === undefined) {\n          addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';\n        } else if (typeof contextType !== 'object') {\n          addendum = ' However, it is set to a ' + typeof contextType + '.';\n        } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {\n          addendum = ' Did you accidentally pass the Context.Provider instead?';\n        } else if (contextType._context !== undefined) {\n          // <Context.Consumer>\n          addendum = ' Did you accidentally pass the Context.Consumer instead?';\n        } else {\n          addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';\n        }\n\n        error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);\n      }\n    }\n  }\n\n  if (typeof contextType === 'object' && contextType !== null) {\n    context = readContext(contextType);\n  } else {\n    unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);\n    var contextTypes = ctor.contextTypes;\n    isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;\n    context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;\n  } // Instantiate twice to help detect side-effects.\n\n\n  {\n    if ( workInProgress.mode & StrictMode) {\n      new ctor(props, context); // eslint-disable-line no-new\n    }\n  }\n\n  var instance = new ctor(props, context);\n  var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;\n  adoptClassInstance(workInProgress, instance);\n\n  {\n    if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {\n      var componentName = getComponentName(ctor) || 'Component';\n\n      if (!didWarnAboutUninitializedState.has(componentName)) {\n        didWarnAboutUninitializedState.add(componentName);\n\n        error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);\n      }\n    } // If new component APIs are defined, \"unsafe\" lifecycles won't be called.\n    // Warn about these lifecycles if they are present.\n    // Don't warn about react-lifecycles-compat polyfilled methods though.\n\n\n    if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {\n      var foundWillMountName = null;\n      var foundWillReceivePropsName = null;\n      var foundWillUpdateName = null;\n\n      if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {\n        foundWillMountName = 'componentWillMount';\n      } else if (typeof instance.UNSAFE_componentWillMount === 'function') {\n        foundWillMountName = 'UNSAFE_componentWillMount';\n      }\n\n      if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {\n        foundWillReceivePropsName = 'componentWillReceiveProps';\n      } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {\n        foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';\n      }\n\n      if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {\n        foundWillUpdateName = 'componentWillUpdate';\n      } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {\n        foundWillUpdateName = 'UNSAFE_componentWillUpdate';\n      }\n\n      if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {\n        var _componentName = getComponentName(ctor) || 'Component';\n\n        var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';\n\n        if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {\n          didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);\n\n          error('Unsafe legacy lifecycles will not be called for components using new component APIs.\\n\\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\\n\\n' + 'The above lifecycles should be removed. Learn more about this warning here:\\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? \"\\n  \" + foundWillMountName : '', foundWillReceivePropsName !== null ? \"\\n  \" + foundWillReceivePropsName : '', foundWillUpdateName !== null ? \"\\n  \" + foundWillUpdateName : '');\n        }\n      }\n    }\n  } // Cache unmasked context so we can avoid recreating masked context unless necessary.\n  // ReactFiberContext usually updates this cache but can't for newly-created instances.\n\n\n  if (isLegacyContextConsumer) {\n    cacheContext(workInProgress, unmaskedContext, context);\n  }\n\n  return instance;\n}\n\nfunction callComponentWillMount(workInProgress, instance) {\n  startPhaseTimer(workInProgress, 'componentWillMount');\n  var oldState = instance.state;\n\n  if (typeof instance.componentWillMount === 'function') {\n    instance.componentWillMount();\n  }\n\n  if (typeof instance.UNSAFE_componentWillMount === 'function') {\n    instance.UNSAFE_componentWillMount();\n  }\n\n  stopPhaseTimer();\n\n  if (oldState !== instance.state) {\n    {\n      error('%s.componentWillMount(): Assigning directly to this.state is ' + \"deprecated (except inside a component's \" + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');\n    }\n\n    classComponentUpdater.enqueueReplaceState(instance, instance.state, null);\n  }\n}\n\nfunction callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {\n  var oldState = instance.state;\n  startPhaseTimer(workInProgress, 'componentWillReceiveProps');\n\n  if (typeof instance.componentWillReceiveProps === 'function') {\n    instance.componentWillReceiveProps(newProps, nextContext);\n  }\n\n  if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {\n    instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);\n  }\n\n  stopPhaseTimer();\n\n  if (instance.state !== oldState) {\n    {\n      var componentName = getComponentName(workInProgress.type) || 'Component';\n\n      if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {\n        didWarnAboutStateAssignmentForComponent.add(componentName);\n\n        error('%s.componentWillReceiveProps(): Assigning directly to ' + \"this.state is deprecated (except inside a component's \" + 'constructor). Use setState instead.', componentName);\n      }\n    }\n\n    classComponentUpdater.enqueueReplaceState(instance, instance.state, null);\n  }\n} // Invokes the mount life-cycles on a previously never rendered instance.\n\n\nfunction mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {\n  {\n    checkClassInstance(workInProgress, ctor, newProps);\n  }\n\n  var instance = workInProgress.stateNode;\n  instance.props = newProps;\n  instance.state = workInProgress.memoizedState;\n  instance.refs = emptyRefsObject;\n  initializeUpdateQueue(workInProgress);\n  var contextType = ctor.contextType;\n\n  if (typeof contextType === 'object' && contextType !== null) {\n    instance.context = readContext(contextType);\n  } else {\n    var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);\n    instance.context = getMaskedContext(workInProgress, unmaskedContext);\n  }\n\n  {\n    if (instance.state === newProps) {\n      var componentName = getComponentName(ctor) || 'Component';\n\n      if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {\n        didWarnAboutDirectlyAssigningPropsToState.add(componentName);\n\n        error('%s: It is not recommended to assign props directly to state ' + \"because updates to props won't be reflected in state. \" + 'In most cases, it is better to use props directly.', componentName);\n      }\n    }\n\n    if (workInProgress.mode & StrictMode) {\n      ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);\n    }\n\n    {\n      ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);\n    }\n  }\n\n  processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);\n  instance.state = workInProgress.memoizedState;\n  var getDerivedStateFromProps = ctor.getDerivedStateFromProps;\n\n  if (typeof getDerivedStateFromProps === 'function') {\n    applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);\n    instance.state = workInProgress.memoizedState;\n  } // In order to support react-lifecycles-compat polyfilled components,\n  // Unsafe lifecycles should not be invoked for components using the new APIs.\n\n\n  if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {\n    callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's\n    // process them now.\n\n    processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);\n    instance.state = workInProgress.memoizedState;\n  }\n\n  if (typeof instance.componentDidMount === 'function') {\n    workInProgress.effectTag |= Update;\n  }\n}\n\nfunction resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {\n  var instance = workInProgress.stateNode;\n  var oldProps = workInProgress.memoizedProps;\n  instance.props = oldProps;\n  var oldContext = instance.context;\n  var contextType = ctor.contextType;\n  var nextContext = emptyContextObject;\n\n  if (typeof contextType === 'object' && contextType !== null) {\n    nextContext = readContext(contextType);\n  } else {\n    var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);\n    nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);\n  }\n\n  var getDerivedStateFromProps = ctor.getDerivedStateFromProps;\n  var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what\n  // ever the previously attempted to render - not the \"current\". However,\n  // during componentDidUpdate we pass the \"current\" props.\n  // In order to support react-lifecycles-compat polyfilled components,\n  // Unsafe lifecycles should not be invoked for components using the new APIs.\n\n  if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {\n    if (oldProps !== newProps || oldContext !== nextContext) {\n      callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);\n    }\n  }\n\n  resetHasForceUpdateBeforeProcessing();\n  var oldState = workInProgress.memoizedState;\n  var newState = instance.state = oldState;\n  processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);\n  newState = workInProgress.memoizedState;\n\n  if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {\n    // If an update was already in progress, we should schedule an Update\n    // effect even though we're bailing out, so that cWU/cDU are called.\n    if (typeof instance.componentDidMount === 'function') {\n      workInProgress.effectTag |= Update;\n    }\n\n    return false;\n  }\n\n  if (typeof getDerivedStateFromProps === 'function') {\n    applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);\n    newState = workInProgress.memoizedState;\n  }\n\n  var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);\n\n  if (shouldUpdate) {\n    // In order to support react-lifecycles-compat polyfilled components,\n    // Unsafe lifecycles should not be invoked for components using the new APIs.\n    if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {\n      startPhaseTimer(workInProgress, 'componentWillMount');\n\n      if (typeof instance.componentWillMount === 'function') {\n        instance.componentWillMount();\n      }\n\n      if (typeof instance.UNSAFE_componentWillMount === 'function') {\n        instance.UNSAFE_componentWillMount();\n      }\n\n      stopPhaseTimer();\n    }\n\n    if (typeof instance.componentDidMount === 'function') {\n      workInProgress.effectTag |= Update;\n    }\n  } else {\n    // If an update was already in progress, we should schedule an Update\n    // effect even though we're bailing out, so that cWU/cDU are called.\n    if (typeof instance.componentDidMount === 'function') {\n      workInProgress.effectTag |= Update;\n    } // If shouldComponentUpdate returned false, we should still update the\n    // memoized state to indicate that this work can be reused.\n\n\n    workInProgress.memoizedProps = newProps;\n    workInProgress.memoizedState = newState;\n  } // Update the existing instance's state, props, and context pointers even\n  // if shouldComponentUpdate returns false.\n\n\n  instance.props = newProps;\n  instance.state = newState;\n  instance.context = nextContext;\n  return shouldUpdate;\n} // Invokes the update life-cycles and returns false if it shouldn't rerender.\n\n\nfunction updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {\n  var instance = workInProgress.stateNode;\n  cloneUpdateQueue(current, workInProgress);\n  var oldProps = workInProgress.memoizedProps;\n  instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);\n  var oldContext = instance.context;\n  var contextType = ctor.contextType;\n  var nextContext = emptyContextObject;\n\n  if (typeof contextType === 'object' && contextType !== null) {\n    nextContext = readContext(contextType);\n  } else {\n    var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);\n    nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);\n  }\n\n  var getDerivedStateFromProps = ctor.getDerivedStateFromProps;\n  var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what\n  // ever the previously attempted to render - not the \"current\". However,\n  // during componentDidUpdate we pass the \"current\" props.\n  // In order to support react-lifecycles-compat polyfilled components,\n  // Unsafe lifecycles should not be invoked for components using the new APIs.\n\n  if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {\n    if (oldProps !== newProps || oldContext !== nextContext) {\n      callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);\n    }\n  }\n\n  resetHasForceUpdateBeforeProcessing();\n  var oldState = workInProgress.memoizedState;\n  var newState = instance.state = oldState;\n  processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);\n  newState = workInProgress.memoizedState;\n\n  if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {\n    // If an update was already in progress, we should schedule an Update\n    // effect even though we're bailing out, so that cWU/cDU are called.\n    if (typeof instance.componentDidUpdate === 'function') {\n      if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {\n        workInProgress.effectTag |= Update;\n      }\n    }\n\n    if (typeof instance.getSnapshotBeforeUpdate === 'function') {\n      if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {\n        workInProgress.effectTag |= Snapshot;\n      }\n    }\n\n    return false;\n  }\n\n  if (typeof getDerivedStateFromProps === 'function') {\n    applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);\n    newState = workInProgress.memoizedState;\n  }\n\n  var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);\n\n  if (shouldUpdate) {\n    // In order to support react-lifecycles-compat polyfilled components,\n    // Unsafe lifecycles should not be invoked for components using the new APIs.\n    if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {\n      startPhaseTimer(workInProgress, 'componentWillUpdate');\n\n      if (typeof instance.componentWillUpdate === 'function') {\n        instance.componentWillUpdate(newProps, newState, nextContext);\n      }\n\n      if (typeof instance.UNSAFE_componentWillUpdate === 'function') {\n        instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);\n      }\n\n      stopPhaseTimer();\n    }\n\n    if (typeof instance.componentDidUpdate === 'function') {\n      workInProgress.effectTag |= Update;\n    }\n\n    if (typeof instance.getSnapshotBeforeUpdate === 'function') {\n      workInProgress.effectTag |= Snapshot;\n    }\n  } else {\n    // If an update was already in progress, we should schedule an Update\n    // effect even though we're bailing out, so that cWU/cDU are called.\n    if (typeof instance.componentDidUpdate === 'function') {\n      if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {\n        workInProgress.effectTag |= Update;\n      }\n    }\n\n    if (typeof instance.getSnapshotBeforeUpdate === 'function') {\n      if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {\n        workInProgress.effectTag |= Snapshot;\n      }\n    } // If shouldComponentUpdate returned false, we should still update the\n    // memoized props/state to indicate that this work can be reused.\n\n\n    workInProgress.memoizedProps = newProps;\n    workInProgress.memoizedState = newState;\n  } // Update the existing instance's state, props, and context pointers even\n  // if shouldComponentUpdate returns false.\n\n\n  instance.props = newProps;\n  instance.state = newState;\n  instance.context = nextContext;\n  return shouldUpdate;\n}\n\nvar didWarnAboutMaps;\nvar didWarnAboutGenerators;\nvar didWarnAboutStringRefs;\nvar ownerHasKeyUseWarning;\nvar ownerHasFunctionTypeWarning;\n\nvar warnForMissingKey = function (child) {};\n\n{\n  didWarnAboutMaps = false;\n  didWarnAboutGenerators = false;\n  didWarnAboutStringRefs = {};\n  /**\n   * Warn if there's no key explicitly set on dynamic arrays of children or\n   * object keys are not valid. This allows us to keep track of children between\n   * updates.\n   */\n\n  ownerHasKeyUseWarning = {};\n  ownerHasFunctionTypeWarning = {};\n\n  warnForMissingKey = function (child) {\n    if (child === null || typeof child !== 'object') {\n      return;\n    }\n\n    if (!child._store || child._store.validated || child.key != null) {\n      return;\n    }\n\n    if (!(typeof child._store === 'object')) {\n      {\n        throw Error( \"React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n\n    child._store.validated = true;\n    var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '\"key\" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();\n\n    if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {\n      return;\n    }\n\n    ownerHasKeyUseWarning[currentComponentErrorInfo] = true;\n\n    error('Each child in a list should have a unique ' + '\"key\" prop. See https://fb.me/react-warning-keys for ' + 'more information.');\n  };\n}\n\nvar isArray$1 = Array.isArray;\n\nfunction coerceRef(returnFiber, current, element) {\n  var mixedRef = element.ref;\n\n  if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {\n    {\n      // TODO: Clean this up once we turn on the string ref warning for\n      // everyone, because the strict mode case will no longer be relevant\n      if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs\n      // because these cannot be automatically converted to an arrow function\n      // using a codemod. Therefore, we don't have to warn about string refs again.\n      !(element._owner && element._self && element._owner.stateNode !== element._self)) {\n        var componentName = getComponentName(returnFiber.type) || 'Component';\n\n        if (!didWarnAboutStringRefs[componentName]) {\n          {\n            error('A string ref, \"%s\", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));\n          }\n\n          didWarnAboutStringRefs[componentName] = true;\n        }\n      }\n    }\n\n    if (element._owner) {\n      var owner = element._owner;\n      var inst;\n\n      if (owner) {\n        var ownerFiber = owner;\n\n        if (!(ownerFiber.tag === ClassComponent)) {\n          {\n            throw Error( \"Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref\" );\n          }\n        }\n\n        inst = ownerFiber.stateNode;\n      }\n\n      if (!inst) {\n        {\n          throw Error( \"Missing owner for string ref \" + mixedRef + \". This error is likely caused by a bug in React. Please file an issue.\" );\n        }\n      }\n\n      var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref\n\n      if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {\n        return current.ref;\n      }\n\n      var ref = function (value) {\n        var refs = inst.refs;\n\n        if (refs === emptyRefsObject) {\n          // This is a lazy pooled frozen object, so we need to initialize.\n          refs = inst.refs = {};\n        }\n\n        if (value === null) {\n          delete refs[stringRef];\n        } else {\n          refs[stringRef] = value;\n        }\n      };\n\n      ref._stringRef = stringRef;\n      return ref;\n    } else {\n      if (!(typeof mixedRef === 'string')) {\n        {\n          throw Error( \"Expected ref to be a function, a string, an object returned by React.createRef(), or null.\" );\n        }\n      }\n\n      if (!element._owner) {\n        {\n          throw Error( \"Element ref was specified as a string (\" + mixedRef + \") but no owner was set. This could happen for one of the following reasons:\\n1. You may be adding a ref to a function component\\n2. You may be adding a ref to a component that was not created inside a component's render method\\n3. You have multiple copies of React loaded\\nSee https://fb.me/react-refs-must-have-owner for more information.\" );\n        }\n      }\n    }\n  }\n\n  return mixedRef;\n}\n\nfunction throwOnInvalidObjectType(returnFiber, newChild) {\n  if (returnFiber.type !== 'textarea') {\n    var addendum = '';\n\n    {\n      addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();\n    }\n\n    {\n      {\n        throw Error( \"Objects are not valid as a React child (found: \" + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + \").\" + addendum );\n      }\n    }\n  }\n}\n\nfunction warnOnFunctionType() {\n  {\n    var currentComponentErrorInfo = 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.' + getCurrentFiberStackInDev();\n\n    if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {\n      return;\n    }\n\n    ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;\n\n    error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');\n  }\n} // This wrapper function exists because I expect to clone the code in each path\n// to be able to optimize each path individually by branching early. This needs\n// a compiler or we can do it manually. Helpers that don't need this branching\n// live outside of this function.\n\n\nfunction ChildReconciler(shouldTrackSideEffects) {\n  function deleteChild(returnFiber, childToDelete) {\n    if (!shouldTrackSideEffects) {\n      // Noop.\n      return;\n    } // Deletions are added in reversed order so we add it to the front.\n    // At this point, the return fiber's effect list is empty except for\n    // deletions, so we can just append the deletion to the list. The remaining\n    // effects aren't added until the complete phase. Once we implement\n    // resuming, this may not be true.\n\n\n    var last = returnFiber.lastEffect;\n\n    if (last !== null) {\n      last.nextEffect = childToDelete;\n      returnFiber.lastEffect = childToDelete;\n    } else {\n      returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;\n    }\n\n    childToDelete.nextEffect = null;\n    childToDelete.effectTag = Deletion;\n  }\n\n  function deleteRemainingChildren(returnFiber, currentFirstChild) {\n    if (!shouldTrackSideEffects) {\n      // Noop.\n      return null;\n    } // TODO: For the shouldClone case, this could be micro-optimized a bit by\n    // assuming that after the first child we've already added everything.\n\n\n    var childToDelete = currentFirstChild;\n\n    while (childToDelete !== null) {\n      deleteChild(returnFiber, childToDelete);\n      childToDelete = childToDelete.sibling;\n    }\n\n    return null;\n  }\n\n  function mapRemainingChildren(returnFiber, currentFirstChild) {\n    // Add the remaining children to a temporary map so that we can find them by\n    // keys quickly. Implicit (null) keys get added to this set with their index\n    // instead.\n    var existingChildren = new Map();\n    var existingChild = currentFirstChild;\n\n    while (existingChild !== null) {\n      if (existingChild.key !== null) {\n        existingChildren.set(existingChild.key, existingChild);\n      } else {\n        existingChildren.set(existingChild.index, existingChild);\n      }\n\n      existingChild = existingChild.sibling;\n    }\n\n    return existingChildren;\n  }\n\n  function useFiber(fiber, pendingProps) {\n    // We currently set sibling to null and index to 0 here because it is easy\n    // to forget to do before returning it. E.g. for the single child case.\n    var clone = createWorkInProgress(fiber, pendingProps);\n    clone.index = 0;\n    clone.sibling = null;\n    return clone;\n  }\n\n  function placeChild(newFiber, lastPlacedIndex, newIndex) {\n    newFiber.index = newIndex;\n\n    if (!shouldTrackSideEffects) {\n      // Noop.\n      return lastPlacedIndex;\n    }\n\n    var current = newFiber.alternate;\n\n    if (current !== null) {\n      var oldIndex = current.index;\n\n      if (oldIndex < lastPlacedIndex) {\n        // This is a move.\n        newFiber.effectTag = Placement;\n        return lastPlacedIndex;\n      } else {\n        // This item can stay in place.\n        return oldIndex;\n      }\n    } else {\n      // This is an insertion.\n      newFiber.effectTag = Placement;\n      return lastPlacedIndex;\n    }\n  }\n\n  function placeSingleChild(newFiber) {\n    // This is simpler for the single child case. We only need to do a\n    // placement for inserting new children.\n    if (shouldTrackSideEffects && newFiber.alternate === null) {\n      newFiber.effectTag = Placement;\n    }\n\n    return newFiber;\n  }\n\n  function updateTextNode(returnFiber, current, textContent, expirationTime) {\n    if (current === null || current.tag !== HostText) {\n      // Insert\n      var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);\n      created.return = returnFiber;\n      return created;\n    } else {\n      // Update\n      var existing = useFiber(current, textContent);\n      existing.return = returnFiber;\n      return existing;\n    }\n  }\n\n  function updateElement(returnFiber, current, element, expirationTime) {\n    if (current !== null) {\n      if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:\n       isCompatibleFamilyForHotReloading(current, element) )) {\n        // Move based on index\n        var existing = useFiber(current, element.props);\n        existing.ref = coerceRef(returnFiber, current, element);\n        existing.return = returnFiber;\n\n        {\n          existing._debugSource = element._source;\n          existing._debugOwner = element._owner;\n        }\n\n        return existing;\n      }\n    } // Insert\n\n\n    var created = createFiberFromElement(element, returnFiber.mode, expirationTime);\n    created.ref = coerceRef(returnFiber, current, element);\n    created.return = returnFiber;\n    return created;\n  }\n\n  function updatePortal(returnFiber, current, portal, expirationTime) {\n    if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {\n      // Insert\n      var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);\n      created.return = returnFiber;\n      return created;\n    } else {\n      // Update\n      var existing = useFiber(current, portal.children || []);\n      existing.return = returnFiber;\n      return existing;\n    }\n  }\n\n  function updateFragment(returnFiber, current, fragment, expirationTime, key) {\n    if (current === null || current.tag !== Fragment) {\n      // Insert\n      var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);\n      created.return = returnFiber;\n      return created;\n    } else {\n      // Update\n      var existing = useFiber(current, fragment);\n      existing.return = returnFiber;\n      return existing;\n    }\n  }\n\n  function createChild(returnFiber, newChild, expirationTime) {\n    if (typeof newChild === 'string' || typeof newChild === 'number') {\n      // Text nodes don't have keys. If the previous node is implicitly keyed\n      // we can continue to replace it without aborting even if it is not a text\n      // node.\n      var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);\n      created.return = returnFiber;\n      return created;\n    }\n\n    if (typeof newChild === 'object' && newChild !== null) {\n      switch (newChild.$$typeof) {\n        case REACT_ELEMENT_TYPE:\n          {\n            var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);\n\n            _created.ref = coerceRef(returnFiber, null, newChild);\n            _created.return = returnFiber;\n            return _created;\n          }\n\n        case REACT_PORTAL_TYPE:\n          {\n            var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);\n\n            _created2.return = returnFiber;\n            return _created2;\n          }\n      }\n\n      if (isArray$1(newChild) || getIteratorFn(newChild)) {\n        var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);\n\n        _created3.return = returnFiber;\n        return _created3;\n      }\n\n      throwOnInvalidObjectType(returnFiber, newChild);\n    }\n\n    {\n      if (typeof newChild === 'function') {\n        warnOnFunctionType();\n      }\n    }\n\n    return null;\n  }\n\n  function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {\n    // Update the fiber if the keys match, otherwise return null.\n    var key = oldFiber !== null ? oldFiber.key : null;\n\n    if (typeof newChild === 'string' || typeof newChild === 'number') {\n      // Text nodes don't have keys. If the previous node is implicitly keyed\n      // we can continue to replace it without aborting even if it is not a text\n      // node.\n      if (key !== null) {\n        return null;\n      }\n\n      return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);\n    }\n\n    if (typeof newChild === 'object' && newChild !== null) {\n      switch (newChild.$$typeof) {\n        case REACT_ELEMENT_TYPE:\n          {\n            if (newChild.key === key) {\n              if (newChild.type === REACT_FRAGMENT_TYPE) {\n                return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);\n              }\n\n              return updateElement(returnFiber, oldFiber, newChild, expirationTime);\n            } else {\n              return null;\n            }\n          }\n\n        case REACT_PORTAL_TYPE:\n          {\n            if (newChild.key === key) {\n              return updatePortal(returnFiber, oldFiber, newChild, expirationTime);\n            } else {\n              return null;\n            }\n          }\n      }\n\n      if (isArray$1(newChild) || getIteratorFn(newChild)) {\n        if (key !== null) {\n          return null;\n        }\n\n        return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);\n      }\n\n      throwOnInvalidObjectType(returnFiber, newChild);\n    }\n\n    {\n      if (typeof newChild === 'function') {\n        warnOnFunctionType();\n      }\n    }\n\n    return null;\n  }\n\n  function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {\n    if (typeof newChild === 'string' || typeof newChild === 'number') {\n      // Text nodes don't have keys, so we neither have to check the old nor\n      // new node for the key. If both are text nodes, they match.\n      var matchedFiber = existingChildren.get(newIdx) || null;\n      return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);\n    }\n\n    if (typeof newChild === 'object' && newChild !== null) {\n      switch (newChild.$$typeof) {\n        case REACT_ELEMENT_TYPE:\n          {\n            var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;\n\n            if (newChild.type === REACT_FRAGMENT_TYPE) {\n              return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);\n            }\n\n            return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);\n          }\n\n        case REACT_PORTAL_TYPE:\n          {\n            var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;\n\n            return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);\n          }\n      }\n\n      if (isArray$1(newChild) || getIteratorFn(newChild)) {\n        var _matchedFiber3 = existingChildren.get(newIdx) || null;\n\n        return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);\n      }\n\n      throwOnInvalidObjectType(returnFiber, newChild);\n    }\n\n    {\n      if (typeof newChild === 'function') {\n        warnOnFunctionType();\n      }\n    }\n\n    return null;\n  }\n  /**\n   * Warns if there is a duplicate or missing key\n   */\n\n\n  function warnOnInvalidKey(child, knownKeys) {\n    {\n      if (typeof child !== 'object' || child === null) {\n        return knownKeys;\n      }\n\n      switch (child.$$typeof) {\n        case REACT_ELEMENT_TYPE:\n        case REACT_PORTAL_TYPE:\n          warnForMissingKey(child);\n          var key = child.key;\n\n          if (typeof key !== 'string') {\n            break;\n          }\n\n          if (knownKeys === null) {\n            knownKeys = new Set();\n            knownKeys.add(key);\n            break;\n          }\n\n          if (!knownKeys.has(key)) {\n            knownKeys.add(key);\n            break;\n          }\n\n          error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);\n\n          break;\n      }\n    }\n\n    return knownKeys;\n  }\n\n  function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {\n    // This algorithm can't optimize by searching from both ends since we\n    // don't have backpointers on fibers. I'm trying to see how far we can get\n    // with that model. If it ends up not being worth the tradeoffs, we can\n    // add it later.\n    // Even with a two ended optimization, we'd want to optimize for the case\n    // where there are few changes and brute force the comparison instead of\n    // going for the Map. It'd like to explore hitting that path first in\n    // forward-only mode and only go for the Map once we notice that we need\n    // lots of look ahead. This doesn't handle reversal as well as two ended\n    // search but that's unusual. Besides, for the two ended optimization to\n    // work on Iterables, we'd need to copy the whole set.\n    // In this first iteration, we'll just live with hitting the bad case\n    // (adding everything to a Map) in for every insert/move.\n    // If you change this code, also update reconcileChildrenIterator() which\n    // uses the same algorithm.\n    {\n      // First, validate keys.\n      var knownKeys = null;\n\n      for (var i = 0; i < newChildren.length; i++) {\n        var child = newChildren[i];\n        knownKeys = warnOnInvalidKey(child, knownKeys);\n      }\n    }\n\n    var resultingFirstChild = null;\n    var previousNewFiber = null;\n    var oldFiber = currentFirstChild;\n    var lastPlacedIndex = 0;\n    var newIdx = 0;\n    var nextOldFiber = null;\n\n    for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {\n      if (oldFiber.index > newIdx) {\n        nextOldFiber = oldFiber;\n        oldFiber = null;\n      } else {\n        nextOldFiber = oldFiber.sibling;\n      }\n\n      var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);\n\n      if (newFiber === null) {\n        // TODO: This breaks on empty slots like null children. That's\n        // unfortunate because it triggers the slow path all the time. We need\n        // a better way to communicate whether this was a miss or null,\n        // boolean, undefined, etc.\n        if (oldFiber === null) {\n          oldFiber = nextOldFiber;\n        }\n\n        break;\n      }\n\n      if (shouldTrackSideEffects) {\n        if (oldFiber && newFiber.alternate === null) {\n          // We matched the slot, but we didn't reuse the existing fiber, so we\n          // need to delete the existing child.\n          deleteChild(returnFiber, oldFiber);\n        }\n      }\n\n      lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);\n\n      if (previousNewFiber === null) {\n        // TODO: Move out of the loop. This only happens for the first run.\n        resultingFirstChild = newFiber;\n      } else {\n        // TODO: Defer siblings if we're not at the right index for this slot.\n        // I.e. if we had null values before, then we want to defer this\n        // for each null value. However, we also don't want to call updateSlot\n        // with the previous one.\n        previousNewFiber.sibling = newFiber;\n      }\n\n      previousNewFiber = newFiber;\n      oldFiber = nextOldFiber;\n    }\n\n    if (newIdx === newChildren.length) {\n      // We've reached the end of the new children. We can delete the rest.\n      deleteRemainingChildren(returnFiber, oldFiber);\n      return resultingFirstChild;\n    }\n\n    if (oldFiber === null) {\n      // If we don't have any more existing children we can choose a fast path\n      // since the rest will all be insertions.\n      for (; newIdx < newChildren.length; newIdx++) {\n        var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);\n\n        if (_newFiber === null) {\n          continue;\n        }\n\n        lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);\n\n        if (previousNewFiber === null) {\n          // TODO: Move out of the loop. This only happens for the first run.\n          resultingFirstChild = _newFiber;\n        } else {\n          previousNewFiber.sibling = _newFiber;\n        }\n\n        previousNewFiber = _newFiber;\n      }\n\n      return resultingFirstChild;\n    } // Add all children to a key map for quick lookups.\n\n\n    var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.\n\n    for (; newIdx < newChildren.length; newIdx++) {\n      var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);\n\n      if (_newFiber2 !== null) {\n        if (shouldTrackSideEffects) {\n          if (_newFiber2.alternate !== null) {\n            // The new fiber is a work in progress, but if there exists a\n            // current, that means that we reused the fiber. We need to delete\n            // it from the child list so that we don't add it to the deletion\n            // list.\n            existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);\n          }\n        }\n\n        lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);\n\n        if (previousNewFiber === null) {\n          resultingFirstChild = _newFiber2;\n        } else {\n          previousNewFiber.sibling = _newFiber2;\n        }\n\n        previousNewFiber = _newFiber2;\n      }\n    }\n\n    if (shouldTrackSideEffects) {\n      // Any existing children that weren't consumed above were deleted. We need\n      // to add them to the deletion list.\n      existingChildren.forEach(function (child) {\n        return deleteChild(returnFiber, child);\n      });\n    }\n\n    return resultingFirstChild;\n  }\n\n  function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {\n    // This is the same implementation as reconcileChildrenArray(),\n    // but using the iterator instead.\n    var iteratorFn = getIteratorFn(newChildrenIterable);\n\n    if (!(typeof iteratorFn === 'function')) {\n      {\n        throw Error( \"An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.\" );\n      }\n    }\n\n    {\n      // We don't support rendering Generators because it's a mutation.\n      // See https://github.com/facebook/react/issues/12995\n      if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag\n      newChildrenIterable[Symbol.toStringTag] === 'Generator') {\n        if (!didWarnAboutGenerators) {\n          error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');\n        }\n\n        didWarnAboutGenerators = true;\n      } // Warn about using Maps as children\n\n\n      if (newChildrenIterable.entries === iteratorFn) {\n        if (!didWarnAboutMaps) {\n          error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');\n        }\n\n        didWarnAboutMaps = true;\n      } // First, validate keys.\n      // We'll get a different iterator later for the main pass.\n\n\n      var _newChildren = iteratorFn.call(newChildrenIterable);\n\n      if (_newChildren) {\n        var knownKeys = null;\n\n        var _step = _newChildren.next();\n\n        for (; !_step.done; _step = _newChildren.next()) {\n          var child = _step.value;\n          knownKeys = warnOnInvalidKey(child, knownKeys);\n        }\n      }\n    }\n\n    var newChildren = iteratorFn.call(newChildrenIterable);\n\n    if (!(newChildren != null)) {\n      {\n        throw Error( \"An iterable object provided no iterator.\" );\n      }\n    }\n\n    var resultingFirstChild = null;\n    var previousNewFiber = null;\n    var oldFiber = currentFirstChild;\n    var lastPlacedIndex = 0;\n    var newIdx = 0;\n    var nextOldFiber = null;\n    var step = newChildren.next();\n\n    for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {\n      if (oldFiber.index > newIdx) {\n        nextOldFiber = oldFiber;\n        oldFiber = null;\n      } else {\n        nextOldFiber = oldFiber.sibling;\n      }\n\n      var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);\n\n      if (newFiber === null) {\n        // TODO: This breaks on empty slots like null children. That's\n        // unfortunate because it triggers the slow path all the time. We need\n        // a better way to communicate whether this was a miss or null,\n        // boolean, undefined, etc.\n        if (oldFiber === null) {\n          oldFiber = nextOldFiber;\n        }\n\n        break;\n      }\n\n      if (shouldTrackSideEffects) {\n        if (oldFiber && newFiber.alternate === null) {\n          // We matched the slot, but we didn't reuse the existing fiber, so we\n          // need to delete the existing child.\n          deleteChild(returnFiber, oldFiber);\n        }\n      }\n\n      lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);\n\n      if (previousNewFiber === null) {\n        // TODO: Move out of the loop. This only happens for the first run.\n        resultingFirstChild = newFiber;\n      } else {\n        // TODO: Defer siblings if we're not at the right index for this slot.\n        // I.e. if we had null values before, then we want to defer this\n        // for each null value. However, we also don't want to call updateSlot\n        // with the previous one.\n        previousNewFiber.sibling = newFiber;\n      }\n\n      previousNewFiber = newFiber;\n      oldFiber = nextOldFiber;\n    }\n\n    if (step.done) {\n      // We've reached the end of the new children. We can delete the rest.\n      deleteRemainingChildren(returnFiber, oldFiber);\n      return resultingFirstChild;\n    }\n\n    if (oldFiber === null) {\n      // If we don't have any more existing children we can choose a fast path\n      // since the rest will all be insertions.\n      for (; !step.done; newIdx++, step = newChildren.next()) {\n        var _newFiber3 = createChild(returnFiber, step.value, expirationTime);\n\n        if (_newFiber3 === null) {\n          continue;\n        }\n\n        lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);\n\n        if (previousNewFiber === null) {\n          // TODO: Move out of the loop. This only happens for the first run.\n          resultingFirstChild = _newFiber3;\n        } else {\n          previousNewFiber.sibling = _newFiber3;\n        }\n\n        previousNewFiber = _newFiber3;\n      }\n\n      return resultingFirstChild;\n    } // Add all children to a key map for quick lookups.\n\n\n    var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.\n\n    for (; !step.done; newIdx++, step = newChildren.next()) {\n      var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);\n\n      if (_newFiber4 !== null) {\n        if (shouldTrackSideEffects) {\n          if (_newFiber4.alternate !== null) {\n            // The new fiber is a work in progress, but if there exists a\n            // current, that means that we reused the fiber. We need to delete\n            // it from the child list so that we don't add it to the deletion\n            // list.\n            existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);\n          }\n        }\n\n        lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);\n\n        if (previousNewFiber === null) {\n          resultingFirstChild = _newFiber4;\n        } else {\n          previousNewFiber.sibling = _newFiber4;\n        }\n\n        previousNewFiber = _newFiber4;\n      }\n    }\n\n    if (shouldTrackSideEffects) {\n      // Any existing children that weren't consumed above were deleted. We need\n      // to add them to the deletion list.\n      existingChildren.forEach(function (child) {\n        return deleteChild(returnFiber, child);\n      });\n    }\n\n    return resultingFirstChild;\n  }\n\n  function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {\n    // There's no need to check for keys on text nodes since we don't have a\n    // way to define them.\n    if (currentFirstChild !== null && currentFirstChild.tag === HostText) {\n      // We already have an existing node so let's just update it and delete\n      // the rest.\n      deleteRemainingChildren(returnFiber, currentFirstChild.sibling);\n      var existing = useFiber(currentFirstChild, textContent);\n      existing.return = returnFiber;\n      return existing;\n    } // The existing first child is not a text node so we need to create one\n    // and delete the existing ones.\n\n\n    deleteRemainingChildren(returnFiber, currentFirstChild);\n    var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);\n    created.return = returnFiber;\n    return created;\n  }\n\n  function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {\n    var key = element.key;\n    var child = currentFirstChild;\n\n    while (child !== null) {\n      // TODO: If key === null and child.key === null, then this only applies to\n      // the first item in the list.\n      if (child.key === key) {\n        switch (child.tag) {\n          case Fragment:\n            {\n              if (element.type === REACT_FRAGMENT_TYPE) {\n                deleteRemainingChildren(returnFiber, child.sibling);\n                var existing = useFiber(child, element.props.children);\n                existing.return = returnFiber;\n\n                {\n                  existing._debugSource = element._source;\n                  existing._debugOwner = element._owner;\n                }\n\n                return existing;\n              }\n\n              break;\n            }\n\n          case Block:\n\n          // We intentionally fallthrough here if enableBlocksAPI is not on.\n          // eslint-disable-next-lined no-fallthrough\n\n          default:\n            {\n              if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:\n               isCompatibleFamilyForHotReloading(child, element) )) {\n                deleteRemainingChildren(returnFiber, child.sibling);\n\n                var _existing3 = useFiber(child, element.props);\n\n                _existing3.ref = coerceRef(returnFiber, child, element);\n                _existing3.return = returnFiber;\n\n                {\n                  _existing3._debugSource = element._source;\n                  _existing3._debugOwner = element._owner;\n                }\n\n                return _existing3;\n              }\n\n              break;\n            }\n        } // Didn't match.\n\n\n        deleteRemainingChildren(returnFiber, child);\n        break;\n      } else {\n        deleteChild(returnFiber, child);\n      }\n\n      child = child.sibling;\n    }\n\n    if (element.type === REACT_FRAGMENT_TYPE) {\n      var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);\n      created.return = returnFiber;\n      return created;\n    } else {\n      var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);\n\n      _created4.ref = coerceRef(returnFiber, currentFirstChild, element);\n      _created4.return = returnFiber;\n      return _created4;\n    }\n  }\n\n  function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {\n    var key = portal.key;\n    var child = currentFirstChild;\n\n    while (child !== null) {\n      // TODO: If key === null and child.key === null, then this only applies to\n      // the first item in the list.\n      if (child.key === key) {\n        if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {\n          deleteRemainingChildren(returnFiber, child.sibling);\n          var existing = useFiber(child, portal.children || []);\n          existing.return = returnFiber;\n          return existing;\n        } else {\n          deleteRemainingChildren(returnFiber, child);\n          break;\n        }\n      } else {\n        deleteChild(returnFiber, child);\n      }\n\n      child = child.sibling;\n    }\n\n    var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);\n    created.return = returnFiber;\n    return created;\n  } // This API will tag the children with the side-effect of the reconciliation\n  // itself. They will be added to the side-effect list as we pass through the\n  // children and the parent.\n\n\n  function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {\n    // This function is not recursive.\n    // If the top level item is an array, we treat it as a set of children,\n    // not as a fragment. Nested arrays on the other hand will be treated as\n    // fragment nodes. Recursion happens at the normal flow.\n    // Handle top level unkeyed fragments as if they were arrays.\n    // This leads to an ambiguity between <>{[...]}</> and <>...</>.\n    // We treat the ambiguous cases above the same.\n    var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;\n\n    if (isUnkeyedTopLevelFragment) {\n      newChild = newChild.props.children;\n    } // Handle object types\n\n\n    var isObject = typeof newChild === 'object' && newChild !== null;\n\n    if (isObject) {\n      switch (newChild.$$typeof) {\n        case REACT_ELEMENT_TYPE:\n          return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));\n\n        case REACT_PORTAL_TYPE:\n          return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));\n      }\n    }\n\n    if (typeof newChild === 'string' || typeof newChild === 'number') {\n      return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));\n    }\n\n    if (isArray$1(newChild)) {\n      return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);\n    }\n\n    if (getIteratorFn(newChild)) {\n      return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);\n    }\n\n    if (isObject) {\n      throwOnInvalidObjectType(returnFiber, newChild);\n    }\n\n    {\n      if (typeof newChild === 'function') {\n        warnOnFunctionType();\n      }\n    }\n\n    if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {\n      // If the new child is undefined, and the return fiber is a composite\n      // component, throw an error. If Fiber return types are disabled,\n      // we already threw above.\n      switch (returnFiber.tag) {\n        case ClassComponent:\n          {\n            {\n              var instance = returnFiber.stateNode;\n\n              if (instance.render._isMockFunction) {\n                // We allow auto-mocks to proceed as if they're returning null.\n                break;\n              }\n            }\n          }\n        // Intentionally fall through to the next case, which handles both\n        // functions and classes\n        // eslint-disable-next-lined no-fallthrough\n\n        case FunctionComponent:\n          {\n            var Component = returnFiber.type;\n\n            {\n              {\n                throw Error( (Component.displayName || Component.name || 'Component') + \"(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.\" );\n              }\n            }\n          }\n      }\n    } // Remaining cases are all treated as empty.\n\n\n    return deleteRemainingChildren(returnFiber, currentFirstChild);\n  }\n\n  return reconcileChildFibers;\n}\n\nvar reconcileChildFibers = ChildReconciler(true);\nvar mountChildFibers = ChildReconciler(false);\nfunction cloneChildFibers(current, workInProgress) {\n  if (!(current === null || workInProgress.child === current.child)) {\n    {\n      throw Error( \"Resuming work not yet implemented.\" );\n    }\n  }\n\n  if (workInProgress.child === null) {\n    return;\n  }\n\n  var currentChild = workInProgress.child;\n  var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);\n  workInProgress.child = newChild;\n  newChild.return = workInProgress;\n\n  while (currentChild.sibling !== null) {\n    currentChild = currentChild.sibling;\n    newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);\n    newChild.return = workInProgress;\n  }\n\n  newChild.sibling = null;\n} // Reset a workInProgress child set to prepare it for a second pass.\n\nfunction resetChildFibers(workInProgress, renderExpirationTime) {\n  var child = workInProgress.child;\n\n  while (child !== null) {\n    resetWorkInProgress(child, renderExpirationTime);\n    child = child.sibling;\n  }\n}\n\nvar NO_CONTEXT = {};\nvar contextStackCursor$1 = createCursor(NO_CONTEXT);\nvar contextFiberStackCursor = createCursor(NO_CONTEXT);\nvar rootInstanceStackCursor = createCursor(NO_CONTEXT);\n\nfunction requiredContext(c) {\n  if (!(c !== NO_CONTEXT)) {\n    {\n      throw Error( \"Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n\n  return c;\n}\n\nfunction getRootHostContainer() {\n  var rootInstance = requiredContext(rootInstanceStackCursor.current);\n  return rootInstance;\n}\n\nfunction pushHostContainer(fiber, nextRootInstance) {\n  // Push current root instance onto the stack;\n  // This allows us to reset root when portals are popped.\n  push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.\n  // This enables us to pop only Fibers that provide unique contexts.\n\n  push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.\n  // However, we can't just call getRootHostContext() and push it because\n  // we'd have a different number of entries on the stack depending on\n  // whether getRootHostContext() throws somewhere in renderer code or not.\n  // So we push an empty value first. This lets us safely unwind on errors.\n\n  push(contextStackCursor$1, NO_CONTEXT, fiber);\n  var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.\n\n  pop(contextStackCursor$1, fiber);\n  push(contextStackCursor$1, nextRootContext, fiber);\n}\n\nfunction popHostContainer(fiber) {\n  pop(contextStackCursor$1, fiber);\n  pop(contextFiberStackCursor, fiber);\n  pop(rootInstanceStackCursor, fiber);\n}\n\nfunction getHostContext() {\n  var context = requiredContext(contextStackCursor$1.current);\n  return context;\n}\n\nfunction pushHostContext(fiber) {\n  var rootInstance = requiredContext(rootInstanceStackCursor.current);\n  var context = requiredContext(contextStackCursor$1.current);\n  var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.\n\n  if (context === nextContext) {\n    return;\n  } // Track the context and the Fiber that provided it.\n  // This enables us to pop only Fibers that provide unique contexts.\n\n\n  push(contextFiberStackCursor, fiber, fiber);\n  push(contextStackCursor$1, nextContext, fiber);\n}\n\nfunction popHostContext(fiber) {\n  // Do not pop unless this Fiber provided the current context.\n  // pushHostContext() only pushes Fibers that provide unique contexts.\n  if (contextFiberStackCursor.current !== fiber) {\n    return;\n  }\n\n  pop(contextStackCursor$1, fiber);\n  pop(contextFiberStackCursor, fiber);\n}\n\nvar DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is\n// inherited deeply down the subtree. The upper bits only affect\n// this immediate suspense boundary and gets reset each new\n// boundary or suspense list.\n\nvar SubtreeSuspenseContextMask = 1; // Subtree Flags:\n// InvisibleParentSuspenseContext indicates that one of our parent Suspense\n// boundaries is not currently showing visible main content.\n// Either because it is already showing a fallback or is not mounted at all.\n// We can use this to determine if it is desirable to trigger a fallback at\n// the parent. If not, then we might need to trigger undesirable boundaries\n// and/or suspend the commit to avoid hiding the parent content.\n\nvar InvisibleParentSuspenseContext = 1; // Shallow Flags:\n// ForceSuspenseFallback can be used by SuspenseList to force newly added\n// items into their fallback state during one of the render passes.\n\nvar ForceSuspenseFallback = 2;\nvar suspenseStackCursor = createCursor(DefaultSuspenseContext);\nfunction hasSuspenseContext(parentContext, flag) {\n  return (parentContext & flag) !== 0;\n}\nfunction setDefaultShallowSuspenseContext(parentContext) {\n  return parentContext & SubtreeSuspenseContextMask;\n}\nfunction setShallowSuspenseContext(parentContext, shallowContext) {\n  return parentContext & SubtreeSuspenseContextMask | shallowContext;\n}\nfunction addSubtreeSuspenseContext(parentContext, subtreeContext) {\n  return parentContext | subtreeContext;\n}\nfunction pushSuspenseContext(fiber, newContext) {\n  push(suspenseStackCursor, newContext, fiber);\n}\nfunction popSuspenseContext(fiber) {\n  pop(suspenseStackCursor, fiber);\n}\n\nfunction shouldCaptureSuspense(workInProgress, hasInvisibleParent) {\n  // If it was the primary children that just suspended, capture and render the\n  // fallback. Otherwise, don't capture and bubble to the next boundary.\n  var nextState = workInProgress.memoizedState;\n\n  if (nextState !== null) {\n    if (nextState.dehydrated !== null) {\n      // A dehydrated boundary always captures.\n      return true;\n    }\n\n    return false;\n  }\n\n  var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.\n\n  if (props.fallback === undefined) {\n    return false;\n  } // Regular boundaries always capture.\n\n\n  if (props.unstable_avoidThisFallback !== true) {\n    return true;\n  } // If it's a boundary we should avoid, then we prefer to bubble up to the\n  // parent boundary if it is currently invisible.\n\n\n  if (hasInvisibleParent) {\n    return false;\n  } // If the parent is not able to handle it, we must handle it.\n\n\n  return true;\n}\nfunction findFirstSuspended(row) {\n  var node = row;\n\n  while (node !== null) {\n    if (node.tag === SuspenseComponent) {\n      var state = node.memoizedState;\n\n      if (state !== null) {\n        var dehydrated = state.dehydrated;\n\n        if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {\n          return node;\n        }\n      }\n    } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't\n    // keep track of whether it suspended or not.\n    node.memoizedProps.revealOrder !== undefined) {\n      var didSuspend = (node.effectTag & DidCapture) !== NoEffect;\n\n      if (didSuspend) {\n        return node;\n      }\n    } else if (node.child !== null) {\n      node.child.return = node;\n      node = node.child;\n      continue;\n    }\n\n    if (node === row) {\n      return null;\n    }\n\n    while (node.sibling === null) {\n      if (node.return === null || node.return === row) {\n        return null;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  }\n\n  return null;\n}\n\nfunction createDeprecatedResponderListener(responder, props) {\n  var eventResponderListener = {\n    responder: responder,\n    props: props\n  };\n\n  {\n    Object.freeze(eventResponderListener);\n  }\n\n  return eventResponderListener;\n}\n\nvar HasEffect =\n/* */\n1; // Represents the phase in which the effect (not the clean-up) fires.\n\nvar Layout =\n/*    */\n2;\nvar Passive$1 =\n/*   */\n4;\n\nvar ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,\n    ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;\nvar didWarnAboutMismatchedHooksForComponent;\n\n{\n  didWarnAboutMismatchedHooksForComponent = new Set();\n}\n\n// These are set right before calling the component.\nvar renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from\n// the work-in-progress hook.\n\nvar currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The\n// current hook list is the list that belongs to the current fiber. The\n// work-in-progress hook list is a new list that will be added to the\n// work-in-progress fiber.\n\nvar currentHook = null;\nvar workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This\n// does not get reset if we do another render pass; only when we're completely\n// finished evaluating this component. This is an optimization so we know\n// whether we need to clear render phase updates after a throw.\n\nvar didScheduleRenderPhaseUpdate = false;\nvar RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook\n\nvar currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.\n// The list stores the order of hooks used during the initial render (mount).\n// Subsequent renders (updates) reference this list.\n\nvar hookTypesDev = null;\nvar hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore\n// the dependencies for Hooks that need them (e.g. useEffect or useMemo).\n// When true, such Hooks will always be \"remounted\". Only used during hot reload.\n\nvar ignorePreviousDependencies = false;\n\nfunction mountHookTypesDev() {\n  {\n    var hookName = currentHookNameInDev;\n\n    if (hookTypesDev === null) {\n      hookTypesDev = [hookName];\n    } else {\n      hookTypesDev.push(hookName);\n    }\n  }\n}\n\nfunction updateHookTypesDev() {\n  {\n    var hookName = currentHookNameInDev;\n\n    if (hookTypesDev !== null) {\n      hookTypesUpdateIndexDev++;\n\n      if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {\n        warnOnHookMismatchInDev(hookName);\n      }\n    }\n  }\n}\n\nfunction checkDepsAreArrayDev(deps) {\n  {\n    if (deps !== undefined && deps !== null && !Array.isArray(deps)) {\n      // Verify deps, but only on mount to avoid extra checks.\n      // It's unlikely their type would change as usually you define them inline.\n      error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);\n    }\n  }\n}\n\nfunction warnOnHookMismatchInDev(currentHookName) {\n  {\n    var componentName = getComponentName(currentlyRenderingFiber$1.type);\n\n    if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {\n      didWarnAboutMismatchedHooksForComponent.add(componentName);\n\n      if (hookTypesDev !== null) {\n        var table = '';\n        var secondColumnStart = 30;\n\n        for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {\n          var oldHookName = hookTypesDev[i];\n          var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;\n          var row = i + 1 + \". \" + oldHookName; // Extra space so second column lines up\n          // lol @ IE not supporting String#repeat\n\n          while (row.length < secondColumnStart) {\n            row += ' ';\n          }\n\n          row += newHookName + '\\n';\n          table += row;\n        }\n\n        error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\\n\\n' + '   Previous render            Next render\\n' + '   ------------------------------------------------------\\n' + '%s' + '   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n', componentName, table);\n      }\n    }\n  }\n}\n\nfunction throwInvalidHookError() {\n  {\n    {\n      throw Error( \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.\" );\n    }\n  }\n}\n\nfunction areHookInputsEqual(nextDeps, prevDeps) {\n  {\n    if (ignorePreviousDependencies) {\n      // Only true when this component is being hot reloaded.\n      return false;\n    }\n  }\n\n  if (prevDeps === null) {\n    {\n      error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);\n    }\n\n    return false;\n  }\n\n  {\n    // Don't bother comparing lengths in prod because these arrays should be\n    // passed inline.\n    if (nextDeps.length !== prevDeps.length) {\n      error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\\n\\n' + 'Previous: %s\\n' + 'Incoming: %s', currentHookNameInDev, \"[\" + prevDeps.join(', ') + \"]\", \"[\" + nextDeps.join(', ') + \"]\");\n    }\n  }\n\n  for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {\n    if (objectIs(nextDeps[i], prevDeps[i])) {\n      continue;\n    }\n\n    return false;\n  }\n\n  return true;\n}\n\nfunction renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {\n  renderExpirationTime = nextRenderExpirationTime;\n  currentlyRenderingFiber$1 = workInProgress;\n\n  {\n    hookTypesDev = current !== null ? current._debugHookTypes : null;\n    hookTypesUpdateIndexDev = -1; // Used for hot reloading:\n\n    ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;\n  }\n\n  workInProgress.memoizedState = null;\n  workInProgress.updateQueue = null;\n  workInProgress.expirationTime = NoWork; // The following should have already been reset\n  // currentHook = null;\n  // workInProgressHook = null;\n  // didScheduleRenderPhaseUpdate = false;\n  // TODO Warn if no hooks are used at all during mount, then some are used during update.\n  // Currently we will identify the update render as a mount because memoizedState === null.\n  // This is tricky because it's valid for certain types of components (e.g. React.lazy)\n  // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.\n  // Non-stateful hooks (e.g. context) don't get added to memoizedState,\n  // so memoizedState would be null during updates and mounts.\n\n  {\n    if (current !== null && current.memoizedState !== null) {\n      ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;\n    } else if (hookTypesDev !== null) {\n      // This dispatcher handles an edge case where a component is updating,\n      // but no stateful hooks have been used.\n      // We want to match the production code behavior (which will use HooksDispatcherOnMount),\n      // but with the extra DEV validation to ensure hooks ordering hasn't changed.\n      // This dispatcher does that.\n      ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;\n    } else {\n      ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;\n    }\n  }\n\n  var children = Component(props, secondArg); // Check if there was a render phase update\n\n  if (workInProgress.expirationTime === renderExpirationTime) {\n    // Keep rendering in a loop for as long as render phase updates continue to\n    // be scheduled. Use a counter to prevent infinite loops.\n    var numberOfReRenders = 0;\n\n    do {\n      workInProgress.expirationTime = NoWork;\n\n      if (!(numberOfReRenders < RE_RENDER_LIMIT)) {\n        {\n          throw Error( \"Too many re-renders. React limits the number of renders to prevent an infinite loop.\" );\n        }\n      }\n\n      numberOfReRenders += 1;\n\n      {\n        // Even when hot reloading, allow dependencies to stabilize\n        // after first render to prevent infinite render phase updates.\n        ignorePreviousDependencies = false;\n      } // Start over from the beginning of the list\n\n\n      currentHook = null;\n      workInProgressHook = null;\n      workInProgress.updateQueue = null;\n\n      {\n        // Also validate hook order for cascading updates.\n        hookTypesUpdateIndexDev = -1;\n      }\n\n      ReactCurrentDispatcher.current =  HooksDispatcherOnRerenderInDEV ;\n      children = Component(props, secondArg);\n    } while (workInProgress.expirationTime === renderExpirationTime);\n  } // We can assume the previous dispatcher is always this one, since we set it\n  // at the beginning of the render phase and there's no re-entrancy.\n\n\n  ReactCurrentDispatcher.current = ContextOnlyDispatcher;\n\n  {\n    workInProgress._debugHookTypes = hookTypesDev;\n  } // This check uses currentHook so that it works the same in DEV and prod bundles.\n  // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.\n\n\n  var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;\n  renderExpirationTime = NoWork;\n  currentlyRenderingFiber$1 = null;\n  currentHook = null;\n  workInProgressHook = null;\n\n  {\n    currentHookNameInDev = null;\n    hookTypesDev = null;\n    hookTypesUpdateIndexDev = -1;\n  }\n\n  didScheduleRenderPhaseUpdate = false;\n\n  if (!!didRenderTooFewHooks) {\n    {\n      throw Error( \"Rendered fewer hooks than expected. This may be caused by an accidental early return statement.\" );\n    }\n  }\n\n  return children;\n}\nfunction bailoutHooks(current, workInProgress, expirationTime) {\n  workInProgress.updateQueue = current.updateQueue;\n  workInProgress.effectTag &= ~(Passive | Update);\n\n  if (current.expirationTime <= expirationTime) {\n    current.expirationTime = NoWork;\n  }\n}\nfunction resetHooksAfterThrow() {\n  // We can assume the previous dispatcher is always this one, since we set it\n  // at the beginning of the render phase and there's no re-entrancy.\n  ReactCurrentDispatcher.current = ContextOnlyDispatcher;\n\n  if (didScheduleRenderPhaseUpdate) {\n    // There were render phase updates. These are only valid for this render\n    // phase, which we are now aborting. Remove the updates from the queues so\n    // they do not persist to the next render. Do not remove updates from hooks\n    // that weren't processed.\n    //\n    // Only reset the updates from the queue if it has a clone. If it does\n    // not have a clone, that means it wasn't processed, and the updates were\n    // scheduled before we entered the render phase.\n    var hook = currentlyRenderingFiber$1.memoizedState;\n\n    while (hook !== null) {\n      var queue = hook.queue;\n\n      if (queue !== null) {\n        queue.pending = null;\n      }\n\n      hook = hook.next;\n    }\n  }\n\n  renderExpirationTime = NoWork;\n  currentlyRenderingFiber$1 = null;\n  currentHook = null;\n  workInProgressHook = null;\n\n  {\n    hookTypesDev = null;\n    hookTypesUpdateIndexDev = -1;\n    currentHookNameInDev = null;\n  }\n\n  didScheduleRenderPhaseUpdate = false;\n}\n\nfunction mountWorkInProgressHook() {\n  var hook = {\n    memoizedState: null,\n    baseState: null,\n    baseQueue: null,\n    queue: null,\n    next: null\n  };\n\n  if (workInProgressHook === null) {\n    // This is the first hook in the list\n    currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;\n  } else {\n    // Append to the end of the list\n    workInProgressHook = workInProgressHook.next = hook;\n  }\n\n  return workInProgressHook;\n}\n\nfunction updateWorkInProgressHook() {\n  // This function is used both for updates and for re-renders triggered by a\n  // render phase update. It assumes there is either a current hook we can\n  // clone, or a work-in-progress hook from a previous render pass that we can\n  // use as a base. When we reach the end of the base list, we must switch to\n  // the dispatcher used for mounts.\n  var nextCurrentHook;\n\n  if (currentHook === null) {\n    var current = currentlyRenderingFiber$1.alternate;\n\n    if (current !== null) {\n      nextCurrentHook = current.memoizedState;\n    } else {\n      nextCurrentHook = null;\n    }\n  } else {\n    nextCurrentHook = currentHook.next;\n  }\n\n  var nextWorkInProgressHook;\n\n  if (workInProgressHook === null) {\n    nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;\n  } else {\n    nextWorkInProgressHook = workInProgressHook.next;\n  }\n\n  if (nextWorkInProgressHook !== null) {\n    // There's already a work-in-progress. Reuse it.\n    workInProgressHook = nextWorkInProgressHook;\n    nextWorkInProgressHook = workInProgressHook.next;\n    currentHook = nextCurrentHook;\n  } else {\n    // Clone from the current hook.\n    if (!(nextCurrentHook !== null)) {\n      {\n        throw Error( \"Rendered more hooks than during the previous render.\" );\n      }\n    }\n\n    currentHook = nextCurrentHook;\n    var newHook = {\n      memoizedState: currentHook.memoizedState,\n      baseState: currentHook.baseState,\n      baseQueue: currentHook.baseQueue,\n      queue: currentHook.queue,\n      next: null\n    };\n\n    if (workInProgressHook === null) {\n      // This is the first hook in the list.\n      currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;\n    } else {\n      // Append to the end of the list.\n      workInProgressHook = workInProgressHook.next = newHook;\n    }\n  }\n\n  return workInProgressHook;\n}\n\nfunction createFunctionComponentUpdateQueue() {\n  return {\n    lastEffect: null\n  };\n}\n\nfunction basicStateReducer(state, action) {\n  // $FlowFixMe: Flow doesn't like mixed types\n  return typeof action === 'function' ? action(state) : action;\n}\n\nfunction mountReducer(reducer, initialArg, init) {\n  var hook = mountWorkInProgressHook();\n  var initialState;\n\n  if (init !== undefined) {\n    initialState = init(initialArg);\n  } else {\n    initialState = initialArg;\n  }\n\n  hook.memoizedState = hook.baseState = initialState;\n  var queue = hook.queue = {\n    pending: null,\n    dispatch: null,\n    lastRenderedReducer: reducer,\n    lastRenderedState: initialState\n  };\n  var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);\n  return [hook.memoizedState, dispatch];\n}\n\nfunction updateReducer(reducer, initialArg, init) {\n  var hook = updateWorkInProgressHook();\n  var queue = hook.queue;\n\n  if (!(queue !== null)) {\n    {\n      throw Error( \"Should have a queue. This is likely a bug in React. Please file an issue.\" );\n    }\n  }\n\n  queue.lastRenderedReducer = reducer;\n  var current = currentHook; // The last rebase update that is NOT part of the base state.\n\n  var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.\n\n  var pendingQueue = queue.pending;\n\n  if (pendingQueue !== null) {\n    // We have new updates that haven't been processed yet.\n    // We'll add them to the base queue.\n    if (baseQueue !== null) {\n      // Merge the pending queue and the base queue.\n      var baseFirst = baseQueue.next;\n      var pendingFirst = pendingQueue.next;\n      baseQueue.next = pendingFirst;\n      pendingQueue.next = baseFirst;\n    }\n\n    current.baseQueue = baseQueue = pendingQueue;\n    queue.pending = null;\n  }\n\n  if (baseQueue !== null) {\n    // We have a queue to process.\n    var first = baseQueue.next;\n    var newState = current.baseState;\n    var newBaseState = null;\n    var newBaseQueueFirst = null;\n    var newBaseQueueLast = null;\n    var update = first;\n\n    do {\n      var updateExpirationTime = update.expirationTime;\n\n      if (updateExpirationTime < renderExpirationTime) {\n        // Priority is insufficient. Skip this update. If this is the first\n        // skipped update, the previous update/state is the new base\n        // update/state.\n        var clone = {\n          expirationTime: update.expirationTime,\n          suspenseConfig: update.suspenseConfig,\n          action: update.action,\n          eagerReducer: update.eagerReducer,\n          eagerState: update.eagerState,\n          next: null\n        };\n\n        if (newBaseQueueLast === null) {\n          newBaseQueueFirst = newBaseQueueLast = clone;\n          newBaseState = newState;\n        } else {\n          newBaseQueueLast = newBaseQueueLast.next = clone;\n        } // Update the remaining priority in the queue.\n\n\n        if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {\n          currentlyRenderingFiber$1.expirationTime = updateExpirationTime;\n          markUnprocessedUpdateTime(updateExpirationTime);\n        }\n      } else {\n        // This update does have sufficient priority.\n        if (newBaseQueueLast !== null) {\n          var _clone = {\n            expirationTime: Sync,\n            // This update is going to be committed so we never want uncommit it.\n            suspenseConfig: update.suspenseConfig,\n            action: update.action,\n            eagerReducer: update.eagerReducer,\n            eagerState: update.eagerState,\n            next: null\n          };\n          newBaseQueueLast = newBaseQueueLast.next = _clone;\n        } // Mark the event time of this update as relevant to this render pass.\n        // TODO: This should ideally use the true event time of this update rather than\n        // its priority which is a derived and not reverseable value.\n        // TODO: We should skip this update if it was already committed but currently\n        // we have no way of detecting the difference between a committed and suspended\n        // update here.\n\n\n        markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.\n\n        if (update.eagerReducer === reducer) {\n          // If this update was processed eagerly, and its reducer matches the\n          // current reducer, we can use the eagerly computed state.\n          newState = update.eagerState;\n        } else {\n          var action = update.action;\n          newState = reducer(newState, action);\n        }\n      }\n\n      update = update.next;\n    } while (update !== null && update !== first);\n\n    if (newBaseQueueLast === null) {\n      newBaseState = newState;\n    } else {\n      newBaseQueueLast.next = newBaseQueueFirst;\n    } // Mark that the fiber performed work, but only if the new state is\n    // different from the current state.\n\n\n    if (!objectIs(newState, hook.memoizedState)) {\n      markWorkInProgressReceivedUpdate();\n    }\n\n    hook.memoizedState = newState;\n    hook.baseState = newBaseState;\n    hook.baseQueue = newBaseQueueLast;\n    queue.lastRenderedState = newState;\n  }\n\n  var dispatch = queue.dispatch;\n  return [hook.memoizedState, dispatch];\n}\n\nfunction rerenderReducer(reducer, initialArg, init) {\n  var hook = updateWorkInProgressHook();\n  var queue = hook.queue;\n\n  if (!(queue !== null)) {\n    {\n      throw Error( \"Should have a queue. This is likely a bug in React. Please file an issue.\" );\n    }\n  }\n\n  queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous\n  // work-in-progress hook.\n\n  var dispatch = queue.dispatch;\n  var lastRenderPhaseUpdate = queue.pending;\n  var newState = hook.memoizedState;\n\n  if (lastRenderPhaseUpdate !== null) {\n    // The queue doesn't persist past this render pass.\n    queue.pending = null;\n    var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;\n    var update = firstRenderPhaseUpdate;\n\n    do {\n      // Process this render phase update. We don't have to check the\n      // priority because it will always be the same as the current\n      // render's.\n      var action = update.action;\n      newState = reducer(newState, action);\n      update = update.next;\n    } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is\n    // different from the current state.\n\n\n    if (!objectIs(newState, hook.memoizedState)) {\n      markWorkInProgressReceivedUpdate();\n    }\n\n    hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to\n    // the base state unless the queue is empty.\n    // TODO: Not sure if this is the desired semantics, but it's what we\n    // do for gDSFP. I can't remember why.\n\n    if (hook.baseQueue === null) {\n      hook.baseState = newState;\n    }\n\n    queue.lastRenderedState = newState;\n  }\n\n  return [newState, dispatch];\n}\n\nfunction mountState(initialState) {\n  var hook = mountWorkInProgressHook();\n\n  if (typeof initialState === 'function') {\n    // $FlowFixMe: Flow doesn't like mixed types\n    initialState = initialState();\n  }\n\n  hook.memoizedState = hook.baseState = initialState;\n  var queue = hook.queue = {\n    pending: null,\n    dispatch: null,\n    lastRenderedReducer: basicStateReducer,\n    lastRenderedState: initialState\n  };\n  var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);\n  return [hook.memoizedState, dispatch];\n}\n\nfunction updateState(initialState) {\n  return updateReducer(basicStateReducer);\n}\n\nfunction rerenderState(initialState) {\n  return rerenderReducer(basicStateReducer);\n}\n\nfunction pushEffect(tag, create, destroy, deps) {\n  var effect = {\n    tag: tag,\n    create: create,\n    destroy: destroy,\n    deps: deps,\n    // Circular\n    next: null\n  };\n  var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;\n\n  if (componentUpdateQueue === null) {\n    componentUpdateQueue = createFunctionComponentUpdateQueue();\n    currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;\n    componentUpdateQueue.lastEffect = effect.next = effect;\n  } else {\n    var lastEffect = componentUpdateQueue.lastEffect;\n\n    if (lastEffect === null) {\n      componentUpdateQueue.lastEffect = effect.next = effect;\n    } else {\n      var firstEffect = lastEffect.next;\n      lastEffect.next = effect;\n      effect.next = firstEffect;\n      componentUpdateQueue.lastEffect = effect;\n    }\n  }\n\n  return effect;\n}\n\nfunction mountRef(initialValue) {\n  var hook = mountWorkInProgressHook();\n  var ref = {\n    current: initialValue\n  };\n\n  {\n    Object.seal(ref);\n  }\n\n  hook.memoizedState = ref;\n  return ref;\n}\n\nfunction updateRef(initialValue) {\n  var hook = updateWorkInProgressHook();\n  return hook.memoizedState;\n}\n\nfunction mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {\n  var hook = mountWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  currentlyRenderingFiber$1.effectTag |= fiberEffectTag;\n  hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);\n}\n\nfunction updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {\n  var hook = updateWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  var destroy = undefined;\n\n  if (currentHook !== null) {\n    var prevEffect = currentHook.memoizedState;\n    destroy = prevEffect.destroy;\n\n    if (nextDeps !== null) {\n      var prevDeps = prevEffect.deps;\n\n      if (areHookInputsEqual(nextDeps, prevDeps)) {\n        pushEffect(hookEffectTag, create, destroy, nextDeps);\n        return;\n      }\n    }\n  }\n\n  currentlyRenderingFiber$1.effectTag |= fiberEffectTag;\n  hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);\n}\n\nfunction mountEffect(create, deps) {\n  {\n    // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests\n    if ('undefined' !== typeof jest) {\n      warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);\n    }\n  }\n\n  return mountEffectImpl(Update | Passive, Passive$1, create, deps);\n}\n\nfunction updateEffect(create, deps) {\n  {\n    // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests\n    if ('undefined' !== typeof jest) {\n      warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);\n    }\n  }\n\n  return updateEffectImpl(Update | Passive, Passive$1, create, deps);\n}\n\nfunction mountLayoutEffect(create, deps) {\n  return mountEffectImpl(Update, Layout, create, deps);\n}\n\nfunction updateLayoutEffect(create, deps) {\n  return updateEffectImpl(Update, Layout, create, deps);\n}\n\nfunction imperativeHandleEffect(create, ref) {\n  if (typeof ref === 'function') {\n    var refCallback = ref;\n\n    var _inst = create();\n\n    refCallback(_inst);\n    return function () {\n      refCallback(null);\n    };\n  } else if (ref !== null && ref !== undefined) {\n    var refObject = ref;\n\n    {\n      if (!refObject.hasOwnProperty('current')) {\n        error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');\n      }\n    }\n\n    var _inst2 = create();\n\n    refObject.current = _inst2;\n    return function () {\n      refObject.current = null;\n    };\n  }\n}\n\nfunction mountImperativeHandle(ref, create, deps) {\n  {\n    if (typeof create !== 'function') {\n      error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');\n    }\n  } // TODO: If deps are provided, should we skip comparing the ref itself?\n\n\n  var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;\n  return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);\n}\n\nfunction updateImperativeHandle(ref, create, deps) {\n  {\n    if (typeof create !== 'function') {\n      error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');\n    }\n  } // TODO: If deps are provided, should we skip comparing the ref itself?\n\n\n  var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;\n  return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);\n}\n\nfunction mountDebugValue(value, formatterFn) {// This hook is normally a no-op.\n  // The react-debug-hooks package injects its own implementation\n  // so that e.g. DevTools can display custom hook values.\n}\n\nvar updateDebugValue = mountDebugValue;\n\nfunction mountCallback(callback, deps) {\n  var hook = mountWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  hook.memoizedState = [callback, nextDeps];\n  return callback;\n}\n\nfunction updateCallback(callback, deps) {\n  var hook = updateWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  var prevState = hook.memoizedState;\n\n  if (prevState !== null) {\n    if (nextDeps !== null) {\n      var prevDeps = prevState[1];\n\n      if (areHookInputsEqual(nextDeps, prevDeps)) {\n        return prevState[0];\n      }\n    }\n  }\n\n  hook.memoizedState = [callback, nextDeps];\n  return callback;\n}\n\nfunction mountMemo(nextCreate, deps) {\n  var hook = mountWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  var nextValue = nextCreate();\n  hook.memoizedState = [nextValue, nextDeps];\n  return nextValue;\n}\n\nfunction updateMemo(nextCreate, deps) {\n  var hook = updateWorkInProgressHook();\n  var nextDeps = deps === undefined ? null : deps;\n  var prevState = hook.memoizedState;\n\n  if (prevState !== null) {\n    // Assume these are defined. If they're not, areHookInputsEqual will warn.\n    if (nextDeps !== null) {\n      var prevDeps = prevState[1];\n\n      if (areHookInputsEqual(nextDeps, prevDeps)) {\n        return prevState[0];\n      }\n    }\n  }\n\n  var nextValue = nextCreate();\n  hook.memoizedState = [nextValue, nextDeps];\n  return nextValue;\n}\n\nfunction mountDeferredValue(value, config) {\n  var _mountState = mountState(value),\n      prevValue = _mountState[0],\n      setValue = _mountState[1];\n\n  mountEffect(function () {\n    var previousConfig = ReactCurrentBatchConfig$1.suspense;\n    ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;\n\n    try {\n      setValue(value);\n    } finally {\n      ReactCurrentBatchConfig$1.suspense = previousConfig;\n    }\n  }, [value, config]);\n  return prevValue;\n}\n\nfunction updateDeferredValue(value, config) {\n  var _updateState = updateState(),\n      prevValue = _updateState[0],\n      setValue = _updateState[1];\n\n  updateEffect(function () {\n    var previousConfig = ReactCurrentBatchConfig$1.suspense;\n    ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;\n\n    try {\n      setValue(value);\n    } finally {\n      ReactCurrentBatchConfig$1.suspense = previousConfig;\n    }\n  }, [value, config]);\n  return prevValue;\n}\n\nfunction rerenderDeferredValue(value, config) {\n  var _rerenderState = rerenderState(),\n      prevValue = _rerenderState[0],\n      setValue = _rerenderState[1];\n\n  updateEffect(function () {\n    var previousConfig = ReactCurrentBatchConfig$1.suspense;\n    ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;\n\n    try {\n      setValue(value);\n    } finally {\n      ReactCurrentBatchConfig$1.suspense = previousConfig;\n    }\n  }, [value, config]);\n  return prevValue;\n}\n\nfunction startTransition(setPending, config, callback) {\n  var priorityLevel = getCurrentPriorityLevel();\n  runWithPriority$1(priorityLevel < UserBlockingPriority$1 ? UserBlockingPriority$1 : priorityLevel, function () {\n    setPending(true);\n  });\n  runWithPriority$1(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {\n    var previousConfig = ReactCurrentBatchConfig$1.suspense;\n    ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;\n\n    try {\n      setPending(false);\n      callback();\n    } finally {\n      ReactCurrentBatchConfig$1.suspense = previousConfig;\n    }\n  });\n}\n\nfunction mountTransition(config) {\n  var _mountState2 = mountState(false),\n      isPending = _mountState2[0],\n      setPending = _mountState2[1];\n\n  var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);\n  return [start, isPending];\n}\n\nfunction updateTransition(config) {\n  var _updateState2 = updateState(),\n      isPending = _updateState2[0],\n      setPending = _updateState2[1];\n\n  var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);\n  return [start, isPending];\n}\n\nfunction rerenderTransition(config) {\n  var _rerenderState2 = rerenderState(),\n      isPending = _rerenderState2[0],\n      setPending = _rerenderState2[1];\n\n  var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);\n  return [start, isPending];\n}\n\nfunction dispatchAction(fiber, queue, action) {\n  {\n    if (typeof arguments[3] === 'function') {\n      error(\"State updates from the useState() and useReducer() Hooks don't support the \" + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');\n    }\n  }\n\n  var currentTime = requestCurrentTimeForUpdate();\n  var suspenseConfig = requestCurrentSuspenseConfig();\n  var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);\n  var update = {\n    expirationTime: expirationTime,\n    suspenseConfig: suspenseConfig,\n    action: action,\n    eagerReducer: null,\n    eagerState: null,\n    next: null\n  };\n\n  {\n    update.priority = getCurrentPriorityLevel();\n  } // Append the update to the end of the list.\n\n\n  var pending = queue.pending;\n\n  if (pending === null) {\n    // This is the first update. Create a circular list.\n    update.next = update;\n  } else {\n    update.next = pending.next;\n    pending.next = update;\n  }\n\n  queue.pending = update;\n  var alternate = fiber.alternate;\n\n  if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {\n    // This is a render phase update. Stash it in a lazily-created map of\n    // queue -> linked list of updates. After this render pass, we'll restart\n    // and apply the stashed updates on top of the work-in-progress hook.\n    didScheduleRenderPhaseUpdate = true;\n    update.expirationTime = renderExpirationTime;\n    currentlyRenderingFiber$1.expirationTime = renderExpirationTime;\n  } else {\n    if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {\n      // The queue is currently empty, which means we can eagerly compute the\n      // next state before entering the render phase. If the new state is the\n      // same as the current state, we may be able to bail out entirely.\n      var lastRenderedReducer = queue.lastRenderedReducer;\n\n      if (lastRenderedReducer !== null) {\n        var prevDispatcher;\n\n        {\n          prevDispatcher = ReactCurrentDispatcher.current;\n          ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n        }\n\n        try {\n          var currentState = queue.lastRenderedState;\n          var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute\n          // it, on the update object. If the reducer hasn't changed by the\n          // time we enter the render phase, then the eager state can be used\n          // without calling the reducer again.\n\n          update.eagerReducer = lastRenderedReducer;\n          update.eagerState = eagerState;\n\n          if (objectIs(eagerState, currentState)) {\n            // Fast path. We can bail out without scheduling React to re-render.\n            // It's still possible that we'll need to rebase this update later,\n            // if the component re-renders for a different reason and by that\n            // time the reducer has changed.\n            return;\n          }\n        } catch (error) {// Suppress the error. It will throw again in the render phase.\n        } finally {\n          {\n            ReactCurrentDispatcher.current = prevDispatcher;\n          }\n        }\n      }\n    }\n\n    {\n      // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests\n      if ('undefined' !== typeof jest) {\n        warnIfNotScopedWithMatchingAct(fiber);\n        warnIfNotCurrentlyActingUpdatesInDev(fiber);\n      }\n    }\n\n    scheduleWork(fiber, expirationTime);\n  }\n}\n\nvar ContextOnlyDispatcher = {\n  readContext: readContext,\n  useCallback: throwInvalidHookError,\n  useContext: throwInvalidHookError,\n  useEffect: throwInvalidHookError,\n  useImperativeHandle: throwInvalidHookError,\n  useLayoutEffect: throwInvalidHookError,\n  useMemo: throwInvalidHookError,\n  useReducer: throwInvalidHookError,\n  useRef: throwInvalidHookError,\n  useState: throwInvalidHookError,\n  useDebugValue: throwInvalidHookError,\n  useResponder: throwInvalidHookError,\n  useDeferredValue: throwInvalidHookError,\n  useTransition: throwInvalidHookError\n};\nvar HooksDispatcherOnMountInDEV = null;\nvar HooksDispatcherOnMountWithHookTypesInDEV = null;\nvar HooksDispatcherOnUpdateInDEV = null;\nvar HooksDispatcherOnRerenderInDEV = null;\nvar InvalidNestedHooksDispatcherOnMountInDEV = null;\nvar InvalidNestedHooksDispatcherOnUpdateInDEV = null;\nvar InvalidNestedHooksDispatcherOnRerenderInDEV = null;\n\n{\n  var warnInvalidContextAccess = function () {\n    error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');\n  };\n\n  var warnInvalidHookAccess = function () {\n    error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');\n  };\n\n  HooksDispatcherOnMountInDEV = {\n    readContext: function (context, observedBits) {\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      mountHookTypesDev();\n      checkDepsAreArrayDev(deps);\n      return mountCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      mountHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      mountHookTypesDev();\n      checkDepsAreArrayDev(deps);\n      return mountEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      mountHookTypesDev();\n      checkDepsAreArrayDev(deps);\n      return mountImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      mountHookTypesDev();\n      checkDepsAreArrayDev(deps);\n      return mountLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      mountHookTypesDev();\n      checkDepsAreArrayDev(deps);\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      mountHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      mountHookTypesDev();\n      return mountRef(initialValue);\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      mountHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      mountHookTypesDev();\n      return mountDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      mountHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      mountHookTypesDev();\n      return mountDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      mountHookTypesDev();\n      return mountTransition(config);\n    }\n  };\n  HooksDispatcherOnMountWithHookTypesInDEV = {\n    readContext: function (context, observedBits) {\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      updateHookTypesDev();\n      return mountCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      updateHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      updateHookTypesDev();\n      return mountEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      updateHookTypesDev();\n      return mountImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      updateHookTypesDev();\n      return mountLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      updateHookTypesDev();\n      return mountRef(initialValue);\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      updateHookTypesDev();\n      return mountDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      updateHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      updateHookTypesDev();\n      return mountDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      updateHookTypesDev();\n      return mountTransition(config);\n    }\n  };\n  HooksDispatcherOnUpdateInDEV = {\n    readContext: function (context, observedBits) {\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      updateHookTypesDev();\n      return updateCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      updateHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      updateHookTypesDev();\n      return updateEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      updateHookTypesDev();\n      return updateImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      updateHookTypesDev();\n      return updateLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      updateHookTypesDev();\n      return updateRef();\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      updateHookTypesDev();\n      return updateDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      updateHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      updateHookTypesDev();\n      return updateDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      updateHookTypesDev();\n      return updateTransition(config);\n    }\n  };\n  HooksDispatcherOnRerenderInDEV = {\n    readContext: function (context, observedBits) {\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      updateHookTypesDev();\n      return updateCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      updateHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      updateHookTypesDev();\n      return updateEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      updateHookTypesDev();\n      return updateImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      updateHookTypesDev();\n      return updateLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;\n\n      try {\n        return updateMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;\n\n      try {\n        return rerenderReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      updateHookTypesDev();\n      return updateRef();\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;\n\n      try {\n        return rerenderState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      updateHookTypesDev();\n      return updateDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      updateHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      updateHookTypesDev();\n      return rerenderDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      updateHookTypesDev();\n      return rerenderTransition(config);\n    }\n  };\n  InvalidNestedHooksDispatcherOnMountInDEV = {\n    readContext: function (context, observedBits) {\n      warnInvalidContextAccess();\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountRef(initialValue);\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;\n\n      try {\n        return mountState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      warnInvalidHookAccess();\n      mountHookTypesDev();\n      return mountTransition(config);\n    }\n  };\n  InvalidNestedHooksDispatcherOnUpdateInDEV = {\n    readContext: function (context, observedBits) {\n      warnInvalidContextAccess();\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateRef();\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateTransition(config);\n    }\n  };\n  InvalidNestedHooksDispatcherOnRerenderInDEV = {\n    readContext: function (context, observedBits) {\n      warnInvalidContextAccess();\n      return readContext(context, observedBits);\n    },\n    useCallback: function (callback, deps) {\n      currentHookNameInDev = 'useCallback';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateCallback(callback, deps);\n    },\n    useContext: function (context, observedBits) {\n      currentHookNameInDev = 'useContext';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return readContext(context, observedBits);\n    },\n    useEffect: function (create, deps) {\n      currentHookNameInDev = 'useEffect';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateEffect(create, deps);\n    },\n    useImperativeHandle: function (ref, create, deps) {\n      currentHookNameInDev = 'useImperativeHandle';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateImperativeHandle(ref, create, deps);\n    },\n    useLayoutEffect: function (create, deps) {\n      currentHookNameInDev = 'useLayoutEffect';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateLayoutEffect(create, deps);\n    },\n    useMemo: function (create, deps) {\n      currentHookNameInDev = 'useMemo';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return updateMemo(create, deps);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useReducer: function (reducer, initialArg, init) {\n      currentHookNameInDev = 'useReducer';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return rerenderReducer(reducer, initialArg, init);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useRef: function (initialValue) {\n      currentHookNameInDev = 'useRef';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateRef();\n    },\n    useState: function (initialState) {\n      currentHookNameInDev = 'useState';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      var prevDispatcher = ReactCurrentDispatcher.current;\n      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;\n\n      try {\n        return rerenderState(initialState);\n      } finally {\n        ReactCurrentDispatcher.current = prevDispatcher;\n      }\n    },\n    useDebugValue: function (value, formatterFn) {\n      currentHookNameInDev = 'useDebugValue';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return updateDebugValue();\n    },\n    useResponder: function (responder, props) {\n      currentHookNameInDev = 'useResponder';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return createDeprecatedResponderListener(responder, props);\n    },\n    useDeferredValue: function (value, config) {\n      currentHookNameInDev = 'useDeferredValue';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return rerenderDeferredValue(value, config);\n    },\n    useTransition: function (config) {\n      currentHookNameInDev = 'useTransition';\n      warnInvalidHookAccess();\n      updateHookTypesDev();\n      return rerenderTransition(config);\n    }\n  };\n}\n\nvar now$1 = Scheduler.unstable_now;\nvar commitTime = 0;\nvar profilerStartTime = -1;\n\nfunction getCommitTime() {\n  return commitTime;\n}\n\nfunction recordCommitTime() {\n\n  commitTime = now$1();\n}\n\nfunction startProfilerTimer(fiber) {\n\n  profilerStartTime = now$1();\n\n  if (fiber.actualStartTime < 0) {\n    fiber.actualStartTime = now$1();\n  }\n}\n\nfunction stopProfilerTimerIfRunning(fiber) {\n\n  profilerStartTime = -1;\n}\n\nfunction stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {\n\n  if (profilerStartTime >= 0) {\n    var elapsedTime = now$1() - profilerStartTime;\n    fiber.actualDuration += elapsedTime;\n\n    if (overrideBaseTime) {\n      fiber.selfBaseDuration = elapsedTime;\n    }\n\n    profilerStartTime = -1;\n  }\n}\n\n// This may have been an insertion or a hydration.\n\nvar hydrationParentFiber = null;\nvar nextHydratableInstance = null;\nvar isHydrating = false;\n\nfunction enterHydrationState(fiber) {\n\n  var parentInstance = fiber.stateNode.containerInfo;\n  nextHydratableInstance = getFirstHydratableChild(parentInstance);\n  hydrationParentFiber = fiber;\n  isHydrating = true;\n  return true;\n}\n\nfunction deleteHydratableInstance(returnFiber, instance) {\n  {\n    switch (returnFiber.tag) {\n      case HostRoot:\n        didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);\n        break;\n\n      case HostComponent:\n        didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);\n        break;\n    }\n  }\n\n  var childToDelete = createFiberFromHostInstanceForDeletion();\n  childToDelete.stateNode = instance;\n  childToDelete.return = returnFiber;\n  childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,\n  // these children are not part of the reconciliation list of children.\n  // Even if we abort and rereconcile the children, that will try to hydrate\n  // again and the nodes are still in the host tree so these will be\n  // recreated.\n\n  if (returnFiber.lastEffect !== null) {\n    returnFiber.lastEffect.nextEffect = childToDelete;\n    returnFiber.lastEffect = childToDelete;\n  } else {\n    returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;\n  }\n}\n\nfunction insertNonHydratedInstance(returnFiber, fiber) {\n  fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;\n\n  {\n    switch (returnFiber.tag) {\n      case HostRoot:\n        {\n          var parentContainer = returnFiber.stateNode.containerInfo;\n\n          switch (fiber.tag) {\n            case HostComponent:\n              var type = fiber.type;\n              var props = fiber.pendingProps;\n              didNotFindHydratableContainerInstance(parentContainer, type);\n              break;\n\n            case HostText:\n              var text = fiber.pendingProps;\n              didNotFindHydratableContainerTextInstance(parentContainer, text);\n              break;\n          }\n\n          break;\n        }\n\n      case HostComponent:\n        {\n          var parentType = returnFiber.type;\n          var parentProps = returnFiber.memoizedProps;\n          var parentInstance = returnFiber.stateNode;\n\n          switch (fiber.tag) {\n            case HostComponent:\n              var _type = fiber.type;\n              var _props = fiber.pendingProps;\n              didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);\n              break;\n\n            case HostText:\n              var _text = fiber.pendingProps;\n              didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);\n              break;\n\n            case SuspenseComponent:\n              didNotFindHydratableSuspenseInstance(parentType, parentProps);\n              break;\n          }\n\n          break;\n        }\n\n      default:\n        return;\n    }\n  }\n}\n\nfunction tryHydrate(fiber, nextInstance) {\n  switch (fiber.tag) {\n    case HostComponent:\n      {\n        var type = fiber.type;\n        var props = fiber.pendingProps;\n        var instance = canHydrateInstance(nextInstance, type);\n\n        if (instance !== null) {\n          fiber.stateNode = instance;\n          return true;\n        }\n\n        return false;\n      }\n\n    case HostText:\n      {\n        var text = fiber.pendingProps;\n        var textInstance = canHydrateTextInstance(nextInstance, text);\n\n        if (textInstance !== null) {\n          fiber.stateNode = textInstance;\n          return true;\n        }\n\n        return false;\n      }\n\n    case SuspenseComponent:\n      {\n\n        return false;\n      }\n\n    default:\n      return false;\n  }\n}\n\nfunction tryToClaimNextHydratableInstance(fiber) {\n  if (!isHydrating) {\n    return;\n  }\n\n  var nextInstance = nextHydratableInstance;\n\n  if (!nextInstance) {\n    // Nothing to hydrate. Make it an insertion.\n    insertNonHydratedInstance(hydrationParentFiber, fiber);\n    isHydrating = false;\n    hydrationParentFiber = fiber;\n    return;\n  }\n\n  var firstAttemptedInstance = nextInstance;\n\n  if (!tryHydrate(fiber, nextInstance)) {\n    // If we can't hydrate this instance let's try the next one.\n    // We use this as a heuristic. It's based on intuition and not data so it\n    // might be flawed or unnecessary.\n    nextInstance = getNextHydratableSibling(firstAttemptedInstance);\n\n    if (!nextInstance || !tryHydrate(fiber, nextInstance)) {\n      // Nothing to hydrate. Make it an insertion.\n      insertNonHydratedInstance(hydrationParentFiber, fiber);\n      isHydrating = false;\n      hydrationParentFiber = fiber;\n      return;\n    } // We matched the next one, we'll now assume that the first one was\n    // superfluous and we'll delete it. Since we can't eagerly delete it\n    // we'll have to schedule a deletion. To do that, this node needs a dummy\n    // fiber associated with it.\n\n\n    deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);\n  }\n\n  hydrationParentFiber = fiber;\n  nextHydratableInstance = getFirstHydratableChild(nextInstance);\n}\n\nfunction prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {\n\n  var instance = fiber.stateNode;\n  var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.\n\n  fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there\n  // is a new ref we mark this as an update.\n\n  if (updatePayload !== null) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction prepareToHydrateHostTextInstance(fiber) {\n\n  var textInstance = fiber.stateNode;\n  var textContent = fiber.memoizedProps;\n  var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);\n\n  {\n    if (shouldUpdate) {\n      // We assume that prepareToHydrateHostTextInstance is called in a context where the\n      // hydration parent is the parent host component of this host text.\n      var returnFiber = hydrationParentFiber;\n\n      if (returnFiber !== null) {\n        switch (returnFiber.tag) {\n          case HostRoot:\n            {\n              var parentContainer = returnFiber.stateNode.containerInfo;\n              didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);\n              break;\n            }\n\n          case HostComponent:\n            {\n              var parentType = returnFiber.type;\n              var parentProps = returnFiber.memoizedProps;\n              var parentInstance = returnFiber.stateNode;\n              didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);\n              break;\n            }\n        }\n      }\n    }\n  }\n\n  return shouldUpdate;\n}\n\nfunction skipPastDehydratedSuspenseInstance(fiber) {\n\n  var suspenseState = fiber.memoizedState;\n  var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;\n\n  if (!suspenseInstance) {\n    {\n      throw Error( \"Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n\n  return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);\n}\n\nfunction popToNextHostParent(fiber) {\n  var parent = fiber.return;\n\n  while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {\n    parent = parent.return;\n  }\n\n  hydrationParentFiber = parent;\n}\n\nfunction popHydrationState(fiber) {\n\n  if (fiber !== hydrationParentFiber) {\n    // We're deeper than the current hydration context, inside an inserted\n    // tree.\n    return false;\n  }\n\n  if (!isHydrating) {\n    // If we're not currently hydrating but we're in a hydration context, then\n    // we were an insertion and now need to pop up reenter hydration of our\n    // siblings.\n    popToNextHostParent(fiber);\n    isHydrating = true;\n    return false;\n  }\n\n  var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.\n  // We only do this deeper than head and body since they tend to have random\n  // other nodes in them. We also ignore components with pure text content in\n  // side of them.\n  // TODO: Better heuristic.\n\n  if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {\n    var nextInstance = nextHydratableInstance;\n\n    while (nextInstance) {\n      deleteHydratableInstance(fiber, nextInstance);\n      nextInstance = getNextHydratableSibling(nextInstance);\n    }\n  }\n\n  popToNextHostParent(fiber);\n\n  if (fiber.tag === SuspenseComponent) {\n    nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);\n  } else {\n    nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;\n  }\n\n  return true;\n}\n\nfunction resetHydrationState() {\n\n  hydrationParentFiber = null;\n  nextHydratableInstance = null;\n  isHydrating = false;\n}\n\nvar ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;\nvar didReceiveUpdate = false;\nvar didWarnAboutBadClass;\nvar didWarnAboutModulePatternComponent;\nvar didWarnAboutContextTypeOnFunctionComponent;\nvar didWarnAboutGetDerivedStateOnFunctionComponent;\nvar didWarnAboutFunctionRefs;\nvar didWarnAboutReassigningProps;\nvar didWarnAboutRevealOrder;\nvar didWarnAboutTailOptions;\n\n{\n  didWarnAboutBadClass = {};\n  didWarnAboutModulePatternComponent = {};\n  didWarnAboutContextTypeOnFunctionComponent = {};\n  didWarnAboutGetDerivedStateOnFunctionComponent = {};\n  didWarnAboutFunctionRefs = {};\n  didWarnAboutReassigningProps = false;\n  didWarnAboutRevealOrder = {};\n  didWarnAboutTailOptions = {};\n}\n\nfunction reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {\n  if (current === null) {\n    // If this is a fresh new component that hasn't been rendered yet, we\n    // won't update its child set by applying minimal side-effects. Instead,\n    // we will add them all to the child before it gets rendered. That means\n    // we can optimize this reconciliation pass by not tracking side-effects.\n    workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);\n  } else {\n    // If the current child is the same as the work in progress, it means that\n    // we haven't yet started any work on these children. Therefore, we use\n    // the clone algorithm to create a copy of all the current children.\n    // If we had any progressed work already, that is invalid at this point so\n    // let's throw it out.\n    workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);\n  }\n}\n\nfunction forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {\n  // This function is fork of reconcileChildren. It's used in cases where we\n  // want to reconcile without matching against the existing set. This has the\n  // effect of all current children being unmounted; even if the type and key\n  // are the same, the old child is unmounted and a new child is created.\n  //\n  // To do this, we're going to go through the reconcile algorithm twice. In\n  // the first pass, we schedule a deletion for all the current children by\n  // passing null.\n  workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we\n  // pass null in place of where we usually pass the current child set. This has\n  // the effect of remounting all children regardless of whether their\n  // identities match.\n\n  workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);\n}\n\nfunction updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {\n  // TODO: current can be non-null here even if the component\n  // hasn't yet mounted. This happens after the first render suspends.\n  // We'll need to figure out if this is fine or can cause issues.\n  {\n    if (workInProgress.type !== workInProgress.elementType) {\n      // Lazy component props can't be validated in createElement\n      // because they're only guaranteed to be resolved here.\n      var innerPropTypes = Component.propTypes;\n\n      if (innerPropTypes) {\n        checkPropTypes(innerPropTypes, nextProps, // Resolved props\n        'prop', getComponentName(Component), getCurrentFiberStackInDev);\n      }\n    }\n  }\n\n  var render = Component.render;\n  var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent\n\n  var nextChildren;\n  prepareToReadContext(workInProgress, renderExpirationTime);\n\n  {\n    ReactCurrentOwner$1.current = workInProgress;\n    setIsRendering(true);\n    nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);\n\n    if ( workInProgress.mode & StrictMode) {\n      // Only double-render components with Hooks\n      if (workInProgress.memoizedState !== null) {\n        nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);\n      }\n    }\n\n    setIsRendering(false);\n  }\n\n  if (current !== null && !didReceiveUpdate) {\n    bailoutHooks(current, workInProgress, renderExpirationTime);\n    return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {\n  if (current === null) {\n    var type = Component.type;\n\n    if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.\n    Component.defaultProps === undefined) {\n      var resolvedType = type;\n\n      {\n        resolvedType = resolveFunctionForHotReloading(type);\n      } // If this is a plain function component without default props,\n      // and with only the default shallow comparison, we upgrade it\n      // to a SimpleMemoComponent to allow fast path updates.\n\n\n      workInProgress.tag = SimpleMemoComponent;\n      workInProgress.type = resolvedType;\n\n      {\n        validateFunctionComponentInDev(workInProgress, type);\n      }\n\n      return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);\n    }\n\n    {\n      var innerPropTypes = type.propTypes;\n\n      if (innerPropTypes) {\n        // Inner memo component props aren't currently validated in createElement.\n        // We could move it there, but we'd still need this for lazy code path.\n        checkPropTypes(innerPropTypes, nextProps, // Resolved props\n        'prop', getComponentName(type), getCurrentFiberStackInDev);\n      }\n    }\n\n    var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);\n    child.ref = workInProgress.ref;\n    child.return = workInProgress;\n    workInProgress.child = child;\n    return child;\n  }\n\n  {\n    var _type = Component.type;\n    var _innerPropTypes = _type.propTypes;\n\n    if (_innerPropTypes) {\n      // Inner memo component props aren't currently validated in createElement.\n      // We could move it there, but we'd still need this for lazy code path.\n      checkPropTypes(_innerPropTypes, nextProps, // Resolved props\n      'prop', getComponentName(_type), getCurrentFiberStackInDev);\n    }\n  }\n\n  var currentChild = current.child; // This is always exactly one child\n\n  if (updateExpirationTime < renderExpirationTime) {\n    // This will be the props with resolved defaultProps,\n    // unlike current.memoizedProps which will be the unresolved ones.\n    var prevProps = currentChild.memoizedProps; // Default to shallow comparison\n\n    var compare = Component.compare;\n    compare = compare !== null ? compare : shallowEqual;\n\n    if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {\n      return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n    }\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n  var newChild = createWorkInProgress(currentChild, nextProps);\n  newChild.ref = workInProgress.ref;\n  newChild.return = workInProgress;\n  workInProgress.child = newChild;\n  return newChild;\n}\n\nfunction updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {\n  // TODO: current can be non-null here even if the component\n  // hasn't yet mounted. This happens when the inner render suspends.\n  // We'll need to figure out if this is fine or can cause issues.\n  {\n    if (workInProgress.type !== workInProgress.elementType) {\n      // Lazy component props can't be validated in createElement\n      // because they're only guaranteed to be resolved here.\n      var outerMemoType = workInProgress.elementType;\n\n      if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {\n        // We warn when you define propTypes on lazy()\n        // so let's just skip over it to find memo() outer wrapper.\n        // Inner props for memo are validated later.\n        outerMemoType = refineResolvedLazyComponent(outerMemoType);\n      }\n\n      var outerPropTypes = outerMemoType && outerMemoType.propTypes;\n\n      if (outerPropTypes) {\n        checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)\n        'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);\n      } // Inner propTypes will be validated in the function component path.\n\n    }\n  }\n\n  if (current !== null) {\n    var prevProps = current.memoizedProps;\n\n    if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.\n     workInProgress.type === current.type )) {\n      didReceiveUpdate = false;\n\n      if (updateExpirationTime < renderExpirationTime) {\n        // The pending update priority was cleared at the beginning of\n        // beginWork. We're about to bail out, but there might be additional\n        // updates at a lower priority. Usually, the priority level of the\n        // remaining updates is accumlated during the evaluation of the\n        // component (i.e. when processing the update queue). But since since\n        // we're bailing out early *without* evaluating the component, we need\n        // to account for it here, too. Reset to the value of the current fiber.\n        // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,\n        // because a MemoComponent fiber does not have hooks or an update queue;\n        // rather, it wraps around an inner component, which may or may not\n        // contains hooks.\n        // TODO: Move the reset at in beginWork out of the common path so that\n        // this is no longer necessary.\n        workInProgress.expirationTime = current.expirationTime;\n        return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n      }\n    }\n  }\n\n  return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);\n}\n\nfunction updateFragment(current, workInProgress, renderExpirationTime) {\n  var nextChildren = workInProgress.pendingProps;\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction updateMode(current, workInProgress, renderExpirationTime) {\n  var nextChildren = workInProgress.pendingProps.children;\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction updateProfiler(current, workInProgress, renderExpirationTime) {\n  {\n    workInProgress.effectTag |= Update;\n  }\n\n  var nextProps = workInProgress.pendingProps;\n  var nextChildren = nextProps.children;\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction markRef(current, workInProgress) {\n  var ref = workInProgress.ref;\n\n  if (current === null && ref !== null || current !== null && current.ref !== ref) {\n    // Schedule a Ref effect\n    workInProgress.effectTag |= Ref;\n  }\n}\n\nfunction updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {\n  {\n    if (workInProgress.type !== workInProgress.elementType) {\n      // Lazy component props can't be validated in createElement\n      // because they're only guaranteed to be resolved here.\n      var innerPropTypes = Component.propTypes;\n\n      if (innerPropTypes) {\n        checkPropTypes(innerPropTypes, nextProps, // Resolved props\n        'prop', getComponentName(Component), getCurrentFiberStackInDev);\n      }\n    }\n  }\n\n  var context;\n\n  {\n    var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);\n    context = getMaskedContext(workInProgress, unmaskedContext);\n  }\n\n  var nextChildren;\n  prepareToReadContext(workInProgress, renderExpirationTime);\n\n  {\n    ReactCurrentOwner$1.current = workInProgress;\n    setIsRendering(true);\n    nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);\n\n    if ( workInProgress.mode & StrictMode) {\n      // Only double-render components with Hooks\n      if (workInProgress.memoizedState !== null) {\n        nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);\n      }\n    }\n\n    setIsRendering(false);\n  }\n\n  if (current !== null && !didReceiveUpdate) {\n    bailoutHooks(current, workInProgress, renderExpirationTime);\n    return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {\n  {\n    if (workInProgress.type !== workInProgress.elementType) {\n      // Lazy component props can't be validated in createElement\n      // because they're only guaranteed to be resolved here.\n      var innerPropTypes = Component.propTypes;\n\n      if (innerPropTypes) {\n        checkPropTypes(innerPropTypes, nextProps, // Resolved props\n        'prop', getComponentName(Component), getCurrentFiberStackInDev);\n      }\n    }\n  } // Push context providers early to prevent context stack mismatches.\n  // During mounting we don't know the child context yet as the instance doesn't exist.\n  // We will invalidate the child context in finishClassComponent() right after rendering.\n\n\n  var hasContext;\n\n  if (isContextProvider(Component)) {\n    hasContext = true;\n    pushContextProvider(workInProgress);\n  } else {\n    hasContext = false;\n  }\n\n  prepareToReadContext(workInProgress, renderExpirationTime);\n  var instance = workInProgress.stateNode;\n  var shouldUpdate;\n\n  if (instance === null) {\n    if (current !== null) {\n      // A class component without an instance only mounts if it suspended\n      // inside a non-concurrent tree, in an inconsistent state. We want to\n      // treat it like a new mount, even though an empty version of it already\n      // committed. Disconnect the alternate pointers.\n      current.alternate = null;\n      workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect\n\n      workInProgress.effectTag |= Placement;\n    } // In the initial pass we might need to construct the instance.\n\n\n    constructClassInstance(workInProgress, Component, nextProps);\n    mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);\n    shouldUpdate = true;\n  } else if (current === null) {\n    // In a resume, we'll already have an instance we can reuse.\n    shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);\n  } else {\n    shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);\n  }\n\n  var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);\n\n  {\n    var inst = workInProgress.stateNode;\n\n    if (inst.props !== nextProps) {\n      if (!didWarnAboutReassigningProps) {\n        error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');\n      }\n\n      didWarnAboutReassigningProps = true;\n    }\n  }\n\n  return nextUnitOfWork;\n}\n\nfunction finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {\n  // Refs should update even if shouldComponentUpdate returns false\n  markRef(current, workInProgress);\n  var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;\n\n  if (!shouldUpdate && !didCaptureError) {\n    // Context providers should defer to sCU for rendering\n    if (hasContext) {\n      invalidateContextProvider(workInProgress, Component, false);\n    }\n\n    return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n  }\n\n  var instance = workInProgress.stateNode; // Rerender\n\n  ReactCurrentOwner$1.current = workInProgress;\n  var nextChildren;\n\n  if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {\n    // If we captured an error, but getDerivedStateFromError is not defined,\n    // unmount all the children. componentDidCatch will schedule an update to\n    // re-render a fallback. This is temporary until we migrate everyone to\n    // the new API.\n    // TODO: Warn in a future release.\n    nextChildren = null;\n\n    {\n      stopProfilerTimerIfRunning();\n    }\n  } else {\n    {\n      setIsRendering(true);\n      nextChildren = instance.render();\n\n      if ( workInProgress.mode & StrictMode) {\n        instance.render();\n      }\n\n      setIsRendering(false);\n    }\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n\n  if (current !== null && didCaptureError) {\n    // If we're recovering from an error, reconcile without reusing any of\n    // the existing children. Conceptually, the normal children and the children\n    // that are shown on error are two different sets, so we shouldn't reuse\n    // normal children even if their identities match.\n    forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);\n  } else {\n    reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  } // Memoize state using the values we just used to render.\n  // TODO: Restructure so we never read values from the instance.\n\n\n  workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.\n\n  if (hasContext) {\n    invalidateContextProvider(workInProgress, Component, true);\n  }\n\n  return workInProgress.child;\n}\n\nfunction pushHostRootContext(workInProgress) {\n  var root = workInProgress.stateNode;\n\n  if (root.pendingContext) {\n    pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);\n  } else if (root.context) {\n    // Should always be set\n    pushTopLevelContextObject(workInProgress, root.context, false);\n  }\n\n  pushHostContainer(workInProgress, root.containerInfo);\n}\n\nfunction updateHostRoot(current, workInProgress, renderExpirationTime) {\n  pushHostRootContext(workInProgress);\n  var updateQueue = workInProgress.updateQueue;\n\n  if (!(current !== null && updateQueue !== null)) {\n    {\n      throw Error( \"If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n\n  var nextProps = workInProgress.pendingProps;\n  var prevState = workInProgress.memoizedState;\n  var prevChildren = prevState !== null ? prevState.element : null;\n  cloneUpdateQueue(current, workInProgress);\n  processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);\n  var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property\n  // being called \"element\".\n\n  var nextChildren = nextState.element;\n\n  if (nextChildren === prevChildren) {\n    // If the state is the same as before, that's a bailout because we had\n    // no work that expires at this time.\n    resetHydrationState();\n    return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n  }\n\n  var root = workInProgress.stateNode;\n\n  if (root.hydrate && enterHydrationState(workInProgress)) {\n    // If we don't have any current children this might be the first pass.\n    // We always try to hydrate. If this isn't a hydration pass there won't\n    // be any children to hydrate which is effectively the same thing as\n    // not hydrating.\n    var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);\n    workInProgress.child = child;\n    var node = child;\n\n    while (node) {\n      // Mark each child as hydrating. This is a fast path to know whether this\n      // tree is part of a hydrating tree. This is used to determine if a child\n      // node has fully mounted yet, and for scheduling event replaying.\n      // Conceptually this is similar to Placement in that a new subtree is\n      // inserted into the React tree here. It just happens to not need DOM\n      // mutations because it already exists.\n      node.effectTag = node.effectTag & ~Placement | Hydrating;\n      node = node.sibling;\n    }\n  } else {\n    // Otherwise reset hydration state in case we aborted and resumed another\n    // root.\n    reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n    resetHydrationState();\n  }\n\n  return workInProgress.child;\n}\n\nfunction updateHostComponent(current, workInProgress, renderExpirationTime) {\n  pushHostContext(workInProgress);\n\n  if (current === null) {\n    tryToClaimNextHydratableInstance(workInProgress);\n  }\n\n  var type = workInProgress.type;\n  var nextProps = workInProgress.pendingProps;\n  var prevProps = current !== null ? current.memoizedProps : null;\n  var nextChildren = nextProps.children;\n  var isDirectTextChild = shouldSetTextContent(type, nextProps);\n\n  if (isDirectTextChild) {\n    // We special case a direct text child of a host node. This is a common\n    // case. We won't handle it as a reified child. We will instead handle\n    // this in the host environment that also has access to this prop. That\n    // avoids allocating another HostText fiber and traversing it.\n    nextChildren = null;\n  } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {\n    // If we're switching from a direct text child to a normal child, or to\n    // empty, we need to schedule the text content to be reset.\n    workInProgress.effectTag |= ContentReset;\n  }\n\n  markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.\n\n  if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {\n    {\n      markSpawnedWork(Never);\n    } // Schedule this fiber to re-render at offscreen priority. Then bailout.\n\n\n    workInProgress.expirationTime = workInProgress.childExpirationTime = Never;\n    return null;\n  }\n\n  reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction updateHostText(current, workInProgress) {\n  if (current === null) {\n    tryToClaimNextHydratableInstance(workInProgress);\n  } // Nothing to do here. This is terminal. We'll do the completion step\n  // immediately after.\n\n\n  return null;\n}\n\nfunction mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {\n  if (_current !== null) {\n    // A lazy component only mounts if it suspended inside a non-\n    // concurrent tree, in an inconsistent state. We want to treat it like\n    // a new mount, even though an empty version of it already committed.\n    // Disconnect the alternate pointers.\n    _current.alternate = null;\n    workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect\n\n    workInProgress.effectTag |= Placement;\n  }\n\n  var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.\n  // Cancel and resume right after we know the tag.\n\n  cancelWorkTimer(workInProgress);\n  var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.\n\n  workInProgress.type = Component;\n  var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);\n  startWorkTimer(workInProgress);\n  var resolvedProps = resolveDefaultProps(Component, props);\n  var child;\n\n  switch (resolvedTag) {\n    case FunctionComponent:\n      {\n        {\n          validateFunctionComponentInDev(workInProgress, Component);\n          workInProgress.type = Component = resolveFunctionForHotReloading(Component);\n        }\n\n        child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);\n        return child;\n      }\n\n    case ClassComponent:\n      {\n        {\n          workInProgress.type = Component = resolveClassForHotReloading(Component);\n        }\n\n        child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);\n        return child;\n      }\n\n    case ForwardRef:\n      {\n        {\n          workInProgress.type = Component = resolveForwardRefForHotReloading(Component);\n        }\n\n        child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);\n        return child;\n      }\n\n    case MemoComponent:\n      {\n        {\n          if (workInProgress.type !== workInProgress.elementType) {\n            var outerPropTypes = Component.propTypes;\n\n            if (outerPropTypes) {\n              checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only\n              'prop', getComponentName(Component), getCurrentFiberStackInDev);\n            }\n          }\n        }\n\n        child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too\n        updateExpirationTime, renderExpirationTime);\n        return child;\n      }\n  }\n\n  var hint = '';\n\n  {\n    if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {\n      hint = ' Did you wrap a component in React.lazy() more than once?';\n    }\n  } // This message intentionally doesn't mention ForwardRef or MemoComponent\n  // because the fact that it's a separate type of work is an\n  // implementation detail.\n\n\n  {\n    {\n      throw Error( \"Element type is invalid. Received a promise that resolves to: \" + Component + \". Lazy element type must resolve to a class or function.\" + hint );\n    }\n  }\n}\n\nfunction mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {\n  if (_current !== null) {\n    // An incomplete component only mounts if it suspended inside a non-\n    // concurrent tree, in an inconsistent state. We want to treat it like\n    // a new mount, even though an empty version of it already committed.\n    // Disconnect the alternate pointers.\n    _current.alternate = null;\n    workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect\n\n    workInProgress.effectTag |= Placement;\n  } // Promote the fiber to a class and try rendering again.\n\n\n  workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`\n  // Push context providers early to prevent context stack mismatches.\n  // During mounting we don't know the child context yet as the instance doesn't exist.\n  // We will invalidate the child context in finishClassComponent() right after rendering.\n\n  var hasContext;\n\n  if (isContextProvider(Component)) {\n    hasContext = true;\n    pushContextProvider(workInProgress);\n  } else {\n    hasContext = false;\n  }\n\n  prepareToReadContext(workInProgress, renderExpirationTime);\n  constructClassInstance(workInProgress, Component, nextProps);\n  mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);\n  return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);\n}\n\nfunction mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {\n  if (_current !== null) {\n    // An indeterminate component only mounts if it suspended inside a non-\n    // concurrent tree, in an inconsistent state. We want to treat it like\n    // a new mount, even though an empty version of it already committed.\n    // Disconnect the alternate pointers.\n    _current.alternate = null;\n    workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect\n\n    workInProgress.effectTag |= Placement;\n  }\n\n  var props = workInProgress.pendingProps;\n  var context;\n\n  {\n    var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);\n    context = getMaskedContext(workInProgress, unmaskedContext);\n  }\n\n  prepareToReadContext(workInProgress, renderExpirationTime);\n  var value;\n\n  {\n    if (Component.prototype && typeof Component.prototype.render === 'function') {\n      var componentName = getComponentName(Component) || 'Unknown';\n\n      if (!didWarnAboutBadClass[componentName]) {\n        error(\"The <%s /> component appears to have a render method, but doesn't extend React.Component. \" + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);\n\n        didWarnAboutBadClass[componentName] = true;\n      }\n    }\n\n    if (workInProgress.mode & StrictMode) {\n      ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);\n    }\n\n    setIsRendering(true);\n    ReactCurrentOwner$1.current = workInProgress;\n    value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);\n    setIsRendering(false);\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n\n  if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {\n    {\n      var _componentName = getComponentName(Component) || 'Unknown';\n\n      if (!didWarnAboutModulePatternComponent[_componentName]) {\n        error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + \"If you can't use a class try assigning the prototype on the function as a workaround. \" + \"`%s.prototype = React.Component.prototype`. Don't use an arrow function since it \" + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);\n\n        didWarnAboutModulePatternComponent[_componentName] = true;\n      }\n    } // Proceed under the assumption that this is a class instance\n\n\n    workInProgress.tag = ClassComponent; // Throw out any hooks that were used.\n\n    workInProgress.memoizedState = null;\n    workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.\n    // During mounting we don't know the child context yet as the instance doesn't exist.\n    // We will invalidate the child context in finishClassComponent() right after rendering.\n\n    var hasContext = false;\n\n    if (isContextProvider(Component)) {\n      hasContext = true;\n      pushContextProvider(workInProgress);\n    } else {\n      hasContext = false;\n    }\n\n    workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;\n    initializeUpdateQueue(workInProgress);\n    var getDerivedStateFromProps = Component.getDerivedStateFromProps;\n\n    if (typeof getDerivedStateFromProps === 'function') {\n      applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);\n    }\n\n    adoptClassInstance(workInProgress, value);\n    mountClassInstance(workInProgress, Component, props, renderExpirationTime);\n    return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);\n  } else {\n    // Proceed under the assumption that this is a function component\n    workInProgress.tag = FunctionComponent;\n\n    {\n\n      if ( workInProgress.mode & StrictMode) {\n        // Only double-render components with Hooks\n        if (workInProgress.memoizedState !== null) {\n          value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);\n        }\n      }\n    }\n\n    reconcileChildren(null, workInProgress, value, renderExpirationTime);\n\n    {\n      validateFunctionComponentInDev(workInProgress, Component);\n    }\n\n    return workInProgress.child;\n  }\n}\n\nfunction validateFunctionComponentInDev(workInProgress, Component) {\n  {\n    if (Component) {\n      if (Component.childContextTypes) {\n        error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');\n      }\n    }\n\n    if (workInProgress.ref !== null) {\n      var info = '';\n      var ownerName = getCurrentFiberOwnerNameInDevOrNull();\n\n      if (ownerName) {\n        info += '\\n\\nCheck the render method of `' + ownerName + '`.';\n      }\n\n      var warningKey = ownerName || workInProgress._debugID || '';\n      var debugSource = workInProgress._debugSource;\n\n      if (debugSource) {\n        warningKey = debugSource.fileName + ':' + debugSource.lineNumber;\n      }\n\n      if (!didWarnAboutFunctionRefs[warningKey]) {\n        didWarnAboutFunctionRefs[warningKey] = true;\n\n        error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);\n      }\n    }\n\n    if (typeof Component.getDerivedStateFromProps === 'function') {\n      var _componentName2 = getComponentName(Component) || 'Unknown';\n\n      if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {\n        error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);\n\n        didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;\n      }\n    }\n\n    if (typeof Component.contextType === 'object' && Component.contextType !== null) {\n      var _componentName3 = getComponentName(Component) || 'Unknown';\n\n      if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {\n        error('%s: Function components do not support contextType.', _componentName3);\n\n        didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;\n      }\n    }\n  }\n}\n\nvar SUSPENDED_MARKER = {\n  dehydrated: null,\n  retryTime: NoWork\n};\n\nfunction shouldRemainOnFallback(suspenseContext, current, workInProgress) {\n  // If the context is telling us that we should show a fallback, and we're not\n  // already showing content, then we should show the fallback instead.\n  return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);\n}\n\nfunction updateSuspenseComponent(current, workInProgress, renderExpirationTime) {\n  var mode = workInProgress.mode;\n  var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.\n\n  {\n    if (shouldSuspend(workInProgress)) {\n      workInProgress.effectTag |= DidCapture;\n    }\n  }\n\n  var suspenseContext = suspenseStackCursor.current;\n  var nextDidTimeout = false;\n  var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;\n\n  if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {\n    // Something in this boundary's subtree already suspended. Switch to\n    // rendering the fallback children.\n    nextDidTimeout = true;\n    workInProgress.effectTag &= ~DidCapture;\n  } else {\n    // Attempting the main content\n    if (current === null || current.memoizedState !== null) {\n      // This is a new mount or this boundary is already showing a fallback state.\n      // Mark this subtree context as having at least one invisible parent that could\n      // handle the fallback state.\n      // Boundaries without fallbacks or should be avoided are not considered since\n      // they cannot handle preferred fallback states.\n      if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {\n        suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);\n      }\n    }\n  }\n\n  suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);\n  pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to\n  // showing the fallback children in place of the \"primary\" children.\n  // However, we don't want to delete the primary children because then their\n  // state will be lost (both the React state and the host state, e.g.\n  // uncontrolled form inputs). Instead we keep them mounted and hide them.\n  // Both the fallback children AND the primary children are rendered at the\n  // same time. Once the primary children are un-suspended, we can delete\n  // the fallback children — don't need to preserve their state.\n  //\n  // The two sets of children are siblings in the host environment, but\n  // semantically, for purposes of reconciliation, they are two separate sets.\n  // So we store them using two fragment fibers.\n  //\n  // However, we want to avoid allocating extra fibers for every placeholder.\n  // They're only necessary when the children time out, because that's the\n  // only time when both sets are mounted.\n  //\n  // So, the extra fragment fibers are only used if the children time out.\n  // Otherwise, we render the primary children directly. This requires some\n  // custom reconciliation logic to preserve the state of the primary\n  // children. It's essentially a very basic form of re-parenting.\n\n  if (current === null) {\n    // If we're currently hydrating, try to hydrate this boundary.\n    // But only if this has a fallback.\n    if (nextProps.fallback !== undefined) {\n      tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.\n    } // This is the initial mount. This branch is pretty simple because there's\n    // no previous state that needs to be preserved.\n\n\n    if (nextDidTimeout) {\n      // Mount separate fragments for primary and fallback children.\n      var nextFallbackChildren = nextProps.fallback;\n      var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);\n      primaryChildFragment.return = workInProgress;\n\n      if ((workInProgress.mode & BlockingMode) === NoMode) {\n        // Outside of blocking mode, we commit the effects from the\n        // partially completed, timed-out tree, too.\n        var progressedState = workInProgress.memoizedState;\n        var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;\n        primaryChildFragment.child = progressedPrimaryChild;\n        var progressedChild = progressedPrimaryChild;\n\n        while (progressedChild !== null) {\n          progressedChild.return = primaryChildFragment;\n          progressedChild = progressedChild.sibling;\n        }\n      }\n\n      var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);\n      fallbackChildFragment.return = workInProgress;\n      primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the\n      // fallback children.\n\n      workInProgress.memoizedState = SUSPENDED_MARKER;\n      workInProgress.child = primaryChildFragment;\n      return fallbackChildFragment;\n    } else {\n      // Mount the primary children without an intermediate fragment fiber.\n      var nextPrimaryChildren = nextProps.children;\n      workInProgress.memoizedState = null;\n      return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);\n    }\n  } else {\n    // This is an update. This branch is more complicated because we need to\n    // ensure the state of the primary children is preserved.\n    var prevState = current.memoizedState;\n\n    if (prevState !== null) {\n      // wrapped in a fragment fiber.\n\n\n      var currentPrimaryChildFragment = current.child;\n      var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;\n\n      if (nextDidTimeout) {\n        // Still timed out. Reuse the current primary children by cloning\n        // its fragment. We're going to skip over these entirely.\n        var _nextFallbackChildren2 = nextProps.fallback;\n\n        var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);\n\n        _primaryChildFragment2.return = workInProgress;\n\n        if ((workInProgress.mode & BlockingMode) === NoMode) {\n          // Outside of blocking mode, we commit the effects from the\n          // partially completed, timed-out tree, too.\n          var _progressedState = workInProgress.memoizedState;\n\n          var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;\n\n          if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {\n            _primaryChildFragment2.child = _progressedPrimaryChild;\n            var _progressedChild2 = _progressedPrimaryChild;\n\n            while (_progressedChild2 !== null) {\n              _progressedChild2.return = _primaryChildFragment2;\n              _progressedChild2 = _progressedChild2.sibling;\n            }\n          }\n        } // Because primaryChildFragment is a new fiber that we're inserting as the\n        // parent of a new tree, we need to set its treeBaseDuration.\n\n\n        if ( workInProgress.mode & ProfileMode) {\n          // treeBaseDuration is the sum of all the child tree base durations.\n          var _treeBaseDuration = 0;\n          var _hiddenChild = _primaryChildFragment2.child;\n\n          while (_hiddenChild !== null) {\n            _treeBaseDuration += _hiddenChild.treeBaseDuration;\n            _hiddenChild = _hiddenChild.sibling;\n          }\n\n          _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;\n        } // Clone the fallback child fragment, too. These we'll continue\n        // working on.\n\n\n        var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);\n\n        _fallbackChildFragment2.return = workInProgress;\n        _primaryChildFragment2.sibling = _fallbackChildFragment2;\n        _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the\n        // fallback children.\n\n        workInProgress.memoizedState = SUSPENDED_MARKER;\n        workInProgress.child = _primaryChildFragment2;\n        return _fallbackChildFragment2;\n      } else {\n        // No longer suspended. Switch back to showing the primary children,\n        // and remove the intermediate fragment fiber.\n        var _nextPrimaryChildren = nextProps.children;\n        var currentPrimaryChild = currentPrimaryChildFragment.child;\n        var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback\n        // children. Wait until the complete phase, after we've confirmed the\n        // fallback is no longer needed.\n        // TODO: Would it be better to store the fallback fragment on\n        // the stateNode?\n        // Continue rendering the children, like we normally do.\n\n        workInProgress.memoizedState = null;\n        return workInProgress.child = primaryChild;\n      }\n    } else {\n      // The current tree has not already timed out. That means the primary\n      // children are not wrapped in a fragment fiber.\n      var _currentPrimaryChild = current.child;\n\n      if (nextDidTimeout) {\n        // Timed out. Wrap the children in a fragment fiber to keep them\n        // separate from the fallback children.\n        var _nextFallbackChildren3 = nextProps.fallback;\n\n        var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't\n        // going to render this fragment.\n        null, mode, NoWork, null);\n\n        _primaryChildFragment3.return = workInProgress;\n        _primaryChildFragment3.child = _currentPrimaryChild;\n\n        if (_currentPrimaryChild !== null) {\n          _currentPrimaryChild.return = _primaryChildFragment3;\n        } // Even though we're creating a new fiber, there are no new children,\n        // because we're reusing an already mounted tree. So we don't need to\n        // schedule a placement.\n        // primaryChildFragment.effectTag |= Placement;\n\n\n        if ((workInProgress.mode & BlockingMode) === NoMode) {\n          // Outside of blocking mode, we commit the effects from the\n          // partially completed, timed-out tree, too.\n          var _progressedState2 = workInProgress.memoizedState;\n\n          var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;\n\n          _primaryChildFragment3.child = _progressedPrimaryChild2;\n          var _progressedChild3 = _progressedPrimaryChild2;\n\n          while (_progressedChild3 !== null) {\n            _progressedChild3.return = _primaryChildFragment3;\n            _progressedChild3 = _progressedChild3.sibling;\n          }\n        } // Because primaryChildFragment is a new fiber that we're inserting as the\n        // parent of a new tree, we need to set its treeBaseDuration.\n\n\n        if ( workInProgress.mode & ProfileMode) {\n          // treeBaseDuration is the sum of all the child tree base durations.\n          var _treeBaseDuration2 = 0;\n          var _hiddenChild2 = _primaryChildFragment3.child;\n\n          while (_hiddenChild2 !== null) {\n            _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;\n            _hiddenChild2 = _hiddenChild2.sibling;\n          }\n\n          _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;\n        } // Create a fragment from the fallback children, too.\n\n\n        var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);\n\n        _fallbackChildFragment3.return = workInProgress;\n        _primaryChildFragment3.sibling = _fallbackChildFragment3;\n        _fallbackChildFragment3.effectTag |= Placement;\n        _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the\n        // fallback children.\n\n        workInProgress.memoizedState = SUSPENDED_MARKER;\n        workInProgress.child = _primaryChildFragment3;\n        return _fallbackChildFragment3;\n      } else {\n        // Still haven't timed out. Continue rendering the children, like we\n        // normally do.\n        workInProgress.memoizedState = null;\n        var _nextPrimaryChildren2 = nextProps.children;\n        return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);\n      }\n    }\n  }\n}\n\nfunction scheduleWorkOnFiber(fiber, renderExpirationTime) {\n  if (fiber.expirationTime < renderExpirationTime) {\n    fiber.expirationTime = renderExpirationTime;\n  }\n\n  var alternate = fiber.alternate;\n\n  if (alternate !== null && alternate.expirationTime < renderExpirationTime) {\n    alternate.expirationTime = renderExpirationTime;\n  }\n\n  scheduleWorkOnParentPath(fiber.return, renderExpirationTime);\n}\n\nfunction propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {\n  // Mark any Suspense boundaries with fallbacks as having work to do.\n  // If they were previously forced into fallbacks, they may now be able\n  // to unblock.\n  var node = firstChild;\n\n  while (node !== null) {\n    if (node.tag === SuspenseComponent) {\n      var state = node.memoizedState;\n\n      if (state !== null) {\n        scheduleWorkOnFiber(node, renderExpirationTime);\n      }\n    } else if (node.tag === SuspenseListComponent) {\n      // If the tail is hidden there might not be an Suspense boundaries\n      // to schedule work on. In this case we have to schedule it on the\n      // list itself.\n      // We don't have to traverse to the children of the list since\n      // the list will propagate the change when it rerenders.\n      scheduleWorkOnFiber(node, renderExpirationTime);\n    } else if (node.child !== null) {\n      node.child.return = node;\n      node = node.child;\n      continue;\n    }\n\n    if (node === workInProgress) {\n      return;\n    }\n\n    while (node.sibling === null) {\n      if (node.return === null || node.return === workInProgress) {\n        return;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  }\n}\n\nfunction findLastContentRow(firstChild) {\n  // This is going to find the last row among these children that is already\n  // showing content on the screen, as opposed to being in fallback state or\n  // new. If a row has multiple Suspense boundaries, any of them being in the\n  // fallback state, counts as the whole row being in a fallback state.\n  // Note that the \"rows\" will be workInProgress, but any nested children\n  // will still be current since we haven't rendered them yet. The mounted\n  // order may not be the same as the new order. We use the new order.\n  var row = firstChild;\n  var lastContentRow = null;\n\n  while (row !== null) {\n    var currentRow = row.alternate; // New rows can't be content rows.\n\n    if (currentRow !== null && findFirstSuspended(currentRow) === null) {\n      lastContentRow = row;\n    }\n\n    row = row.sibling;\n  }\n\n  return lastContentRow;\n}\n\nfunction validateRevealOrder(revealOrder) {\n  {\n    if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {\n      didWarnAboutRevealOrder[revealOrder] = true;\n\n      if (typeof revealOrder === 'string') {\n        switch (revealOrder.toLowerCase()) {\n          case 'together':\n          case 'forwards':\n          case 'backwards':\n            {\n              error('\"%s\" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase \"%s\" instead.', revealOrder, revealOrder.toLowerCase());\n\n              break;\n            }\n\n          case 'forward':\n          case 'backward':\n            {\n              error('\"%s\" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use \"%ss\" instead.', revealOrder, revealOrder.toLowerCase());\n\n              break;\n            }\n\n          default:\n            error('\"%s\" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean \"together\", \"forwards\" or \"backwards\"?', revealOrder);\n\n            break;\n        }\n      } else {\n        error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean \"together\", \"forwards\" or \"backwards\"?', revealOrder);\n      }\n    }\n  }\n}\n\nfunction validateTailOptions(tailMode, revealOrder) {\n  {\n    if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {\n      if (tailMode !== 'collapsed' && tailMode !== 'hidden') {\n        didWarnAboutTailOptions[tailMode] = true;\n\n        error('\"%s\" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean \"collapsed\" or \"hidden\"?', tailMode);\n      } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {\n        didWarnAboutTailOptions[tailMode] = true;\n\n        error('<SuspenseList tail=\"%s\" /> is only valid if revealOrder is ' + '\"forwards\" or \"backwards\". ' + 'Did you mean to specify revealOrder=\"forwards\"?', tailMode);\n      }\n    }\n  }\n}\n\nfunction validateSuspenseListNestedChild(childSlot, index) {\n  {\n    var isArray = Array.isArray(childSlot);\n    var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';\n\n    if (isArray || isIterable) {\n      var type = isArray ? 'array' : 'iterable';\n\n      error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);\n\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction validateSuspenseListChildren(children, revealOrder) {\n  {\n    if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {\n      if (Array.isArray(children)) {\n        for (var i = 0; i < children.length; i++) {\n          if (!validateSuspenseListNestedChild(children[i], i)) {\n            return;\n          }\n        }\n      } else {\n        var iteratorFn = getIteratorFn(children);\n\n        if (typeof iteratorFn === 'function') {\n          var childrenIterator = iteratorFn.call(children);\n\n          if (childrenIterator) {\n            var step = childrenIterator.next();\n            var _i = 0;\n\n            for (; !step.done; step = childrenIterator.next()) {\n              if (!validateSuspenseListNestedChild(step.value, _i)) {\n                return;\n              }\n\n              _i++;\n            }\n          }\n        } else {\n          error('A single row was passed to a <SuspenseList revealOrder=\"%s\" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);\n        }\n      }\n    }\n  }\n}\n\nfunction initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {\n  var renderState = workInProgress.memoizedState;\n\n  if (renderState === null) {\n    workInProgress.memoizedState = {\n      isBackwards: isBackwards,\n      rendering: null,\n      renderingStartTime: 0,\n      last: lastContentRow,\n      tail: tail,\n      tailExpiration: 0,\n      tailMode: tailMode,\n      lastEffect: lastEffectBeforeRendering\n    };\n  } else {\n    // We can reuse the existing object from previous renders.\n    renderState.isBackwards = isBackwards;\n    renderState.rendering = null;\n    renderState.renderingStartTime = 0;\n    renderState.last = lastContentRow;\n    renderState.tail = tail;\n    renderState.tailExpiration = 0;\n    renderState.tailMode = tailMode;\n    renderState.lastEffect = lastEffectBeforeRendering;\n  }\n} // This can end up rendering this component multiple passes.\n// The first pass splits the children fibers into two sets. A head and tail.\n// We first render the head. If anything is in fallback state, we do another\n// pass through beginWork to rerender all children (including the tail) with\n// the force suspend context. If the first render didn't have anything in\n// in fallback state. Then we render each row in the tail one-by-one.\n// That happens in the completeWork phase without going back to beginWork.\n\n\nfunction updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {\n  var nextProps = workInProgress.pendingProps;\n  var revealOrder = nextProps.revealOrder;\n  var tailMode = nextProps.tail;\n  var newChildren = nextProps.children;\n  validateRevealOrder(revealOrder);\n  validateTailOptions(tailMode, revealOrder);\n  validateSuspenseListChildren(newChildren, revealOrder);\n  reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);\n  var suspenseContext = suspenseStackCursor.current;\n  var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);\n\n  if (shouldForceFallback) {\n    suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);\n    workInProgress.effectTag |= DidCapture;\n  } else {\n    var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;\n\n    if (didSuspendBefore) {\n      // If we previously forced a fallback, we need to schedule work\n      // on any nested boundaries to let them know to try to render\n      // again. This is the same as context updating.\n      propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);\n    }\n\n    suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);\n  }\n\n  pushSuspenseContext(workInProgress, suspenseContext);\n\n  if ((workInProgress.mode & BlockingMode) === NoMode) {\n    // Outside of blocking mode, SuspenseList doesn't work so we just\n    // use make it a noop by treating it as the default revealOrder.\n    workInProgress.memoizedState = null;\n  } else {\n    switch (revealOrder) {\n      case 'forwards':\n        {\n          var lastContentRow = findLastContentRow(workInProgress.child);\n          var tail;\n\n          if (lastContentRow === null) {\n            // The whole list is part of the tail.\n            // TODO: We could fast path by just rendering the tail now.\n            tail = workInProgress.child;\n            workInProgress.child = null;\n          } else {\n            // Disconnect the tail rows after the content row.\n            // We're going to render them separately later.\n            tail = lastContentRow.sibling;\n            lastContentRow.sibling = null;\n          }\n\n          initSuspenseListRenderState(workInProgress, false, // isBackwards\n          tail, lastContentRow, tailMode, workInProgress.lastEffect);\n          break;\n        }\n\n      case 'backwards':\n        {\n          // We're going to find the first row that has existing content.\n          // At the same time we're going to reverse the list of everything\n          // we pass in the meantime. That's going to be our tail in reverse\n          // order.\n          var _tail = null;\n          var row = workInProgress.child;\n          workInProgress.child = null;\n\n          while (row !== null) {\n            var currentRow = row.alternate; // New rows can't be content rows.\n\n            if (currentRow !== null && findFirstSuspended(currentRow) === null) {\n              // This is the beginning of the main content.\n              workInProgress.child = row;\n              break;\n            }\n\n            var nextRow = row.sibling;\n            row.sibling = _tail;\n            _tail = row;\n            row = nextRow;\n          } // TODO: If workInProgress.child is null, we can continue on the tail immediately.\n\n\n          initSuspenseListRenderState(workInProgress, true, // isBackwards\n          _tail, null, // last\n          tailMode, workInProgress.lastEffect);\n          break;\n        }\n\n      case 'together':\n        {\n          initSuspenseListRenderState(workInProgress, false, // isBackwards\n          null, // tail\n          null, // last\n          undefined, workInProgress.lastEffect);\n          break;\n        }\n\n      default:\n        {\n          // The default reveal order is the same as not having\n          // a boundary.\n          workInProgress.memoizedState = null;\n        }\n    }\n  }\n\n  return workInProgress.child;\n}\n\nfunction updatePortalComponent(current, workInProgress, renderExpirationTime) {\n  pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n  var nextChildren = workInProgress.pendingProps;\n\n  if (current === null) {\n    // Portals are special because we don't append the children during mount\n    // but at commit. Therefore we need to track insertions which the normal\n    // flow doesn't do during mount. This doesn't happen at the root because\n    // the root always starts with a \"current\" with a null child.\n    // TODO: Consider unifying this with how the root works.\n    workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);\n  } else {\n    reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);\n  }\n\n  return workInProgress.child;\n}\n\nfunction updateContextProvider(current, workInProgress, renderExpirationTime) {\n  var providerType = workInProgress.type;\n  var context = providerType._context;\n  var newProps = workInProgress.pendingProps;\n  var oldProps = workInProgress.memoizedProps;\n  var newValue = newProps.value;\n\n  {\n    var providerPropTypes = workInProgress.type.propTypes;\n\n    if (providerPropTypes) {\n      checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);\n    }\n  }\n\n  pushProvider(workInProgress, newValue);\n\n  if (oldProps !== null) {\n    var oldValue = oldProps.value;\n    var changedBits = calculateChangedBits(context, newValue, oldValue);\n\n    if (changedBits === 0) {\n      // No change. Bailout early if children are the same.\n      if (oldProps.children === newProps.children && !hasContextChanged()) {\n        return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n      }\n    } else {\n      // The context value changed. Search for matching consumers and schedule\n      // them to update.\n      propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);\n    }\n  }\n\n  var newChildren = newProps.children;\n  reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nvar hasWarnedAboutUsingContextAsConsumer = false;\n\nfunction updateContextConsumer(current, workInProgress, renderExpirationTime) {\n  var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In\n  // DEV mode, we create a separate object for Context.Consumer that acts\n  // like a proxy to Context. This proxy object adds unnecessary code in PROD\n  // so we use the old behaviour (Context.Consumer references Context) to\n  // reduce size and overhead. The separate object references context via\n  // a property called \"_context\", which also gives us the ability to check\n  // in DEV mode if this property exists or not and warn if it does not.\n\n  {\n    if (context._context === undefined) {\n      // This may be because it's a Context (rather than a Consumer).\n      // Or it may be because it's older React where they're the same thing.\n      // We only want to warn if we're sure it's a new React.\n      if (context !== context.Consumer) {\n        if (!hasWarnedAboutUsingContextAsConsumer) {\n          hasWarnedAboutUsingContextAsConsumer = true;\n\n          error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');\n        }\n      }\n    } else {\n      context = context._context;\n    }\n  }\n\n  var newProps = workInProgress.pendingProps;\n  var render = newProps.children;\n\n  {\n    if (typeof render !== 'function') {\n      error('A context consumer was rendered with multiple children, or a child ' + \"that isn't a function. A context consumer expects a single child \" + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');\n    }\n  }\n\n  prepareToReadContext(workInProgress, renderExpirationTime);\n  var newValue = readContext(context, newProps.unstable_observedBits);\n  var newChildren;\n\n  {\n    ReactCurrentOwner$1.current = workInProgress;\n    setIsRendering(true);\n    newChildren = render(newValue);\n    setIsRendering(false);\n  } // React DevTools reads this flag.\n\n\n  workInProgress.effectTag |= PerformedWork;\n  reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);\n  return workInProgress.child;\n}\n\nfunction markWorkInProgressReceivedUpdate() {\n  didReceiveUpdate = true;\n}\n\nfunction bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {\n  cancelWorkTimer(workInProgress);\n\n  if (current !== null) {\n    // Reuse previous dependencies\n    workInProgress.dependencies = current.dependencies;\n  }\n\n  {\n    // Don't update \"base\" render times for bailouts.\n    stopProfilerTimerIfRunning();\n  }\n\n  var updateExpirationTime = workInProgress.expirationTime;\n\n  if (updateExpirationTime !== NoWork) {\n    markUnprocessedUpdateTime(updateExpirationTime);\n  } // Check if the children have any pending work.\n\n\n  var childExpirationTime = workInProgress.childExpirationTime;\n\n  if (childExpirationTime < renderExpirationTime) {\n    // The children don't have any work either. We can skip them.\n    // TODO: Once we add back resuming, we should check if the children are\n    // a work-in-progress set. If so, we need to transfer their effects.\n    return null;\n  } else {\n    // This fiber doesn't have work, but its subtree does. Clone the child\n    // fibers and continue.\n    cloneChildFibers(current, workInProgress);\n    return workInProgress.child;\n  }\n}\n\nfunction remountFiber(current, oldWorkInProgress, newWorkInProgress) {\n  {\n    var returnFiber = oldWorkInProgress.return;\n\n    if (returnFiber === null) {\n      throw new Error('Cannot swap the root fiber.');\n    } // Disconnect from the old current.\n    // It will get deleted.\n\n\n    current.alternate = null;\n    oldWorkInProgress.alternate = null; // Connect to the new tree.\n\n    newWorkInProgress.index = oldWorkInProgress.index;\n    newWorkInProgress.sibling = oldWorkInProgress.sibling;\n    newWorkInProgress.return = oldWorkInProgress.return;\n    newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.\n\n    if (oldWorkInProgress === returnFiber.child) {\n      returnFiber.child = newWorkInProgress;\n    } else {\n      var prevSibling = returnFiber.child;\n\n      if (prevSibling === null) {\n        throw new Error('Expected parent to have a child.');\n      }\n\n      while (prevSibling.sibling !== oldWorkInProgress) {\n        prevSibling = prevSibling.sibling;\n\n        if (prevSibling === null) {\n          throw new Error('Expected to find the previous sibling.');\n        }\n      }\n\n      prevSibling.sibling = newWorkInProgress;\n    } // Delete the old fiber and place the new one.\n    // Since the old fiber is disconnected, we have to schedule it manually.\n\n\n    var last = returnFiber.lastEffect;\n\n    if (last !== null) {\n      last.nextEffect = current;\n      returnFiber.lastEffect = current;\n    } else {\n      returnFiber.firstEffect = returnFiber.lastEffect = current;\n    }\n\n    current.nextEffect = null;\n    current.effectTag = Deletion;\n    newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.\n\n    return newWorkInProgress;\n  }\n}\n\nfunction beginWork(current, workInProgress, renderExpirationTime) {\n  var updateExpirationTime = workInProgress.expirationTime;\n\n  {\n    if (workInProgress._debugNeedsRemount && current !== null) {\n      // This will restart the begin phase with a new fiber.\n      return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));\n    }\n  }\n\n  if (current !== null) {\n    var oldProps = current.memoizedProps;\n    var newProps = workInProgress.pendingProps;\n\n    if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:\n     workInProgress.type !== current.type )) {\n      // If props or context changed, mark the fiber as having performed work.\n      // This may be unset if the props are determined to be equal later (memo).\n      didReceiveUpdate = true;\n    } else if (updateExpirationTime < renderExpirationTime) {\n      didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering\n      // the begin phase. There's still some bookkeeping we that needs to be done\n      // in this optimized path, mostly pushing stuff onto the stack.\n\n      switch (workInProgress.tag) {\n        case HostRoot:\n          pushHostRootContext(workInProgress);\n          resetHydrationState();\n          break;\n\n        case HostComponent:\n          pushHostContext(workInProgress);\n\n          if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {\n            {\n              markSpawnedWork(Never);\n            } // Schedule this fiber to re-render at offscreen priority. Then bailout.\n\n\n            workInProgress.expirationTime = workInProgress.childExpirationTime = Never;\n            return null;\n          }\n\n          break;\n\n        case ClassComponent:\n          {\n            var Component = workInProgress.type;\n\n            if (isContextProvider(Component)) {\n              pushContextProvider(workInProgress);\n            }\n\n            break;\n          }\n\n        case HostPortal:\n          pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n          break;\n\n        case ContextProvider:\n          {\n            var newValue = workInProgress.memoizedProps.value;\n            pushProvider(workInProgress, newValue);\n            break;\n          }\n\n        case Profiler:\n          {\n            // Profiler should only call onRender when one of its descendants actually rendered.\n            var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;\n\n            if (hasChildWork) {\n              workInProgress.effectTag |= Update;\n            }\n          }\n\n          break;\n\n        case SuspenseComponent:\n          {\n            var state = workInProgress.memoizedState;\n\n            if (state !== null) {\n              // whether to retry the primary children, or to skip over it and\n              // go straight to the fallback. Check the priority of the primary\n              // child fragment.\n\n\n              var primaryChildFragment = workInProgress.child;\n              var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;\n\n              if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {\n                // The primary children have pending work. Use the normal path\n                // to attempt to render the primary children again.\n                return updateSuspenseComponent(current, workInProgress, renderExpirationTime);\n              } else {\n                pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient\n                // priority. Bailout.\n\n                var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n\n                if (child !== null) {\n                  // The fallback children have pending work. Skip over the\n                  // primary children and work on the fallback.\n                  return child.sibling;\n                } else {\n                  return null;\n                }\n              }\n            } else {\n              pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));\n            }\n\n            break;\n          }\n\n        case SuspenseListComponent:\n          {\n            var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;\n\n            var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;\n\n            if (didSuspendBefore) {\n              if (_hasChildWork) {\n                // If something was in fallback state last time, and we have all the\n                // same children then we're still in progressive loading state.\n                // Something might get unblocked by state updates or retries in the\n                // tree which will affect the tail. So we need to use the normal\n                // path to compute the correct tail.\n                return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);\n              } // If none of the children had any work, that means that none of\n              // them got retried so they'll still be blocked in the same way\n              // as before. We can fast bail out.\n\n\n              workInProgress.effectTag |= DidCapture;\n            } // If nothing suspended before and we're rendering the same children,\n            // then the tail doesn't matter. Anything new that suspends will work\n            // in the \"together\" mode, so we can continue from the state we had.\n\n\n            var renderState = workInProgress.memoizedState;\n\n            if (renderState !== null) {\n              // Reset to the \"together\" mode in case we've started a different\n              // update in the past but didn't complete it.\n              renderState.rendering = null;\n              renderState.tail = null;\n            }\n\n            pushSuspenseContext(workInProgress, suspenseStackCursor.current);\n\n            if (_hasChildWork) {\n              break;\n            } else {\n              // If none of the children had any work, that means that none of\n              // them got retried so they'll still be blocked in the same way\n              // as before. We can fast bail out.\n              return null;\n            }\n          }\n      }\n\n      return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);\n    } else {\n      // An update was scheduled on this fiber, but there are no new props\n      // nor legacy context. Set this to false. If an update queue or context\n      // consumer produces a changed value, it will set this to true. Otherwise,\n      // the component will assume the children have not changed and bail out.\n      didReceiveUpdate = false;\n    }\n  } else {\n    didReceiveUpdate = false;\n  } // Before entering the begin phase, clear pending update priority.\n  // TODO: This assumes that we're about to evaluate the component and process\n  // the update queue. However, there's an exception: SimpleMemoComponent\n  // sometimes bails out later in the begin phase. This indicates that we should\n  // move this assignment out of the common path and into each branch.\n\n\n  workInProgress.expirationTime = NoWork;\n\n  switch (workInProgress.tag) {\n    case IndeterminateComponent:\n      {\n        return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);\n      }\n\n    case LazyComponent:\n      {\n        var elementType = workInProgress.elementType;\n        return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);\n      }\n\n    case FunctionComponent:\n      {\n        var _Component = workInProgress.type;\n        var unresolvedProps = workInProgress.pendingProps;\n        var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);\n        return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);\n      }\n\n    case ClassComponent:\n      {\n        var _Component2 = workInProgress.type;\n        var _unresolvedProps = workInProgress.pendingProps;\n\n        var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);\n\n        return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);\n      }\n\n    case HostRoot:\n      return updateHostRoot(current, workInProgress, renderExpirationTime);\n\n    case HostComponent:\n      return updateHostComponent(current, workInProgress, renderExpirationTime);\n\n    case HostText:\n      return updateHostText(current, workInProgress);\n\n    case SuspenseComponent:\n      return updateSuspenseComponent(current, workInProgress, renderExpirationTime);\n\n    case HostPortal:\n      return updatePortalComponent(current, workInProgress, renderExpirationTime);\n\n    case ForwardRef:\n      {\n        var type = workInProgress.type;\n        var _unresolvedProps2 = workInProgress.pendingProps;\n\n        var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);\n\n        return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);\n      }\n\n    case Fragment:\n      return updateFragment(current, workInProgress, renderExpirationTime);\n\n    case Mode:\n      return updateMode(current, workInProgress, renderExpirationTime);\n\n    case Profiler:\n      return updateProfiler(current, workInProgress, renderExpirationTime);\n\n    case ContextProvider:\n      return updateContextProvider(current, workInProgress, renderExpirationTime);\n\n    case ContextConsumer:\n      return updateContextConsumer(current, workInProgress, renderExpirationTime);\n\n    case MemoComponent:\n      {\n        var _type2 = workInProgress.type;\n        var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.\n\n        var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);\n\n        {\n          if (workInProgress.type !== workInProgress.elementType) {\n            var outerPropTypes = _type2.propTypes;\n\n            if (outerPropTypes) {\n              checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only\n              'prop', getComponentName(_type2), getCurrentFiberStackInDev);\n            }\n          }\n        }\n\n        _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);\n        return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);\n      }\n\n    case SimpleMemoComponent:\n      {\n        return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);\n      }\n\n    case IncompleteClassComponent:\n      {\n        var _Component3 = workInProgress.type;\n        var _unresolvedProps4 = workInProgress.pendingProps;\n\n        var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);\n\n        return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);\n      }\n\n    case SuspenseListComponent:\n      {\n        return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);\n      }\n  }\n\n  {\n    {\n      throw Error( \"Unknown unit of work tag (\" + workInProgress.tag + \"). This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction markUpdate(workInProgress) {\n  // Tag the fiber with an update effect. This turns a Placement into\n  // a PlacementAndUpdate.\n  workInProgress.effectTag |= Update;\n}\n\nfunction markRef$1(workInProgress) {\n  workInProgress.effectTag |= Ref;\n}\n\nvar appendAllChildren;\nvar updateHostContainer;\nvar updateHostComponent$1;\nvar updateHostText$1;\n\n{\n  // Mutation mode\n  appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {\n    // We only have the top Fiber that was created but we need recurse down its\n    // children to find all the terminal nodes.\n    var node = workInProgress.child;\n\n    while (node !== null) {\n      if (node.tag === HostComponent || node.tag === HostText) {\n        appendInitialChild(parent, node.stateNode);\n      } else if (node.tag === HostPortal) ; else if (node.child !== null) {\n        node.child.return = node;\n        node = node.child;\n        continue;\n      }\n\n      if (node === workInProgress) {\n        return;\n      }\n\n      while (node.sibling === null) {\n        if (node.return === null || node.return === workInProgress) {\n          return;\n        }\n\n        node = node.return;\n      }\n\n      node.sibling.return = node.return;\n      node = node.sibling;\n    }\n  };\n\n  updateHostContainer = function (workInProgress) {// Noop\n  };\n\n  updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {\n    // If we have an alternate, that means this is an update and we need to\n    // schedule a side-effect to do the updates.\n    var oldProps = current.memoizedProps;\n\n    if (oldProps === newProps) {\n      // In mutation mode, this is sufficient for a bailout because\n      // we won't touch this node even if children changed.\n      return;\n    } // If we get updated because one of our children updated, we don't\n    // have newProps so we'll have to reuse them.\n    // TODO: Split the update API as separate for the props vs. children.\n    // Even better would be if children weren't special cased at all tho.\n\n\n    var instance = workInProgress.stateNode;\n    var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host\n    // component is hitting the resume path. Figure out why. Possibly\n    // related to `hidden`.\n\n    var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.\n\n    workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there\n    // is a new ref we mark this as an update. All the work is done in commitWork.\n\n    if (updatePayload) {\n      markUpdate(workInProgress);\n    }\n  };\n\n  updateHostText$1 = function (current, workInProgress, oldText, newText) {\n    // If the text differs, mark it as an update. All the work in done in commitWork.\n    if (oldText !== newText) {\n      markUpdate(workInProgress);\n    }\n  };\n}\n\nfunction cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {\n  switch (renderState.tailMode) {\n    case 'hidden':\n      {\n        // Any insertions at the end of the tail list after this point\n        // should be invisible. If there are already mounted boundaries\n        // anything before them are not considered for collapsing.\n        // Therefore we need to go through the whole tail to find if\n        // there are any.\n        var tailNode = renderState.tail;\n        var lastTailNode = null;\n\n        while (tailNode !== null) {\n          if (tailNode.alternate !== null) {\n            lastTailNode = tailNode;\n          }\n\n          tailNode = tailNode.sibling;\n        } // Next we're simply going to delete all insertions after the\n        // last rendered item.\n\n\n        if (lastTailNode === null) {\n          // All remaining items in the tail are insertions.\n          renderState.tail = null;\n        } else {\n          // Detach the insertion after the last node that was already\n          // inserted.\n          lastTailNode.sibling = null;\n        }\n\n        break;\n      }\n\n    case 'collapsed':\n      {\n        // Any insertions at the end of the tail list after this point\n        // should be invisible. If there are already mounted boundaries\n        // anything before them are not considered for collapsing.\n        // Therefore we need to go through the whole tail to find if\n        // there are any.\n        var _tailNode = renderState.tail;\n        var _lastTailNode = null;\n\n        while (_tailNode !== null) {\n          if (_tailNode.alternate !== null) {\n            _lastTailNode = _tailNode;\n          }\n\n          _tailNode = _tailNode.sibling;\n        } // Next we're simply going to delete all insertions after the\n        // last rendered item.\n\n\n        if (_lastTailNode === null) {\n          // All remaining items in the tail are insertions.\n          if (!hasRenderedATailFallback && renderState.tail !== null) {\n            // We suspended during the head. We want to show at least one\n            // row at the tail. So we'll keep on and cut off the rest.\n            renderState.tail.sibling = null;\n          } else {\n            renderState.tail = null;\n          }\n        } else {\n          // Detach the insertion after the last node that was already\n          // inserted.\n          _lastTailNode.sibling = null;\n        }\n\n        break;\n      }\n  }\n}\n\nfunction completeWork(current, workInProgress, renderExpirationTime) {\n  var newProps = workInProgress.pendingProps;\n\n  switch (workInProgress.tag) {\n    case IndeterminateComponent:\n    case LazyComponent:\n    case SimpleMemoComponent:\n    case FunctionComponent:\n    case ForwardRef:\n    case Fragment:\n    case Mode:\n    case Profiler:\n    case ContextConsumer:\n    case MemoComponent:\n      return null;\n\n    case ClassComponent:\n      {\n        var Component = workInProgress.type;\n\n        if (isContextProvider(Component)) {\n          popContext(workInProgress);\n        }\n\n        return null;\n      }\n\n    case HostRoot:\n      {\n        popHostContainer(workInProgress);\n        popTopLevelContextObject(workInProgress);\n        var fiberRoot = workInProgress.stateNode;\n\n        if (fiberRoot.pendingContext) {\n          fiberRoot.context = fiberRoot.pendingContext;\n          fiberRoot.pendingContext = null;\n        }\n\n        if (current === null || current.child === null) {\n          // If we hydrated, pop so that we can delete any remaining children\n          // that weren't hydrated.\n          var wasHydrated = popHydrationState(workInProgress);\n\n          if (wasHydrated) {\n            // If we hydrated, then we'll need to schedule an update for\n            // the commit side-effects on the root.\n            markUpdate(workInProgress);\n          }\n        }\n\n        updateHostContainer(workInProgress);\n        return null;\n      }\n\n    case HostComponent:\n      {\n        popHostContext(workInProgress);\n        var rootContainerInstance = getRootHostContainer();\n        var type = workInProgress.type;\n\n        if (current !== null && workInProgress.stateNode != null) {\n          updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);\n\n          if (current.ref !== workInProgress.ref) {\n            markRef$1(workInProgress);\n          }\n        } else {\n          if (!newProps) {\n            if (!(workInProgress.stateNode !== null)) {\n              {\n                throw Error( \"We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.\" );\n              }\n            } // This can happen when we abort work.\n\n\n            return null;\n          }\n\n          var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context\n          // \"stack\" as the parent. Then append children as we go in beginWork\n          // or completeWork depending on whether we want to add them top->down or\n          // bottom->up. Top->down is faster in IE11.\n\n          var _wasHydrated = popHydrationState(workInProgress);\n\n          if (_wasHydrated) {\n            // TODO: Move this and createInstance step into the beginPhase\n            // to consolidate.\n            if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {\n              // If changes to the hydrated node need to be applied at the\n              // commit-phase we mark this as such.\n              markUpdate(workInProgress);\n            }\n          } else {\n            var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);\n            appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners\n\n            workInProgress.stateNode = instance;\n            // (eg DOM renderer supports auto-focus for certain elements).\n            // Make sure such renderers get scheduled for later work.\n\n\n            if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {\n              markUpdate(workInProgress);\n            }\n          }\n\n          if (workInProgress.ref !== null) {\n            // If there is a ref on a host node we need to schedule a callback\n            markRef$1(workInProgress);\n          }\n        }\n\n        return null;\n      }\n\n    case HostText:\n      {\n        var newText = newProps;\n\n        if (current && workInProgress.stateNode != null) {\n          var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need\n          // to schedule a side-effect to do the updates.\n\n          updateHostText$1(current, workInProgress, oldText, newText);\n        } else {\n          if (typeof newText !== 'string') {\n            if (!(workInProgress.stateNode !== null)) {\n              {\n                throw Error( \"We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.\" );\n              }\n            } // This can happen when we abort work.\n\n          }\n\n          var _rootContainerInstance = getRootHostContainer();\n\n          var _currentHostContext = getHostContext();\n\n          var _wasHydrated2 = popHydrationState(workInProgress);\n\n          if (_wasHydrated2) {\n            if (prepareToHydrateHostTextInstance(workInProgress)) {\n              markUpdate(workInProgress);\n            }\n          } else {\n            workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);\n          }\n        }\n\n        return null;\n      }\n\n    case SuspenseComponent:\n      {\n        popSuspenseContext(workInProgress);\n        var nextState = workInProgress.memoizedState;\n\n        if ((workInProgress.effectTag & DidCapture) !== NoEffect) {\n          // Something suspended. Re-render with the fallback children.\n          workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.\n\n          return workInProgress;\n        }\n\n        var nextDidTimeout = nextState !== null;\n        var prevDidTimeout = false;\n\n        if (current === null) {\n          if (workInProgress.memoizedProps.fallback !== undefined) {\n            popHydrationState(workInProgress);\n          }\n        } else {\n          var prevState = current.memoizedState;\n          prevDidTimeout = prevState !== null;\n\n          if (!nextDidTimeout && prevState !== null) {\n            // We just switched from the fallback to the normal children.\n            // Delete the fallback.\n            // TODO: Would it be better to store the fallback fragment on\n            // the stateNode during the begin phase?\n            var currentFallbackChild = current.child.sibling;\n\n            if (currentFallbackChild !== null) {\n              // Deletions go at the beginning of the return fiber's effect list\n              var first = workInProgress.firstEffect;\n\n              if (first !== null) {\n                workInProgress.firstEffect = currentFallbackChild;\n                currentFallbackChild.nextEffect = first;\n              } else {\n                workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;\n                currentFallbackChild.nextEffect = null;\n              }\n\n              currentFallbackChild.effectTag = Deletion;\n            }\n          }\n        }\n\n        if (nextDidTimeout && !prevDidTimeout) {\n          // If this subtreee is running in blocking mode we can suspend,\n          // otherwise we won't suspend.\n          // TODO: This will still suspend a synchronous tree if anything\n          // in the concurrent tree already suspended during this render.\n          // This is a known bug.\n          if ((workInProgress.mode & BlockingMode) !== NoMode) {\n            // TODO: Move this back to throwException because this is too late\n            // if this is a large tree which is common for initial loads. We\n            // don't know if we should restart a render or not until we get\n            // this marker, and this is too late.\n            // If this render already had a ping or lower pri updates,\n            // and this is the first time we know we're going to suspend we\n            // should be able to immediately restart from within throwException.\n            var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;\n\n            if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {\n              // If this was in an invisible tree or a new render, then showing\n              // this boundary is ok.\n              renderDidSuspend();\n            } else {\n              // Otherwise, we're going to have to hide content so we should\n              // suspend for longer if possible.\n              renderDidSuspendDelayIfPossible();\n            }\n          }\n        }\n\n        {\n          // TODO: Only schedule updates if these values are non equal, i.e. it changed.\n          if (nextDidTimeout || prevDidTimeout) {\n            // If this boundary just timed out, schedule an effect to attach a\n            // retry listener to the promise. This flag is also used to hide the\n            // primary children. In mutation mode, we also need the flag to\n            // *unhide* children that were previously hidden, so check if this\n            // is currently timed out, too.\n            workInProgress.effectTag |= Update;\n          }\n        }\n\n        return null;\n      }\n\n    case HostPortal:\n      popHostContainer(workInProgress);\n      updateHostContainer(workInProgress);\n      return null;\n\n    case ContextProvider:\n      // Pop provider fiber\n      popProvider(workInProgress);\n      return null;\n\n    case IncompleteClassComponent:\n      {\n        // Same as class component case. I put it down here so that the tags are\n        // sequential to ensure this switch is compiled to a jump table.\n        var _Component = workInProgress.type;\n\n        if (isContextProvider(_Component)) {\n          popContext(workInProgress);\n        }\n\n        return null;\n      }\n\n    case SuspenseListComponent:\n      {\n        popSuspenseContext(workInProgress);\n        var renderState = workInProgress.memoizedState;\n\n        if (renderState === null) {\n          // We're running in the default, \"independent\" mode.\n          // We don't do anything in this mode.\n          return null;\n        }\n\n        var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;\n        var renderedTail = renderState.rendering;\n\n        if (renderedTail === null) {\n          // We just rendered the head.\n          if (!didSuspendAlready) {\n            // This is the first pass. We need to figure out if anything is still\n            // suspended in the rendered set.\n            // If new content unsuspended, but there's still some content that\n            // didn't. Then we need to do a second pass that forces everything\n            // to keep showing their fallbacks.\n            // We might be suspended if something in this render pass suspended, or\n            // something in the previous committed pass suspended. Otherwise,\n            // there's no chance so we can skip the expensive call to\n            // findFirstSuspended.\n            var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);\n\n            if (!cannotBeSuspended) {\n              var row = workInProgress.child;\n\n              while (row !== null) {\n                var suspended = findFirstSuspended(row);\n\n                if (suspended !== null) {\n                  didSuspendAlready = true;\n                  workInProgress.effectTag |= DidCapture;\n                  cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as\n                  // part of the second pass. In that case nothing will subscribe to\n                  // its thennables. Instead, we'll transfer its thennables to the\n                  // SuspenseList so that it can retry if they resolve.\n                  // There might be multiple of these in the list but since we're\n                  // going to wait for all of them anyway, it doesn't really matter\n                  // which ones gets to ping. In theory we could get clever and keep\n                  // track of how many dependencies remain but it gets tricky because\n                  // in the meantime, we can add/remove/change items and dependencies.\n                  // We might bail out of the loop before finding any but that\n                  // doesn't matter since that means that the other boundaries that\n                  // we did find already has their listeners attached.\n\n                  var newThennables = suspended.updateQueue;\n\n                  if (newThennables !== null) {\n                    workInProgress.updateQueue = newThennables;\n                    workInProgress.effectTag |= Update;\n                  } // Rerender the whole list, but this time, we'll force fallbacks\n                  // to stay in place.\n                  // Reset the effect list before doing the second pass since that's now invalid.\n\n\n                  if (renderState.lastEffect === null) {\n                    workInProgress.firstEffect = null;\n                  }\n\n                  workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.\n\n                  resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately\n                  // rerender the children.\n\n                  pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));\n                  return workInProgress.child;\n                }\n\n                row = row.sibling;\n              }\n            }\n          } else {\n            cutOffTailIfNeeded(renderState, false);\n          } // Next we're going to render the tail.\n\n        } else {\n          // Append the rendered row to the child list.\n          if (!didSuspendAlready) {\n            var _suspended = findFirstSuspended(renderedTail);\n\n            if (_suspended !== null) {\n              workInProgress.effectTag |= DidCapture;\n              didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't\n              // get lost if this row ends up dropped during a second pass.\n\n              var _newThennables = _suspended.updateQueue;\n\n              if (_newThennables !== null) {\n                workInProgress.updateQueue = _newThennables;\n                workInProgress.effectTag |= Update;\n              }\n\n              cutOffTailIfNeeded(renderState, true); // This might have been modified.\n\n              if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {\n                // We need to delete the row we just rendered.\n                // Reset the effect list to what it was before we rendered this\n                // child. The nested children have already appended themselves.\n                var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.\n\n                if (lastEffect !== null) {\n                  lastEffect.nextEffect = null;\n                } // We're done.\n\n\n                return null;\n              }\n            } else if ( // The time it took to render last row is greater than time until\n            // the expiration.\n            now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {\n              // We have now passed our CPU deadline and we'll just give up further\n              // attempts to render the main content and only render fallbacks.\n              // The assumption is that this is usually faster.\n              workInProgress.effectTag |= DidCapture;\n              didSuspendAlready = true;\n              cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this\n              // to get it started back up to attempt the next item. If we can show\n              // them, then they really have the same priority as this render.\n              // So we'll pick it back up the very next render pass once we've had\n              // an opportunity to yield for paint.\n\n              var nextPriority = renderExpirationTime - 1;\n              workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;\n\n              {\n                markSpawnedWork(nextPriority);\n              }\n            }\n          }\n\n          if (renderState.isBackwards) {\n            // The effect list of the backwards tail will have been added\n            // to the end. This breaks the guarantee that life-cycles fire in\n            // sibling order but that isn't a strong guarantee promised by React.\n            // Especially since these might also just pop in during future commits.\n            // Append to the beginning of the list.\n            renderedTail.sibling = workInProgress.child;\n            workInProgress.child = renderedTail;\n          } else {\n            var previousSibling = renderState.last;\n\n            if (previousSibling !== null) {\n              previousSibling.sibling = renderedTail;\n            } else {\n              workInProgress.child = renderedTail;\n            }\n\n            renderState.last = renderedTail;\n          }\n        }\n\n        if (renderState.tail !== null) {\n          // We still have tail rows to render.\n          if (renderState.tailExpiration === 0) {\n            // Heuristic for how long we're willing to spend rendering rows\n            // until we just give up and show what we have so far.\n            var TAIL_EXPIRATION_TIMEOUT_MS = 500;\n            renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this\n            // is a per component value. It should really be since the start\n            // of the total render or last commit. Consider using something like\n            // globalMostRecentFallbackTime. That doesn't account for being\n            // suspended for part of the time or when it's a new render.\n            // It should probably use a global start time value instead.\n          } // Pop a row.\n\n\n          var next = renderState.tail;\n          renderState.rendering = next;\n          renderState.tail = next.sibling;\n          renderState.lastEffect = workInProgress.lastEffect;\n          renderState.renderingStartTime = now();\n          next.sibling = null; // Restore the context.\n          // TODO: We can probably just avoid popping it instead and only\n          // setting it the first time we go from not suspended to suspended.\n\n          var suspenseContext = suspenseStackCursor.current;\n\n          if (didSuspendAlready) {\n            suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);\n          } else {\n            suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);\n          }\n\n          pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.\n\n          return next;\n        }\n\n        return null;\n      }\n  }\n\n  {\n    {\n      throw Error( \"Unknown unit of work tag (\" + workInProgress.tag + \"). This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction unwindWork(workInProgress, renderExpirationTime) {\n  switch (workInProgress.tag) {\n    case ClassComponent:\n      {\n        var Component = workInProgress.type;\n\n        if (isContextProvider(Component)) {\n          popContext(workInProgress);\n        }\n\n        var effectTag = workInProgress.effectTag;\n\n        if (effectTag & ShouldCapture) {\n          workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;\n          return workInProgress;\n        }\n\n        return null;\n      }\n\n    case HostRoot:\n      {\n        popHostContainer(workInProgress);\n        popTopLevelContextObject(workInProgress);\n        var _effectTag = workInProgress.effectTag;\n\n        if (!((_effectTag & DidCapture) === NoEffect)) {\n          {\n            throw Error( \"The root failed to unmount after an error. This is likely a bug in React. Please file an issue.\" );\n          }\n        }\n\n        workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;\n        return workInProgress;\n      }\n\n    case HostComponent:\n      {\n        // TODO: popHydrationState\n        popHostContext(workInProgress);\n        return null;\n      }\n\n    case SuspenseComponent:\n      {\n        popSuspenseContext(workInProgress);\n\n        var _effectTag2 = workInProgress.effectTag;\n\n        if (_effectTag2 & ShouldCapture) {\n          workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.\n\n          return workInProgress;\n        }\n\n        return null;\n      }\n\n    case SuspenseListComponent:\n      {\n        popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been\n        // caught by a nested boundary. If not, it should bubble through.\n\n        return null;\n      }\n\n    case HostPortal:\n      popHostContainer(workInProgress);\n      return null;\n\n    case ContextProvider:\n      popProvider(workInProgress);\n      return null;\n\n    default:\n      return null;\n  }\n}\n\nfunction unwindInterruptedWork(interruptedWork) {\n  switch (interruptedWork.tag) {\n    case ClassComponent:\n      {\n        var childContextTypes = interruptedWork.type.childContextTypes;\n\n        if (childContextTypes !== null && childContextTypes !== undefined) {\n          popContext(interruptedWork);\n        }\n\n        break;\n      }\n\n    case HostRoot:\n      {\n        popHostContainer(interruptedWork);\n        popTopLevelContextObject(interruptedWork);\n        break;\n      }\n\n    case HostComponent:\n      {\n        popHostContext(interruptedWork);\n        break;\n      }\n\n    case HostPortal:\n      popHostContainer(interruptedWork);\n      break;\n\n    case SuspenseComponent:\n      popSuspenseContext(interruptedWork);\n      break;\n\n    case SuspenseListComponent:\n      popSuspenseContext(interruptedWork);\n      break;\n\n    case ContextProvider:\n      popProvider(interruptedWork);\n      break;\n  }\n}\n\nfunction createCapturedValue(value, source) {\n  // If the value is an error, call this function immediately after it is thrown\n  // so the stack is accurate.\n  return {\n    value: value,\n    source: source,\n    stack: getStackByFiberInDevAndProd(source)\n  };\n}\n\nfunction logCapturedError(capturedError) {\n\n  var error = capturedError.error;\n\n  {\n    var componentName = capturedError.componentName,\n        componentStack = capturedError.componentStack,\n        errorBoundaryName = capturedError.errorBoundaryName,\n        errorBoundaryFound = capturedError.errorBoundaryFound,\n        willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling\n    // `preventDefault()` in window `error` handler.\n    // We record this information as an expando on the error.\n\n    if (error != null && error._suppressLogging) {\n      if (errorBoundaryFound && willRetry) {\n        // The error is recoverable and was silenced.\n        // Ignore it and don't print the stack addendum.\n        // This is handy for testing error boundaries without noise.\n        return;\n      } // The error is fatal. Since the silencing might have\n      // been accidental, we'll surface it anyway.\n      // However, the browser would have silenced the original error\n      // so we'll print it first, and then print the stack addendum.\n\n\n      console['error'](error); // Don't transform to our wrapper\n      // For a more detailed description of this block, see:\n      // https://github.com/facebook/react/pull/13384\n    }\n\n    var componentNameMessage = componentName ? \"The above error occurred in the <\" + componentName + \"> component:\" : 'The above error occurred in one of your React components:';\n    var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.\n\n    if (errorBoundaryFound && errorBoundaryName) {\n      if (willRetry) {\n        errorBoundaryMessage = \"React will try to recreate this component tree from scratch \" + (\"using the error boundary you provided, \" + errorBoundaryName + \".\");\n      } else {\n        errorBoundaryMessage = \"This error was initially handled by the error boundary \" + errorBoundaryName + \".\\n\" + \"Recreating the tree from scratch failed so React will unmount the tree.\";\n      }\n    } else {\n      errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.';\n    }\n\n    var combinedMessage = \"\" + componentNameMessage + componentStack + \"\\n\\n\" + (\"\" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.\n    // We don't include the original error message and JS stack because the browser\n    // has already printed it. Even if the application swallows the error, it is still\n    // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.\n\n    console['error'](combinedMessage); // Don't transform to our wrapper\n  }\n}\n\nvar didWarnAboutUndefinedSnapshotBeforeUpdate = null;\n\n{\n  didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();\n}\n\nvar PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;\nfunction logError(boundary, errorInfo) {\n  var source = errorInfo.source;\n  var stack = errorInfo.stack;\n\n  if (stack === null && source !== null) {\n    stack = getStackByFiberInDevAndProd(source);\n  }\n\n  var capturedError = {\n    componentName: source !== null ? getComponentName(source.type) : null,\n    componentStack: stack !== null ? stack : '',\n    error: errorInfo.value,\n    errorBoundary: null,\n    errorBoundaryName: null,\n    errorBoundaryFound: false,\n    willRetry: false\n  };\n\n  if (boundary !== null && boundary.tag === ClassComponent) {\n    capturedError.errorBoundary = boundary.stateNode;\n    capturedError.errorBoundaryName = getComponentName(boundary.type);\n    capturedError.errorBoundaryFound = true;\n    capturedError.willRetry = true;\n  }\n\n  try {\n    logCapturedError(capturedError);\n  } catch (e) {\n    // This method must not throw, or React internal state will get messed up.\n    // If console.error is overridden, or logCapturedError() shows a dialog that throws,\n    // we want to report this error outside of the normal stack as a last resort.\n    // https://github.com/facebook/react/issues/13188\n    setTimeout(function () {\n      throw e;\n    });\n  }\n}\n\nvar callComponentWillUnmountWithTimer = function (current, instance) {\n  startPhaseTimer(current, 'componentWillUnmount');\n  instance.props = current.memoizedProps;\n  instance.state = current.memoizedState;\n  instance.componentWillUnmount();\n  stopPhaseTimer();\n}; // Capture errors so they don't interrupt unmounting.\n\n\nfunction safelyCallComponentWillUnmount(current, instance) {\n  {\n    invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);\n\n    if (hasCaughtError()) {\n      var unmountError = clearCaughtError();\n      captureCommitPhaseError(current, unmountError);\n    }\n  }\n}\n\nfunction safelyDetachRef(current) {\n  var ref = current.ref;\n\n  if (ref !== null) {\n    if (typeof ref === 'function') {\n      {\n        invokeGuardedCallback(null, ref, null, null);\n\n        if (hasCaughtError()) {\n          var refError = clearCaughtError();\n          captureCommitPhaseError(current, refError);\n        }\n      }\n    } else {\n      ref.current = null;\n    }\n  }\n}\n\nfunction safelyCallDestroy(current, destroy) {\n  {\n    invokeGuardedCallback(null, destroy, null);\n\n    if (hasCaughtError()) {\n      var error = clearCaughtError();\n      captureCommitPhaseError(current, error);\n    }\n  }\n}\n\nfunction commitBeforeMutationLifeCycles(current, finishedWork) {\n  switch (finishedWork.tag) {\n    case FunctionComponent:\n    case ForwardRef:\n    case SimpleMemoComponent:\n    case Block:\n      {\n        return;\n      }\n\n    case ClassComponent:\n      {\n        if (finishedWork.effectTag & Snapshot) {\n          if (current !== null) {\n            var prevProps = current.memoizedProps;\n            var prevState = current.memoizedState;\n            startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');\n            var instance = finishedWork.stateNode; // We could update instance props and state here,\n            // but instead we rely on them being set during last render.\n            // TODO: revisit this when we implement resuming.\n\n            {\n              if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {\n                if (instance.props !== finishedWork.memoizedProps) {\n                  error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n\n                if (instance.state !== finishedWork.memoizedState) {\n                  error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n              }\n            }\n\n            var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);\n\n            {\n              var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;\n\n              if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {\n                didWarnSet.add(finishedWork.type);\n\n                error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));\n              }\n            }\n\n            instance.__reactInternalSnapshotBeforeUpdate = snapshot;\n            stopPhaseTimer();\n          }\n        }\n\n        return;\n      }\n\n    case HostRoot:\n    case HostComponent:\n    case HostText:\n    case HostPortal:\n    case IncompleteClassComponent:\n      // Nothing to do for these component types\n      return;\n  }\n\n  {\n    {\n      throw Error( \"This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction commitHookEffectListUnmount(tag, finishedWork) {\n  var updateQueue = finishedWork.updateQueue;\n  var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;\n\n  if (lastEffect !== null) {\n    var firstEffect = lastEffect.next;\n    var effect = firstEffect;\n\n    do {\n      if ((effect.tag & tag) === tag) {\n        // Unmount\n        var destroy = effect.destroy;\n        effect.destroy = undefined;\n\n        if (destroy !== undefined) {\n          destroy();\n        }\n      }\n\n      effect = effect.next;\n    } while (effect !== firstEffect);\n  }\n}\n\nfunction commitHookEffectListMount(tag, finishedWork) {\n  var updateQueue = finishedWork.updateQueue;\n  var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;\n\n  if (lastEffect !== null) {\n    var firstEffect = lastEffect.next;\n    var effect = firstEffect;\n\n    do {\n      if ((effect.tag & tag) === tag) {\n        // Mount\n        var create = effect.create;\n        effect.destroy = create();\n\n        {\n          var destroy = effect.destroy;\n\n          if (destroy !== undefined && typeof destroy !== 'function') {\n            var addendum = void 0;\n\n            if (destroy === null) {\n              addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';\n            } else if (typeof destroy.then === 'function') {\n              addendum = '\\n\\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\\n\\n' + 'useEffect(() => {\\n' + '  async function fetchData() {\\n' + '    // You can await here\\n' + '    const response = await MyAPI.getData(someId);\\n' + '    // ...\\n' + '  }\\n' + '  fetchData();\\n' + \"}, [someId]); // Or [] if effect doesn't need props or state\\n\\n\" + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';\n            } else {\n              addendum = ' You returned: ' + destroy;\n            }\n\n            error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));\n          }\n        }\n      }\n\n      effect = effect.next;\n    } while (effect !== firstEffect);\n  }\n}\n\nfunction commitPassiveHookEffects(finishedWork) {\n  if ((finishedWork.effectTag & Passive) !== NoEffect) {\n    switch (finishedWork.tag) {\n      case FunctionComponent:\n      case ForwardRef:\n      case SimpleMemoComponent:\n      case Block:\n        {\n          // TODO (#17945) We should call all passive destroy functions (for all fibers)\n          // before calling any create functions. The current approach only serializes\n          // these for a single fiber.\n          commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);\n          commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);\n          break;\n        }\n    }\n  }\n}\n\nfunction commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {\n  switch (finishedWork.tag) {\n    case FunctionComponent:\n    case ForwardRef:\n    case SimpleMemoComponent:\n    case Block:\n      {\n        // At this point layout effects have already been destroyed (during mutation phase).\n        // This is done to prevent sibling component effects from interfering with each other,\n        // e.g. a destroy function in one component should never override a ref set\n        // by a create function in another component during the same commit.\n        commitHookEffectListMount(Layout | HasEffect, finishedWork);\n\n        return;\n      }\n\n    case ClassComponent:\n      {\n        var instance = finishedWork.stateNode;\n\n        if (finishedWork.effectTag & Update) {\n          if (current === null) {\n            startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,\n            // but instead we rely on them being set during last render.\n            // TODO: revisit this when we implement resuming.\n\n            {\n              if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {\n                if (instance.props !== finishedWork.memoizedProps) {\n                  error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n\n                if (instance.state !== finishedWork.memoizedState) {\n                  error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n              }\n            }\n\n            instance.componentDidMount();\n            stopPhaseTimer();\n          } else {\n            var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);\n            var prevState = current.memoizedState;\n            startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,\n            // but instead we rely on them being set during last render.\n            // TODO: revisit this when we implement resuming.\n\n            {\n              if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {\n                if (instance.props !== finishedWork.memoizedProps) {\n                  error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n\n                if (instance.state !== finishedWork.memoizedState) {\n                  error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n                }\n              }\n            }\n\n            instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);\n            stopPhaseTimer();\n          }\n        }\n\n        var updateQueue = finishedWork.updateQueue;\n\n        if (updateQueue !== null) {\n          {\n            if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {\n              if (instance.props !== finishedWork.memoizedProps) {\n                error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n              }\n\n              if (instance.state !== finishedWork.memoizedState) {\n                error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');\n              }\n            }\n          } // We could update instance props and state here,\n          // but instead we rely on them being set during last render.\n          // TODO: revisit this when we implement resuming.\n\n\n          commitUpdateQueue(finishedWork, updateQueue, instance);\n        }\n\n        return;\n      }\n\n    case HostRoot:\n      {\n        var _updateQueue = finishedWork.updateQueue;\n\n        if (_updateQueue !== null) {\n          var _instance = null;\n\n          if (finishedWork.child !== null) {\n            switch (finishedWork.child.tag) {\n              case HostComponent:\n                _instance = getPublicInstance(finishedWork.child.stateNode);\n                break;\n\n              case ClassComponent:\n                _instance = finishedWork.child.stateNode;\n                break;\n            }\n          }\n\n          commitUpdateQueue(finishedWork, _updateQueue, _instance);\n        }\n\n        return;\n      }\n\n    case HostComponent:\n      {\n        var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted\n        // (eg DOM renderer may schedule auto-focus for inputs and form controls).\n        // These effects should only be committed when components are first mounted,\n        // aka when there is no current/alternate.\n\n        if (current === null && finishedWork.effectTag & Update) {\n          var type = finishedWork.type;\n          var props = finishedWork.memoizedProps;\n          commitMount(_instance2, type, props);\n        }\n\n        return;\n      }\n\n    case HostText:\n      {\n        // We have no life-cycles associated with text.\n        return;\n      }\n\n    case HostPortal:\n      {\n        // We have no life-cycles associated with portals.\n        return;\n      }\n\n    case Profiler:\n      {\n        {\n          var onRender = finishedWork.memoizedProps.onRender;\n\n          if (typeof onRender === 'function') {\n            {\n              onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);\n            }\n          }\n        }\n\n        return;\n      }\n\n    case SuspenseComponent:\n      {\n        commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);\n        return;\n      }\n\n    case SuspenseListComponent:\n    case IncompleteClassComponent:\n    case FundamentalComponent:\n    case ScopeComponent:\n      return;\n  }\n\n  {\n    {\n      throw Error( \"This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction hideOrUnhideAllChildren(finishedWork, isHidden) {\n  {\n    // We only have the top Fiber that was inserted but we need to recurse down its\n    // children to find all the terminal nodes.\n    var node = finishedWork;\n\n    while (true) {\n      if (node.tag === HostComponent) {\n        var instance = node.stateNode;\n\n        if (isHidden) {\n          hideInstance(instance);\n        } else {\n          unhideInstance(node.stateNode, node.memoizedProps);\n        }\n      } else if (node.tag === HostText) {\n        var _instance3 = node.stateNode;\n\n        if (isHidden) {\n          hideTextInstance(_instance3);\n        } else {\n          unhideTextInstance(_instance3, node.memoizedProps);\n        }\n      } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {\n        // Found a nested Suspense component that timed out. Skip over the\n        // primary child fragment, which should remain hidden.\n        var fallbackChildFragment = node.child.sibling;\n        fallbackChildFragment.return = node;\n        node = fallbackChildFragment;\n        continue;\n      } else if (node.child !== null) {\n        node.child.return = node;\n        node = node.child;\n        continue;\n      }\n\n      if (node === finishedWork) {\n        return;\n      }\n\n      while (node.sibling === null) {\n        if (node.return === null || node.return === finishedWork) {\n          return;\n        }\n\n        node = node.return;\n      }\n\n      node.sibling.return = node.return;\n      node = node.sibling;\n    }\n  }\n}\n\nfunction commitAttachRef(finishedWork) {\n  var ref = finishedWork.ref;\n\n  if (ref !== null) {\n    var instance = finishedWork.stateNode;\n    var instanceToUse;\n\n    switch (finishedWork.tag) {\n      case HostComponent:\n        instanceToUse = getPublicInstance(instance);\n        break;\n\n      default:\n        instanceToUse = instance;\n    } // Moved outside to ensure DCE works with this flag\n\n    if (typeof ref === 'function') {\n      ref(instanceToUse);\n    } else {\n      {\n        if (!ref.hasOwnProperty('current')) {\n          error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));\n        }\n      }\n\n      ref.current = instanceToUse;\n    }\n  }\n}\n\nfunction commitDetachRef(current) {\n  var currentRef = current.ref;\n\n  if (currentRef !== null) {\n    if (typeof currentRef === 'function') {\n      currentRef(null);\n    } else {\n      currentRef.current = null;\n    }\n  }\n} // User-originating errors (lifecycles and refs) should not interrupt\n// deletion, so don't let them throw. Host-originating errors should\n// interrupt deletion, so it's okay\n\n\nfunction commitUnmount(finishedRoot, current, renderPriorityLevel) {\n  onCommitUnmount(current);\n\n  switch (current.tag) {\n    case FunctionComponent:\n    case ForwardRef:\n    case MemoComponent:\n    case SimpleMemoComponent:\n    case Block:\n      {\n        var updateQueue = current.updateQueue;\n\n        if (updateQueue !== null) {\n          var lastEffect = updateQueue.lastEffect;\n\n          if (lastEffect !== null) {\n            var firstEffect = lastEffect.next;\n\n            {\n              // When the owner fiber is deleted, the destroy function of a passive\n              // effect hook is called during the synchronous commit phase. This is\n              // a concession to implementation complexity. Calling it in the\n              // passive effect phase (like they usually are, when dependencies\n              // change during an update) would require either traversing the\n              // children of the deleted fiber again, or including unmount effects\n              // as part of the fiber effect list.\n              //\n              // Because this is during the sync commit phase, we need to change\n              // the priority.\n              //\n              // TODO: Reconsider this implementation trade off.\n              var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;\n              runWithPriority$1(priorityLevel, function () {\n                var effect = firstEffect;\n\n                do {\n                  var _destroy = effect.destroy;\n\n                  if (_destroy !== undefined) {\n                    safelyCallDestroy(current, _destroy);\n                  }\n\n                  effect = effect.next;\n                } while (effect !== firstEffect);\n              });\n            }\n          }\n        }\n\n        return;\n      }\n\n    case ClassComponent:\n      {\n        safelyDetachRef(current);\n        var instance = current.stateNode;\n\n        if (typeof instance.componentWillUnmount === 'function') {\n          safelyCallComponentWillUnmount(current, instance);\n        }\n\n        return;\n      }\n\n    case HostComponent:\n      {\n\n        safelyDetachRef(current);\n        return;\n      }\n\n    case HostPortal:\n      {\n        // TODO: this is recursive.\n        // We are also not using this parent because\n        // the portal will get pushed immediately.\n        {\n          unmountHostComponents(finishedRoot, current, renderPriorityLevel);\n        }\n\n        return;\n      }\n\n    case FundamentalComponent:\n      {\n\n        return;\n      }\n\n    case DehydratedFragment:\n      {\n\n        return;\n      }\n\n    case ScopeComponent:\n      {\n\n        return;\n      }\n  }\n}\n\nfunction commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {\n  // While we're inside a removed host node we don't want to call\n  // removeChild on the inner nodes because they're removed by the top\n  // call anyway. We also want to call componentWillUnmount on all\n  // composites before this host node is removed from the tree. Therefore\n  // we do an inner loop while we're still inside the host node.\n  var node = root;\n\n  while (true) {\n    commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.\n    // Skip portals because commitUnmount() currently visits them recursively.\n\n    if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.\n    // If we don't use mutation we drill down into portals here instead.\n     node.tag !== HostPortal)) {\n      node.child.return = node;\n      node = node.child;\n      continue;\n    }\n\n    if (node === root) {\n      return;\n    }\n\n    while (node.sibling === null) {\n      if (node.return === null || node.return === root) {\n        return;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  }\n}\n\nfunction detachFiber(current) {\n  var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we\n  // should clear the child pointer of the parent alternate to let this\n  // get GC:ed but we don't know which for sure which parent is the current\n  // one so we'll settle for GC:ing the subtree of this child. This child\n  // itself will be GC:ed when the parent updates the next time.\n\n  current.return = null;\n  current.child = null;\n  current.memoizedState = null;\n  current.updateQueue = null;\n  current.dependencies = null;\n  current.alternate = null;\n  current.firstEffect = null;\n  current.lastEffect = null;\n  current.pendingProps = null;\n  current.memoizedProps = null;\n  current.stateNode = null;\n\n  if (alternate !== null) {\n    detachFiber(alternate);\n  }\n}\n\nfunction getHostParentFiber(fiber) {\n  var parent = fiber.return;\n\n  while (parent !== null) {\n    if (isHostParent(parent)) {\n      return parent;\n    }\n\n    parent = parent.return;\n  }\n\n  {\n    {\n      throw Error( \"Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction isHostParent(fiber) {\n  return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;\n}\n\nfunction getHostSibling(fiber) {\n  // We're going to search forward into the tree until we find a sibling host\n  // node. Unfortunately, if multiple insertions are done in a row we have to\n  // search past them. This leads to exponential search for the next sibling.\n  // TODO: Find a more efficient way to do this.\n  var node = fiber;\n\n  siblings: while (true) {\n    // If we didn't find anything, let's try the next sibling.\n    while (node.sibling === null) {\n      if (node.return === null || isHostParent(node.return)) {\n        // If we pop out of the root or hit the parent the fiber we are the\n        // last sibling.\n        return null;\n      }\n\n      node = node.return;\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n\n    while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {\n      // If it is not host node and, we might have a host node inside it.\n      // Try to search down until we find one.\n      if (node.effectTag & Placement) {\n        // If we don't have a child, try the siblings instead.\n        continue siblings;\n      } // If we don't have a child, try the siblings instead.\n      // We also skip portals because they are not part of this host tree.\n\n\n      if (node.child === null || node.tag === HostPortal) {\n        continue siblings;\n      } else {\n        node.child.return = node;\n        node = node.child;\n      }\n    } // Check if this host node is stable or about to be placed.\n\n\n    if (!(node.effectTag & Placement)) {\n      // Found it!\n      return node.stateNode;\n    }\n  }\n}\n\nfunction commitPlacement(finishedWork) {\n\n\n  var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.\n\n  var parent;\n  var isContainer;\n  var parentStateNode = parentFiber.stateNode;\n\n  switch (parentFiber.tag) {\n    case HostComponent:\n      parent = parentStateNode;\n      isContainer = false;\n      break;\n\n    case HostRoot:\n      parent = parentStateNode.containerInfo;\n      isContainer = true;\n      break;\n\n    case HostPortal:\n      parent = parentStateNode.containerInfo;\n      isContainer = true;\n      break;\n\n    case FundamentalComponent:\n\n    // eslint-disable-next-line-no-fallthrough\n\n    default:\n      {\n        {\n          throw Error( \"Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.\" );\n        }\n      }\n\n  }\n\n  if (parentFiber.effectTag & ContentReset) {\n    // Reset the text content of the parent before doing any insertions\n    resetTextContent(parent); // Clear ContentReset from the effect tag\n\n    parentFiber.effectTag &= ~ContentReset;\n  }\n\n  var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its\n  // children to find all the terminal nodes.\n\n  if (isContainer) {\n    insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);\n  } else {\n    insertOrAppendPlacementNode(finishedWork, before, parent);\n  }\n}\n\nfunction insertOrAppendPlacementNodeIntoContainer(node, before, parent) {\n  var tag = node.tag;\n  var isHost = tag === HostComponent || tag === HostText;\n\n  if (isHost || enableFundamentalAPI ) {\n    var stateNode = isHost ? node.stateNode : node.stateNode.instance;\n\n    if (before) {\n      insertInContainerBefore(parent, stateNode, before);\n    } else {\n      appendChildToContainer(parent, stateNode);\n    }\n  } else if (tag === HostPortal) ; else {\n    var child = node.child;\n\n    if (child !== null) {\n      insertOrAppendPlacementNodeIntoContainer(child, before, parent);\n      var sibling = child.sibling;\n\n      while (sibling !== null) {\n        insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);\n        sibling = sibling.sibling;\n      }\n    }\n  }\n}\n\nfunction insertOrAppendPlacementNode(node, before, parent) {\n  var tag = node.tag;\n  var isHost = tag === HostComponent || tag === HostText;\n\n  if (isHost || enableFundamentalAPI ) {\n    var stateNode = isHost ? node.stateNode : node.stateNode.instance;\n\n    if (before) {\n      insertBefore(parent, stateNode, before);\n    } else {\n      appendChild(parent, stateNode);\n    }\n  } else if (tag === HostPortal) ; else {\n    var child = node.child;\n\n    if (child !== null) {\n      insertOrAppendPlacementNode(child, before, parent);\n      var sibling = child.sibling;\n\n      while (sibling !== null) {\n        insertOrAppendPlacementNode(sibling, before, parent);\n        sibling = sibling.sibling;\n      }\n    }\n  }\n}\n\nfunction unmountHostComponents(finishedRoot, current, renderPriorityLevel) {\n  // We only have the top Fiber that was deleted but we need to recurse down its\n  // children to find all the terminal nodes.\n  var node = current; // Each iteration, currentParent is populated with node's host parent if not\n  // currentParentIsValid.\n\n  var currentParentIsValid = false; // Note: these two variables *must* always be updated together.\n\n  var currentParent;\n  var currentParentIsContainer;\n\n  while (true) {\n    if (!currentParentIsValid) {\n      var parent = node.return;\n\n      findParent: while (true) {\n        if (!(parent !== null)) {\n          {\n            throw Error( \"Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.\" );\n          }\n        }\n\n        var parentStateNode = parent.stateNode;\n\n        switch (parent.tag) {\n          case HostComponent:\n            currentParent = parentStateNode;\n            currentParentIsContainer = false;\n            break findParent;\n\n          case HostRoot:\n            currentParent = parentStateNode.containerInfo;\n            currentParentIsContainer = true;\n            break findParent;\n\n          case HostPortal:\n            currentParent = parentStateNode.containerInfo;\n            currentParentIsContainer = true;\n            break findParent;\n\n        }\n\n        parent = parent.return;\n      }\n\n      currentParentIsValid = true;\n    }\n\n    if (node.tag === HostComponent || node.tag === HostText) {\n      commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the\n      // node from the tree.\n\n      if (currentParentIsContainer) {\n        removeChildFromContainer(currentParent, node.stateNode);\n      } else {\n        removeChild(currentParent, node.stateNode);\n      } // Don't visit children because we already visited them.\n\n    } else if (node.tag === HostPortal) {\n      if (node.child !== null) {\n        // When we go into a portal, it becomes the parent to remove from.\n        // We will reassign it back when we pop the portal on the way up.\n        currentParent = node.stateNode.containerInfo;\n        currentParentIsContainer = true; // Visit children because portals might contain host components.\n\n        node.child.return = node;\n        node = node.child;\n        continue;\n      }\n    } else {\n      commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.\n\n      if (node.child !== null) {\n        node.child.return = node;\n        node = node.child;\n        continue;\n      }\n    }\n\n    if (node === current) {\n      return;\n    }\n\n    while (node.sibling === null) {\n      if (node.return === null || node.return === current) {\n        return;\n      }\n\n      node = node.return;\n\n      if (node.tag === HostPortal) {\n        // When we go out of the portal, we need to restore the parent.\n        // Since we don't keep a stack of them, we will search for it.\n        currentParentIsValid = false;\n      }\n    }\n\n    node.sibling.return = node.return;\n    node = node.sibling;\n  }\n}\n\nfunction commitDeletion(finishedRoot, current, renderPriorityLevel) {\n  {\n    // Recursively delete all host nodes from the parent.\n    // Detach refs and call componentWillUnmount() on the whole subtree.\n    unmountHostComponents(finishedRoot, current, renderPriorityLevel);\n  }\n\n  detachFiber(current);\n}\n\nfunction commitWork(current, finishedWork) {\n\n  switch (finishedWork.tag) {\n    case FunctionComponent:\n    case ForwardRef:\n    case MemoComponent:\n    case SimpleMemoComponent:\n    case Block:\n      {\n        // Layout effects are destroyed during the mutation phase so that all\n        // destroy functions for all fibers are called before any create functions.\n        // This prevents sibling component effects from interfering with each other,\n        // e.g. a destroy function in one component should never override a ref set\n        // by a create function in another component during the same commit.\n        commitHookEffectListUnmount(Layout | HasEffect, finishedWork);\n        return;\n      }\n\n    case ClassComponent:\n      {\n        return;\n      }\n\n    case HostComponent:\n      {\n        var instance = finishedWork.stateNode;\n\n        if (instance != null) {\n          // Commit the work prepared earlier.\n          var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps\n          // as the newProps. The updatePayload will contain the real change in\n          // this case.\n\n          var oldProps = current !== null ? current.memoizedProps : newProps;\n          var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.\n\n          var updatePayload = finishedWork.updateQueue;\n          finishedWork.updateQueue = null;\n\n          if (updatePayload !== null) {\n            commitUpdate(instance, updatePayload, type, oldProps, newProps);\n          }\n        }\n\n        return;\n      }\n\n    case HostText:\n      {\n        if (!(finishedWork.stateNode !== null)) {\n          {\n            throw Error( \"This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.\" );\n          }\n        }\n\n        var textInstance = finishedWork.stateNode;\n        var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps\n        // as the newProps. The updatePayload will contain the real change in\n        // this case.\n\n        var oldText = current !== null ? current.memoizedProps : newText;\n        commitTextUpdate(textInstance, oldText, newText);\n        return;\n      }\n\n    case HostRoot:\n      {\n        {\n          var _root = finishedWork.stateNode;\n\n          if (_root.hydrate) {\n            // We've just hydrated. No need to hydrate again.\n            _root.hydrate = false;\n            commitHydratedContainer(_root.containerInfo);\n          }\n        }\n\n        return;\n      }\n\n    case Profiler:\n      {\n        return;\n      }\n\n    case SuspenseComponent:\n      {\n        commitSuspenseComponent(finishedWork);\n        attachSuspenseRetryListeners(finishedWork);\n        return;\n      }\n\n    case SuspenseListComponent:\n      {\n        attachSuspenseRetryListeners(finishedWork);\n        return;\n      }\n\n    case IncompleteClassComponent:\n      {\n        return;\n      }\n  }\n\n  {\n    {\n      throw Error( \"This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  }\n}\n\nfunction commitSuspenseComponent(finishedWork) {\n  var newState = finishedWork.memoizedState;\n  var newDidTimeout;\n  var primaryChildParent = finishedWork;\n\n  if (newState === null) {\n    newDidTimeout = false;\n  } else {\n    newDidTimeout = true;\n    primaryChildParent = finishedWork.child;\n    markCommitTimeOfFallback();\n  }\n\n  if ( primaryChildParent !== null) {\n    hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);\n  }\n}\n\nfunction commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {\n\n  var newState = finishedWork.memoizedState;\n\n  if (newState === null) {\n    var current = finishedWork.alternate;\n\n    if (current !== null) {\n      var prevState = current.memoizedState;\n\n      if (prevState !== null) {\n        var suspenseInstance = prevState.dehydrated;\n\n        if (suspenseInstance !== null) {\n          commitHydratedSuspenseInstance(suspenseInstance);\n        }\n      }\n    }\n  }\n}\n\nfunction attachSuspenseRetryListeners(finishedWork) {\n  // If this boundary just timed out, then it will have a set of thenables.\n  // For each thenable, attach a listener so that when it resolves, React\n  // attempts to re-render the boundary in the primary (pre-timeout) state.\n  var thenables = finishedWork.updateQueue;\n\n  if (thenables !== null) {\n    finishedWork.updateQueue = null;\n    var retryCache = finishedWork.stateNode;\n\n    if (retryCache === null) {\n      retryCache = finishedWork.stateNode = new PossiblyWeakSet();\n    }\n\n    thenables.forEach(function (thenable) {\n      // Memoize using the boundary fiber to prevent redundant listeners.\n      var retry = resolveRetryThenable.bind(null, finishedWork, thenable);\n\n      if (!retryCache.has(thenable)) {\n        {\n          if (thenable.__reactDoNotTraceInteractions !== true) {\n            retry = tracing.unstable_wrap(retry);\n          }\n        }\n\n        retryCache.add(thenable);\n        thenable.then(retry, retry);\n      }\n    });\n  }\n}\n\nfunction commitResetTextContent(current) {\n\n  resetTextContent(current.stateNode);\n}\n\nvar PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;\n\nfunction createRootErrorUpdate(fiber, errorInfo, expirationTime) {\n  var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.\n\n  update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property\n  // being called \"element\".\n\n  update.payload = {\n    element: null\n  };\n  var error = errorInfo.value;\n\n  update.callback = function () {\n    onUncaughtError(error);\n    logError(fiber, errorInfo);\n  };\n\n  return update;\n}\n\nfunction createClassErrorUpdate(fiber, errorInfo, expirationTime) {\n  var update = createUpdate(expirationTime, null);\n  update.tag = CaptureUpdate;\n  var getDerivedStateFromError = fiber.type.getDerivedStateFromError;\n\n  if (typeof getDerivedStateFromError === 'function') {\n    var error$1 = errorInfo.value;\n\n    update.payload = function () {\n      logError(fiber, errorInfo);\n      return getDerivedStateFromError(error$1);\n    };\n  }\n\n  var inst = fiber.stateNode;\n\n  if (inst !== null && typeof inst.componentDidCatch === 'function') {\n    update.callback = function callback() {\n      {\n        markFailedErrorBoundaryForHotReloading(fiber);\n      }\n\n      if (typeof getDerivedStateFromError !== 'function') {\n        // To preserve the preexisting retry behavior of error boundaries,\n        // we keep track of which ones already failed during this batch.\n        // This gets reset before we yield back to the browser.\n        // TODO: Warn in strict mode if getDerivedStateFromError is\n        // not defined.\n        markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined\n\n        logError(fiber, errorInfo);\n      }\n\n      var error$1 = errorInfo.value;\n      var stack = errorInfo.stack;\n      this.componentDidCatch(error$1, {\n        componentStack: stack !== null ? stack : ''\n      });\n\n      {\n        if (typeof getDerivedStateFromError !== 'function') {\n          // If componentDidCatch is the only error boundary method defined,\n          // then it needs to call setState to recover from errors.\n          // If no state update is scheduled then the boundary will swallow the error.\n          if (fiber.expirationTime !== Sync) {\n            error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');\n          }\n        }\n      }\n    };\n  } else {\n    update.callback = function () {\n      markFailedErrorBoundaryForHotReloading(fiber);\n    };\n  }\n\n  return update;\n}\n\nfunction attachPingListener(root, renderExpirationTime, thenable) {\n  // Attach a listener to the promise to \"ping\" the root and retry. But\n  // only if one does not already exist for the current render expiration\n  // time (which acts like a \"thread ID\" here).\n  var pingCache = root.pingCache;\n  var threadIDs;\n\n  if (pingCache === null) {\n    pingCache = root.pingCache = new PossiblyWeakMap$1();\n    threadIDs = new Set();\n    pingCache.set(thenable, threadIDs);\n  } else {\n    threadIDs = pingCache.get(thenable);\n\n    if (threadIDs === undefined) {\n      threadIDs = new Set();\n      pingCache.set(thenable, threadIDs);\n    }\n  }\n\n  if (!threadIDs.has(renderExpirationTime)) {\n    // Memoize using the thread ID to prevent redundant listeners.\n    threadIDs.add(renderExpirationTime);\n    var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);\n    thenable.then(ping, ping);\n  }\n}\n\nfunction throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {\n  // The source fiber did not complete.\n  sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.\n\n  sourceFiber.firstEffect = sourceFiber.lastEffect = null;\n\n  if (value !== null && typeof value === 'object' && typeof value.then === 'function') {\n    // This is a thenable.\n    var thenable = value;\n\n    if ((sourceFiber.mode & BlockingMode) === NoMode) {\n      // Reset the memoizedState to what it was before we attempted\n      // to render it.\n      var currentSource = sourceFiber.alternate;\n\n      if (currentSource) {\n        sourceFiber.updateQueue = currentSource.updateQueue;\n        sourceFiber.memoizedState = currentSource.memoizedState;\n        sourceFiber.expirationTime = currentSource.expirationTime;\n      } else {\n        sourceFiber.updateQueue = null;\n        sourceFiber.memoizedState = null;\n      }\n    }\n\n    var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.\n\n    var _workInProgress = returnFiber;\n\n    do {\n      if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {\n        // Found the nearest boundary.\n        // Stash the promise on the boundary fiber. If the boundary times out, we'll\n        // attach another listener to flip the boundary back to its normal state.\n        var thenables = _workInProgress.updateQueue;\n\n        if (thenables === null) {\n          var updateQueue = new Set();\n          updateQueue.add(thenable);\n          _workInProgress.updateQueue = updateQueue;\n        } else {\n          thenables.add(thenable);\n        } // If the boundary is outside of blocking mode, we should *not*\n        // suspend the commit. Pretend as if the suspended component rendered\n        // null and keep rendering. In the commit phase, we'll schedule a\n        // subsequent synchronous update to re-render the Suspense.\n        //\n        // Note: It doesn't matter whether the component that suspended was\n        // inside a blocking mode tree. If the Suspense is outside of it, we\n        // should *not* suspend the commit.\n\n\n        if ((_workInProgress.mode & BlockingMode) === NoMode) {\n          _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.\n          // But we shouldn't call any lifecycle methods or callbacks. Remove\n          // all lifecycle effect tags.\n\n          sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);\n\n          if (sourceFiber.tag === ClassComponent) {\n            var currentSourceFiber = sourceFiber.alternate;\n\n            if (currentSourceFiber === null) {\n              // This is a new mount. Change the tag so it's not mistaken for a\n              // completed class component. For example, we should not call\n              // componentWillUnmount if it is deleted.\n              sourceFiber.tag = IncompleteClassComponent;\n            } else {\n              // When we try rendering again, we should not reuse the current fiber,\n              // since it's known to be in an inconsistent state. Use a force update to\n              // prevent a bail out.\n              var update = createUpdate(Sync, null);\n              update.tag = ForceUpdate;\n              enqueueUpdate(sourceFiber, update);\n            }\n          } // The source fiber did not complete. Mark it with Sync priority to\n          // indicate that it still has pending work.\n\n\n          sourceFiber.expirationTime = Sync; // Exit without suspending.\n\n          return;\n        } // Confirmed that the boundary is in a concurrent mode tree. Continue\n        // with the normal suspend path.\n        //\n        // After this we'll use a set of heuristics to determine whether this\n        // render pass will run to completion or restart or \"suspend\" the commit.\n        // The actual logic for this is spread out in different places.\n        //\n        // This first principle is that if we're going to suspend when we complete\n        // a root, then we should also restart if we get an update or ping that\n        // might unsuspend it, and vice versa. The only reason to suspend is\n        // because you think you might want to restart before committing. However,\n        // it doesn't make sense to restart only while in the period we're suspended.\n        //\n        // Restarting too aggressively is also not good because it starves out any\n        // intermediate loading state. So we use heuristics to determine when.\n        // Suspense Heuristics\n        //\n        // If nothing threw a Promise or all the same fallbacks are already showing,\n        // then don't suspend/restart.\n        //\n        // If this is an initial render of a new tree of Suspense boundaries and\n        // those trigger a fallback, then don't suspend/restart. We want to ensure\n        // that we can show the initial loading state as quickly as possible.\n        //\n        // If we hit a \"Delayed\" case, such as when we'd switch from content back into\n        // a fallback, then we should always suspend/restart. SuspenseConfig applies to\n        // this case. If none is defined, JND is used instead.\n        //\n        // If we're already showing a fallback and it gets \"retried\", allowing us to show\n        // another level, but there's still an inner boundary that would show a fallback,\n        // then we suspend/restart for 500ms since the last time we showed a fallback\n        // anywhere in the tree. This effectively throttles progressive loading into a\n        // consistent train of commits. This also gives us an opportunity to restart to\n        // get to the completed state slightly earlier.\n        //\n        // If there's ambiguity due to batching it's resolved in preference of:\n        // 1) \"delayed\", 2) \"initial render\", 3) \"retry\".\n        //\n        // We want to ensure that a \"busy\" state doesn't get force committed. We want to\n        // ensure that new initial loading states can commit as soon as possible.\n\n\n        attachPingListener(root, renderExpirationTime, thenable);\n        _workInProgress.effectTag |= ShouldCapture;\n        _workInProgress.expirationTime = renderExpirationTime;\n        return;\n      } // This boundary already captured during this render. Continue to the next\n      // boundary.\n\n\n      _workInProgress = _workInProgress.return;\n    } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.\n    // TODO: Use invariant so the message is stripped in prod?\n\n\n    value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\\n' + '\\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.' + getStackByFiberInDevAndProd(sourceFiber));\n  } // We didn't find a boundary that could handle this type of exception. Start\n  // over and traverse parent path again, this time treating the exception\n  // as an error.\n\n\n  renderDidError();\n  value = createCapturedValue(value, sourceFiber);\n  var workInProgress = returnFiber;\n\n  do {\n    switch (workInProgress.tag) {\n      case HostRoot:\n        {\n          var _errorInfo = value;\n          workInProgress.effectTag |= ShouldCapture;\n          workInProgress.expirationTime = renderExpirationTime;\n\n          var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);\n\n          enqueueCapturedUpdate(workInProgress, _update);\n          return;\n        }\n\n      case ClassComponent:\n        // Capture and retry\n        var errorInfo = value;\n        var ctor = workInProgress.type;\n        var instance = workInProgress.stateNode;\n\n        if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {\n          workInProgress.effectTag |= ShouldCapture;\n          workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state\n\n          var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);\n\n          enqueueCapturedUpdate(workInProgress, _update2);\n          return;\n        }\n\n        break;\n    }\n\n    workInProgress = workInProgress.return;\n  } while (workInProgress !== null);\n}\n\nvar ceil = Math.ceil;\nvar ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,\n    ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,\n    IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;\nvar NoContext =\n/*                    */\n0;\nvar BatchedContext =\n/*               */\n1;\nvar EventContext =\n/*                 */\n2;\nvar DiscreteEventContext =\n/*         */\n4;\nvar LegacyUnbatchedContext =\n/*       */\n8;\nvar RenderContext =\n/*                */\n16;\nvar CommitContext =\n/*                */\n32;\nvar RootIncomplete = 0;\nvar RootFatalErrored = 1;\nvar RootErrored = 2;\nvar RootSuspended = 3;\nvar RootSuspendedWithDelay = 4;\nvar RootCompleted = 5;\n// Describes where we are in the React execution stack\nvar executionContext = NoContext; // The root we're working on\n\nvar workInProgressRoot = null; // The fiber we're working on\n\nvar workInProgress = null; // The expiration time we're rendering\n\nvar renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.\n\nvar workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown\n\nvar workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.\n// This is conceptually a time stamp but expressed in terms of an ExpirationTime\n// because we deal mostly with expiration times in the hot path, so this avoids\n// the conversion happening in the hot path.\n\nvar workInProgressRootLatestProcessedExpirationTime = Sync;\nvar workInProgressRootLatestSuspenseTimeout = Sync;\nvar workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only\n// includes unprocessed updates, not work in bailed out children.\n\nvar workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.\n// This flag determines if it might be worthwhile to restart if an opportunity\n// happens latere.\n\nvar workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train\n// model where we don't commit new loading states in too quick succession.\n\nvar globalMostRecentFallbackTime = 0;\nvar FALLBACK_THROTTLE_MS = 500;\nvar nextEffect = null;\nvar hasUncaughtError = false;\nvar firstUncaughtError = null;\nvar legacyErrorBoundariesThatAlreadyFailed = null;\nvar rootDoesHavePassiveEffects = false;\nvar rootWithPendingPassiveEffects = null;\nvar pendingPassiveEffectsRenderPriority = NoPriority;\nvar pendingPassiveEffectsExpirationTime = NoWork;\nvar rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates\n\nvar NESTED_UPDATE_LIMIT = 50;\nvar nestedUpdateCount = 0;\nvar rootWithNestedUpdates = null;\nvar NESTED_PASSIVE_UPDATE_LIMIT = 50;\nvar nestedPassiveUpdateCount = 0;\nvar interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times\n// during the commit phase. This enables them to be traced across components\n// that spawn new work during render. E.g. hidden boundaries, suspended SSR\n// hydration or SuspenseList.\n\nvar spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start\n// time). However, if two updates are scheduled within the same event, we\n// should treat their start times as simultaneous, even if the actual clock\n// time has advanced between the first and second call.\n// In other words, because expiration times determine how updates are batched,\n// we want all updates of like priority that occur within the same event to\n// receive the same expiration time. Otherwise we get tearing.\n\nvar currentEventTime = NoWork;\nfunction requestCurrentTimeForUpdate() {\n  if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {\n    // We're inside React, so it's fine to read the actual time.\n    return msToExpirationTime(now());\n  } // We're not inside React, so we may be in the middle of a browser event.\n\n\n  if (currentEventTime !== NoWork) {\n    // Use the same start time for all updates until we enter React again.\n    return currentEventTime;\n  } // This is the first update since React yielded. Compute a new start time.\n\n\n  currentEventTime = msToExpirationTime(now());\n  return currentEventTime;\n}\nfunction getCurrentTime() {\n  return msToExpirationTime(now());\n}\nfunction computeExpirationForFiber(currentTime, fiber, suspenseConfig) {\n  var mode = fiber.mode;\n\n  if ((mode & BlockingMode) === NoMode) {\n    return Sync;\n  }\n\n  var priorityLevel = getCurrentPriorityLevel();\n\n  if ((mode & ConcurrentMode) === NoMode) {\n    return priorityLevel === ImmediatePriority ? Sync : Batched;\n  }\n\n  if ((executionContext & RenderContext) !== NoContext) {\n    // Use whatever time we're already rendering\n    // TODO: Should there be a way to opt out, like with `runWithPriority`?\n    return renderExpirationTime$1;\n  }\n\n  var expirationTime;\n\n  if (suspenseConfig !== null) {\n    // Compute an expiration time based on the Suspense timeout.\n    expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);\n  } else {\n    // Compute an expiration time based on the Scheduler priority.\n    switch (priorityLevel) {\n      case ImmediatePriority:\n        expirationTime = Sync;\n        break;\n\n      case UserBlockingPriority$1:\n        // TODO: Rename this to computeUserBlockingExpiration\n        expirationTime = computeInteractiveExpiration(currentTime);\n        break;\n\n      case NormalPriority:\n      case LowPriority:\n        // TODO: Handle LowPriority\n        // TODO: Rename this to... something better.\n        expirationTime = computeAsyncExpiration(currentTime);\n        break;\n\n      case IdlePriority:\n        expirationTime = Idle;\n        break;\n\n      default:\n        {\n          {\n            throw Error( \"Expected a valid priority level\" );\n          }\n        }\n\n    }\n  } // If we're in the middle of rendering a tree, do not update at the same\n  // expiration time that is already rendering.\n  // TODO: We shouldn't have to do this if the update is on a different root.\n  // Refactor computeExpirationForFiber + scheduleUpdate so we have access to\n  // the root when we check for this condition.\n\n\n  if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {\n    // This is a trick to move this update into a separate batch\n    expirationTime -= 1;\n  }\n\n  return expirationTime;\n}\nfunction scheduleUpdateOnFiber(fiber, expirationTime) {\n  checkForNestedUpdates();\n  warnAboutRenderPhaseUpdatesInDEV(fiber);\n  var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);\n\n  if (root === null) {\n    warnAboutUpdateOnUnmountedFiberInDEV(fiber);\n    return;\n  }\n\n  checkForInterruption(fiber, expirationTime);\n  recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the\n  // priority as an argument to that function and this one.\n\n  var priorityLevel = getCurrentPriorityLevel();\n\n  if (expirationTime === Sync) {\n    if ( // Check if we're inside unbatchedUpdates\n    (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering\n    (executionContext & (RenderContext | CommitContext)) === NoContext) {\n      // Register pending interactions on the root to avoid losing traced interaction data.\n      schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed\n      // root inside of batchedUpdates should be synchronous, but layout updates\n      // should be deferred until the end of the batch.\n\n      performSyncWorkOnRoot(root);\n    } else {\n      ensureRootIsScheduled(root);\n      schedulePendingInteractions(root, expirationTime);\n\n      if (executionContext === NoContext) {\n        // Flush the synchronous work now, unless we're already working or inside\n        // a batch. This is intentionally inside scheduleUpdateOnFiber instead of\n        // scheduleCallbackForFiber to preserve the ability to schedule a callback\n        // without immediately flushing it. We only do this for user-initiated\n        // updates, to preserve historical behavior of legacy mode.\n        flushSyncCallbackQueue();\n      }\n    }\n  } else {\n    ensureRootIsScheduled(root);\n    schedulePendingInteractions(root, expirationTime);\n  }\n\n  if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered\n  // discrete, even inside a discrete event.\n  priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority)) {\n    // This is the result of a discrete event. Track the lowest priority\n    // discrete update per root so we can flush them early, if needed.\n    if (rootsWithPendingDiscreteUpdates === null) {\n      rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);\n    } else {\n      var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);\n\n      if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {\n        rootsWithPendingDiscreteUpdates.set(root, expirationTime);\n      }\n    }\n  }\n}\nvar scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending\n// work without treating it as a typical update that originates from an event;\n// e.g. retrying a Suspense boundary isn't an update, but it does schedule work\n// on a fiber.\n\nfunction markUpdateTimeFromFiberToRoot(fiber, expirationTime) {\n  // Update the source fiber's expiration time\n  if (fiber.expirationTime < expirationTime) {\n    fiber.expirationTime = expirationTime;\n  }\n\n  var alternate = fiber.alternate;\n\n  if (alternate !== null && alternate.expirationTime < expirationTime) {\n    alternate.expirationTime = expirationTime;\n  } // Walk the parent path to the root and update the child expiration time.\n\n\n  var node = fiber.return;\n  var root = null;\n\n  if (node === null && fiber.tag === HostRoot) {\n    root = fiber.stateNode;\n  } else {\n    while (node !== null) {\n      alternate = node.alternate;\n\n      if (node.childExpirationTime < expirationTime) {\n        node.childExpirationTime = expirationTime;\n\n        if (alternate !== null && alternate.childExpirationTime < expirationTime) {\n          alternate.childExpirationTime = expirationTime;\n        }\n      } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {\n        alternate.childExpirationTime = expirationTime;\n      }\n\n      if (node.return === null && node.tag === HostRoot) {\n        root = node.stateNode;\n        break;\n      }\n\n      node = node.return;\n    }\n  }\n\n  if (root !== null) {\n    if (workInProgressRoot === root) {\n      // Received an update to a tree that's in the middle of rendering. Mark\n      // that's unprocessed work on this root.\n      markUnprocessedUpdateTime(expirationTime);\n\n      if (workInProgressRootExitStatus === RootSuspendedWithDelay) {\n        // The root already suspended with a delay, which means this render\n        // definitely won't finish. Since we have a new update, let's mark it as\n        // suspended now, right before marking the incoming update. This has the\n        // effect of interrupting the current render and switching to the update.\n        // TODO: This happens to work when receiving an update during the render\n        // phase, because of the trick inside computeExpirationForFiber to\n        // subtract 1 from `renderExpirationTime` to move it into a\n        // separate bucket. But we should probably model it with an exception,\n        // using the same mechanism we use to force hydration of a subtree.\n        // TODO: This does not account for low pri updates that were already\n        // scheduled before the root started rendering. Need to track the next\n        // pending expiration time (perhaps by backtracking the return path) and\n        // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.\n        markRootSuspendedAtTime(root, renderExpirationTime$1);\n      }\n    } // Mark that the root has a pending update.\n\n\n    markRootUpdatedAtTime(root, expirationTime);\n  }\n\n  return root;\n}\n\nfunction getNextRootExpirationTimeToWorkOn(root) {\n  // Determines the next expiration time that the root should render, taking\n  // into account levels that may be suspended, or levels that may have\n  // received a ping.\n  var lastExpiredTime = root.lastExpiredTime;\n\n  if (lastExpiredTime !== NoWork) {\n    return lastExpiredTime;\n  } // \"Pending\" refers to any update that hasn't committed yet, including if it\n  // suspended. The \"suspended\" range is therefore a subset.\n\n\n  var firstPendingTime = root.firstPendingTime;\n\n  if (!isRootSuspendedAtTime(root, firstPendingTime)) {\n    // The highest priority pending time is not suspended. Let's work on that.\n    return firstPendingTime;\n  } // If the first pending time is suspended, check if there's a lower priority\n  // pending level that we know about. Or check if we received a ping. Work\n  // on whichever is higher priority.\n\n\n  var lastPingedTime = root.lastPingedTime;\n  var nextKnownPendingLevel = root.nextKnownPendingLevel;\n  var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;\n\n  if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {\n    // Don't work on Idle/Never priority unless everything else is committed.\n    return NoWork;\n  }\n\n  return nextLevel;\n} // Use this function to schedule a task for a root. There's only one task per\n// root; if a task was already scheduled, we'll check to make sure the\n// expiration time of the existing task is the same as the expiration time of\n// the next level that the root has work on. This function is called on every\n// update, and right before exiting a task.\n\n\nfunction ensureRootIsScheduled(root) {\n  var lastExpiredTime = root.lastExpiredTime;\n\n  if (lastExpiredTime !== NoWork) {\n    // Special case: Expired work should flush synchronously.\n    root.callbackExpirationTime = Sync;\n    root.callbackPriority = ImmediatePriority;\n    root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));\n    return;\n  }\n\n  var expirationTime = getNextRootExpirationTimeToWorkOn(root);\n  var existingCallbackNode = root.callbackNode;\n\n  if (expirationTime === NoWork) {\n    // There's nothing to work on.\n    if (existingCallbackNode !== null) {\n      root.callbackNode = null;\n      root.callbackExpirationTime = NoWork;\n      root.callbackPriority = NoPriority;\n    }\n\n    return;\n  } // TODO: If this is an update, we already read the current time. Pass the\n  // time as an argument.\n\n\n  var currentTime = requestCurrentTimeForUpdate();\n  var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and\n  // expiration time. Otherwise, we'll cancel it and schedule a new one.\n\n  if (existingCallbackNode !== null) {\n    var existingCallbackPriority = root.callbackPriority;\n    var existingCallbackExpirationTime = root.callbackExpirationTime;\n\n    if ( // Callback must have the exact same expiration time.\n    existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.\n    existingCallbackPriority >= priorityLevel) {\n      // Existing callback is sufficient.\n      return;\n    } // Need to schedule a new task.\n    // TODO: Instead of scheduling a new task, we should be able to change the\n    // priority of the existing one.\n\n\n    cancelCallback(existingCallbackNode);\n  }\n\n  root.callbackExpirationTime = expirationTime;\n  root.callbackPriority = priorityLevel;\n  var callbackNode;\n\n  if (expirationTime === Sync) {\n    // Sync React callbacks are scheduled on a special internal queue\n    callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));\n  } else {\n    callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects\n    // ordering because tasks are processed in timeout order.\n    {\n      timeout: expirationTimeToMs(expirationTime) - now()\n    });\n  }\n\n  root.callbackNode = callbackNode;\n} // This is the entry point for every concurrent task, i.e. anything that\n// goes through Scheduler.\n\n\nfunction performConcurrentWorkOnRoot(root, didTimeout) {\n  // Since we know we're in a React event, we can clear the current\n  // event time. The next update will compute a new event time.\n  currentEventTime = NoWork;\n\n  if (didTimeout) {\n    // The render task took too long to complete. Mark the current time as\n    // expired to synchronously render all expired work in a single batch.\n    var currentTime = requestCurrentTimeForUpdate();\n    markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.\n\n    ensureRootIsScheduled(root);\n    return null;\n  } // Determine the next expiration time to work on, using the fields stored\n  // on the root.\n\n\n  var expirationTime = getNextRootExpirationTimeToWorkOn(root);\n\n  if (expirationTime !== NoWork) {\n    var originalCallbackNode = root.callbackNode;\n\n    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {\n      {\n        throw Error( \"Should not already be working.\" );\n      }\n    }\n\n    flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack\n    // and prepare a fresh one. Otherwise we'll continue where we left off.\n\n    if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {\n      prepareFreshStack(root, expirationTime);\n      startWorkOnPendingInteractions(root, expirationTime);\n    } // If we have a work-in-progress fiber, it means there's still work to do\n    // in this root.\n\n\n    if (workInProgress !== null) {\n      var prevExecutionContext = executionContext;\n      executionContext |= RenderContext;\n      var prevDispatcher = pushDispatcher();\n      var prevInteractions = pushInteractions(root);\n      startWorkLoopTimer(workInProgress);\n\n      do {\n        try {\n          workLoopConcurrent();\n          break;\n        } catch (thrownValue) {\n          handleError(root, thrownValue);\n        }\n      } while (true);\n\n      resetContextDependencies();\n      executionContext = prevExecutionContext;\n      popDispatcher(prevDispatcher);\n\n      {\n        popInteractions(prevInteractions);\n      }\n\n      if (workInProgressRootExitStatus === RootFatalErrored) {\n        var fatalError = workInProgressRootFatalError;\n        stopInterruptedWorkLoopTimer();\n        prepareFreshStack(root, expirationTime);\n        markRootSuspendedAtTime(root, expirationTime);\n        ensureRootIsScheduled(root);\n        throw fatalError;\n      }\n\n      if (workInProgress !== null) {\n        // There's still work left over. Exit without committing.\n        stopInterruptedWorkLoopTimer();\n      } else {\n        // We now have a consistent tree. The next step is either to commit it,\n        // or, if something suspended, wait to commit it after a timeout.\n        stopFinishedWorkLoopTimer();\n        var finishedWork = root.finishedWork = root.current.alternate;\n        root.finishedExpirationTime = expirationTime;\n        finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);\n      }\n\n      ensureRootIsScheduled(root);\n\n      if (root.callbackNode === originalCallbackNode) {\n        // The task node scheduled for this root is the same one that's\n        // currently executed. Need to return a continuation.\n        return performConcurrentWorkOnRoot.bind(null, root);\n      }\n    }\n  }\n\n  return null;\n}\n\nfunction finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {\n  // Set this to null to indicate there's no in-progress render.\n  workInProgressRoot = null;\n\n  switch (exitStatus) {\n    case RootIncomplete:\n    case RootFatalErrored:\n      {\n        {\n          {\n            throw Error( \"Root did not complete. This is a bug in React.\" );\n          }\n        }\n      }\n    // Flow knows about invariant, so it complains if I add a break\n    // statement, but eslint doesn't know about invariant, so it complains\n    // if I do. eslint-disable-next-line no-fallthrough\n\n    case RootErrored:\n      {\n        // If this was an async render, the error may have happened due to\n        // a mutation in a concurrent event. Try rendering one more time,\n        // synchronously, to see if the error goes away. If there are\n        // lower priority updates, let's include those, too, in case they\n        // fix the inconsistency. Render at Idle to include all updates.\n        // If it was Idle or Never or some not-yet-invented time, render\n        // at that time.\n        markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous\n        // and therefore not hit this path again.\n\n        break;\n      }\n\n    case RootSuspended:\n      {\n        markRootSuspendedAtTime(root, expirationTime);\n        var lastSuspendedTime = root.lastSuspendedTime;\n\n        if (expirationTime === lastSuspendedTime) {\n          root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);\n        } // We have an acceptable loading state. We need to figure out if we\n        // should immediately commit it or wait a bit.\n        // If we have processed new updates during this render, we may now\n        // have a new loading state ready. We want to ensure that we commit\n        // that as soon as possible.\n\n\n        var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;\n\n        if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope\n        !( IsThisRendererActing.current)) {\n          // If we have not processed any new updates during this pass, then\n          // this is either a retry of an existing fallback state or a\n          // hidden tree. Hidden trees shouldn't be batched with other work\n          // and after that's fixed it can only be a retry. We're going to\n          // throttle committing retries so that we don't show too many\n          // loading states too quickly.\n          var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.\n\n          if (msUntilTimeout > 10) {\n            if (workInProgressRootHasPendingPing) {\n              var lastPingedTime = root.lastPingedTime;\n\n              if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {\n                // This render was pinged but we didn't get to restart\n                // earlier so try restarting now instead.\n                root.lastPingedTime = expirationTime;\n                prepareFreshStack(root, expirationTime);\n                break;\n              }\n            }\n\n            var nextTime = getNextRootExpirationTimeToWorkOn(root);\n\n            if (nextTime !== NoWork && nextTime !== expirationTime) {\n              // There's additional work on this root.\n              break;\n            }\n\n            if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {\n              // We should prefer to render the fallback of at the last\n              // suspended level. Ping the last suspended level to try\n              // rendering it again.\n              root.lastPingedTime = lastSuspendedTime;\n              break;\n            } // The render is suspended, it hasn't timed out, and there's no\n            // lower priority work to do. Instead of committing the fallback\n            // immediately, wait for more data to arrive.\n\n\n            root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);\n            break;\n          }\n        } // The work expired. Commit immediately.\n\n\n        commitRoot(root);\n        break;\n      }\n\n    case RootSuspendedWithDelay:\n      {\n        markRootSuspendedAtTime(root, expirationTime);\n        var _lastSuspendedTime = root.lastSuspendedTime;\n\n        if (expirationTime === _lastSuspendedTime) {\n          root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);\n        }\n\n        if ( // do not delay if we're inside an act() scope\n        !( IsThisRendererActing.current)) {\n          // We're suspended in a state that should be avoided. We'll try to\n          // avoid committing it for as long as the timeouts let us.\n          if (workInProgressRootHasPendingPing) {\n            var _lastPingedTime = root.lastPingedTime;\n\n            if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {\n              // This render was pinged but we didn't get to restart earlier\n              // so try restarting now instead.\n              root.lastPingedTime = expirationTime;\n              prepareFreshStack(root, expirationTime);\n              break;\n            }\n          }\n\n          var _nextTime = getNextRootExpirationTimeToWorkOn(root);\n\n          if (_nextTime !== NoWork && _nextTime !== expirationTime) {\n            // There's additional work on this root.\n            break;\n          }\n\n          if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {\n            // We should prefer to render the fallback of at the last\n            // suspended level. Ping the last suspended level to try\n            // rendering it again.\n            root.lastPingedTime = _lastSuspendedTime;\n            break;\n          }\n\n          var _msUntilTimeout;\n\n          if (workInProgressRootLatestSuspenseTimeout !== Sync) {\n            // We have processed a suspense config whose expiration time we\n            // can use as the timeout.\n            _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();\n          } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {\n            // This should never normally happen because only new updates\n            // cause delayed states, so we should have processed something.\n            // However, this could also happen in an offscreen tree.\n            _msUntilTimeout = 0;\n          } else {\n            // If we don't have a suspense config, we're going to use a\n            // heuristic to determine how long we can suspend.\n            var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);\n            var currentTimeMs = now();\n            var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;\n            var timeElapsed = currentTimeMs - eventTimeMs;\n\n            if (timeElapsed < 0) {\n              // We get this wrong some time since we estimate the time.\n              timeElapsed = 0;\n            }\n\n            _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the\n            // event time is exact instead of inferred from expiration time\n            // we don't need this.\n\n            if (timeUntilExpirationMs < _msUntilTimeout) {\n              _msUntilTimeout = timeUntilExpirationMs;\n            }\n          } // Don't bother with a very short suspense time.\n\n\n          if (_msUntilTimeout > 10) {\n            // The render is suspended, it hasn't timed out, and there's no\n            // lower priority work to do. Instead of committing the fallback\n            // immediately, wait for more data to arrive.\n            root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);\n            break;\n          }\n        } // The work expired. Commit immediately.\n\n\n        commitRoot(root);\n        break;\n      }\n\n    case RootCompleted:\n      {\n        // The work completed. Ready to commit.\n        if ( // do not delay if we're inside an act() scope\n        !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {\n          // If we have exceeded the minimum loading delay, which probably\n          // means we have shown a spinner already, we might have to suspend\n          // a bit longer to ensure that the spinner is shown for\n          // enough time.\n          var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);\n\n          if (_msUntilTimeout2 > 10) {\n            markRootSuspendedAtTime(root, expirationTime);\n            root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);\n            break;\n          }\n        }\n\n        commitRoot(root);\n        break;\n      }\n\n    default:\n      {\n        {\n          {\n            throw Error( \"Unknown root exit status.\" );\n          }\n        }\n      }\n  }\n} // This is the entry point for synchronous tasks that don't go\n// through Scheduler\n\n\nfunction performSyncWorkOnRoot(root) {\n  // Check if there's expired work on this root. Otherwise, render at Sync.\n  var lastExpiredTime = root.lastExpiredTime;\n  var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;\n\n  if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {\n    {\n      throw Error( \"Should not already be working.\" );\n    }\n  }\n\n  flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack\n  // and prepare a fresh one. Otherwise we'll continue where we left off.\n\n  if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {\n    prepareFreshStack(root, expirationTime);\n    startWorkOnPendingInteractions(root, expirationTime);\n  } // If we have a work-in-progress fiber, it means there's still work to do\n  // in this root.\n\n\n  if (workInProgress !== null) {\n    var prevExecutionContext = executionContext;\n    executionContext |= RenderContext;\n    var prevDispatcher = pushDispatcher();\n    var prevInteractions = pushInteractions(root);\n    startWorkLoopTimer(workInProgress);\n\n    do {\n      try {\n        workLoopSync();\n        break;\n      } catch (thrownValue) {\n        handleError(root, thrownValue);\n      }\n    } while (true);\n\n    resetContextDependencies();\n    executionContext = prevExecutionContext;\n    popDispatcher(prevDispatcher);\n\n    {\n      popInteractions(prevInteractions);\n    }\n\n    if (workInProgressRootExitStatus === RootFatalErrored) {\n      var fatalError = workInProgressRootFatalError;\n      stopInterruptedWorkLoopTimer();\n      prepareFreshStack(root, expirationTime);\n      markRootSuspendedAtTime(root, expirationTime);\n      ensureRootIsScheduled(root);\n      throw fatalError;\n    }\n\n    if (workInProgress !== null) {\n      // This is a sync render, so we should have finished the whole tree.\n      {\n        {\n          throw Error( \"Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.\" );\n        }\n      }\n    } else {\n      // We now have a consistent tree. Because this is a sync render, we\n      // will commit it even if something suspended.\n      stopFinishedWorkLoopTimer();\n      root.finishedWork = root.current.alternate;\n      root.finishedExpirationTime = expirationTime;\n      finishSyncRender(root);\n    } // Before exiting, make sure there's a callback scheduled for the next\n    // pending level.\n\n\n    ensureRootIsScheduled(root);\n  }\n\n  return null;\n}\n\nfunction finishSyncRender(root) {\n  // Set this to null to indicate there's no in-progress render.\n  workInProgressRoot = null;\n  commitRoot(root);\n}\nfunction flushDiscreteUpdates() {\n  // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.\n  // However, `act` uses `batchedUpdates`, so there's no way to distinguish\n  // those two cases. Need to fix this before exposing flushDiscreteUpdates\n  // as a public API.\n  if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {\n    {\n      if ((executionContext & RenderContext) !== NoContext) {\n        error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');\n      }\n    } // We're already rendering, so we can't synchronously flush pending work.\n    // This is probably a nested event dispatch triggered by a lifecycle/effect,\n    // like `el.focus()`. Exit.\n\n\n    return;\n  }\n\n  flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that\n  // they fire before the next serial event.\n\n  flushPassiveEffects();\n}\nfunction syncUpdates(fn, a, b, c) {\n  return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c));\n}\n\nfunction flushPendingDiscreteUpdates() {\n  if (rootsWithPendingDiscreteUpdates !== null) {\n    // For each root with pending discrete updates, schedule a callback to\n    // immediately flush them.\n    var roots = rootsWithPendingDiscreteUpdates;\n    rootsWithPendingDiscreteUpdates = null;\n    roots.forEach(function (expirationTime, root) {\n      markRootExpiredAtTime(root, expirationTime);\n      ensureRootIsScheduled(root);\n    }); // Now flush the immediate queue.\n\n    flushSyncCallbackQueue();\n  }\n}\n\nfunction batchedUpdates$1(fn, a) {\n  var prevExecutionContext = executionContext;\n  executionContext |= BatchedContext;\n\n  try {\n    return fn(a);\n  } finally {\n    executionContext = prevExecutionContext;\n\n    if (executionContext === NoContext) {\n      // Flush the immediate callbacks that were scheduled during this batch\n      flushSyncCallbackQueue();\n    }\n  }\n}\nfunction batchedEventUpdates$1(fn, a) {\n  var prevExecutionContext = executionContext;\n  executionContext |= EventContext;\n\n  try {\n    return fn(a);\n  } finally {\n    executionContext = prevExecutionContext;\n\n    if (executionContext === NoContext) {\n      // Flush the immediate callbacks that were scheduled during this batch\n      flushSyncCallbackQueue();\n    }\n  }\n}\nfunction discreteUpdates$1(fn, a, b, c, d) {\n  var prevExecutionContext = executionContext;\n  executionContext |= DiscreteEventContext;\n\n  try {\n    // Should this\n    return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c, d));\n  } finally {\n    executionContext = prevExecutionContext;\n\n    if (executionContext === NoContext) {\n      // Flush the immediate callbacks that were scheduled during this batch\n      flushSyncCallbackQueue();\n    }\n  }\n}\nfunction unbatchedUpdates(fn, a) {\n  var prevExecutionContext = executionContext;\n  executionContext &= ~BatchedContext;\n  executionContext |= LegacyUnbatchedContext;\n\n  try {\n    return fn(a);\n  } finally {\n    executionContext = prevExecutionContext;\n\n    if (executionContext === NoContext) {\n      // Flush the immediate callbacks that were scheduled during this batch\n      flushSyncCallbackQueue();\n    }\n  }\n}\nfunction flushSync(fn, a) {\n  if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {\n    {\n      {\n        throw Error( \"flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.\" );\n      }\n    }\n  }\n\n  var prevExecutionContext = executionContext;\n  executionContext |= BatchedContext;\n\n  try {\n    return runWithPriority$1(ImmediatePriority, fn.bind(null, a));\n  } finally {\n    executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.\n    // Note that this will happen even if batchedUpdates is higher up\n    // the stack.\n\n    flushSyncCallbackQueue();\n  }\n}\n\nfunction prepareFreshStack(root, expirationTime) {\n  root.finishedWork = null;\n  root.finishedExpirationTime = NoWork;\n  var timeoutHandle = root.timeoutHandle;\n\n  if (timeoutHandle !== noTimeout) {\n    // The root previous suspended and scheduled a timeout to commit a fallback\n    // state. Now that we have additional work, cancel the timeout.\n    root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above\n\n    cancelTimeout(timeoutHandle);\n  }\n\n  if (workInProgress !== null) {\n    var interruptedWork = workInProgress.return;\n\n    while (interruptedWork !== null) {\n      unwindInterruptedWork(interruptedWork);\n      interruptedWork = interruptedWork.return;\n    }\n  }\n\n  workInProgressRoot = root;\n  workInProgress = createWorkInProgress(root.current, null);\n  renderExpirationTime$1 = expirationTime;\n  workInProgressRootExitStatus = RootIncomplete;\n  workInProgressRootFatalError = null;\n  workInProgressRootLatestProcessedExpirationTime = Sync;\n  workInProgressRootLatestSuspenseTimeout = Sync;\n  workInProgressRootCanSuspendUsingConfig = null;\n  workInProgressRootNextUnprocessedUpdateTime = NoWork;\n  workInProgressRootHasPendingPing = false;\n\n  {\n    spawnedWorkDuringRender = null;\n  }\n\n  {\n    ReactStrictModeWarnings.discardPendingWarnings();\n  }\n}\n\nfunction handleError(root, thrownValue) {\n  do {\n    try {\n      // Reset module-level state that was set during the render phase.\n      resetContextDependencies();\n      resetHooksAfterThrow();\n      resetCurrentFiber();\n\n      if (workInProgress === null || workInProgress.return === null) {\n        // Expected to be working on a non-root fiber. This is a fatal error\n        // because there's no ancestor that can handle it; the root is\n        // supposed to capture all errors that weren't caught by an error\n        // boundary.\n        workInProgressRootExitStatus = RootFatalErrored;\n        workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next\n        // sibling, or the parent if there are no siblings. But since the root\n        // has no siblings nor a parent, we set it to null. Usually this is\n        // handled by `completeUnitOfWork` or `unwindWork`, but since we're\n        // interntionally not calling those, we need set it here.\n        // TODO: Consider calling `unwindWork` to pop the contexts.\n\n        workInProgress = null;\n        return null;\n      }\n\n      if (enableProfilerTimer && workInProgress.mode & ProfileMode) {\n        // Record the time spent rendering before an error was thrown. This\n        // avoids inaccurate Profiler durations in the case of a\n        // suspended render.\n        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);\n      }\n\n      throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);\n      workInProgress = completeUnitOfWork(workInProgress);\n    } catch (yetAnotherThrownValue) {\n      // Something in the return path also threw.\n      thrownValue = yetAnotherThrownValue;\n      continue;\n    } // Return to the normal work loop.\n\n\n    return;\n  } while (true);\n}\n\nfunction pushDispatcher(root) {\n  var prevDispatcher = ReactCurrentDispatcher$1.current;\n  ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;\n\n  if (prevDispatcher === null) {\n    // The React isomorphic package does not include a default dispatcher.\n    // Instead the first renderer will lazily attach one, in order to give\n    // nicer error messages.\n    return ContextOnlyDispatcher;\n  } else {\n    return prevDispatcher;\n  }\n}\n\nfunction popDispatcher(prevDispatcher) {\n  ReactCurrentDispatcher$1.current = prevDispatcher;\n}\n\nfunction pushInteractions(root) {\n  {\n    var prevInteractions = tracing.__interactionsRef.current;\n    tracing.__interactionsRef.current = root.memoizedInteractions;\n    return prevInteractions;\n  }\n}\n\nfunction popInteractions(prevInteractions) {\n  {\n    tracing.__interactionsRef.current = prevInteractions;\n  }\n}\n\nfunction markCommitTimeOfFallback() {\n  globalMostRecentFallbackTime = now();\n}\nfunction markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {\n  if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {\n    workInProgressRootLatestProcessedExpirationTime = expirationTime;\n  }\n\n  if (suspenseConfig !== null) {\n    if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {\n      workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.\n\n      workInProgressRootCanSuspendUsingConfig = suspenseConfig;\n    }\n  }\n}\nfunction markUnprocessedUpdateTime(expirationTime) {\n  if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {\n    workInProgressRootNextUnprocessedUpdateTime = expirationTime;\n  }\n}\nfunction renderDidSuspend() {\n  if (workInProgressRootExitStatus === RootIncomplete) {\n    workInProgressRootExitStatus = RootSuspended;\n  }\n}\nfunction renderDidSuspendDelayIfPossible() {\n  if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {\n    workInProgressRootExitStatus = RootSuspendedWithDelay;\n  } // Check if there's a lower priority update somewhere else in the tree.\n\n\n  if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {\n    // Mark the current render as suspended, and then mark that there's a\n    // pending update.\n    // TODO: This should immediately interrupt the current render, instead\n    // of waiting until the next time we yield.\n    markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);\n    markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);\n  }\n}\nfunction renderDidError() {\n  if (workInProgressRootExitStatus !== RootCompleted) {\n    workInProgressRootExitStatus = RootErrored;\n  }\n} // Called during render to determine if anything has suspended.\n// Returns false if we're not sure.\n\nfunction renderHasNotSuspendedYet() {\n  // If something errored or completed, we can't really be sure,\n  // so those are false.\n  return workInProgressRootExitStatus === RootIncomplete;\n}\n\nfunction inferTimeFromExpirationTime(expirationTime) {\n  // We don't know exactly when the update was scheduled, but we can infer an\n  // approximate start time from the expiration time.\n  var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);\n  return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;\n}\n\nfunction inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {\n  // We don't know exactly when the update was scheduled, but we can infer an\n  // approximate start time from the expiration time by subtracting the timeout\n  // that was added to the event time.\n  var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);\n  return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);\n} // The work loop is an extremely hot path. Tell Closure not to inline it.\n\n/** @noinline */\n\n\nfunction workLoopSync() {\n  // Already timed out, so perform work without checking if we need to yield.\n  while (workInProgress !== null) {\n    workInProgress = performUnitOfWork(workInProgress);\n  }\n}\n/** @noinline */\n\n\nfunction workLoopConcurrent() {\n  // Perform work until Scheduler asks us to yield\n  while (workInProgress !== null && !shouldYield()) {\n    workInProgress = performUnitOfWork(workInProgress);\n  }\n}\n\nfunction performUnitOfWork(unitOfWork) {\n  // The current, flushed, state of this fiber is the alternate. Ideally\n  // nothing should rely on this, but relying on it here means that we don't\n  // need an additional field on the work in progress.\n  var current = unitOfWork.alternate;\n  startWorkTimer(unitOfWork);\n  setCurrentFiber(unitOfWork);\n  var next;\n\n  if ( (unitOfWork.mode & ProfileMode) !== NoMode) {\n    startProfilerTimer(unitOfWork);\n    next = beginWork$1(current, unitOfWork, renderExpirationTime$1);\n    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);\n  } else {\n    next = beginWork$1(current, unitOfWork, renderExpirationTime$1);\n  }\n\n  resetCurrentFiber();\n  unitOfWork.memoizedProps = unitOfWork.pendingProps;\n\n  if (next === null) {\n    // If this doesn't spawn new work, complete the current work.\n    next = completeUnitOfWork(unitOfWork);\n  }\n\n  ReactCurrentOwner$2.current = null;\n  return next;\n}\n\nfunction completeUnitOfWork(unitOfWork) {\n  // Attempt to complete the current unit of work, then move to the next\n  // sibling. If there are no more siblings, return to the parent fiber.\n  workInProgress = unitOfWork;\n\n  do {\n    // The current, flushed, state of this fiber is the alternate. Ideally\n    // nothing should rely on this, but relying on it here means that we don't\n    // need an additional field on the work in progress.\n    var current = workInProgress.alternate;\n    var returnFiber = workInProgress.return; // Check if the work completed or if something threw.\n\n    if ((workInProgress.effectTag & Incomplete) === NoEffect) {\n      setCurrentFiber(workInProgress);\n      var next = void 0;\n\n      if ( (workInProgress.mode & ProfileMode) === NoMode) {\n        next = completeWork(current, workInProgress, renderExpirationTime$1);\n      } else {\n        startProfilerTimer(workInProgress);\n        next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.\n\n        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);\n      }\n\n      stopWorkTimer(workInProgress);\n      resetCurrentFiber();\n      resetChildExpirationTime(workInProgress);\n\n      if (next !== null) {\n        // Completing this fiber spawned new work. Work on that next.\n        return next;\n      }\n\n      if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete\n      (returnFiber.effectTag & Incomplete) === NoEffect) {\n        // Append all the effects of the subtree and this fiber onto the effect\n        // list of the parent. The completion order of the children affects the\n        // side-effect order.\n        if (returnFiber.firstEffect === null) {\n          returnFiber.firstEffect = workInProgress.firstEffect;\n        }\n\n        if (workInProgress.lastEffect !== null) {\n          if (returnFiber.lastEffect !== null) {\n            returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;\n          }\n\n          returnFiber.lastEffect = workInProgress.lastEffect;\n        } // If this fiber had side-effects, we append it AFTER the children's\n        // side-effects. We can perform certain side-effects earlier if needed,\n        // by doing multiple passes over the effect list. We don't want to\n        // schedule our own side-effect on our own list because if end up\n        // reusing children we'll schedule this effect onto itself since we're\n        // at the end.\n\n\n        var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect\n        // list. PerformedWork effect is read by React DevTools but shouldn't be\n        // committed.\n\n        if (effectTag > PerformedWork) {\n          if (returnFiber.lastEffect !== null) {\n            returnFiber.lastEffect.nextEffect = workInProgress;\n          } else {\n            returnFiber.firstEffect = workInProgress;\n          }\n\n          returnFiber.lastEffect = workInProgress;\n        }\n      }\n    } else {\n      // This fiber did not complete because something threw. Pop values off\n      // the stack without entering the complete phase. If this is a boundary,\n      // capture values if possible.\n      var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.\n\n\n      if ( (workInProgress.mode & ProfileMode) !== NoMode) {\n        // Record the render duration for the fiber that errored.\n        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.\n\n        var actualDuration = workInProgress.actualDuration;\n        var child = workInProgress.child;\n\n        while (child !== null) {\n          actualDuration += child.actualDuration;\n          child = child.sibling;\n        }\n\n        workInProgress.actualDuration = actualDuration;\n      }\n\n      if (_next !== null) {\n        // If completing this work spawned new work, do that next. We'll come\n        // back here again.\n        // Since we're restarting, remove anything that is not a host effect\n        // from the effect tag.\n        // TODO: The name stopFailedWorkTimer is misleading because Suspense\n        // also captures and restarts.\n        stopFailedWorkTimer(workInProgress);\n        _next.effectTag &= HostEffectMask;\n        return _next;\n      }\n\n      stopWorkTimer(workInProgress);\n\n      if (returnFiber !== null) {\n        // Mark the parent fiber as incomplete and clear its effect list.\n        returnFiber.firstEffect = returnFiber.lastEffect = null;\n        returnFiber.effectTag |= Incomplete;\n      }\n    }\n\n    var siblingFiber = workInProgress.sibling;\n\n    if (siblingFiber !== null) {\n      // If there is more work to do in this returnFiber, do that next.\n      return siblingFiber;\n    } // Otherwise, return to the parent\n\n\n    workInProgress = returnFiber;\n  } while (workInProgress !== null); // We've reached the root.\n\n\n  if (workInProgressRootExitStatus === RootIncomplete) {\n    workInProgressRootExitStatus = RootCompleted;\n  }\n\n  return null;\n}\n\nfunction getRemainingExpirationTime(fiber) {\n  var updateExpirationTime = fiber.expirationTime;\n  var childExpirationTime = fiber.childExpirationTime;\n  return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;\n}\n\nfunction resetChildExpirationTime(completedWork) {\n  if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {\n    // The children of this component are hidden. Don't bubble their\n    // expiration times.\n    return;\n  }\n\n  var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.\n\n  if ( (completedWork.mode & ProfileMode) !== NoMode) {\n    // In profiling mode, resetChildExpirationTime is also used to reset\n    // profiler durations.\n    var actualDuration = completedWork.actualDuration;\n    var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will\n    // only be updated if work is done on the fiber (i.e. it doesn't bailout).\n    // When work is done, it should bubble to the parent's actualDuration. If\n    // the fiber has not been cloned though, (meaning no work was done), then\n    // this value will reflect the amount of time spent working on a previous\n    // render. In that case it should not bubble. We determine whether it was\n    // cloned by comparing the child pointer.\n\n    var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;\n    var child = completedWork.child;\n\n    while (child !== null) {\n      var childUpdateExpirationTime = child.expirationTime;\n      var childChildExpirationTime = child.childExpirationTime;\n\n      if (childUpdateExpirationTime > newChildExpirationTime) {\n        newChildExpirationTime = childUpdateExpirationTime;\n      }\n\n      if (childChildExpirationTime > newChildExpirationTime) {\n        newChildExpirationTime = childChildExpirationTime;\n      }\n\n      if (shouldBubbleActualDurations) {\n        actualDuration += child.actualDuration;\n      }\n\n      treeBaseDuration += child.treeBaseDuration;\n      child = child.sibling;\n    }\n\n    completedWork.actualDuration = actualDuration;\n    completedWork.treeBaseDuration = treeBaseDuration;\n  } else {\n    var _child = completedWork.child;\n\n    while (_child !== null) {\n      var _childUpdateExpirationTime = _child.expirationTime;\n      var _childChildExpirationTime = _child.childExpirationTime;\n\n      if (_childUpdateExpirationTime > newChildExpirationTime) {\n        newChildExpirationTime = _childUpdateExpirationTime;\n      }\n\n      if (_childChildExpirationTime > newChildExpirationTime) {\n        newChildExpirationTime = _childChildExpirationTime;\n      }\n\n      _child = _child.sibling;\n    }\n  }\n\n  completedWork.childExpirationTime = newChildExpirationTime;\n}\n\nfunction commitRoot(root) {\n  var renderPriorityLevel = getCurrentPriorityLevel();\n  runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));\n  return null;\n}\n\nfunction commitRootImpl(root, renderPriorityLevel) {\n  do {\n    // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which\n    // means `flushPassiveEffects` will sometimes result in additional\n    // passive effects. So we need to keep flushing in a loop until there are\n    // no more pending effects.\n    // TODO: Might be better if `flushPassiveEffects` did not automatically\n    // flush synchronous work at the end, to avoid factoring hazards like this.\n    flushPassiveEffects();\n  } while (rootWithPendingPassiveEffects !== null);\n\n  flushRenderPhaseStrictModeWarningsInDEV();\n\n  if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {\n    {\n      throw Error( \"Should not already be working.\" );\n    }\n  }\n\n  var finishedWork = root.finishedWork;\n  var expirationTime = root.finishedExpirationTime;\n\n  if (finishedWork === null) {\n    return null;\n  }\n\n  root.finishedWork = null;\n  root.finishedExpirationTime = NoWork;\n\n  if (!(finishedWork !== root.current)) {\n    {\n      throw Error( \"Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.\" );\n    }\n  } // commitRoot never returns a continuation; it always finishes synchronously.\n  // So we can clear these now to allow a new callback to be scheduled.\n\n\n  root.callbackNode = null;\n  root.callbackExpirationTime = NoWork;\n  root.callbackPriority = NoPriority;\n  root.nextKnownPendingLevel = NoWork;\n  startCommitTimer(); // Update the first and last pending times on this root. The new first\n  // pending time is whatever is left on the root fiber.\n\n  var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);\n  markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);\n\n  if (root === workInProgressRoot) {\n    // We can reset these now that they are finished.\n    workInProgressRoot = null;\n    workInProgress = null;\n    renderExpirationTime$1 = NoWork;\n  } // This indicates that the last root we worked on is not the same one that\n  // we're committing now. This most commonly happens when a suspended root\n  // times out.\n  // Get the list of effects.\n\n\n  var firstEffect;\n\n  if (finishedWork.effectTag > PerformedWork) {\n    // A fiber's effect list consists only of its children, not itself. So if\n    // the root has an effect, we need to add it to the end of the list. The\n    // resulting list is the set that would belong to the root's parent, if it\n    // had one; that is, all the effects in the tree including the root.\n    if (finishedWork.lastEffect !== null) {\n      finishedWork.lastEffect.nextEffect = finishedWork;\n      firstEffect = finishedWork.firstEffect;\n    } else {\n      firstEffect = finishedWork;\n    }\n  } else {\n    // There is no effect on the root.\n    firstEffect = finishedWork.firstEffect;\n  }\n\n  if (firstEffect !== null) {\n    var prevExecutionContext = executionContext;\n    executionContext |= CommitContext;\n    var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles\n\n    ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass\n    // of the effect list for each phase: all mutation effects come before all\n    // layout effects, and so on.\n    // The first phase a \"before mutation\" phase. We use this phase to read the\n    // state of the host tree right before we mutate it. This is where\n    // getSnapshotBeforeUpdate is called.\n\n    startCommitSnapshotEffectsTimer();\n    prepareForCommit(root.containerInfo);\n    nextEffect = firstEffect;\n\n    do {\n      {\n        invokeGuardedCallback(null, commitBeforeMutationEffects, null);\n\n        if (hasCaughtError()) {\n          if (!(nextEffect !== null)) {\n            {\n              throw Error( \"Should be working on an effect.\" );\n            }\n          }\n\n          var error = clearCaughtError();\n          captureCommitPhaseError(nextEffect, error);\n          nextEffect = nextEffect.nextEffect;\n        }\n      }\n    } while (nextEffect !== null);\n\n    stopCommitSnapshotEffectsTimer();\n\n    {\n      // Mark the current commit time to be shared by all Profilers in this\n      // batch. This enables them to be grouped later.\n      recordCommitTime();\n    } // The next phase is the mutation phase, where we mutate the host tree.\n\n\n    startCommitHostEffectsTimer();\n    nextEffect = firstEffect;\n\n    do {\n      {\n        invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);\n\n        if (hasCaughtError()) {\n          if (!(nextEffect !== null)) {\n            {\n              throw Error( \"Should be working on an effect.\" );\n            }\n          }\n\n          var _error = clearCaughtError();\n\n          captureCommitPhaseError(nextEffect, _error);\n          nextEffect = nextEffect.nextEffect;\n        }\n      }\n    } while (nextEffect !== null);\n\n    stopCommitHostEffectsTimer();\n    resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after\n    // the mutation phase, so that the previous tree is still current during\n    // componentWillUnmount, but before the layout phase, so that the finished\n    // work is current during componentDidMount/Update.\n\n    root.current = finishedWork; // The next phase is the layout phase, where we call effects that read\n    // the host tree after it's been mutated. The idiomatic use case for this is\n    // layout, but class component lifecycles also fire here for legacy reasons.\n\n    startCommitLifeCyclesTimer();\n    nextEffect = firstEffect;\n\n    do {\n      {\n        invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);\n\n        if (hasCaughtError()) {\n          if (!(nextEffect !== null)) {\n            {\n              throw Error( \"Should be working on an effect.\" );\n            }\n          }\n\n          var _error2 = clearCaughtError();\n\n          captureCommitPhaseError(nextEffect, _error2);\n          nextEffect = nextEffect.nextEffect;\n        }\n      }\n    } while (nextEffect !== null);\n\n    stopCommitLifeCyclesTimer();\n    nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an\n    // opportunity to paint.\n\n    requestPaint();\n\n    {\n      popInteractions(prevInteractions);\n    }\n\n    executionContext = prevExecutionContext;\n  } else {\n    // No effects.\n    root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were\n    // no effects.\n    // TODO: Maybe there's a better way to report this.\n\n    startCommitSnapshotEffectsTimer();\n    stopCommitSnapshotEffectsTimer();\n\n    {\n      recordCommitTime();\n    }\n\n    startCommitHostEffectsTimer();\n    stopCommitHostEffectsTimer();\n    startCommitLifeCyclesTimer();\n    stopCommitLifeCyclesTimer();\n  }\n\n  stopCommitTimer();\n  var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;\n\n  if (rootDoesHavePassiveEffects) {\n    // This commit has passive effects. Stash a reference to them. But don't\n    // schedule a callback until after flushing layout work.\n    rootDoesHavePassiveEffects = false;\n    rootWithPendingPassiveEffects = root;\n    pendingPassiveEffectsExpirationTime = expirationTime;\n    pendingPassiveEffectsRenderPriority = renderPriorityLevel;\n  } else {\n    // We are done with the effect chain at this point so let's clear the\n    // nextEffect pointers to assist with GC. If we have passive effects, we'll\n    // clear this in flushPassiveEffects.\n    nextEffect = firstEffect;\n\n    while (nextEffect !== null) {\n      var nextNextEffect = nextEffect.nextEffect;\n      nextEffect.nextEffect = null;\n      nextEffect = nextNextEffect;\n    }\n  } // Check if there's remaining work on this root\n\n\n  var remainingExpirationTime = root.firstPendingTime;\n\n  if (remainingExpirationTime !== NoWork) {\n    {\n      if (spawnedWorkDuringRender !== null) {\n        var expirationTimes = spawnedWorkDuringRender;\n        spawnedWorkDuringRender = null;\n\n        for (var i = 0; i < expirationTimes.length; i++) {\n          scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);\n        }\n      }\n\n      schedulePendingInteractions(root, remainingExpirationTime);\n    }\n  } else {\n    // If there's no remaining work, we can clear the set of already failed\n    // error boundaries.\n    legacyErrorBoundariesThatAlreadyFailed = null;\n  }\n\n  {\n    if (!rootDidHavePassiveEffects) {\n      // If there are no passive effects, then we can complete the pending interactions.\n      // Otherwise, we'll wait until after the passive effects are flushed.\n      // Wait to do this until after remaining work has been scheduled,\n      // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.\n      finishPendingInteractions(root, expirationTime);\n    }\n  }\n\n  if (remainingExpirationTime === Sync) {\n    // Count the number of times the root synchronously re-renders without\n    // finishing. If there are too many, it indicates an infinite update loop.\n    if (root === rootWithNestedUpdates) {\n      nestedUpdateCount++;\n    } else {\n      nestedUpdateCount = 0;\n      rootWithNestedUpdates = root;\n    }\n  } else {\n    nestedUpdateCount = 0;\n  }\n\n  onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any\n  // additional work on this root is scheduled.\n\n  ensureRootIsScheduled(root);\n\n  if (hasUncaughtError) {\n    hasUncaughtError = false;\n    var _error3 = firstUncaughtError;\n    firstUncaughtError = null;\n    throw _error3;\n  }\n\n  if ((executionContext & LegacyUnbatchedContext) !== NoContext) {\n    // This is a legacy edge case. We just committed the initial mount of\n    // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired\n    // synchronously, but layout updates should be deferred until the end\n    // of the batch.\n    return null;\n  } // If layout work was scheduled, flush it now.\n\n\n  flushSyncCallbackQueue();\n  return null;\n}\n\nfunction commitBeforeMutationEffects() {\n  while (nextEffect !== null) {\n    var effectTag = nextEffect.effectTag;\n\n    if ((effectTag & Snapshot) !== NoEffect) {\n      setCurrentFiber(nextEffect);\n      recordEffect();\n      var current = nextEffect.alternate;\n      commitBeforeMutationLifeCycles(current, nextEffect);\n      resetCurrentFiber();\n    }\n\n    if ((effectTag & Passive) !== NoEffect) {\n      // If there are passive effects, schedule a callback to flush at\n      // the earliest opportunity.\n      if (!rootDoesHavePassiveEffects) {\n        rootDoesHavePassiveEffects = true;\n        scheduleCallback(NormalPriority, function () {\n          flushPassiveEffects();\n          return null;\n        });\n      }\n    }\n\n    nextEffect = nextEffect.nextEffect;\n  }\n}\n\nfunction commitMutationEffects(root, renderPriorityLevel) {\n  // TODO: Should probably move the bulk of this function to commitWork.\n  while (nextEffect !== null) {\n    setCurrentFiber(nextEffect);\n    var effectTag = nextEffect.effectTag;\n\n    if (effectTag & ContentReset) {\n      commitResetTextContent(nextEffect);\n    }\n\n    if (effectTag & Ref) {\n      var current = nextEffect.alternate;\n\n      if (current !== null) {\n        commitDetachRef(current);\n      }\n    } // The following switch statement is only concerned about placement,\n    // updates, and deletions. To avoid needing to add a case for every possible\n    // bitmap value, we remove the secondary effects from the effect tag and\n    // switch on that value.\n\n\n    var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);\n\n    switch (primaryEffectTag) {\n      case Placement:\n        {\n          commitPlacement(nextEffect); // Clear the \"placement\" from effect tag so that we know that this is\n          // inserted, before any life-cycles like componentDidMount gets called.\n          // TODO: findDOMNode doesn't rely on this any more but isMounted does\n          // and isMounted is deprecated anyway so we should be able to kill this.\n\n          nextEffect.effectTag &= ~Placement;\n          break;\n        }\n\n      case PlacementAndUpdate:\n        {\n          // Placement\n          commitPlacement(nextEffect); // Clear the \"placement\" from effect tag so that we know that this is\n          // inserted, before any life-cycles like componentDidMount gets called.\n\n          nextEffect.effectTag &= ~Placement; // Update\n\n          var _current = nextEffect.alternate;\n          commitWork(_current, nextEffect);\n          break;\n        }\n\n      case Hydrating:\n        {\n          nextEffect.effectTag &= ~Hydrating;\n          break;\n        }\n\n      case HydratingAndUpdate:\n        {\n          nextEffect.effectTag &= ~Hydrating; // Update\n\n          var _current2 = nextEffect.alternate;\n          commitWork(_current2, nextEffect);\n          break;\n        }\n\n      case Update:\n        {\n          var _current3 = nextEffect.alternate;\n          commitWork(_current3, nextEffect);\n          break;\n        }\n\n      case Deletion:\n        {\n          commitDeletion(root, nextEffect, renderPriorityLevel);\n          break;\n        }\n    } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.\n\n\n    recordEffect();\n    resetCurrentFiber();\n    nextEffect = nextEffect.nextEffect;\n  }\n}\n\nfunction commitLayoutEffects(root, committedExpirationTime) {\n  // TODO: Should probably move the bulk of this function to commitWork.\n  while (nextEffect !== null) {\n    setCurrentFiber(nextEffect);\n    var effectTag = nextEffect.effectTag;\n\n    if (effectTag & (Update | Callback)) {\n      recordEffect();\n      var current = nextEffect.alternate;\n      commitLifeCycles(root, current, nextEffect);\n    }\n\n    if (effectTag & Ref) {\n      recordEffect();\n      commitAttachRef(nextEffect);\n    }\n\n    resetCurrentFiber();\n    nextEffect = nextEffect.nextEffect;\n  }\n}\n\nfunction flushPassiveEffects() {\n  if (pendingPassiveEffectsRenderPriority !== NoPriority) {\n    var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;\n    pendingPassiveEffectsRenderPriority = NoPriority;\n    return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);\n  }\n}\n\nfunction flushPassiveEffectsImpl() {\n  if (rootWithPendingPassiveEffects === null) {\n    return false;\n  }\n\n  var root = rootWithPendingPassiveEffects;\n  var expirationTime = pendingPassiveEffectsExpirationTime;\n  rootWithPendingPassiveEffects = null;\n  pendingPassiveEffectsExpirationTime = NoWork;\n\n  if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {\n    {\n      throw Error( \"Cannot flush passive effects while already rendering.\" );\n    }\n  }\n\n  var prevExecutionContext = executionContext;\n  executionContext |= CommitContext;\n  var prevInteractions = pushInteractions(root);\n\n  {\n    // Note: This currently assumes there are no passive effects on the root fiber\n    // because the root is not part of its own effect list.\n    // This could change in the future.\n    var _effect2 = root.current.firstEffect;\n\n    while (_effect2 !== null) {\n      {\n        setCurrentFiber(_effect2);\n        invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);\n\n        if (hasCaughtError()) {\n          if (!(_effect2 !== null)) {\n            {\n              throw Error( \"Should be working on an effect.\" );\n            }\n          }\n\n          var _error5 = clearCaughtError();\n\n          captureCommitPhaseError(_effect2, _error5);\n        }\n\n        resetCurrentFiber();\n      }\n\n      var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC\n\n      _effect2.nextEffect = null;\n      _effect2 = nextNextEffect;\n    }\n  }\n\n  {\n    popInteractions(prevInteractions);\n    finishPendingInteractions(root, expirationTime);\n  }\n\n  executionContext = prevExecutionContext;\n  flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this\n  // exceeds the limit, we'll fire a warning.\n\n  nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;\n  return true;\n}\n\nfunction isAlreadyFailedLegacyErrorBoundary(instance) {\n  return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);\n}\nfunction markLegacyErrorBoundaryAsFailed(instance) {\n  if (legacyErrorBoundariesThatAlreadyFailed === null) {\n    legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);\n  } else {\n    legacyErrorBoundariesThatAlreadyFailed.add(instance);\n  }\n}\n\nfunction prepareToThrowUncaughtError(error) {\n  if (!hasUncaughtError) {\n    hasUncaughtError = true;\n    firstUncaughtError = error;\n  }\n}\n\nvar onUncaughtError = prepareToThrowUncaughtError;\n\nfunction captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {\n  var errorInfo = createCapturedValue(error, sourceFiber);\n  var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);\n  enqueueUpdate(rootFiber, update);\n  var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);\n\n  if (root !== null) {\n    ensureRootIsScheduled(root);\n    schedulePendingInteractions(root, Sync);\n  }\n}\n\nfunction captureCommitPhaseError(sourceFiber, error) {\n  if (sourceFiber.tag === HostRoot) {\n    // Error was thrown at the root. There is no parent, so the root\n    // itself should capture it.\n    captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);\n    return;\n  }\n\n  var fiber = sourceFiber.return;\n\n  while (fiber !== null) {\n    if (fiber.tag === HostRoot) {\n      captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);\n      return;\n    } else if (fiber.tag === ClassComponent) {\n      var ctor = fiber.type;\n      var instance = fiber.stateNode;\n\n      if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {\n        var errorInfo = createCapturedValue(error, sourceFiber);\n        var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync\n        Sync);\n        enqueueUpdate(fiber, update);\n        var root = markUpdateTimeFromFiberToRoot(fiber, Sync);\n\n        if (root !== null) {\n          ensureRootIsScheduled(root);\n          schedulePendingInteractions(root, Sync);\n        }\n\n        return;\n      }\n    }\n\n    fiber = fiber.return;\n  }\n}\nfunction pingSuspendedRoot(root, thenable, suspendedTime) {\n  var pingCache = root.pingCache;\n\n  if (pingCache !== null) {\n    // The thenable resolved, so we no longer need to memoize, because it will\n    // never be thrown again.\n    pingCache.delete(thenable);\n  }\n\n  if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {\n    // Received a ping at the same priority level at which we're currently\n    // rendering. We might want to restart this render. This should mirror\n    // the logic of whether or not a root suspends once it completes.\n    // TODO: If we're rendering sync either due to Sync, Batched or expired,\n    // we should probably never restart.\n    // If we're suspended with delay, we'll always suspend so we can always\n    // restart. If we're suspended without any updates, it might be a retry.\n    // If it's early in the retry we can restart. We can't know for sure\n    // whether we'll eventually process an update during this render pass,\n    // but it's somewhat unlikely that we get to a ping before that, since\n    // getting to the root most update is usually very fast.\n    if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {\n      // Restart from the root. Don't need to schedule a ping because\n      // we're already working on this tree.\n      prepareFreshStack(root, renderExpirationTime$1);\n    } else {\n      // Even though we can't restart right now, we might get an\n      // opportunity later. So we mark this render as having a ping.\n      workInProgressRootHasPendingPing = true;\n    }\n\n    return;\n  }\n\n  if (!isRootSuspendedAtTime(root, suspendedTime)) {\n    // The root is no longer suspended at this time.\n    return;\n  }\n\n  var lastPingedTime = root.lastPingedTime;\n\n  if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {\n    // There's already a lower priority ping scheduled.\n    return;\n  } // Mark the time at which this ping was scheduled.\n\n\n  root.lastPingedTime = suspendedTime;\n\n  ensureRootIsScheduled(root);\n  schedulePendingInteractions(root, suspendedTime);\n}\n\nfunction retryTimedOutBoundary(boundaryFiber, retryTime) {\n  // The boundary fiber (a Suspense component or SuspenseList component)\n  // previously was rendered in its fallback state. One of the promises that\n  // suspended it has resolved, which means at least part of the tree was\n  // likely unblocked. Try rendering again, at a new expiration time.\n  if (retryTime === NoWork) {\n    var suspenseConfig = null; // Retries don't carry over the already committed update.\n\n    var currentTime = requestCurrentTimeForUpdate();\n    retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);\n  } // TODO: Special case idle priority?\n\n\n  var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);\n\n  if (root !== null) {\n    ensureRootIsScheduled(root);\n    schedulePendingInteractions(root, retryTime);\n  }\n}\nfunction resolveRetryThenable(boundaryFiber, thenable) {\n  var retryTime = NoWork; // Default\n\n  var retryCache;\n\n  {\n    retryCache = boundaryFiber.stateNode;\n  }\n\n  if (retryCache !== null) {\n    // The thenable resolved, so we no longer need to memoize, because it will\n    // never be thrown again.\n    retryCache.delete(thenable);\n  }\n\n  retryTimedOutBoundary(boundaryFiber, retryTime);\n} // Computes the next Just Noticeable Difference (JND) boundary.\n// The theory is that a person can't tell the difference between small differences in time.\n// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable\n// difference in the experience. However, waiting for longer might mean that we can avoid\n// showing an intermediate loading state. The longer we have already waited, the harder it\n// is to tell small differences in time. Therefore, the longer we've already waited,\n// the longer we can wait additionally. At some point we have to give up though.\n// We pick a train model where the next boundary commits at a consistent schedule.\n// These particular numbers are vague estimates. We expect to adjust them based on research.\n\nfunction jnd(timeElapsed) {\n  return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;\n}\n\nfunction computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {\n  var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;\n\n  if (busyMinDurationMs <= 0) {\n    return 0;\n  }\n\n  var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.\n\n  var currentTimeMs = now();\n  var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);\n  var timeElapsed = currentTimeMs - eventTimeMs;\n\n  if (timeElapsed <= busyDelayMs) {\n    // If we haven't yet waited longer than the initial delay, we don't\n    // have to wait any additional time.\n    return 0;\n  }\n\n  var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.\n\n  return msUntilTimeout;\n}\n\nfunction checkForNestedUpdates() {\n  if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {\n    nestedUpdateCount = 0;\n    rootWithNestedUpdates = null;\n\n    {\n      {\n        throw Error( \"Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.\" );\n      }\n    }\n  }\n\n  {\n    if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {\n      nestedPassiveUpdateCount = 0;\n\n      error('Maximum update depth exceeded. This can happen when a component ' + \"calls setState inside useEffect, but useEffect either doesn't \" + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');\n    }\n  }\n}\n\nfunction flushRenderPhaseStrictModeWarningsInDEV() {\n  {\n    ReactStrictModeWarnings.flushLegacyContextWarning();\n\n    {\n      ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();\n    }\n  }\n}\n\nfunction stopFinishedWorkLoopTimer() {\n  var didCompleteRoot = true;\n  stopWorkLoopTimer(interruptedBy, didCompleteRoot);\n  interruptedBy = null;\n}\n\nfunction stopInterruptedWorkLoopTimer() {\n  // TODO: Track which fiber caused the interruption.\n  var didCompleteRoot = false;\n  stopWorkLoopTimer(interruptedBy, didCompleteRoot);\n  interruptedBy = null;\n}\n\nfunction checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {\n  if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {\n    interruptedBy = fiberThatReceivedUpdate;\n  }\n}\n\nvar didWarnStateUpdateForUnmountedComponent = null;\n\nfunction warnAboutUpdateOnUnmountedFiberInDEV(fiber) {\n  {\n    var tag = fiber.tag;\n\n    if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {\n      // Only warn for user-defined components, not internal ones like Suspense.\n      return;\n    }\n    // the problematic code almost always lies inside that component.\n\n\n    var componentName = getComponentName(fiber.type) || 'ReactComponent';\n\n    if (didWarnStateUpdateForUnmountedComponent !== null) {\n      if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {\n        return;\n      }\n\n      didWarnStateUpdateForUnmountedComponent.add(componentName);\n    } else {\n      didWarnStateUpdateForUnmountedComponent = new Set([componentName]);\n    }\n\n    error(\"Can't perform a React state update on an unmounted component. This \" + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));\n  }\n}\n\nvar beginWork$1;\n\n{\n  var dummyFiber = null;\n\n  beginWork$1 = function (current, unitOfWork, expirationTime) {\n    // If a component throws an error, we replay it again in a synchronously\n    // dispatched event, so that the debugger will treat it as an uncaught\n    // error See ReactErrorUtils for more information.\n    // Before entering the begin phase, copy the work-in-progress onto a dummy\n    // fiber. If beginWork throws, we'll use this to reset the state.\n    var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);\n\n    try {\n      return beginWork(current, unitOfWork, expirationTime);\n    } catch (originalError) {\n      if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {\n        // Don't replay promises. Treat everything else like an error.\n        throw originalError;\n      } // Keep this code in sync with handleError; any changes here must have\n      // corresponding changes there.\n\n\n      resetContextDependencies();\n      resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the\n      // same fiber again.\n      // Unwind the failed stack frame\n\n      unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.\n\n      assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);\n\n      if ( unitOfWork.mode & ProfileMode) {\n        // Reset the profiler timer.\n        startProfilerTimer(unitOfWork);\n      } // Run beginWork again.\n\n\n      invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);\n\n      if (hasCaughtError()) {\n        var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.\n        // Rethrow this error instead of the original one.\n\n        throw replayError;\n      } else {\n        // This branch is reachable if the render phase is impure.\n        throw originalError;\n      }\n    }\n  };\n}\n\nvar didWarnAboutUpdateInRender = false;\nvar didWarnAboutUpdateInRenderForAnotherComponent;\n\n{\n  didWarnAboutUpdateInRenderForAnotherComponent = new Set();\n}\n\nfunction warnAboutRenderPhaseUpdatesInDEV(fiber) {\n  {\n    if (isRendering && (executionContext & RenderContext) !== NoContext) {\n      switch (fiber.tag) {\n        case FunctionComponent:\n        case ForwardRef:\n        case SimpleMemoComponent:\n          {\n            var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.\n\n            var dedupeKey = renderingComponentName;\n\n            if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {\n              didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);\n              var setStateComponentName = getComponentName(fiber.type) || 'Unknown';\n\n              error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://fb.me/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);\n            }\n\n            break;\n          }\n\n        case ClassComponent:\n          {\n            if (!didWarnAboutUpdateInRender) {\n              error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');\n\n              didWarnAboutUpdateInRender = true;\n            }\n\n            break;\n          }\n      }\n    }\n  }\n} // a 'shared' variable that changes when act() opens/closes in tests.\n\n\nvar IsThisRendererActing = {\n  current: false\n};\nfunction warnIfNotScopedWithMatchingAct(fiber) {\n  {\n    if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {\n      error(\"It looks like you're using the wrong act() around your test interactions.\\n\" + 'Be sure to use the matching version of act() corresponding to your renderer:\\n\\n' + '// for react-dom:\\n' + \"import {act} from 'react-dom/test-utils';\\n\" + '// ...\\n' + 'act(() => ...);\\n\\n' + '// for react-test-renderer:\\n' + \"import TestRenderer from 'react-test-renderer';\\n\" + 'const {act} = TestRenderer;\\n' + '// ...\\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));\n    }\n  }\n}\nfunction warnIfNotCurrentlyActingEffectsInDEV(fiber) {\n  {\n    if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {\n      error('An update to %s ran an effect, but was not wrapped in act(...).\\n\\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\\n\\n' + 'act(() => {\\n' + '  /* fire events that update state */\\n' + '});\\n' + '/* assert on the output */\\n\\n' + \"This ensures that you're testing the behavior the user would see \" + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));\n    }\n  }\n}\n\nfunction warnIfNotCurrentlyActingUpdatesInDEV(fiber) {\n  {\n    if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {\n      error('An update to %s inside a test was not wrapped in act(...).\\n\\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\\n\\n' + 'act(() => {\\n' + '  /* fire events that update state */\\n' + '});\\n' + '/* assert on the output */\\n\\n' + \"This ensures that you're testing the behavior the user would see \" + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));\n    }\n  }\n}\n\nvar warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.\n\nvar didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked\n// scheduler is the actual recommendation. The alternative could be a testing build,\n// a new lib, or whatever; we dunno just yet. This message is for early adopters\n// to get their tests right.\n\nfunction warnIfUnmockedScheduler(fiber) {\n  {\n    if (didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined) {\n      if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {\n        didWarnAboutUnmockedScheduler = true;\n\n        error('In Concurrent or Sync modes, the \"scheduler\" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \\n' + \"jest.mock('scheduler', () => require('scheduler/unstable_mock'));\\n\\n\" + 'For more info, visit https://fb.me/react-mock-scheduler');\n      }\n    }\n  }\n}\n\nfunction computeThreadID(root, expirationTime) {\n  // Interaction threads are unique per root and expiration time.\n  return expirationTime * 1000 + root.interactionThreadID;\n}\n\nfunction markSpawnedWork(expirationTime) {\n\n  if (spawnedWorkDuringRender === null) {\n    spawnedWorkDuringRender = [expirationTime];\n  } else {\n    spawnedWorkDuringRender.push(expirationTime);\n  }\n}\n\nfunction scheduleInteractions(root, expirationTime, interactions) {\n\n  if (interactions.size > 0) {\n    var pendingInteractionMap = root.pendingInteractionMap;\n    var pendingInteractions = pendingInteractionMap.get(expirationTime);\n\n    if (pendingInteractions != null) {\n      interactions.forEach(function (interaction) {\n        if (!pendingInteractions.has(interaction)) {\n          // Update the pending async work count for previously unscheduled interaction.\n          interaction.__count++;\n        }\n\n        pendingInteractions.add(interaction);\n      });\n    } else {\n      pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.\n\n      interactions.forEach(function (interaction) {\n        interaction.__count++;\n      });\n    }\n\n    var subscriber = tracing.__subscriberRef.current;\n\n    if (subscriber !== null) {\n      var threadID = computeThreadID(root, expirationTime);\n      subscriber.onWorkScheduled(interactions, threadID);\n    }\n  }\n}\n\nfunction schedulePendingInteractions(root, expirationTime) {\n\n  scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);\n}\n\nfunction startWorkOnPendingInteractions(root, expirationTime) {\n  // we can accurately attribute time spent working on it, And so that cascading\n  // work triggered during the render phase will be associated with it.\n\n\n  var interactions = new Set();\n  root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {\n    if (scheduledExpirationTime >= expirationTime) {\n      scheduledInteractions.forEach(function (interaction) {\n        return interactions.add(interaction);\n      });\n    }\n  }); // Store the current set of interactions on the FiberRoot for a few reasons:\n  // We can re-use it in hot functions like performConcurrentWorkOnRoot()\n  // without having to recalculate it. We will also use it in commitWork() to\n  // pass to any Profiler onRender() hooks. This also provides DevTools with a\n  // way to access it when the onCommitRoot() hook is called.\n\n  root.memoizedInteractions = interactions;\n\n  if (interactions.size > 0) {\n    var subscriber = tracing.__subscriberRef.current;\n\n    if (subscriber !== null) {\n      var threadID = computeThreadID(root, expirationTime);\n\n      try {\n        subscriber.onWorkStarted(interactions, threadID);\n      } catch (error) {\n        // If the subscriber throws, rethrow it in a separate task\n        scheduleCallback(ImmediatePriority, function () {\n          throw error;\n        });\n      }\n    }\n  }\n}\n\nfunction finishPendingInteractions(root, committedExpirationTime) {\n\n  var earliestRemainingTimeAfterCommit = root.firstPendingTime;\n  var subscriber;\n\n  try {\n    subscriber = tracing.__subscriberRef.current;\n\n    if (subscriber !== null && root.memoizedInteractions.size > 0) {\n      var threadID = computeThreadID(root, committedExpirationTime);\n      subscriber.onWorkStopped(root.memoizedInteractions, threadID);\n    }\n  } catch (error) {\n    // If the subscriber throws, rethrow it in a separate task\n    scheduleCallback(ImmediatePriority, function () {\n      throw error;\n    });\n  } finally {\n    // Clear completed interactions from the pending Map.\n    // Unless the render was suspended or cascading work was scheduled,\n    // In which case– leave pending interactions until the subsequent render.\n    var pendingInteractionMap = root.pendingInteractionMap;\n    pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {\n      // Only decrement the pending interaction count if we're done.\n      // If there's still work at the current priority,\n      // That indicates that we are waiting for suspense data.\n      if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {\n        pendingInteractionMap.delete(scheduledExpirationTime);\n        scheduledInteractions.forEach(function (interaction) {\n          interaction.__count--;\n\n          if (subscriber !== null && interaction.__count === 0) {\n            try {\n              subscriber.onInteractionScheduledWorkCompleted(interaction);\n            } catch (error) {\n              // If the subscriber throws, rethrow it in a separate task\n              scheduleCallback(ImmediatePriority, function () {\n                throw error;\n              });\n            }\n          }\n        });\n      }\n    });\n  }\n}\n\nvar onScheduleFiberRoot = null;\nvar onCommitFiberRoot = null;\nvar onCommitFiberUnmount = null;\nvar hasLoggedError = false;\nvar isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';\nfunction injectInternals(internals) {\n  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {\n    // No DevTools\n    return false;\n  }\n\n  var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;\n\n  if (hook.isDisabled) {\n    // This isn't a real property on the hook, but it can be set to opt out\n    // of DevTools integration and associated warnings and logs.\n    // https://github.com/facebook/react/issues/3877\n    return true;\n  }\n\n  if (!hook.supportsFiber) {\n    {\n      error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');\n    } // DevTools exists, even though it doesn't support Fiber.\n\n\n    return true;\n  }\n\n  try {\n    var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.\n\n    if (true) {\n      // Only used by Fast Refresh\n      if (typeof hook.onScheduleFiberRoot === 'function') {\n        onScheduleFiberRoot = function (root, children) {\n          try {\n            hook.onScheduleFiberRoot(rendererID, root, children);\n          } catch (err) {\n            if (true && !hasLoggedError) {\n              hasLoggedError = true;\n\n              error('React instrumentation encountered an error: %s', err);\n            }\n          }\n        };\n      }\n    }\n\n    onCommitFiberRoot = function (root, expirationTime) {\n      try {\n        var didError = (root.current.effectTag & DidCapture) === DidCapture;\n\n        if (enableProfilerTimer) {\n          var currentTime = getCurrentTime();\n          var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);\n          hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);\n        } else {\n          hook.onCommitFiberRoot(rendererID, root, undefined, didError);\n        }\n      } catch (err) {\n        if (true) {\n          if (!hasLoggedError) {\n            hasLoggedError = true;\n\n            error('React instrumentation encountered an error: %s', err);\n          }\n        }\n      }\n    };\n\n    onCommitFiberUnmount = function (fiber) {\n      try {\n        hook.onCommitFiberUnmount(rendererID, fiber);\n      } catch (err) {\n        if (true) {\n          if (!hasLoggedError) {\n            hasLoggedError = true;\n\n            error('React instrumentation encountered an error: %s', err);\n          }\n        }\n      }\n    };\n  } catch (err) {\n    // Catch all errors because it is unsafe to throw during initialization.\n    {\n      error('React instrumentation encountered an error: %s.', err);\n    }\n  } // DevTools exists\n\n\n  return true;\n}\nfunction onScheduleRoot(root, children) {\n  if (typeof onScheduleFiberRoot === 'function') {\n    onScheduleFiberRoot(root, children);\n  }\n}\nfunction onCommitRoot(root, expirationTime) {\n  if (typeof onCommitFiberRoot === 'function') {\n    onCommitFiberRoot(root, expirationTime);\n  }\n}\nfunction onCommitUnmount(fiber) {\n  if (typeof onCommitFiberUnmount === 'function') {\n    onCommitFiberUnmount(fiber);\n  }\n}\n\nvar hasBadMapPolyfill;\n\n{\n  hasBadMapPolyfill = false;\n\n  try {\n    var nonExtensibleObject = Object.preventExtensions({});\n    var testMap = new Map([[nonExtensibleObject, null]]);\n    var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.\n    // https://github.com/rollup/rollup/issues/1771\n    // TODO: we can remove these if Rollup fixes the bug.\n\n    testMap.set(0, 0);\n    testSet.add(0);\n  } catch (e) {\n    // TODO: Consider warning about bad polyfills\n    hasBadMapPolyfill = true;\n  }\n}\n\nvar debugCounter = 1;\n\nfunction FiberNode(tag, pendingProps, key, mode) {\n  // Instance\n  this.tag = tag;\n  this.key = key;\n  this.elementType = null;\n  this.type = null;\n  this.stateNode = null; // Fiber\n\n  this.return = null;\n  this.child = null;\n  this.sibling = null;\n  this.index = 0;\n  this.ref = null;\n  this.pendingProps = pendingProps;\n  this.memoizedProps = null;\n  this.updateQueue = null;\n  this.memoizedState = null;\n  this.dependencies = null;\n  this.mode = mode; // Effects\n\n  this.effectTag = NoEffect;\n  this.nextEffect = null;\n  this.firstEffect = null;\n  this.lastEffect = null;\n  this.expirationTime = NoWork;\n  this.childExpirationTime = NoWork;\n  this.alternate = null;\n\n  {\n    // Note: The following is done to avoid a v8 performance cliff.\n    //\n    // Initializing the fields below to smis and later updating them with\n    // double values will cause Fibers to end up having separate shapes.\n    // This behavior/bug has something to do with Object.preventExtension().\n    // Fortunately this only impacts DEV builds.\n    // Unfortunately it makes React unusably slow for some applications.\n    // To work around this, initialize the fields below with doubles.\n    //\n    // Learn more about this here:\n    // https://github.com/facebook/react/issues/14365\n    // https://bugs.chromium.org/p/v8/issues/detail?id=8538\n    this.actualDuration = Number.NaN;\n    this.actualStartTime = Number.NaN;\n    this.selfBaseDuration = Number.NaN;\n    this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.\n    // This won't trigger the performance cliff mentioned above,\n    // and it simplifies other profiler code (including DevTools).\n\n    this.actualDuration = 0;\n    this.actualStartTime = -1;\n    this.selfBaseDuration = 0;\n    this.treeBaseDuration = 0;\n  } // This is normally DEV-only except www when it adds listeners.\n  // TODO: remove the User Timing integration in favor of Root Events.\n\n\n  {\n    this._debugID = debugCounter++;\n    this._debugIsCurrentlyTiming = false;\n  }\n\n  {\n    this._debugSource = null;\n    this._debugOwner = null;\n    this._debugNeedsRemount = false;\n    this._debugHookTypes = null;\n\n    if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {\n      Object.preventExtensions(this);\n    }\n  }\n} // This is a constructor function, rather than a POJO constructor, still\n// please ensure we do the following:\n// 1) Nobody should add any instance methods on this. Instance methods can be\n//    more difficult to predict when they get optimized and they are almost\n//    never inlined properly in static compilers.\n// 2) Nobody should rely on `instanceof Fiber` for type testing. We should\n//    always know when it is a fiber.\n// 3) We might want to experiment with using numeric keys since they are easier\n//    to optimize in a non-JIT environment.\n// 4) We can easily go from a constructor to a createFiber object literal if that\n//    is faster.\n// 5) It should be easy to port this to a C struct and keep a C implementation\n//    compatible.\n\n\nvar createFiber = function (tag, pendingProps, key, mode) {\n  // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors\n  return new FiberNode(tag, pendingProps, key, mode);\n};\n\nfunction shouldConstruct(Component) {\n  var prototype = Component.prototype;\n  return !!(prototype && prototype.isReactComponent);\n}\n\nfunction isSimpleFunctionComponent(type) {\n  return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;\n}\nfunction resolveLazyComponentTag(Component) {\n  if (typeof Component === 'function') {\n    return shouldConstruct(Component) ? ClassComponent : FunctionComponent;\n  } else if (Component !== undefined && Component !== null) {\n    var $$typeof = Component.$$typeof;\n\n    if ($$typeof === REACT_FORWARD_REF_TYPE) {\n      return ForwardRef;\n    }\n\n    if ($$typeof === REACT_MEMO_TYPE) {\n      return MemoComponent;\n    }\n  }\n\n  return IndeterminateComponent;\n} // This is used to create an alternate fiber to do work on.\n\nfunction createWorkInProgress(current, pendingProps) {\n  var workInProgress = current.alternate;\n\n  if (workInProgress === null) {\n    // We use a double buffering pooling technique because we know that we'll\n    // only ever need at most two versions of a tree. We pool the \"other\" unused\n    // node that we're free to reuse. This is lazily created to avoid allocating\n    // extra objects for things that are never updated. It also allow us to\n    // reclaim the extra memory if needed.\n    workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);\n    workInProgress.elementType = current.elementType;\n    workInProgress.type = current.type;\n    workInProgress.stateNode = current.stateNode;\n\n    {\n      // DEV-only fields\n      {\n        workInProgress._debugID = current._debugID;\n      }\n\n      workInProgress._debugSource = current._debugSource;\n      workInProgress._debugOwner = current._debugOwner;\n      workInProgress._debugHookTypes = current._debugHookTypes;\n    }\n\n    workInProgress.alternate = current;\n    current.alternate = workInProgress;\n  } else {\n    workInProgress.pendingProps = pendingProps; // We already have an alternate.\n    // Reset the effect tag.\n\n    workInProgress.effectTag = NoEffect; // The effect list is no longer valid.\n\n    workInProgress.nextEffect = null;\n    workInProgress.firstEffect = null;\n    workInProgress.lastEffect = null;\n\n    {\n      // We intentionally reset, rather than copy, actualDuration & actualStartTime.\n      // This prevents time from endlessly accumulating in new commits.\n      // This has the downside of resetting values for different priority renders,\n      // But works for yielding (the common case) and should support resuming.\n      workInProgress.actualDuration = 0;\n      workInProgress.actualStartTime = -1;\n    }\n  }\n\n  workInProgress.childExpirationTime = current.childExpirationTime;\n  workInProgress.expirationTime = current.expirationTime;\n  workInProgress.child = current.child;\n  workInProgress.memoizedProps = current.memoizedProps;\n  workInProgress.memoizedState = current.memoizedState;\n  workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so\n  // it cannot be shared with the current fiber.\n\n  var currentDependencies = current.dependencies;\n  workInProgress.dependencies = currentDependencies === null ? null : {\n    expirationTime: currentDependencies.expirationTime,\n    firstContext: currentDependencies.firstContext,\n    responders: currentDependencies.responders\n  }; // These will be overridden during the parent's reconciliation\n\n  workInProgress.sibling = current.sibling;\n  workInProgress.index = current.index;\n  workInProgress.ref = current.ref;\n\n  {\n    workInProgress.selfBaseDuration = current.selfBaseDuration;\n    workInProgress.treeBaseDuration = current.treeBaseDuration;\n  }\n\n  {\n    workInProgress._debugNeedsRemount = current._debugNeedsRemount;\n\n    switch (workInProgress.tag) {\n      case IndeterminateComponent:\n      case FunctionComponent:\n      case SimpleMemoComponent:\n        workInProgress.type = resolveFunctionForHotReloading(current.type);\n        break;\n\n      case ClassComponent:\n        workInProgress.type = resolveClassForHotReloading(current.type);\n        break;\n\n      case ForwardRef:\n        workInProgress.type = resolveForwardRefForHotReloading(current.type);\n        break;\n    }\n  }\n\n  return workInProgress;\n} // Used to reuse a Fiber for a second pass.\n\nfunction resetWorkInProgress(workInProgress, renderExpirationTime) {\n  // This resets the Fiber to what createFiber or createWorkInProgress would\n  // have set the values to before during the first pass. Ideally this wouldn't\n  // be necessary but unfortunately many code paths reads from the workInProgress\n  // when they should be reading from current and writing to workInProgress.\n  // We assume pendingProps, index, key, ref, return are still untouched to\n  // avoid doing another reconciliation.\n  // Reset the effect tag but keep any Placement tags, since that's something\n  // that child fiber is setting, not the reconciliation.\n  workInProgress.effectTag &= Placement; // The effect list is no longer valid.\n\n  workInProgress.nextEffect = null;\n  workInProgress.firstEffect = null;\n  workInProgress.lastEffect = null;\n  var current = workInProgress.alternate;\n\n  if (current === null) {\n    // Reset to createFiber's initial values.\n    workInProgress.childExpirationTime = NoWork;\n    workInProgress.expirationTime = renderExpirationTime;\n    workInProgress.child = null;\n    workInProgress.memoizedProps = null;\n    workInProgress.memoizedState = null;\n    workInProgress.updateQueue = null;\n    workInProgress.dependencies = null;\n\n    {\n      // Note: We don't reset the actualTime counts. It's useful to accumulate\n      // actual time across multiple render passes.\n      workInProgress.selfBaseDuration = 0;\n      workInProgress.treeBaseDuration = 0;\n    }\n  } else {\n    // Reset to the cloned values that createWorkInProgress would've.\n    workInProgress.childExpirationTime = current.childExpirationTime;\n    workInProgress.expirationTime = current.expirationTime;\n    workInProgress.child = current.child;\n    workInProgress.memoizedProps = current.memoizedProps;\n    workInProgress.memoizedState = current.memoizedState;\n    workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so\n    // it cannot be shared with the current fiber.\n\n    var currentDependencies = current.dependencies;\n    workInProgress.dependencies = currentDependencies === null ? null : {\n      expirationTime: currentDependencies.expirationTime,\n      firstContext: currentDependencies.firstContext,\n      responders: currentDependencies.responders\n    };\n\n    {\n      // Note: We don't reset the actualTime counts. It's useful to accumulate\n      // actual time across multiple render passes.\n      workInProgress.selfBaseDuration = current.selfBaseDuration;\n      workInProgress.treeBaseDuration = current.treeBaseDuration;\n    }\n  }\n\n  return workInProgress;\n}\nfunction createHostRootFiber(tag) {\n  var mode;\n\n  if (tag === ConcurrentRoot) {\n    mode = ConcurrentMode | BlockingMode | StrictMode;\n  } else if (tag === BlockingRoot) {\n    mode = BlockingMode | StrictMode;\n  } else {\n    mode = NoMode;\n  }\n\n  if ( isDevToolsPresent) {\n    // Always collect profile timings when DevTools are present.\n    // This enables DevTools to start capturing timing at any point–\n    // Without some nodes in the tree having empty base times.\n    mode |= ProfileMode;\n  }\n\n  return createFiber(HostRoot, null, null, mode);\n}\nfunction createFiberFromTypeAndProps(type, // React$ElementType\nkey, pendingProps, owner, mode, expirationTime) {\n  var fiber;\n  var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.\n\n  var resolvedType = type;\n\n  if (typeof type === 'function') {\n    if (shouldConstruct(type)) {\n      fiberTag = ClassComponent;\n\n      {\n        resolvedType = resolveClassForHotReloading(resolvedType);\n      }\n    } else {\n      {\n        resolvedType = resolveFunctionForHotReloading(resolvedType);\n      }\n    }\n  } else if (typeof type === 'string') {\n    fiberTag = HostComponent;\n  } else {\n    getTag: switch (type) {\n      case REACT_FRAGMENT_TYPE:\n        return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);\n\n      case REACT_CONCURRENT_MODE_TYPE:\n        fiberTag = Mode;\n        mode |= ConcurrentMode | BlockingMode | StrictMode;\n        break;\n\n      case REACT_STRICT_MODE_TYPE:\n        fiberTag = Mode;\n        mode |= StrictMode;\n        break;\n\n      case REACT_PROFILER_TYPE:\n        return createFiberFromProfiler(pendingProps, mode, expirationTime, key);\n\n      case REACT_SUSPENSE_TYPE:\n        return createFiberFromSuspense(pendingProps, mode, expirationTime, key);\n\n      case REACT_SUSPENSE_LIST_TYPE:\n        return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);\n\n      default:\n        {\n          if (typeof type === 'object' && type !== null) {\n            switch (type.$$typeof) {\n              case REACT_PROVIDER_TYPE:\n                fiberTag = ContextProvider;\n                break getTag;\n\n              case REACT_CONTEXT_TYPE:\n                // This is a consumer\n                fiberTag = ContextConsumer;\n                break getTag;\n\n              case REACT_FORWARD_REF_TYPE:\n                fiberTag = ForwardRef;\n\n                {\n                  resolvedType = resolveForwardRefForHotReloading(resolvedType);\n                }\n\n                break getTag;\n\n              case REACT_MEMO_TYPE:\n                fiberTag = MemoComponent;\n                break getTag;\n\n              case REACT_LAZY_TYPE:\n                fiberTag = LazyComponent;\n                resolvedType = null;\n                break getTag;\n\n              case REACT_BLOCK_TYPE:\n                fiberTag = Block;\n                break getTag;\n\n            }\n          }\n\n          var info = '';\n\n          {\n            if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {\n              info += ' You likely forgot to export your component from the file ' + \"it's defined in, or you might have mixed up default and \" + 'named imports.';\n            }\n\n            var ownerName = owner ? getComponentName(owner.type) : null;\n\n            if (ownerName) {\n              info += '\\n\\nCheck the render method of `' + ownerName + '`.';\n            }\n          }\n\n          {\n            {\n              throw Error( \"Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: \" + (type == null ? type : typeof type) + \".\" + info );\n            }\n          }\n        }\n    }\n  }\n\n  fiber = createFiber(fiberTag, pendingProps, key, mode);\n  fiber.elementType = type;\n  fiber.type = resolvedType;\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\nfunction createFiberFromElement(element, mode, expirationTime) {\n  var owner = null;\n\n  {\n    owner = element._owner;\n  }\n\n  var type = element.type;\n  var key = element.key;\n  var pendingProps = element.props;\n  var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);\n\n  {\n    fiber._debugSource = element._source;\n    fiber._debugOwner = element._owner;\n  }\n\n  return fiber;\n}\nfunction createFiberFromFragment(elements, mode, expirationTime, key) {\n  var fiber = createFiber(Fragment, elements, key, mode);\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\n\nfunction createFiberFromProfiler(pendingProps, mode, expirationTime, key) {\n  {\n    if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {\n      error('Profiler must specify an \"id\" string and \"onRender\" function as props');\n    }\n  }\n\n  var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.\n\n  fiber.elementType = REACT_PROFILER_TYPE;\n  fiber.type = REACT_PROFILER_TYPE;\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\n\nfunction createFiberFromSuspense(pendingProps, mode, expirationTime, key) {\n  var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.\n  // This needs to be fixed in getComponentName so that it relies on the tag\n  // instead.\n\n  fiber.type = REACT_SUSPENSE_TYPE;\n  fiber.elementType = REACT_SUSPENSE_TYPE;\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\nfunction createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {\n  var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);\n\n  {\n    // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.\n    // This needs to be fixed in getComponentName so that it relies on the tag\n    // instead.\n    fiber.type = REACT_SUSPENSE_LIST_TYPE;\n  }\n\n  fiber.elementType = REACT_SUSPENSE_LIST_TYPE;\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\nfunction createFiberFromText(content, mode, expirationTime) {\n  var fiber = createFiber(HostText, content, null, mode);\n  fiber.expirationTime = expirationTime;\n  return fiber;\n}\nfunction createFiberFromHostInstanceForDeletion() {\n  var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.\n\n  fiber.elementType = 'DELETED';\n  fiber.type = 'DELETED';\n  return fiber;\n}\nfunction createFiberFromPortal(portal, mode, expirationTime) {\n  var pendingProps = portal.children !== null ? portal.children : [];\n  var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);\n  fiber.expirationTime = expirationTime;\n  fiber.stateNode = {\n    containerInfo: portal.containerInfo,\n    pendingChildren: null,\n    // Used by persistent updates\n    implementation: portal.implementation\n  };\n  return fiber;\n} // Used for stashing WIP properties to replay failed work in DEV.\n\nfunction assignFiberPropertiesInDEV(target, source) {\n  if (target === null) {\n    // This Fiber's initial properties will always be overwritten.\n    // We only use a Fiber to ensure the same hidden class so DEV isn't slow.\n    target = createFiber(IndeterminateComponent, null, null, NoMode);\n  } // This is intentionally written as a list of all properties.\n  // We tried to use Object.assign() instead but this is called in\n  // the hottest path, and Object.assign() was too slow:\n  // https://github.com/facebook/react/issues/12502\n  // This code is DEV-only so size is not a concern.\n\n\n  target.tag = source.tag;\n  target.key = source.key;\n  target.elementType = source.elementType;\n  target.type = source.type;\n  target.stateNode = source.stateNode;\n  target.return = source.return;\n  target.child = source.child;\n  target.sibling = source.sibling;\n  target.index = source.index;\n  target.ref = source.ref;\n  target.pendingProps = source.pendingProps;\n  target.memoizedProps = source.memoizedProps;\n  target.updateQueue = source.updateQueue;\n  target.memoizedState = source.memoizedState;\n  target.dependencies = source.dependencies;\n  target.mode = source.mode;\n  target.effectTag = source.effectTag;\n  target.nextEffect = source.nextEffect;\n  target.firstEffect = source.firstEffect;\n  target.lastEffect = source.lastEffect;\n  target.expirationTime = source.expirationTime;\n  target.childExpirationTime = source.childExpirationTime;\n  target.alternate = source.alternate;\n\n  {\n    target.actualDuration = source.actualDuration;\n    target.actualStartTime = source.actualStartTime;\n    target.selfBaseDuration = source.selfBaseDuration;\n    target.treeBaseDuration = source.treeBaseDuration;\n  }\n\n  {\n    target._debugID = source._debugID;\n  }\n\n  target._debugSource = source._debugSource;\n  target._debugOwner = source._debugOwner;\n  target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;\n  target._debugNeedsRemount = source._debugNeedsRemount;\n  target._debugHookTypes = source._debugHookTypes;\n  return target;\n}\n\nfunction FiberRootNode(containerInfo, tag, hydrate) {\n  this.tag = tag;\n  this.current = null;\n  this.containerInfo = containerInfo;\n  this.pendingChildren = null;\n  this.pingCache = null;\n  this.finishedExpirationTime = NoWork;\n  this.finishedWork = null;\n  this.timeoutHandle = noTimeout;\n  this.context = null;\n  this.pendingContext = null;\n  this.hydrate = hydrate;\n  this.callbackNode = null;\n  this.callbackPriority = NoPriority;\n  this.firstPendingTime = NoWork;\n  this.firstSuspendedTime = NoWork;\n  this.lastSuspendedTime = NoWork;\n  this.nextKnownPendingLevel = NoWork;\n  this.lastPingedTime = NoWork;\n  this.lastExpiredTime = NoWork;\n\n  {\n    this.interactionThreadID = tracing.unstable_getThreadID();\n    this.memoizedInteractions = new Set();\n    this.pendingInteractionMap = new Map();\n  }\n}\n\nfunction createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {\n  var root = new FiberRootNode(containerInfo, tag, hydrate);\n  // stateNode is any.\n\n\n  var uninitializedFiber = createHostRootFiber(tag);\n  root.current = uninitializedFiber;\n  uninitializedFiber.stateNode = root;\n  initializeUpdateQueue(uninitializedFiber);\n  return root;\n}\nfunction isRootSuspendedAtTime(root, expirationTime) {\n  var firstSuspendedTime = root.firstSuspendedTime;\n  var lastSuspendedTime = root.lastSuspendedTime;\n  return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;\n}\nfunction markRootSuspendedAtTime(root, expirationTime) {\n  var firstSuspendedTime = root.firstSuspendedTime;\n  var lastSuspendedTime = root.lastSuspendedTime;\n\n  if (firstSuspendedTime < expirationTime) {\n    root.firstSuspendedTime = expirationTime;\n  }\n\n  if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {\n    root.lastSuspendedTime = expirationTime;\n  }\n\n  if (expirationTime <= root.lastPingedTime) {\n    root.lastPingedTime = NoWork;\n  }\n\n  if (expirationTime <= root.lastExpiredTime) {\n    root.lastExpiredTime = NoWork;\n  }\n}\nfunction markRootUpdatedAtTime(root, expirationTime) {\n  // Update the range of pending times\n  var firstPendingTime = root.firstPendingTime;\n\n  if (expirationTime > firstPendingTime) {\n    root.firstPendingTime = expirationTime;\n  } // Update the range of suspended times. Treat everything lower priority or\n  // equal to this update as unsuspended.\n\n\n  var firstSuspendedTime = root.firstSuspendedTime;\n\n  if (firstSuspendedTime !== NoWork) {\n    if (expirationTime >= firstSuspendedTime) {\n      // The entire suspended range is now unsuspended.\n      root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;\n    } else if (expirationTime >= root.lastSuspendedTime) {\n      root.lastSuspendedTime = expirationTime + 1;\n    } // This is a pending level. Check if it's higher priority than the next\n    // known pending level.\n\n\n    if (expirationTime > root.nextKnownPendingLevel) {\n      root.nextKnownPendingLevel = expirationTime;\n    }\n  }\n}\nfunction markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {\n  // Update the range of pending times\n  root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or\n  // equal to this update as unsuspended.\n\n  if (finishedExpirationTime <= root.lastSuspendedTime) {\n    // The entire suspended range is now unsuspended.\n    root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;\n  } else if (finishedExpirationTime <= root.firstSuspendedTime) {\n    // Part of the suspended range is now unsuspended. Narrow the range to\n    // include everything between the unsuspended time (non-inclusive) and the\n    // last suspended time.\n    root.firstSuspendedTime = finishedExpirationTime - 1;\n  }\n\n  if (finishedExpirationTime <= root.lastPingedTime) {\n    // Clear the pinged time\n    root.lastPingedTime = NoWork;\n  }\n\n  if (finishedExpirationTime <= root.lastExpiredTime) {\n    // Clear the expired time\n    root.lastExpiredTime = NoWork;\n  }\n}\nfunction markRootExpiredAtTime(root, expirationTime) {\n  var lastExpiredTime = root.lastExpiredTime;\n\n  if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {\n    root.lastExpiredTime = expirationTime;\n  }\n}\n\nvar didWarnAboutNestedUpdates;\nvar didWarnAboutFindNodeInStrictMode;\n\n{\n  didWarnAboutNestedUpdates = false;\n  didWarnAboutFindNodeInStrictMode = {};\n}\n\nfunction getContextForSubtree(parentComponent) {\n  if (!parentComponent) {\n    return emptyContextObject;\n  }\n\n  var fiber = get(parentComponent);\n  var parentContext = findCurrentUnmaskedContext(fiber);\n\n  if (fiber.tag === ClassComponent) {\n    var Component = fiber.type;\n\n    if (isContextProvider(Component)) {\n      return processChildContext(fiber, Component, parentContext);\n    }\n  }\n\n  return parentContext;\n}\n\nfunction findHostInstanceWithWarning(component, methodName) {\n  {\n    var fiber = get(component);\n\n    if (fiber === undefined) {\n      if (typeof component.render === 'function') {\n        {\n          {\n            throw Error( \"Unable to find node on an unmounted component.\" );\n          }\n        }\n      } else {\n        {\n          {\n            throw Error( \"Argument appears to not be a ReactComponent. Keys: \" + Object.keys(component) );\n          }\n        }\n      }\n    }\n\n    var hostFiber = findCurrentHostFiber(fiber);\n\n    if (hostFiber === null) {\n      return null;\n    }\n\n    if (hostFiber.mode & StrictMode) {\n      var componentName = getComponentName(fiber.type) || 'Component';\n\n      if (!didWarnAboutFindNodeInStrictMode[componentName]) {\n        didWarnAboutFindNodeInStrictMode[componentName] = true;\n\n        if (fiber.mode & StrictMode) {\n          error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));\n        } else {\n          error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));\n        }\n      }\n    }\n\n    return hostFiber.stateNode;\n  }\n}\n\nfunction createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {\n  return createFiberRoot(containerInfo, tag, hydrate);\n}\nfunction updateContainer(element, container, parentComponent, callback) {\n  {\n    onScheduleRoot(container, element);\n  }\n\n  var current$1 = container.current;\n  var currentTime = requestCurrentTimeForUpdate();\n\n  {\n    // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests\n    if ('undefined' !== typeof jest) {\n      warnIfUnmockedScheduler(current$1);\n      warnIfNotScopedWithMatchingAct(current$1);\n    }\n  }\n\n  var suspenseConfig = requestCurrentSuspenseConfig();\n  var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);\n  var context = getContextForSubtree(parentComponent);\n\n  if (container.context === null) {\n    container.context = context;\n  } else {\n    container.pendingContext = context;\n  }\n\n  {\n    if (isRendering && current !== null && !didWarnAboutNestedUpdates) {\n      didWarnAboutNestedUpdates = true;\n\n      error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\\n\\n' + 'Check the render method of %s.', getComponentName(current.type) || 'Unknown');\n    }\n  }\n\n  var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property\n  // being called \"element\".\n\n  update.payload = {\n    element: element\n  };\n  callback = callback === undefined ? null : callback;\n\n  if (callback !== null) {\n    {\n      if (typeof callback !== 'function') {\n        error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);\n      }\n    }\n\n    update.callback = callback;\n  }\n\n  enqueueUpdate(current$1, update);\n  scheduleWork(current$1, expirationTime);\n  return expirationTime;\n}\nfunction getPublicRootInstance(container) {\n  var containerFiber = container.current;\n\n  if (!containerFiber.child) {\n    return null;\n  }\n\n  switch (containerFiber.child.tag) {\n    case HostComponent:\n      return getPublicInstance(containerFiber.child.stateNode);\n\n    default:\n      return containerFiber.child.stateNode;\n  }\n}\n\nfunction markRetryTimeImpl(fiber, retryTime) {\n  var suspenseState = fiber.memoizedState;\n\n  if (suspenseState !== null && suspenseState.dehydrated !== null) {\n    if (suspenseState.retryTime < retryTime) {\n      suspenseState.retryTime = retryTime;\n    }\n  }\n} // Increases the priority of thennables when they resolve within this boundary.\n\n\nfunction markRetryTimeIfNotHydrated(fiber, retryTime) {\n  markRetryTimeImpl(fiber, retryTime);\n  var alternate = fiber.alternate;\n\n  if (alternate) {\n    markRetryTimeImpl(alternate, retryTime);\n  }\n}\n\nfunction attemptUserBlockingHydration$1(fiber) {\n  if (fiber.tag !== SuspenseComponent) {\n    // We ignore HostRoots here because we can't increase\n    // their priority and they should not suspend on I/O,\n    // since you have to wrap anything that might suspend in\n    // Suspense.\n    return;\n  }\n\n  var expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());\n  scheduleWork(fiber, expTime);\n  markRetryTimeIfNotHydrated(fiber, expTime);\n}\nfunction attemptContinuousHydration$1(fiber) {\n  if (fiber.tag !== SuspenseComponent) {\n    // We ignore HostRoots here because we can't increase\n    // their priority and they should not suspend on I/O,\n    // since you have to wrap anything that might suspend in\n    // Suspense.\n    return;\n  }\n\n  scheduleWork(fiber, ContinuousHydration);\n  markRetryTimeIfNotHydrated(fiber, ContinuousHydration);\n}\nfunction attemptHydrationAtCurrentPriority$1(fiber) {\n  if (fiber.tag !== SuspenseComponent) {\n    // We ignore HostRoots here because we can't increase\n    // their priority other than synchronously flush it.\n    return;\n  }\n\n  var currentTime = requestCurrentTimeForUpdate();\n  var expTime = computeExpirationForFiber(currentTime, fiber, null);\n  scheduleWork(fiber, expTime);\n  markRetryTimeIfNotHydrated(fiber, expTime);\n}\nfunction findHostInstanceWithNoPortals(fiber) {\n  var hostFiber = findCurrentHostFiberWithNoPortals(fiber);\n\n  if (hostFiber === null) {\n    return null;\n  }\n\n  if (hostFiber.tag === FundamentalComponent) {\n    return hostFiber.stateNode.instance;\n  }\n\n  return hostFiber.stateNode;\n}\n\nvar shouldSuspendImpl = function (fiber) {\n  return false;\n};\n\nfunction shouldSuspend(fiber) {\n  return shouldSuspendImpl(fiber);\n}\nvar overrideHookState = null;\nvar overrideProps = null;\nvar scheduleUpdate = null;\nvar setSuspenseHandler = null;\n\n{\n  var copyWithSetImpl = function (obj, path, idx, value) {\n    if (idx >= path.length) {\n      return value;\n    }\n\n    var key = path[idx];\n    var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here\n\n    updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);\n    return updated;\n  };\n\n  var copyWithSet = function (obj, path, value) {\n    return copyWithSetImpl(obj, path, 0, value);\n  }; // Support DevTools editable values for useState and useReducer.\n\n\n  overrideHookState = function (fiber, id, path, value) {\n    // For now, the \"id\" of stateful hooks is just the stateful hook index.\n    // This may change in the future with e.g. nested hooks.\n    var currentHook = fiber.memoizedState;\n\n    while (currentHook !== null && id > 0) {\n      currentHook = currentHook.next;\n      id--;\n    }\n\n    if (currentHook !== null) {\n      var newState = copyWithSet(currentHook.memoizedState, path, value);\n      currentHook.memoizedState = newState;\n      currentHook.baseState = newState; // We aren't actually adding an update to the queue,\n      // because there is no update we can add for useReducer hooks that won't trigger an error.\n      // (There's no appropriate action type for DevTools overrides.)\n      // As a result though, React will see the scheduled update as a noop and bailout.\n      // Shallow cloning props works as a workaround for now to bypass the bailout check.\n\n      fiber.memoizedProps = _assign({}, fiber.memoizedProps);\n      scheduleWork(fiber, Sync);\n    }\n  }; // Support DevTools props for function components, forwardRef, memo, host components, etc.\n\n\n  overrideProps = function (fiber, path, value) {\n    fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);\n\n    if (fiber.alternate) {\n      fiber.alternate.pendingProps = fiber.pendingProps;\n    }\n\n    scheduleWork(fiber, Sync);\n  };\n\n  scheduleUpdate = function (fiber) {\n    scheduleWork(fiber, Sync);\n  };\n\n  setSuspenseHandler = function (newShouldSuspendImpl) {\n    shouldSuspendImpl = newShouldSuspendImpl;\n  };\n}\n\nfunction injectIntoDevTools(devToolsConfig) {\n  var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;\n  var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;\n  return injectInternals(_assign({}, devToolsConfig, {\n    overrideHookState: overrideHookState,\n    overrideProps: overrideProps,\n    setSuspenseHandler: setSuspenseHandler,\n    scheduleUpdate: scheduleUpdate,\n    currentDispatcherRef: ReactCurrentDispatcher,\n    findHostInstanceByFiber: function (fiber) {\n      var hostFiber = findCurrentHostFiber(fiber);\n\n      if (hostFiber === null) {\n        return null;\n      }\n\n      return hostFiber.stateNode;\n    },\n    findFiberByHostInstance: function (instance) {\n      if (!findFiberByHostInstance) {\n        // Might not be implemented by the renderer.\n        return null;\n      }\n\n      return findFiberByHostInstance(instance);\n    },\n    // React Refresh\n    findHostInstancesForRefresh:  findHostInstancesForRefresh ,\n    scheduleRefresh:  scheduleRefresh ,\n    scheduleRoot:  scheduleRoot ,\n    setRefreshHandler:  setRefreshHandler ,\n    // Enables DevTools to append owner stacks to error messages in DEV mode.\n    getCurrentFiber:  function () {\n      return current;\n    } \n  }));\n}\nvar IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;\n\nfunction ReactDOMRoot(container, options) {\n  this._internalRoot = createRootImpl(container, ConcurrentRoot, options);\n}\n\nfunction ReactDOMBlockingRoot(container, tag, options) {\n  this._internalRoot = createRootImpl(container, tag, options);\n}\n\nReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {\n  var root = this._internalRoot;\n\n  {\n    if (typeof arguments[1] === 'function') {\n      error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');\n    }\n\n    var container = root.containerInfo;\n\n    if (container.nodeType !== COMMENT_NODE) {\n      var hostInstance = findHostInstanceWithNoPortals(root.current);\n\n      if (hostInstance) {\n        if (hostInstance.parentNode !== container) {\n          error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + \"root.unmount() to empty a root's container.\");\n        }\n      }\n    }\n  }\n\n  updateContainer(children, root, null, null);\n};\n\nReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {\n  {\n    if (typeof arguments[0] === 'function') {\n      error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');\n    }\n  }\n\n  var root = this._internalRoot;\n  var container = root.containerInfo;\n  updateContainer(null, root, null, function () {\n    unmarkContainerAsRoot(container);\n  });\n};\n\nfunction createRootImpl(container, tag, options) {\n  // Tag is either LegacyRoot or Concurrent Root\n  var hydrate = options != null && options.hydrate === true;\n  var hydrationCallbacks = options != null && options.hydrationOptions || null;\n  var root = createContainer(container, tag, hydrate);\n  markContainerAsRoot(root.current, container);\n\n  if (hydrate && tag !== LegacyRoot) {\n    var doc = container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument;\n    eagerlyTrapReplayableEvents(container, doc);\n  }\n\n  return root;\n}\nfunction createLegacyRoot(container, options) {\n  return new ReactDOMBlockingRoot(container, LegacyRoot, options);\n}\nfunction isValidContainer(node) {\n  return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable '));\n}\n\nvar ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;\nvar topLevelUpdateWarnings;\nvar warnedAboutHydrateAPI = false;\n\n{\n  topLevelUpdateWarnings = function (container) {\n    if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {\n      var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);\n\n      if (hostInstance) {\n        if (hostInstance.parentNode !== container) {\n          error('render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.');\n        }\n      }\n    }\n\n    var isRootRenderedBySomeReact = !!container._reactRootContainer;\n    var rootEl = getReactRootElementInContainer(container);\n    var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));\n\n    if (hasNonRootReactChild && !isRootRenderedBySomeReact) {\n      error('render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.');\n    }\n\n    if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {\n      error('render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.');\n    }\n  };\n}\n\nfunction getReactRootElementInContainer(container) {\n  if (!container) {\n    return null;\n  }\n\n  if (container.nodeType === DOCUMENT_NODE) {\n    return container.documentElement;\n  } else {\n    return container.firstChild;\n  }\n}\n\nfunction shouldHydrateDueToLegacyHeuristic(container) {\n  var rootElement = getReactRootElementInContainer(container);\n  return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));\n}\n\nfunction legacyCreateRootFromDOMContainer(container, forceHydrate) {\n  var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.\n\n  if (!shouldHydrate) {\n    var warned = false;\n    var rootSibling;\n\n    while (rootSibling = container.lastChild) {\n      {\n        if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {\n          warned = true;\n\n          error('render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.');\n        }\n      }\n\n      container.removeChild(rootSibling);\n    }\n  }\n\n  {\n    if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {\n      warnedAboutHydrateAPI = true;\n\n      warn('render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');\n    }\n  }\n\n  return createLegacyRoot(container, shouldHydrate ? {\n    hydrate: true\n  } : undefined);\n}\n\nfunction warnOnInvalidCallback$1(callback, callerName) {\n  {\n    if (callback !== null && typeof callback !== 'function') {\n      error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);\n    }\n  }\n}\n\nfunction legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {\n  {\n    topLevelUpdateWarnings(container);\n    warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');\n  } // TODO: Without `any` type, Flow says \"Property cannot be accessed on any\n  // member of intersection type.\" Whyyyyyy.\n\n\n  var root = container._reactRootContainer;\n  var fiberRoot;\n\n  if (!root) {\n    // Initial mount\n    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);\n    fiberRoot = root._internalRoot;\n\n    if (typeof callback === 'function') {\n      var originalCallback = callback;\n\n      callback = function () {\n        var instance = getPublicRootInstance(fiberRoot);\n        originalCallback.call(instance);\n      };\n    } // Initial mount should not be batched.\n\n\n    unbatchedUpdates(function () {\n      updateContainer(children, fiberRoot, parentComponent, callback);\n    });\n  } else {\n    fiberRoot = root._internalRoot;\n\n    if (typeof callback === 'function') {\n      var _originalCallback = callback;\n\n      callback = function () {\n        var instance = getPublicRootInstance(fiberRoot);\n\n        _originalCallback.call(instance);\n      };\n    } // Update\n\n\n    updateContainer(children, fiberRoot, parentComponent, callback);\n  }\n\n  return getPublicRootInstance(fiberRoot);\n}\n\nfunction findDOMNode(componentOrElement) {\n  {\n    var owner = ReactCurrentOwner$3.current;\n\n    if (owner !== null && owner.stateNode !== null) {\n      var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;\n\n      if (!warnedAboutRefsInRender) {\n        error('%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(owner.type) || 'A component');\n      }\n\n      owner.stateNode._warnedAboutRefsInRender = true;\n    }\n  }\n\n  if (componentOrElement == null) {\n    return null;\n  }\n\n  if (componentOrElement.nodeType === ELEMENT_NODE) {\n    return componentOrElement;\n  }\n\n  {\n    return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');\n  }\n}\nfunction hydrate(element, container, callback) {\n  if (!isValidContainer(container)) {\n    {\n      throw Error( \"Target container is not a DOM element.\" );\n    }\n  }\n\n  {\n    var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;\n\n    if (isModernRoot) {\n      error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');\n    }\n  } // TODO: throw or warn if we couldn't hydrate?\n\n\n  return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);\n}\nfunction render(element, container, callback) {\n  if (!isValidContainer(container)) {\n    {\n      throw Error( \"Target container is not a DOM element.\" );\n    }\n  }\n\n  {\n    var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;\n\n    if (isModernRoot) {\n      error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');\n    }\n  }\n\n  return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);\n}\nfunction unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {\n  if (!isValidContainer(containerNode)) {\n    {\n      throw Error( \"Target container is not a DOM element.\" );\n    }\n  }\n\n  if (!(parentComponent != null && has(parentComponent))) {\n    {\n      throw Error( \"parentComponent must be a valid React Component\" );\n    }\n  }\n\n  return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);\n}\nfunction unmountComponentAtNode(container) {\n  if (!isValidContainer(container)) {\n    {\n      throw Error( \"unmountComponentAtNode(...): Target container is not a DOM element.\" );\n    }\n  }\n\n  {\n    var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;\n\n    if (isModernRoot) {\n      error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');\n    }\n  }\n\n  if (container._reactRootContainer) {\n    {\n      var rootEl = getReactRootElementInContainer(container);\n      var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);\n\n      if (renderedByDifferentReact) {\n        error(\"unmountComponentAtNode(): The node you're attempting to unmount \" + 'was rendered by another copy of React.');\n      }\n    } // Unmount should not be batched.\n\n\n    unbatchedUpdates(function () {\n      legacyRenderSubtreeIntoContainer(null, null, container, false, function () {\n        // $FlowFixMe This should probably use `delete container._reactRootContainer`\n        container._reactRootContainer = null;\n        unmarkContainerAsRoot(container);\n      });\n    }); // If you call unmountComponentAtNode twice in quick succession, you'll\n    // get `true` twice. That's probably fine?\n\n    return true;\n  } else {\n    {\n      var _rootEl = getReactRootElementInContainer(container);\n\n      var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); // Check if the container itself is a React root node.\n\n      var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;\n\n      if (hasNonRootReactChild) {\n        error(\"unmountComponentAtNode(): The node you're attempting to unmount \" + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.');\n      }\n    }\n\n    return false;\n  }\n}\n\nfunction createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.\nimplementation) {\n  var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n  return {\n    // This tag allow us to uniquely identify this as a React Portal\n    $$typeof: REACT_PORTAL_TYPE,\n    key: key == null ? null : '' + key,\n    children: children,\n    containerInfo: containerInfo,\n    implementation: implementation\n  };\n}\n\nvar ReactVersion = '16.13.1';\n\nsetAttemptUserBlockingHydration(attemptUserBlockingHydration$1);\nsetAttemptContinuousHydration(attemptContinuousHydration$1);\nsetAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);\nvar didWarnAboutUnstableCreatePortal = false;\n\n{\n  if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype\n  Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype\n  Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {\n    error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');\n  }\n}\n\nsetRestoreImplementation(restoreControlledState$3);\nsetBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);\n\nfunction createPortal$1(children, container) {\n  var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n  if (!isValidContainer(container)) {\n    {\n      throw Error( \"Target container is not a DOM element.\" );\n    }\n  } // TODO: pass ReactDOM portal implementation as third argument\n  // $FlowFixMe The Flow type is opaque but there's no way to actually create it.\n\n\n  return createPortal(children, container, null, key);\n}\n\nfunction renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {\n\n  return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);\n}\n\nfunction unstable_createPortal(children, container) {\n  var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n  {\n    if (!didWarnAboutUnstableCreatePortal) {\n      didWarnAboutUnstableCreatePortal = true;\n\n      warn('The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the \"unstable_\" prefix.');\n    }\n  }\n\n  return createPortal$1(children, container, key);\n}\n\nvar Internals = {\n  // Keep in sync with ReactDOMUnstableNativeDependencies.js\n  // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.\n  Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]\n};\nvar foundDevTools = injectIntoDevTools({\n  findFiberByHostInstance: getClosestInstanceFromNode,\n  bundleType:  1 ,\n  version: ReactVersion,\n  rendererPackageName: 'react-dom'\n});\n\n{\n  if (!foundDevTools && canUseDOM && window.top === window.self) {\n    // If we're in Chrome or Firefox, provide a download link if not installed.\n    if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {\n      var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.\n\n      if (/^(https?|file):$/.test(protocol)) {\n        // eslint-disable-next-line react-internal/no-production-logging\n        console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://fb.me/react-devtools' + (protocol === 'file:' ? '\\nYou might need to use a local HTTP server (instead of file://): ' + 'https://fb.me/react-devtools-faq' : ''), 'font-weight:bold');\n      }\n    }\n  }\n}\n\nexports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;\nexports.createPortal = createPortal$1;\nexports.findDOMNode = findDOMNode;\nexports.flushSync = flushSync;\nexports.hydrate = hydrate;\nexports.render = render;\nexports.unmountComponentAtNode = unmountComponentAtNode;\nexports.unstable_batchedUpdates = batchedUpdates$1;\nexports.unstable_createPortal = unstable_createPortal;\nexports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;\nexports.version = ReactVersion;\n  })();\n}\n","'use strict';\n\nfunction checkDCE() {\n  /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n  if (\n    typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n    typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n  ) {\n    return;\n  }\n  if (process.env.NODE_ENV !== 'production') {\n    // This branch is unreachable because this function is only called\n    // in production, but the condition is true only in development.\n    // Therefore if the branch is still here, dead code elimination wasn't\n    // properly applied.\n    // Don't change the message. React DevTools relies on it. Also make sure\n    // this message doesn't occur elsewhere in this function, or it will cause\n    // a false positive.\n    throw new Error('^_^');\n  }\n  try {\n    // Verify that the code above has been dead code eliminated (DCE'd).\n    __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n  } catch (err) {\n    // DevTools shouldn't crash React, no matter what.\n    // We should still report in case we break this code.\n    console.error(err);\n  }\n}\n\nif (process.env.NODE_ENV === 'production') {\n  // DCE check should happen before ReactDOM bundle executes so that\n  // DevTools can report bad minification during injection.\n  checkDCE();\n  module.exports = require('./cjs/react-dom.production.min.js');\n} else {\n  module.exports = require('./cjs/react-dom.development.js');\n}\n","/* global Map:readonly, Set:readonly, ArrayBuffer:readonly */\n\nvar hasElementType = typeof Element !== 'undefined';\nvar hasMap = typeof Map === 'function';\nvar hasSet = typeof Set === 'function';\nvar hasArrayBuffer = typeof ArrayBuffer === 'function' && !!ArrayBuffer.isView;\n\n// Note: We **don't** need `envHasBigInt64Array` in fde es6/index.js\n\nfunction equal(a, b) {\n  // START: fast-deep-equal es6/index.js 3.1.1\n  if (a === b) return true;\n\n  if (a && b && typeof a == 'object' && typeof b == 'object') {\n    if (a.constructor !== b.constructor) return false;\n\n    var length, i, keys;\n    if (Array.isArray(a)) {\n      length = a.length;\n      if (length != b.length) return false;\n      for (i = length; i-- !== 0;)\n        if (!equal(a[i], b[i])) return false;\n      return true;\n    }\n\n    // START: Modifications:\n    // 1. Extra `has<Type> &&` helpers in initial condition allow es6 code\n    //    to co-exist with es5.\n    // 2. Replace `for of` with es5 compliant iteration using `for`.\n    //    Basically, take:\n    //\n    //    ```js\n    //    for (i of a.entries())\n    //      if (!b.has(i[0])) return false;\n    //    ```\n    //\n    //    ... and convert to:\n    //\n    //    ```js\n    //    it = a.entries();\n    //    while (!(i = it.next()).done)\n    //      if (!b.has(i.value[0])) return false;\n    //    ```\n    //\n    //    **Note**: `i` access switches to `i.value`.\n    var it;\n    if (hasMap && (a instanceof Map) && (b instanceof Map)) {\n      if (a.size !== b.size) return false;\n      it = a.entries();\n      while (!(i = it.next()).done)\n        if (!b.has(i.value[0])) return false;\n      it = a.entries();\n      while (!(i = it.next()).done)\n        if (!equal(i.value[1], b.get(i.value[0]))) return false;\n      return true;\n    }\n\n    if (hasSet && (a instanceof Set) && (b instanceof Set)) {\n      if (a.size !== b.size) return false;\n      it = a.entries();\n      while (!(i = it.next()).done)\n        if (!b.has(i.value[0])) return false;\n      return true;\n    }\n    // END: Modifications\n\n    if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n      length = a.length;\n      if (length != b.length) return false;\n      for (i = length; i-- !== 0;)\n        if (a[i] !== b[i]) return false;\n      return true;\n    }\n\n    if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n    if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n    if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n    keys = Object.keys(a);\n    length = keys.length;\n    if (length !== Object.keys(b).length) return false;\n\n    for (i = length; i-- !== 0;)\n      if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n    // END: fast-deep-equal\n\n    // START: react-fast-compare\n    // custom handling for DOM elements\n    if (hasElementType && a instanceof Element) return false;\n\n    // custom handling for React/Preact\n    for (i = length; i-- !== 0;) {\n      if ((keys[i] === '_owner' || keys[i] === '__v' || keys[i] === '__o') && a.$$typeof) {\n        // React-specific: avoid traversing React elements' _owner\n        // Preact-specific: avoid traversing Preact elements' __v and __o\n        //    __v = $_original / $_vnode\n        //    __o = $_owner\n        // These properties contain circular references and are not needed when\n        // comparing the actual elements (and not their owners)\n        // .$$typeof and ._store on just reasonable markers of elements\n\n        continue;\n      }\n\n      // all other properties should be traversed as usual\n      if (!equal(a[keys[i]], b[keys[i]])) return false;\n    }\n    // END: react-fast-compare\n\n    // START: fast-deep-equal\n    return true;\n  }\n\n  return a !== a && b !== b;\n}\n// end fast-deep-equal\n\nmodule.exports = function isEqual(a, b) {\n  try {\n    return equal(a, b);\n  } catch (error) {\n    if (((error.message || '').match(/stack|recursion/i))) {\n      // warn on circular references, don't crash\n      // browsers give this different errors name and messages:\n      // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n      // firefox: \"InternalError\", too much recursion\"\n      // edge: \"Error\", \"Out of stack space\"\n      console.warn('react-fast-compare cannot handle circular refs');\n      return false;\n    }\n    // some other error. we should definitely know about these\n    throw error;\n  }\n};\n",null,"/** @license React v16.13.1\n * react-is.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary\n// (unstable) APIs that have been removed. Can we remove the symbols?\n\nvar REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf;\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\nvar REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;\nvar REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;\nvar REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;\nvar REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;\n\nfunction isValidElementType(type) {\n  return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.\n  type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);\n}\n\nfunction typeOf(object) {\n  if (typeof object === 'object' && object !== null) {\n    var $$typeof = object.$$typeof;\n\n    switch ($$typeof) {\n      case REACT_ELEMENT_TYPE:\n        var type = object.type;\n\n        switch (type) {\n          case REACT_ASYNC_MODE_TYPE:\n          case REACT_CONCURRENT_MODE_TYPE:\n          case REACT_FRAGMENT_TYPE:\n          case REACT_PROFILER_TYPE:\n          case REACT_STRICT_MODE_TYPE:\n          case REACT_SUSPENSE_TYPE:\n            return type;\n\n          default:\n            var $$typeofType = type && type.$$typeof;\n\n            switch ($$typeofType) {\n              case REACT_CONTEXT_TYPE:\n              case REACT_FORWARD_REF_TYPE:\n              case REACT_LAZY_TYPE:\n              case REACT_MEMO_TYPE:\n              case REACT_PROVIDER_TYPE:\n                return $$typeofType;\n\n              default:\n                return $$typeof;\n            }\n\n        }\n\n      case REACT_PORTAL_TYPE:\n        return $$typeof;\n    }\n  }\n\n  return undefined;\n} // AsyncMode is deprecated along with isAsyncMode\n\nvar AsyncMode = REACT_ASYNC_MODE_TYPE;\nvar ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;\nvar ContextConsumer = REACT_CONTEXT_TYPE;\nvar ContextProvider = REACT_PROVIDER_TYPE;\nvar Element = REACT_ELEMENT_TYPE;\nvar ForwardRef = REACT_FORWARD_REF_TYPE;\nvar Fragment = REACT_FRAGMENT_TYPE;\nvar Lazy = REACT_LAZY_TYPE;\nvar Memo = REACT_MEMO_TYPE;\nvar Portal = REACT_PORTAL_TYPE;\nvar Profiler = REACT_PROFILER_TYPE;\nvar StrictMode = REACT_STRICT_MODE_TYPE;\nvar Suspense = REACT_SUSPENSE_TYPE;\nvar hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated\n\nfunction isAsyncMode(object) {\n  {\n    if (!hasWarnedAboutDeprecatedIsAsyncMode) {\n      hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint\n\n      console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.');\n    }\n  }\n\n  return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;\n}\nfunction isConcurrentMode(object) {\n  return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;\n}\nfunction isContextConsumer(object) {\n  return typeOf(object) === REACT_CONTEXT_TYPE;\n}\nfunction isContextProvider(object) {\n  return typeOf(object) === REACT_PROVIDER_TYPE;\n}\nfunction isElement(object) {\n  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n}\nfunction isForwardRef(object) {\n  return typeOf(object) === REACT_FORWARD_REF_TYPE;\n}\nfunction isFragment(object) {\n  return typeOf(object) === REACT_FRAGMENT_TYPE;\n}\nfunction isLazy(object) {\n  return typeOf(object) === REACT_LAZY_TYPE;\n}\nfunction isMemo(object) {\n  return typeOf(object) === REACT_MEMO_TYPE;\n}\nfunction isPortal(object) {\n  return typeOf(object) === REACT_PORTAL_TYPE;\n}\nfunction isProfiler(object) {\n  return typeOf(object) === REACT_PROFILER_TYPE;\n}\nfunction isStrictMode(object) {\n  return typeOf(object) === REACT_STRICT_MODE_TYPE;\n}\nfunction isSuspense(object) {\n  return typeOf(object) === REACT_SUSPENSE_TYPE;\n}\n\nexports.AsyncMode = AsyncMode;\nexports.ConcurrentMode = ConcurrentMode;\nexports.ContextConsumer = ContextConsumer;\nexports.ContextProvider = ContextProvider;\nexports.Element = Element;\nexports.ForwardRef = ForwardRef;\nexports.Fragment = Fragment;\nexports.Lazy = Lazy;\nexports.Memo = Memo;\nexports.Portal = Portal;\nexports.Profiler = Profiler;\nexports.StrictMode = StrictMode;\nexports.Suspense = Suspense;\nexports.isAsyncMode = isAsyncMode;\nexports.isConcurrentMode = isConcurrentMode;\nexports.isContextConsumer = isContextConsumer;\nexports.isContextProvider = isContextProvider;\nexports.isElement = isElement;\nexports.isForwardRef = isForwardRef;\nexports.isFragment = isFragment;\nexports.isLazy = isLazy;\nexports.isMemo = isMemo;\nexports.isPortal = isPortal;\nexports.isProfiler = isProfiler;\nexports.isStrictMode = isStrictMode;\nexports.isSuspense = isSuspense;\nexports.isValidElementType = isValidElementType;\nexports.typeOf = typeOf;\n  })();\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/react-is.production.min.js');\n} else {\n  module.exports = require('./cjs/react-is.development.js');\n}\n","import _assertThisInitialized from \"@babel/runtime/helpers/assertThisInitialized\";\nimport _inheritsLoose from \"@babel/runtime/helpers/inheritsLoose\";\nimport _defineProperty from \"@babel/runtime/helpers/defineProperty\";\nimport * as React from 'react';\nimport createContext from 'create-react-context';\nexport var ManagerReferenceNodeContext = createContext();\nexport var ManagerReferenceNodeSetterContext = createContext();\n\nvar Manager =\n/*#__PURE__*/\nfunction (_React$Component) {\n  _inheritsLoose(Manager, _React$Component);\n\n  function Manager() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n\n    _defineProperty(_assertThisInitialized(_this), \"referenceNode\", void 0);\n\n    _defineProperty(_assertThisInitialized(_this), \"setReferenceNode\", function (newReferenceNode) {\n      if (newReferenceNode && _this.referenceNode !== newReferenceNode) {\n        _this.referenceNode = newReferenceNode;\n\n        _this.forceUpdate();\n      }\n    });\n\n    return _this;\n  }\n\n  var _proto = Manager.prototype;\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    this.referenceNode = null;\n  };\n\n  _proto.render = function render() {\n    return React.createElement(ManagerReferenceNodeContext.Provider, {\n      value: this.referenceNode\n    }, React.createElement(ManagerReferenceNodeSetterContext.Provider, {\n      value: this.setReferenceNode\n    }, this.props.children));\n  };\n\n  return Manager;\n}(React.Component);\n\nexport { Manager as default };","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/extends\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/assertThisInitialized\";\nimport _inheritsLoose from \"@babel/runtime/helpers/inheritsLoose\";\nimport _defineProperty from \"@babel/runtime/helpers/defineProperty\";\nimport deepEqual from \"deep-equal\";\nimport * as React from 'react';\nimport PopperJS from 'popper.js';\nimport { ManagerReferenceNodeContext } from './Manager';\nimport { unwrapArray, setRef, shallowEqual } from './utils';\nvar initialStyle = {\n  position: 'absolute',\n  top: 0,\n  left: 0,\n  opacity: 0,\n  pointerEvents: 'none'\n};\nvar initialArrowStyle = {};\nexport var InnerPopper =\n/*#__PURE__*/\nfunction (_React$Component) {\n  _inheritsLoose(InnerPopper, _React$Component);\n\n  function InnerPopper() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n\n    _defineProperty(_assertThisInitialized(_this), \"state\", {\n      data: undefined,\n      placement: undefined\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"popperInstance\", void 0);\n\n    _defineProperty(_assertThisInitialized(_this), \"popperNode\", null);\n\n    _defineProperty(_assertThisInitialized(_this), \"arrowNode\", null);\n\n    _defineProperty(_assertThisInitialized(_this), \"setPopperNode\", function (popperNode) {\n      if (!popperNode || _this.popperNode === popperNode) return;\n      setRef(_this.props.innerRef, popperNode);\n      _this.popperNode = popperNode;\n\n      _this.updatePopperInstance();\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"setArrowNode\", function (arrowNode) {\n      _this.arrowNode = arrowNode;\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"updateStateModifier\", {\n      enabled: true,\n      order: 900,\n      fn: function fn(data) {\n        var placement = data.placement;\n\n        _this.setState({\n          data: data,\n          placement: placement\n        });\n\n        return data;\n      }\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"getOptions\", function () {\n      return {\n        placement: _this.props.placement,\n        eventsEnabled: _this.props.eventsEnabled,\n        positionFixed: _this.props.positionFixed,\n        modifiers: _extends({}, _this.props.modifiers, {\n          arrow: _extends({}, _this.props.modifiers && _this.props.modifiers.arrow, {\n            enabled: !!_this.arrowNode,\n            element: _this.arrowNode\n          }),\n          applyStyle: {\n            enabled: false\n          },\n          updateStateModifier: _this.updateStateModifier\n        })\n      };\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"getPopperStyle\", function () {\n      return !_this.popperNode || !_this.state.data ? initialStyle : _extends({\n        position: _this.state.data.offsets.popper.position\n      }, _this.state.data.styles);\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"getPopperPlacement\", function () {\n      return !_this.state.data ? undefined : _this.state.placement;\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"getArrowStyle\", function () {\n      return !_this.arrowNode || !_this.state.data ? initialArrowStyle : _this.state.data.arrowStyles;\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"getOutOfBoundariesState\", function () {\n      return _this.state.data ? _this.state.data.hide : undefined;\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"destroyPopperInstance\", function () {\n      if (!_this.popperInstance) return;\n\n      _this.popperInstance.destroy();\n\n      _this.popperInstance = null;\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"updatePopperInstance\", function () {\n      _this.destroyPopperInstance();\n\n      var _assertThisInitialize = _assertThisInitialized(_this),\n          popperNode = _assertThisInitialize.popperNode;\n\n      var referenceElement = _this.props.referenceElement;\n      if (!referenceElement || !popperNode) return;\n      _this.popperInstance = new PopperJS(referenceElement, popperNode, _this.getOptions());\n    });\n\n    _defineProperty(_assertThisInitialized(_this), \"scheduleUpdate\", function () {\n      if (_this.popperInstance) {\n        _this.popperInstance.scheduleUpdate();\n      }\n    });\n\n    return _this;\n  }\n\n  var _proto = InnerPopper.prototype;\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    // If the Popper.js options have changed, update the instance (destroy + create)\n    if (this.props.placement !== prevProps.placement || this.props.referenceElement !== prevProps.referenceElement || this.props.positionFixed !== prevProps.positionFixed || !deepEqual(this.props.modifiers, prevProps.modifiers, {\n      strict: true\n    })) {\n      // develop only check that modifiers isn't being updated needlessly\n      if (process.env.NODE_ENV === \"development\") {\n        if (this.props.modifiers !== prevProps.modifiers && this.props.modifiers != null && prevProps.modifiers != null && shallowEqual(this.props.modifiers, prevProps.modifiers)) {\n          console.warn(\"'modifiers' prop reference updated even though all values appear the same.\\nConsider memoizing the 'modifiers' object to avoid needless rendering.\");\n        }\n      }\n\n      this.updatePopperInstance();\n    } else if (this.props.eventsEnabled !== prevProps.eventsEnabled && this.popperInstance) {\n      this.props.eventsEnabled ? this.popperInstance.enableEventListeners() : this.popperInstance.disableEventListeners();\n    } // A placement difference in state means popper determined a new placement\n    // apart from the props value. By the time the popper element is rendered with\n    // the new position Popper has already measured it, if the place change triggers\n    // a size change it will result in a misaligned popper. So we schedule an update to be sure.\n\n\n    if (prevState.placement !== this.state.placement) {\n      this.scheduleUpdate();\n    }\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    setRef(this.props.innerRef, null);\n    this.destroyPopperInstance();\n  };\n\n  _proto.render = function render() {\n    return unwrapArray(this.props.children)({\n      ref: this.setPopperNode,\n      style: this.getPopperStyle(),\n      placement: this.getPopperPlacement(),\n      outOfBoundaries: this.getOutOfBoundariesState(),\n      scheduleUpdate: this.scheduleUpdate,\n      arrowProps: {\n        ref: this.setArrowNode,\n        style: this.getArrowStyle()\n      }\n    });\n  };\n\n  return InnerPopper;\n}(React.Component);\n\n_defineProperty(InnerPopper, \"defaultProps\", {\n  placement: 'bottom',\n  eventsEnabled: true,\n  referenceElement: undefined,\n  positionFixed: false\n});\n\nvar placements = PopperJS.placements;\nexport { placements };\nexport default function Popper(_ref) {\n  var referenceElement = _ref.referenceElement,\n      props = _objectWithoutPropertiesLoose(_ref, [\"referenceElement\"]);\n\n  return React.createElement(ManagerReferenceNodeContext.Consumer, null, function (referenceNode) {\n    return React.createElement(InnerPopper, _extends({\n      referenceElement: referenceElement !== undefined ? referenceElement : referenceNode\n    }, props));\n  });\n}","import _extends from \"@babel/runtime/helpers/extends\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/assertThisInitialized\";\nimport _inheritsLoose from \"@babel/runtime/helpers/inheritsLoose\";\nimport _defineProperty from \"@babel/runtime/helpers/defineProperty\";\nimport * as React from 'react';\nimport warning from 'warning';\nimport { ManagerReferenceNodeSetterContext } from './Manager';\nimport { safeInvoke, unwrapArray, setRef } from './utils';\n\nvar InnerReference =\n/*#__PURE__*/\nfunction (_React$Component) {\n  _inheritsLoose(InnerReference, _React$Component);\n\n  function InnerReference() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n\n    _defineProperty(_assertThisInitialized(_this), \"refHandler\", function (node) {\n      setRef(_this.props.innerRef, node);\n      safeInvoke(_this.props.setReferenceNode, node);\n    });\n\n    return _this;\n  }\n\n  var _proto = InnerReference.prototype;\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    setRef(this.props.innerRef, null);\n  };\n\n  _proto.render = function render() {\n    warning(Boolean(this.props.setReferenceNode), '`Reference` should not be used outside of a `Manager` component.');\n    return unwrapArray(this.props.children)({\n      ref: this.refHandler\n    });\n  };\n\n  return InnerReference;\n}(React.Component);\n\nexport default function Reference(props) {\n  return React.createElement(ManagerReferenceNodeSetterContext.Consumer, null, function (setReferenceNode) {\n    return React.createElement(InnerReference, _extends({\n      setReferenceNode: setReferenceNode\n    }, props));\n  });\n}","// Public components\nimport Popper, { placements } from './Popper';\nimport Manager from './Manager';\nimport Reference from './Reference';\nexport { Popper, placements, Manager, Reference }; // Public types","/**\n * Takes an argument and if it's an array, returns the first item in the array,\n * otherwise returns the argument. Used for Preact compatibility.\n */\nexport var unwrapArray = function unwrapArray(arg) {\n  return Array.isArray(arg) ? arg[0] : arg;\n};\n/**\n * Takes a maybe-undefined function and arbitrary args and invokes the function\n * only if it is defined.\n */\n\nexport var safeInvoke = function safeInvoke(fn) {\n  if (typeof fn === \"function\") {\n    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    return fn.apply(void 0, args);\n  }\n};\n/**\n * Does a shallow equality check of two objects by comparing the reference\n * equality of each value.\n */\n\nexport var shallowEqual = function shallowEqual(objA, objB) {\n  var aKeys = Object.keys(objA);\n  var bKeys = Object.keys(objB);\n\n  if (bKeys.length !== aKeys.length) {\n    return false;\n  }\n\n  for (var i = 0; i < bKeys.length; i++) {\n    var key = aKeys[i];\n\n    if (objA[key] !== objB[key]) {\n      return false;\n    }\n  }\n\n  return true;\n};\n/**\n * Sets a ref using either a ref callback or a ref object\n */\n\nexport var setRef = function setRef(ref, node) {\n  // if its a function call it\n  if (typeof ref === \"function\") {\n    return safeInvoke(ref, node);\n  } // otherwise we should treat it as a ref object\n  else if (ref != null) {\n      ref.current = node;\n    }\n};","import React from \"react\";\nimport { Router } from \"react-router\";\nimport { createBrowserHistory as createHistory } from \"history\";\nimport PropTypes from \"prop-types\";\nimport warning from \"tiny-warning\";\n\n/**\n * The public API for a <Router> that uses HTML5 history.\n */\nclass BrowserRouter extends React.Component {\n  history = createHistory(this.props);\n\n  render() {\n    return <Router history={this.history} children={this.props.children} />;\n  }\n}\n\nif (__DEV__) {\n  BrowserRouter.propTypes = {\n    basename: PropTypes.string,\n    children: PropTypes.node,\n    forceRefresh: PropTypes.bool,\n    getUserConfirmation: PropTypes.func,\n    keyLength: PropTypes.number\n  };\n\n  BrowserRouter.prototype.componentDidMount = function() {\n    warning(\n      !this.props.history,\n      \"<BrowserRouter> ignores the history prop. To use a custom history, \" +\n        \"use `import { Router }` instead of `import { BrowserRouter as Router }`.\"\n    );\n  };\n}\n\nexport default BrowserRouter;\n","import React from \"react\";\nimport { Router } from \"react-router\";\nimport { createHashHistory as createHistory } from \"history\";\nimport PropTypes from \"prop-types\";\nimport warning from \"tiny-warning\";\n\n/**\n * The public API for a <Router> that uses window.location.hash.\n */\nclass HashRouter extends React.Component {\n  history = createHistory(this.props);\n\n  render() {\n    return <Router history={this.history} children={this.props.children} />;\n  }\n}\n\nif (__DEV__) {\n  HashRouter.propTypes = {\n    basename: PropTypes.string,\n    children: PropTypes.node,\n    getUserConfirmation: PropTypes.func,\n    hashType: PropTypes.oneOf([\"hashbang\", \"noslash\", \"slash\"])\n  };\n\n  HashRouter.prototype.componentDidMount = function() {\n    warning(\n      !this.props.history,\n      \"<HashRouter> ignores the history prop. To use a custom history, \" +\n        \"use `import { Router }` instead of `import { HashRouter as Router }`.\"\n    );\n  };\n}\n\nexport default HashRouter;\n","import { createLocation } from \"history\";\n\nexport const resolveToLocation = (to, currentLocation) =>\n  typeof to === \"function\" ? to(currentLocation) : to;\n\nexport const normalizeToLocation = (to, currentLocation) => {\n  return typeof to === \"string\"\n    ? createLocation(to, null, null, currentLocation)\n    : to;\n};\n","import React from \"react\";\nimport { __RouterContext as RouterContext } from \"react-router\";\nimport PropTypes from \"prop-types\";\nimport invariant from \"tiny-invariant\";\nimport {\n  resolveToLocation,\n  normalizeToLocation\n} from \"./utils/locationUtils.js\";\n\n// React 15 compat\nconst forwardRefShim = C => C;\nlet { forwardRef } = React;\nif (typeof forwardRef === \"undefined\") {\n  forwardRef = forwardRefShim;\n}\n\nfunction isModifiedEvent(event) {\n  return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);\n}\n\nconst LinkAnchor = forwardRef(\n  (\n    {\n      innerRef, // TODO: deprecate\n      navigate,\n      onClick,\n      ...rest\n    },\n    forwardedRef\n  ) => {\n    const { target } = rest;\n\n    let props = {\n      ...rest,\n      onClick: event => {\n        try {\n          if (onClick) onClick(event);\n        } catch (ex) {\n          event.preventDefault();\n          throw ex;\n        }\n\n        if (\n          !event.defaultPrevented && // onClick prevented default\n          event.button === 0 && // ignore everything but left clicks\n          (!target || target === \"_self\") && // let browser handle \"target=_blank\" etc.\n          !isModifiedEvent(event) // ignore clicks with modifier keys\n        ) {\n          event.preventDefault();\n          navigate();\n        }\n      }\n    };\n\n    // React 15 compat\n    if (forwardRefShim !== forwardRef) {\n      props.ref = forwardedRef || innerRef;\n    } else {\n      props.ref = innerRef;\n    }\n\n    /* eslint-disable-next-line jsx-a11y/anchor-has-content */\n    return <a {...props} />;\n  }\n);\n\nif (__DEV__) {\n  LinkAnchor.displayName = \"LinkAnchor\";\n}\n\n/**\n * The public API for rendering a history-aware <a>.\n */\nconst Link = forwardRef(\n  (\n    {\n      component = LinkAnchor,\n      replace,\n      to,\n      innerRef, // TODO: deprecate\n      ...rest\n    },\n    forwardedRef\n  ) => {\n    return (\n      <RouterContext.Consumer>\n        {context => {\n          invariant(context, \"You should not use <Link> outside a <Router>\");\n\n          const { history } = context;\n\n          const location = normalizeToLocation(\n            resolveToLocation(to, context.location),\n            context.location\n          );\n\n          const href = location ? history.createHref(location) : \"\";\n          const props = {\n            ...rest,\n            href,\n            navigate() {\n              const location = resolveToLocation(to, context.location);\n              const method = replace ? history.replace : history.push;\n\n              method(location);\n            }\n          };\n\n          // React 15 compat\n          if (forwardRefShim !== forwardRef) {\n            props.ref = forwardedRef || innerRef;\n          } else {\n            props.innerRef = innerRef;\n          }\n\n          return React.createElement(component, props);\n        }}\n      </RouterContext.Consumer>\n    );\n  }\n);\n\nif (__DEV__) {\n  const toType = PropTypes.oneOfType([\n    PropTypes.string,\n    PropTypes.object,\n    PropTypes.func\n  ]);\n  const refType = PropTypes.oneOfType([\n    PropTypes.string,\n    PropTypes.func,\n    PropTypes.shape({ current: PropTypes.any })\n  ]);\n\n  Link.displayName = \"Link\";\n\n  Link.propTypes = {\n    innerRef: refType,\n    onClick: PropTypes.func,\n    replace: PropTypes.bool,\n    target: PropTypes.string,\n    to: toType.isRequired\n  };\n}\n\nexport default Link;\n","import React from \"react\";\nimport { __RouterContext as RouterContext, matchPath } from \"react-router\";\nimport PropTypes from \"prop-types\";\nimport invariant from \"tiny-invariant\";\nimport Link from \"./Link.js\";\nimport {\n  resolveToLocation,\n  normalizeToLocation\n} from \"./utils/locationUtils.js\";\n\n// React 15 compat\nconst forwardRefShim = C => C;\nlet { forwardRef } = React;\nif (typeof forwardRef === \"undefined\") {\n  forwardRef = forwardRefShim;\n}\n\nfunction joinClassnames(...classnames) {\n  return classnames.filter(i => i).join(\" \");\n}\n\n/**\n * A <Link> wrapper that knows if it's \"active\" or not.\n */\nconst NavLink = forwardRef(\n  (\n    {\n      \"aria-current\": ariaCurrent = \"page\",\n      activeClassName = \"active\",\n      activeStyle,\n      className: classNameProp,\n      exact,\n      isActive: isActiveProp,\n      location: locationProp,\n      sensitive,\n      strict,\n      style: styleProp,\n      to,\n      innerRef, // TODO: deprecate\n      ...rest\n    },\n    forwardedRef\n  ) => {\n    return (\n      <RouterContext.Consumer>\n        {context => {\n          invariant(context, \"You should not use <NavLink> outside a <Router>\");\n\n          const currentLocation = locationProp || context.location;\n          const toLocation = normalizeToLocation(\n            resolveToLocation(to, currentLocation),\n            currentLocation\n          );\n          const { pathname: path } = toLocation;\n          // Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202\n          const escapedPath =\n            path && path.replace(/([.+*?=^!:${}()[\\]|/\\\\])/g, \"\\\\$1\");\n\n          const match = escapedPath\n            ? matchPath(currentLocation.pathname, {\n                path: escapedPath,\n                exact,\n                sensitive,\n                strict\n              })\n            : null;\n          const isActive = !!(isActiveProp\n            ? isActiveProp(match, currentLocation)\n            : match);\n\n          const className = isActive\n            ? joinClassnames(classNameProp, activeClassName)\n            : classNameProp;\n          const style = isActive ? { ...styleProp, ...activeStyle } : styleProp;\n\n          const props = {\n            \"aria-current\": (isActive && ariaCurrent) || null,\n            className,\n            style,\n            to: toLocation,\n            ...rest\n          };\n\n          // React 15 compat\n          if (forwardRefShim !== forwardRef) {\n            props.ref = forwardedRef || innerRef;\n          } else {\n            props.innerRef = innerRef;\n          }\n\n          return <Link {...props} />;\n        }}\n      </RouterContext.Consumer>\n    );\n  }\n);\n\nif (__DEV__) {\n  NavLink.displayName = \"NavLink\";\n\n  const ariaCurrentType = PropTypes.oneOf([\n    \"page\",\n    \"step\",\n    \"location\",\n    \"date\",\n    \"time\",\n    \"true\"\n  ]);\n\n  NavLink.propTypes = {\n    ...Link.propTypes,\n    \"aria-current\": ariaCurrentType,\n    activeClassName: PropTypes.string,\n    activeStyle: PropTypes.object,\n    className: PropTypes.string,\n    exact: PropTypes.bool,\n    isActive: PropTypes.func,\n    location: PropTypes.object,\n    sensitive: PropTypes.bool,\n    strict: PropTypes.bool,\n    style: PropTypes.object\n  };\n}\n\nexport default NavLink;\n","// TODO: Replace with React.createContext once we can assume React 16+\nimport createContext from \"mini-create-react-context\";\n\nconst createNamedContext = name => {\n  const context = createContext();\n  context.displayName = name;\n\n  return context;\n};\n\nexport default createNamedContext;\n","import createNamedContext from \"./createNameContext\";\n\nconst historyContext = /*#__PURE__*/ createNamedContext(\"Router-History\");\nexport default historyContext;\n","// TODO: Replace with React.createContext once we can assume React 16+\nimport createContext from \"mini-create-react-context\";\n\nconst createNamedContext = name => {\n  const context = createContext();\n  context.displayName = name;\n\n  return context;\n};\n\nconst context = /*#__PURE__*/ createNamedContext(\"Router\");\nexport default context;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport warning from \"tiny-warning\";\n\nimport HistoryContext from \"./HistoryContext.js\";\nimport RouterContext from \"./RouterContext.js\";\n\n/**\n * The public API for putting history on context.\n */\nclass Router extends React.Component {\n  static computeRootMatch(pathname) {\n    return { path: \"/\", url: \"/\", params: {}, isExact: pathname === \"/\" };\n  }\n\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      location: props.history.location\n    };\n\n    // This is a bit of a hack. We have to start listening for location\n    // changes here in the constructor in case there are any <Redirect>s\n    // on the initial render. If there are, they will replace/push when\n    // they mount and since cDM fires in children before parents, we may\n    // get a new location before the <Router> is mounted.\n    this._isMounted = false;\n    this._pendingLocation = null;\n\n    if (!props.staticContext) {\n      this.unlisten = props.history.listen(location => {\n        if (this._isMounted) {\n          this.setState({ location });\n        } else {\n          this._pendingLocation = location;\n        }\n      });\n    }\n  }\n\n  componentDidMount() {\n    this._isMounted = true;\n\n    if (this._pendingLocation) {\n      this.setState({ location: this._pendingLocation });\n    }\n  }\n\n  componentWillUnmount() {\n    if (this.unlisten) this.unlisten();\n  }\n\n  render() {\n    return (\n      <RouterContext.Provider\n        value={{\n          history: this.props.history,\n          location: this.state.location,\n          match: Router.computeRootMatch(this.state.location.pathname),\n          staticContext: this.props.staticContext\n        }}\n      >\n        <HistoryContext.Provider\n          children={this.props.children || null}\n          value={this.props.history}\n        />\n      </RouterContext.Provider>\n    );\n  }\n}\n\nif (__DEV__) {\n  Router.propTypes = {\n    children: PropTypes.node,\n    history: PropTypes.object.isRequired,\n    staticContext: PropTypes.object\n  };\n\n  Router.prototype.componentDidUpdate = function(prevProps) {\n    warning(\n      prevProps.history === this.props.history,\n      \"You cannot change <Router history>\"\n    );\n  };\n}\n\nexport default Router;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { createMemoryHistory as createHistory } from \"history\";\nimport warning from \"tiny-warning\";\n\nimport Router from \"./Router.js\";\n\n/**\n * The public API for a <Router> that stores location in memory.\n */\nclass MemoryRouter extends React.Component {\n  history = createHistory(this.props);\n\n  render() {\n    return <Router history={this.history} children={this.props.children} />;\n  }\n}\n\nif (__DEV__) {\n  MemoryRouter.propTypes = {\n    initialEntries: PropTypes.array,\n    initialIndex: PropTypes.number,\n    getUserConfirmation: PropTypes.func,\n    keyLength: PropTypes.number,\n    children: PropTypes.node\n  };\n\n  MemoryRouter.prototype.componentDidMount = function() {\n    warning(\n      !this.props.history,\n      \"<MemoryRouter> ignores the history prop. To use a custom history, \" +\n        \"use `import { Router }` instead of `import { MemoryRouter as Router }`.\"\n    );\n  };\n}\n\nexport default MemoryRouter;\n","import React from \"react\";\n\nclass Lifecycle extends React.Component {\n  componentDidMount() {\n    if (this.props.onMount) this.props.onMount.call(this, this);\n  }\n\n  componentDidUpdate(prevProps) {\n    if (this.props.onUpdate) this.props.onUpdate.call(this, this, prevProps);\n  }\n\n  componentWillUnmount() {\n    if (this.props.onUnmount) this.props.onUnmount.call(this, this);\n  }\n\n  render() {\n    return null;\n  }\n}\n\nexport default Lifecycle;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport invariant from \"tiny-invariant\";\n\nimport Lifecycle from \"./Lifecycle.js\";\nimport RouterContext from \"./RouterContext.js\";\n\n/**\n * The public API for prompting the user before navigating away from a screen.\n */\nfunction Prompt({ message, when = true }) {\n  return (\n    <RouterContext.Consumer>\n      {context => {\n        invariant(context, \"You should not use <Prompt> outside a <Router>\");\n\n        if (!when || context.staticContext) return null;\n\n        const method = context.history.block;\n\n        return (\n          <Lifecycle\n            onMount={self => {\n              self.release = method(message);\n            }}\n            onUpdate={(self, prevProps) => {\n              if (prevProps.message !== message) {\n                self.release();\n                self.release = method(message);\n              }\n            }}\n            onUnmount={self => {\n              self.release();\n            }}\n            message={message}\n          />\n        );\n      }}\n    </RouterContext.Consumer>\n  );\n}\n\nif (__DEV__) {\n  const messageType = PropTypes.oneOfType([PropTypes.func, PropTypes.string]);\n\n  Prompt.propTypes = {\n    when: PropTypes.bool,\n    message: messageType.isRequired\n  };\n}\n\nexport default Prompt;\n","import pathToRegexp from \"path-to-regexp\";\n\nconst cache = {};\nconst cacheLimit = 10000;\nlet cacheCount = 0;\n\nfunction compilePath(path) {\n  if (cache[path]) return cache[path];\n\n  const generator = pathToRegexp.compile(path);\n\n  if (cacheCount < cacheLimit) {\n    cache[path] = generator;\n    cacheCount++;\n  }\n\n  return generator;\n}\n\n/**\n * Public API for generating a URL pathname from a path and parameters.\n */\nfunction generatePath(path = \"/\", params = {}) {\n  return path === \"/\" ? path : compilePath(path)(params, { pretty: true });\n}\n\nexport default generatePath;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { createLocation, locationsAreEqual } from \"history\";\nimport invariant from \"tiny-invariant\";\n\nimport Lifecycle from \"./Lifecycle.js\";\nimport RouterContext from \"./RouterContext.js\";\nimport generatePath from \"./generatePath.js\";\n\n/**\n * The public API for navigating programmatically with a component.\n */\nfunction Redirect({ computedMatch, to, push = false }) {\n  return (\n    <RouterContext.Consumer>\n      {context => {\n        invariant(context, \"You should not use <Redirect> outside a <Router>\");\n\n        const { history, staticContext } = context;\n\n        const method = push ? history.push : history.replace;\n        const location = createLocation(\n          computedMatch\n            ? typeof to === \"string\"\n              ? generatePath(to, computedMatch.params)\n              : {\n                  ...to,\n                  pathname: generatePath(to.pathname, computedMatch.params)\n                }\n            : to\n        );\n\n        // When rendering in a static context,\n        // set the new location immediately.\n        if (staticContext) {\n          method(location);\n          return null;\n        }\n\n        return (\n          <Lifecycle\n            onMount={() => {\n              method(location);\n            }}\n            onUpdate={(self, prevProps) => {\n              const prevLocation = createLocation(prevProps.to);\n              if (\n                !locationsAreEqual(prevLocation, {\n                  ...location,\n                  key: prevLocation.key\n                })\n              ) {\n                method(location);\n              }\n            }}\n            to={to}\n          />\n        );\n      }}\n    </RouterContext.Consumer>\n  );\n}\n\nif (__DEV__) {\n  Redirect.propTypes = {\n    push: PropTypes.bool,\n    from: PropTypes.string,\n    to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired\n  };\n}\n\nexport default Redirect;\n","import pathToRegexp from \"path-to-regexp\";\n\nconst cache = {};\nconst cacheLimit = 10000;\nlet cacheCount = 0;\n\nfunction compilePath(path, options) {\n  const cacheKey = `${options.end}${options.strict}${options.sensitive}`;\n  const pathCache = cache[cacheKey] || (cache[cacheKey] = {});\n\n  if (pathCache[path]) return pathCache[path];\n\n  const keys = [];\n  const regexp = pathToRegexp(path, keys, options);\n  const result = { regexp, keys };\n\n  if (cacheCount < cacheLimit) {\n    pathCache[path] = result;\n    cacheCount++;\n  }\n\n  return result;\n}\n\n/**\n * Public API for matching a URL pathname to a path.\n */\nfunction matchPath(pathname, options = {}) {\n  if (typeof options === \"string\" || Array.isArray(options)) {\n    options = { path: options };\n  }\n\n  const { path, exact = false, strict = false, sensitive = false } = options;\n\n  const paths = [].concat(path);\n\n  return paths.reduce((matched, path) => {\n    if (!path && path !== \"\") return null;\n    if (matched) return matched;\n\n    const { regexp, keys } = compilePath(path, {\n      end: exact,\n      strict,\n      sensitive\n    });\n    const match = regexp.exec(pathname);\n\n    if (!match) return null;\n\n    const [url, ...values] = match;\n    const isExact = pathname === url;\n\n    if (exact && !isExact) return null;\n\n    return {\n      path, // the path used to match\n      url: path === \"/\" && url === \"\" ? \"/\" : url, // the matched portion of the URL\n      isExact, // whether or not we matched exactly\n      params: keys.reduce((memo, key, index) => {\n        memo[key.name] = values[index];\n        return memo;\n      }, {})\n    };\n  }, null);\n}\n\nexport default matchPath;\n","import React from \"react\";\nimport { isValidElementType } from \"react-is\";\nimport PropTypes from \"prop-types\";\nimport invariant from \"tiny-invariant\";\nimport warning from \"tiny-warning\";\n\nimport RouterContext from \"./RouterContext.js\";\nimport matchPath from \"./matchPath.js\";\n\nfunction isEmptyChildren(children) {\n  return React.Children.count(children) === 0;\n}\n\nfunction evalChildrenDev(children, props, path) {\n  const value = children(props);\n\n  warning(\n    value !== undefined,\n    \"You returned `undefined` from the `children` function of \" +\n      `<Route${path ? ` path=\"${path}\"` : \"\"}>, but you ` +\n      \"should have returned a React element or `null`\"\n  );\n\n  return value || null;\n}\n\n/**\n * The public API for matching a single path and rendering.\n */\nclass Route extends React.Component {\n  render() {\n    return (\n      <RouterContext.Consumer>\n        {context => {\n          invariant(context, \"You should not use <Route> outside a <Router>\");\n\n          const location = this.props.location || context.location;\n          const match = this.props.computedMatch\n            ? this.props.computedMatch // <Switch> already computed the match for us\n            : this.props.path\n            ? matchPath(location.pathname, this.props)\n            : context.match;\n\n          const props = { ...context, location, match };\n\n          let { children, component, render } = this.props;\n\n          // Preact uses an empty array as children by\n          // default, so use null if that's the case.\n          if (Array.isArray(children) && children.length === 0) {\n            children = null;\n          }\n\n          return (\n            <RouterContext.Provider value={props}>\n              {props.match\n                ? children\n                  ? typeof children === \"function\"\n                    ? __DEV__\n                      ? evalChildrenDev(children, props, this.props.path)\n                      : children(props)\n                    : children\n                  : component\n                  ? React.createElement(component, props)\n                  : render\n                  ? render(props)\n                  : null\n                : typeof children === \"function\"\n                ? __DEV__\n                  ? evalChildrenDev(children, props, this.props.path)\n                  : children(props)\n                : null}\n            </RouterContext.Provider>\n          );\n        }}\n      </RouterContext.Consumer>\n    );\n  }\n}\n\nif (__DEV__) {\n  Route.propTypes = {\n    children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),\n    component: (props, propName) => {\n      if (props[propName] && !isValidElementType(props[propName])) {\n        return new Error(\n          `Invalid prop 'component' supplied to 'Route': the prop is not a valid React component`\n        );\n      }\n    },\n    exact: PropTypes.bool,\n    location: PropTypes.object,\n    path: PropTypes.oneOfType([\n      PropTypes.string,\n      PropTypes.arrayOf(PropTypes.string)\n    ]),\n    render: PropTypes.func,\n    sensitive: PropTypes.bool,\n    strict: PropTypes.bool\n  };\n\n  Route.prototype.componentDidMount = function() {\n    warning(\n      !(\n        this.props.children &&\n        !isEmptyChildren(this.props.children) &&\n        this.props.component\n      ),\n      \"You should not use <Route component> and <Route children> in the same route; <Route component> will be ignored\"\n    );\n\n    warning(\n      !(\n        this.props.children &&\n        !isEmptyChildren(this.props.children) &&\n        this.props.render\n      ),\n      \"You should not use <Route render> and <Route children> in the same route; <Route render> will be ignored\"\n    );\n\n    warning(\n      !(this.props.component && this.props.render),\n      \"You should not use <Route component> and <Route render> in the same route; <Route render> will be ignored\"\n    );\n  };\n\n  Route.prototype.componentDidUpdate = function(prevProps) {\n    warning(\n      !(this.props.location && !prevProps.location),\n      '<Route> elements should not change from uncontrolled to controlled (or vice versa). You initially used no \"location\" prop and then provided one on a subsequent render.'\n    );\n\n    warning(\n      !(!this.props.location && prevProps.location),\n      '<Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a \"location\" prop initially but omitted it on a subsequent render.'\n    );\n  };\n}\n\nexport default Route;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { createLocation, createPath } from \"history\";\nimport invariant from \"tiny-invariant\";\nimport warning from \"tiny-warning\";\n\nimport Router from \"./Router.js\";\n\nfunction addLeadingSlash(path) {\n  return path.charAt(0) === \"/\" ? path : \"/\" + path;\n}\n\nfunction addBasename(basename, location) {\n  if (!basename) return location;\n\n  return {\n    ...location,\n    pathname: addLeadingSlash(basename) + location.pathname\n  };\n}\n\nfunction stripBasename(basename, location) {\n  if (!basename) return location;\n\n  const base = addLeadingSlash(basename);\n\n  if (location.pathname.indexOf(base) !== 0) return location;\n\n  return {\n    ...location,\n    pathname: location.pathname.substr(base.length)\n  };\n}\n\nfunction createURL(location) {\n  return typeof location === \"string\" ? location : createPath(location);\n}\n\nfunction staticHandler(methodName) {\n  return () => {\n    invariant(false, \"You cannot %s with <StaticRouter>\", methodName);\n  };\n}\n\nfunction noop() {}\n\n/**\n * The public top-level API for a \"static\" <Router>, so-called because it\n * can't actually change the current location. Instead, it just records\n * location changes in a context object. Useful mainly in testing and\n * server-rendering scenarios.\n */\nclass StaticRouter extends React.Component {\n  navigateTo(location, action) {\n    const { basename = \"\", context = {} } = this.props;\n    context.action = action;\n    context.location = addBasename(basename, createLocation(location));\n    context.url = createURL(context.location);\n  }\n\n  handlePush = location => this.navigateTo(location, \"PUSH\");\n  handleReplace = location => this.navigateTo(location, \"REPLACE\");\n  handleListen = () => noop;\n  handleBlock = () => noop;\n\n  render() {\n    const { basename = \"\", context = {}, location = \"/\", ...rest } = this.props;\n\n    const history = {\n      createHref: path => addLeadingSlash(basename + createURL(path)),\n      action: \"POP\",\n      location: stripBasename(basename, createLocation(location)),\n      push: this.handlePush,\n      replace: this.handleReplace,\n      go: staticHandler(\"go\"),\n      goBack: staticHandler(\"goBack\"),\n      goForward: staticHandler(\"goForward\"),\n      listen: this.handleListen,\n      block: this.handleBlock\n    };\n\n    return <Router {...rest} history={history} staticContext={context} />;\n  }\n}\n\nif (__DEV__) {\n  StaticRouter.propTypes = {\n    basename: PropTypes.string,\n    context: PropTypes.object,\n    location: PropTypes.oneOfType([PropTypes.string, PropTypes.object])\n  };\n\n  StaticRouter.prototype.componentDidMount = function() {\n    warning(\n      !this.props.history,\n      \"<StaticRouter> ignores the history prop. To use a custom history, \" +\n        \"use `import { Router }` instead of `import { StaticRouter as Router }`.\"\n    );\n  };\n}\n\nexport default StaticRouter;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport invariant from \"tiny-invariant\";\nimport warning from \"tiny-warning\";\n\nimport RouterContext from \"./RouterContext.js\";\nimport matchPath from \"./matchPath.js\";\n\n/**\n * The public API for rendering the first <Route> that matches.\n */\nclass Switch extends React.Component {\n  render() {\n    return (\n      <RouterContext.Consumer>\n        {context => {\n          invariant(context, \"You should not use <Switch> outside a <Router>\");\n\n          const location = this.props.location || context.location;\n\n          let element, match;\n\n          // We use React.Children.forEach instead of React.Children.toArray().find()\n          // here because toArray adds keys to all child elements and we do not want\n          // to trigger an unmount/remount for two <Route>s that render the same\n          // component at different URLs.\n          React.Children.forEach(this.props.children, child => {\n            if (match == null && React.isValidElement(child)) {\n              element = child;\n\n              const path = child.props.path || child.props.from;\n\n              match = path\n                ? matchPath(location.pathname, { ...child.props, path })\n                : context.match;\n            }\n          });\n\n          return match\n            ? React.cloneElement(element, { location, computedMatch: match })\n            : null;\n        }}\n      </RouterContext.Consumer>\n    );\n  }\n}\n\nif (__DEV__) {\n  Switch.propTypes = {\n    children: PropTypes.node,\n    location: PropTypes.object\n  };\n\n  Switch.prototype.componentDidUpdate = function(prevProps) {\n    warning(\n      !(this.props.location && !prevProps.location),\n      '<Switch> elements should not change from uncontrolled to controlled (or vice versa). You initially used no \"location\" prop and then provided one on a subsequent render.'\n    );\n\n    warning(\n      !(!this.props.location && prevProps.location),\n      '<Switch> elements should not change from controlled to uncontrolled (or vice versa). You provided a \"location\" prop initially but omitted it on a subsequent render.'\n    );\n  };\n}\n\nexport default Switch;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport hoistStatics from \"hoist-non-react-statics\";\nimport invariant from \"tiny-invariant\";\n\nimport RouterContext from \"./RouterContext.js\";\n\n/**\n * A public higher-order component to access the imperative API\n */\nfunction withRouter(Component) {\n  const displayName = `withRouter(${Component.displayName || Component.name})`;\n  const C = props => {\n    const { wrappedComponentRef, ...remainingProps } = props;\n\n    return (\n      <RouterContext.Consumer>\n        {context => {\n          invariant(\n            context,\n            `You should not use <${displayName} /> outside a <Router>`\n          );\n          return (\n            <Component\n              {...remainingProps}\n              {...context}\n              ref={wrappedComponentRef}\n            />\n          );\n        }}\n      </RouterContext.Consumer>\n    );\n  };\n\n  C.displayName = displayName;\n  C.WrappedComponent = Component;\n\n  if (__DEV__) {\n    C.propTypes = {\n      wrappedComponentRef: PropTypes.oneOfType([\n        PropTypes.string,\n        PropTypes.func,\n        PropTypes.object\n      ])\n    };\n  }\n\n  return hoistStatics(C, Component);\n}\n\nexport default withRouter;\n","import React from \"react\";\nimport invariant from \"tiny-invariant\";\n\nimport Context from \"./RouterContext.js\";\nimport HistoryContext from \"./HistoryContext.js\";\nimport matchPath from \"./matchPath.js\";\n\nconst useContext = React.useContext;\n\nexport function useHistory() {\n  if (__DEV__) {\n    invariant(\n      typeof useContext === \"function\",\n      \"You must use React >= 16.8 in order to use useHistory()\"\n    );\n  }\n\n  return useContext(HistoryContext);\n}\n\nexport function useLocation() {\n  if (__DEV__) {\n    invariant(\n      typeof useContext === \"function\",\n      \"You must use React >= 16.8 in order to use useLocation()\"\n    );\n  }\n\n  return useContext(Context).location;\n}\n\nexport function useParams() {\n  if (__DEV__) {\n    invariant(\n      typeof useContext === \"function\",\n      \"You must use React >= 16.8 in order to use useParams()\"\n    );\n  }\n\n  const match = useContext(Context).match;\n  return match ? match.params : {};\n}\n\nexport function useRouteMatch(path) {\n  if (__DEV__) {\n    invariant(\n      typeof useContext === \"function\",\n      \"You must use React >= 16.8 in order to use useRouteMatch()\"\n    );\n  }\n\n  const location = useLocation();\n  const match = useContext(Context).match;\n\n  return path ? matchPath(location.pathname, path) : match;\n}\n","if (__DEV__) {\n  if (typeof window !== \"undefined\") {\n    const global = window;\n    const key = \"__react_router_build__\";\n    const buildNames = { cjs: \"CommonJS\", esm: \"ES modules\", umd: \"UMD\" };\n\n    if (global[key] && global[key] !== process.env.BUILD_FORMAT) {\n      const initialBuildName = buildNames[global[key]];\n      const secondaryBuildName = buildNames[process.env.BUILD_FORMAT];\n\n      // TODO: Add link to article that explains in detail how to avoid\n      // loading 2 different builds.\n      throw new Error(\n        `You are loading the ${secondaryBuildName} build of React Router ` +\n          `on a page that is already running the ${initialBuildName} ` +\n          `build, so things won't work right.`\n      );\n    }\n\n    global[key] = process.env.BUILD_FORMAT;\n  }\n}\n\nexport { default as MemoryRouter } from \"./MemoryRouter.js\";\nexport { default as Prompt } from \"./Prompt.js\";\nexport { default as Redirect } from \"./Redirect.js\";\nexport { default as Route } from \"./Route.js\";\nexport { default as Router } from \"./Router.js\";\nexport { default as StaticRouter } from \"./StaticRouter.js\";\nexport { default as Switch } from \"./Switch.js\";\nexport { default as generatePath } from \"./generatePath.js\";\nexport { default as matchPath } from \"./matchPath.js\";\nexport { default as withRouter } from \"./withRouter.js\";\n\nimport { useHistory, useLocation, useParams, useRouteMatch } from \"./hooks.js\";\nexport { useHistory, useLocation, useParams, useRouteMatch };\n\nexport { default as __HistoryContext } from \"./HistoryContext.js\";\nexport { default as __RouterContext } from \"./RouterContext.js\";\n","module.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n","var isarray = require('isarray')\n\n/**\n * Expose `pathToRegexp`.\n */\nmodule.exports = pathToRegexp\nmodule.exports.parse = parse\nmodule.exports.compile = compile\nmodule.exports.tokensToFunction = tokensToFunction\nmodule.exports.tokensToRegExp = tokensToRegExp\n\n/**\n * The main path matching regexp utility.\n *\n * @type {RegExp}\n */\nvar PATH_REGEXP = new RegExp([\n  // Match escaped characters that would otherwise appear in future matches.\n  // This allows the user to escape special characters that won't transform.\n  '(\\\\\\\\.)',\n  // Match Express-style parameters and un-named parameters with a prefix\n  // and optional suffixes. Matches appear as:\n  //\n  // \"/:test(\\\\d+)?\" => [\"/\", \"test\", \"\\d+\", undefined, \"?\", undefined]\n  // \"/route(\\\\d+)\"  => [undefined, undefined, undefined, \"\\d+\", undefined, undefined]\n  // \"/*\"            => [\"/\", undefined, undefined, undefined, undefined, \"*\"]\n  '([\\\\/.])?(?:(?:\\\\:(\\\\w+)(?:\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))?|\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))([+*?])?|(\\\\*))'\n].join('|'), 'g')\n\n/**\n * Parse a string for the raw tokens.\n *\n * @param  {string}  str\n * @param  {Object=} options\n * @return {!Array}\n */\nfunction parse (str, options) {\n  var tokens = []\n  var key = 0\n  var index = 0\n  var path = ''\n  var defaultDelimiter = options && options.delimiter || '/'\n  var res\n\n  while ((res = PATH_REGEXP.exec(str)) != null) {\n    var m = res[0]\n    var escaped = res[1]\n    var offset = res.index\n    path += str.slice(index, offset)\n    index = offset + m.length\n\n    // Ignore already escaped sequences.\n    if (escaped) {\n      path += escaped[1]\n      continue\n    }\n\n    var next = str[index]\n    var prefix = res[2]\n    var name = res[3]\n    var capture = res[4]\n    var group = res[5]\n    var modifier = res[6]\n    var asterisk = res[7]\n\n    // Push the current path onto the tokens.\n    if (path) {\n      tokens.push(path)\n      path = ''\n    }\n\n    var partial = prefix != null && next != null && next !== prefix\n    var repeat = modifier === '+' || modifier === '*'\n    var optional = modifier === '?' || modifier === '*'\n    var delimiter = res[2] || defaultDelimiter\n    var pattern = capture || group\n\n    tokens.push({\n      name: name || key++,\n      prefix: prefix || '',\n      delimiter: delimiter,\n      optional: optional,\n      repeat: repeat,\n      partial: partial,\n      asterisk: !!asterisk,\n      pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')\n    })\n  }\n\n  // Match any characters still remaining.\n  if (index < str.length) {\n    path += str.substr(index)\n  }\n\n  // If the path exists, push it onto the end.\n  if (path) {\n    tokens.push(path)\n  }\n\n  return tokens\n}\n\n/**\n * Compile a string to a template function for the path.\n *\n * @param  {string}             str\n * @param  {Object=}            options\n * @return {!function(Object=, Object=)}\n */\nfunction compile (str, options) {\n  return tokensToFunction(parse(str, options), options)\n}\n\n/**\n * Prettier encoding of URI path segments.\n *\n * @param  {string}\n * @return {string}\n */\nfunction encodeURIComponentPretty (str) {\n  return encodeURI(str).replace(/[\\/?#]/g, function (c) {\n    return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n  })\n}\n\n/**\n * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.\n *\n * @param  {string}\n * @return {string}\n */\nfunction encodeAsterisk (str) {\n  return encodeURI(str).replace(/[?#]/g, function (c) {\n    return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n  })\n}\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nfunction tokensToFunction (tokens, options) {\n  // Compile all the tokens into regexps.\n  var matches = new Array(tokens.length)\n\n  // Compile all the patterns before compilation.\n  for (var i = 0; i < tokens.length; i++) {\n    if (typeof tokens[i] === 'object') {\n      matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options))\n    }\n  }\n\n  return function (obj, opts) {\n    var path = ''\n    var data = obj || {}\n    var options = opts || {}\n    var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent\n\n    for (var i = 0; i < tokens.length; i++) {\n      var token = tokens[i]\n\n      if (typeof token === 'string') {\n        path += token\n\n        continue\n      }\n\n      var value = data[token.name]\n      var segment\n\n      if (value == null) {\n        if (token.optional) {\n          // Prepend partial segment prefixes.\n          if (token.partial) {\n            path += token.prefix\n          }\n\n          continue\n        } else {\n          throw new TypeError('Expected \"' + token.name + '\" to be defined')\n        }\n      }\n\n      if (isarray(value)) {\n        if (!token.repeat) {\n          throw new TypeError('Expected \"' + token.name + '\" to not repeat, but received `' + JSON.stringify(value) + '`')\n        }\n\n        if (value.length === 0) {\n          if (token.optional) {\n            continue\n          } else {\n            throw new TypeError('Expected \"' + token.name + '\" to not be empty')\n          }\n        }\n\n        for (var j = 0; j < value.length; j++) {\n          segment = encode(value[j])\n\n          if (!matches[i].test(segment)) {\n            throw new TypeError('Expected all \"' + token.name + '\" to match \"' + token.pattern + '\", but received `' + JSON.stringify(segment) + '`')\n          }\n\n          path += (j === 0 ? token.prefix : token.delimiter) + segment\n        }\n\n        continue\n      }\n\n      segment = token.asterisk ? encodeAsterisk(value) : encode(value)\n\n      if (!matches[i].test(segment)) {\n        throw new TypeError('Expected \"' + token.name + '\" to match \"' + token.pattern + '\", but received \"' + segment + '\"')\n      }\n\n      path += token.prefix + segment\n    }\n\n    return path\n  }\n}\n\n/**\n * Escape a regular expression string.\n *\n * @param  {string} str\n * @return {string}\n */\nfunction escapeString (str) {\n  return str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1')\n}\n\n/**\n * Escape the capturing group by escaping special characters and meaning.\n *\n * @param  {string} group\n * @return {string}\n */\nfunction escapeGroup (group) {\n  return group.replace(/([=!:$\\/()])/g, '\\\\$1')\n}\n\n/**\n * Attach the keys as a property of the regexp.\n *\n * @param  {!RegExp} re\n * @param  {Array}   keys\n * @return {!RegExp}\n */\nfunction attachKeys (re, keys) {\n  re.keys = keys\n  return re\n}\n\n/**\n * Get the flags for a regexp from the options.\n *\n * @param  {Object} options\n * @return {string}\n */\nfunction flags (options) {\n  return options && options.sensitive ? '' : 'i'\n}\n\n/**\n * Pull out keys from a regexp.\n *\n * @param  {!RegExp} path\n * @param  {!Array}  keys\n * @return {!RegExp}\n */\nfunction regexpToRegexp (path, keys) {\n  // Use a negative lookahead to match only capturing groups.\n  var groups = path.source.match(/\\((?!\\?)/g)\n\n  if (groups) {\n    for (var i = 0; i < groups.length; i++) {\n      keys.push({\n        name: i,\n        prefix: null,\n        delimiter: null,\n        optional: false,\n        repeat: false,\n        partial: false,\n        asterisk: false,\n        pattern: null\n      })\n    }\n  }\n\n  return attachKeys(path, keys)\n}\n\n/**\n * Transform an array into a regexp.\n *\n * @param  {!Array}  path\n * @param  {Array}   keys\n * @param  {!Object} options\n * @return {!RegExp}\n */\nfunction arrayToRegexp (path, keys, options) {\n  var parts = []\n\n  for (var i = 0; i < path.length; i++) {\n    parts.push(pathToRegexp(path[i], keys, options).source)\n  }\n\n  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))\n\n  return attachKeys(regexp, keys)\n}\n\n/**\n * Create a path regexp from string input.\n *\n * @param  {string}  path\n * @param  {!Array}  keys\n * @param  {!Object} options\n * @return {!RegExp}\n */\nfunction stringToRegexp (path, keys, options) {\n  return tokensToRegExp(parse(path, options), keys, options)\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n *\n * @param  {!Array}          tokens\n * @param  {(Array|Object)=} keys\n * @param  {Object=}         options\n * @return {!RegExp}\n */\nfunction tokensToRegExp (tokens, keys, options) {\n  if (!isarray(keys)) {\n    options = /** @type {!Object} */ (keys || options)\n    keys = []\n  }\n\n  options = options || {}\n\n  var strict = options.strict\n  var end = options.end !== false\n  var route = ''\n\n  // Iterate over the tokens and create our regexp string.\n  for (var i = 0; i < tokens.length; i++) {\n    var token = tokens[i]\n\n    if (typeof token === 'string') {\n      route += escapeString(token)\n    } else {\n      var prefix = escapeString(token.prefix)\n      var capture = '(?:' + token.pattern + ')'\n\n      keys.push(token)\n\n      if (token.repeat) {\n        capture += '(?:' + prefix + capture + ')*'\n      }\n\n      if (token.optional) {\n        if (!token.partial) {\n          capture = '(?:' + prefix + '(' + capture + '))?'\n        } else {\n          capture = prefix + '(' + capture + ')?'\n        }\n      } else {\n        capture = prefix + '(' + capture + ')'\n      }\n\n      route += capture\n    }\n  }\n\n  var delimiter = escapeString(options.delimiter || '/')\n  var endsWithDelimiter = route.slice(-delimiter.length) === delimiter\n\n  // In non-strict mode we allow a slash at the end of match. If the path to\n  // match already ends with a slash, we remove it for consistency. The slash\n  // is valid at the end of a path match, not in the middle. This is important\n  // in non-ending mode, where \"/test/\" shouldn't match \"/test//route\".\n  if (!strict) {\n    route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'\n  }\n\n  if (end) {\n    route += '$'\n  } else {\n    // In non-ending mode, we need the capturing groups to match as much as\n    // possible by using a positive lookahead to the end or next path segment.\n    route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'\n  }\n\n  return attachKeys(new RegExp('^' + route, flags(options)), keys)\n}\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n *\n * @param  {(string|RegExp|Array)} path\n * @param  {(Array|Object)=}       keys\n * @param  {Object=}               options\n * @return {!RegExp}\n */\nfunction pathToRegexp (path, keys, options) {\n  if (!isarray(keys)) {\n    options = /** @type {!Object} */ (keys || options)\n    keys = []\n  }\n\n  options = options || {}\n\n  if (path instanceof RegExp) {\n    return regexpToRegexp(path, /** @type {!Array} */ (keys))\n  }\n\n  if (isarray(path)) {\n    return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)\n  }\n\n  return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)\n}\n","var api = require(\"!../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n            var content = require(\"!!../../css-loader/dist/cjs.js!./react-semantic-ui-datepickers.css\");\n\n            content = content.__esModule ? content.default : content;\n\n            if (typeof content === 'string') {\n              content = [[module.id, content, '']];\n            }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\nif (module.hot) {\n  if (!content.locals || module.hot.invalidate) {\n    var isEqualLocals = function isEqualLocals(a, b) {\n  if (!a && b || a && !b) {\n    return false;\n  }\n\n  var p;\n\n  for (p in a) {\n    if (a[p] !== b[p]) {\n      return false;\n    }\n  }\n\n  for (p in b) {\n    if (!a[p]) {\n      return false;\n    }\n  }\n\n  return true;\n};\n    var oldLocals = content.locals;\n\n    module.hot.accept(\n      \"!!../../css-loader/dist/cjs.js!./react-semantic-ui-datepickers.css\",\n      function () {\n        content = require(\"!!../../css-loader/dist/cjs.js!./react-semantic-ui-datepickers.css\");\n\n              content = content.__esModule ? content.default : content;\n\n              if (typeof content === 'string') {\n                content = [[module.id, content, '']];\n              }\n\n              if (!isEqualLocals(oldLocals, content.locals)) {\n                module.hot.invalidate();\n\n                return;\n              }\n\n              oldLocals = content.locals;\n\n              update(content);\n      }\n    )\n  }\n\n  module.hot.dispose(function() {\n    update();\n  });\n}\n\nmodule.exports = content.locals || {};","import { convertTokens } from '@date-fns/upgrade/v2';\nimport { parse } from 'date-fns';\nimport format from 'date-fns/format';\nimport isBefore from 'date-fns/isBefore';\nimport startOfDay from 'date-fns/startOfDay';\nimport { DateObj } from 'dayzed';\nimport { Object } from './types';\n\nexport const isSelectable = (date: Date, minDate?: Date, maxDate?: Date) => {\n  if (\n    (minDate && isBefore(date, minDate)) ||\n    (maxDate && isBefore(maxDate, date))\n  ) {\n    return false;\n  }\n\n  return true;\n};\n\nexport const getToday = (minDate?: Date, maxDate?: Date): DateObj => {\n  const today = new Date();\n\n  return {\n    date: startOfDay(today),\n    nextMonth: false,\n    prevMonth: false,\n    selectable: isSelectable(today, minDate, maxDate),\n    selected: false,\n    today: true,\n  };\n};\n\nexport const formatDate = (date: Date | null, dateFormat: string) =>\n  date ? format(startOfDay(date), convertTokens(dateFormat)) : undefined;\n\nexport const omit = (keysToOmit: string[], obj: Object) => {\n  const newObj = { ...obj };\n\n  keysToOmit.forEach((key) => delete newObj[key]);\n\n  return newObj;\n};\n\nexport const pick = (keysToPick: string[], obj: Object) => {\n  const newObj: Object = {};\n\n  keysToPick.forEach((key) => {\n    newObj[key] = obj[key];\n  });\n\n  return newObj;\n};\n\nexport const moveElementsByN = <T>(n: number, arr: T[]) =>\n  arr.slice(n).concat(arr.slice(0, n));\n\nexport const formatSelectedDate = (\n  selectedDate: Date | Date[] | null | undefined,\n  dateFormat: string\n) => {\n  if (!selectedDate) {\n    return '';\n  }\n\n  return Array.isArray(selectedDate)\n    ? selectedDate.map((date) => formatDate(date, dateFormat)).join(' - ')\n    : formatDate(selectedDate, dateFormat);\n};\n\nexport const parseFormatString = (formatString: string) =>\n  formatString.replace(/[D, Y]/gi, (a) => a.toLowerCase());\n\nexport const parseOnBlur = (typedValue: string, formatString: string) => {\n  return parse(typedValue, parseFormatString(formatString), new Date());\n};\n\nexport const parseRangeOnBlur = (typedValue: string, formatString: string) => {\n  const parsedFormatString = parseFormatString(formatString);\n\n  const rangeValues = typedValue.split(' - ');\n\n  return rangeValues\n    .map((value) => parse(value, parsedFormatString, new Date()))\n    .sort((a, b) => (a > b ? 1 : -1));\n};\n\nexport const onlyNumbers = (value = '') => value.replace(/[^\\d]/g, '');\n\nexport function getShortDate(date?: Date) {\n  if (!date) {\n    return undefined;\n  }\n\n  return date.toISOString().slice(0, 10);\n}\n","/**\n * This is intended to be used to compose event handlers\n * They are executed in order until one of them calls\n * `event.preventDefault()`. Not sure this is the best\n * way to do this, but it seems legit...\n * @param {Function} fns the event hanlder functions\n * @return {Function} the event handler to add to an element\n */\nexport function composeEventHandlers(...fns) {\n  return (event, ...args) =>\n    fns.some((fn) => {\n      if (fn) {\n        fn(event, ...args);\n      }\n\n      return event.defaultPrevented;\n    });\n}\n\n/**\n * Create an event handler for keyboard key given a config map\n * of event handlers\n * @param {Object} config consists of left, right, up, and down\n * @return {Function} the event handler to handle keyboard key\n */\nexport function getArrowKeyHandlers(config) {\n  return (event) => {\n    const { keyCode } = event;\n    const fn = {\n      37: config.left,\n      39: config.right,\n      38: config.up,\n      40: config.down,\n    }[keyCode];\n    if (fn) {\n      fn(event);\n    }\n  };\n}\n\n/**\n * Checks if a given date is with date range\n * @param {Array} range the range array with upper and lower bound\n * @param {Date} date a given date\n * @return {Boolean} true if date is in the range, false otherwise\n */\nexport function isInRange(range, date) {\n  return range.length === 2 && range[0] <= date && range[1] >= date;\n}\n","import Dayzed from 'dayzed';\nimport React from 'react';\nimport { BaseDatePickerProps } from '../types';\nimport { getArrowKeyHandlers } from './utils';\n\nclass BaseDatePicker extends React.Component<BaseDatePickerProps> {\n  state = {\n    offset: 0,\n  };\n\n  rootNode = React.createRef<HTMLElement>();\n\n  handleArrowKeys = getArrowKeyHandlers({\n    left: () => {\n      this.getKeyOffset(-1);\n    },\n    right: () => {\n      this.getKeyOffset(1);\n    },\n    up: () => {\n      this.getKeyOffset(-7);\n    },\n    down: () => {\n      this.getKeyOffset(7);\n    },\n  });\n\n  getKeyOffset(number) {\n    if (!this.rootNode.current) {\n      return;\n    }\n\n    const e = document.activeElement;\n    const buttons = this.rootNode.current.querySelectorAll('button');\n    buttons.forEach((el, i) => {\n      const newNodeKey = i + number;\n      if (el === e) {\n        if (newNodeKey <= buttons.length - 1 && newNodeKey >= 0) {\n          buttons[newNodeKey].focus();\n        } else {\n          buttons[0].focus();\n        }\n      }\n    });\n  }\n\n  setRootNode = (ref) => {\n    this.rootNode = ref;\n  };\n\n  getRootProps = ({ refKey = 'ref', ...rest } = {}) => {\n    return {\n      [refKey]: this.setRootNode,\n      onKeyDown: this.handleArrowKeys,\n      ...rest,\n    };\n  };\n\n  _handleOffsetChanged = (offset) => {\n    this.setState({\n      offset,\n    });\n  };\n\n  componentDidUpdate(prevProps) {\n    if (this.props.date !== prevProps.date) {\n      this._handleOffsetChanged(0);\n    }\n  }\n\n  render() {\n    const { children, ...rest } = this.props;\n\n    return (\n      <Dayzed\n        {...rest}\n        offset={this.state.offset}\n        onOffsetChanged={this._handleOffsetChanged}\n        render={(renderProps) =>\n          children({\n            ...renderProps,\n            getRootProps: this.getRootProps,\n          })\n        }\n      />\n    );\n  }\n}\n\nexport default BaseDatePicker;\n","import React from 'react';\nimport { BasicDatePickerProps } from '../types';\nimport BaseDatePicker from './base';\n\nclass DatePicker extends React.Component<BasicDatePickerProps> {\n  _handleOnDateSelected = (\n    { selectable, date },\n    event: React.SyntheticEvent\n  ) => {\n    const { selected: selectedDate, onChange } = this.props;\n\n    if (!selectable) {\n      return;\n    }\n\n    let newDate = date;\n    if (selectedDate && selectedDate.getTime() === date.getTime()) {\n      newDate = null;\n    }\n\n    if (onChange) {\n      onChange(event, newDate);\n    }\n  };\n\n  render() {\n    return (\n      <BaseDatePicker\n        {...this.props}\n        onDateSelected={this._handleOnDateSelected}\n      />\n    );\n  }\n}\n\nexport default DatePicker;\n","import compareAsc from 'date-fns/compareAsc';\nimport isSameDay from 'date-fns/isSameDay';\nimport React from 'react';\nimport { RangeDatePickerProps } from '../types';\nimport BaseDatePicker from './base';\nimport { composeEventHandlers, isInRange } from './utils';\n\ntype RangeDatePickerState = {\n  hoveredDate: Date | null;\n};\n\nclass RangeDatePicker extends React.Component<\n  RangeDatePickerProps,\n  RangeDatePickerState\n> {\n  static defaultProps = {\n    selected: [],\n  };\n\n  state = { hoveredDate: null };\n\n  setHoveredDate = (date) => {\n    this.setState((state) =>\n      state.hoveredDate === date ? null : { hoveredDate: date }\n    );\n  };\n\n  // Calendar level\n  onMouseLeave = () => {\n    this.setHoveredDate(null);\n  };\n\n  // Date level\n  onHoverFocusDate(date) {\n    if (this.props.selected.length !== 1) {\n      return;\n    }\n    this.setHoveredDate(date);\n  }\n\n  _handleOnDateSelected = (\n    { selectable, date },\n    event: React.SyntheticEvent\n  ) => {\n    const { selected: selectedDates, onChange } = this.props;\n\n    if (!selectable) {\n      return;\n    }\n\n    const dateTime = date.getTime();\n    let newDates = [...selectedDates];\n    if (selectedDates.length) {\n      if (selectedDates.length === 1) {\n        const firstTime = selectedDates[0].getTime();\n        if (firstTime < dateTime) {\n          newDates.push(date);\n        } else {\n          newDates.unshift(date);\n        }\n      } else if (newDates.length === 2) {\n        newDates = [date];\n      }\n    } else {\n      newDates.push(date);\n    }\n\n    if (onChange) {\n      onChange(event, newDates);\n    }\n\n    if (newDates.length === 2) {\n      this.setHoveredDate(null);\n    }\n  };\n\n  getEnhancedDateProps = (\n    getDateProps,\n    dateBounds,\n    { onMouseEnter, onFocus, ...restProps }\n  ) => {\n    const { hoveredDate } = this.state;\n    const { date } = restProps.dateObj;\n    return getDateProps({\n      ...restProps,\n      inRange: isInRange(dateBounds, date),\n      start: dateBounds[0] && isSameDay(dateBounds[0], date),\n      end: dateBounds[1] && isSameDay(dateBounds[1], date),\n      // @ts-ignore\n      hovered: hoveredDate && isSameDay(hoveredDate, date),\n      onMouseEnter: composeEventHandlers(onMouseEnter, () => {\n        this.onHoverFocusDate(date);\n      }),\n      onFocus: composeEventHandlers(onFocus, () => {\n        this.onHoverFocusDate(date);\n      }),\n    });\n  };\n\n  getEnhancedRootProps = (getRootProps, props) =>\n    getRootProps({\n      ...props,\n      onMouseLeave: this.onMouseLeave,\n    });\n\n  render() {\n    const { children, ...rest } = this.props;\n    const { hoveredDate } = this.state;\n    const { selected } = this.props;\n\n    const dateBounds =\n      selected.length === 2 || !selected.length || !hoveredDate\n        ? selected\n        : // prettier-ignore\n          // @ts-ignore\n          [selected[0], hoveredDate].sort(compareAsc);\n\n    return (\n      <BaseDatePicker {...rest} onDateSelected={this._handleOnDateSelected}>\n        {({ getRootProps, getDateProps, ...renderProps }) =>\n          children({\n            ...renderProps,\n            getRootProps: this.getEnhancedRootProps.bind(this, getRootProps),\n            getDateProps: this.getEnhancedDateProps.bind(\n              this,\n              getDateProps,\n              dateBounds\n            ),\n          })\n        }\n      </BaseDatePicker>\n    );\n  }\n}\n\nexport default RangeDatePicker;\n","import React from 'react';\nimport { Button, ButtonProps } from 'semantic-ui-react';\n\nconst CustomButton = ({ icon, ...otherProps }: ButtonProps) => (\n  <Button basic compact icon={icon} {...otherProps} />\n);\n\nexport default CustomButton;\n","function styleInject(css, ref) {\n  if ( ref === void 0 ) ref = {};\n  var insertAt = ref.insertAt;\n\n  if (!css || typeof document === 'undefined') { return; }\n\n  var head = document.head || document.getElementsByTagName('head')[0];\n  var style = document.createElement('style');\n  style.type = 'text/css';\n\n  if (insertAt === 'top') {\n    if (head.firstChild) {\n      head.insertBefore(style, head.firstChild);\n    } else {\n      head.appendChild(style);\n    }\n  } else {\n    head.appendChild(style);\n  }\n\n  if (style.styleSheet) {\n    style.styleSheet.cssText = css;\n  } else {\n    style.appendChild(document.createTextNode(css));\n  }\n}\n\nexport default styleInject;\n","import cn from 'classnames';\nimport React from 'react';\nimport './cell.css';\n\ntype CalendarCellProps = {\n  end?: boolean;\n  hovered?: boolean;\n  inRange?: boolean;\n  nextMonth?: boolean;\n  prevMonth?: boolean;\n  selectable?: boolean;\n  selected?: boolean;\n  start?: boolean;\n  today?: boolean;\n  title?: string;\n};\n\nconst CalendarCell: React.FC<CalendarCellProps> = ({\n  end,\n  hovered,\n  inRange,\n  nextMonth,\n  prevMonth,\n  selectable,\n  selected,\n  start,\n  today,\n  ...otherProps\n}) => (\n  <span\n    className={cn('clndr-cell', {\n      'clndr-cell-today': today,\n      'clndr-cell-disabled': !selectable,\n      'clndr-cell-other-month': nextMonth || prevMonth,\n      'clndr-cell-inrange': inRange,\n      'clndr-cell-selected': selected,\n    })}\n    {...otherProps}\n  />\n);\n\nCalendarCell.defaultProps = {\n  end: false,\n  hovered: false,\n  inRange: false,\n  nextMonth: false,\n  prevMonth: false,\n  start: false,\n};\n\nexport default CalendarCell;\n","import React from 'react';\nimport { DateObj } from 'dayzed';\nimport { Button } from 'semantic-ui-react';\n\ninterface TodayButtonProps extends DateObj {\n  end?: boolean;\n  hovered?: boolean;\n  inRange?: boolean;\n  start?: boolean;\n}\n\nconst style: React.CSSProperties = { marginTop: 10 };\n\nconst TodayButton: React.FC<TodayButtonProps> = ({\n  end,\n  hovered,\n  inRange,\n  nextMonth,\n  prevMonth,\n  selectable,\n  selected,\n  start,\n  today,\n  ...otherProps\n}) => (\n  <Button\n    className=\"clndr-button-today\"\n    compact\n    data-testid=\"datepicker-today-button\"\n    fluid\n    style={style}\n    {...otherProps}\n  />\n);\n\nexport default TodayButton;\n","import cn from 'classnames';\nimport React, { Fragment } from 'react';\nimport { Segment } from 'semantic-ui-react';\nimport { Locale, RenderProps, SemanticDatepickerProps } from 'types';\nimport { getShortDate, getToday } from '../../utils';\nimport Button from '../button';\nimport CalendarCell from '../cell';\nimport TodayButton from '../today-button';\nimport './calendar.css';\n\ninterface CalendarProps extends RenderProps {\n  filterDate: (date: Date) => boolean;\n  inline: SemanticDatepickerProps['inline'];\n  maxDate?: Date;\n  minDate?: Date;\n  months: Locale['months'];\n  nextMonth: string;\n  nextYear: string;\n  pointing: SemanticDatepickerProps['pointing'];\n  previousMonth: string;\n  previousYear: string;\n  showToday: SemanticDatepickerProps['showToday'];\n  todayButton: string;\n  weekdays: Locale['weekdays'];\n}\n\nconst styles: { [key: string]: React.CSSProperties } = {\n  leftBtn: { textAlign: 'start' },\n  rightBtn: { textAlign: 'end' },\n};\n\nconst pointings = {\n  'top left': 'clndr-top clndr-left',\n  'top right': 'clndr-top clndr-right',\n  left: 'clndr-left',\n  right: 'clndr-right',\n};\n\nconst Calendar: React.FC<CalendarProps> = ({\n  calendars,\n  filterDate,\n  getBackProps,\n  getDateProps,\n  getForwardProps,\n  inline,\n  maxDate,\n  minDate,\n  months,\n  nextMonth,\n  nextYear,\n  previousMonth,\n  previousYear,\n  showToday,\n  todayButton,\n  weekdays,\n  pointing,\n}) => (\n  <Segment\n    className={cn('clndr-calendars-segment', {\n      'clndr-floating': !inline,\n      [pointings[pointing]]: !inline,\n    })}\n  >\n    <div\n      className=\"clndr-calendars-wrapper\"\n      style={{ '--n': calendars.length } as React.CSSProperties}\n    >\n      {calendars.map((calendar, calendarIdx) => (\n        <div key={`${calendar.year}-${calendar.month}`}>\n          <div className=\"clndr-control\">\n            <div style={styles.leftBtn}>\n              {calendarIdx === 0 && (\n                <Fragment>\n                  <Button\n                    icon=\"angle double left\"\n                    title={previousYear}\n                    {...getBackProps({ calendars, offset: 12 })}\n                  />\n                  <Button\n                    icon=\"angle left\"\n                    style={{ marginRight: 0 }}\n                    title={previousMonth}\n                    {...getBackProps({ calendars })}\n                  />\n                </Fragment>\n              )}\n            </div>\n\n            <span title={`${months[calendar.month]} ${calendar.year}`}>\n              {months[calendar.month].slice(0, 3)} {calendar.year}\n            </span>\n\n            <div style={styles.rightBtn}>\n              {calendarIdx === calendars.length - 1 && (\n                <Fragment>\n                  <Button\n                    icon=\"angle right\"\n                    title={nextMonth}\n                    {...getForwardProps({ calendars })}\n                  />\n                  <Button\n                    icon=\"angle double right\"\n                    style={{ marginRight: 0 }}\n                    title={nextYear}\n                    {...getForwardProps({ calendars, offset: 12 })}\n                  />\n                </Fragment>\n              )}\n            </div>\n          </div>\n          <div className=\"clndr-days\">\n            {weekdays.map((weekday) => (\n              <CalendarCell\n                key={`${calendar.year}-${calendar.month}-${weekday}`}\n                title={weekday}\n              >\n                {weekday.slice(0, 2)}\n              </CalendarCell>\n            ))}\n            {calendar.weeks.map((week) =>\n              week.map((dateObj, weekIdx) => {\n                const key = `${calendar.year}-${calendar.month}-${weekIdx}`;\n\n                if (!dateObj) {\n                  return <CalendarCell key={key} />;\n                }\n\n                const selectable =\n                  dateObj.selectable && filterDate(dateObj.date);\n                const shortDate = getShortDate(dateObj.date);\n\n                return (\n                  <CalendarCell\n                    key={key}\n                    {...dateObj}\n                    {...getDateProps({ dateObj: { ...dateObj, selectable } })}\n                    data-testid={`datepicker-cell-${shortDate}`}\n                    selectable={selectable}\n                  >\n                    {dateObj.date.getDate()}\n                  </CalendarCell>\n                );\n              })\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n    {showToday && (\n      <TodayButton\n        {...getToday(minDate, maxDate)}\n        {...getDateProps({\n          dateObj: getToday(minDate, maxDate),\n        })}\n      >\n        {todayButton}\n      </TodayButton>\n    )}\n  </Segment>\n);\n\nexport default Calendar;\n","import React from 'react';\nimport { Icon as SUIIcon } from 'semantic-ui-react';\nimport { SemanticDatepickerProps } from '../types';\n\ntype CustomIconProps = {\n  clearIcon: SemanticDatepickerProps['clearIcon'];\n  icon: SemanticDatepickerProps['icon'];\n  isClearIconVisible: boolean;\n  onClear: () => void;\n  onClick: () => void;\n};\n\nconst CustomIcon = ({\n  clearIcon,\n  icon,\n  isClearIconVisible,\n  onClear,\n  onClick,\n}: CustomIconProps) => {\n  if (isClearIconVisible && clearIcon && React.isValidElement(clearIcon)) {\n    return React.cloneElement(clearIcon, {\n      'data-testid': 'datepicker-icon',\n      onClick: onClear,\n    });\n  }\n\n  if (isClearIconVisible && clearIcon && !React.isValidElement(clearIcon)) {\n    return (\n      <SUIIcon\n        data-testid=\"datepicker-icon\"\n        link\n        name={clearIcon}\n        onClick={onClear}\n      />\n    );\n  }\n\n  if (icon && React.isValidElement(icon)) {\n    return React.cloneElement(icon, {\n      'data-testid': 'datepicker-icon',\n      onClick,\n    });\n  }\n\n  return (\n    <SUIIcon data-testid=\"datepicker-icon\" link name={icon} onClick={onClick} />\n  );\n};\n\nexport default CustomIcon;\n","import React from 'react';\nimport { Form, Input, FormInputProps } from 'semantic-ui-react';\nimport { SemanticDatepickerProps } from '../types';\nimport CustomIcon from './icon';\n\ntype InputProps = FormInputProps & {\n  clearIcon: SemanticDatepickerProps['clearIcon'];\n  icon: SemanticDatepickerProps['icon'];\n  isClearIconVisible: boolean;\n};\n\nconst CustomInput = React.forwardRef<Input, InputProps>((props, ref) => {\n  const {\n    clearIcon,\n    icon,\n    isClearIconVisible,\n    label,\n    onClear,\n    onClick,\n    required,\n    value,\n    ...rest\n  } = props;\n\n  return (\n    <Form.Field required={required}>\n      {label && <label htmlFor={rest.id as string | undefined}>{label}</label>}\n      <Input\n        data-testid=\"datepicker-input\"\n        {...rest}\n        ref={ref}\n        required={required}\n        icon={\n          <CustomIcon\n            clearIcon={clearIcon}\n            icon={icon}\n            isClearIconVisible={isClearIconVisible}\n            onClear={onClear}\n            onClick={onClick}\n          />\n        }\n        onClick={onClick}\n        value={value}\n      />\n    </Form.Field>\n  );\n});\n\nexport default CustomInput;\n","import isValid from 'date-fns/isValid';\nimport formatStringByPattern from 'format-string-by-pattern';\nimport React from 'react';\nimport isEqual from 'react-fast-compare';\nimport { Input as SUIInput } from 'semantic-ui-react';\nimport {\n  formatSelectedDate,\n  moveElementsByN,\n  omit,\n  onlyNumbers,\n  parseOnBlur,\n  parseRangeOnBlur,\n  pick,\n} from './utils';\nimport { BasicDatePicker, RangeDatePicker } from './pickers';\nimport { Locale, SemanticDatepickerProps } from './types';\nimport Calendar from './components/calendar';\nimport Input from './components/input';\n\nconst style: React.CSSProperties = {\n  display: 'inline-block',\n  position: 'relative',\n};\nconst semanticInputProps = [\n  'autoComplete',\n  'className',\n  'clearIcon',\n  'disabled',\n  'error',\n  'icon',\n  'iconPosition',\n  'id',\n  'label',\n  'loading',\n  'name',\n  'onBlur',\n  'onChange',\n  'onClick',\n  'onContextMenu',\n  'onDoubleClick',\n  'onFocus',\n  'onInput',\n  'onKeyDown',\n  'onKeyPress',\n  'onKeyUp',\n  'onMouseDown',\n  'onMouseEnter',\n  'onMouseLeave',\n  'onMouseMove',\n  'onMouseOut',\n  'onMouseOver',\n  'onMouseUp',\n  'placeholder',\n  'required',\n  'size',\n  'transparent',\n  'readOnly',\n];\n\ntype SemanticDatepickerState = {\n  isVisible: boolean;\n  locale: Locale;\n  selectedDate: Date | Date[] | null;\n  selectedDateFormatted?: string;\n  typedValue: string | null;\n};\n\nclass SemanticDatepicker extends React.Component<\n  SemanticDatepickerProps,\n  SemanticDatepickerState\n> {\n  static defaultProps = {\n    allowOnlyNumbers: false,\n    clearIcon: 'close',\n    clearOnSameDateClick: true,\n    clearable: true,\n    date: undefined,\n    filterDate: () => true,\n    firstDayOfWeek: 0,\n    format: 'YYYY-MM-DD',\n    icon: 'calendar',\n    id: undefined,\n    inline: false,\n    keepOpenOnClear: false,\n    keepOpenOnSelect: false,\n    label: undefined,\n    locale: 'en-US',\n    name: undefined,\n    onBlur: () => {},\n    onChange: () => {},\n    placeholder: undefined,\n    pointing: 'left',\n    readOnly: false,\n    datePickerOnly: false,\n    required: false,\n    showToday: true,\n    showOutsideDays: false,\n    type: 'basic',\n    value: null,\n  };\n\n  el = React.createRef<HTMLDivElement>();\n  inputRef = React.createRef<SUIInput>();\n\n  componentDidUpdate(prevProps: SemanticDatepickerProps) {\n    const { locale, value } = this.props;\n\n    if (!isEqual(value, prevProps.value)) {\n      this.onDateSelected(undefined, value);\n    }\n\n    if (locale !== prevProps.locale) {\n      this.setState({ locale: this.locale });\n    }\n  }\n\n  get isRangeInput() {\n    return this.props.type === 'range';\n  }\n\n  get initialState() {\n    const { format, value } = this.props;\n    const initialSelectedDate = this.isRangeInput ? [] : null;\n\n    return {\n      isVisible: false,\n      locale: this.locale,\n      selectedDate: value || initialSelectedDate,\n      selectedDateFormatted: formatSelectedDate(value, format),\n      typedValue: null,\n    };\n  }\n\n  get dayzedProps() {\n    return omit(semanticInputProps, this.props);\n  }\n\n  get inputProps() {\n    const props = pick(semanticInputProps, this.props);\n    const placeholder =\n      props.placeholder !== undefined ? props.placeholder : this.props.format;\n\n    return {\n      ...props,\n      placeholder,\n    };\n  }\n\n  get date() {\n    const { selectedDate } = this.state;\n    const { date } = this.props;\n\n    if (!selectedDate) {\n      return date;\n    }\n\n    return this.isRangeInput ? selectedDate[0] : selectedDate;\n  }\n\n  get locale() {\n    const { locale } = this.props;\n\n    let localeJson: Locale;\n\n    try {\n      localeJson = require(`./locales/${locale}.json`);\n    } catch (e) {\n      console.warn(`\"${locale}\" is not a valid locale`);\n      localeJson = require('./locales/en-US.json');\n    }\n\n    return localeJson;\n  }\n\n  get weekdays() {\n    const { firstDayOfWeek } = this.dayzedProps;\n    const { weekdays } = this.state.locale;\n\n    return moveElementsByN(firstDayOfWeek, weekdays);\n  }\n\n  state = this.initialState;\n\n  Component: React.ElementType = this.isRangeInput\n    ? RangeDatePicker\n    : BasicDatePicker;\n\n  resetState = (event) => {\n    const { keepOpenOnClear, onChange } = this.props;\n    const newState = {\n      isVisible: keepOpenOnClear,\n      selectedDate: this.isRangeInput ? [] : null,\n      selectedDateFormatted: '',\n    };\n\n    this.setState(newState, () => {\n      onChange(event, { ...this.props, value: null });\n    });\n  };\n\n  clearInput = (event) => {\n    this.resetState(event);\n    this.handleBlur(event);\n  };\n\n  mousedownCb = (mousedownEvent) => {\n    const { isVisible } = this.state;\n\n    if (isVisible && this.el) {\n      if (this.el.current && !this.el.current.contains(mousedownEvent.target)) {\n        this.close(mousedownEvent);\n      }\n    }\n  };\n\n  keydownCb = (keydownEvent) => {\n    const { isVisible } = this.state;\n    if (keydownEvent.keyCode === 27 && isVisible) {\n      // Escape\n      this.close(keydownEvent);\n    }\n  };\n\n  close = (event) => {\n    window.removeEventListener('keydown', this.keydownCb);\n    window.removeEventListener('mousedown', this.mousedownCb);\n\n    this.handleBlur(event);\n    this.setState({\n      isVisible: false,\n    });\n  };\n\n  focusOnInput = () => {\n    if (this.inputRef?.current?.focus) {\n      this.inputRef.current.focus();\n    }\n  };\n\n  showCalendar = (event) => {\n    event.preventDefault();\n    window.addEventListener('mousedown', this.mousedownCb);\n    window.addEventListener('keydown', this.keydownCb);\n\n    this.focusOnInput();\n    this.setState({\n      isVisible: true,\n    });\n  };\n\n  handleRangeInput = (newDates, event, fromBlur = false) => {\n    const { format, keepOpenOnSelect, onChange } = this.props;\n\n    if (!newDates || !newDates.length) {\n      this.resetState(event);\n\n      if (!fromBlur) {\n        this.handleBlur(event);\n      }\n\n      return;\n    }\n\n    const newState = {\n      selectedDate: newDates,\n      selectedDateFormatted: formatSelectedDate(newDates, format),\n      typedValue: null,\n    };\n\n    this.setState(newState, () => {\n      onChange(event, { ...this.props, value: newDates });\n\n      if (newDates.length === 2) {\n        this.setState({ isVisible: keepOpenOnSelect });\n\n        if (keepOpenOnSelect) {\n          this.focusOnInput();\n        } else if (!fromBlur) {\n          this.handleBlur(event);\n        }\n      } else if (newDates.length === 1) {\n        this.focusOnInput();\n      } else if (!fromBlur) {\n        this.handleBlur(event);\n      }\n    });\n  };\n\n  handleBasicInput = (newDate, event, fromBlur = false) => {\n    const {\n      format,\n      keepOpenOnSelect,\n      onChange,\n      clearOnSameDateClick,\n    } = this.props;\n\n    if (!newDate) {\n      // if clearOnSameDateClick is true (this is the default case)\n      // then reset the state. This is what was previously the default\n      // behavior, without a specific prop.\n      if (clearOnSameDateClick) {\n        this.resetState(event);\n\n        if (!fromBlur) {\n          this.handleBlur(event);\n        }\n      } else {\n        // Don't reset the state. Instead, close or keep open the\n        // datepicker according to the value of keepOpenOnSelect.\n        // Essentially, follow the default behavior of clicking a date\n        // but without changing the value in state.\n        this.setState({\n          isVisible: keepOpenOnSelect,\n        });\n\n        if (keepOpenOnSelect) {\n          this.focusOnInput();\n        } else if (!fromBlur) {\n          this.handleBlur(event);\n        }\n      }\n\n      return;\n    }\n\n    const newState = {\n      isVisible: keepOpenOnSelect,\n      selectedDate: newDate,\n      selectedDateFormatted: formatSelectedDate(newDate, format),\n      typedValue: null,\n    };\n\n    if (keepOpenOnSelect) {\n      this.focusOnInput();\n    } else if (!fromBlur) {\n      this.handleBlur(event);\n    }\n\n    this.setState(newState, () => {\n      onChange(event, { ...this.props, value: newDate });\n    });\n  };\n\n  handleBlur = (event?: React.SyntheticEvent) => {\n    const { format, onBlur, onChange } = this.props;\n    const { typedValue } = this.state;\n\n    onBlur(event);\n\n    if (!typedValue) {\n      return;\n    }\n\n    if (this.isRangeInput) {\n      const parsedValue = parseRangeOnBlur(String(typedValue), format);\n      const areDatesValid = parsedValue.every(isValid);\n\n      if (areDatesValid) {\n        this.handleRangeInput(parsedValue, event, true);\n        return;\n      }\n    } else {\n      const parsedValue = parseOnBlur(String(typedValue), format);\n      const isDateValid = isValid(parsedValue);\n\n      if (isDateValid) {\n        this.handleBasicInput(parsedValue, event, true);\n        return;\n      }\n    }\n\n    this.setState({ typedValue: null }, () => {\n      onChange(event, { ...this.props, value: null });\n    });\n  };\n\n  handleChange = (event: React.SyntheticEvent, { value }) => {\n    const { allowOnlyNumbers, format, onChange } = this.props;\n    const formatString = this.isRangeInput ? `${format} - ${format}` : format;\n    const typedValue = allowOnlyNumbers ? onlyNumbers(value) : value;\n\n    if (!typedValue) {\n      const newState = {\n        selectedDate: this.isRangeInput ? [] : null,\n        selectedDateFormatted: '',\n        typedValue: null,\n      };\n\n      this.setState(newState, () => {\n        onChange(event, { ...this.props, value: null });\n      });\n\n      return;\n    }\n\n    this.setState({\n      selectedDate: this.isRangeInput ? [] : null,\n      selectedDateFormatted: '',\n      typedValue: formatStringByPattern(formatString, typedValue),\n    });\n  };\n\n  handleKeyDown = (evt) => {\n    // If the Enter key was pressed...\n    if (evt.keyCode === 13) {\n      this.handleBlur();\n    }\n  };\n\n  onDateSelected = (event: React.SyntheticEvent | undefined, dateOrDates) => {\n    if (this.isRangeInput) {\n      this.handleRangeInput(dateOrDates, event);\n    } else {\n      this.handleBasicInput(dateOrDates, event);\n    }\n  };\n\n  render() {\n    const {\n      isVisible,\n      locale,\n      selectedDate,\n      selectedDateFormatted,\n      typedValue,\n    } = this.state;\n    const {\n      clearable,\n      pointing,\n      filterDate,\n      inline,\n      readOnly,\n      datePickerOnly,\n    } = this.props;\n    const datepickerComponent = (\n      <this.Component\n        {...this.dayzedProps}\n        monthsToDisplay={this.isRangeInput ? 2 : 1}\n        onChange={this.onDateSelected}\n        selected={selectedDate}\n        date={this.date}\n      >\n        {(props) => (\n          <Calendar\n            {...this.dayzedProps}\n            {...props}\n            {...locale}\n            filterDate={filterDate}\n            pointing={pointing}\n            weekdays={this.weekdays}\n          />\n        )}\n      </this.Component>\n    );\n\n    return inline ? (\n      datepickerComponent\n    ) : (\n      <div className=\"field\" style={style} ref={this.el}>\n        <Input\n          {...this.inputProps}\n          isClearIconVisible={Boolean(clearable && selectedDateFormatted)}\n          onBlur={() => {}}\n          onChange={this.handleChange}\n          onClear={this.clearInput}\n          onClick={readOnly ? null : this.showCalendar}\n          onKeyDown={this.handleKeyDown}\n          readOnly={readOnly || datePickerOnly}\n          ref={this.inputRef}\n          value={typedValue || selectedDateFormatted}\n        />\n        {isVisible && datepickerComponent}\n      </div>\n    );\n  }\n}\n\nexport default SemanticDatepicker;\n","export default function addLeadingZeros(number, targetLength) {\n  var sign = number < 0 ? '-' : '';\n  var output = Math.abs(number).toString();\n\n  while (output.length < targetLength) {\n    output = '0' + output;\n  }\n\n  return sign + output;\n}","export default function assign(target, dirtyObject) {\n  if (target == null) {\n    throw new TypeError('assign requires that input parameter not be null or undefined');\n  }\n\n  dirtyObject = dirtyObject || {};\n\n  for (var property in dirtyObject) {\n    if (dirtyObject.hasOwnProperty(property)) {\n      target[property] = dirtyObject[property];\n    }\n  }\n\n  return target;\n}","import assign from '../assign/index.js';\nexport default function cloneObject(dirtyObject) {\n  return assign({}, dirtyObject);\n}","import lightFormatters from '../lightFormatters/index.js';\nimport getUTCDayOfYear from '../../../_lib/getUTCDayOfYear/index.js';\nimport getUTCISOWeek from '../../../_lib/getUTCISOWeek/index.js';\nimport getUTCISOWeekYear from '../../../_lib/getUTCISOWeekYear/index.js';\nimport getUTCWeek from '../../../_lib/getUTCWeek/index.js';\nimport getUTCWeekYear from '../../../_lib/getUTCWeekYear/index.js';\nimport addLeadingZeros from '../../addLeadingZeros/index.js';\nvar dayPeriodEnum = {\n  am: 'am',\n  pm: 'pm',\n  midnight: 'midnight',\n  noon: 'noon',\n  morning: 'morning',\n  afternoon: 'afternoon',\n  evening: 'evening',\n  night: 'night'\n  /*\n   * |     | Unit                           |     | Unit                           |\n   * |-----|--------------------------------|-----|--------------------------------|\n   * |  a  | AM, PM                         |  A* | Milliseconds in day            |\n   * |  b  | AM, PM, noon, midnight         |  B  | Flexible day period            |\n   * |  c  | Stand-alone local day of week  |  C* | Localized hour w/ day period   |\n   * |  d  | Day of month                   |  D  | Day of year                    |\n   * |  e  | Local day of week              |  E  | Day of week                    |\n   * |  f  |                                |  F* | Day of week in month           |\n   * |  g* | Modified Julian day            |  G  | Era                            |\n   * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n   * |  i! | ISO day of week                |  I! | ISO week of year               |\n   * |  j* | Localized hour w/ day period   |  J* | Localized hour w/o day period  |\n   * |  k  | Hour [1-24]                    |  K  | Hour [0-11]                    |\n   * |  l* | (deprecated)                   |  L  | Stand-alone month              |\n   * |  m  | Minute                         |  M  | Month                          |\n   * |  n  |                                |  N  |                                |\n   * |  o! | Ordinal number modifier        |  O  | Timezone (GMT)                 |\n   * |  p! | Long localized time            |  P! | Long localized date            |\n   * |  q  | Stand-alone quarter            |  Q  | Quarter                        |\n   * |  r* | Related Gregorian year         |  R! | ISO week-numbering year        |\n   * |  s  | Second                         |  S  | Fraction of second             |\n   * |  t! | Seconds timestamp              |  T! | Milliseconds timestamp         |\n   * |  u  | Extended year                  |  U* | Cyclic year                    |\n   * |  v* | Timezone (generic non-locat.)  |  V* | Timezone (location)            |\n   * |  w  | Local week of year             |  W* | Week of month                  |\n   * |  x  | Timezone (ISO-8601 w/o Z)      |  X  | Timezone (ISO-8601)            |\n   * |  y  | Year (abs)                     |  Y  | Local week-numbering year      |\n   * |  z  | Timezone (specific non-locat.) |  Z* | Timezone (aliases)             |\n   *\n   * Letters marked by * are not implemented but reserved by Unicode standard.\n   *\n   * Letters marked by ! are non-standard, but implemented by date-fns:\n   * - `o` modifies the previous token to turn it into an ordinal (see `format` docs)\n   * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n   *   i.e. 7 for Sunday, 1 for Monday, etc.\n   * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n   * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n   *   `R` is supposed to be used in conjunction with `I` and `i`\n   *   for universal ISO week-numbering date, whereas\n   *   `Y` is supposed to be used in conjunction with `w` and `e`\n   *   for week-numbering date specific to the locale.\n   * - `P` is long localized date format\n   * - `p` is long localized time format\n   */\n\n};\nvar formatters = {\n  // Era\n  G: function (date, token, localize) {\n    var era = date.getUTCFullYear() > 0 ? 1 : 0;\n\n    switch (token) {\n      // AD, BC\n      case 'G':\n      case 'GG':\n      case 'GGG':\n        return localize.era(era, {\n          width: 'abbreviated'\n        });\n      // A, B\n\n      case 'GGGGG':\n        return localize.era(era, {\n          width: 'narrow'\n        });\n      // Anno Domini, Before Christ\n\n      case 'GGGG':\n      default:\n        return localize.era(era, {\n          width: 'wide'\n        });\n    }\n  },\n  // Year\n  y: function (date, token, localize) {\n    // Ordinal number\n    if (token === 'yo') {\n      var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n      var year = signedYear > 0 ? signedYear : 1 - signedYear;\n      return localize.ordinalNumber(year, {\n        unit: 'year'\n      });\n    }\n\n    return lightFormatters.y(date, token);\n  },\n  // Local week-numbering year\n  Y: function (date, token, localize, options) {\n    var signedWeekYear = getUTCWeekYear(date, options); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n    var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear; // Two digit year\n\n    if (token === 'YY') {\n      var twoDigitYear = weekYear % 100;\n      return addLeadingZeros(twoDigitYear, 2);\n    } // Ordinal number\n\n\n    if (token === 'Yo') {\n      return localize.ordinalNumber(weekYear, {\n        unit: 'year'\n      });\n    } // Padding\n\n\n    return addLeadingZeros(weekYear, token.length);\n  },\n  // ISO week-numbering year\n  R: function (date, token) {\n    var isoWeekYear = getUTCISOWeekYear(date); // Padding\n\n    return addLeadingZeros(isoWeekYear, token.length);\n  },\n  // Extended year. This is a single number designating the year of this calendar system.\n  // The main difference between `y` and `u` localizers are B.C. years:\n  // | Year | `y` | `u` |\n  // |------|-----|-----|\n  // | AC 1 |   1 |   1 |\n  // | BC 1 |   1 |   0 |\n  // | BC 2 |   2 |  -1 |\n  // Also `yy` always returns the last two digits of a year,\n  // while `uu` pads single digit years to 2 characters and returns other years unchanged.\n  u: function (date, token) {\n    var year = date.getUTCFullYear();\n    return addLeadingZeros(year, token.length);\n  },\n  // Quarter\n  Q: function (date, token, localize) {\n    var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);\n\n    switch (token) {\n      // 1, 2, 3, 4\n      case 'Q':\n        return String(quarter);\n      // 01, 02, 03, 04\n\n      case 'QQ':\n        return addLeadingZeros(quarter, 2);\n      // 1st, 2nd, 3rd, 4th\n\n      case 'Qo':\n        return localize.ordinalNumber(quarter, {\n          unit: 'quarter'\n        });\n      // Q1, Q2, Q3, Q4\n\n      case 'QQQ':\n        return localize.quarter(quarter, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n      case 'QQQQQ':\n        return localize.quarter(quarter, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // 1st quarter, 2nd quarter, ...\n\n      case 'QQQQ':\n      default:\n        return localize.quarter(quarter, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone quarter\n  q: function (date, token, localize) {\n    var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);\n\n    switch (token) {\n      // 1, 2, 3, 4\n      case 'q':\n        return String(quarter);\n      // 01, 02, 03, 04\n\n      case 'qq':\n        return addLeadingZeros(quarter, 2);\n      // 1st, 2nd, 3rd, 4th\n\n      case 'qo':\n        return localize.ordinalNumber(quarter, {\n          unit: 'quarter'\n        });\n      // Q1, Q2, Q3, Q4\n\n      case 'qqq':\n        return localize.quarter(quarter, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n      case 'qqqqq':\n        return localize.quarter(quarter, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // 1st quarter, 2nd quarter, ...\n\n      case 'qqqq':\n      default:\n        return localize.quarter(quarter, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // Month\n  M: function (date, token, localize) {\n    var month = date.getUTCMonth();\n\n    switch (token) {\n      case 'M':\n      case 'MM':\n        return lightFormatters.M(date, token);\n      // 1st, 2nd, ..., 12th\n\n      case 'Mo':\n        return localize.ordinalNumber(month + 1, {\n          unit: 'month'\n        });\n      // Jan, Feb, ..., Dec\n\n      case 'MMM':\n        return localize.month(month, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // J, F, ..., D\n\n      case 'MMMMM':\n        return localize.month(month, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // January, February, ..., December\n\n      case 'MMMM':\n      default:\n        return localize.month(month, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone month\n  L: function (date, token, localize) {\n    var month = date.getUTCMonth();\n\n    switch (token) {\n      // 1, 2, ..., 12\n      case 'L':\n        return String(month + 1);\n      // 01, 02, ..., 12\n\n      case 'LL':\n        return addLeadingZeros(month + 1, 2);\n      // 1st, 2nd, ..., 12th\n\n      case 'Lo':\n        return localize.ordinalNumber(month + 1, {\n          unit: 'month'\n        });\n      // Jan, Feb, ..., Dec\n\n      case 'LLL':\n        return localize.month(month, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // J, F, ..., D\n\n      case 'LLLLL':\n        return localize.month(month, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // January, February, ..., December\n\n      case 'LLLL':\n      default:\n        return localize.month(month, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // Local week of year\n  w: function (date, token, localize, options) {\n    var week = getUTCWeek(date, options);\n\n    if (token === 'wo') {\n      return localize.ordinalNumber(week, {\n        unit: 'week'\n      });\n    }\n\n    return addLeadingZeros(week, token.length);\n  },\n  // ISO week of year\n  I: function (date, token, localize) {\n    var isoWeek = getUTCISOWeek(date);\n\n    if (token === 'Io') {\n      return localize.ordinalNumber(isoWeek, {\n        unit: 'week'\n      });\n    }\n\n    return addLeadingZeros(isoWeek, token.length);\n  },\n  // Day of the month\n  d: function (date, token, localize) {\n    if (token === 'do') {\n      return localize.ordinalNumber(date.getUTCDate(), {\n        unit: 'date'\n      });\n    }\n\n    return lightFormatters.d(date, token);\n  },\n  // Day of year\n  D: function (date, token, localize) {\n    var dayOfYear = getUTCDayOfYear(date);\n\n    if (token === 'Do') {\n      return localize.ordinalNumber(dayOfYear, {\n        unit: 'dayOfYear'\n      });\n    }\n\n    return addLeadingZeros(dayOfYear, token.length);\n  },\n  // Day of week\n  E: function (date, token, localize) {\n    var dayOfWeek = date.getUTCDay();\n\n    switch (token) {\n      // Tue\n      case 'E':\n      case 'EE':\n      case 'EEE':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'EEEEE':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'EEEEEE':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'EEEE':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Local day of week\n  e: function (date, token, localize, options) {\n    var dayOfWeek = date.getUTCDay();\n    var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n\n    switch (token) {\n      // Numerical value (Nth day of week with current locale or weekStartsOn)\n      case 'e':\n        return String(localDayOfWeek);\n      // Padded numerical value\n\n      case 'ee':\n        return addLeadingZeros(localDayOfWeek, 2);\n      // 1st, 2nd, ..., 7th\n\n      case 'eo':\n        return localize.ordinalNumber(localDayOfWeek, {\n          unit: 'day'\n        });\n\n      case 'eee':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'eeeee':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'eeeeee':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'eeee':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Stand-alone local day of week\n  c: function (date, token, localize, options) {\n    var dayOfWeek = date.getUTCDay();\n    var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n\n    switch (token) {\n      // Numerical value (same as in `e`)\n      case 'c':\n        return String(localDayOfWeek);\n      // Padded numerical value\n\n      case 'cc':\n        return addLeadingZeros(localDayOfWeek, token.length);\n      // 1st, 2nd, ..., 7th\n\n      case 'co':\n        return localize.ordinalNumber(localDayOfWeek, {\n          unit: 'day'\n        });\n\n      case 'ccc':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'standalone'\n        });\n      // T\n\n      case 'ccccc':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'standalone'\n        });\n      // Tu\n\n      case 'cccccc':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'standalone'\n        });\n      // Tuesday\n\n      case 'cccc':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'standalone'\n        });\n    }\n  },\n  // ISO day of week\n  i: function (date, token, localize) {\n    var dayOfWeek = date.getUTCDay();\n    var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;\n\n    switch (token) {\n      // 2\n      case 'i':\n        return String(isoDayOfWeek);\n      // 02\n\n      case 'ii':\n        return addLeadingZeros(isoDayOfWeek, token.length);\n      // 2nd\n\n      case 'io':\n        return localize.ordinalNumber(isoDayOfWeek, {\n          unit: 'day'\n        });\n      // Tue\n\n      case 'iii':\n        return localize.day(dayOfWeek, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n      // T\n\n      case 'iiiii':\n        return localize.day(dayOfWeek, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n      // Tu\n\n      case 'iiiiii':\n        return localize.day(dayOfWeek, {\n          width: 'short',\n          context: 'formatting'\n        });\n      // Tuesday\n\n      case 'iiii':\n      default:\n        return localize.day(dayOfWeek, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // AM or PM\n  a: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';\n\n    switch (token) {\n      case 'a':\n      case 'aa':\n      case 'aaa':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'aaaaa':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'aaaa':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // AM, PM, midnight, noon\n  b: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue;\n\n    if (hours === 12) {\n      dayPeriodEnumValue = dayPeriodEnum.noon;\n    } else if (hours === 0) {\n      dayPeriodEnumValue = dayPeriodEnum.midnight;\n    } else {\n      dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';\n    }\n\n    switch (token) {\n      case 'b':\n      case 'bb':\n      case 'bbb':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'bbbbb':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'bbbb':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // in the morning, in the afternoon, in the evening, at night\n  B: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    var dayPeriodEnumValue;\n\n    if (hours >= 17) {\n      dayPeriodEnumValue = dayPeriodEnum.evening;\n    } else if (hours >= 12) {\n      dayPeriodEnumValue = dayPeriodEnum.afternoon;\n    } else if (hours >= 4) {\n      dayPeriodEnumValue = dayPeriodEnum.morning;\n    } else {\n      dayPeriodEnumValue = dayPeriodEnum.night;\n    }\n\n    switch (token) {\n      case 'B':\n      case 'BB':\n      case 'BBB':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'abbreviated',\n          context: 'formatting'\n        });\n\n      case 'BBBBB':\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'narrow',\n          context: 'formatting'\n        });\n\n      case 'BBBB':\n      default:\n        return localize.dayPeriod(dayPeriodEnumValue, {\n          width: 'wide',\n          context: 'formatting'\n        });\n    }\n  },\n  // Hour [1-12]\n  h: function (date, token, localize) {\n    if (token === 'ho') {\n      var hours = date.getUTCHours() % 12;\n      if (hours === 0) hours = 12;\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return lightFormatters.h(date, token);\n  },\n  // Hour [0-23]\n  H: function (date, token, localize) {\n    if (token === 'Ho') {\n      return localize.ordinalNumber(date.getUTCHours(), {\n        unit: 'hour'\n      });\n    }\n\n    return lightFormatters.H(date, token);\n  },\n  // Hour [0-11]\n  K: function (date, token, localize) {\n    var hours = date.getUTCHours() % 12;\n\n    if (token === 'Ko') {\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return addLeadingZeros(hours, token.length);\n  },\n  // Hour [1-24]\n  k: function (date, token, localize) {\n    var hours = date.getUTCHours();\n    if (hours === 0) hours = 24;\n\n    if (token === 'ko') {\n      return localize.ordinalNumber(hours, {\n        unit: 'hour'\n      });\n    }\n\n    return addLeadingZeros(hours, token.length);\n  },\n  // Minute\n  m: function (date, token, localize) {\n    if (token === 'mo') {\n      return localize.ordinalNumber(date.getUTCMinutes(), {\n        unit: 'minute'\n      });\n    }\n\n    return lightFormatters.m(date, token);\n  },\n  // Second\n  s: function (date, token, localize) {\n    if (token === 'so') {\n      return localize.ordinalNumber(date.getUTCSeconds(), {\n        unit: 'second'\n      });\n    }\n\n    return lightFormatters.s(date, token);\n  },\n  // Fraction of second\n  S: function (date, token) {\n    return lightFormatters.S(date, token);\n  },\n  // Timezone (ISO-8601. If offset is 0, output is always `'Z'`)\n  X: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    if (timezoneOffset === 0) {\n      return 'Z';\n    }\n\n    switch (token) {\n      // Hours and optional minutes\n      case 'X':\n        return formatTimezoneWithOptionalMinutes(timezoneOffset);\n      // Hours, minutes and optional seconds without `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `XX`\n\n      case 'XXXX':\n      case 'XX':\n        // Hours and minutes without `:` delimiter\n        return formatTimezone(timezoneOffset);\n      // Hours, minutes and optional seconds with `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `XXX`\n\n      case 'XXXXX':\n      case 'XXX': // Hours and minutes with `:` delimiter\n\n      default:\n        return formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)\n  x: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Hours and optional minutes\n      case 'x':\n        return formatTimezoneWithOptionalMinutes(timezoneOffset);\n      // Hours, minutes and optional seconds without `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `xx`\n\n      case 'xxxx':\n      case 'xx':\n        // Hours and minutes without `:` delimiter\n        return formatTimezone(timezoneOffset);\n      // Hours, minutes and optional seconds with `:` delimiter\n      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n      // so this token always has the same output as `xxx`\n\n      case 'xxxxx':\n      case 'xxx': // Hours and minutes with `:` delimiter\n\n      default:\n        return formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (GMT)\n  O: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Short\n      case 'O':\n      case 'OO':\n      case 'OOO':\n        return 'GMT' + formatTimezoneShort(timezoneOffset, ':');\n      // Long\n\n      case 'OOOO':\n      default:\n        return 'GMT' + formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Timezone (specific non-location)\n  z: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timezoneOffset = originalDate.getTimezoneOffset();\n\n    switch (token) {\n      // Short\n      case 'z':\n      case 'zz':\n      case 'zzz':\n        return 'GMT' + formatTimezoneShort(timezoneOffset, ':');\n      // Long\n\n      case 'zzzz':\n      default:\n        return 'GMT' + formatTimezone(timezoneOffset, ':');\n    }\n  },\n  // Seconds timestamp\n  t: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timestamp = Math.floor(originalDate.getTime() / 1000);\n    return addLeadingZeros(timestamp, token.length);\n  },\n  // Milliseconds timestamp\n  T: function (date, token, _localize, options) {\n    var originalDate = options._originalDate || date;\n    var timestamp = originalDate.getTime();\n    return addLeadingZeros(timestamp, token.length);\n  }\n};\n\nfunction formatTimezoneShort(offset, dirtyDelimiter) {\n  var sign = offset > 0 ? '-' : '+';\n  var absOffset = Math.abs(offset);\n  var hours = Math.floor(absOffset / 60);\n  var minutes = absOffset % 60;\n\n  if (minutes === 0) {\n    return sign + String(hours);\n  }\n\n  var delimiter = dirtyDelimiter || '';\n  return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);\n}\n\nfunction formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) {\n  if (offset % 60 === 0) {\n    var sign = offset > 0 ? '-' : '+';\n    return sign + addLeadingZeros(Math.abs(offset) / 60, 2);\n  }\n\n  return formatTimezone(offset, dirtyDelimiter);\n}\n\nfunction formatTimezone(offset, dirtyDelimiter) {\n  var delimiter = dirtyDelimiter || '';\n  var sign = offset > 0 ? '-' : '+';\n  var absOffset = Math.abs(offset);\n  var hours = addLeadingZeros(Math.floor(absOffset / 60), 2);\n  var minutes = addLeadingZeros(absOffset % 60, 2);\n  return sign + hours + delimiter + minutes;\n}\n\nexport default formatters;","import addLeadingZeros from '../../addLeadingZeros/index.js';\n/*\n * |     | Unit                           |     | Unit                           |\n * |-----|--------------------------------|-----|--------------------------------|\n * |  a  | AM, PM                         |  A* |                                |\n * |  d  | Day of month                   |  D  |                                |\n * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n * |  m  | Minute                         |  M  | Month                          |\n * |  s  | Second                         |  S  | Fraction of second             |\n * |  y  | Year (abs)                     |  Y  |                                |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n */\n\nvar formatters = {\n  // Year\n  y: function (date, token) {\n    // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens\n    // | Year     |     y | yy |   yyy |  yyyy | yyyyy |\n    // |----------|-------|----|-------|-------|-------|\n    // | AD 1     |     1 | 01 |   001 |  0001 | 00001 |\n    // | AD 12    |    12 | 12 |   012 |  0012 | 00012 |\n    // | AD 123   |   123 | 23 |   123 |  0123 | 00123 |\n    // | AD 1234  |  1234 | 34 |  1234 |  1234 | 01234 |\n    // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n    var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)\n\n    var year = signedYear > 0 ? signedYear : 1 - signedYear;\n    return addLeadingZeros(token === 'yy' ? year % 100 : year, token.length);\n  },\n  // Month\n  M: function (date, token) {\n    var month = date.getUTCMonth();\n    return token === 'M' ? String(month + 1) : addLeadingZeros(month + 1, 2);\n  },\n  // Day of the month\n  d: function (date, token) {\n    return addLeadingZeros(date.getUTCDate(), token.length);\n  },\n  // AM or PM\n  a: function (date, token) {\n    var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am';\n\n    switch (token) {\n      case 'a':\n      case 'aa':\n      case 'aaa':\n        return dayPeriodEnumValue.toUpperCase();\n\n      case 'aaaaa':\n        return dayPeriodEnumValue[0];\n\n      case 'aaaa':\n      default:\n        return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.';\n    }\n  },\n  // Hour [1-12]\n  h: function (date, token) {\n    return addLeadingZeros(date.getUTCHours() % 12 || 12, token.length);\n  },\n  // Hour [0-23]\n  H: function (date, token) {\n    return addLeadingZeros(date.getUTCHours(), token.length);\n  },\n  // Minute\n  m: function (date, token) {\n    return addLeadingZeros(date.getUTCMinutes(), token.length);\n  },\n  // Second\n  s: function (date, token) {\n    return addLeadingZeros(date.getUTCSeconds(), token.length);\n  },\n  // Fraction of second\n  S: function (date, token) {\n    var numberOfDigits = token.length;\n    var milliseconds = date.getUTCMilliseconds();\n    var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3));\n    return addLeadingZeros(fractionalSeconds, token.length);\n  }\n};\nexport default formatters;","function dateLongFormatter(pattern, formatLong) {\n  switch (pattern) {\n    case 'P':\n      return formatLong.date({\n        width: 'short'\n      });\n\n    case 'PP':\n      return formatLong.date({\n        width: 'medium'\n      });\n\n    case 'PPP':\n      return formatLong.date({\n        width: 'long'\n      });\n\n    case 'PPPP':\n    default:\n      return formatLong.date({\n        width: 'full'\n      });\n  }\n}\n\nfunction timeLongFormatter(pattern, formatLong) {\n  switch (pattern) {\n    case 'p':\n      return formatLong.time({\n        width: 'short'\n      });\n\n    case 'pp':\n      return formatLong.time({\n        width: 'medium'\n      });\n\n    case 'ppp':\n      return formatLong.time({\n        width: 'long'\n      });\n\n    case 'pppp':\n    default:\n      return formatLong.time({\n        width: 'full'\n      });\n  }\n}\n\nfunction dateTimeLongFormatter(pattern, formatLong) {\n  var matchResult = pattern.match(/(P+)(p+)?/);\n  var datePattern = matchResult[1];\n  var timePattern = matchResult[2];\n\n  if (!timePattern) {\n    return dateLongFormatter(pattern, formatLong);\n  }\n\n  var dateTimeFormat;\n\n  switch (datePattern) {\n    case 'P':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'short'\n      });\n      break;\n\n    case 'PP':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'medium'\n      });\n      break;\n\n    case 'PPP':\n      dateTimeFormat = formatLong.dateTime({\n        width: 'long'\n      });\n      break;\n\n    case 'PPPP':\n    default:\n      dateTimeFormat = formatLong.dateTime({\n        width: 'full'\n      });\n      break;\n  }\n\n  return dateTimeFormat.replace('{{date}}', dateLongFormatter(datePattern, formatLong)).replace('{{time}}', timeLongFormatter(timePattern, formatLong));\n}\n\nvar longFormatters = {\n  p: timeLongFormatter,\n  P: dateTimeLongFormatter\n};\nexport default longFormatters;","var MILLISECONDS_IN_MINUTE = 60000;\n\nfunction getDateMillisecondsPart(date) {\n  return date.getTime() % MILLISECONDS_IN_MINUTE;\n}\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\n\n\nexport default function getTimezoneOffsetInMilliseconds(dirtyDate) {\n  var date = new Date(dirtyDate.getTime());\n  var baseTimezoneOffset = Math.ceil(date.getTimezoneOffset());\n  date.setSeconds(0, 0);\n  var hasNegativeUTCOffset = baseTimezoneOffset > 0;\n  var millisecondsPartOfTimezoneOffset = hasNegativeUTCOffset ? (MILLISECONDS_IN_MINUTE + getDateMillisecondsPart(date)) % MILLISECONDS_IN_MINUTE : getDateMillisecondsPart(date);\n  return baseTimezoneOffset * MILLISECONDS_IN_MINUTE + millisecondsPartOfTimezoneOffset;\n}","import toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 86400000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var timestamp = date.getTime();\n  date.setUTCMonth(0, 1);\n  date.setUTCHours(0, 0, 0, 0);\n  var startOfYearTimestamp = date.getTime();\n  var difference = timestamp - startOfYearTimestamp;\n  return Math.floor(difference / MILLISECONDS_IN_DAY) + 1;\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport startOfUTCISOWeekYear from '../startOfUTCISOWeekYear/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfUTCISOWeek(date).getTime() - startOfUTCISOWeekYear(date).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getUTCFullYear();\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0);\n  var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear);\n  var fourthOfJanuaryOfThisYear = new Date(0);\n  fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4);\n  fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0);\n  var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import toDate from '../../toDate/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport startOfUTCWeekYear from '../startOfUTCWeekYear/index.js';\nimport requiredArgs from '../requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfUTCWeek(date, options).getTime() - startOfUTCWeekYear(date, options).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function getUTCWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate, dirtyOptions);\n  var year = date.getUTCFullYear();\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var firstWeekOfNextYear = new Date(0);\n  firstWeekOfNextYear.setUTCFullYear(year + 1, 0, firstWeekContainsDate);\n  firstWeekOfNextYear.setUTCHours(0, 0, 0, 0);\n  var startOfNextYear = startOfUTCWeek(firstWeekOfNextYear, dirtyOptions);\n  var firstWeekOfThisYear = new Date(0);\n  firstWeekOfThisYear.setUTCFullYear(year, 0, firstWeekContainsDate);\n  firstWeekOfThisYear.setUTCHours(0, 0, 0, 0);\n  var startOfThisYear = startOfUTCWeek(firstWeekOfThisYear, dirtyOptions);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","var protectedDayOfYearTokens = ['D', 'DD'];\nvar protectedWeekYearTokens = ['YY', 'YYYY'];\nexport function isProtectedDayOfYearToken(token) {\n  return protectedDayOfYearTokens.indexOf(token) !== -1;\n}\nexport function isProtectedWeekYearToken(token) {\n  return protectedWeekYearTokens.indexOf(token) !== -1;\n}\nexport function throwProtectedError(token, format, input) {\n  if (token === 'YYYY') {\n    throw new RangeError(\"Use `yyyy` instead of `YYYY` (in `\".concat(format, \"`) for formatting years to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'YY') {\n    throw new RangeError(\"Use `yy` instead of `YY` (in `\".concat(format, \"`) for formatting years to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'D') {\n    throw new RangeError(\"Use `d` instead of `D` (in `\".concat(format, \"`) for formatting days of the month to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  } else if (token === 'DD') {\n    throw new RangeError(\"Use `dd` instead of `DD` (in `\".concat(format, \"`) for formatting days of the month to the input `\").concat(input, \"`; see: https://git.io/fxCyr\"));\n  }\n}","export default function requiredArgs(required, args) {\n  if (args.length < required) {\n    throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');\n  }\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCDay(dirtyDate, dirtyDay, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = toInteger(dirtyDay);\n  var currentDay = date.getUTCDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISODay(dirtyDate, dirtyDay) {\n  requiredArgs(2, arguments);\n  var day = toInteger(dirtyDay);\n\n  if (day % 7 === 0) {\n    day = day - 7;\n  }\n\n  var weekStartsOn = 1;\n  var date = toDate(dirtyDate);\n  var currentDay = date.getUTCDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport getUTCISOWeek from '../getUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISOWeek(dirtyDate, dirtyISOWeek) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeek = toInteger(dirtyISOWeek);\n  var diff = getUTCISOWeek(date) - isoWeek;\n  date.setUTCDate(date.getUTCDate() - diff * 7);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport getUTCWeek from '../getUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCWeek(dirtyDate, dirtyWeek, options) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var week = toInteger(dirtyWeek);\n  var diff = getUTCWeek(date, options) - week;\n  date.setUTCDate(date.getUTCDate() - diff * 7);\n  return date;\n}","import toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var weekStartsOn = 1;\n  var date = toDate(dirtyDate);\n  var day = date.getUTCDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setUTCDate(date.getUTCDate() - diff);\n  date.setUTCHours(0, 0, 0, 0);\n  return date;\n}","import getUTCISOWeekYear from '../getUTCISOWeekYear/index.js';\nimport startOfUTCISOWeek from '../startOfUTCISOWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getUTCISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setUTCFullYear(year, 0, 4);\n  fourthOfJanuary.setUTCHours(0, 0, 0, 0);\n  var date = startOfUTCISOWeek(fourthOfJanuary);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport toDate from '../../toDate/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getUTCDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setUTCDate(date.getUTCDate() - diff);\n  date.setUTCHours(0, 0, 0, 0);\n  return date;\n}","import toInteger from '../toInteger/index.js';\nimport getUTCWeekYear from '../getUTCWeekYear/index.js';\nimport startOfUTCWeek from '../startOfUTCWeek/index.js';\nimport requiredArgs from '../requiredArgs/index.js'; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function startOfUTCWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var year = getUTCWeekYear(dirtyDate, dirtyOptions);\n  var firstWeek = new Date(0);\n  firstWeek.setUTCFullYear(year, 0, firstWeekContainsDate);\n  firstWeek.setUTCHours(0, 0, 0, 0);\n  var date = startOfUTCWeek(firstWeek, dirtyOptions);\n  return date;\n}","export default function toInteger(dirtyNumber) {\n  if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {\n    return NaN;\n  }\n\n  var number = Number(dirtyNumber);\n\n  if (isNaN(number)) {\n    return number;\n  }\n\n  return number < 0 ? Math.ceil(number) : Math.floor(number);\n}","import addDays from '../addDays/index.js';\nimport addMonths from '../addMonths/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name add\n * @category Common Helpers\n * @summary Add the specified years, months, weeks, days, hours, minutes and seconds to the given date.\n *\n * @description\n * Add the specified years, months, weeks, days, hours, minutes and seconds to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Duration} duration - the object with years, months, weeks, days, hours, minutes and seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n *\n * | Key            | Description                        |\n * |----------------|------------------------------------|\n * | years          | Amount of years to be added        |\n * | months         | Amount of months to be added       |\n * | weeks          | Amount of weeks to be added       |\n * | days           | Amount of days to be added         |\n * | hours          | Amount of hours to be added        |\n * | minutes        | Amount of minutes to be added      |\n * | seconds        | Amount of seconds to be added      |\n *\n * All values default to 0\n *\n * @returns {Date} the new date with the seconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add the following duration to 1 September 2014, 10:19:50\n * var result = add(new Date(2014, 8, 1, 10, 19, 50), {\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30,\n * })\n * //=> Thu Jun 15 2017 15:29:20\n */\n\nexport default function add(dirtyDate, duration) {\n  requiredArgs(2, arguments);\n  if (!duration || typeof duration !== 'object') return new Date(NaN);\n  var years = 'years' in duration ? toInteger(duration.years) : 0;\n  var months = 'months' in duration ? toInteger(duration.months) : 0;\n  var weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0;\n  var days = 'days' in duration ? toInteger(duration.days) : 0;\n  var hours = 'hours' in duration ? toInteger(duration.hours) : 0;\n  var minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0;\n  var seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0; // Add years and months\n\n  var date = toDate(dirtyDate);\n  var dateWithMonths = months || years ? addMonths(date, months + years * 12) : date; // Add weeks and days\n\n  var dateWithDays = days || weeks ? addDays(dateWithMonths, days + weeks * 7) : dateWithMonths; // Add days, hours, minutes and seconds\n\n  var minutesToAdd = minutes + hours * 60;\n  var secondsToAdd = seconds + minutesToAdd * 60;\n  var msToAdd = secondsToAdd * 1000;\n  var finalDate = new Date(dateWithDays.getTime() + msToAdd);\n  return finalDate;\n}","import isWeekend from '../isWeekend/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport isSunday from '../isSunday/index.js';\nimport isSaturday from '../isSaturday/index.js';\n/**\n * @name addBusinessDays\n * @category Day Helpers\n * @summary Add the specified number of business days (mon - fri) to the given date.\n *\n * @description\n * Add the specified number of business days (mon - fri) to the given date, ignoring weekends.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of business days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the business days added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 10 business days to 1 September 2014:\n * var result = addBusinessDays(new Date(2014, 8, 1), 10)\n * //=> Mon Sep 15 2014 00:00:00 (skipped weekend days)\n */\n\nexport default function addBusinessDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var startedOnWeekend = isWeekend(date);\n  var amount = toInteger(dirtyAmount);\n  if (isNaN(amount)) return new Date(NaN);\n  var hours = date.getHours();\n  var sign = amount < 0 ? -1 : 1;\n  var fullWeeks = toInteger(amount / 5);\n  date.setDate(date.getDate() + fullWeeks * 7); // Get remaining days not part of a full week\n\n  var restDays = Math.abs(amount % 5); // Loops over remaining days\n\n  while (restDays > 0) {\n    date.setDate(date.getDate() + sign);\n    if (!isWeekend(date)) restDays -= 1;\n  } // If the date is a weekend day and we reduce a dividable of\n  // 5 from it, we land on a weekend date.\n  // To counter this, we add days accordingly to land on the next business day\n\n\n  if (startedOnWeekend && isWeekend(date) && amount !== 0) {\n    // If we're reducing days, we want to add days until we land on a weekday\n    // If we're adding days we want to reduce days until we land on a weekday\n    if (isSaturday(date)) date.setDate(date.getDate() + (sign < 0 ? 2 : -1));\n    if (isSunday(date)) date.setDate(date.getDate() + (sign < 0 ? 1 : -2));\n  } // Restore hours to avoid DST lag\n\n\n  date.setHours(hours);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addDays\n * @category Day Helpers\n * @summary Add the specified number of days to the given date.\n *\n * @description\n * Add the specified number of days to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the days added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 10 days to 1 September 2014:\n * var result = addDays(new Date(2014, 8, 1), 10)\n * //=> Thu Sep 11 2014 00:00:00\n */\n\nexport default function addDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var amount = toInteger(dirtyAmount);\n\n  if (isNaN(amount)) {\n    return new Date(NaN);\n  }\n\n  if (!amount) {\n    // If 0 days, no-op to avoid changing times in the hour before end of DST\n    return date;\n  }\n\n  date.setDate(date.getDate() + amount);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\n/**\n * @name addHours\n * @category Hour Helpers\n * @summary Add the specified number of hours to the given date.\n *\n * @description\n * Add the specified number of hours to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of hours to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the hours added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 2 hours to 10 July 2014 23:00:00:\n * var result = addHours(new Date(2014, 6, 10, 23, 0), 2)\n * //=> Fri Jul 11 2014 01:00:00\n */\n\nexport default function addHours(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport getISOWeekYear from '../getISOWeekYear/index.js';\nimport setISOWeekYear from '../setISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Add the specified number of ISO week-numbering years to the given date.\n *\n * @description\n * Add the specified number of ISO week-numbering years to the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `addISOYears` to `addISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of ISO week-numbering years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the ISO week-numbering years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 ISO week-numbering years to 2 July 2010:\n * var result = addISOWeekYears(new Date(2010, 6, 2), 5)\n * //=> Fri Jun 26 2015 00:00:00\n */\n\nexport default function addISOWeekYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return setISOWeekYear(dirtyDate, getISOWeekYear(dirtyDate) + amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addMilliseconds\n * @category Millisecond Helpers\n * @summary Add the specified number of milliseconds to the given date.\n *\n * @description\n * Add the specified number of milliseconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of milliseconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the milliseconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 750 milliseconds to 10 July 2014 12:45:30.000:\n * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)\n * //=> Thu Jul 10 2014 12:45:30.750\n */\n\nexport default function addMilliseconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var timestamp = toDate(dirtyDate).getTime();\n  var amount = toInteger(dirtyAmount);\n  return new Date(timestamp + amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_MINUTE = 60000;\n/**\n * @name addMinutes\n * @category Minute Helpers\n * @summary Add the specified number of minutes to the given date.\n *\n * @description\n * Add the specified number of minutes to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of minutes to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the minutes added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 minutes to 10 July 2014 12:00:00:\n * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30)\n * //=> Thu Jul 10 2014 12:30:00\n */\n\nexport default function addMinutes(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addMonths\n * @category Month Helpers\n * @summary Add the specified number of months to the given date.\n *\n * @description\n * Add the specified number of months to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the months added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 months to 1 September 2014:\n * var result = addMonths(new Date(2014, 8, 1), 5)\n * //=> Sun Feb 01 2015 00:00:00\n */\n\nexport default function addMonths(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var amount = toInteger(dirtyAmount);\n\n  if (isNaN(amount)) {\n    return new Date(NaN);\n  }\n\n  if (!amount) {\n    // If 0 months, no-op to avoid changing times in the hour before end of DST\n    return date;\n  }\n\n  var dayOfMonth = date.getDate(); // The JS Date object supports date math by accepting out-of-bounds values for\n  // month, day, etc. For example, new Date(2020, 1, 0) returns 31 Dec 2019 and\n  // new Date(2020, 13, 1) returns 1 Feb 2021.  This is *almost* the behavior we\n  // want except that dates will wrap around the end of a month, meaning that\n  // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So\n  // we'll default to the end of the desired month by adding 1 to the desired\n  // month and using a date of 0 to back up one day to the end of the desired\n  // month.\n\n  var endOfDesiredMonth = new Date(date.getTime());\n  endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);\n  var daysInMonth = endOfDesiredMonth.getDate();\n\n  if (dayOfMonth >= daysInMonth) {\n    // If we're already at the end of the month, then this is the correct date\n    // and we're done.\n    return endOfDesiredMonth;\n  } else {\n    // Otherwise, we now know that setting the original day-of-month value won't\n    // cause an overflow, so set the desired day-of-month. Note that we can't\n    // just set the date of `endOfDesiredMonth` because that object may have had\n    // its time changed in the unusual case where where a DST transition was on\n    // the last day of the month and its local time was in the hour skipped or\n    // repeated next to a DST transition.  So we use `date` instead which is\n    // guaranteed to still have the original time.\n    date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);\n    return date;\n  }\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addQuarters\n * @category Quarter Helpers\n * @summary Add the specified number of year quarters to the given date.\n *\n * @description\n * Add the specified number of year quarters to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of quarters to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the quarters added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 1 quarter to 1 September 2014:\n * var result = addQuarters(new Date(2014, 8, 1), 1)\n * //=> Mon Dec 01 2014 00:00:00\n */\n\nexport default function addQuarters(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  var months = amount * 3;\n  return addMonths(dirtyDate, months);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addSeconds\n * @category Second Helpers\n * @summary Add the specified number of seconds to the given date.\n *\n * @description\n * Add the specified number of seconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 seconds to 10 July 2014 12:45:00:\n * var result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:45:30\n */\n\nexport default function addSeconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, amount * 1000);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addDays from '../addDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addWeeks\n * @category Week Helpers\n * @summary Add the specified number of weeks to the given date.\n *\n * @description\n * Add the specified number of week to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of weeks to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the weeks added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 4 weeks to 1 September 2014:\n * var result = addWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Sep 29 2014 00:00:00\n */\n\nexport default function addWeeks(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  var days = amount * 7;\n  return addDays(dirtyDate, days);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name addYears\n * @category Year Helpers\n * @summary Add the specified number of years to the given date.\n *\n * @description\n * Add the specified number of years to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 years to 1 September 2014:\n * var result = addYears(new Date(2014, 8, 1), 5)\n * //=> Sun Sep 01 2019 00:00:00\n */\n\nexport default function addYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMonths(dirtyDate, amount * 12);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name areIntervalsOverlapping\n * @category Interval Helpers\n * @summary Is the given time interval overlapping with another time interval?\n *\n * @description\n * Is the given time interval overlapping with another time interval? Adjacent intervals do not count as overlapping.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `areRangesOverlapping` to `areIntervalsOverlapping`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   areRangesOverlapping(\n *     new Date(2014, 0, 10), new Date(2014, 0, 20),\n *     new Date(2014, 0, 17), new Date(2014, 0, 21)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   areIntervalsOverlapping(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *     { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n *   )\n *   ```\n *\n * @param {Interval} intervalLeft - the first interval to compare. See [Interval]{@link docs/types/Interval}\n * @param {Interval} intervalRight - the second interval to compare. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - the object with options\n * @param {Boolean} [options.inclusive=false] - whether the comparison is inclusive or not\n * @returns {Boolean} whether the time intervals are overlapping\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For overlapping time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n * )\n * //=> true\n *\n * @example\n * // For non-overlapping time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 21), end: new Date(2014, 0, 22) }\n * )\n * //=> false\n *\n * @example\n * // For adjacent time intervals:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 30) }\n * )\n * //=> false\n *\n * @example\n * // Using the inclusive option:\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 24) }\n * )\n * //=> false\n * areIntervalsOverlapping(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 20), end: new Date(2014, 0, 24) },\n *   { inclusive: true }\n * )\n * //=> true\n */\n\nexport default function areIntervalsOverlapping(dirtyIntervalLeft, dirtyIntervalRight) {\n  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n  requiredArgs(2, arguments);\n  var intervalLeft = dirtyIntervalLeft || {};\n  var intervalRight = dirtyIntervalRight || {};\n  var leftStartTime = toDate(intervalLeft.start).getTime();\n  var leftEndTime = toDate(intervalLeft.end).getTime();\n  var rightStartTime = toDate(intervalRight.start).getTime();\n  var rightEndTime = toDate(intervalRight.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  if (options.inclusive) {\n    return leftStartTime <= rightEndTime && rightStartTime <= leftEndTime;\n  }\n\n  return leftStartTime < rightEndTime && rightStartTime < leftEndTime;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name closestIndexTo\n * @category Common Helpers\n * @summary Return an index of the closest date from the array comparing to the given date.\n *\n * @description\n * Return an index of the closest date from the array comparing to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now, `closestIndexTo` doesn't throw an exception\n *   when the second argument is not an array, and returns Invalid Date instead.\n *\n * @param {Date|Number} dateToCompare - the date to compare with\n * @param {Date[]|Number[]} datesArray - the array to search\n * @returns {Number} an index of the date closest to the given date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Which date is closer to 6 September 2015?\n * var dateToCompare = new Date(2015, 8, 6)\n * var datesArray = [\n *   new Date(2015, 0, 1),\n *   new Date(2016, 0, 1),\n *   new Date(2017, 0, 1)\n * ]\n * var result = closestIndexTo(dateToCompare, datesArray)\n * //=> 1\n */\n\nexport default function closestIndexTo(dirtyDateToCompare, dirtyDatesArray) {\n  requiredArgs(2, arguments);\n  var dateToCompare = toDate(dirtyDateToCompare);\n\n  if (isNaN(dateToCompare)) {\n    return NaN;\n  }\n\n  var timeToCompare = dateToCompare.getTime();\n  var datesArray; // `dirtyDatesArray` is undefined or null\n\n  if (dirtyDatesArray == null) {\n    datesArray = []; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n  } else if (typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array\n  } else {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  }\n\n  var result;\n  var minDistance;\n  datesArray.forEach(function (dirtyDate, index) {\n    var currentDate = toDate(dirtyDate);\n\n    if (isNaN(currentDate)) {\n      result = NaN;\n      minDistance = NaN;\n      return;\n    }\n\n    var distance = Math.abs(timeToCompare - currentDate.getTime());\n\n    if (result == null || distance < minDistance) {\n      result = index;\n      minDistance = distance;\n    }\n  });\n  return result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name closestTo\n * @category Common Helpers\n * @summary Return a date from the array closest to the given date.\n *\n * @description\n * Return a date from the array closest to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now, `closestTo` doesn't throw an exception\n *   when the second argument is not an array, and returns Invalid Date instead.\n *\n * @param {Date|Number} dateToCompare - the date to compare with\n * @param {Date[]|Number[]} datesArray - the array to search\n * @returns {Date} the date from the array closest to the given date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030?\n * var dateToCompare = new Date(2015, 8, 6)\n * var result = closestTo(dateToCompare, [\n *   new Date(2000, 0, 1),\n *   new Date(2030, 0, 1)\n * ])\n * //=> Tue Jan 01 2030 00:00:00\n */\n\nexport default function closestTo(dirtyDateToCompare, dirtyDatesArray) {\n  requiredArgs(2, arguments);\n  var dateToCompare = toDate(dirtyDateToCompare);\n\n  if (isNaN(dateToCompare)) {\n    return new Date(NaN);\n  }\n\n  var timeToCompare = dateToCompare.getTime();\n  var datesArray; // `dirtyDatesArray` is undefined or null\n\n  if (dirtyDatesArray == null) {\n    datesArray = []; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n  } else if (typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array\n  } else {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  }\n\n  var result;\n  var minDistance;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (isNaN(currentDate)) {\n      result = new Date(NaN);\n      minDistance = NaN;\n      return;\n    }\n\n    var distance = Math.abs(timeToCompare - currentDate.getTime());\n\n    if (result == null || distance < minDistance) {\n      result = currentDate;\n      minDistance = distance;\n    }\n  });\n  return result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name compareAsc\n * @category Common Helpers\n * @summary Compare the two dates and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return 1 if the first date is after the second,\n * -1 if the first date is before the second or 0 if dates are equal.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Number} the result of the comparison\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989:\n * var result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> -1\n *\n * @example\n * // Sort the array of dates:\n * var result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareAsc)\n * //=> [\n * //   Wed Feb 11 1987 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Sun Jul 02 1995 00:00:00\n * // ]\n */\n\nexport default function compareAsc(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var diff = dateLeft.getTime() - dateRight.getTime();\n\n  if (diff < 0) {\n    return -1;\n  } else if (diff > 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name compareDesc\n * @category Common Helpers\n * @summary Compare the two dates reverse chronologically and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return -1 if the first date is after the second,\n * 1 if the first date is before the second or 0 if dates are equal.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Number} the result of the comparison\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989 reverse chronologically:\n * var result = compareDesc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> 1\n *\n * @example\n * // Sort the array of dates in reverse chronological order:\n * var result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareDesc)\n * //=> [\n * //   Sun Jul 02 1995 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Wed Feb 11 1987 00:00:00\n * // ]\n */\n\nexport default function compareDesc(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var diff = dateLeft.getTime() - dateRight.getTime();\n\n  if (diff > 0) {\n    return -1;\n  } else if (diff < 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}","/**\n *  Maximum allowed time.\n *  @constant\n *  @type {number}\n *  @default\n */\nexport var maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;\n/**\n *  Minimum allowed time.\n *  @constant\n *  @type {number}\n *  @default\n */\n\nexport var minTime = -maxTime;","import isValid from '../isValid/index.js';\nimport isWeekend from '../isWeekend/index.js';\nimport toDate from '../toDate/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport addDays from '../addDays/index.js';\nimport isSameDay from '../isSameDay/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInBusinessDays\n * @category Day Helpers\n * @summary Get the number of business days between the given dates.\n *\n * @description\n * Get the number of business day periods between the given dates.\n * Business days being days that arent in the weekend.\n * Like `differenceInCalendarDays`, the function removes the times from\n * the dates before calculating the difference.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of business days\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many business days are between\n * // 10 January 2014 and 20 July 2014?\n * var result = differenceInBusinessDays(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 0, 10)\n * )\n * //=> 136\n */\n\nexport default function differenceInBusinessDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  if (!isValid(dateLeft) || !isValid(dateRight)) return new Date(NaN);\n  var calendarDifference = differenceInCalendarDays(dateLeft, dateRight);\n  var sign = calendarDifference < 0 ? -1 : 1;\n  var weeks = toInteger(calendarDifference / 7);\n  var result = weeks * 5;\n  dateRight = addDays(dateRight, weeks * 7); // the loop below will run at most 6 times to account for the remaining days that don't makeup a full week\n\n  while (!isSameDay(dateLeft, dateRight)) {\n    // sign is used to account for both negative and positive differences\n    result += isWeekend(dateRight) ? 0 : sign;\n    dateRight = addDays(dateRight, sign);\n  }\n\n  return result === 0 ? 0 : result;\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport startOfDay from '../startOfDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 86400000;\n/**\n * @name differenceInCalendarDays\n * @category Day Helpers\n * @summary Get the number of calendar days between the given dates.\n *\n * @description\n * Get the number of calendar days between the given dates. This means that the times are removed\n * from the dates and then the difference in days is calculated.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar days\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar days are between\n * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?\n * var result = differenceInCalendarDays(\n *   new Date(2012, 6, 2, 0, 0),\n *   new Date(2011, 6, 2, 23, 0)\n * )\n * //=> 366\n * // How many calendar days are between\n * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?\n * var result = differenceInCalendarDays(\n *   new Date(2011, 6, 3, 0, 1),\n *   new Date(2011, 6, 2, 23, 59)\n * )\n * //=> 1\n */\n\nexport default function differenceInCalendarDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var startOfDayLeft = startOfDay(dirtyDateLeft);\n  var startOfDayRight = startOfDay(dirtyDateRight);\n  var timestampLeft = startOfDayLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfDayLeft);\n  var timestampRight = startOfDayRight.getTime() - getTimezoneOffsetInMilliseconds(startOfDayRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a day is not constant\n  // (e.g. it's different in the day of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY);\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of calendar ISO week-numbering years between the given dates.\n *\n * @description\n * Get the number of calendar ISO week-numbering years between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `differenceInCalendarISOYears` to `differenceInCalendarISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar ISO week-numbering years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar ISO week-numbering years are 1 January 2010 and 1 January 2012?\n * var result = differenceInCalendarISOWeekYears(\n *   new Date(2012, 0, 1),\n *   new Date(2010, 0, 1)\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarISOWeekYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  return getISOWeekYear(dirtyDateLeft) - getISOWeekYear(dirtyDateRight);\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name differenceInCalendarISOWeeks\n * @category ISO Week Helpers\n * @summary Get the number of calendar ISO weeks between the given dates.\n *\n * @description\n * Get the number of calendar ISO weeks between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar ISO weeks\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar ISO weeks are between 6 July 2014 and 21 July 2014?\n * var result = differenceInCalendarISOWeeks(\n *   new Date(2014, 6, 21),\n *   new Date(2014, 6, 6)\n * )\n * //=> 3\n */\n\nexport default function differenceInCalendarISOWeeks(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var startOfISOWeekLeft = startOfISOWeek(dirtyDateLeft);\n  var startOfISOWeekRight = startOfISOWeek(dirtyDateRight);\n  var timestampLeft = startOfISOWeekLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfISOWeekLeft);\n  var timestampRight = startOfISOWeekRight.getTime() - getTimezoneOffsetInMilliseconds(startOfISOWeekRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarMonths\n * @category Month Helpers\n * @summary Get the number of calendar months between the given dates.\n *\n * @description\n * Get the number of calendar months between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar months\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar months are between 31 January 2014 and 1 September 2014?\n * var result = differenceInCalendarMonths(\n *   new Date(2014, 8, 1),\n *   new Date(2014, 0, 31)\n * )\n * //=> 8\n */\n\nexport default function differenceInCalendarMonths(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();\n  var monthDiff = dateLeft.getMonth() - dateRight.getMonth();\n  return yearDiff * 12 + monthDiff;\n}","import getQuarter from '../getQuarter/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarQuarters\n * @category Quarter Helpers\n * @summary Get the number of calendar quarters between the given dates.\n *\n * @description\n * Get the number of calendar quarters between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar quarters\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar quarters are between 31 December 2013 and 2 July 2014?\n * var result = differenceInCalendarQuarters(\n *   new Date(2014, 6, 2),\n *   new Date(2013, 11, 31)\n * )\n * //=> 3\n */\n\nexport default function differenceInCalendarQuarters(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();\n  var quarterDiff = getQuarter(dateLeft) - getQuarter(dateRight);\n  return yearDiff * 4 + quarterDiff;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name differenceInCalendarWeeks\n * @category Week Helpers\n * @summary Get the number of calendar weeks between the given dates.\n *\n * @description\n * Get the number of calendar weeks between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInCalendarWeeks(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 6, 5)\n * )\n * //=> 3\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInCalendarWeeks(\n *   new Date(2014, 6, 20),\n *   new Date(2014, 6, 5),\n *   { weekStartsOn: 1 }\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarWeeks(dirtyDateLeft, dirtyDateRight, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var startOfWeekLeft = startOfWeek(dirtyDateLeft, dirtyOptions);\n  var startOfWeekRight = startOfWeek(dirtyDateRight, dirtyOptions);\n  var timestampLeft = startOfWeekLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekLeft);\n  var timestampRight = startOfWeekRight.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekRight); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInCalendarYears\n * @category Year Helpers\n * @summary Get the number of calendar years between the given dates.\n *\n * @description\n * Get the number of calendar years between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of calendar years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many calendar years are between 31 December 2013 and 11 February 2015?\n * var result = differenceInCalendarYears(\n *   new Date(2015, 1, 11),\n *   new Date(2013, 11, 31)\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() - dateRight.getFullYear();\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // Like `compareAsc` but uses local time not UTC, which is needed\n// for accurate equality comparisons of UTC timestamps that end up\n// having the same representation in local time, e.g. one hour before\n// DST ends vs. the instant that DST ends.\n\nfunction compareLocalAsc(dateLeft, dateRight) {\n  var diff = dateLeft.getFullYear() - dateRight.getFullYear() || dateLeft.getMonth() - dateRight.getMonth() || dateLeft.getDate() - dateRight.getDate() || dateLeft.getHours() - dateRight.getHours() || dateLeft.getMinutes() - dateRight.getMinutes() || dateLeft.getSeconds() - dateRight.getSeconds() || dateLeft.getMilliseconds() - dateRight.getMilliseconds();\n\n  if (diff < 0) {\n    return -1;\n  } else if (diff > 0) {\n    return 1; // Return 0 if diff is 0; return NaN if diff is NaN\n  } else {\n    return diff;\n  }\n}\n/**\n * @name differenceInDays\n * @category Day Helpers\n * @summary Get the number of full days between the given dates.\n *\n * @description\n * Get the number of full day periods between two dates. Fractional days are\n * truncated towards zero.\n *\n * One \"full day\" is the distance between a local time in one day to the same\n * local time on the next or previous day. A full day can sometimes be less than\n * or more than 24 hours if a daylight savings change happens between two dates.\n *\n * To ignore DST and only measure exact 24-hour periods, use this instead:\n * `Math.floor(differenceInHours(dateLeft, dateRight)/24)|0`.\n *\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full days according to the local timezone\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full days are between\n * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?\n * var result = differenceInDays(\n *   new Date(2012, 6, 2, 0, 0),\n *   new Date(2011, 6, 2, 23, 0)\n * )\n * //=> 365\n * // How many full days are between\n * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?\n * var result = differenceInDays(\n *   new Date(2011, 6, 3, 0, 1),\n *   new Date(2011, 6, 2, 23, 59)\n * )\n * //=> 0\n * // How many full days are between\n * // 1 March 2020 0:00 and 1 June 2020 0:00 ?\n * // Note: because local time is used, the\n * // result will always be 92 days, even in\n * // time zones where DST starts and the\n * // period has only 92*24-1 hours.\n * var result = differenceInDays(\n *   new Date(2020, 5, 1),\n *   new Date(2020, 2, 1)\n * )\n//=> 92\n */\n\n\nexport default function differenceInDays(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareLocalAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarDays(dateLeft, dateRight));\n  dateLeft.setDate(dateLeft.getDate() - sign * difference); // Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastDayNotFull = compareLocalAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastDayNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\n/**\n * @name differenceInHours\n * @category Hour Helpers\n * @summary Get the number of hours between the given dates.\n *\n * @description\n * Get the number of hours between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of hours\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00?\n * var result = differenceInHours(\n *   new Date(2014, 6, 2, 19, 0),\n *   new Date(2014, 6, 2, 6, 50)\n * )\n * //=> 12\n */\n\nexport default function differenceInHours(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_HOUR;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarISOWeekYears from '../differenceInCalendarISOWeekYears/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport subISOWeekYears from '../subISOWeekYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of full ISO week-numbering years between the given dates.\n *\n * @description\n * Get the number of full ISO week-numbering years between the given dates.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `differenceInISOYears` to `differenceInISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full ISO week-numbering years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full ISO week-numbering years are between 1 January 2010 and 1 January 2012?\n * var result = differenceInISOWeekYears(\n *   new Date(2012, 0, 1),\n *   new Date(2010, 0, 1)\n * )\n * //=> 1\n */\n\nexport default function differenceInISOWeekYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarISOWeekYears(dateLeft, dateRight));\n  dateLeft = subISOWeekYears(dateLeft, sign * difference); // Math.abs(diff in full ISO years - diff in calendar ISO years) === 1\n  // if last calendar ISO year is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastISOWeekYearNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastISOWeekYearNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInMilliseconds\n * @category Millisecond Helpers\n * @summary Get the number of milliseconds between the given dates.\n *\n * @description\n * Get the number of milliseconds between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of milliseconds\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many milliseconds are between\n * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?\n * var result = differenceInMilliseconds(\n *   new Date(2014, 6, 2, 12, 30, 21, 700),\n *   new Date(2014, 6, 2, 12, 30, 20, 600)\n * )\n * //=> 1100\n */\n\nexport default function differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getTime() - dateRight.getTime();\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_MINUTE = 60000;\n/**\n * @name differenceInMinutes\n * @category Minute Helpers\n * @summary Get the number of minutes between the given dates.\n *\n * @description\n * Get the signed number of full (rounded towards 0) minutes between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of minutes\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00?\n * var result = differenceInMinutes(\n *   new Date(2014, 6, 2, 12, 20, 0),\n *   new Date(2014, 6, 2, 12, 7, 59)\n * )\n * //=> 12\n *\n * @example\n * // How many minutes are from 10:01:59 to 10:00:00\n * var result = differenceInMinutes(\n *   new Date(2000, 0, 1, 10, 0, 0),\n *   new Date(2000, 0, 1, 10, 1, 59)\n * )\n * //=> -1\n */\n\nexport default function differenceInMinutes(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_MINUTE;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarMonths from '../differenceInCalendarMonths/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInMonths\n * @category Month Helpers\n * @summary Get the number of full months between the given dates.\n *\n * @description\n * Get the number of full months between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full months\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full months are between 31 January 2014 and 1 September 2014?\n * var result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))\n * //=> 7\n */\n\nexport default function differenceInMonths(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarMonths(dateLeft, dateRight));\n  dateLeft.setMonth(dateLeft.getMonth() - sign * difference); // Math.abs(diff in full months - diff in calendar months) === 1 if last calendar month is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastMonthNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastMonthNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import differenceInMonths from '../differenceInMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInQuarters\n * @category Quarter Helpers\n * @summary Get the number of full quarters between the given dates.\n *\n * @description\n * Get the number of full quarters between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full quarters\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full quarters are between 31 December 2013 and 2 July 2014?\n * var result = differenceInQuarters(new Date(2014, 6, 2), new Date(2013, 11, 31))\n * //=> 2\n */\n\nexport default function differenceInQuarters(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMonths(dirtyDateLeft, dirtyDateRight) / 3;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import differenceInMilliseconds from '../differenceInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInSeconds\n * @category Second Helpers\n * @summary Get the number of seconds between the given dates.\n *\n * @description\n * Get the number of seconds between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of seconds\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many seconds are between\n * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?\n * var result = differenceInSeconds(\n *   new Date(2014, 6, 2, 12, 30, 20, 0),\n *   new Date(2014, 6, 2, 12, 30, 7, 999)\n * )\n * //=> 12\n */\n\nexport default function differenceInSeconds(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / 1000;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import differenceInDays from '../differenceInDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInWeeks\n * @category Week Helpers\n * @summary Get the number of full weeks between the given dates.\n *\n * @description\n * Get the number of full weeks between two dates. Fractional weeks are\n * truncated towards zero.\n *\n * One \"full week\" is the distance between a local time in one day to the same\n * local time 7 days earlier or later. A full week can sometimes be less than\n * or more than 7*24 hours if a daylight savings change happens between two dates.\n *\n * To ignore DST and only measure exact 7*24-hour periods, use this instead:\n * `Math.floor(differenceInHours(dateLeft, dateRight)/(7*24))|0`.\n *\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full weeks\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full weeks are between 5 July 2014 and 20 July 2014?\n * var result = differenceInWeeks(new Date(2014, 6, 20), new Date(2014, 6, 5))\n * //=> 2\n *\n * // How many full weeks are between\n * // 1 March 2020 0:00 and 6 June 2020 0:00 ?\n * // Note: because local time is used, the\n * // result will always be 8 weeks (54 days),\n * // even if DST starts and the period has\n * // only 54*24-1 hours.\n * var result = differenceInWeeks(\n *   new Date(2020, 5, 1),\n *   new Date(2020, 2, 6)\n * )\n * //=> 8\n */\n\nexport default function differenceInWeeks(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var diff = differenceInDays(dirtyDateLeft, dirtyDateRight) / 7;\n  return diff > 0 ? Math.floor(diff) : Math.ceil(diff);\n}","import toDate from '../toDate/index.js';\nimport differenceInCalendarYears from '../differenceInCalendarYears/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name differenceInYears\n * @category Year Helpers\n * @summary Get the number of full years between the given dates.\n *\n * @description\n * Get the number of full years between the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @returns {Number} the number of full years\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // How many full years are between 31 December 2013 and 11 February 2015?\n * var result = differenceInYears(new Date(2015, 1, 11), new Date(2013, 11, 31))\n * //=> 1\n */\n\nexport default function differenceInYears(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  var sign = compareAsc(dateLeft, dateRight);\n  var difference = Math.abs(differenceInCalendarYears(dateLeft, dateRight)); // Set both dates to a valid leap year for accurate comparison when dealing\n  // with leap days\n\n  dateLeft.setFullYear('1584');\n  dateRight.setFullYear('1584'); // Math.abs(diff in full years - diff in calendar years) === 1 if last calendar year is not full\n  // If so, result must be decreased by 1 in absolute value\n\n  var isLastYearNotFull = compareAsc(dateLeft, dateRight) === -sign;\n  var result = sign * (difference - isLastYearNotFull); // Prevent negative zero\n\n  return result === 0 ? 0 : result;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachDayOfInterval\n * @category Interval Helpers\n * @summary Return the array of dates within the specified time interval.\n *\n * @description\n * Return the array of dates within the specified time interval.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `eachDay` to `eachDayOfInterval`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   eachDay(new Date(2014, 0, 10), new Date(2014, 0, 20))\n *\n *   // v2.0.0 onward\n *\n *   eachDayOfInterval(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) }\n *   )\n *   ```\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.step=1] - the step to increment by. The value should be more than 1.\n * @returns {Date[]} the array with starts of days from the day of the interval start to the day of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.step` must be a number greater than 1\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each day between 6 October 2014 and 10 October 2014:\n * var result = eachDayOfInterval({\n *   start: new Date(2014, 9, 6),\n *   end: new Date(2014, 9, 10)\n * })\n * //=> [\n * //   Mon Oct 06 2014 00:00:00,\n * //   Tue Oct 07 2014 00:00:00,\n * //   Wed Oct 08 2014 00:00:00,\n * //   Thu Oct 09 2014 00:00:00,\n * //   Fri Oct 10 2014 00:00:00\n * // ]\n */\n\nexport default function eachDayOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  var step = options && 'step' in options ? Number(options.step) : 1;\n  if (step < 1 || isNaN(step)) throw new RangeError('`options.step` must be a number greater than 1');\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setDate(currentDate.getDate() + step);\n    currentDate.setHours(0, 0, 0, 0);\n  }\n\n  return dates;\n}","import addHours from '../addHours/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachHourOfInterval\n * @category Interval Helpers\n * @summary Return the array of hours within the specified time interval.\n *\n * @description\n * Return the array of hours within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.step=1] - the step to increment by. The value should be more than 1.\n * @returns {Date[]} the array with starts of hours from the hour of the interval start to the hour of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.step` must be a number greater than 1\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each hour between 6 October 2014, 12:00 and 10 October 2014, 15:00\n * var result = eachHourOfInterval({\n *   start: new Date(2014, 9, 6, 12),\n *   end: new Date(2014, 9, 6, 15)\n * })\n * //=> [\n * //   Mon Oct 06 2014 12:00:00,\n * //   Mon Oct 06 2014 13:00:00,\n * //   Mon Oct 06 2014 14:00:00,\n * //   Mon Oct 06 2014 15:00:00\n * // ]\n */\n\nexport default function eachHourOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var startTime = startDate.getTime();\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startTime <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setMinutes(0, 0, 0);\n  var step = options && 'step' in options ? Number(options.step) : 1;\n  if (step < 1 || isNaN(step)) throw new RangeError('`options.step` must be a number greater than 1');\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate = addHours(currentDate, step);\n  }\n\n  return dates;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachMonthOfInterval\n * @category Interval Helpers\n * @summary Return the array of months within the specified time interval.\n *\n * @description\n * Return the array of months within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of months from the month of the interval start to the month of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each month between 6 February 2014 and 10 August 2014:\n * var result = eachMonthOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2014, 7, 10)\n * })\n * //=> [\n * //   Sat Feb 01 2014 00:00:00,\n * //   Sat Mar 01 2014 00:00:00,\n * //   Tue Apr 01 2014 00:00:00,\n * //   Thu May 01 2014 00:00:00,\n * //   Sun Jun 01 2014 00:00:00,\n * //   Tue Jul 01 2014 00:00:00,\n * //   Fri Aug 01 2014 00:00:00\n * // ]\n */\n\nexport default function eachMonthOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  currentDate.setDate(1);\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setMonth(currentDate.getMonth() + 1);\n  }\n\n  return dates;\n}","import addQuarters from '../addQuarters/index.js';\nimport startOfQuarter from '../startOfQuarter/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachQuarterOfInterval\n * @category Interval Helpers\n * @summary Return the array of quarters within the specified time interval.\n *\n * @description\n * Return the array of quarters within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of quarters from the quarter of the interval start to the quarter of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each quarter within interval 6 February 2014 - 10 August 2014:\n * var result = eachQuarterOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2014, 7, 10)\n * })\n * //=> [\n * //   Wed Jan 01 2014 00:00:00,\n * //   Tue Apr 01 2014 00:00:00,\n * //   Tue Jul 01 2014 00:00:00,\n * // ]\n */\n\nexport default function eachQuarterOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var startDateQuarter = startOfQuarter(startDate);\n  var endDateQuarter = startOfQuarter(endDate);\n  endTime = endDateQuarter.getTime();\n  var quarters = [];\n  var currentQuarter = startDateQuarter;\n\n  while (currentQuarter.getTime() <= endTime) {\n    quarters.push(toDate(currentQuarter));\n    currentQuarter = addQuarters(currentQuarter, 1);\n  }\n\n  return quarters;\n}","import addWeeks from '../addWeeks/index.js';\nimport startOfWeek from '../startOfWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekOfInterval\n * @category Interval Helpers\n * @summary Return the array of weeks within the specified time interval.\n *\n * @description\n * Return the array of weeks within the specified time interval.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date[]} the array with starts of weeks from the week of the interval start to the week of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be 0, 1, ..., 6\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each week within interval 6 October 2014 - 23 November 2014:\n * var result = eachWeekOfInterval({\n *   start: new Date(2014, 9, 6),\n *   end: new Date(2014, 10, 23)\n * })\n * //=> [\n * //   Sun Oct 05 2014 00:00:00,\n * //   Sun Oct 12 2014 00:00:00,\n * //   Sun Oct 19 2014 00:00:00,\n * //   Sun Oct 26 2014 00:00:00,\n * //   Sun Nov 02 2014 00:00:00,\n * //   Sun Nov 09 2014 00:00:00,\n * //   Sun Nov 16 2014 00:00:00,\n * //   Sun Nov 23 2014 00:00:00\n * // ]\n */\n\nexport default function eachWeekOfInterval(dirtyInterval, options) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var startDateWeek = startOfWeek(startDate, options);\n  var endDateWeek = startOfWeek(endDate, options); // Some timezones switch DST at midnight, making start of day unreliable in these timezones, 3pm is a safe bet\n\n  startDateWeek.setHours(15);\n  endDateWeek.setHours(15);\n  endTime = endDateWeek.getTime();\n  var weeks = [];\n  var currentWeek = startDateWeek;\n\n  while (currentWeek.getTime() <= endTime) {\n    currentWeek.setHours(0);\n    weeks.push(toDate(currentWeek));\n    currentWeek = addWeeks(currentWeek, 1);\n    currentWeek.setHours(15);\n  }\n\n  return weeks;\n}","import eachDayOfInterval from '../eachDayOfInterval/index.js';\nimport isSunday from '../isSunday/index.js';\nimport isWeekend from '../isWeekend/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfInterval\n * @category Interval Helpers\n * @summary List all the Saturdays and Sundays in the given date interval.\n *\n * @description\n * Get all the Saturdays and Sundays in the given date interval.\n *\n * @param {Interval} interval - the given interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Lists all Saturdays and Sundays in the given date interval\n * var result = eachWeekendOfInterval({\n *   start: new Date(2018, 8, 17),\n *   end: new Date(2018, 8, 30)\n * })\n * //=> [\n * //   Sat Sep 22 2018 00:00:00,\n * //   Sun Sep 23 2018 00:00:00,\n * //   Sat Sep 29 2018 00:00:00,\n * //   Sun Sep 30 2018 00:00:00\n * // ]\n */\n\nexport default function eachWeekendOfInterval(interval) {\n  requiredArgs(1, arguments);\n  var dateInterval = eachDayOfInterval(interval);\n  var weekends = [];\n  var index = 0;\n\n  while (index < dateInterval.length) {\n    var date = dateInterval[index++];\n\n    if (isWeekend(date)) {\n      weekends.push(date);\n      if (isSunday(date)) index = index + 5;\n    }\n  }\n\n  return weekends;\n}","import eachWeekendOfInterval from '../eachWeekendOfInterval/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport endOfMonth from '../endOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfMonth\n * @category Month Helpers\n * @summary List all the Saturdays and Sundays in the given month.\n *\n * @description\n * Get all the Saturdays and Sundays in the given month.\n *\n * @param {Date|Number} date - the given month\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The passed date is invalid\n *\n * @example\n * // Lists all Saturdays and Sundays in the given month\n * var result = eachWeekendOfMonth(new Date(2022, 1, 1))\n * //=> [\n * //   Sat Feb 05 2022 00:00:00,\n * //   Sun Feb 06 2022 00:00:00,\n * //   Sat Feb 12 2022 00:00:00,\n * //   Sun Feb 13 2022 00:00:00,\n * //   Sat Feb 19 2022 00:00:00,\n * //   Sun Feb 20 2022 00:00:00,\n * //   Sat Feb 26 2022 00:00:00,\n * //   Sun Feb 27 2022 00:00:00\n * // ]\n */\n\nexport default function eachWeekendOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var startDate = startOfMonth(dirtyDate);\n  if (isNaN(startDate)) throw new RangeError('The passed date is invalid');\n  var endDate = endOfMonth(dirtyDate);\n  return eachWeekendOfInterval({\n    start: startDate,\n    end: endDate\n  });\n}","import eachWeekendOfInterval from '../eachWeekendOfInterval/index.js';\nimport startOfYear from '../startOfYear/index.js';\nimport endOfYear from '../endOfYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachWeekendOfYear\n * @category Year Helpers\n * @summary List all the Saturdays and Sundays in the year.\n *\n * @description\n * Get all the Saturdays and Sundays in the year.\n *\n * @param {Date|Number} date - the given year\n * @returns {Date[]} an array containing all the Saturdays and Sundays\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The passed date is invalid\n *\n * @example\n * // Lists all Saturdays and Sundays in the year\n * var result = eachWeekendOfYear(new Date(2020, 1, 1))\n * //=> [\n * //   Sat Jan 03 2020 00:00:00,\n * //   Sun Jan 04 2020 00:00:00,\n * //   ...\n * //   Sun Dec 27 2020 00:00:00\n * // ]\n * ]\n */\n\nexport default function eachWeekendOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var startDate = startOfYear(dirtyDate);\n  if (isNaN(startDate)) throw new RangeError('The passed date is invalid');\n  var endDate = endOfYear(dirtyDate);\n  return eachWeekendOfInterval({\n    start: startDate,\n    end: endDate\n  });\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name eachYearOfInterval\n * @category Interval Helpers\n * @summary Return the array of yearly timestamps within the specified time interval.\n *\n * @description\n * Return the array of yearly timestamps within the specified time interval.\n *\n * @param {Interval} interval - the interval. See [Interval]{@link docs/types/Interval}\n * @returns {Date[]} the array with starts of yearly timestamps from the month of the interval start to the month of the interval end\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // Each year between 6 February 2014 and 10 August 2017:\n * var result = eachYearOfInterval({\n *   start: new Date(2014, 1, 6),\n *   end: new Date(2017, 7, 10)\n * })\n * //=> [\n * //   Wed Jan 01 2014 00:00:00,\n * //   Thu Jan 01 2015 00:00:00,\n * //   Fri Jan 01 2016 00:00:00,\n * //   Sun Jan 01 2017 00:00:00\n * // ]\n */\n\nexport default function eachYearOfInterval(dirtyInterval) {\n  requiredArgs(1, arguments);\n  var interval = dirtyInterval || {};\n  var startDate = toDate(interval.start);\n  var endDate = toDate(interval.end);\n  var endTime = endDate.getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startDate.getTime() <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var dates = [];\n  var currentDate = startDate;\n  currentDate.setHours(0, 0, 0, 0);\n  currentDate.setMonth(0, 1);\n\n  while (currentDate.getTime() <= endTime) {\n    dates.push(toDate(currentDate));\n    currentDate.setFullYear(currentDate.getFullYear() + 1);\n  }\n\n  return dates;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfDay\n * @category Day Helpers\n * @summary Return the end of a day for the given date.\n *\n * @description\n * Return the end of a day for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a day\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a day for 2 September 2014 11:55:00:\n * var result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 23:59:59.999\n */\n\nexport default function endOfDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfDecade\n * @category Decade Helpers\n * @summary Return the end of a decade for the given date.\n *\n * @description\n * Return the end of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a decade\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // The end of a decade for 12 May 1984 00:00:00:\n * var result = endOfDecade(new Date(1984, 4, 12, 00, 00, 00))\n * //=> Dec 31 1989 23:59:59.999\n */\n\nexport default function endOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = 9 + Math.floor(year / 10) * 10;\n  date.setFullYear(decade, 11, 31);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfHour\n * @category Hour Helpers\n * @summary Return the end of an hour for the given date.\n *\n * @description\n * Return the end of an hour for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an hour for 2 September 2014 11:55:00:\n * var result = endOfHour(new Date(2014, 8, 2, 11, 55))\n * //=> Tue Sep 02 2014 11:59:59.999\n */\n\nexport default function endOfHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMinutes(59, 59, 999);\n  return date;\n}","import endOfWeek from '../endOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the end of an ISO week for the given date.\n *\n * @description\n * Return the end of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an ISO week for 2 September 2014 11:55:00:\n * var result = endOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Sep 07 2014 23:59:59.999\n */\n\nexport default function endOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return endOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the end of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the end of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `endOfISOYear` to `endOfISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `addWeekYears`.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of an ISO week-numbering year for 2 July 2005:\n * var result = endOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Sun Jan 01 2006 23:59:59.999\n */\n\nexport default function endOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuaryOfNextYear);\n  date.setMilliseconds(date.getMilliseconds() - 1);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfMinute\n * @category Minute Helpers\n * @summary Return the end of a minute for the given date.\n *\n * @description\n * Return the end of a minute for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a minute for 1 December 2014 22:15:45.400:\n * var result = endOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:59.999\n */\n\nexport default function endOfMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setSeconds(59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfMonth\n * @category Month Helpers\n * @summary Return the end of a month for the given date.\n *\n * @description\n * Return the end of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a month for 2 September 2014 11:55:00:\n * var result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\n\nexport default function endOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  date.setFullYear(date.getFullYear(), month + 1, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfQuarter\n * @category Quarter Helpers\n * @summary Return the end of a year quarter for the given date.\n *\n * @description\n * Return the end of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a quarter for 2 September 2014 11:55:00:\n * var result = endOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\n\nexport default function endOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3 + 3;\n  date.setMonth(month, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfSecond\n * @category Second Helpers\n * @summary Return the end of a second for the given date.\n *\n * @description\n * Return the end of a second for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a second for 1 December 2014 22:15:45.400:\n * var result = endOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:45.999\n */\n\nexport default function endOfSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMilliseconds(999);\n  return date;\n}","import endOfDay from '../endOfDay/index.js';\n/**\n * @name endOfToday\n * @category Day Helpers\n * @summary Return the end of today.\n * @pure false\n *\n * @description\n * Return the end of today.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of today\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfToday()\n * //=> Mon Oct 6 2014 23:59:59.999\n */\n\nexport default function endOfToday() {\n  return endOfDay(Date.now());\n}","/**\n * @name endOfTomorrow\n * @category Day Helpers\n * @summary Return the end of tomorrow.\n * @pure false\n *\n * @description\n * Return the end of tomorrow.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of tomorrow\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfTomorrow()\n * //=> Tue Oct 7 2014 23:59:59.999\n */\nexport default function endOfTomorrow() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day + 1);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfWeek\n * @category Week Helpers\n * @summary Return the end of a week for the given date.\n *\n * @description\n * Return the end of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the end of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The end of a week for 2 September 2014 11:55:00:\n * var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sat Sep 06 2014 23:59:59.999\n *\n * @example\n * // If the week starts on Monday, the end of the week for 2 September 2014 11:55:00:\n * var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 23:59:59.999\n */\n\nexport default function endOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);\n  date.setDate(date.getDate() + diff);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name endOfYear\n * @category Year Helpers\n * @summary Return the end of a year for the given date.\n *\n * @description\n * Return the end of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The end of a year for 2 September 2014 11:55:00:\n * var result = endOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Dec 31 2014 23:59:59.999\n */\n\nexport default function endOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  date.setFullYear(year + 1, 0, 0);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","/**\n * @name endOfYesterday\n * @category Day Helpers\n * @summary Return the end of yesterday.\n * @pure false\n *\n * @description\n * Return the end of yesterday.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the end of yesterday\n *\n * @example\n * // If today is 6 October 2014:\n * var result = endOfYesterday()\n * //=> Sun Oct 5 2014 23:59:59.999\n */\nexport default function endOfYesterday() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day - 1);\n  date.setHours(23, 59, 59, 999);\n  return date;\n}","import isValid from '../isValid/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport formatters from '../_lib/format/formatters/index.js';\nimport longFormatters from '../_lib/format/longFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport { isProtectedDayOfYearToken, isProtectedWeekYearToken, throwProtectedError } from '../_lib/protectedTokens/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n//   (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\n\nvar longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name format\n * @category Common Helpers\n * @summary Format the date.\n *\n * @description\n * Return the formatted date string in the given format. The result may vary by locale.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n * (see the last example)\n *\n * Format of the string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 7 below the table).\n *\n * Accepted patterns:\n * | Unit                            | Pattern | Result examples                   | Notes |\n * |---------------------------------|---------|-----------------------------------|-------|\n * | Era                             | G..GGG  | AD, BC                            |       |\n * |                                 | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 | GGGGG   | A, B                              |       |\n * | Calendar year                   | y       | 44, 1, 1900, 2017                 | 5     |\n * |                                 | yo      | 44th, 1st, 0th, 17th              | 5,7   |\n * |                                 | yy      | 44, 01, 00, 17                    | 5     |\n * |                                 | yyy     | 044, 001, 1900, 2017              | 5     |\n * |                                 | yyyy    | 0044, 0001, 1900, 2017            | 5     |\n * |                                 | yyyyy   | ...                               | 3,5   |\n * | Local week-numbering year       | Y       | 44, 1, 1900, 2017                 | 5     |\n * |                                 | Yo      | 44th, 1st, 1900th, 2017th         | 5,7   |\n * |                                 | YY      | 44, 01, 00, 17                    | 5,8   |\n * |                                 | YYY     | 044, 001, 1900, 2017              | 5     |\n * |                                 | YYYY    | 0044, 0001, 1900, 2017            | 5,8   |\n * |                                 | YYYYY   | ...                               | 3,5   |\n * | ISO week-numbering year         | R       | -43, 0, 1, 1900, 2017             | 5,7   |\n * |                                 | RR      | -43, 00, 01, 1900, 2017           | 5,7   |\n * |                                 | RRR     | -043, 000, 001, 1900, 2017        | 5,7   |\n * |                                 | RRRR    | -0043, 0000, 0001, 1900, 2017     | 5,7   |\n * |                                 | RRRRR   | ...                               | 3,5,7 |\n * | Extended year                   | u       | -43, 0, 1, 1900, 2017             | 5     |\n * |                                 | uu      | -43, 01, 1900, 2017               | 5     |\n * |                                 | uuu     | -043, 001, 1900, 2017             | 5     |\n * |                                 | uuuu    | -0043, 0001, 1900, 2017           | 5     |\n * |                                 | uuuuu   | ...                               | 3,5   |\n * | Quarter (formatting)            | Q       | 1, 2, 3, 4                        |       |\n * |                                 | Qo      | 1st, 2nd, 3rd, 4th                | 7     |\n * |                                 | QQ      | 01, 02, 03, 04                    |       |\n * |                                 | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | q       | 1, 2, 3, 4                        |       |\n * |                                 | qo      | 1st, 2nd, 3rd, 4th                | 7     |\n * |                                 | qq      | 01, 02, 03, 04                    |       |\n * |                                 | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 | qqqqq   | 1, 2, 3, 4                        | 4     |\n * | Month (formatting)              | M       | 1, 2, ..., 12                     |       |\n * |                                 | Mo      | 1st, 2nd, ..., 12th               | 7     |\n * |                                 | MM      | 01, 02, ..., 12                   |       |\n * |                                 | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 | MMMM    | January, February, ..., December  | 2     |\n * |                                 | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | L       | 1, 2, ..., 12                     |       |\n * |                                 | Lo      | 1st, 2nd, ..., 12th               | 7     |\n * |                                 | LL      | 01, 02, ..., 12                   |       |\n * |                                 | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 | LLLL    | January, February, ..., December  | 2     |\n * |                                 | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | w       | 1, 2, ..., 53                     |       |\n * |                                 | wo      | 1st, 2nd, ..., 53th               | 7     |\n * |                                 | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | I       | 1, 2, ..., 53                     | 7     |\n * |                                 | Io      | 1st, 2nd, ..., 53th               | 7     |\n * |                                 | II      | 01, 02, ..., 53                   | 7     |\n * | Day of month                    | d       | 1, 2, ..., 31                     |       |\n * |                                 | do      | 1st, 2nd, ..., 31st               | 7     |\n * |                                 | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     | D       | 1, 2, ..., 365, 366               | 9     |\n * |                                 | Do      | 1st, 2nd, ..., 365th, 366th       | 7     |\n * |                                 | DD      | 01, 02, ..., 365, 366             | 9     |\n * |                                 | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 | DDDD    | ...                               | 3     |\n * | Day of week (formatting)        | E..EEE  | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    | i       | 1, 2, 3, ..., 7                   | 7     |\n * |                                 | io      | 1st, 2nd, ..., 7th                | 7     |\n * |                                 | ii      | 01, 02, ..., 07                   | 7     |\n * |                                 | iii     | Mon, Tue, Wed, ..., Sun           | 7     |\n * |                                 | iiii    | Monday, Tuesday, ..., Sunday      | 2,7   |\n * |                                 | iiiii   | M, T, W, T, F, S, S               | 7     |\n * |                                 | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 7     |\n * | Local day of week (formatting)  | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 | eo      | 2nd, 3rd, ..., 1st                | 7     |\n * |                                 | ee      | 02, 03, ..., 01                   |       |\n * |                                 | eee     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 | co      | 2nd, 3rd, ..., 1st                | 7     |\n * |                                 | cc      | 02, 03, ..., 01                   |       |\n * |                                 | ccc     | Mon, Tue, Wed, ..., Sun           |       |\n * |                                 | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          | a..aaa  | AM, PM                            |       |\n * |                                 | aaaa    | a.m., p.m.                        | 2     |\n * |                                 | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             | B..BBB  | at night, in the morning, ...     |       |\n * |                                 | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 | ho      | 1st, 2nd, ..., 11th, 12th         | 7     |\n * |                                 | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 | Ho      | 0th, 1st, 2nd, ..., 23rd          | 7     |\n * |                                 | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 | Ko      | 1st, 2nd, ..., 11th, 0th          | 7     |\n * |                                 | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 | ko      | 24th, 1st, 2nd, ..., 23rd         | 7     |\n * |                                 | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          | m       | 0, 1, ..., 59                     |       |\n * |                                 | mo      | 0th, 1st, ..., 59th               | 7     |\n * |                                 | mm      | 00, 01, ..., 59                   |       |\n * | Second                          | s       | 0, 1, ..., 59                     |       |\n * |                                 | so      | 0th, 1st, ..., 59th               | 7     |\n * |                                 | ss      | 00, 01, ..., 59                   |       |\n * | Fraction of second              | S       | 0, 1, ..., 9                      |       |\n * |                                 | SS      | 00, 01, ..., 99                   |       |\n * |                                 | SSS     | 000, 0001, ..., 999               |       |\n * |                                 | SSSS    | ...                               | 3     |\n * | Timezone (ISO-8601 w/ Z)        | X       | -08, +0530, Z                     |       |\n * |                                 | XX      | -0800, +0530, Z                   |       |\n * |                                 | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       | x       | -08, +0530, +00                   |       |\n * |                                 | xx      | -0800, +0530, +0000               |       |\n * |                                 | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Timezone (GMT)                  | O...OOO | GMT-8, GMT+5:30, GMT+0            |       |\n * |                                 | OOOO    | GMT-08:00, GMT+05:30, GMT+00:00   | 2     |\n * | Timezone (specific non-locat.)  | z...zzz | GMT-8, GMT+5:30, GMT+0            | 6     |\n * |                                 | zzzz    | GMT-08:00, GMT+05:30, GMT+00:00   | 2,6   |\n * | Seconds timestamp               | t       | 512969520                         | 7     |\n * |                                 | tt      | ...                               | 3,7   |\n * | Milliseconds timestamp          | T       | 512969520900                      | 7     |\n * |                                 | TT      | ...                               | 3,7   |\n * | Long localized date             | P       | 05/29/1453                        | 7     |\n * |                                 | PP      | May 29, 1453                      | 7     |\n * |                                 | PPP     | May 29th, 1453                    | 7     |\n * |                                 | PPPP    | Sunday, May 29th, 1453            | 2,7   |\n * | Long localized time             | p       | 12:00 AM                          | 7     |\n * |                                 | pp      | 12:00:00 AM                       | 7     |\n * |                                 | ppp     | 12:00:00 AM GMT+2                 | 7     |\n * |                                 | pppp    | 12:00:00 AM GMT+02:00             | 2,7   |\n * | Combination of date and time    | Pp      | 05/29/1453, 12:00 AM              | 7     |\n * |                                 | PPpp    | May 29, 1453, 12:00:00 AM         | 7     |\n * |                                 | PPPppp  | May 29th, 1453 at ...             | 7     |\n * |                                 | PPPPpppp| Sunday, May 29th, 1453 at ...     | 2,7   |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)\n *    the output will be the same as default pattern for this unit, usually\n *    the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units\n *    are marked with \"2\" in the last column of the table.\n *\n *    `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`\n *\n *    `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`\n *\n * 3. Some patterns could be unlimited length (such as `yyyyyyyy`).\n *    The output will be padded with zeros to match the length of the pattern.\n *\n *    `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`\n *\n * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 5. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` always returns the last two digits of a year,\n *    while `uu` pads single digit years to 2 characters and returns other years unchanged:\n *\n *    | Year | `yy` | `uu` |\n *    |------|------|------|\n *    | 1    |   01 |   01 |\n *    | 14   |   14 |   14 |\n *    | 376  |   76 |  376 |\n *    | 1453 |   53 | 1453 |\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [getISOWeekYear]{@link https://date-fns.org/docs/getISOWeekYear}\n *    and [getWeekYear]{@link https://date-fns.org/docs/getWeekYear}).\n *\n * 6. Specific non-location timezones are currently unavailable in `date-fns`,\n *    so right now these tokens fall back to GMT timezones.\n *\n * 7. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `t`: seconds timestamp\n *    - `T`: milliseconds timestamp\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 9. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The second argument is now required for the sake of explicitness.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   format(new Date(2016, 0, 1))\n *\n *   // v2.0.0 onward\n *   format(new Date(2016, 0, 1), \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\")\n *   ```\n *\n * - New format string API for `format` function\n *   which is based on [Unicode Technical Standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).\n *   See [this post](https://blog.date-fns.org/post/unicode-tokens-in-date-fns-v2-sreatyki91jg) for more details.\n *\n * - Characters are now escaped using single quote symbols (`'`) instead of square brackets.\n *\n * @param {Date|Number} date - the original date\n * @param {String} format - the string of tokens\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {Number} [options.firstWeekContainsDate=1] - the day of January, which is\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {String} the formatted date string\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `localize` property\n * @throws {RangeError} `options.locale` must contain `formatLong` property\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Represent 11 February 2014 in middle-endian format:\n * var result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')\n * //=> '02/11/2014'\n *\n * @example\n * // Represent 2 July 2014 in Esperanto:\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = format(new Date(2014, 6, 2), \"do 'de' MMMM yyyy\", {\n *   locale: eoLocale\n * })\n * //=> '2-a de julio 2014'\n *\n * @example\n * // Escape string by single quote characters:\n * var result = format(new Date(2014, 6, 2, 15), \"h 'o''clock'\")\n * //=> \"3 o'clock\"\n */\n\nexport default function format(dirtyDate, dirtyFormatStr, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var formatStr = String(dirtyFormatStr);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n  var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  if (!locale.localize) {\n    throw new RangeError('locale must contain localize property');\n  }\n\n  if (!locale.formatLong) {\n    throw new RangeError('locale must contain formatLong property');\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376\n\n\n  var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);\n  var utcDate = subMilliseconds(originalDate, timezoneOffset);\n  var formatterOptions = {\n    firstWeekContainsDate: firstWeekContainsDate,\n    weekStartsOn: weekStartsOn,\n    locale: locale,\n    _originalDate: originalDate\n  };\n  var result = formatStr.match(longFormattingTokensRegExp).map(function (substring) {\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === 'p' || firstCharacter === 'P') {\n      var longFormatter = longFormatters[firstCharacter];\n      return longFormatter(substring, locale.formatLong, formatterOptions);\n    }\n\n    return substring;\n  }).join('').match(formattingTokensRegExp).map(function (substring) {\n    // Replace two single quote characters with one single quote character\n    if (substring === \"''\") {\n      return \"'\";\n    }\n\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === \"'\") {\n      return cleanEscapedString(substring);\n    }\n\n    var formatter = formatters[firstCharacter];\n\n    if (formatter) {\n      if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(substring)) {\n        throwProtectedError(substring, dirtyFormatStr, dirtyDate);\n      }\n\n      if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(substring)) {\n        throwProtectedError(substring, dirtyFormatStr, dirtyDate);\n      }\n\n      return formatter(utcDate, substring, locale.localize, formatterOptions);\n    }\n\n    if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n      throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n    }\n\n    return substring;\n  }).join('');\n  return result;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","import compareAsc from '../compareAsc/index.js';\nimport differenceInMonths from '../differenceInMonths/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport toDate from '../toDate/index.js';\nimport cloneObject from '../_lib/cloneObject/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MINUTES_IN_DAY = 1440;\nvar MINUTES_IN_ALMOST_TWO_DAYS = 2520;\nvar MINUTES_IN_MONTH = 43200;\nvar MINUTES_IN_TWO_MONTHS = 86400;\n/**\n * @name formatDistance\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words.\n *\n * | Distance between dates                                            | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance between dates | Result               |\n * |------------------------|----------------------|\n * | 0 secs ... 5 secs      | less than 5 seconds  |\n * | 5 secs ... 10 secs     | less than 10 seconds |\n * | 10 secs ... 20 secs    | less than 20 seconds |\n * | 20 secs ... 40 secs    | half a minute        |\n * | 40 secs ... 60 secs    | less than a minute   |\n * | 60 secs ... 90 secs    | 1 minute             |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWords ` to `formatDistance`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n * - The order of arguments is swapped to make the function\n *   consistent with `differenceIn...` functions.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWords(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 11, 32, 0),\n *     { addSuffix: true }\n *   ) //=> 'in about 1 hour'\n *\n *   // v2.0.0 onward\n *\n *   formatDistance(\n *     new Date(1986, 3, 4, 11, 32, 0),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { addSuffix: true }\n *   ) //=> 'in about 1 hour'\n *   ```\n *\n * @param {Date|Number} date - the date\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * var result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00, including seconds?\n * var result = formatDistance(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0),\n *   { includeSeconds: true }\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * var result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> 'about 1 year ago'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> 'pli ol 1 jaro'\n */\n\nexport default function formatDistance(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.formatDistance) {\n    throw new RangeError('locale must contain formatDistance property');\n  }\n\n  var comparison = compareAsc(dirtyDate, dirtyBaseDate);\n\n  if (isNaN(comparison)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var localizeOptions = cloneObject(options);\n  localizeOptions.addSuffix = Boolean(options.addSuffix);\n  localizeOptions.comparison = comparison;\n  var dateLeft;\n  var dateRight;\n\n  if (comparison > 0) {\n    dateLeft = toDate(dirtyBaseDate);\n    dateRight = toDate(dirtyDate);\n  } else {\n    dateLeft = toDate(dirtyDate);\n    dateRight = toDate(dirtyBaseDate);\n  }\n\n  var seconds = differenceInSeconds(dateRight, dateLeft);\n  var offsetInSeconds = (getTimezoneOffsetInMilliseconds(dateRight) - getTimezoneOffsetInMilliseconds(dateLeft)) / 1000;\n  var minutes = Math.round((seconds - offsetInSeconds) / 60);\n  var months; // 0 up to 2 mins\n\n  if (minutes < 2) {\n    if (options.includeSeconds) {\n      if (seconds < 5) {\n        return locale.formatDistance('lessThanXSeconds', 5, localizeOptions);\n      } else if (seconds < 10) {\n        return locale.formatDistance('lessThanXSeconds', 10, localizeOptions);\n      } else if (seconds < 20) {\n        return locale.formatDistance('lessThanXSeconds', 20, localizeOptions);\n      } else if (seconds < 40) {\n        return locale.formatDistance('halfAMinute', null, localizeOptions);\n      } else if (seconds < 60) {\n        return locale.formatDistance('lessThanXMinutes', 1, localizeOptions);\n      } else {\n        return locale.formatDistance('xMinutes', 1, localizeOptions);\n      }\n    } else {\n      if (minutes === 0) {\n        return locale.formatDistance('lessThanXMinutes', 1, localizeOptions);\n      } else {\n        return locale.formatDistance('xMinutes', minutes, localizeOptions);\n      }\n    } // 2 mins up to 0.75 hrs\n\n  } else if (minutes < 45) {\n    return locale.formatDistance('xMinutes', minutes, localizeOptions); // 0.75 hrs up to 1.5 hrs\n  } else if (minutes < 90) {\n    return locale.formatDistance('aboutXHours', 1, localizeOptions); // 1.5 hrs up to 24 hrs\n  } else if (minutes < MINUTES_IN_DAY) {\n    var hours = Math.round(minutes / 60);\n    return locale.formatDistance('aboutXHours', hours, localizeOptions); // 1 day up to 1.75 days\n  } else if (minutes < MINUTES_IN_ALMOST_TWO_DAYS) {\n    return locale.formatDistance('xDays', 1, localizeOptions); // 1.75 days up to 30 days\n  } else if (minutes < MINUTES_IN_MONTH) {\n    var days = Math.round(minutes / MINUTES_IN_DAY);\n    return locale.formatDistance('xDays', days, localizeOptions); // 1 month up to 2 months\n  } else if (minutes < MINUTES_IN_TWO_MONTHS) {\n    months = Math.round(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('aboutXMonths', months, localizeOptions);\n  }\n\n  months = differenceInMonths(dateRight, dateLeft); // 2 months up to 12 months\n\n  if (months < 12) {\n    var nearestMonth = Math.round(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('xMonths', nearestMonth, localizeOptions); // 1 year up to max Date\n  } else {\n    var monthsSinceStartOfYear = months % 12;\n    var years = Math.floor(months / 12); // N years up to 1 years 3 months\n\n    if (monthsSinceStartOfYear < 3) {\n      return locale.formatDistance('aboutXYears', years, localizeOptions); // N years 3 months up to N years 9 months\n    } else if (monthsSinceStartOfYear < 9) {\n      return locale.formatDistance('overXYears', years, localizeOptions); // N years 9 months up to N year 12 months\n    } else {\n      return locale.formatDistance('almostXYears', years + 1, localizeOptions);\n    }\n  }\n}","import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport compareAsc from '../compareAsc/index.js';\nimport toDate from '../toDate/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport cloneObject from '../_lib/cloneObject/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MINUTES_IN_DAY = 1440;\nvar MINUTES_IN_MONTH = 43200;\nvar MINUTES_IN_YEAR = 525600;\n/**\n * @name formatDistanceStrict\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words, using strict units.\n * This is like `formatDistance`, but does not use helpers like 'almost', 'over',\n * 'less than' and the like.\n *\n * | Distance between dates | Result              |\n * |------------------------|---------------------|\n * | 0 ... 59 secs          | [0..59] seconds     |\n * | 1 ... 59 mins          | [1..59] minutes     |\n * | 1 ... 23 hrs           | [1..23] hours       |\n * | 1 ... 29 days          | [1..29] days        |\n * | 1 ... 11 months        | [1..11] months      |\n * | 1 ... N years          | [1..N]  years       |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWordsStrict` to `formatDistanceStrict`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n * - The order of arguments is swapped to make the function\n *   consistent with `differenceIn...` functions.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(2015, 0, 2),\n *     new Date(2014, 6, 2)\n *   ) //=> '6 months'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(2014, 6, 2),\n *     new Date(2015, 0, 2)\n *   ) //=> '6 months'\n *   ```\n *\n * - `partialMethod` option is renamed to `roundingMethod`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     { partialMethod: 'ceil' }\n *   ) //=> '2 minutes'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { roundingMethod: 'ceil' }\n *   ) //=> '2 minutes'\n *   ```\n *\n * - If `roundingMethod` is not specified, it now defaults to `round` instead of `floor`.\n *\n * - `unit` option now accepts one of the strings:\n *   'second', 'minute', 'hour', 'day', 'month' or 'year' instead of 's', 'm', 'h', 'd', 'M' or 'Y'\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsStrict(\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     { unit: 'm' }\n *   )\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceStrict(\n *     new Date(1986, 3, 4, 10, 33, 1),\n *     new Date(1986, 3, 4, 10, 32, 0),\n *     { unit: 'minute' }\n *   )\n *   ```\n *\n * @param {Date|Number} date - the date\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {'second'|'minute'|'hour'|'day'|'month'|'year'} [options.unit] - if specified, will force a unit\n * @param {'floor'|'ceil'|'round'} [options.roundingMethod='round'] - which way to round partial units\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.roundingMethod` must be 'floor', 'ceil' or 'round'\n * @throws {RangeError} `options.unit` must be 'second', 'minute', 'hour', 'day', 'month' or 'year'\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * var result = formatDistanceStrict(new Date(2014, 6, 2), new Date(2015, 0, 2))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00?\n * var result = formatDistanceStrict(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0)\n * )\n * //=> '15 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * var result = formatDistanceStrict(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> '1 year ago'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, in minutes?\n * var result = formatDistanceStrict(new Date(2016, 0, 1), new Date(2015, 0, 1), {\n *   unit: 'minute'\n * })\n * //=> '525600 minutes'\n *\n * @example\n * // What is the distance from 1 January 2015\n * // to 28 January 2015, in months, rounded up?\n * var result = formatDistanceStrict(new Date(2015, 0, 28), new Date(2015, 0, 1), {\n *   unit: 'month',\n *   roundingMethod: 'ceil'\n * })\n * //=> '1 month'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * var result = formatDistanceStrict(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> '1 jaro'\n */\n\nexport default function formatDistanceStrict(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.formatDistance) {\n    throw new RangeError('locale must contain localize.formatDistance property');\n  }\n\n  var comparison = compareAsc(dirtyDate, dirtyBaseDate);\n\n  if (isNaN(comparison)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var localizeOptions = cloneObject(options);\n  localizeOptions.addSuffix = Boolean(options.addSuffix);\n  localizeOptions.comparison = comparison;\n  var dateLeft;\n  var dateRight;\n\n  if (comparison > 0) {\n    dateLeft = toDate(dirtyBaseDate);\n    dateRight = toDate(dirtyDate);\n  } else {\n    dateLeft = toDate(dirtyDate);\n    dateRight = toDate(dirtyBaseDate);\n  }\n\n  var roundingMethod = options.roundingMethod == null ? 'round' : String(options.roundingMethod);\n  var roundingMethodFn;\n\n  if (roundingMethod === 'floor') {\n    roundingMethodFn = Math.floor;\n  } else if (roundingMethod === 'ceil') {\n    roundingMethodFn = Math.ceil;\n  } else if (roundingMethod === 'round') {\n    roundingMethodFn = Math.round;\n  } else {\n    throw new RangeError(\"roundingMethod must be 'floor', 'ceil' or 'round'\");\n  }\n\n  var seconds = differenceInSeconds(dateRight, dateLeft);\n  var offsetInSeconds = (getTimezoneOffsetInMilliseconds(dateRight) - getTimezoneOffsetInMilliseconds(dateLeft)) / 1000;\n  var minutes = roundingMethodFn((seconds - offsetInSeconds) / 60);\n  var unit;\n\n  if (options.unit == null) {\n    if (minutes < 1) {\n      unit = 'second';\n    } else if (minutes < 60) {\n      unit = 'minute';\n    } else if (minutes < MINUTES_IN_DAY) {\n      unit = 'hour';\n    } else if (minutes < MINUTES_IN_MONTH) {\n      unit = 'day';\n    } else if (minutes < MINUTES_IN_YEAR) {\n      unit = 'month';\n    } else {\n      unit = 'year';\n    }\n  } else {\n    unit = String(options.unit);\n  } // 0 up to 60 seconds\n\n\n  if (unit === 'second') {\n    return locale.formatDistance('xSeconds', seconds, localizeOptions); // 1 up to 60 mins\n  } else if (unit === 'minute') {\n    return locale.formatDistance('xMinutes', minutes, localizeOptions); // 1 up to 24 hours\n  } else if (unit === 'hour') {\n    var hours = roundingMethodFn(minutes / 60);\n    return locale.formatDistance('xHours', hours, localizeOptions); // 1 up to 30 days\n  } else if (unit === 'day') {\n    var days = roundingMethodFn(minutes / MINUTES_IN_DAY);\n    return locale.formatDistance('xDays', days, localizeOptions); // 1 up to 12 months\n  } else if (unit === 'month') {\n    var months = roundingMethodFn(minutes / MINUTES_IN_MONTH);\n    return locale.formatDistance('xMonths', months, localizeOptions); // 1 year up to max Date\n  } else if (unit === 'year') {\n    var years = roundingMethodFn(minutes / MINUTES_IN_YEAR);\n    return locale.formatDistance('xYears', years, localizeOptions);\n  }\n\n  throw new RangeError(\"unit must be 'second', 'minute', 'hour', 'day', 'month' or 'year'\");\n}","import distanceInWords from '../formatDistance/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatDistanceToNow\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given date and now in words.\n *\n * | Distance to now                                                   | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance to now     | Result               |\n * |---------------------|----------------------|\n * | 0 secs ... 5 secs   | less than 5 seconds  |\n * | 5 secs ... 10 secs  | less than 10 seconds |\n * | 10 secs ... 20 secs | less than 20 seconds |\n * | 20 secs ... 40 secs | half a minute        |\n * | 40 secs ... 60 secs | less than a minute   |\n * | 60 secs ... 90 secs | 1 minute             |\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `distanceInWordsToNow ` to `formatDistanceToNow`\n *   to make its name consistent with `format` and `formatRelative`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   distanceInWordsToNow(new Date(2014, 6, 2), { addSuffix: true })\n *   //=> 'in 6 months'\n *\n *   // v2.0.0 onward\n *\n *   formatDistanceToNow(new Date(2014, 6, 2), { addSuffix: true })\n *   //=> 'in 6 months'\n *   ```\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - the object with options\n * @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed\n * @param {Boolean} [options.addSuffix=false] - result specifies if now is earlier or later than the passed date\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * var result = formatDistanceToNow(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * var result = formatDistanceToNow(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   {includeSeconds: true}\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * var result = formatDistanceToNow(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in about 1 year'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * var eoLocale = require('date-fns/locale/eo')\n * var result = formatDistanceToNow(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> 'pli ol 1 jaro'\n */\n\nexport default function formatDistanceToNow(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  return distanceInWords(dirtyDate, Date.now(), dirtyOptions);\n}","import distanceInStrictWords from '../formatDistanceStrict/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatDistanceToNowStrict\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given dates in words, using strict units.\n * This is like `formatDistance`, but does not use helpers like 'almost', 'over',\n * 'less than' and the like.\n *\n * | Distance between dates | Result              |\n * |------------------------|---------------------|\n * | 0 ... 59 secs          | [0..59] seconds     |\n * | 1 ... 59 mins          | [1..59] minutes     |\n * | 1 ... 23 hrs           | [1..23] hours       |\n * | 1 ... 29 days          | [1..29] days        |\n * | 1 ... 11 months        | [1..11] months      |\n * | 1 ... N years          | [1..N]  years       |\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first\n * @param {'second'|'minute'|'hour'|'day'|'month'|'year'} [options.unit] - if specified, will force a unit\n * @param {'floor'|'ceil'|'round'} [options.roundingMethod='round'] - which way to round partial units\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @returns {String} the distance in words\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * var result = formatDistanceToNowStrict(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * var result = formatDistanceToNowStrict(\n *   new Date(2015, 0, 1, 0, 0, 15)\n * )\n * //=> '20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * var result = formatDistanceToNowStrict(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in 1 year'\n *\n * @example\n * // If today is 28 January 2015,\n * // what is the distance to 1 January 2015, in months, rounded up??\n * var result = formatDistanceToNowStrict(new Date(2015, 0, 1), {\n *   unit: 'month',\n *   roundingMethod: 'ceil'\n * })\n * //=> '1 month'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * var eoLocale = require('date-fns/locale/eo')\n * var result = formatDistanceToNowStrict(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> '1 jaro'\n */\n\nexport default function formatDistanceToNowStrict(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  return distanceInStrictWords(dirtyDate, Date.now(), dirtyOptions);\n}","import defaultLocale from '../locale/en-US/index.js';\nvar defaultFormat = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'];\n/**\n * @name formatDuration\n * @category Common Helpers\n * @summary Formats a duration in human-readable format\n *\n * @description\n * Return human-readable duration string i.e. \"9 months 2 days\"\n *\n * @param {Duration} duration - the duration to format\n * @param {Object} [options] - an object with options.\n\n * @param {string[]} [options.format=['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds']] - the array of units to format\n * @param {boolean} [options.zero=false] - should be zeros be included in the output?\n * @param {string} [options.delimiter=' '] - delimiter string\n * @returns {string} the formatted date string\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Format full duration\n * formatDuration({\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30\n * })\n * //=> '2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds\n *\n * @example\n * // Format partial duration\n * formatDuration({ months: 9, days: 2 })\n * //=> '9 months 2 days'\n *\n * @example\n * // Customize the format\n * formatDuration(\n *   {\n *     years: 2,\n *     months: 9,\n *     weeks: 1,\n *     days: 7,\n *     hours: 5,\n *     minutes: 9,\n *     seconds: 30\n *   },\n *   { format: ['months', 'weeks'] }\n * ) === '9 months 1 week'\n *\n * @example\n * // Customize the zeros presence\n * formatDuration({ years: 0, months: 9 })\n * //=> '9 months'\n * formatDuration({ years: 0, months: 9 }, null, { zero: true })\n * //=> '0 years 9 months'\n *\n * @example\n * // Customize the delimiter\n * formatDuration({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' })\n * //=> '2 years, 9 months, 3 weeks'\n */\n\nexport default function formatDuration(duration) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var format = options.format || defaultFormat;\n  var locale = options.locale || defaultLocale;\n  var zero = options.zero || false;\n  var delimiter = options.delimiter || ' ';\n  var result = format.reduce(function (acc, unit) {\n    var token = \"x\".concat(unit.replace(/(^.)/, function (m) {\n      return m.toUpperCase();\n    }));\n    var addChunk = typeof duration[unit] === 'number' && (zero || duration[unit]);\n    return addChunk ? acc.concat(locale.formatDistance(token, duration[unit])) : acc;\n  }, []).join(delimiter);\n  return result;\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\n/**\n * @name formatISO\n * @category Common Helpers\n * @summary Format the date according to the ISO 8601 standard (http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003169814.htm).\n *\n * @description\n * Return the formatted date string in ISO 8601 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.\n * @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time with time zone, or both.\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.format` must be 'extended' or 'basic'\n * @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18T19:00:52Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601, short format (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })\n * //=> '20190918T190052'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format, date only:\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })\n * //=> '2019-09-18'\n *\n * @example\n * // Represent 18 September 2019 in ISO 8601 format, time only (UTC):\n * const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })\n * //=> '19:00:52Z'\n */\n\nexport default function formatISO(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var format = options.format == null ? 'extended' : String(options.format);\n  var representation = options.representation == null ? 'complete' : String(options.representation);\n\n  if (format !== 'extended' && format !== 'basic') {\n    throw new RangeError(\"format must be 'extended' or 'basic'\");\n  }\n\n  if (representation !== 'date' && representation !== 'time' && representation !== 'complete') {\n    throw new RangeError(\"representation must be 'date', 'time', or 'complete'\");\n  }\n\n  var result = '';\n  var tzOffset = '';\n  var dateDelimiter = format === 'extended' ? '-' : '';\n  var timeDelimiter = format === 'extended' ? ':' : ''; // Representation is either 'date' or 'complete'\n\n  if (representation !== 'time') {\n    var day = addLeadingZeros(originalDate.getDate(), 2);\n    var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n    var year = addLeadingZeros(originalDate.getFullYear(), 4); // yyyyMMdd or yyyy-MM-dd.\n\n    result = \"\".concat(year).concat(dateDelimiter).concat(month).concat(dateDelimiter).concat(day);\n  } // Representation is either 'time' or 'complete'\n\n\n  if (representation !== 'date') {\n    // Add the timezone.\n    var offset = originalDate.getTimezoneOffset();\n\n    if (offset !== 0) {\n      var absoluteOffset = Math.abs(offset);\n      var hourOffset = addLeadingZeros(Math.floor(absoluteOffset / 60), 2);\n      var minuteOffset = addLeadingZeros(absoluteOffset % 60, 2); // If less than 0, the sign is +, because it is ahead of time.\n\n      var sign = offset < 0 ? '+' : '-';\n      tzOffset = \"\".concat(sign).concat(hourOffset, \":\").concat(minuteOffset);\n    } else {\n      tzOffset = 'Z';\n    }\n\n    var hour = addLeadingZeros(originalDate.getHours(), 2);\n    var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n    var second = addLeadingZeros(originalDate.getSeconds(), 2); // If there's also date, separate it with time with 'T'\n\n    var separator = result === '' ? '' : 'T'; // Creates a time string consisting of hour, minute, and second, separated by delimiters, if defined.\n\n    var time = [hour, minute, second].join(timeDelimiter); // HHmmss or HH:mm:ss.\n\n    result = \"\".concat(result).concat(separator).concat(time).concat(tzOffset);\n  }\n\n  return result;\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\n/**\n * @name formatISO9075\n * @category Common Helpers\n * @summary Format the date according to the ISO 9075 standard (https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_get-format).\n *\n * @description\n * Return the formatted date string in ISO 9075 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.\n * @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time, or both.\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.format` must be 'extended' or 'basic'\n * @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18 19:00:52'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075, short format:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })\n * //=> '20190918 190052'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format, date only:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })\n * //=> '2019-09-18'\n *\n * @example\n * // Represent 18 September 2019 in ISO 9075 format, time only:\n * const result = formatISO9075(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })\n * //=> '19:00:52'\n */\n\nexport default function formatISO9075(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 argument required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var format = options.format == null ? 'extended' : String(options.format);\n  var representation = options.representation == null ? 'complete' : String(options.representation);\n\n  if (format !== 'extended' && format !== 'basic') {\n    throw new RangeError(\"format must be 'extended' or 'basic'\");\n  }\n\n  if (representation !== 'date' && representation !== 'time' && representation !== 'complete') {\n    throw new RangeError(\"representation must be 'date', 'time', or 'complete'\");\n  }\n\n  var result = '';\n  var dateDelimiter = format === 'extended' ? '-' : '';\n  var timeDelimiter = format === 'extended' ? ':' : ''; // Representation is either 'date' or 'complete'\n\n  if (representation !== 'time') {\n    var day = addLeadingZeros(originalDate.getDate(), 2);\n    var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n    var year = addLeadingZeros(originalDate.getFullYear(), 4); // yyyyMMdd or yyyy-MM-dd.\n\n    result = \"\".concat(year).concat(dateDelimiter).concat(month).concat(dateDelimiter).concat(day);\n  } // Representation is either 'time' or 'complete'\n\n\n  if (representation !== 'date') {\n    var hour = addLeadingZeros(originalDate.getHours(), 2);\n    var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n    var second = addLeadingZeros(originalDate.getSeconds(), 2); // If there's also date, separate it with time with a space\n\n    var separator = result === '' ? '' : ' '; // HHmmss or HH:mm:ss.\n\n    result = \"\".concat(result).concat(separator).concat(hour).concat(timeDelimiter).concat(minute).concat(timeDelimiter).concat(second);\n  }\n\n  return result;\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatISODuration\n * @category Common Helpers\n * @summary Format a duration object according as ISO 8601 duration string\n *\n * @description\n * Format a duration object according to the ISO 8601 duration standard (https://www.digi.com/resources/documentation/digidocs/90001437-13/reference/r_iso_8601_duration_format.htm)\n *\n * @param {Duration} duration - the duration to format\n *\n * @returns {String} The ISO 8601 duration string\n * @throws {TypeError} Requires 1 argument\n * @throws {Error} Argument must be an object\n *\n * @example\n * // Format the given duration as ISO 8601 string\n * formatISODuration({\n *   years: 39,\n *   months: 2,\n *   days: 20,\n *   hours: 7,\n *   minutes: 5,\n *   seconds: 0\n * })\n * //=> 'P39Y2M20DT0H0M0S'\n */\n\nexport default function formatISODuration(duration) {\n  requiredArgs(1, arguments);\n  if (typeof duration !== 'object') throw new Error('Duration must be an object');\n  var _duration$years = duration.years,\n      years = _duration$years === void 0 ? 0 : _duration$years,\n      _duration$months = duration.months,\n      months = _duration$months === void 0 ? 0 : _duration$months,\n      _duration$days = duration.days,\n      days = _duration$days === void 0 ? 0 : _duration$days,\n      _duration$hours = duration.hours,\n      hours = _duration$hours === void 0 ? 0 : _duration$hours,\n      _duration$minutes = duration.minutes,\n      minutes = _duration$minutes === void 0 ? 0 : _duration$minutes,\n      _duration$seconds = duration.seconds,\n      seconds = _duration$seconds === void 0 ? 0 : _duration$seconds;\n  return \"P\".concat(years, \"Y\").concat(months, \"M\").concat(days, \"DT\").concat(hours, \"H\").concat(minutes, \"M\").concat(seconds, \"S\");\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name formatRFC3339\n * @category Common Helpers\n * @summary Format the date according to the ISO 3339 standard (https://tools.ietf.org/html/rfc3339#section-5.6).\n *\n * @description\n * Return the formatted date string in ISO 3339 format. Options may be passed to control the parts and notations of the date.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {0|1|2|3} [options.fractionDigits=0] - number of digits after the decimal point after seconds\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `options.fractionDigits` must be between 0 and 3\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format:\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52))\n * //=> '2019-09-18T19:00:52Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format, 2 digits of second fraction:\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52, 234), { fractionDigits: 2 })\n * //=> '2019-09-18T19:00:52.23Z'\n *\n * @example\n * // Represent 18 September 2019 in ISO 3339 format, 3 digits of second fraction\n * const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52, 234), { fractionDigits: 3 })\n * //=> '2019-09-18T19:00:52.234Z'\n */\n\nexport default function formatRFC3339(dirtyDate, dirtyOptions) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 arguments required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var options = dirtyOptions || {};\n  var fractionDigits = options.fractionDigits == null ? 0 : toInteger(options.fractionDigits); // Test if fractionDigits is between 0 and 3 _and_ is not NaN\n\n  if (!(fractionDigits >= 0 && fractionDigits <= 3)) {\n    throw new RangeError('fractionDigits must be between 0 and 3 inclusively');\n  }\n\n  var day = addLeadingZeros(originalDate.getDate(), 2);\n  var month = addLeadingZeros(originalDate.getMonth() + 1, 2);\n  var year = originalDate.getFullYear();\n  var hour = addLeadingZeros(originalDate.getHours(), 2);\n  var minute = addLeadingZeros(originalDate.getMinutes(), 2);\n  var second = addLeadingZeros(originalDate.getSeconds(), 2);\n  var fractionalSecond = '';\n\n  if (fractionDigits > 0) {\n    var milliseconds = originalDate.getMilliseconds();\n    var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, fractionDigits - 3));\n    fractionalSecond = '.' + addLeadingZeros(fractionalSeconds, fractionDigits);\n  }\n\n  var offset = '';\n  var tzOffset = originalDate.getTimezoneOffset();\n\n  if (tzOffset !== 0) {\n    var absoluteOffset = Math.abs(tzOffset);\n    var hourOffset = addLeadingZeros(absoluteOffset / 60, 2);\n    var minuteOffset = addLeadingZeros(absoluteOffset % 60, 2); // If less than 0, the sign is +, because it is ahead of time.\n\n    var sign = tzOffset < 0 ? '+' : '-';\n    offset = \"\".concat(sign).concat(hourOffset, \":\").concat(minuteOffset);\n  } else {\n    offset = 'Z';\n  }\n\n  return \"\".concat(year, \"-\").concat(month, \"-\").concat(day, \"T\").concat(hour, \":\").concat(minute, \":\").concat(second).concat(fractionalSecond).concat(offset);\n}","import toDate from '../toDate/index.js';\nimport isValid from '../isValid/index.js';\nimport addLeadingZeros from '../_lib/addLeadingZeros/index.js';\nvar days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n/**\n * @name formatRFC7231\n * @category Common Helpers\n * @summary Format the date according to the RFC 7231 standard (https://tools.ietf.org/html/rfc7231#section-7.1.1.1).\n *\n * @description\n * Return the formatted date string in RFC 7231 format.\n * The result will always be in UTC timezone.\n *\n * @param {Date|Number} date - the original date\n * @returns {String} the formatted date string\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `date` must not be Invalid Date\n *\n * @example\n * // Represent 18 September 2019 in RFC 7231 format:\n * const result = formatRFC7231(new Date(2019, 8, 18, 19, 0, 52))\n * //=> 'Wed, 18 Sep 2019 19:00:52 GMT'\n */\n\nexport default function formatRFC7231(dirtyDate) {\n  if (arguments.length < 1) {\n    throw new TypeError(\"1 arguments required, but only \".concat(arguments.length, \" present\"));\n  }\n\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var dayName = days[originalDate.getUTCDay()];\n  var dayOfMonth = addLeadingZeros(originalDate.getUTCDate(), 2);\n  var monthName = months[originalDate.getUTCMonth()];\n  var year = originalDate.getUTCFullYear();\n  var hour = addLeadingZeros(originalDate.getUTCHours(), 2);\n  var minute = addLeadingZeros(originalDate.getUTCMinutes(), 2);\n  var second = addLeadingZeros(originalDate.getUTCSeconds(), 2); // Result variables.\n\n  return \"\".concat(dayName, \", \").concat(dayOfMonth, \" \").concat(monthName, \" \").concat(year, \" \").concat(hour, \":\").concat(minute, \":\").concat(second, \" GMT\");\n}","import differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport format from '../format/index.js';\nimport defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name formatRelative\n * @category Common Helpers\n * @summary Represent the date in words relative to the given base date.\n *\n * @description\n * Represent the date in words relative to the given base date.\n *\n * | Distance to the base date | Result                    |\n * |---------------------------|---------------------------|\n * | Previous 6 days           | last Sunday at 04:30 AM   |\n * | Last day                  | yesterday at 04:30 AM     |\n * | Same day                  | today at 04:30 AM         |\n * | Next day                  | tomorrow at 04:30 AM      |\n * | Next 6 days               | Sunday at 04:30 AM        |\n * | Other                     | 12/31/2017                |\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to format\n * @param {Date|Number} baseDate - the date to compare with\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {String} the date in words\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `date` must not be Invalid Date\n * @throws {RangeError} `baseDate` must not be Invalid Date\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.locale` must contain `localize` property\n * @throws {RangeError} `options.locale` must contain `formatLong` property\n * @throws {RangeError} `options.locale` must contain `formatRelative` property\n */\n\nexport default function formatRelative(dirtyDate, dirtyBaseDate, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var baseDate = toDate(dirtyBaseDate);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.localize) {\n    throw new RangeError('locale must contain localize property');\n  }\n\n  if (!locale.formatLong) {\n    throw new RangeError('locale must contain formatLong property');\n  }\n\n  if (!locale.formatRelative) {\n    throw new RangeError('locale must contain formatRelative property');\n  }\n\n  var diff = differenceInCalendarDays(date, baseDate);\n\n  if (isNaN(diff)) {\n    throw new RangeError('Invalid time value');\n  }\n\n  var token;\n\n  if (diff < -6) {\n    token = 'other';\n  } else if (diff < -1) {\n    token = 'lastWeek';\n  } else if (diff < 0) {\n    token = 'yesterday';\n  } else if (diff < 1) {\n    token = 'today';\n  } else if (diff < 2) {\n    token = 'tomorrow';\n  } else if (diff < 7) {\n    token = 'nextWeek';\n  } else {\n    token = 'other';\n  }\n\n  var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));\n  var utcBaseDate = subMilliseconds(baseDate, getTimezoneOffsetInMilliseconds(baseDate));\n  var formatStr = locale.formatRelative(token, utcDate, utcBaseDate, options);\n  return format(date, formatStr, options);\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name fromUnixTime\n * @category Timestamp Helpers\n * @summary Create a date from a Unix timestamp.\n *\n * @description\n * Create a date from a Unix timestamp.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Number} unixTime - the given Unix timestamp\n * @returns {Date} the date\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Create the date 29 February 2012 11:45:05:\n * var result = fromUnixTime(1330515905)\n * //=> Wed Feb 29 2012 11:45:05\n */\n\nexport default function fromUnixTime(dirtyUnixTime) {\n  requiredArgs(1, arguments);\n  var unixTime = toInteger(dirtyUnixTime);\n  return toDate(unixTime * 1000);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDate\n * @category Day Helpers\n * @summary Get the day of the month of the given date.\n *\n * @description\n * Get the day of the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the month is 29 February 2012?\n * var result = getDate(new Date(2012, 1, 29))\n * //=> 29\n */\n\nexport default function getDate(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfMonth = date.getDate();\n  return dayOfMonth;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDay\n * @category Weekday Helpers\n * @summary Get the day of the week of the given date.\n *\n * @description\n * Get the day of the week of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {0|1|2|3|4|5|6} the day of week, 0 represents Sunday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the week is 29 February 2012?\n * var result = getDay(new Date(2012, 1, 29))\n * //=> 3\n */\n\nexport default function getDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  return day;\n}","import toDate from '../toDate/index.js';\nimport startOfYear from '../startOfYear/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDayOfYear\n * @category Day Helpers\n * @summary Get the day of the year of the given date.\n *\n * @description\n * Get the day of the year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the year is 2 July 2014?\n * var result = getDayOfYear(new Date(2014, 6, 2))\n * //=> 183\n */\n\nexport default function getDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = differenceInCalendarDays(date, startOfYear(date));\n  var dayOfYear = diff + 1;\n  return dayOfYear;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of days in a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many days are in February 2000?\n * var result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\n\nexport default function getDaysInMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var monthIndex = date.getMonth();\n  var lastDayOfMonth = new Date(0);\n  lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n  lastDayOfMonth.setHours(0, 0, 0, 0);\n  return lastDayOfMonth.getDate();\n}","import toDate from '../toDate/index.js';\nimport isLeapYear from '../isLeapYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDaysInYear\n * @category Year Helpers\n * @summary Get the number of days in a year of the given date.\n *\n * @description\n * Get the number of days in a year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of days in a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many days are in 2012?\n * var result = getDaysInYear(new Date(2012, 0, 1))\n * //=> 366\n */\n\nexport default function getDaysInYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n\n  if (isNaN(date)) {\n    return NaN;\n  }\n\n  return isLeapYear(date) ? 366 : 365;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getDecade\n * @category Decade Helpers\n * @summary Get the decade of the given date.\n *\n * @description\n * Get the decade of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the year of decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which decade belongs 27 November 1942?\n * var result = getDecade(new Date(1942, 10, 27))\n * //=> 1940\n */\n\nexport default function getDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = Math.floor(year / 10) * 10;\n  return decade;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getHours\n * @category Hour Helpers\n * @summary Get the hours of the given date.\n *\n * @description\n * Get the hours of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the hours\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the hours of 29 February 2012 11:45:00:\n * var result = getHours(new Date(2012, 1, 29, 11, 45))\n * //=> 11\n */\n\nexport default function getHours(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var hours = date.getHours();\n  return hours;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getISODay\n * @category Weekday Helpers\n * @summary Get the day of the ISO week of the given date.\n *\n * @description\n * Get the day of the ISO week of the given date,\n * which is 7 for Sunday, 1 for Monday etc.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the day of ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which day of the ISO week is 26 February 2012?\n * var result = getISODay(new Date(2012, 1, 26))\n * //=> 7\n */\n\nexport default function getISODay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n\n  if (day === 0) {\n    day = 7;\n  }\n\n  return day;\n}","import toDate from '../toDate/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getISOWeek\n * @category ISO Week Helpers\n * @summary Get the ISO week of the given date.\n *\n * @description\n * Get the ISO week of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which week of the ISO-week numbering year is 2 January 2005?\n * var result = getISOWeek(new Date(2005, 0, 2))\n * //=> 53\n */\n\nexport default function getISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfISOWeek(date).getTime() - startOfISOWeekYear(date).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toDate from '../toDate/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the ISO week-numbering year of the given date.\n *\n * @description\n * Get the ISO week-numbering year of the given date,\n * which always starts 3 days before the year's first Thursday.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `getISOYear` to `getISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which ISO-week numbering year is 2 January 2005?\n * var result = getISOWeekYear(new Date(2005, 0, 2))\n * //=> 2004\n */\n\nexport default function getISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var fourthOfJanuaryOfNextYear = new Date(0);\n  fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n  fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n  var startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear);\n  var fourthOfJanuaryOfThisYear = new Date(0);\n  fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);\n  fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);\n  var startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport addWeeks from '../addWeeks/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getISOWeeksInYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the number of weeks in an ISO week-numbering year of the given date.\n *\n * @description\n * Get the number of weeks in an ISO week-numbering year of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of ISO weeks in a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many weeks are in ISO week-numbering year 2015?\n * var result = getISOWeeksInYear(new Date(2015, 1, 11))\n * //=> 53\n */\n\nexport default function getISOWeeksInYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var thisYear = startOfISOWeekYear(dirtyDate);\n  var nextYear = startOfISOWeekYear(addWeeks(thisYear, 60));\n  var diff = nextYear.valueOf() - thisYear.valueOf(); // Round the number of weeks to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMilliseconds\n * @category Millisecond Helpers\n * @summary Get the milliseconds of the given date.\n *\n * @description\n * Get the milliseconds of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the milliseconds\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the milliseconds of 29 February 2012 11:45:05.123:\n * var result = getMilliseconds(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 123\n */\n\nexport default function getMilliseconds(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var milliseconds = date.getMilliseconds();\n  return milliseconds;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMinutes\n * @category Minute Helpers\n * @summary Get the minutes of the given date.\n *\n * @description\n * Get the minutes of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the minutes\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the minutes of 29 February 2012 11:45:05:\n * var result = getMinutes(new Date(2012, 1, 29, 11, 45, 5))\n * //=> 45\n */\n\nexport default function getMinutes(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var minutes = date.getMinutes();\n  return minutes;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getMonth\n * @category Month Helpers\n * @summary Get the month of the given date.\n *\n * @description\n * Get the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which month is 29 February 2012?\n * var result = getMonth(new Date(2012, 1, 29))\n * //=> 1\n */\n\nexport default function getMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  return month;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;\n/**\n * @name getOverlappingDaysInIntervals\n * @category Interval Helpers\n * @summary Get the number of days that overlap in two time intervals\n *\n * @description\n * Get the number of days that overlap in two time intervals\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `getOverlappingDaysInRanges` to `getOverlappingDaysInIntervals`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   getOverlappingDaysInRanges(\n *     new Date(2014, 0, 10), new Date(2014, 0, 20),\n *     new Date(2014, 0, 17), new Date(2014, 0, 21)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   getOverlappingDaysInIntervals(\n *     { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *     { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n *   )\n *   ```\n *\n * @param {Interval} intervalLeft - the first interval to compare. See [Interval]{@link docs/Interval}\n * @param {Interval} intervalRight - the second interval to compare. See [Interval]{@link docs/Interval}\n * @returns {Number} the number of days that overlap in two time intervals\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For overlapping time intervals adds 1 for each started overlapping day:\n * getOverlappingDaysInIntervals(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }\n * )\n * //=> 3\n *\n * @example\n * // For non-overlapping time intervals returns 0:\n * getOverlappingDaysInIntervals(\n *   { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },\n *   { start: new Date(2014, 0, 21), end: new Date(2014, 0, 22) }\n * )\n * //=> 0\n */\n\nexport default function getOverlappingDaysInIntervals(dirtyIntervalLeft, dirtyIntervalRight) {\n  requiredArgs(2, arguments);\n  var intervalLeft = dirtyIntervalLeft || {};\n  var intervalRight = dirtyIntervalRight || {};\n  var leftStartTime = toDate(intervalLeft.start).getTime();\n  var leftEndTime = toDate(intervalLeft.end).getTime();\n  var rightStartTime = toDate(intervalRight.start).getTime();\n  var rightEndTime = toDate(intervalRight.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  var isOverlapping = leftStartTime < rightEndTime && rightStartTime < leftEndTime;\n\n  if (!isOverlapping) {\n    return 0;\n  }\n\n  var overlapStartDate = rightStartTime < leftStartTime ? leftStartTime : rightStartTime;\n  var overlapEndDate = rightEndTime > leftEndTime ? leftEndTime : rightEndTime;\n  var differenceInMs = overlapEndDate - overlapStartDate;\n  return Math.ceil(differenceInMs / MILLISECONDS_IN_DAY);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getQuarter\n * @category Quarter Helpers\n * @summary Get the year quarter of the given date.\n *\n * @description\n * Get the year quarter of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which quarter is 2 July 2014?\n * var result = getQuarter(new Date(2014, 6, 2))\n * //=> 3\n */\n\nexport default function getQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var quarter = Math.floor(date.getMonth() / 3) + 1;\n  return quarter;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getSeconds\n * @category Second Helpers\n * @summary Get the seconds of the given date.\n *\n * @description\n * Get the seconds of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the seconds\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the seconds of 29 February 2012 11:45:05.123:\n * var result = getSeconds(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 5\n */\n\nexport default function getSeconds(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var seconds = date.getSeconds();\n  return seconds;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getTime\n * @category Timestamp Helpers\n * @summary Get the milliseconds timestamp of the given date.\n *\n * @description\n * Get the milliseconds timestamp of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the timestamp\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the timestamp of 29 February 2012 11:45:05.123:\n * var result = getTime(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 1330515905123\n */\n\nexport default function getTime(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var timestamp = date.getTime();\n  return timestamp;\n}","import getTime from '../getTime/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getUnixTime\n * @category Timestamp Helpers\n * @summary Get the seconds timestamp of the given date.\n *\n * @description\n * Get the seconds timestamp of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the timestamp\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the timestamp of 29 February 2012 11:45:05 CET:\n * var result = getUnixTime(new Date(2012, 1, 29, 11, 45, 5))\n * //=> 1330512305\n */\n\nexport default function getUnixTime(dirtyDate) {\n  requiredArgs(1, arguments);\n  return Math.floor(getTime(dirtyDate) / 1000);\n}","import startOfWeek from '../startOfWeek/index.js';\nimport startOfWeekYear from '../startOfWeekYear/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getWeek\n * @category Week Helpers\n * @summary Get the local week index of the given date.\n *\n * @description\n * Get the local week index of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week of the local week numbering year is 2 January 2005 with default options?\n * var result = getISOWeek(new Date(2005, 0, 2))\n * //=> 2\n *\n * // Which week of the local week numbering year is 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January?\n * var result = getISOWeek(new Date(2005, 0, 2), {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> 53\n */\n\nexport default function getWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var diff = startOfWeek(date, options).getTime() - startOfWeekYear(date, options).getTime(); // Round the number of days to the nearest integer\n  // because the number of milliseconds in a week is not constant\n  // (e.g. it's different in the week of the daylight saving time clock shift)\n\n  return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import getDate from '../getDate/index.js';\nimport getDay from '../getDay/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeekOfMonth\n * @category Week Helpers\n * @summary Get the week of the month of the given date.\n *\n * @description\n * Get the week of the month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the week of month\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Which week of the month is 9 November 2017?\n * var result = getWeekOfMonth(new Date(2017, 10, 9))\n * //=> 2\n */\n\nexport default function getWeekOfMonth(date, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var currentDayOfMonth = getDate(date);\n\n  if (isNaN(currentDayOfMonth)) {\n    return currentDayOfMonth;\n  }\n\n  var startWeekDay = getDay(startOfMonth(date));\n  var lastDayOfFirstWeek = 0;\n\n  if (startWeekDay >= weekStartsOn) {\n    lastDayOfFirstWeek = weekStartsOn + 7 - startWeekDay;\n  } else {\n    lastDayOfFirstWeek = weekStartsOn - startWeekDay;\n  }\n\n  var weekNumber = 1;\n\n  if (currentDayOfMonth > lastDayOfFirstWeek) {\n    var remainingDaysAfterFirstWeek = currentDayOfMonth - lastDayOfFirstWeek;\n    weekNumber = weekNumber + Math.ceil(remainingDaysAfterFirstWeek / 7);\n  }\n\n  return weekNumber;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Get the local week-numbering year of the given date.\n *\n * @description\n * Get the local week-numbering year of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the local week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week numbering year is 26 December 2004 with the default settings?\n * var result = getWeekYear(new Date(2004, 11, 26))\n * //=> 2005\n *\n * @example\n * // Which week numbering year is 26 December 2004 if week starts on Saturday?\n * var result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })\n * //=> 2004\n *\n * @example\n * // Which week numbering year is 26 December 2004 if the first week contains 4 January?\n * var result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })\n * //=> 2004\n */\n\nexport default function getWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var firstWeekOfNextYear = new Date(0);\n  firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);\n  firstWeekOfNextYear.setHours(0, 0, 0, 0);\n  var startOfNextYear = startOfWeek(firstWeekOfNextYear, dirtyOptions);\n  var firstWeekOfThisYear = new Date(0);\n  firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);\n  firstWeekOfThisYear.setHours(0, 0, 0, 0);\n  var startOfThisYear = startOfWeek(firstWeekOfThisYear, dirtyOptions);\n\n  if (date.getTime() >= startOfNextYear.getTime()) {\n    return year + 1;\n  } else if (date.getTime() >= startOfThisYear.getTime()) {\n    return year;\n  } else {\n    return year - 1;\n  }\n}","import differenceInCalendarWeeks from '../differenceInCalendarWeeks/index.js';\nimport lastDayOfMonth from '../lastDayOfMonth/index.js';\nimport startOfMonth from '../startOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getWeeksInMonth\n * @category Week Helpers\n * @summary Get the number of calendar weeks a month spans.\n *\n * @description\n * Get the number of calendar weeks the month in the given date spans.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks does February 2015 span?\n * var result = getWeeksInMonth(new Date(2015, 1, 8))\n * //=> 4\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks does July 2017 span?\n * var result = getWeeksInMonth(new Date(2017, 6, 5), { weekStartsOn: 1 })\n * //=> 6\n */\n\nexport default function getWeeksInMonth(date, options) {\n  requiredArgs(1, arguments);\n  return differenceInCalendarWeeks(lastDayOfMonth(date), startOfMonth(date), options) + 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name getYear\n * @category Year Helpers\n * @summary Get the year of the given date.\n *\n * @description\n * Get the year of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which year is 2 July 2014?\n * var result = getYear(new Date(2014, 6, 2))\n * //=> 2014\n */\n\nexport default function getYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  return year;\n}","// This file is generated automatically by `scripts/build/indices.js`. Please, don't change it.\nexport { default as add } from './add/index.js';\nexport { default as addBusinessDays } from './addBusinessDays/index.js';\nexport { default as addDays } from './addDays/index.js';\nexport { default as addHours } from './addHours/index.js';\nexport { default as addISOWeekYears } from './addISOWeekYears/index.js';\nexport { default as addMilliseconds } from './addMilliseconds/index.js';\nexport { default as addMinutes } from './addMinutes/index.js';\nexport { default as addMonths } from './addMonths/index.js';\nexport { default as addQuarters } from './addQuarters/index.js';\nexport { default as addSeconds } from './addSeconds/index.js';\nexport { default as addWeeks } from './addWeeks/index.js';\nexport { default as addYears } from './addYears/index.js';\nexport { default as areIntervalsOverlapping } from './areIntervalsOverlapping/index.js';\nexport { default as closestIndexTo } from './closestIndexTo/index.js';\nexport { default as closestTo } from './closestTo/index.js';\nexport { default as compareAsc } from './compareAsc/index.js';\nexport { default as compareDesc } from './compareDesc/index.js';\nexport { default as differenceInBusinessDays } from './differenceInBusinessDays/index.js';\nexport { default as differenceInCalendarDays } from './differenceInCalendarDays/index.js';\nexport { default as differenceInCalendarISOWeekYears } from './differenceInCalendarISOWeekYears/index.js';\nexport { default as differenceInCalendarISOWeeks } from './differenceInCalendarISOWeeks/index.js';\nexport { default as differenceInCalendarMonths } from './differenceInCalendarMonths/index.js';\nexport { default as differenceInCalendarQuarters } from './differenceInCalendarQuarters/index.js';\nexport { default as differenceInCalendarWeeks } from './differenceInCalendarWeeks/index.js';\nexport { default as differenceInCalendarYears } from './differenceInCalendarYears/index.js';\nexport { default as differenceInDays } from './differenceInDays/index.js';\nexport { default as differenceInHours } from './differenceInHours/index.js';\nexport { default as differenceInISOWeekYears } from './differenceInISOWeekYears/index.js';\nexport { default as differenceInMilliseconds } from './differenceInMilliseconds/index.js';\nexport { default as differenceInMinutes } from './differenceInMinutes/index.js';\nexport { default as differenceInMonths } from './differenceInMonths/index.js';\nexport { default as differenceInQuarters } from './differenceInQuarters/index.js';\nexport { default as differenceInSeconds } from './differenceInSeconds/index.js';\nexport { default as differenceInWeeks } from './differenceInWeeks/index.js';\nexport { default as differenceInYears } from './differenceInYears/index.js';\nexport { default as eachDayOfInterval } from './eachDayOfInterval/index.js';\nexport { default as eachHourOfInterval } from './eachHourOfInterval/index.js';\nexport { default as eachMonthOfInterval } from './eachMonthOfInterval/index.js';\nexport { default as eachQuarterOfInterval } from './eachQuarterOfInterval/index.js';\nexport { default as eachWeekOfInterval } from './eachWeekOfInterval/index.js';\nexport { default as eachWeekendOfInterval } from './eachWeekendOfInterval/index.js';\nexport { default as eachWeekendOfMonth } from './eachWeekendOfMonth/index.js';\nexport { default as eachWeekendOfYear } from './eachWeekendOfYear/index.js';\nexport { default as eachYearOfInterval } from './eachYearOfInterval/index.js';\nexport { default as endOfDay } from './endOfDay/index.js';\nexport { default as endOfDecade } from './endOfDecade/index.js';\nexport { default as endOfHour } from './endOfHour/index.js';\nexport { default as endOfISOWeek } from './endOfISOWeek/index.js';\nexport { default as endOfISOWeekYear } from './endOfISOWeekYear/index.js';\nexport { default as endOfMinute } from './endOfMinute/index.js';\nexport { default as endOfMonth } from './endOfMonth/index.js';\nexport { default as endOfQuarter } from './endOfQuarter/index.js';\nexport { default as endOfSecond } from './endOfSecond/index.js';\nexport { default as endOfToday } from './endOfToday/index.js';\nexport { default as endOfTomorrow } from './endOfTomorrow/index.js';\nexport { default as endOfWeek } from './endOfWeek/index.js';\nexport { default as endOfYear } from './endOfYear/index.js';\nexport { default as endOfYesterday } from './endOfYesterday/index.js';\nexport { default as format } from './format/index.js';\nexport { default as formatDistance } from './formatDistance/index.js';\nexport { default as formatDistanceStrict } from './formatDistanceStrict/index.js';\nexport { default as formatDistanceToNow } from './formatDistanceToNow/index.js';\nexport { default as formatDistanceToNowStrict } from './formatDistanceToNowStrict/index.js';\nexport { default as formatDuration } from './formatDuration/index.js';\nexport { default as formatISO } from './formatISO/index.js';\nexport { default as formatISO9075 } from './formatISO9075/index.js';\nexport { default as formatISODuration } from './formatISODuration/index.js';\nexport { default as formatRFC3339 } from './formatRFC3339/index.js';\nexport { default as formatRFC7231 } from './formatRFC7231/index.js';\nexport { default as formatRelative } from './formatRelative/index.js';\nexport { default as fromUnixTime } from './fromUnixTime/index.js';\nexport { default as getDate } from './getDate/index.js';\nexport { default as getDay } from './getDay/index.js';\nexport { default as getDayOfYear } from './getDayOfYear/index.js';\nexport { default as getDaysInMonth } from './getDaysInMonth/index.js';\nexport { default as getDaysInYear } from './getDaysInYear/index.js';\nexport { default as getDecade } from './getDecade/index.js';\nexport { default as getHours } from './getHours/index.js';\nexport { default as getISODay } from './getISODay/index.js';\nexport { default as getISOWeek } from './getISOWeek/index.js';\nexport { default as getISOWeekYear } from './getISOWeekYear/index.js';\nexport { default as getISOWeeksInYear } from './getISOWeeksInYear/index.js';\nexport { default as getMilliseconds } from './getMilliseconds/index.js';\nexport { default as getMinutes } from './getMinutes/index.js';\nexport { default as getMonth } from './getMonth/index.js';\nexport { default as getOverlappingDaysInIntervals } from './getOverlappingDaysInIntervals/index.js';\nexport { default as getQuarter } from './getQuarter/index.js';\nexport { default as getSeconds } from './getSeconds/index.js';\nexport { default as getTime } from './getTime/index.js';\nexport { default as getUnixTime } from './getUnixTime/index.js';\nexport { default as getWeek } from './getWeek/index.js';\nexport { default as getWeekOfMonth } from './getWeekOfMonth/index.js';\nexport { default as getWeekYear } from './getWeekYear/index.js';\nexport { default as getWeeksInMonth } from './getWeeksInMonth/index.js';\nexport { default as getYear } from './getYear/index.js';\nexport { default as intervalToDuration } from './intervalToDuration/index.js';\nexport { default as isAfter } from './isAfter/index.js';\nexport { default as isBefore } from './isBefore/index.js';\nexport { default as isDate } from './isDate/index.js';\nexport { default as isEqual } from './isEqual/index.js';\nexport { default as isExists } from './isExists/index.js';\nexport { default as isFirstDayOfMonth } from './isFirstDayOfMonth/index.js';\nexport { default as isFriday } from './isFriday/index.js';\nexport { default as isFuture } from './isFuture/index.js';\nexport { default as isLastDayOfMonth } from './isLastDayOfMonth/index.js';\nexport { default as isLeapYear } from './isLeapYear/index.js';\nexport { default as isMatch } from './isMatch/index.js';\nexport { default as isMonday } from './isMonday/index.js';\nexport { default as isPast } from './isPast/index.js';\nexport { default as isSameDay } from './isSameDay/index.js';\nexport { default as isSameHour } from './isSameHour/index.js';\nexport { default as isSameISOWeek } from './isSameISOWeek/index.js';\nexport { default as isSameISOWeekYear } from './isSameISOWeekYear/index.js';\nexport { default as isSameMinute } from './isSameMinute/index.js';\nexport { default as isSameMonth } from './isSameMonth/index.js';\nexport { default as isSameQuarter } from './isSameQuarter/index.js';\nexport { default as isSameSecond } from './isSameSecond/index.js';\nexport { default as isSameWeek } from './isSameWeek/index.js';\nexport { default as isSameYear } from './isSameYear/index.js';\nexport { default as isSaturday } from './isSaturday/index.js';\nexport { default as isSunday } from './isSunday/index.js';\nexport { default as isThisHour } from './isThisHour/index.js';\nexport { default as isThisISOWeek } from './isThisISOWeek/index.js';\nexport { default as isThisMinute } from './isThisMinute/index.js';\nexport { default as isThisMonth } from './isThisMonth/index.js';\nexport { default as isThisQuarter } from './isThisQuarter/index.js';\nexport { default as isThisSecond } from './isThisSecond/index.js';\nexport { default as isThisWeek } from './isThisWeek/index.js';\nexport { default as isThisYear } from './isThisYear/index.js';\nexport { default as isThursday } from './isThursday/index.js';\nexport { default as isToday } from './isToday/index.js';\nexport { default as isTomorrow } from './isTomorrow/index.js';\nexport { default as isTuesday } from './isTuesday/index.js';\nexport { default as isValid } from './isValid/index.js';\nexport { default as isWednesday } from './isWednesday/index.js';\nexport { default as isWeekend } from './isWeekend/index.js';\nexport { default as isWithinInterval } from './isWithinInterval/index.js';\nexport { default as isYesterday } from './isYesterday/index.js';\nexport { default as lastDayOfDecade } from './lastDayOfDecade/index.js';\nexport { default as lastDayOfISOWeek } from './lastDayOfISOWeek/index.js';\nexport { default as lastDayOfISOWeekYear } from './lastDayOfISOWeekYear/index.js';\nexport { default as lastDayOfMonth } from './lastDayOfMonth/index.js';\nexport { default as lastDayOfQuarter } from './lastDayOfQuarter/index.js';\nexport { default as lastDayOfWeek } from './lastDayOfWeek/index.js';\nexport { default as lastDayOfYear } from './lastDayOfYear/index.js';\nexport { default as lightFormat } from './lightFormat/index.js';\nexport { default as max } from './max/index.js';\nexport { default as min } from './min/index.js';\nexport { default as parse } from './parse/index.js';\nexport { default as parseISO } from './parseISO/index.js';\nexport { default as parseJSON } from './parseJSON/index.js';\nexport { default as roundToNearestMinutes } from './roundToNearestMinutes/index.js';\nexport { default as set } from './set/index.js';\nexport { default as setDate } from './setDate/index.js';\nexport { default as setDay } from './setDay/index.js';\nexport { default as setDayOfYear } from './setDayOfYear/index.js';\nexport { default as setHours } from './setHours/index.js';\nexport { default as setISODay } from './setISODay/index.js';\nexport { default as setISOWeek } from './setISOWeek/index.js';\nexport { default as setISOWeekYear } from './setISOWeekYear/index.js';\nexport { default as setMilliseconds } from './setMilliseconds/index.js';\nexport { default as setMinutes } from './setMinutes/index.js';\nexport { default as setMonth } from './setMonth/index.js';\nexport { default as setQuarter } from './setQuarter/index.js';\nexport { default as setSeconds } from './setSeconds/index.js';\nexport { default as setWeek } from './setWeek/index.js';\nexport { default as setWeekYear } from './setWeekYear/index.js';\nexport { default as setYear } from './setYear/index.js';\nexport { default as startOfDay } from './startOfDay/index.js';\nexport { default as startOfDecade } from './startOfDecade/index.js';\nexport { default as startOfHour } from './startOfHour/index.js';\nexport { default as startOfISOWeek } from './startOfISOWeek/index.js';\nexport { default as startOfISOWeekYear } from './startOfISOWeekYear/index.js';\nexport { default as startOfMinute } from './startOfMinute/index.js';\nexport { default as startOfMonth } from './startOfMonth/index.js';\nexport { default as startOfQuarter } from './startOfQuarter/index.js';\nexport { default as startOfSecond } from './startOfSecond/index.js';\nexport { default as startOfToday } from './startOfToday/index.js';\nexport { default as startOfTomorrow } from './startOfTomorrow/index.js';\nexport { default as startOfWeek } from './startOfWeek/index.js';\nexport { default as startOfWeekYear } from './startOfWeekYear/index.js';\nexport { default as startOfYear } from './startOfYear/index.js';\nexport { default as startOfYesterday } from './startOfYesterday/index.js';\nexport { default as sub } from './sub/index.js';\nexport { default as subBusinessDays } from './subBusinessDays/index.js';\nexport { default as subDays } from './subDays/index.js';\nexport { default as subHours } from './subHours/index.js';\nexport { default as subISOWeekYears } from './subISOWeekYears/index.js';\nexport { default as subMilliseconds } from './subMilliseconds/index.js';\nexport { default as subMinutes } from './subMinutes/index.js';\nexport { default as subMonths } from './subMonths/index.js';\nexport { default as subQuarters } from './subQuarters/index.js';\nexport { default as subSeconds } from './subSeconds/index.js';\nexport { default as subWeeks } from './subWeeks/index.js';\nexport { default as subYears } from './subYears/index.js';\nexport { default as toDate } from './toDate/index.js';\nexport * from './constants/index.js';","import compareAsc from '../compareAsc/index.js';\nimport differenceInYears from '../differenceInYears/index.js';\nimport differenceInMonths from '../differenceInMonths/index.js';\nimport differenceInDays from '../differenceInDays/index.js';\nimport differenceInHours from '../differenceInHours/index.js';\nimport differenceInMinutes from '../differenceInMinutes/index.js';\nimport differenceInSeconds from '../differenceInSeconds/index.js';\nimport isValid from '../isValid/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toDate from '../toDate/index.js';\nimport sub from '../sub/index.js';\n/**\n * @name intervalToDuration\n * @category Common Helpers\n * @summary Convert interval to duration\n *\n * @description\n * Convert a interval object to a duration object.\n *\n * @param {Interval} interval - the interval to convert to duration\n *\n * @returns {Duration} The duration Object\n * @throws {TypeError} Requires 2 arguments\n * @throws {RangeError} `start` must not be Invalid Date\n * @throws {RangeError} `end` must not be Invalid Date\n *\n * @example\n * // Get the duration between January 15, 1929 and April 4, 1968.\n * intervalToDuration({\n *   start: new Date(1929, 0, 15, 12, 0, 0),\n *   end: new Date(1968, 3, 4, 19, 5, 0)\n * })\n * // => { years: 39, months: 2, days: 20, hours: 7, minutes: 5, seconds: 0 }\n */\n\nexport default function intervalToDuration(_ref) {\n  var start = _ref.start,\n      end = _ref.end;\n  requiredArgs(1, arguments);\n  var dateLeft = toDate(start);\n  var dateRight = toDate(end);\n\n  if (!isValid(dateLeft)) {\n    throw new RangeError('Start Date is invalid');\n  }\n\n  if (!isValid(dateRight)) {\n    throw new RangeError('End Date is invalid');\n  }\n\n  var duration = {\n    years: 0,\n    months: 0,\n    days: 0,\n    hours: 0,\n    minutes: 0,\n    seconds: 0\n  };\n  var sign = compareAsc(dateLeft, dateRight);\n  duration.years = Math.abs(differenceInYears(dateLeft, dateRight));\n  var remainingMonths = sub(dateLeft, {\n    years: sign * duration.years\n  });\n  duration.months = Math.abs(differenceInMonths(remainingMonths, dateRight));\n  var remainingDays = sub(remainingMonths, {\n    months: sign * duration.months\n  });\n  duration.days = Math.abs(differenceInDays(remainingDays, dateRight));\n  var remainingHours = sub(remainingDays, {\n    days: sign * duration.days\n  });\n  duration.hours = Math.abs(differenceInHours(remainingHours, dateRight));\n  var remainingMinutes = sub(remainingHours, {\n    hours: sign * duration.hours\n  });\n  duration.minutes = Math.abs(differenceInMinutes(remainingMinutes, dateRight));\n  var remainingSeconds = sub(remainingMinutes, {\n    minutes: sign * duration.minutes\n  });\n  duration.seconds = Math.abs(differenceInSeconds(remainingSeconds, dateRight));\n  return duration;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isAfter\n * @category Common Helpers\n * @summary Is the first date after the second one?\n *\n * @description\n * Is the first date after the second one?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date that should be after the other one to return true\n * @param {Date|Number} dateToCompare - the date to compare with\n * @returns {Boolean} the first date is after the second date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Is 10 July 1989 after 11 February 1987?\n * var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11))\n * //=> true\n */\n\nexport default function isAfter(dirtyDate, dirtyDateToCompare) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dateToCompare = toDate(dirtyDateToCompare);\n  return date.getTime() > dateToCompare.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isBefore\n * @category Common Helpers\n * @summary Is the first date before the second one?\n *\n * @description\n * Is the first date before the second one?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date that should be before the other one to return true\n * @param {Date|Number} dateToCompare - the date to compare with\n * @returns {Boolean} the first date is before the second date\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Is 10 July 1989 before 11 February 1987?\n * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))\n * //=> false\n */\n\nexport default function isBefore(dirtyDate, dirtyDateToCompare) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dateToCompare = toDate(dirtyDateToCompare);\n  return date.getTime() < dateToCompare.getTime();\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {*} value - the value to check\n * @returns {boolean} true if the given value is a date\n * @throws {TypeError} 1 arguments required\n *\n * @example\n * // For a valid date:\n * var result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * var result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * var result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * var result = isDate({})\n * //=> false\n */\n\nexport default function isDate(value) {\n  requiredArgs(1, arguments);\n  return value instanceof Date || typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]';\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isEqual\n * @category Common Helpers\n * @summary Are the given dates equal?\n *\n * @description\n * Are the given dates equal?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to compare\n * @param {Date|Number} dateRight - the second date to compare\n * @returns {Boolean} the dates are equal\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal?\n * var result = isEqual(\n *   new Date(2014, 6, 2, 6, 30, 45, 0),\n *   new Date(2014, 6, 2, 6, 30, 45, 500)\n * )\n * //=> false\n */\n\nexport default function isEqual(dirtyLeftDate, dirtyRightDate) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyLeftDate);\n  var dateRight = toDate(dirtyRightDate);\n  return dateLeft.getTime() === dateRight.getTime();\n}","/**\n * @name isExists\n * @category Common Helpers\n * @summary Is the given date exists?\n *\n * @description\n * Checks if the given arguments convert to an existing date.\n *\n * @param {Number} year of the date to check\n * @param {Number} month of the date to check\n * @param {Number} day of the date to check\n * @returns {Boolean} the date exists\n * @throws {TypeError} 3 arguments required\n *\n * @example\n * // For the valid date:\n * var result = isExists(2018, 0, 31)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * var result = isExists(2018, 1, 31)\n * //=> false\n */\nexport default function isExists(year, month, day) {\n  if (arguments.length < 3) {\n    throw new TypeError('3 argument required, but only ' + arguments.length + ' present');\n  }\n\n  var date = new Date(year, month, day);\n  return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFirstDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the first day of a month?\n *\n * @description\n * Is the given date the first day of a month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is the first day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 1 September 2014 the first day of a month?\n * var result = isFirstDayOfMonth(new Date(2014, 8, 1))\n * //=> true\n */\n\nexport default function isFirstDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDate() === 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFriday\n * @category Weekday Helpers\n * @summary Is the given date Friday?\n *\n * @description\n * Is the given date Friday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Friday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 26 September 2014 Friday?\n * var result = isFriday(new Date(2014, 8, 26))\n * //=> true\n */\n\nexport default function isFriday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 5;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isFuture\n * @category Common Helpers\n * @summary Is the given date in the future?\n * @pure false\n *\n * @description\n * Is the given date in the future?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the future\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 31 December 2014 in the future?\n * var result = isFuture(new Date(2014, 11, 31))\n * //=> true\n */\n\nexport default function isFuture(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getTime() > Date.now();\n}","import toDate from '../toDate/index.js';\nimport endOfDay from '../endOfDay/index.js';\nimport endOfMonth from '../endOfMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isLastDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the last day of a month?\n *\n * @description\n * Is the given date the last day of a month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is the last day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 28 February 2014 the last day of a month?\n * var result = isLastDayOfMonth(new Date(2014, 1, 28))\n * //=> true\n */\n\nexport default function isLastDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  return endOfDay(date).getTime() === endOfMonth(date).getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isLeapYear\n * @category Year Helpers\n * @summary Is the given date in the leap year?\n *\n * @description\n * Is the given date in the leap year?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the leap year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 1 September 2012 in the leap year?\n * var result = isLeapYear(new Date(2012, 8, 1))\n * //=> true\n */\n\nexport default function isLeapYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}","import parse from '../parse/index.js';\nimport isValid from '../isValid/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isMatch\n * @category Common Helpers\n * @summary validates the date string against given formats\n *\n * @description\n * Return the true if given date is string correct against the given format else\n * will return false.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters in the format string wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the format string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 5 below the table).\n *\n * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited\n * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:\n *\n * ```javascript\n * isMatch('23 AM', 'HH a')\n * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time\n * ```\n *\n * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true\n *\n * Accepted format string patterns:\n * | Unit                            |Prior| Pattern | Result examples                   | Notes |\n * |---------------------------------|-----|---------|-----------------------------------|-------|\n * | Era                             | 140 | G..GGG  | AD, BC                            |       |\n * |                                 |     | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 |     | GGGGG   | A, B                              |       |\n * | Calendar year                   | 130 | y       | 44, 1, 1900, 2017, 9999           | 4     |\n * |                                 |     | yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | yy      | 44, 01, 00, 17                    | 4     |\n * |                                 |     | yyy     | 044, 001, 123, 999                | 4     |\n * |                                 |     | yyyy    | 0044, 0001, 1900, 2017            | 4     |\n * |                                 |     | yyyyy   | ...                               | 2,4   |\n * | Local week-numbering year       | 130 | Y       | 44, 1, 1900, 2017, 9000           | 4     |\n * |                                 |     | Yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | YY      | 44, 01, 00, 17                    | 4,6   |\n * |                                 |     | YYY     | 044, 001, 123, 999                | 4     |\n * |                                 |     | YYYY    | 0044, 0001, 1900, 2017            | 4,6   |\n * |                                 |     | YYYYY   | ...                               | 2,4   |\n * | ISO week-numbering year         | 130 | R       | -43, 1, 1900, 2017, 9999, -9999   | 4,5   |\n * |                                 |     | RR      | -43, 01, 00, 17                   | 4,5   |\n * |                                 |     | RRR     | -043, 001, 123, 999, -999         | 4,5   |\n * |                                 |     | RRRR    | -0043, 0001, 2017, 9999, -9999    | 4,5   |\n * |                                 |     | RRRRR   | ...                               | 2,4,5 |\n * | Extended year                   | 130 | u       | -43, 1, 1900, 2017, 9999, -999    | 4     |\n * |                                 |     | uu      | -43, 01, 99, -99                  | 4     |\n * |                                 |     | uuu     | -043, 001, 123, 999, -999         | 4     |\n * |                                 |     | uuuu    | -0043, 0001, 2017, 9999, -9999    | 4     |\n * |                                 |     | uuuuu   | ...                               | 2,4   |\n * | Quarter (formatting)            | 120 | Q       | 1, 2, 3, 4                        |       |\n * |                                 |     | Qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | QQ      | 01, 02, 03, 04                    |       |\n * |                                 |     | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | 120 | q       | 1, 2, 3, 4                        |       |\n * |                                 |     | qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | qq      | 01, 02, 03, 04                    |       |\n * |                                 |     | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | qqqqq   | 1, 2, 3, 4                        | 3     |\n * | Month (formatting)              | 110 | M       | 1, 2, ..., 12                     |       |\n * |                                 |     | Mo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | MM      | 01, 02, ..., 12                   |       |\n * |                                 |     | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | MMMM    | January, February, ..., December  | 2     |\n * |                                 |     | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | 110 | L       | 1, 2, ..., 12                     |       |\n * |                                 |     | Lo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | LL      | 01, 02, ..., 12                   |       |\n * |                                 |     | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | LLLL    | January, February, ..., December  | 2     |\n * |                                 |     | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | 100 | w       | 1, 2, ..., 53                     |       |\n * |                                 |     | wo      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | 100 | I       | 1, 2, ..., 53                     | 5     |\n * |                                 |     | Io      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | II      | 01, 02, ..., 53                   | 5     |\n * | Day of month                    |  90 | d       | 1, 2, ..., 31                     |       |\n * |                                 |     | do      | 1st, 2nd, ..., 31st               | 5     |\n * |                                 |     | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     |  90 | D       | 1, 2, ..., 365, 366               | 7     |\n * |                                 |     | Do      | 1st, 2nd, ..., 365th, 366th       | 5     |\n * |                                 |     | DD      | 01, 02, ..., 365, 366             | 7     |\n * |                                 |     | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 |     | DDDD    | ...                               | 2     |\n * | Day of week (formatting)        |  90 | E..EEE  | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 |     | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    |  90 | i       | 1, 2, 3, ..., 7                   | 5     |\n * |                                 |     | io      | 1st, 2nd, ..., 7th                | 5     |\n * |                                 |     | ii      | 01, 02, ..., 07                   | 5     |\n * |                                 |     | iii     | Mon, Tue, Wed, ..., Su            | 5     |\n * |                                 |     | iiii    | Monday, Tuesday, ..., Sunday      | 2,5   |\n * |                                 |     | iiiii   | M, T, W, T, F, S, S               | 5     |\n * |                                 |     | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 5     |\n * | Local day of week (formatting)  |  90 | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | eo      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | ee      | 02, 03, ..., 01                   |       |\n * |                                 |     | eee     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 |     | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) |  90 | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | co      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | cc      | 02, 03, ..., 01                   |       |\n * |                                 |     | ccc     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 |     | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          |  80 | a..aaa  | AM, PM                            |       |\n * |                                 |     | aaaa    | a.m., p.m.                        | 2     |\n * |                                 |     | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          |  80 | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 |     | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 |     | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             |  80 | B..BBB  | at night, in the morning, ...     |       |\n * |                                 |     | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 |     | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     |  70 | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 |     | ho      | 1st, 2nd, ..., 11th, 12th         | 5     |\n * |                                 |     | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     |  70 | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 |     | Ho      | 0th, 1st, 2nd, ..., 23rd          | 5     |\n * |                                 |     | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     |  70 | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 |     | Ko      | 1st, 2nd, ..., 11th, 0th          | 5     |\n * |                                 |     | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     |  70 | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 |     | ko      | 24th, 1st, 2nd, ..., 23rd         | 5     |\n * |                                 |     | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          |  60 | m       | 0, 1, ..., 59                     |       |\n * |                                 |     | mo      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | mm      | 00, 01, ..., 59                   |       |\n * | Second                          |  50 | s       | 0, 1, ..., 59                     |       |\n * |                                 |     | so      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | ss      | 00, 01, ..., 59                   |       |\n * | Seconds timestamp               |  40 | t       | 512969520                         |       |\n * |                                 |     | tt      | ...                               | 2     |\n * | Fraction of second              |  30 | S       | 0, 1, ..., 9                      |       |\n * |                                 |     | SS      | 00, 01, ..., 99                   |       |\n * |                                 |     | SSS     | 000, 0001, ..., 999               |       |\n * |                                 |     | SSSS    | ...                               | 2     |\n * | Milliseconds timestamp          |  20 | T       | 512969520900                      |       |\n * |                                 |     | TT      | ...                               | 2     |\n * | Timezone (ISO-8601 w/ Z)        |  10 | X       | -08, +0530, Z                     |       |\n * |                                 |     | XX      | -0800, +0530, Z                   |       |\n * |                                 |     | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 |     | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 |     | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       |  10 | x       | -08, +0530, +00                   |       |\n * |                                 |     | xx      | -0800, +0530, +0000               |       |\n * |                                 |     | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 |     | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 |     | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Long localized date             |  NA | P       | 05/29/1453                        | 5,8   |\n * |                                 |     | PP      | May 29, 1453                      |       |\n * |                                 |     | PPP     | May 29th, 1453                    |       |\n * |                                 |     | PPPP    | Sunday, May 29th, 1453            | 2,5,8 |\n * | Long localized time             |  NA | p       | 12:00 AM                          | 5,8   |\n * |                                 |     | pp      | 12:00:00 AM                       |       |\n * | Combination of date and time    |  NA | Pp      | 05/29/1453, 12:00 AM              |       |\n * |                                 |     | PPpp    | May 29, 1453, 12:00:00 AM         |       |\n * |                                 |     | PPPpp   | May 29th, 1453 at ...             |       |\n * |                                 |     | PPPPpp  | Sunday, May 29th, 1453 at ...     | 2,5,8 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular.\n *    In `format` function, they will produce different result:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n *    `isMatch` will try to match both formatting and stand-alone units interchangably.\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table:\n *    - for numerical units (`yyyyyyyy`) `isMatch` will try to match a number\n *      as wide as the sequence\n *    - for text units (`MMMMMMMM`) `isMatch` will try to match the widest variation of the unit.\n *      These variations are marked with \"2\" in the last column of the table.\n *\n * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 4. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:\n *\n *    `isMatch('50', 'yy') //=> true`\n *\n *    `isMatch('75', 'yy') //=> true`\n *\n *    while `uu` will use the year as is:\n *\n *    `isMatch('50', 'uu') //=> true`\n *\n *    `isMatch('75', 'uu') //=> true`\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}\n *    and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).\n *\n * 5. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based\n *    on the given locale.\n *\n *    using `en-US` locale: `P` => `MM/dd/yyyy`\n *    using `en-US` locale: `p` => `hh:mm a`\n *    using `pt-BR` locale: `P` => `dd/MM/yyyy`\n *    using `pt-BR` locale: `p` => `HH:mm`\n *\n * Values will be checked in the descending order of its unit's priority.\n * Units of an equal priority overwrite each other in the order of appearance.\n *\n * If no values of higher priority are matched (e.g. when matching string 'January 1st' without a year),\n * the values will be taken from today's using `new Date()` date which works as a context of parsing.\n *\n * The result may vary by locale.\n *\n * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.\n *\n *\n *\n * @param {String} dateString - the date string to verify\n * @param {String} formatString - the string of tokens\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {Boolean}\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} `options.locale` must contain `match` property\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Match 11 February 2014 from middle-endian format:\n * var result = isMatch('02/11/2014', 'MM/dd/yyyy')\n * //=> true\n *\n * @example\n * // Match 28th of February in Esperanto locale in the context of 2010 year:\n * import eo from 'date-fns/locale/eo'\n * var result = isMatch('28-a de februaro', \"do 'de' MMMM\", {\n *   locale: eo\n * })\n * //=> true\n */\n\nexport default function isMatch(dateString, formatString, dirtyOptions) {\n  requiredArgs(2, arguments);\n  return isValid(parse(dateString, formatString, new Date(), dirtyOptions));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isMonday\n * @category Weekday Helpers\n * @summary Is the given date Monday?\n *\n * @description\n * Is the given date Monday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Monday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 22 September 2014 Monday?\n * var result = isMonday(new Date(2014, 8, 22))\n * //=> true\n */\n\nexport default function isMonday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 1;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isPast\n * @category Common Helpers\n * @summary Is the given date in the past?\n * @pure false\n *\n * @description\n * Is the given date in the past?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in the past\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 2 July 2014 in the past?\n * var result = isPast(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isPast(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getTime() < Date.now();\n}","import startOfDay from '../startOfDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameDay\n * @category Day Helpers\n * @summary Are the given dates in the same day?\n *\n * @description\n * Are the given dates in the same day?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same day\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?\n * var result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))\n * //=> true\n */\n\nexport default function isSameDay(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfDay = startOfDay(dirtyDateLeft);\n  var dateRightStartOfDay = startOfDay(dirtyDateRight);\n  return dateLeftStartOfDay.getTime() === dateRightStartOfDay.getTime();\n}","import startOfHour from '../startOfHour/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameHour\n * @category Hour Helpers\n * @summary Are the given dates in the same hour?\n *\n * @description\n * Are the given dates in the same hour?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same hour\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:00:00 and 4 September 06:30:00 in the same hour?\n * var result = isSameHour(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 6, 30))\n * //=> true\n */\n\nexport default function isSameHour(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfHour = startOfHour(dirtyDateLeft);\n  var dateRightStartOfHour = startOfHour(dirtyDateRight);\n  return dateLeftStartOfHour.getTime() === dateRightStartOfHour.getTime();\n}","import isSameWeek from '../isSameWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameISOWeek\n * @category ISO Week Helpers\n * @summary Are the given dates in the same ISO week?\n *\n * @description\n * Are the given dates in the same ISO week?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same ISO week\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 1 September 2014 and 7 September 2014 in the same ISO week?\n * var result = isSameISOWeek(new Date(2014, 8, 1), new Date(2014, 8, 7))\n * //=> true\n */\n\nexport default function isSameISOWeek(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  return isSameWeek(dirtyDateLeft, dirtyDateRight, {\n    weekStartsOn: 1\n  });\n}","import startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Are the given dates in the same ISO week-numbering year?\n *\n * @description\n * Are the given dates in the same ISO week-numbering year?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `isSameISOYear` to `isSameISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same ISO week-numbering year\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 29 December 2003 and 2 January 2005 in the same ISO week-numbering year?\n * var result = isSameISOWeekYear(new Date(2003, 11, 29), new Date(2005, 0, 2))\n * //=> true\n */\n\nexport default function isSameISOWeekYear(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfYear = startOfISOWeekYear(dirtyDateLeft);\n  var dateRightStartOfYear = startOfISOWeekYear(dirtyDateRight);\n  return dateLeftStartOfYear.getTime() === dateRightStartOfYear.getTime();\n}","import startOfMinute from '../startOfMinute/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameMinute\n * @category Minute Helpers\n * @summary Are the given dates in the same minute?\n *\n * @description\n * Are the given dates in the same minute?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same minute\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:30:00 and 4 September 2014 06:30:15\n * // in the same minute?\n * var result = isSameMinute(\n *   new Date(2014, 8, 4, 6, 30),\n *   new Date(2014, 8, 4, 6, 30, 15)\n * )\n * //=> true\n */\n\nexport default function isSameMinute(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfMinute = startOfMinute(dirtyDateLeft);\n  var dateRightStartOfMinute = startOfMinute(dirtyDateRight);\n  return dateLeftStartOfMinute.getTime() === dateRightStartOfMinute.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameMonth\n * @category Month Helpers\n * @summary Are the given dates in the same month?\n *\n * @description\n * Are the given dates in the same month?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same month\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 September 2014 and 25 September 2014 in the same month?\n * var result = isSameMonth(new Date(2014, 8, 2), new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isSameMonth(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() === dateRight.getFullYear() && dateLeft.getMonth() === dateRight.getMonth();\n}","import startOfQuarter from '../startOfQuarter/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameQuarter\n * @category Quarter Helpers\n * @summary Are the given dates in the same year quarter?\n *\n * @description\n * Are the given dates in the same year quarter?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same quarter\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 1 January 2014 and 8 March 2014 in the same quarter?\n * var result = isSameQuarter(new Date(2014, 0, 1), new Date(2014, 2, 8))\n * //=> true\n */\n\nexport default function isSameQuarter(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfQuarter = startOfQuarter(dirtyDateLeft);\n  var dateRightStartOfQuarter = startOfQuarter(dirtyDateRight);\n  return dateLeftStartOfQuarter.getTime() === dateRightStartOfQuarter.getTime();\n}","import startOfSecond from '../startOfSecond/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameSecond\n * @category Second Helpers\n * @summary Are the given dates in the same second?\n *\n * @description\n * Are the given dates in the same second?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same second\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 4 September 2014 06:30:15.000 and 4 September 2014 06:30.15.500\n * // in the same second?\n * var result = isSameSecond(\n *   new Date(2014, 8, 4, 6, 30, 15),\n *   new Date(2014, 8, 4, 6, 30, 15, 500)\n * )\n * //=> true\n */\n\nexport default function isSameSecond(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfSecond = startOfSecond(dirtyDateLeft);\n  var dateRightStartOfSecond = startOfSecond(dirtyDateRight);\n  return dateLeftStartOfSecond.getTime() === dateRightStartOfSecond.getTime();\n}","import startOfWeek from '../startOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameWeek\n * @category Week Helpers\n * @summary Are the given dates in the same week?\n *\n * @description\n * Are the given dates in the same week?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Boolean} the dates are in the same week\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Are 31 August 2014 and 4 September 2014 in the same week?\n * var result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4))\n * //=> true\n *\n * @example\n * // If week starts with Monday,\n * // are 31 August 2014 and 4 September 2014 in the same week?\n * var result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4), {\n *   weekStartsOn: 1\n * })\n * //=> false\n */\n\nexport default function isSameWeek(dirtyDateLeft, dirtyDateRight, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var dateLeftStartOfWeek = startOfWeek(dirtyDateLeft, dirtyOptions);\n  var dateRightStartOfWeek = startOfWeek(dirtyDateRight, dirtyOptions);\n  return dateLeftStartOfWeek.getTime() === dateRightStartOfWeek.getTime();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSameYear\n * @category Year Helpers\n * @summary Are the given dates in the same year?\n *\n * @description\n * Are the given dates in the same year?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} dateLeft - the first date to check\n * @param {Date|Number} dateRight - the second date to check\n * @returns {Boolean} the dates are in the same year\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Are 2 September 2014 and 25 September 2014 in the same year?\n * var result = isSameYear(new Date(2014, 8, 2), new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isSameYear(dirtyDateLeft, dirtyDateRight) {\n  requiredArgs(2, arguments);\n  var dateLeft = toDate(dirtyDateLeft);\n  var dateRight = toDate(dirtyDateRight);\n  return dateLeft.getFullYear() === dateRight.getFullYear();\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSaturday\n * @category Weekday Helpers\n * @summary Is the given date Saturday?\n *\n * @description\n * Is the given date Saturday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Saturday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 27 September 2014 Saturday?\n * var result = isSaturday(new Date(2014, 8, 27))\n * //=> true\n */\n\nexport default function isSaturday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 6;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isSunday\n * @category Weekday Helpers\n * @summary Is the given date Sunday?\n *\n * @description\n * Is the given date Sunday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Sunday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 21 September 2014 Sunday?\n * var result = isSunday(new Date(2014, 8, 21))\n * //=> true\n */\n\nexport default function isSunday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 0;\n}","import isSameHour from '../isSameHour/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisHour\n * @category Hour Helpers\n * @summary Is the given date in the same hour as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same hour as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:00:00 in this hour?\n * var result = isThisHour(new Date(2014, 8, 25, 18))\n * //=> true\n */\n\nexport default function isThisHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameHour(Date.now(), dirtyDate);\n}","import isSameISOWeek from '../isSameISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisISOWeek\n * @category ISO Week Helpers\n * @summary Is the given date in the same ISO week as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same ISO week as the current date?\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 22 September 2014 in this ISO week?\n * var result = isThisISOWeek(new Date(2014, 8, 22))\n * //=> true\n */\n\nexport default function isThisISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameISOWeek(dirtyDate, Date.now());\n}","import isSameMinute from '../isSameMinute/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisMinute\n * @category Minute Helpers\n * @summary Is the given date in the same minute as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same minute as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:30:00 in this minute?\n * var result = isThisMinute(new Date(2014, 8, 25, 18, 30))\n * //=> true\n */\n\nexport default function isThisMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameMinute(Date.now(), dirtyDate);\n}","import isSameMonth from '../isSameMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisMonth\n * @category Month Helpers\n * @summary Is the given date in the same month as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same month as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 15 September 2014 in this month?\n * var result = isThisMonth(new Date(2014, 8, 15))\n * //=> true\n */\n\nexport default function isThisMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameMonth(Date.now(), dirtyDate);\n}","import isSameQuarter from '../isSameQuarter/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisQuarter\n * @category Quarter Helpers\n * @summary Is the given date in the same quarter as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same quarter as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 2 July 2014 in this quarter?\n * var result = isThisQuarter(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isThisQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameQuarter(Date.now(), dirtyDate);\n}","import isSameSecond from '../isSameSecond/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisSecond\n * @category Second Helpers\n * @summary Is the given date in the same second as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same second as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If now is 25 September 2014 18:30:15.500,\n * // is 25 September 2014 18:30:15.000 in this second?\n * var result = isThisSecond(new Date(2014, 8, 25, 18, 30, 15))\n * //=> true\n */\n\nexport default function isThisSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameSecond(Date.now(), dirtyDate);\n}","import isSameWeek from '../isSameWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisWeek\n * @category Week Helpers\n * @summary Is the given date in the same week as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same week as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @param {Object} [options] - the object with options\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Boolean} the date is in this week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // If today is 25 September 2014, is 21 September 2014 in this week?\n * var result = isThisWeek(new Date(2014, 8, 21))\n * //=> true\n *\n * @example\n * // If today is 25 September 2014 and week starts with Monday\n * // is 21 September 2014 in this week?\n * var result = isThisWeek(new Date(2014, 8, 21), { weekStartsOn: 1 })\n * //=> false\n */\n\nexport default function isThisWeek(dirtyDate, options) {\n  requiredArgs(1, arguments);\n  return isSameWeek(dirtyDate, Date.now(), options);\n}","import isSameYear from '../isSameYear/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThisYear\n * @category Year Helpers\n * @summary Is the given date in the same year as the current date?\n * @pure false\n *\n * @description\n * Is the given date in the same year as the current date?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is in this year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 25 September 2014, is 2 July 2014 in this year?\n * var result = isThisYear(new Date(2014, 6, 2))\n * //=> true\n */\n\nexport default function isThisYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameYear(dirtyDate, Date.now());\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isThursday\n * @category Weekday Helpers\n * @summary Is the given date Thursday?\n *\n * @description\n * Is the given date Thursday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Thursday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 25 September 2014 Thursday?\n * var result = isThursday(new Date(2014, 8, 25))\n * //=> true\n */\n\nexport default function isThursday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 4;\n}","import isSameDay from '../isSameDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isToday\n * @category Day Helpers\n * @summary Is the given date today?\n * @pure false\n *\n * @description\n * Is the given date today?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is today\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 6 October 14:00:00 today?\n * var result = isToday(new Date(2014, 9, 6, 14, 0))\n * //=> true\n */\n\nexport default function isToday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, Date.now());\n}","import addDays from '../addDays/index.js';\nimport isSameDay from '../isSameDay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isTomorrow\n * @category Day Helpers\n * @summary Is the given date tomorrow?\n * @pure false\n *\n * @description\n * Is the given date tomorrow?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is tomorrow\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 7 October 14:00:00 tomorrow?\n * var result = isTomorrow(new Date(2014, 9, 7, 14, 0))\n * //=> true\n */\n\nexport default function isTomorrow(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, addDays(Date.now(), 1));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isTuesday\n * @category Weekday Helpers\n * @summary Is the given date Tuesday?\n *\n * @description\n * Is the given date Tuesday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Tuesday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 23 September 2014 Tuesday?\n * var result = isTuesday(new Date(2014, 8, 23))\n * //=> true\n */\n\nexport default function isTuesday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 2;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now `isValid` doesn't throw an exception\n *   if the first argument is not an instance of Date.\n *   Instead, argument is converted beforehand using `toDate`.\n *\n *   Examples:\n *\n *   | `isValid` argument        | Before v2.0.0 | v2.0.0 onward |\n *   |---------------------------|---------------|---------------|\n *   | `new Date()`              | `true`        | `true`        |\n *   | `new Date('2016-01-01')`  | `true`        | `true`        |\n *   | `new Date('')`            | `false`       | `false`       |\n *   | `new Date(1488370835081)` | `true`        | `true`        |\n *   | `new Date(NaN)`           | `false`       | `false`       |\n *   | `'2016-01-01'`            | `TypeError`   | `false`       |\n *   | `''`                      | `TypeError`   | `false`       |\n *   | `1488370835081`           | `TypeError`   | `true`        |\n *   | `NaN`                     | `TypeError`   | `false`       |\n *\n *   We introduce this change to make *date-fns* consistent with ECMAScript behavior\n *   that try to coerce arguments to the expected type\n *   (which is also the case with other *date-fns* functions).\n *\n * @param {*} date - the date to check\n * @returns {Boolean} the date is valid\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // For the valid date:\n * var result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * var result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * var result = isValid(new Date(''))\n * //=> false\n */\n\nexport default function isValid(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  return !isNaN(date);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWednesday\n * @category Weekday Helpers\n * @summary Is the given date Wednesday?\n *\n * @description\n * Is the given date Wednesday?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is Wednesday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Is 24 September 2014 Wednesday?\n * var result = isWednesday(new Date(2014, 8, 24))\n * //=> true\n */\n\nexport default function isWednesday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return toDate(dirtyDate).getDay() === 3;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWeekend\n * @category Weekday Helpers\n * @summary Does the given date fall on a weekend?\n *\n * @description\n * Does the given date fall on a weekend?\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date falls on a weekend\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Does 5 October 2014 fall on a weekend?\n * var result = isWeekend(new Date(2014, 9, 5))\n * //=> true\n */\n\nexport default function isWeekend(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  return day === 0 || day === 6;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isWithinInterval\n * @category Interval Helpers\n * @summary Is the given date within the interval?\n *\n * @description\n * Is the given date within the interval? (Including start and end.)\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `isWithinRange` to `isWithinInterval`.\n *   This change was made to mirror the use of the word \"interval\" in standard ISO 8601:2004 terminology:\n *\n *   ```\n *   2.1.3\n *   time interval\n *   part of the time axis limited by two instants\n *   ```\n *\n *   Also, this function now accepts an object with `start` and `end` properties\n *   instead of two arguments as an interval.\n *   This function now throws `RangeError` if the start of the interval is after its end\n *   or if any date in the interval is `Invalid Date`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *\n *   isWithinRange(\n *     new Date(2014, 0, 3),\n *     new Date(2014, 0, 1), new Date(2014, 0, 7)\n *   )\n *\n *   // v2.0.0 onward\n *\n *   isWithinInterval(\n *     new Date(2014, 0, 3),\n *     { start: new Date(2014, 0, 1), end: new Date(2014, 0, 7) }\n *   )\n *   ```\n *\n * @param {Date|Number} date - the date to check\n * @param {Interval} interval - the interval to check\n * @returns {Boolean} the date is within the interval\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} The start of an interval cannot be after its end\n * @throws {RangeError} Date in interval cannot be `Invalid Date`\n *\n * @example\n * // For the date within the interval:\n * isWithinInterval(new Date(2014, 0, 3), {\n *   start: new Date(2014, 0, 1),\n *   end: new Date(2014, 0, 7)\n * })\n * //=> true\n *\n * @example\n * // For the date outside of the interval:\n * isWithinInterval(new Date(2014, 0, 10), {\n *   start: new Date(2014, 0, 1),\n *   end: new Date(2014, 0, 7)\n * })\n * //=> false\n *\n * @example\n * // For date equal to interval start:\n * isWithinInterval(date, { start, end: date }) // => true\n *\n * @example\n * // For date equal to interval end:\n * isWithinInterval(date, { start: date, end }) // => true\n */\n\nexport default function isWithinInterval(dirtyDate, dirtyInterval) {\n  requiredArgs(2, arguments);\n  var interval = dirtyInterval || {};\n  var time = toDate(dirtyDate).getTime();\n  var startTime = toDate(interval.start).getTime();\n  var endTime = toDate(interval.end).getTime(); // Throw an exception if start date is after end date or if any date is `Invalid Date`\n\n  if (!(startTime <= endTime)) {\n    throw new RangeError('Invalid interval');\n  }\n\n  return time >= startTime && time <= endTime;\n}","import isSameDay from '../isSameDay/index.js';\nimport subDays from '../subDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name isYesterday\n * @category Day Helpers\n * @summary Is the given date yesterday?\n * @pure false\n *\n * @description\n * Is the given date yesterday?\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to check\n * @returns {Boolean} the date is yesterday\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // If today is 6 October 2014, is 5 October 14:00:00 yesterday?\n * var result = isYesterday(new Date(2014, 9, 5, 14, 0))\n * //=> true\n */\n\nexport default function isYesterday(dirtyDate) {\n  requiredArgs(1, arguments);\n  return isSameDay(dirtyDate, subDays(Date.now(), 1));\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfDecade\n * @category Decade Helpers\n * @summary Return the last day of a decade for the given date.\n *\n * @description\n * Return the last day of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a decade for 21 December 2012 21:12:00:\n * var result = lastDayOfDecade(new Date(2012, 11, 21, 21, 12, 00))\n * //=> Wed Dec 31 2019 00:00:00\n */\n\nexport default function lastDayOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = 9 + Math.floor(year / 10) * 10;\n  date.setFullYear(decade + 1, 0, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import lastDayOfWeek from '../lastDayOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the last day of an ISO week for the given date.\n *\n * @description\n * Return the last day of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of an ISO week for 2 September 2014 11:55:00:\n * var result = lastDayOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function lastDayOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return lastDayOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the last day of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the last day of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `lastDayOfISOYear` to `lastDayOfISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `getWeekYear`.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the end of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of an ISO week-numbering year for 2 July 2005:\n * var result = lastDayOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Sun Jan 01 2006 00:00:00\n */\n\nexport default function lastDayOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(year + 1, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuary);\n  date.setDate(date.getDate() - 1);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfMonth\n * @category Month Helpers\n * @summary Return the last day of a month for the given date.\n *\n * @description\n * Return the last day of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a month for 2 September 2014 11:55:00:\n * var result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function lastDayOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var month = date.getMonth();\n  date.setFullYear(date.getFullYear(), month + 1, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfQuarter\n * @category Quarter Helpers\n * @summary Return the last day of a year quarter for the given date.\n *\n * @description\n * Return the last day of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * @returns {Date} the last day of a quarter\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // The last day of a quarter for 2 September 2014 11:55:00:\n * var result = lastDayOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function lastDayOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3 + 3;\n  date.setMonth(month, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfWeek\n * @category Week Helpers\n * @summary Return the last day of a week for the given date.\n *\n * @description\n * Return the last day of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the last day of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The last day of a week for 2 September 2014 11:55:00:\n * var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sat Sep 06 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the last day of the week for 2 September 2014 11:55:00:\n * var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function lastDayOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);\n  date.setHours(0, 0, 0, 0);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name lastDayOfYear\n * @category Year Helpers\n * @summary Return the last day of a year for the given date.\n *\n * @description\n * Return the last day of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a year for 2 September 2014 11:55:00:\n * var result = lastDayOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Dec 31 2014 00:00:00\n */\n\nexport default function lastDayOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  date.setFullYear(year + 1, 0, 0);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport formatters from '../_lib/format/lightFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport isValid from '../isValid/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js'; // This RegExp consists of three parts separated by `|`:\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /(\\w)\\1*|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name lightFormat\n * @category Common Helpers\n * @summary Format the date.\n *\n * @description\n * Return the formatted date string in the given format. Unlike `format`,\n * `lightFormat` doesn't use locales and outputs date using the most popular tokens.\n *\n * > ⚠️ Please note that the `lightFormat` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n *\n * Accepted patterns:\n * | Unit                            | Pattern | Result examples                   |\n * |---------------------------------|---------|-----------------------------------|\n * | AM, PM                          | a..aaa  | AM, PM                            |\n * |                                 | aaaa    | a.m., p.m.                        |\n * |                                 | aaaaa   | a, p                              |\n * | Calendar year                   | y       | 44, 1, 1900, 2017                 |\n * |                                 | yy      | 44, 01, 00, 17                    |\n * |                                 | yyy     | 044, 001, 000, 017                |\n * |                                 | yyyy    | 0044, 0001, 1900, 2017            |\n * | Month (formatting)              | M       | 1, 2, ..., 12                     |\n * |                                 | MM      | 01, 02, ..., 12                   |\n * | Day of month                    | d       | 1, 2, ..., 31                     |\n * |                                 | dd      | 01, 02, ..., 31                   |\n * | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |\n * |                                 | hh      | 01, 02, ..., 11, 12               |\n * | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |\n * |                                 | HH      | 00, 01, 02, ..., 23               |\n * | Minute                          | m       | 0, 1, ..., 59                     |\n * |                                 | mm      | 00, 01, ..., 59                   |\n * | Second                          | s       | 0, 1, ..., 59                     |\n * |                                 | ss      | 00, 01, ..., 59                   |\n * | Fraction of second              | S       | 0, 1, ..., 9                      |\n * |                                 | SS      | 00, 01, ..., 99                   |\n * |                                 | SSS     | 000, 0001, ..., 999               |\n * |                                 | SSSS    | ...                               |\n *\n * @param {Date|Number} date - the original date\n * @param {String} format - the string of tokens\n * @returns {String} the formatted date string\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * var result = lightFormat(new Date(2014, 1, 11), 'yyyy-MM-dd')\n * //=> '1987-02-11'\n */\n\nexport default function lightFormat(dirtyDate, dirtyFormatStr) {\n  requiredArgs(2, arguments);\n  var formatStr = String(dirtyFormatStr);\n  var originalDate = toDate(dirtyDate);\n\n  if (!isValid(originalDate)) {\n    throw new RangeError('Invalid time value');\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376\n\n\n  var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);\n  var utcDate = subMilliseconds(originalDate, timezoneOffset);\n  var result = formatStr.match(formattingTokensRegExp).map(function (substring) {\n    // Replace two single quote characters with one single quote character\n    if (substring === \"''\") {\n      return \"'\";\n    }\n\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === \"'\") {\n      return cleanEscapedString(substring);\n    }\n\n    var formatter = formatters[firstCharacter];\n\n    if (formatter) {\n      return formatter(utcDate, substring, null, {});\n    }\n\n    if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n      throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n    }\n\n    return substring;\n  }).join('');\n  return result;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","export default function buildFormatLongFn(args) {\n  return function (dirtyOptions) {\n    var options = dirtyOptions || {};\n    var width = options.width ? String(options.width) : args.defaultWidth;\n    var format = args.formats[width] || args.formats[args.defaultWidth];\n    return format;\n  };\n}","export default function buildLocalizeFn(args) {\n  return function (dirtyIndex, dirtyOptions) {\n    var options = dirtyOptions || {};\n    var context = options.context ? String(options.context) : 'standalone';\n    var valuesArray;\n\n    if (context === 'formatting' && args.formattingValues) {\n      var defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n      var width = options.width ? String(options.width) : defaultWidth;\n      valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];\n    } else {\n      var _defaultWidth = args.defaultWidth;\n\n      var _width = options.width ? String(options.width) : args.defaultWidth;\n\n      valuesArray = args.values[_width] || args.values[_defaultWidth];\n    }\n\n    var index = args.argumentCallback ? args.argumentCallback(dirtyIndex) : dirtyIndex;\n    return valuesArray[index];\n  };\n}","export default function buildMatchFn(args) {\n  return function (dirtyString, dirtyOptions) {\n    var string = String(dirtyString);\n    var options = dirtyOptions || {};\n    var width = options.width;\n    var matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];\n    var matchResult = string.match(matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n\n    var matchedString = matchResult[0];\n    var parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];\n    var value;\n\n    if (Object.prototype.toString.call(parsePatterns) === '[object Array]') {\n      value = findIndex(parsePatterns, function (pattern) {\n        return pattern.test(matchedString);\n      });\n    } else {\n      value = findKey(parsePatterns, function (pattern) {\n        return pattern.test(matchedString);\n      });\n    }\n\n    value = args.valueCallback ? args.valueCallback(value) : value;\n    value = options.valueCallback ? options.valueCallback(value) : value;\n    return {\n      value: value,\n      rest: string.slice(matchedString.length)\n    };\n  };\n}\n\nfunction findKey(object, predicate) {\n  for (var key in object) {\n    if (object.hasOwnProperty(key) && predicate(object[key])) {\n      return key;\n    }\n  }\n}\n\nfunction findIndex(array, predicate) {\n  for (var key = 0; key < array.length; key++) {\n    if (predicate(array[key])) {\n      return key;\n    }\n  }\n}","export default function buildMatchPatternFn(args) {\n  return function (dirtyString, dirtyOptions) {\n    var string = String(dirtyString);\n    var options = dirtyOptions || {};\n    var matchResult = string.match(args.matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n\n    var matchedString = matchResult[0];\n    var parseResult = string.match(args.parsePattern);\n\n    if (!parseResult) {\n      return null;\n    }\n\n    var value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];\n    value = options.valueCallback ? options.valueCallback(value) : value;\n    return {\n      value: value,\n      rest: string.slice(matchedString.length)\n    };\n  };\n}","var formatDistanceLocale = {\n  lessThanXSeconds: {\n    one: 'less than a second',\n    other: 'less than {{count}} seconds'\n  },\n  xSeconds: {\n    one: '1 second',\n    other: '{{count}} seconds'\n  },\n  halfAMinute: 'half a minute',\n  lessThanXMinutes: {\n    one: 'less than a minute',\n    other: 'less than {{count}} minutes'\n  },\n  xMinutes: {\n    one: '1 minute',\n    other: '{{count}} minutes'\n  },\n  aboutXHours: {\n    one: 'about 1 hour',\n    other: 'about {{count}} hours'\n  },\n  xHours: {\n    one: '1 hour',\n    other: '{{count}} hours'\n  },\n  xDays: {\n    one: '1 day',\n    other: '{{count}} days'\n  },\n  aboutXWeeks: {\n    one: 'about 1 week',\n    other: 'about {{count}} weeks'\n  },\n  xWeeks: {\n    one: '1 week',\n    other: '{{count}} weeks'\n  },\n  aboutXMonths: {\n    one: 'about 1 month',\n    other: 'about {{count}} months'\n  },\n  xMonths: {\n    one: '1 month',\n    other: '{{count}} months'\n  },\n  aboutXYears: {\n    one: 'about 1 year',\n    other: 'about {{count}} years'\n  },\n  xYears: {\n    one: '1 year',\n    other: '{{count}} years'\n  },\n  overXYears: {\n    one: 'over 1 year',\n    other: 'over {{count}} years'\n  },\n  almostXYears: {\n    one: 'almost 1 year',\n    other: 'almost {{count}} years'\n  }\n};\nexport default function formatDistance(token, count, options) {\n  options = options || {};\n  var result;\n\n  if (typeof formatDistanceLocale[token] === 'string') {\n    result = formatDistanceLocale[token];\n  } else if (count === 1) {\n    result = formatDistanceLocale[token].one;\n  } else {\n    result = formatDistanceLocale[token].other.replace('{{count}}', count);\n  }\n\n  if (options.addSuffix) {\n    if (options.comparison > 0) {\n      return 'in ' + result;\n    } else {\n      return result + ' ago';\n    }\n  }\n\n  return result;\n}","import buildFormatLongFn from '../../../_lib/buildFormatLongFn/index.js';\nvar dateFormats = {\n  full: 'EEEE, MMMM do, y',\n  long: 'MMMM do, y',\n  medium: 'MMM d, y',\n  short: 'MM/dd/yyyy'\n};\nvar timeFormats = {\n  full: 'h:mm:ss a zzzz',\n  long: 'h:mm:ss a z',\n  medium: 'h:mm:ss a',\n  short: 'h:mm a'\n};\nvar dateTimeFormats = {\n  full: \"{{date}} 'at' {{time}}\",\n  long: \"{{date}} 'at' {{time}}\",\n  medium: '{{date}}, {{time}}',\n  short: '{{date}}, {{time}}'\n};\nvar formatLong = {\n  date: buildFormatLongFn({\n    formats: dateFormats,\n    defaultWidth: 'full'\n  }),\n  time: buildFormatLongFn({\n    formats: timeFormats,\n    defaultWidth: 'full'\n  }),\n  dateTime: buildFormatLongFn({\n    formats: dateTimeFormats,\n    defaultWidth: 'full'\n  })\n};\nexport default formatLong;","var formatRelativeLocale = {\n  lastWeek: \"'last' eeee 'at' p\",\n  yesterday: \"'yesterday at' p\",\n  today: \"'today at' p\",\n  tomorrow: \"'tomorrow at' p\",\n  nextWeek: \"eeee 'at' p\",\n  other: 'P'\n};\nexport default function formatRelative(token, _date, _baseDate, _options) {\n  return formatRelativeLocale[token];\n}","import buildLocalizeFn from '../../../_lib/buildLocalizeFn/index.js';\nvar eraValues = {\n  narrow: ['B', 'A'],\n  abbreviated: ['BC', 'AD'],\n  wide: ['Before Christ', 'Anno Domini']\n};\nvar quarterValues = {\n  narrow: ['1', '2', '3', '4'],\n  abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'],\n  wide: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'] // Note: in English, the names of days of the week and months are capitalized.\n  // If you are making a new locale based on this one, check if the same is true for the language you're working on.\n  // Generally, formatted dates should look like they are in the middle of a sentence,\n  // e.g. in Spanish language the weekdays and months should be in the lowercase.\n\n};\nvar monthValues = {\n  narrow: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],\n  abbreviated: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n  wide: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n};\nvar dayValues = {\n  narrow: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],\n  short: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\n  abbreviated: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n  wide: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n};\nvar dayPeriodValues = {\n  narrow: {\n    am: 'a',\n    pm: 'p',\n    midnight: 'mi',\n    noon: 'n',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  },\n  abbreviated: {\n    am: 'AM',\n    pm: 'PM',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  },\n  wide: {\n    am: 'a.m.',\n    pm: 'p.m.',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'morning',\n    afternoon: 'afternoon',\n    evening: 'evening',\n    night: 'night'\n  }\n};\nvar formattingDayPeriodValues = {\n  narrow: {\n    am: 'a',\n    pm: 'p',\n    midnight: 'mi',\n    noon: 'n',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  },\n  abbreviated: {\n    am: 'AM',\n    pm: 'PM',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  },\n  wide: {\n    am: 'a.m.',\n    pm: 'p.m.',\n    midnight: 'midnight',\n    noon: 'noon',\n    morning: 'in the morning',\n    afternoon: 'in the afternoon',\n    evening: 'in the evening',\n    night: 'at night'\n  }\n};\n\nfunction ordinalNumber(dirtyNumber, _dirtyOptions) {\n  var number = Number(dirtyNumber); // If ordinal numbers depend on context, for example,\n  // if they are different for different grammatical genders,\n  // use `options.unit`:\n  //\n  //   var options = dirtyOptions || {}\n  //   var unit = String(options.unit)\n  //\n  // where `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',\n  // 'day', 'hour', 'minute', 'second'\n\n  var rem100 = number % 100;\n\n  if (rem100 > 20 || rem100 < 10) {\n    switch (rem100 % 10) {\n      case 1:\n        return number + 'st';\n\n      case 2:\n        return number + 'nd';\n\n      case 3:\n        return number + 'rd';\n    }\n  }\n\n  return number + 'th';\n}\n\nvar localize = {\n  ordinalNumber: ordinalNumber,\n  era: buildLocalizeFn({\n    values: eraValues,\n    defaultWidth: 'wide'\n  }),\n  quarter: buildLocalizeFn({\n    values: quarterValues,\n    defaultWidth: 'wide',\n    argumentCallback: function (quarter) {\n      return Number(quarter) - 1;\n    }\n  }),\n  month: buildLocalizeFn({\n    values: monthValues,\n    defaultWidth: 'wide'\n  }),\n  day: buildLocalizeFn({\n    values: dayValues,\n    defaultWidth: 'wide'\n  }),\n  dayPeriod: buildLocalizeFn({\n    values: dayPeriodValues,\n    defaultWidth: 'wide',\n    formattingValues: formattingDayPeriodValues,\n    defaultFormattingWidth: 'wide'\n  })\n};\nexport default localize;","import buildMatchPatternFn from '../../../_lib/buildMatchPatternFn/index.js';\nimport buildMatchFn from '../../../_lib/buildMatchFn/index.js';\nvar matchOrdinalNumberPattern = /^(\\d+)(th|st|nd|rd)?/i;\nvar parseOrdinalNumberPattern = /\\d+/i;\nvar matchEraPatterns = {\n  narrow: /^(b|a)/i,\n  abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n  wide: /^(before christ|before common era|anno domini|common era)/i\n};\nvar parseEraPatterns = {\n  any: [/^b/i, /^(a|c)/i]\n};\nvar matchQuarterPatterns = {\n  narrow: /^[1234]/i,\n  abbreviated: /^q[1234]/i,\n  wide: /^[1234](th|st|nd|rd)? quarter/i\n};\nvar parseQuarterPatterns = {\n  any: [/1/i, /2/i, /3/i, /4/i]\n};\nvar matchMonthPatterns = {\n  narrow: /^[jfmasond]/i,\n  abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n  wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i\n};\nvar parseMonthPatterns = {\n  narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],\n  any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i]\n};\nvar matchDayPatterns = {\n  narrow: /^[smtwf]/i,\n  short: /^(su|mo|tu|we|th|fr|sa)/i,\n  abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n  wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i\n};\nvar parseDayPatterns = {\n  narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n  any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]\n};\nvar matchDayPeriodPatterns = {\n  narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n  any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i\n};\nvar parseDayPeriodPatterns = {\n  any: {\n    am: /^a/i,\n    pm: /^p/i,\n    midnight: /^mi/i,\n    noon: /^no/i,\n    morning: /morning/i,\n    afternoon: /afternoon/i,\n    evening: /evening/i,\n    night: /night/i\n  }\n};\nvar match = {\n  ordinalNumber: buildMatchPatternFn({\n    matchPattern: matchOrdinalNumberPattern,\n    parsePattern: parseOrdinalNumberPattern,\n    valueCallback: function (value) {\n      return parseInt(value, 10);\n    }\n  }),\n  era: buildMatchFn({\n    matchPatterns: matchEraPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseEraPatterns,\n    defaultParseWidth: 'any'\n  }),\n  quarter: buildMatchFn({\n    matchPatterns: matchQuarterPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseQuarterPatterns,\n    defaultParseWidth: 'any',\n    valueCallback: function (index) {\n      return index + 1;\n    }\n  }),\n  month: buildMatchFn({\n    matchPatterns: matchMonthPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseMonthPatterns,\n    defaultParseWidth: 'any'\n  }),\n  day: buildMatchFn({\n    matchPatterns: matchDayPatterns,\n    defaultMatchWidth: 'wide',\n    parsePatterns: parseDayPatterns,\n    defaultParseWidth: 'any'\n  }),\n  dayPeriod: buildMatchFn({\n    matchPatterns: matchDayPeriodPatterns,\n    defaultMatchWidth: 'any',\n    parsePatterns: parseDayPeriodPatterns,\n    defaultParseWidth: 'any'\n  })\n};\nexport default match;","import formatDistance from './_lib/formatDistance/index.js';\nimport formatLong from './_lib/formatLong/index.js';\nimport formatRelative from './_lib/formatRelative/index.js';\nimport localize from './_lib/localize/index.js';\nimport match from './_lib/match/index.js';\n/**\n * @type {Locale}\n * @category Locales\n * @summary English locale (United States).\n * @language English\n * @iso-639-2 eng\n * @author Sasha Koss [@kossnocorp]{@link https://github.com/kossnocorp}\n * @author Lesha Koss [@leshakoss]{@link https://github.com/leshakoss}\n */\n\nvar locale = {\n  code: 'en-US',\n  formatDistance: formatDistance,\n  formatLong: formatLong,\n  formatRelative: formatRelative,\n  localize: localize,\n  match: match,\n  options: {\n    weekStartsOn: 0\n    /* Sunday */\n    ,\n    firstWeekContainsDate: 1\n  }\n};\nexport default locale;","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name max\n * @category Common Helpers\n * @summary Return the latest of the given dates.\n *\n * @description\n * Return the latest of the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - `max` function now accepts an array of dates rather than spread arguments.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   var date1 = new Date(1989, 6, 10)\n *   var date2 = new Date(1987, 1, 11)\n *   var maxDate = max(date1, date2)\n *\n *   // v2.0.0 onward:\n *   var dates = [new Date(1989, 6, 10), new Date(1987, 1, 11)]\n *   var maxDate = max(dates)\n *   ```\n *\n * @param {Date[]|Number[]} datesArray - the dates to compare\n * @returns {Date} the latest of the dates\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which of these dates is the latest?\n * var result = max([\n *   new Date(1989, 6, 10),\n *   new Date(1987, 1, 11),\n *   new Date(1995, 6, 2),\n *   new Date(1990, 0, 1)\n * ])\n * //=> Sun Jul 02 1995 00:00:00\n */\n\nexport default function max(dirtyDatesArray) {\n  requiredArgs(1, arguments);\n  var datesArray; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n\n  if (dirtyDatesArray && typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array.\n  } else if (typeof dirtyDatesArray === 'object' && dirtyDatesArray !== null) {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  } else {\n    // `dirtyDatesArray` is non-iterable, return Invalid Date\n    return new Date(NaN);\n  }\n\n  var result;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (result === undefined || result < currentDate || isNaN(currentDate)) {\n      result = currentDate;\n    }\n  });\n  return result || new Date(NaN);\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name min\n * @category Common Helpers\n * @summary Return the earliest of the given dates.\n *\n * @description\n * Return the earliest of the given dates.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - `min` function now accepts an array of dates rather than spread arguments.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   var date1 = new Date(1989, 6, 10)\n *   var date2 = new Date(1987, 1, 11)\n *   var minDate = min(date1, date2)\n *\n *   // v2.0.0 onward:\n *   var dates = [new Date(1989, 6, 10), new Date(1987, 1, 11)]\n *   var minDate = min(dates)\n *   ```\n *\n * @param {Date[]|Number[]} datesArray - the dates to compare\n * @returns {Date} the earliest of the dates\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which of these dates is the earliest?\n * var result = min([\n *   new Date(1989, 6, 10),\n *   new Date(1987, 1, 11),\n *   new Date(1995, 6, 2),\n *   new Date(1990, 0, 1)\n * ])\n * //=> Wed Feb 11 1987 00:00:00\n */\n\nexport default function min(dirtyDatesArray) {\n  requiredArgs(1, arguments);\n  var datesArray; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method\n\n  if (dirtyDatesArray && typeof dirtyDatesArray.forEach === 'function') {\n    datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array.\n  } else if (typeof dirtyDatesArray === 'object' && dirtyDatesArray !== null) {\n    datesArray = Array.prototype.slice.call(dirtyDatesArray);\n  } else {\n    // `dirtyDatesArray` is non-iterable, return Invalid Date\n    return new Date(NaN);\n  }\n\n  var result;\n  datesArray.forEach(function (dirtyDate) {\n    var currentDate = toDate(dirtyDate);\n\n    if (result === undefined || result > currentDate || isNaN(currentDate)) {\n      result = currentDate;\n    }\n  });\n  return result || new Date(NaN);\n}","import getUTCWeekYear from '../../../_lib/getUTCWeekYear/index.js';\nimport setUTCDay from '../../../_lib/setUTCDay/index.js';\nimport setUTCISODay from '../../../_lib/setUTCISODay/index.js';\nimport setUTCISOWeek from '../../../_lib/setUTCISOWeek/index.js';\nimport setUTCWeek from '../../../_lib/setUTCWeek/index.js';\nimport startOfUTCISOWeek from '../../../_lib/startOfUTCISOWeek/index.js';\nimport startOfUTCWeek from '../../../_lib/startOfUTCWeek/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar MILLISECONDS_IN_SECOND = 1000;\nvar numericPatterns = {\n  month: /^(1[0-2]|0?\\d)/,\n  // 0 to 12\n  date: /^(3[0-1]|[0-2]?\\d)/,\n  // 0 to 31\n  dayOfYear: /^(36[0-6]|3[0-5]\\d|[0-2]?\\d?\\d)/,\n  // 0 to 366\n  week: /^(5[0-3]|[0-4]?\\d)/,\n  // 0 to 53\n  hour23h: /^(2[0-3]|[0-1]?\\d)/,\n  // 0 to 23\n  hour24h: /^(2[0-4]|[0-1]?\\d)/,\n  // 0 to 24\n  hour11h: /^(1[0-1]|0?\\d)/,\n  // 0 to 11\n  hour12h: /^(1[0-2]|0?\\d)/,\n  // 0 to 12\n  minute: /^[0-5]?\\d/,\n  // 0 to 59\n  second: /^[0-5]?\\d/,\n  // 0 to 59\n  singleDigit: /^\\d/,\n  // 0 to 9\n  twoDigits: /^\\d{1,2}/,\n  // 0 to 99\n  threeDigits: /^\\d{1,3}/,\n  // 0 to 999\n  fourDigits: /^\\d{1,4}/,\n  // 0 to 9999\n  anyDigitsSigned: /^-?\\d+/,\n  singleDigitSigned: /^-?\\d/,\n  // 0 to 9, -0 to -9\n  twoDigitsSigned: /^-?\\d{1,2}/,\n  // 0 to 99, -0 to -99\n  threeDigitsSigned: /^-?\\d{1,3}/,\n  // 0 to 999, -0 to -999\n  fourDigitsSigned: /^-?\\d{1,4}/ // 0 to 9999, -0 to -9999\n\n};\nvar timezonePatterns = {\n  basicOptionalMinutes: /^([+-])(\\d{2})(\\d{2})?|Z/,\n  basic: /^([+-])(\\d{2})(\\d{2})|Z/,\n  basicOptionalSeconds: /^([+-])(\\d{2})(\\d{2})((\\d{2}))?|Z/,\n  extended: /^([+-])(\\d{2}):(\\d{2})|Z/,\n  extendedOptionalSeconds: /^([+-])(\\d{2}):(\\d{2})(:(\\d{2}))?|Z/\n};\n\nfunction parseNumericPattern(pattern, string, valueCallback) {\n  var matchResult = string.match(pattern);\n\n  if (!matchResult) {\n    return null;\n  }\n\n  var value = parseInt(matchResult[0], 10);\n  return {\n    value: valueCallback ? valueCallback(value) : value,\n    rest: string.slice(matchResult[0].length)\n  };\n}\n\nfunction parseTimezonePattern(pattern, string) {\n  var matchResult = string.match(pattern);\n\n  if (!matchResult) {\n    return null;\n  } // Input is 'Z'\n\n\n  if (matchResult[0] === 'Z') {\n    return {\n      value: 0,\n      rest: string.slice(1)\n    };\n  }\n\n  var sign = matchResult[1] === '+' ? 1 : -1;\n  var hours = matchResult[2] ? parseInt(matchResult[2], 10) : 0;\n  var minutes = matchResult[3] ? parseInt(matchResult[3], 10) : 0;\n  var seconds = matchResult[5] ? parseInt(matchResult[5], 10) : 0;\n  return {\n    value: sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * MILLISECONDS_IN_SECOND),\n    rest: string.slice(matchResult[0].length)\n  };\n}\n\nfunction parseAnyDigitsSigned(string, valueCallback) {\n  return parseNumericPattern(numericPatterns.anyDigitsSigned, string, valueCallback);\n}\n\nfunction parseNDigits(n, string, valueCallback) {\n  switch (n) {\n    case 1:\n      return parseNumericPattern(numericPatterns.singleDigit, string, valueCallback);\n\n    case 2:\n      return parseNumericPattern(numericPatterns.twoDigits, string, valueCallback);\n\n    case 3:\n      return parseNumericPattern(numericPatterns.threeDigits, string, valueCallback);\n\n    case 4:\n      return parseNumericPattern(numericPatterns.fourDigits, string, valueCallback);\n\n    default:\n      return parseNumericPattern(new RegExp('^\\\\d{1,' + n + '}'), string, valueCallback);\n  }\n}\n\nfunction parseNDigitsSigned(n, string, valueCallback) {\n  switch (n) {\n    case 1:\n      return parseNumericPattern(numericPatterns.singleDigitSigned, string, valueCallback);\n\n    case 2:\n      return parseNumericPattern(numericPatterns.twoDigitsSigned, string, valueCallback);\n\n    case 3:\n      return parseNumericPattern(numericPatterns.threeDigitsSigned, string, valueCallback);\n\n    case 4:\n      return parseNumericPattern(numericPatterns.fourDigitsSigned, string, valueCallback);\n\n    default:\n      return parseNumericPattern(new RegExp('^-?\\\\d{1,' + n + '}'), string, valueCallback);\n  }\n}\n\nfunction dayPeriodEnumToHours(enumValue) {\n  switch (enumValue) {\n    case 'morning':\n      return 4;\n\n    case 'evening':\n      return 17;\n\n    case 'pm':\n    case 'noon':\n    case 'afternoon':\n      return 12;\n\n    case 'am':\n    case 'midnight':\n    case 'night':\n    default:\n      return 0;\n  }\n}\n\nfunction normalizeTwoDigitYear(twoDigitYear, currentYear) {\n  var isCommonEra = currentYear > 0; // Absolute number of the current year:\n  // 1 -> 1 AC\n  // 0 -> 1 BC\n  // -1 -> 2 BC\n\n  var absCurrentYear = isCommonEra ? currentYear : 1 - currentYear;\n  var result;\n\n  if (absCurrentYear <= 50) {\n    result = twoDigitYear || 100;\n  } else {\n    var rangeEnd = absCurrentYear + 50;\n    var rangeEndCentury = Math.floor(rangeEnd / 100) * 100;\n    var isPreviousCentury = twoDigitYear >= rangeEnd % 100;\n    result = twoDigitYear + rangeEndCentury - (isPreviousCentury ? 100 : 0);\n  }\n\n  return isCommonEra ? result : 1 - result;\n}\n\nvar DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nvar DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // User for validation\n\nfunction isLeapYearIndex(year) {\n  return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}\n/*\n * |     | Unit                           |     | Unit                           |\n * |-----|--------------------------------|-----|--------------------------------|\n * |  a  | AM, PM                         |  A* | Milliseconds in day            |\n * |  b  | AM, PM, noon, midnight         |  B  | Flexible day period            |\n * |  c  | Stand-alone local day of week  |  C* | Localized hour w/ day period   |\n * |  d  | Day of month                   |  D  | Day of year                    |\n * |  e  | Local day of week              |  E  | Day of week                    |\n * |  f  |                                |  F* | Day of week in month           |\n * |  g* | Modified Julian day            |  G  | Era                            |\n * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |\n * |  i! | ISO day of week                |  I! | ISO week of year               |\n * |  j* | Localized hour w/ day period   |  J* | Localized hour w/o day period  |\n * |  k  | Hour [1-24]                    |  K  | Hour [0-11]                    |\n * |  l* | (deprecated)                   |  L  | Stand-alone month              |\n * |  m  | Minute                         |  M  | Month                          |\n * |  n  |                                |  N  |                                |\n * |  o! | Ordinal number modifier        |  O* | Timezone (GMT)                 |\n * |  p  |                                |  P  |                                |\n * |  q  | Stand-alone quarter            |  Q  | Quarter                        |\n * |  r* | Related Gregorian year         |  R! | ISO week-numbering year        |\n * |  s  | Second                         |  S  | Fraction of second             |\n * |  t! | Seconds timestamp              |  T! | Milliseconds timestamp         |\n * |  u  | Extended year                  |  U* | Cyclic year                    |\n * |  v* | Timezone (generic non-locat.)  |  V* | Timezone (location)            |\n * |  w  | Local week of year             |  W* | Week of month                  |\n * |  x  | Timezone (ISO-8601 w/o Z)      |  X  | Timezone (ISO-8601)            |\n * |  y  | Year (abs)                     |  Y  | Local week-numbering year      |\n * |  z* | Timezone (specific non-locat.) |  Z* | Timezone (aliases)             |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n *\n * Letters marked by ! are non-standard, but implemented by date-fns:\n * - `o` modifies the previous token to turn it into an ordinal (see `parse` docs)\n * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n *   i.e. 7 for Sunday, 1 for Monday, etc.\n * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n *   `R` is supposed to be used in conjunction with `I` and `i`\n *   for universal ISO week-numbering date, whereas\n *   `Y` is supposed to be used in conjunction with `w` and `e`\n *   for week-numbering date specific to the locale.\n */\n\n\nvar parsers = {\n  // Era\n  G: {\n    priority: 140,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // AD, BC\n        case 'G':\n        case 'GG':\n        case 'GGG':\n          return match.era(string, {\n            width: 'abbreviated'\n          }) || match.era(string, {\n            width: 'narrow'\n          });\n        // A, B\n\n        case 'GGGGG':\n          return match.era(string, {\n            width: 'narrow'\n          });\n        // Anno Domini, Before Christ\n\n        case 'GGGG':\n        default:\n          return match.era(string, {\n            width: 'wide'\n          }) || match.era(string, {\n            width: 'abbreviated'\n          }) || match.era(string, {\n            width: 'narrow'\n          });\n      }\n    },\n    set: function (date, flags, value, _options) {\n      flags.era = value;\n      date.setUTCFullYear(value, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['R', 'u', 't', 'T']\n  },\n  // Year\n  y: {\n    // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns\n    // | Year     |     y | yy |   yyy |  yyyy | yyyyy |\n    // |----------|-------|----|-------|-------|-------|\n    // | AD 1     |     1 | 01 |   001 |  0001 | 00001 |\n    // | AD 12    |    12 | 12 |   012 |  0012 | 00012 |\n    // | AD 123   |   123 | 23 |   123 |  0123 | 00123 |\n    // | AD 1234  |  1234 | 34 |  1234 |  1234 | 01234 |\n    // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n    priority: 130,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (year) {\n        return {\n          year: year,\n          isTwoDigitYear: token === 'yy'\n        };\n      };\n\n      switch (token) {\n        case 'y':\n          return parseNDigits(4, string, valueCallback);\n\n        case 'yo':\n          return match.ordinalNumber(string, {\n            unit: 'year',\n            valueCallback: valueCallback\n          });\n\n        default:\n          return parseNDigits(token.length, string, valueCallback);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value.isTwoDigitYear || value.year > 0;\n    },\n    set: function (date, flags, value, _options) {\n      var currentYear = date.getUTCFullYear();\n\n      if (value.isTwoDigitYear) {\n        var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n        date.setUTCFullYear(normalizedTwoDigitYear, 0, 1);\n        date.setUTCHours(0, 0, 0, 0);\n        return date;\n      }\n\n      var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n      date.setUTCFullYear(year, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'u', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local week-numbering year\n  Y: {\n    priority: 130,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (year) {\n        return {\n          year: year,\n          isTwoDigitYear: token === 'YY'\n        };\n      };\n\n      switch (token) {\n        case 'Y':\n          return parseNDigits(4, string, valueCallback);\n\n        case 'Yo':\n          return match.ordinalNumber(string, {\n            unit: 'year',\n            valueCallback: valueCallback\n          });\n\n        default:\n          return parseNDigits(token.length, string, valueCallback);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value.isTwoDigitYear || value.year > 0;\n    },\n    set: function (date, flags, value, options) {\n      var currentYear = getUTCWeekYear(date, options);\n\n      if (value.isTwoDigitYear) {\n        var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n        date.setUTCFullYear(normalizedTwoDigitYear, 0, options.firstWeekContainsDate);\n        date.setUTCHours(0, 0, 0, 0);\n        return startOfUTCWeek(date, options);\n      }\n\n      var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n      date.setUTCFullYear(year, 0, options.firstWeekContainsDate);\n      date.setUTCHours(0, 0, 0, 0);\n      return startOfUTCWeek(date, options);\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'Q', 'q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n  },\n  // ISO week-numbering year\n  R: {\n    priority: 130,\n    parse: function (string, token, _match, _options) {\n      if (token === 'R') {\n        return parseNDigitsSigned(4, string);\n      }\n\n      return parseNDigitsSigned(token.length, string);\n    },\n    set: function (_date, _flags, value, _options) {\n      var firstWeekOfYear = new Date(0);\n      firstWeekOfYear.setUTCFullYear(value, 0, 4);\n      firstWeekOfYear.setUTCHours(0, 0, 0, 0);\n      return startOfUTCISOWeek(firstWeekOfYear);\n    },\n    incompatibleTokens: ['G', 'y', 'Y', 'u', 'Q', 'q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n  },\n  // Extended year\n  u: {\n    priority: 130,\n    parse: function (string, token, _match, _options) {\n      if (token === 'u') {\n        return parseNDigitsSigned(4, string);\n      }\n\n      return parseNDigitsSigned(token.length, string);\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCFullYear(value, 0, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['G', 'y', 'Y', 'R', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n  },\n  // Quarter\n  Q: {\n    priority: 120,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // 1, 2, 3, 4\n        case 'Q':\n        case 'QQ':\n          // 01, 02, 03, 04\n          return parseNDigits(token.length, string);\n        // 1st, 2nd, 3rd, 4th\n\n        case 'Qo':\n          return match.ordinalNumber(string, {\n            unit: 'quarter'\n          });\n        // Q1, Q2, Q3, Q4\n\n        case 'QQQ':\n          return match.quarter(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n        case 'QQQQQ':\n          return match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // 1st quarter, 2nd quarter, ...\n\n        case 'QQQQ':\n        default:\n          return match.quarter(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 4;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth((value - 1) * 3, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Stand-alone quarter\n  q: {\n    priority: 120,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // 1, 2, 3, 4\n        case 'q':\n        case 'qq':\n          // 01, 02, 03, 04\n          return parseNDigits(token.length, string);\n        // 1st, 2nd, 3rd, 4th\n\n        case 'qo':\n          return match.ordinalNumber(string, {\n            unit: 'quarter'\n          });\n        // Q1, Q2, Q3, Q4\n\n        case 'qqq':\n          return match.quarter(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n        case 'qqqqq':\n          return match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // 1st quarter, 2nd quarter, ...\n\n        case 'qqqq':\n        default:\n          return match.quarter(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.quarter(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 4;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth((value - 1) * 3, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'Q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Month\n  M: {\n    priority: 110,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        return value - 1;\n      };\n\n      switch (token) {\n        // 1, 2, ..., 12\n        case 'M':\n          return parseNumericPattern(numericPatterns.month, string, valueCallback);\n        // 01, 02, ..., 12\n\n        case 'MM':\n          return parseNDigits(2, string, valueCallback);\n        // 1st, 2nd, ..., 12th\n\n        case 'Mo':\n          return match.ordinalNumber(string, {\n            unit: 'month',\n            valueCallback: valueCallback\n          });\n        // Jan, Feb, ..., Dec\n\n        case 'MMM':\n          return match.month(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // J, F, ..., D\n\n        case 'MMMMM':\n          return match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // January, February, ..., December\n\n        case 'MMMM':\n        default:\n          return match.month(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(value, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'L', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Stand-alone month\n  L: {\n    priority: 110,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        return value - 1;\n      };\n\n      switch (token) {\n        // 1, 2, ..., 12\n        case 'L':\n          return parseNumericPattern(numericPatterns.month, string, valueCallback);\n        // 01, 02, ..., 12\n\n        case 'LL':\n          return parseNDigits(2, string, valueCallback);\n        // 1st, 2nd, ..., 12th\n\n        case 'Lo':\n          return match.ordinalNumber(string, {\n            unit: 'month',\n            valueCallback: valueCallback\n          });\n        // Jan, Feb, ..., Dec\n\n        case 'LLL':\n          return match.month(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // J, F, ..., D\n\n        case 'LLLLL':\n          return match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // January, February, ..., December\n\n        case 'LLLL':\n        default:\n          return match.month(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.month(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(value, 1);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local week of year\n  w: {\n    priority: 100,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'w':\n          return parseNumericPattern(numericPatterns.week, string);\n\n        case 'wo':\n          return match.ordinalNumber(string, {\n            unit: 'week'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 53;\n    },\n    set: function (date, _flags, value, options) {\n      return startOfUTCWeek(setUTCWeek(date, value, options), options);\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n  },\n  // ISO week of year\n  I: {\n    priority: 100,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'I':\n          return parseNumericPattern(numericPatterns.week, string);\n\n        case 'Io':\n          return match.ordinalNumber(string, {\n            unit: 'week'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 53;\n    },\n    set: function (date, _flags, value, options) {\n      return startOfUTCISOWeek(setUTCISOWeek(date, value, options), options);\n    },\n    incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n  },\n  // Day of the month\n  d: {\n    priority: 90,\n    subPriority: 1,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'd':\n          return parseNumericPattern(numericPatterns.date, string);\n\n        case 'do':\n          return match.ordinalNumber(string, {\n            unit: 'date'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (date, value, _options) {\n      var year = date.getUTCFullYear();\n      var isLeapYear = isLeapYearIndex(year);\n      var month = date.getUTCMonth();\n\n      if (isLeapYear) {\n        return value >= 1 && value <= DAYS_IN_MONTH_LEAP_YEAR[month];\n      } else {\n        return value >= 1 && value <= DAYS_IN_MONTH[month];\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCDate(value);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Day of year\n  D: {\n    priority: 90,\n    subPriority: 1,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'D':\n        case 'DD':\n          return parseNumericPattern(numericPatterns.dayOfYear, string);\n\n        case 'Do':\n          return match.ordinalNumber(string, {\n            unit: 'date'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (date, value, _options) {\n      var year = date.getUTCFullYear();\n      var isLeapYear = isLeapYearIndex(year);\n\n      if (isLeapYear) {\n        return value >= 1 && value <= 366;\n      } else {\n        return value >= 1 && value <= 365;\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMonth(0, value);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'L', 'w', 'I', 'd', 'E', 'i', 'e', 'c', 't', 'T']\n  },\n  // Day of week\n  E: {\n    priority: 90,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        // Tue\n        case 'E':\n        case 'EE':\n        case 'EEE':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // T\n\n        case 'EEEEE':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tu\n\n        case 'EEEEEE':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tuesday\n\n        case 'EEEE':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['D', 'i', 'e', 'c', 't', 'T']\n  },\n  // Local day of week\n  e: {\n    priority: 90,\n    parse: function (string, token, match, options) {\n      var valueCallback = function (value) {\n        var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n        return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n      };\n\n      switch (token) {\n        // 3\n        case 'e':\n        case 'ee':\n          // 03\n          return parseNDigits(token.length, string, valueCallback);\n        // 3rd\n\n        case 'eo':\n          return match.ordinalNumber(string, {\n            unit: 'day',\n            valueCallback: valueCallback\n          });\n        // Tue\n\n        case 'eee':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // T\n\n        case 'eeeee':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tu\n\n        case 'eeeeee':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n        // Tuesday\n\n        case 'eeee':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'c', 't', 'T']\n  },\n  // Stand-alone local day of week\n  c: {\n    priority: 90,\n    parse: function (string, token, match, options) {\n      var valueCallback = function (value) {\n        var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n        return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n      };\n\n      switch (token) {\n        // 3\n        case 'c':\n        case 'cc':\n          // 03\n          return parseNDigits(token.length, string, valueCallback);\n        // 3rd\n\n        case 'co':\n          return match.ordinalNumber(string, {\n            unit: 'day',\n            valueCallback: valueCallback\n          });\n        // Tue\n\n        case 'ccc':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // T\n\n        case 'ccccc':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // Tu\n\n        case 'cccccc':\n          return match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n        // Tuesday\n\n        case 'cccc':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'short',\n            context: 'standalone'\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'standalone'\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 6;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCDay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'e', 't', 'T']\n  },\n  // ISO day of week\n  i: {\n    priority: 90,\n    parse: function (string, token, match, _options) {\n      var valueCallback = function (value) {\n        if (value === 0) {\n          return 7;\n        }\n\n        return value;\n      };\n\n      switch (token) {\n        // 2\n        case 'i':\n        case 'ii':\n          // 02\n          return parseNDigits(token.length, string);\n        // 2nd\n\n        case 'io':\n          return match.ordinalNumber(string, {\n            unit: 'day'\n          });\n        // Tue\n\n        case 'iii':\n          return match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // T\n\n        case 'iiiii':\n          return match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // Tu\n\n        case 'iiiiii':\n          return match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n        // Tuesday\n\n        case 'iiii':\n        default:\n          return match.day(string, {\n            width: 'wide',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'abbreviated',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'short',\n            context: 'formatting',\n            valueCallback: valueCallback\n          }) || match.day(string, {\n            width: 'narrow',\n            context: 'formatting',\n            valueCallback: valueCallback\n          });\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 7;\n    },\n    set: function (date, _flags, value, options) {\n      date = setUTCISODay(date, value, options);\n      date.setUTCHours(0, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'E', 'e', 'c', 't', 'T']\n  },\n  // AM or PM\n  a: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'a':\n        case 'aa':\n        case 'aaa':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'aaaaa':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'aaaa':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['b', 'B', 'H', 'K', 'k', 't', 'T']\n  },\n  // AM, PM, midnight\n  b: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'b':\n        case 'bb':\n        case 'bbb':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'bbbbb':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'bbbb':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'B', 'H', 'K', 'k', 't', 'T']\n  },\n  // in the morning, in the afternoon, in the evening, at night\n  B: {\n    priority: 80,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'B':\n        case 'BB':\n        case 'BBB':\n          return match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'BBBBB':\n          return match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n\n        case 'BBBB':\n        default:\n          return match.dayPeriod(string, {\n            width: 'wide',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'abbreviated',\n            context: 'formatting'\n          }) || match.dayPeriod(string, {\n            width: 'narrow',\n            context: 'formatting'\n          });\n      }\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 't', 'T']\n  },\n  // Hour [1-12]\n  h: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'h':\n          return parseNumericPattern(numericPatterns.hour12h, string);\n\n        case 'ho':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 12;\n    },\n    set: function (date, _flags, value, _options) {\n      var isPM = date.getUTCHours() >= 12;\n\n      if (isPM && value < 12) {\n        date.setUTCHours(value + 12, 0, 0, 0);\n      } else if (!isPM && value === 12) {\n        date.setUTCHours(0, 0, 0, 0);\n      } else {\n        date.setUTCHours(value, 0, 0, 0);\n      }\n\n      return date;\n    },\n    incompatibleTokens: ['H', 'K', 'k', 't', 'T']\n  },\n  // Hour [0-23]\n  H: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'H':\n          return parseNumericPattern(numericPatterns.hour23h, string);\n\n        case 'Ho':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 23;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCHours(value, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'K', 'k', 't', 'T']\n  },\n  // Hour [0-11]\n  K: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'K':\n          return parseNumericPattern(numericPatterns.hour11h, string);\n\n        case 'Ko':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 11;\n    },\n    set: function (date, _flags, value, _options) {\n      var isPM = date.getUTCHours() >= 12;\n\n      if (isPM && value < 12) {\n        date.setUTCHours(value + 12, 0, 0, 0);\n      } else {\n        date.setUTCHours(value, 0, 0, 0);\n      }\n\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'H', 'k', 't', 'T']\n  },\n  // Hour [1-24]\n  k: {\n    priority: 70,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'k':\n          return parseNumericPattern(numericPatterns.hour24h, string);\n\n        case 'ko':\n          return match.ordinalNumber(string, {\n            unit: 'hour'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 1 && value <= 24;\n    },\n    set: function (date, _flags, value, _options) {\n      var hours = value <= 24 ? value % 24 : value;\n      date.setUTCHours(hours, 0, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['a', 'b', 'h', 'H', 'K', 't', 'T']\n  },\n  // Minute\n  m: {\n    priority: 60,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 'm':\n          return parseNumericPattern(numericPatterns.minute, string);\n\n        case 'mo':\n          return match.ordinalNumber(string, {\n            unit: 'minute'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 59;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMinutes(value, 0, 0);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Second\n  s: {\n    priority: 50,\n    parse: function (string, token, match, _options) {\n      switch (token) {\n        case 's':\n          return parseNumericPattern(numericPatterns.second, string);\n\n        case 'so':\n          return match.ordinalNumber(string, {\n            unit: 'second'\n          });\n\n        default:\n          return parseNDigits(token.length, string);\n      }\n    },\n    validate: function (_date, value, _options) {\n      return value >= 0 && value <= 59;\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCSeconds(value, 0);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Fraction of second\n  S: {\n    priority: 30,\n    parse: function (string, token, _match, _options) {\n      var valueCallback = function (value) {\n        return Math.floor(value * Math.pow(10, -token.length + 3));\n      };\n\n      return parseNDigits(token.length, string, valueCallback);\n    },\n    set: function (date, _flags, value, _options) {\n      date.setUTCMilliseconds(value);\n      return date;\n    },\n    incompatibleTokens: ['t', 'T']\n  },\n  // Timezone (ISO-8601. +00:00 is `'Z'`)\n  X: {\n    priority: 10,\n    parse: function (string, token, _match, _options) {\n      switch (token) {\n        case 'X':\n          return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n        case 'XX':\n          return parseTimezonePattern(timezonePatterns.basic, string);\n\n        case 'XXXX':\n          return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n        case 'XXXXX':\n          return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n        case 'XXX':\n        default:\n          return parseTimezonePattern(timezonePatterns.extended, string);\n      }\n    },\n    set: function (date, flags, value, _options) {\n      if (flags.timestampIsSet) {\n        return date;\n      }\n\n      return new Date(date.getTime() - value);\n    },\n    incompatibleTokens: ['t', 'T', 'x']\n  },\n  // Timezone (ISO-8601)\n  x: {\n    priority: 10,\n    parse: function (string, token, _match, _options) {\n      switch (token) {\n        case 'x':\n          return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n        case 'xx':\n          return parseTimezonePattern(timezonePatterns.basic, string);\n\n        case 'xxxx':\n          return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n        case 'xxxxx':\n          return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n        case 'xxx':\n        default:\n          return parseTimezonePattern(timezonePatterns.extended, string);\n      }\n    },\n    set: function (date, flags, value, _options) {\n      if (flags.timestampIsSet) {\n        return date;\n      }\n\n      return new Date(date.getTime() - value);\n    },\n    incompatibleTokens: ['t', 'T', 'X']\n  },\n  // Seconds timestamp\n  t: {\n    priority: 40,\n    parse: function (string, _token, _match, _options) {\n      return parseAnyDigitsSigned(string);\n    },\n    set: function (_date, _flags, value, _options) {\n      return [new Date(value * 1000), {\n        timestampIsSet: true\n      }];\n    },\n    incompatibleTokens: '*'\n  },\n  // Milliseconds timestamp\n  T: {\n    priority: 20,\n    parse: function (string, _token, _match, _options) {\n      return parseAnyDigitsSigned(string);\n    },\n    set: function (_date, _flags, value, _options) {\n      return [new Date(value), {\n        timestampIsSet: true\n      }];\n    },\n    incompatibleTokens: '*'\n  }\n};\nexport default parsers;","import defaultLocale from '../locale/en-US/index.js';\nimport subMilliseconds from '../subMilliseconds/index.js';\nimport toDate from '../toDate/index.js';\nimport assign from '../_lib/assign/index.js';\nimport longFormatters from '../_lib/format/longFormatters/index.js';\nimport getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';\nimport { isProtectedDayOfYearToken, isProtectedWeekYearToken, throwProtectedError } from '../_lib/protectedTokens/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport parsers from './_lib/parsers/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar TIMEZONE_UNIT_PRIORITY = 10; // This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n//   (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n//   except a single quote symbol, which ends the sequence.\n//   Two quote characters do not end the sequence.\n//   If there is no matching single quote\n//   then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\n\nvar longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar notWhitespaceRegExp = /\\S/;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name parse\n * @category Common Helpers\n * @summary Parse the date.\n *\n * @description\n * Return the date parsed from string using the given format string.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters in the format string wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the format string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 5 below the table).\n *\n * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited\n * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:\n *\n * ```javascript\n * parse('23 AM', 'HH a', new Date())\n * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time\n * ```\n *\n * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true\n *\n * Accepted format string patterns:\n * | Unit                            |Prior| Pattern | Result examples                   | Notes |\n * |---------------------------------|-----|---------|-----------------------------------|-------|\n * | Era                             | 140 | G..GGG  | AD, BC                            |       |\n * |                                 |     | GGGG    | Anno Domini, Before Christ        | 2     |\n * |                                 |     | GGGGG   | A, B                              |       |\n * | Calendar year                   | 130 | y       | 44, 1, 1900, 2017, 9999           | 4     |\n * |                                 |     | yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | yy      | 44, 01, 00, 17                    | 4     |\n * |                                 |     | yyy     | 044, 001, 123, 999                | 4     |\n * |                                 |     | yyyy    | 0044, 0001, 1900, 2017            | 4     |\n * |                                 |     | yyyyy   | ...                               | 2,4   |\n * | Local week-numbering year       | 130 | Y       | 44, 1, 1900, 2017, 9000           | 4     |\n * |                                 |     | Yo      | 44th, 1st, 1900th, 9999999th      | 4,5   |\n * |                                 |     | YY      | 44, 01, 00, 17                    | 4,6   |\n * |                                 |     | YYY     | 044, 001, 123, 999                | 4     |\n * |                                 |     | YYYY    | 0044, 0001, 1900, 2017            | 4,6   |\n * |                                 |     | YYYYY   | ...                               | 2,4   |\n * | ISO week-numbering year         | 130 | R       | -43, 1, 1900, 2017, 9999, -9999   | 4,5   |\n * |                                 |     | RR      | -43, 01, 00, 17                   | 4,5   |\n * |                                 |     | RRR     | -043, 001, 123, 999, -999         | 4,5   |\n * |                                 |     | RRRR    | -0043, 0001, 2017, 9999, -9999    | 4,5   |\n * |                                 |     | RRRRR   | ...                               | 2,4,5 |\n * | Extended year                   | 130 | u       | -43, 1, 1900, 2017, 9999, -999    | 4     |\n * |                                 |     | uu      | -43, 01, 99, -99                  | 4     |\n * |                                 |     | uuu     | -043, 001, 123, 999, -999         | 4     |\n * |                                 |     | uuuu    | -0043, 0001, 2017, 9999, -9999    | 4     |\n * |                                 |     | uuuuu   | ...                               | 2,4   |\n * | Quarter (formatting)            | 120 | Q       | 1, 2, 3, 4                        |       |\n * |                                 |     | Qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | QQ      | 01, 02, 03, 04                    |       |\n * |                                 |     | QQQ     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | QQQQQ   | 1, 2, 3, 4                        | 4     |\n * | Quarter (stand-alone)           | 120 | q       | 1, 2, 3, 4                        |       |\n * |                                 |     | qo      | 1st, 2nd, 3rd, 4th                | 5     |\n * |                                 |     | qq      | 01, 02, 03, 04                    |       |\n * |                                 |     | qqq     | Q1, Q2, Q3, Q4                    |       |\n * |                                 |     | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |\n * |                                 |     | qqqqq   | 1, 2, 3, 4                        | 3     |\n * | Month (formatting)              | 110 | M       | 1, 2, ..., 12                     |       |\n * |                                 |     | Mo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | MM      | 01, 02, ..., 12                   |       |\n * |                                 |     | MMM     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | MMMM    | January, February, ..., December  | 2     |\n * |                                 |     | MMMMM   | J, F, ..., D                      |       |\n * | Month (stand-alone)             | 110 | L       | 1, 2, ..., 12                     |       |\n * |                                 |     | Lo      | 1st, 2nd, ..., 12th               | 5     |\n * |                                 |     | LL      | 01, 02, ..., 12                   |       |\n * |                                 |     | LLL     | Jan, Feb, ..., Dec                |       |\n * |                                 |     | LLLL    | January, February, ..., December  | 2     |\n * |                                 |     | LLLLL   | J, F, ..., D                      |       |\n * | Local week of year              | 100 | w       | 1, 2, ..., 53                     |       |\n * |                                 |     | wo      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | ww      | 01, 02, ..., 53                   |       |\n * | ISO week of year                | 100 | I       | 1, 2, ..., 53                     | 5     |\n * |                                 |     | Io      | 1st, 2nd, ..., 53th               | 5     |\n * |                                 |     | II      | 01, 02, ..., 53                   | 5     |\n * | Day of month                    |  90 | d       | 1, 2, ..., 31                     |       |\n * |                                 |     | do      | 1st, 2nd, ..., 31st               | 5     |\n * |                                 |     | dd      | 01, 02, ..., 31                   |       |\n * | Day of year                     |  90 | D       | 1, 2, ..., 365, 366               | 7     |\n * |                                 |     | Do      | 1st, 2nd, ..., 365th, 366th       | 5     |\n * |                                 |     | DD      | 01, 02, ..., 365, 366             | 7     |\n * |                                 |     | DDD     | 001, 002, ..., 365, 366           |       |\n * |                                 |     | DDDD    | ...                               | 2     |\n * | Day of week (formatting)        |  90 | E..EEE  | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | EEEEE   | M, T, W, T, F, S, S               |       |\n * |                                 |     | EEEEEE  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | ISO day of week (formatting)    |  90 | i       | 1, 2, 3, ..., 7                   | 5     |\n * |                                 |     | io      | 1st, 2nd, ..., 7th                | 5     |\n * |                                 |     | ii      | 01, 02, ..., 07                   | 5     |\n * |                                 |     | iii     | Mon, Tue, Wed, ..., Su            | 5     |\n * |                                 |     | iiii    | Monday, Tuesday, ..., Sunday      | 2,5   |\n * |                                 |     | iiiii   | M, T, W, T, F, S, S               | 5     |\n * |                                 |     | iiiiii  | Mo, Tu, We, Th, Fr, Su, Sa        | 5     |\n * | Local day of week (formatting)  |  90 | e       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | eo      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | ee      | 02, 03, ..., 01                   |       |\n * |                                 |     | eee     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | eeee    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | eeeee   | M, T, W, T, F, S, S               |       |\n * |                                 |     | eeeeee  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | Local day of week (stand-alone) |  90 | c       | 2, 3, 4, ..., 1                   |       |\n * |                                 |     | co      | 2nd, 3rd, ..., 1st                | 5     |\n * |                                 |     | cc      | 02, 03, ..., 01                   |       |\n * |                                 |     | ccc     | Mon, Tue, Wed, ..., Su            |       |\n * |                                 |     | cccc    | Monday, Tuesday, ..., Sunday      | 2     |\n * |                                 |     | ccccc   | M, T, W, T, F, S, S               |       |\n * |                                 |     | cccccc  | Mo, Tu, We, Th, Fr, Su, Sa        |       |\n * | AM, PM                          |  80 | a..aaa  | AM, PM                            |       |\n * |                                 |     | aaaa    | a.m., p.m.                        | 2     |\n * |                                 |     | aaaaa   | a, p                              |       |\n * | AM, PM, noon, midnight          |  80 | b..bbb  | AM, PM, noon, midnight            |       |\n * |                                 |     | bbbb    | a.m., p.m., noon, midnight        | 2     |\n * |                                 |     | bbbbb   | a, p, n, mi                       |       |\n * | Flexible day period             |  80 | B..BBB  | at night, in the morning, ...     |       |\n * |                                 |     | BBBB    | at night, in the morning, ...     | 2     |\n * |                                 |     | BBBBB   | at night, in the morning, ...     |       |\n * | Hour [1-12]                     |  70 | h       | 1, 2, ..., 11, 12                 |       |\n * |                                 |     | ho      | 1st, 2nd, ..., 11th, 12th         | 5     |\n * |                                 |     | hh      | 01, 02, ..., 11, 12               |       |\n * | Hour [0-23]                     |  70 | H       | 0, 1, 2, ..., 23                  |       |\n * |                                 |     | Ho      | 0th, 1st, 2nd, ..., 23rd          | 5     |\n * |                                 |     | HH      | 00, 01, 02, ..., 23               |       |\n * | Hour [0-11]                     |  70 | K       | 1, 2, ..., 11, 0                  |       |\n * |                                 |     | Ko      | 1st, 2nd, ..., 11th, 0th          | 5     |\n * |                                 |     | KK      | 01, 02, ..., 11, 00               |       |\n * | Hour [1-24]                     |  70 | k       | 24, 1, 2, ..., 23                 |       |\n * |                                 |     | ko      | 24th, 1st, 2nd, ..., 23rd         | 5     |\n * |                                 |     | kk      | 24, 01, 02, ..., 23               |       |\n * | Minute                          |  60 | m       | 0, 1, ..., 59                     |       |\n * |                                 |     | mo      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | mm      | 00, 01, ..., 59                   |       |\n * | Second                          |  50 | s       | 0, 1, ..., 59                     |       |\n * |                                 |     | so      | 0th, 1st, ..., 59th               | 5     |\n * |                                 |     | ss      | 00, 01, ..., 59                   |       |\n * | Seconds timestamp               |  40 | t       | 512969520                         |       |\n * |                                 |     | tt      | ...                               | 2     |\n * | Fraction of second              |  30 | S       | 0, 1, ..., 9                      |       |\n * |                                 |     | SS      | 00, 01, ..., 99                   |       |\n * |                                 |     | SSS     | 000, 0001, ..., 999               |       |\n * |                                 |     | SSSS    | ...                               | 2     |\n * | Milliseconds timestamp          |  20 | T       | 512969520900                      |       |\n * |                                 |     | TT      | ...                               | 2     |\n * | Timezone (ISO-8601 w/ Z)        |  10 | X       | -08, +0530, Z                     |       |\n * |                                 |     | XX      | -0800, +0530, Z                   |       |\n * |                                 |     | XXX     | -08:00, +05:30, Z                 |       |\n * |                                 |     | XXXX    | -0800, +0530, Z, +123456          | 2     |\n * |                                 |     | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |\n * | Timezone (ISO-8601 w/o Z)       |  10 | x       | -08, +0530, +00                   |       |\n * |                                 |     | xx      | -0800, +0530, +0000               |       |\n * |                                 |     | xxx     | -08:00, +05:30, +00:00            | 2     |\n * |                                 |     | xxxx    | -0800, +0530, +0000, +123456      |       |\n * |                                 |     | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |\n * | Long localized date             |  NA | P       | 05/29/1453                        | 5,8   |\n * |                                 |     | PP      | May 29, 1453                      |       |\n * |                                 |     | PPP     | May 29th, 1453                    |       |\n * |                                 |     | PPPP    | Sunday, May 29th, 1453            | 2,5,8 |\n * | Long localized time             |  NA | p       | 12:00 AM                          | 5,8   |\n * |                                 |     | pp      | 12:00:00 AM                       |       |\n * | Combination of date and time    |  NA | Pp      | 05/29/1453, 12:00 AM              |       |\n * |                                 |     | PPpp    | May 29, 1453, 12:00:00 AM         |       |\n * |                                 |     | PPPpp   | May 29th, 1453 at ...             |       |\n * |                                 |     | PPPPpp  | Sunday, May 29th, 1453 at ...     | 2,5,8 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n *    are the same as \"stand-alone\" units, but are different in some languages.\n *    \"Formatting\" units are declined according to the rules of the language\n *    in the context of a date. \"Stand-alone\" units are always nominative singular.\n *    In `format` function, they will produce different result:\n *\n *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n *    `parse` will try to match both formatting and stand-alone units interchangably.\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n *    the single quote characters (see below).\n *    If the sequence is longer than listed in table:\n *    - for numerical units (`yyyyyyyy`) `parse` will try to match a number\n *      as wide as the sequence\n *    - for text units (`MMMMMMMM`) `parse` will try to match the widest variation of the unit.\n *      These variations are marked with \"2\" in the last column of the table.\n *\n * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n *    These tokens represent the shortest form of the quarter.\n *\n * 4. The main difference between `y` and `u` patterns are B.C. years:\n *\n *    | Year | `y` | `u` |\n *    |------|-----|-----|\n *    | AC 1 |   1 |   1 |\n *    | BC 1 |   1 |   0 |\n *    | BC 2 |   2 |  -1 |\n *\n *    Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:\n *\n *    `parse('50', 'yy', new Date(2018, 0, 1)) //=> Sat Jan 01 2050 00:00:00`\n *\n *    `parse('75', 'yy', new Date(2018, 0, 1)) //=> Wed Jan 01 1975 00:00:00`\n *\n *    while `uu` will just assign the year as is:\n *\n *    `parse('50', 'uu', new Date(2018, 0, 1)) //=> Sat Jan 01 0050 00:00:00`\n *\n *    `parse('75', 'uu', new Date(2018, 0, 1)) //=> Tue Jan 01 0075 00:00:00`\n *\n *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n *    except local week-numbering years are dependent on `options.weekStartsOn`\n *    and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}\n *    and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).\n *\n * 5. These patterns are not in the Unicode Technical Standard #35:\n *    - `i`: ISO day of week\n *    - `I`: ISO week of year\n *    - `R`: ISO week-numbering year\n *    - `o`: ordinal number modifier\n *    - `P`: long localized date\n *    - `p`: long localized time\n *\n * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based\n *    on the given locale.\n *\n *    using `en-US` locale: `P` => `MM/dd/yyyy`\n *    using `en-US` locale: `p` => `hh:mm a`\n *    using `pt-BR` locale: `P` => `dd/MM/yyyy`\n *    using `pt-BR` locale: `p` => `HH:mm`\n *\n * Values will be assigned to the date in the descending order of its unit's priority.\n * Units of an equal priority overwrite each other in the order of appearance.\n *\n * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year),\n * the values will be taken from 3rd argument `referenceDate` which works as a context of parsing.\n *\n * `referenceDate` must be passed for correct work of the function.\n * If you're not sure which `referenceDate` to supply, create a new instance of Date:\n * `parse('02/11/2014', 'MM/dd/yyyy', new Date())`\n * In this case parsing will be done in the context of the current date.\n * If `referenceDate` is `Invalid Date` or a value not convertible to valid `Date`,\n * then `Invalid Date` will be returned.\n *\n * The result may vary by locale.\n *\n * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.\n *\n * If parsing failed, `Invalid Date` will be returned.\n * Invalid Date is a Date, whose time value is NaN.\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Old `parse` was renamed to `toDate`.\n *   Now `parse` is a new function which parses a string using a provided format.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   parse('2016-01-01')\n *\n *   // v2.0.0 onward\n *   toDate('2016-01-01')\n *   parse('2016-01-01', 'yyyy-MM-dd', new Date())\n *   ```\n *\n * @param {String} dateString - the string to parse\n * @param {String} formatString - the string of tokens\n * @param {Date|Number} referenceDate - defines values missing from the parsed dateString\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n *   see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n *   see: https://git.io/fxCyr\n * @returns {Date} the parsed date\n * @throws {TypeError} 3 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} `options.locale` must contain `match` property\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Parse 11 February 2014 from middle-endian format:\n * var result = parse('02/11/2014', 'MM/dd/yyyy', new Date())\n * //=> Tue Feb 11 2014 00:00:00\n *\n * @example\n * // Parse 28th of February in Esperanto locale in the context of 2010 year:\n * import eo from 'date-fns/locale/eo'\n * var result = parse('28-a de februaro', \"do 'de' MMMM\", new Date(2010, 0, 1), {\n *   locale: eo\n * })\n * //=> Sun Feb 28 2010 00:00:00\n */\n\nexport default function parse(dirtyDateString, dirtyFormatString, dirtyReferenceDate, dirtyOptions) {\n  requiredArgs(3, arguments);\n  var dateString = String(dirtyDateString);\n  var formatString = String(dirtyFormatString);\n  var options = dirtyOptions || {};\n  var locale = options.locale || defaultLocale;\n\n  if (!locale.match) {\n    throw new RangeError('locale must contain match property');\n  }\n\n  var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n  if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n    throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n  }\n\n  var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  if (formatString === '') {\n    if (dateString === '') {\n      return toDate(dirtyReferenceDate);\n    } else {\n      return new Date(NaN);\n    }\n  }\n\n  var subFnOptions = {\n    firstWeekContainsDate: firstWeekContainsDate,\n    weekStartsOn: weekStartsOn,\n    locale: locale // If timezone isn't specified, it will be set to the system timezone\n\n  };\n  var setters = [{\n    priority: TIMEZONE_UNIT_PRIORITY,\n    subPriority: -1,\n    set: dateToSystemTimezone,\n    index: 0\n  }];\n  var i;\n  var tokens = formatString.match(longFormattingTokensRegExp).map(function (substring) {\n    var firstCharacter = substring[0];\n\n    if (firstCharacter === 'p' || firstCharacter === 'P') {\n      var longFormatter = longFormatters[firstCharacter];\n      return longFormatter(substring, locale.formatLong, subFnOptions);\n    }\n\n    return substring;\n  }).join('').match(formattingTokensRegExp);\n  var usedTokens = [];\n\n  for (i = 0; i < tokens.length; i++) {\n    var token = tokens[i];\n\n    if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(token)) {\n      throwProtectedError(token, formatString, dirtyDateString);\n    }\n\n    if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(token)) {\n      throwProtectedError(token, formatString, dirtyDateString);\n    }\n\n    var firstCharacter = token[0];\n    var parser = parsers[firstCharacter];\n\n    if (parser) {\n      var incompatibleTokens = parser.incompatibleTokens;\n\n      if (Array.isArray(incompatibleTokens)) {\n        var incompatibleToken = void 0;\n\n        for (var _i = 0; _i < usedTokens.length; _i++) {\n          var usedToken = usedTokens[_i].token;\n\n          if (incompatibleTokens.indexOf(usedToken) !== -1 || usedToken === firstCharacter) {\n            incompatibleToken = usedTokens[_i];\n            break;\n          }\n        }\n\n        if (incompatibleToken) {\n          throw new RangeError(\"The format string mustn't contain `\".concat(incompatibleToken.fullToken, \"` and `\").concat(token, \"` at the same time\"));\n        }\n      } else if (parser.incompatibleTokens === '*' && usedTokens.length) {\n        throw new RangeError(\"The format string mustn't contain `\".concat(token, \"` and any other token at the same time\"));\n      }\n\n      usedTokens.push({\n        token: firstCharacter,\n        fullToken: token\n      });\n      var parseResult = parser.parse(dateString, token, locale.match, subFnOptions);\n\n      if (!parseResult) {\n        return new Date(NaN);\n      }\n\n      setters.push({\n        priority: parser.priority,\n        subPriority: parser.subPriority || 0,\n        set: parser.set,\n        validate: parser.validate,\n        value: parseResult.value,\n        index: setters.length\n      });\n      dateString = parseResult.rest;\n    } else {\n      if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n        throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n      } // Replace two single quote characters with one single quote character\n\n\n      if (token === \"''\") {\n        token = \"'\";\n      } else if (firstCharacter === \"'\") {\n        token = cleanEscapedString(token);\n      } // Cut token from string, or, if string doesn't match the token, return Invalid Date\n\n\n      if (dateString.indexOf(token) === 0) {\n        dateString = dateString.slice(token.length);\n      } else {\n        return new Date(NaN);\n      }\n    }\n  } // Check if the remaining input contains something other than whitespace\n\n\n  if (dateString.length > 0 && notWhitespaceRegExp.test(dateString)) {\n    return new Date(NaN);\n  }\n\n  var uniquePrioritySetters = setters.map(function (setter) {\n    return setter.priority;\n  }).sort(function (a, b) {\n    return b - a;\n  }).filter(function (priority, index, array) {\n    return array.indexOf(priority) === index;\n  }).map(function (priority) {\n    return setters.filter(function (setter) {\n      return setter.priority === priority;\n    }).sort(function (a, b) {\n      return b.subPriority - a.subPriority;\n    });\n  }).map(function (setterArray) {\n    return setterArray[0];\n  });\n  var date = toDate(dirtyReferenceDate);\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n  // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n  // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37\n\n\n  var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));\n  var flags = {};\n\n  for (i = 0; i < uniquePrioritySetters.length; i++) {\n    var setter = uniquePrioritySetters[i];\n\n    if (setter.validate && !setter.validate(utcDate, setter.value, subFnOptions)) {\n      return new Date(NaN);\n    }\n\n    var result = setter.set(utcDate, flags, setter.value, subFnOptions); // Result is tuple (date, flags)\n\n    if (result[0]) {\n      utcDate = result[0];\n      assign(flags, result[1]); // Result is date\n    } else {\n      utcDate = result;\n    }\n  }\n\n  return utcDate;\n}\n\nfunction dateToSystemTimezone(date, flags) {\n  if (flags.timestampIsSet) {\n    return date;\n  }\n\n  var convertedDate = new Date(0);\n  convertedDate.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n  convertedDate.setHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());\n  return convertedDate;\n}\n\nfunction cleanEscapedString(input) {\n  return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","import toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar DEFAULT_ADDITIONAL_DIGITS = 2;\nvar patterns = {\n  dateTimeDelimiter: /[T ]/,\n  timeZoneDelimiter: /[Z ]/i,\n  timezone: /([Z+-].*)$/\n};\nvar dateRegex = /^-?(?:(\\d{3})|(\\d{2})(?:-?(\\d{2}))?|W(\\d{2})(?:-?(\\d{1}))?|)$/;\nvar timeRegex = /^(\\d{2}(?:[.,]\\d*)?)(?::?(\\d{2}(?:[.,]\\d*)?))?(?::?(\\d{2}(?:[.,]\\d*)?))?$/;\nvar timezoneRegex = /^([+-])(\\d{2})(?::?(\\d{2}))?$/;\n/**\n * @name parseISO\n * @category Common Helpers\n * @summary Parse ISO string\n *\n * @description\n * Parse the given string in ISO 8601 format and return an instance of Date.\n *\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n *\n * If the argument isn't a string, the function cannot parse the string or\n * the values are invalid, it returns Invalid Date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The previous `parse` implementation was renamed to `parseISO`.\n *\n *   ```javascript\n *   // Before v2.0.0\n *   parse('2016-01-01')\n *\n *   // v2.0.0 onward\n *   parseISO('2016-01-01')\n *   ```\n *\n * - `parseISO` now validates separate date and time values in ISO-8601 strings\n *   and returns `Invalid Date` if the date is invalid.\n *\n *   ```javascript\n *   parseISO('2018-13-32')\n *   //=> Invalid Date\n *   ```\n *\n * - `parseISO` now doesn't fall back to `new Date` constructor\n *   if it fails to parse a string argument. Instead, it returns `Invalid Date`.\n *\n * @param {String} argument - the value to convert\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * var result = parseISO('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * var result = parseISO('+02014101', { additionalDigits: 1 })\n * //=> Fri Apr 11 2014 00:00:00\n */\n\nexport default function parseISO(argument, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var additionalDigits = options.additionalDigits == null ? DEFAULT_ADDITIONAL_DIGITS : toInteger(options.additionalDigits);\n\n  if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {\n    throw new RangeError('additionalDigits must be 0, 1 or 2');\n  }\n\n  if (!(typeof argument === 'string' || Object.prototype.toString.call(argument) === '[object String]')) {\n    return new Date(NaN);\n  }\n\n  var dateStrings = splitDateString(argument);\n  var date;\n\n  if (dateStrings.date) {\n    var parseYearResult = parseYear(dateStrings.date, additionalDigits);\n    date = parseDate(parseYearResult.restDateString, parseYearResult.year);\n  }\n\n  if (isNaN(date) || !date) {\n    return new Date(NaN);\n  }\n\n  var timestamp = date.getTime();\n  var time = 0;\n  var offset;\n\n  if (dateStrings.time) {\n    time = parseTime(dateStrings.time);\n\n    if (isNaN(time) || time === null) {\n      return new Date(NaN);\n    }\n  }\n\n  if (dateStrings.timezone) {\n    offset = parseTimezone(dateStrings.timezone);\n\n    if (isNaN(offset)) {\n      return new Date(NaN);\n    }\n  } else {\n    var dirtyDate = new Date(timestamp + time); // js parsed string assuming it's in UTC timezone\n    // but we need it to be parsed in our timezone\n    // so we use utc values to build date in our timezone.\n    // Year values from 0 to 99 map to the years 1900 to 1999\n    // so set year explicitly with setFullYear.\n\n    var result = new Date(dirtyDate.getUTCFullYear(), dirtyDate.getUTCMonth(), dirtyDate.getUTCDate(), dirtyDate.getUTCHours(), dirtyDate.getUTCMinutes(), dirtyDate.getUTCSeconds(), dirtyDate.getUTCMilliseconds());\n    result.setFullYear(dirtyDate.getUTCFullYear());\n    return result;\n  }\n\n  return new Date(timestamp + time + offset);\n}\n\nfunction splitDateString(dateString) {\n  var dateStrings = {};\n  var array = dateString.split(patterns.dateTimeDelimiter);\n  var timeString; // The regex match should only return at maximum two array elements.\n  // [date], [time], or [date, time].\n\n  if (array.length > 2) {\n    return dateStrings;\n  }\n\n  if (/:/.test(array[0])) {\n    dateStrings.date = null;\n    timeString = array[0];\n  } else {\n    dateStrings.date = array[0];\n    timeString = array[1];\n\n    if (patterns.timeZoneDelimiter.test(dateStrings.date)) {\n      dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];\n      timeString = dateString.substr(dateStrings.date.length, dateString.length);\n    }\n  }\n\n  if (timeString) {\n    var token = patterns.timezone.exec(timeString);\n\n    if (token) {\n      dateStrings.time = timeString.replace(token[1], '');\n      dateStrings.timezone = token[1];\n    } else {\n      dateStrings.time = timeString;\n    }\n  }\n\n  return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n  var regex = new RegExp('^(?:(\\\\d{4}|[+-]\\\\d{' + (4 + additionalDigits) + '})|(\\\\d{2}|[+-]\\\\d{' + (2 + additionalDigits) + '})$)');\n  var captures = dateString.match(regex); // Invalid ISO-formatted year\n\n  if (!captures) return {\n    year: null\n  };\n  var year = captures[1] && parseInt(captures[1]);\n  var century = captures[2] && parseInt(captures[2]);\n  return {\n    year: century == null ? year : century * 100,\n    restDateString: dateString.slice((captures[1] || captures[2]).length)\n  };\n}\n\nfunction parseDate(dateString, year) {\n  // Invalid ISO-formatted year\n  if (year === null) return null;\n  var captures = dateString.match(dateRegex); // Invalid ISO-formatted string\n\n  if (!captures) return null;\n  var isWeekDate = !!captures[4];\n  var dayOfYear = parseDateUnit(captures[1]);\n  var month = parseDateUnit(captures[2]) - 1;\n  var day = parseDateUnit(captures[3]);\n  var week = parseDateUnit(captures[4]);\n  var dayOfWeek = parseDateUnit(captures[5]) - 1;\n\n  if (isWeekDate) {\n    if (!validateWeekDate(year, week, dayOfWeek)) {\n      return new Date(NaN);\n    }\n\n    return dayOfISOWeekYear(year, week, dayOfWeek);\n  } else {\n    var date = new Date(0);\n\n    if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) {\n      return new Date(NaN);\n    }\n\n    date.setUTCFullYear(year, month, Math.max(dayOfYear, day));\n    return date;\n  }\n}\n\nfunction parseDateUnit(value) {\n  return value ? parseInt(value) : 1;\n}\n\nfunction parseTime(timeString) {\n  var captures = timeString.match(timeRegex);\n  if (!captures) return null; // Invalid ISO-formatted time\n\n  var hours = parseTimeUnit(captures[1]);\n  var minutes = parseTimeUnit(captures[2]);\n  var seconds = parseTimeUnit(captures[3]);\n\n  if (!validateTime(hours, minutes, seconds)) {\n    return NaN;\n  }\n\n  return hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * 1000;\n}\n\nfunction parseTimeUnit(value) {\n  return value && parseFloat(value.replace(',', '.')) || 0;\n}\n\nfunction parseTimezone(timezoneString) {\n  if (timezoneString === 'Z') return 0;\n  var captures = timezoneString.match(timezoneRegex);\n  if (!captures) return 0;\n  var sign = captures[1] === '+' ? -1 : 1;\n  var hours = parseInt(captures[2]);\n  var minutes = captures[3] && parseInt(captures[3]) || 0;\n\n  if (!validateTimezone(hours, minutes)) {\n    return NaN;\n  }\n\n  return sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE);\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n  var date = new Date(0);\n  date.setUTCFullYear(isoWeekYear, 0, 4);\n  var fourthOfJanuaryDay = date.getUTCDay() || 7;\n  var diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;\n  date.setUTCDate(date.getUTCDate() + diff);\n  return date;\n} // Validation functions\n// February is null to handle the leap year (using ||)\n\n\nvar daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n  return year % 400 === 0 || year % 4 === 0 && year % 100;\n}\n\nfunction validateDate(year, month, date) {\n  return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28));\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n  return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);\n}\n\nfunction validateWeekDate(_year, week, day) {\n  return week >= 1 && week <= 53 && day >= 0 && day <= 6;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n  if (hours === 24) {\n    return minutes === 0 && seconds === 0;\n  }\n\n  return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25;\n}\n\nfunction validateTimezone(_hours, minutes) {\n  return minutes >= 0 && minutes <= 59;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name parseJSON\n * @category Common Helpers\n * @summary Parse a JSON date string\n *\n * @description\n * Converts a complete ISO date string in UTC time, the typical format for transmitting\n * a date in JSON, to a JavaScript `Date` instance.\n *\n * This is a minimal implementation for converting dates retrieved from a JSON API to\n * a `Date` instance which can be used with other functions in the `date-fns` library.\n * The following formats are supported:\n *\n * - `2000-03-15T05:20:10.123Z`: The output of `.toISOString()` and `JSON.stringify(new Date())`\n * - `2000-03-15T05:20:10Z`: Without milliseconds\n * - `2000-03-15T05:20:10+00:00`: With a zero offset, the default JSON encoded format in some other languages\n * - `2000-03-15T05:20:10+0000`: With a zero offset without a colon\n * - `2000-03-15T05:20:10`: Without a trailing 'Z' symbol\n * - `2000-03-15T05:20:10.1234567`: Up to 7 digits in milliseconds field. Only first 3 are taken into account since JS does not allow fractional milliseconds\n * - `2000-03-15 05:20:10`: With a space instead of a 'T' separator for APIs returning a SQL date without reformatting\n *\n * For convenience and ease of use these other input types are also supported\n * via [toDate]{@link https://date-fns.org/docs/toDate}:\n *\n * - A `Date` instance will be cloned\n * - A `number` will be treated as a timestamp\n *\n * Any other input type or invalid date strings will return an `Invalid Date`.\n *\n * @param {String|Number|Date} argument A fully formed ISO8601 date string to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n */\n\nexport default function parseJSON(argument) {\n  requiredArgs(1, arguments);\n\n  if (typeof argument === 'string') {\n    var parts = argument.match(/(\\d{4})-(\\d{2})-(\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{0,7}))?(?:Z|\\+00:?00)?/);\n\n    if (parts) {\n      return new Date(Date.UTC(+parts[1], parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6], +((parts[7] || '0') + '00').substring(0, 3)));\n    }\n\n    return new Date(NaN);\n  }\n\n  return toDate(argument);\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name roundToNearestMinutes\n * @category Minute Helpers\n * @summary Rounds the given date to the nearest minute\n *\n * @description\n * Rounds the given date to the nearest minute (or number of minutes).\n * Rounds up when the given date is exactly between the nearest round minutes.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to round\n * @param {Object} [options] - an object with options.\n * @param {Number} [options.nearestTo=1] - nearest number of minutes to round to. E.g. `15` to round to quarter hours.\n * @returns {Date} the new date rounded to the closest minute\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.nearestTo` must be between 1 and 30\n *\n * @example\n * // Round 10 July 2014 12:12:34 to nearest minute:\n * var result = roundToNearestMinutes(new Date(2014, 6, 10, 12, 12, 34))\n * //=> Thu Jul 10 2014 12:13:00\n *\n * @example\n * // Round 10 July 2014 12:07:30 to nearest quarter hour:\n * var result = roundToNearestMinutes(new Date(2014, 6, 10, 12, 12, 34), { nearestTo: 15 })\n * // rounds up because given date is exactly between 12:00:00 and 12:15:00\n * //=> Thu Jul 10 2014 12:15:00\n */\n\nexport default function roundToNearestMinutes(dirtyDate, options) {\n  if (arguments.length < 1) {\n    throw new TypeError('1 argument required, but only none provided present');\n  }\n\n  var nearestTo = options && 'nearestTo' in options ? toInteger(options.nearestTo) : 1;\n\n  if (nearestTo < 1 || nearestTo > 30) {\n    throw new RangeError('`options.nearestTo` must be between 1 and 30');\n  }\n\n  var date = toDate(dirtyDate);\n  var seconds = date.getSeconds(); // relevant if nearestTo is 1, which is the default case\n\n  var minutes = date.getMinutes() + seconds / 60;\n  var roundedMinutes = Math.floor(minutes / nearestTo) * nearestTo;\n  var remainderMinutes = minutes % nearestTo;\n  var addedMinutes = Math.round(remainderMinutes / nearestTo) * nearestTo;\n  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), roundedMinutes + addedMinutes);\n}","import toDate from '../toDate/index.js';\nimport setMonth from '../setMonth/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name set\n * @category Common Helpers\n * @summary Set date values to a given date.\n *\n * @description\n * Set date values to a given date.\n *\n * Sets time values to date from object `values`.\n * A value is not set if it is undefined or null or doesn't exist in `values`.\n *\n * Note about bundle size: `set` does not internally use `setX` functions from date-fns but instead opts\n * to use native `Date#setX` methods. If you use this function, you may not want to include the\n * other `setX` functions that date-fns provides if you are concerned about the bundle size.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Object} values - an object with options\n * @param {Number} [values.year] - the number of years to be set\n * @param {Number} [values.month] - the number of months to be set\n * @param {Number} [values.date] - the number of days to be set\n * @param {Number} [values.hours] - the number of hours to be set\n * @param {Number} [values.minutes] - the number of minutes to be set\n * @param {Number} [values.seconds] - the number of seconds to be set\n * @param {Number} [values.milliseconds] - the number of milliseconds to be set\n * @returns {Date} the new date with options set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `values` must be an object\n *\n * @example\n * // Transform 1 September 2014 into 20 October 2015 in a single line:\n * var result = set(new Date(2014, 8, 20), { year: 2015, month: 9, date: 20 })\n * //=> Tue Oct 20 2015 00:00:00\n *\n * @example\n * // Set 12 PM to 1 September 2014 01:23:45 to 1 September 2014 12:00:00:\n * var result = set(new Date(2014, 8, 1, 1, 23, 45), { hours: 12 })\n * //=> Mon Sep 01 2014 12:23:45\n */\n\nexport default function set(dirtyDate, values) {\n  requiredArgs(2, arguments);\n\n  if (typeof values !== 'object' || values === null) {\n    throw new RangeError('values parameter must be an object');\n  }\n\n  var date = toDate(dirtyDate); // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  }\n\n  if (values.year != null) {\n    date.setFullYear(values.year);\n  }\n\n  if (values.month != null) {\n    date = setMonth(date, values.month);\n  }\n\n  if (values.date != null) {\n    date.setDate(toInteger(values.date));\n  }\n\n  if (values.hours != null) {\n    date.setHours(toInteger(values.hours));\n  }\n\n  if (values.minutes != null) {\n    date.setMinutes(toInteger(values.minutes));\n  }\n\n  if (values.seconds != null) {\n    date.setSeconds(toInteger(values.seconds));\n  }\n\n  if (values.milliseconds != null) {\n    date.setMilliseconds(toInteger(values.milliseconds));\n  }\n\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDate\n * @category Day Helpers\n * @summary Set the day of the month to the given date.\n *\n * @description\n * Set the day of the month to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} dayOfMonth - the day of the month of the new date\n * @returns {Date} the new date with the day of the month set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 30th day of the month to 1 September 2014:\n * var result = setDate(new Date(2014, 8, 1), 30)\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function setDate(dirtyDate, dirtyDayOfMonth) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfMonth = toInteger(dirtyDayOfMonth);\n  date.setDate(dayOfMonth);\n  return date;\n}","import addDays from '../addDays/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDay\n * @category Weekday Helpers\n * @summary Set the day of the week to the given date.\n *\n * @description\n * Set the day of the week to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} day - the day of the week of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the new date with the day of the week set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // Set week day to Sunday, with the default weekStartsOn of Sunday:\n * var result = setDay(new Date(2014, 8, 1), 0)\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // Set week day to Sunday, with a weekStartsOn of Monday:\n * var result = setDay(new Date(2014, 8, 1), 0, { weekStartsOn: 1 })\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function setDay(dirtyDate, dirtyDay, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate, options);\n  var day = toInteger(dirtyDay);\n  var currentDay = date.getDay();\n  var remainder = day % 7;\n  var dayIndex = (remainder + 7) % 7;\n  var delta = 7 - weekStartsOn;\n  var diff = day < 0 || day > 6 ? day - (currentDay + delta) % 7 : (dayIndex + delta) % 7 - (currentDay + delta) % 7;\n  return addDays(date, diff, options);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setDayOfYear\n * @category Day Helpers\n * @summary Set the day of the year to the given date.\n *\n * @description\n * Set the day of the year to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} dayOfYear - the day of the year of the new date\n * @returns {Date} the new date with the day of the year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 2nd day of the year to 2 July 2014:\n * var result = setDayOfYear(new Date(2014, 6, 2), 2)\n * //=> Thu Jan 02 2014 00:00:00\n */\n\nexport default function setDayOfYear(dirtyDate, dirtyDayOfYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var dayOfYear = toInteger(dirtyDayOfYear);\n  date.setMonth(0);\n  date.setDate(dayOfYear);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setHours\n * @category Hour Helpers\n * @summary Set the hours to the given date.\n *\n * @description\n * Set the hours to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} hours - the hours of the new date\n * @returns {Date} the new date with the hours set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 4 hours to 1 September 2014 11:30:00:\n * var result = setHours(new Date(2014, 8, 1, 11, 30), 4)\n * //=> Mon Sep 01 2014 04:30:00\n */\n\nexport default function setHours(dirtyDate, dirtyHours) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var hours = toInteger(dirtyHours);\n  date.setHours(hours);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport addDays from '../addDays/index.js';\nimport getISODay from '../getISODay/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISODay\n * @category Weekday Helpers\n * @summary Set the day of the ISO week to the given date.\n *\n * @description\n * Set the day of the ISO week to the given date.\n * ISO week starts with Monday.\n * 7 is the index of Sunday, 1 is the index of Monday etc.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} day - the day of the ISO week of the new date\n * @returns {Date} the new date with the day of the ISO week set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set Sunday to 1 September 2014:\n * var result = setISODay(new Date(2014, 8, 1), 7)\n * //=> Sun Sep 07 2014 00:00:00\n */\n\nexport default function setISODay(dirtyDate, dirtyDay) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var day = toInteger(dirtyDay);\n  var currentDay = getISODay(date);\n  var diff = day - currentDay;\n  return addDays(date, diff);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport getISOWeek from '../getISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISOWeek\n * @category ISO Week Helpers\n * @summary Set the ISO week to the given date.\n *\n * @description\n * Set the ISO week to the given date, saving the weekday number.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} isoWeek - the ISO week of the new date\n * @returns {Date} the new date with the ISO week set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 53rd ISO week to 7 August 2004:\n * var result = setISOWeek(new Date(2004, 7, 7), 53)\n * //=> Sat Jan 01 2005 00:00:00\n */\n\nexport default function setISOWeek(dirtyDate, dirtyISOWeek) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeek = toInteger(dirtyISOWeek);\n  var diff = getISOWeek(date) - isoWeek;\n  date.setDate(date.getDate() - diff * 7);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport startOfISOWeekYear from '../startOfISOWeekYear/index.js';\nimport differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Set the ISO week-numbering year to the given date.\n *\n * @description\n * Set the ISO week-numbering year to the given date,\n * saving the week number and the weekday number.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `setISOYear` to `setISOWeekYear`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `setWeekYear`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} isoWeekYear - the ISO week-numbering year of the new date\n * @returns {Date} the new date with the ISO week-numbering year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set ISO week-numbering year 2007 to 29 December 2008:\n * var result = setISOWeekYear(new Date(2008, 11, 29), 2007)\n * //=> Mon Jan 01 2007 00:00:00\n */\n\nexport default function setISOWeekYear(dirtyDate, dirtyISOWeekYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var isoWeekYear = toInteger(dirtyISOWeekYear);\n  var diff = differenceInCalendarDays(date, startOfISOWeekYear(date));\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(isoWeekYear, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  date = startOfISOWeekYear(fourthOfJanuary);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMilliseconds\n * @category Millisecond Helpers\n * @summary Set the milliseconds to the given date.\n *\n * @description\n * Set the milliseconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} milliseconds - the milliseconds of the new date\n * @returns {Date} the new date with the milliseconds set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 300 milliseconds to 1 September 2014 11:30:40.500:\n * var result = setMilliseconds(new Date(2014, 8, 1, 11, 30, 40, 500), 300)\n * //=> Mon Sep 01 2014 11:30:40.300\n */\n\nexport default function setMilliseconds(dirtyDate, dirtyMilliseconds) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var milliseconds = toInteger(dirtyMilliseconds);\n  date.setMilliseconds(milliseconds);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMinutes\n * @category Minute Helpers\n * @summary Set the minutes to the given date.\n *\n * @description\n * Set the minutes to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} minutes - the minutes of the new date\n * @returns {Date} the new date with the minutes set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 45 minutes to 1 September 2014 11:30:40:\n * var result = setMinutes(new Date(2014, 8, 1, 11, 30, 40), 45)\n * //=> Mon Sep 01 2014 11:45:40\n */\n\nexport default function setMinutes(dirtyDate, dirtyMinutes) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var minutes = toInteger(dirtyMinutes);\n  date.setMinutes(minutes);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport getDaysInMonth from '../getDaysInMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setMonth\n * @category Month Helpers\n * @summary Set the month to the given date.\n *\n * @description\n * Set the month to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} month - the month of the new date\n * @returns {Date} the new date with the month set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set February to 1 September 2014:\n * var result = setMonth(new Date(2014, 8, 1), 1)\n * //=> Sat Feb 01 2014 00:00:00\n */\n\nexport default function setMonth(dirtyDate, dirtyMonth) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var month = toInteger(dirtyMonth);\n  var year = date.getFullYear();\n  var day = date.getDate();\n  var dateWithDesiredMonth = new Date(0);\n  dateWithDesiredMonth.setFullYear(year, month, 15);\n  dateWithDesiredMonth.setHours(0, 0, 0, 0);\n  var daysInMonth = getDaysInMonth(dateWithDesiredMonth); // Set the last day of the new month\n  // if the original date was the last day of the longer month\n\n  date.setMonth(month, Math.min(day, daysInMonth));\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport setMonth from '../setMonth/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setQuarter\n * @category Quarter Helpers\n * @summary Set the year quarter to the given date.\n *\n * @description\n * Set the year quarter to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} quarter - the quarter of the new date\n * @returns {Date} the new date with the quarter set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set the 2nd quarter to 2 July 2014:\n * var result = setQuarter(new Date(2014, 6, 2), 2)\n * //=> Wed Apr 02 2014 00:00:00\n */\n\nexport default function setQuarter(dirtyDate, dirtyQuarter) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var quarter = toInteger(dirtyQuarter);\n  var oldQuarter = Math.floor(date.getMonth() / 3) + 1;\n  var diff = quarter - oldQuarter;\n  return setMonth(date, date.getMonth() + diff * 3);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setSeconds\n * @category Second Helpers\n * @summary Set the seconds to the given date.\n *\n * @description\n * Set the seconds to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} seconds - the seconds of the new date\n * @returns {Date} the new date with the seconds set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set 45 seconds to 1 September 2014 11:30:40:\n * var result = setSeconds(new Date(2014, 8, 1, 11, 30, 40), 45)\n * //=> Mon Sep 01 2014 11:30:45\n */\n\nexport default function setSeconds(dirtyDate, dirtySeconds) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var seconds = toInteger(dirtySeconds);\n  date.setSeconds(seconds);\n  return date;\n}","import getWeek from '../getWeek/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setWeek\n * @category Week Helpers\n * @summary Set the local week to the given date.\n *\n * @description\n * Set the local week to the given date, saving the weekday number.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} week - the week of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the new date with the local week set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Set the 1st week to 2 January 2005 with default options:\n * var result = setWeek(new Date(2005, 0, 2), 1)\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // Set the 1st week to 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January:\n * var result = setWeek(new Date(2005, 0, 2), 1, {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Sun Jan 4 2004 00:00:00\n */\n\nexport default function setWeek(dirtyDate, dirtyWeek, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var week = toInteger(dirtyWeek);\n  var diff = getWeek(date, dirtyOptions) - week;\n  date.setDate(date.getDate() - diff * 7);\n  return date;\n}","import differenceInCalendarDays from '../differenceInCalendarDays/index.js';\nimport startOfWeekYear from '../startOfWeekYear/index.js';\nimport toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Set the local week-numbering year to the given date.\n *\n * @description\n * Set the local week-numbering year to the given date,\n * saving the week number and the weekday number.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} weekYear - the local week-numbering year of the new date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the new date with the local week-numbering year set\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Set the local week-numbering year 2004 to 2 January 2010 with default options:\n * var result = setWeekYear(new Date(2010, 0, 2), 2004)\n * //=> Sat Jan 03 2004 00:00:00\n *\n * @example\n * // Set the local week-numbering year 2004 to 2 January 2010,\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * var result = setWeekYear(new Date(2010, 0, 2), 2004, {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Sat Jan 01 2005 00:00:00\n */\n\nexport default function setWeekYear(dirtyDate, dirtyWeekYear, dirtyOptions) {\n  requiredArgs(2, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var date = toDate(dirtyDate);\n  var weekYear = toInteger(dirtyWeekYear);\n  var diff = differenceInCalendarDays(date, startOfWeekYear(date, dirtyOptions));\n  var firstWeek = new Date(0);\n  firstWeek.setFullYear(weekYear, 0, firstWeekContainsDate);\n  firstWeek.setHours(0, 0, 0, 0);\n  date = startOfWeekYear(firstWeek, dirtyOptions);\n  date.setDate(date.getDate() + diff);\n  return date;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name setYear\n * @category Year Helpers\n * @summary Set the year to the given date.\n *\n * @description\n * Set the year to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} year - the year of the new date\n * @returns {Date} the new date with the year set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set year 2013 to 1 September 2014:\n * var result = setYear(new Date(2014, 8, 1), 2013)\n * //=> Sun Sep 01 2013 00:00:00\n */\n\nexport default function setYear(dirtyDate, dirtyYear) {\n  requiredArgs(2, arguments);\n  var date = toDate(dirtyDate);\n  var year = toInteger(dirtyYear); // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date\n\n  if (isNaN(date)) {\n    return new Date(NaN);\n  }\n\n  date.setFullYear(year);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfDay\n * @category Day Helpers\n * @summary Return the start of a day for the given date.\n *\n * @description\n * Return the start of a day for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a day\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a day for 2 September 2014 11:55:00:\n * var result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 00:00:00\n */\n\nexport default function startOfDay(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfDecade\n * @category Decade Helpers\n * @summary Return the start of a decade for the given date.\n *\n * @description\n * Return the start of a decade for the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a decade\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a decade for 21 October 2015 00:00:00:\n * var result = startOfDecade(new Date(2015, 9, 21, 00, 00, 00))\n * //=> Jan 01 2010 00:00:00\n */\n\nexport default function startOfDecade(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var year = date.getFullYear();\n  var decade = Math.floor(year / 10) * 10;\n  date.setFullYear(decade, 0, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfHour\n * @category Hour Helpers\n * @summary Return the start of an hour for the given date.\n *\n * @description\n * Return the start of an hour for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an hour\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an hour for 2 September 2014 11:55:00:\n * var result = startOfHour(new Date(2014, 8, 2, 11, 55))\n * //=> Tue Sep 02 2014 11:00:00\n */\n\nexport default function startOfHour(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMinutes(0, 0, 0);\n  return date;\n}","import startOfWeek from '../startOfWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the start of an ISO week for the given date.\n *\n * @description\n * Return the start of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week for 2 September 2014 11:55:00:\n * var result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfISOWeek(dirtyDate) {\n  requiredArgs(1, arguments);\n  return startOfWeek(dirtyDate, {\n    weekStartsOn: 1\n  });\n}","import getISOWeekYear from '../getISOWeekYear/index.js';\nimport startOfISOWeek from '../startOfISOWeek/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the start of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the start of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week-numbering year for 2 July 2005:\n * var result = startOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfISOWeekYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var year = getISOWeekYear(dirtyDate);\n  var fourthOfJanuary = new Date(0);\n  fourthOfJanuary.setFullYear(year, 0, 4);\n  fourthOfJanuary.setHours(0, 0, 0, 0);\n  var date = startOfISOWeek(fourthOfJanuary);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfMinute\n * @category Minute Helpers\n * @summary Return the start of a minute for the given date.\n *\n * @description\n * Return the start of a minute for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a minute for 1 December 2014 22:15:45.400:\n * var result = startOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:00\n */\n\nexport default function startOfMinute(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setSeconds(0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfMonth\n * @category Month Helpers\n * @summary Return the start of a month for the given date.\n *\n * @description\n * Return the start of a month for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a month for 2 September 2014 11:55:00:\n * var result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfMonth(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setDate(1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfQuarter\n * @category Quarter Helpers\n * @summary Return the start of a year quarter for the given date.\n *\n * @description\n * Return the start of a year quarter for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a quarter\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a quarter for 2 September 2014 11:55:00:\n * var result = startOfQuarter(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Jul 01 2014 00:00:00\n */\n\nexport default function startOfQuarter(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  var currentMonth = date.getMonth();\n  var month = currentMonth - currentMonth % 3;\n  date.setMonth(month, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfSecond\n * @category Second Helpers\n * @summary Return the start of a second for the given date.\n *\n * @description\n * Return the start of a second for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a second\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a second for 1 December 2014 22:15:45.400:\n * var result = startOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:45.000\n */\n\nexport default function startOfSecond(dirtyDate) {\n  requiredArgs(1, arguments);\n  var date = toDate(dirtyDate);\n  date.setMilliseconds(0);\n  return date;\n}","import startOfDay from '../startOfDay/index.js';\n/**\n * @name startOfToday\n * @category Day Helpers\n * @summary Return the start of today.\n * @pure false\n *\n * @description\n * Return the start of today.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `Date.now()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of today\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfToday()\n * //=> Mon Oct 6 2014 00:00:00\n */\n\nexport default function startOfToday() {\n  return startOfDay(Date.now());\n}","/**\n * @name startOfTomorrow\n * @category Day Helpers\n * @summary Return the start of tomorrow.\n * @pure false\n *\n * @description\n * Return the start of tomorrow.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of tomorrow\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfTomorrow()\n * //=> Tue Oct 7 2014 00:00:00\n */\nexport default function startOfTomorrow() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day + 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfWeek\n * @category Week Helpers\n * @summary Return the start of a week for the given date.\n *\n * @description\n * Return the start of a week for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the start of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The start of a week for 2 September 2014 11:55:00:\n * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:\n * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfWeek(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n  var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n  var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n  if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n    throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n  }\n\n  var date = toDate(dirtyDate);\n  var day = date.getDay();\n  var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n  date.setDate(date.getDate() - diff);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import getWeekYear from '../getWeekYear/index.js';\nimport startOfWeek from '../startOfWeek/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Return the start of a local week-numbering year for the given date.\n *\n * @description\n * Return the start of a local week-numbering year.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the start of a week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // The start of an a week-numbering year for 2 July 2005 with default settings:\n * var result = startOfWeekYear(new Date(2005, 6, 2))\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // The start of a week-numbering year for 2 July 2005\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * var result = startOfWeekYear(new Date(2005, 6, 2), {\n *   weekStartsOn: 1,\n *   firstWeekContainsDate: 4\n * })\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfWeekYear(dirtyDate, dirtyOptions) {\n  requiredArgs(1, arguments);\n  var options = dirtyOptions || {};\n  var locale = options.locale;\n  var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;\n  var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n  var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);\n  var year = getWeekYear(dirtyDate, dirtyOptions);\n  var firstWeek = new Date(0);\n  firstWeek.setFullYear(year, 0, firstWeekContainsDate);\n  firstWeek.setHours(0, 0, 0, 0);\n  var date = startOfWeek(firstWeek, dirtyOptions);\n  return date;\n}","import toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name startOfYear\n * @category Year Helpers\n * @summary Return the start of a year for the given date.\n *\n * @description\n * Return the start of a year for the given date.\n * The result will be in the local timezone.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a year for 2 September 2014 11:55:00:\n * var result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Jan 01 2014 00:00:00\n */\n\nexport default function startOfYear(dirtyDate) {\n  requiredArgs(1, arguments);\n  var cleanDate = toDate(dirtyDate);\n  var date = new Date(0);\n  date.setFullYear(cleanDate.getFullYear(), 0, 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","/**\n * @name startOfYesterday\n * @category Day Helpers\n * @summary Return the start of yesterday.\n * @pure false\n *\n * @description\n * Return the start of yesterday.\n *\n * > ⚠️ Please note that this function is not present in the FP submodule as\n * > it uses `new Date()` internally hence impure and can't be safely curried.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @returns {Date} the start of yesterday\n *\n * @example\n * // If today is 6 October 2014:\n * var result = startOfYesterday()\n * //=> Sun Oct 5 2014 00:00:00\n */\nexport default function startOfYesterday() {\n  var now = new Date();\n  var year = now.getFullYear();\n  var month = now.getMonth();\n  var day = now.getDate();\n  var date = new Date(0);\n  date.setFullYear(year, month, day - 1);\n  date.setHours(0, 0, 0, 0);\n  return date;\n}","import subDays from '../subDays/index.js';\nimport subMonths from '../subMonths/index.js';\nimport toDate from '../toDate/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\nimport toInteger from '../_lib/toInteger/index.js';\n/**\n * @name sub\n * @category Common Helpers\n * @summary Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.\n *\n * @description\n * Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Duration} duration - the object with years, months, weeks, days, hours, minutes and seconds to be subtracted\n *\n * | Key     | Description                        |\n * |---------|------------------------------------|\n * | years   | Amount of years to be subtracted   |\n * | months  | Amount of months to be subtracted  |\n * | weeks   | Amount of weeks to be subtracted   |\n * | days    | Amount of days to be subtracted    |\n * | hours   | Amount of hours to be subtracted   |\n * | minutes | Amount of minutes to be subtracted |\n * | seconds | Amount of seconds to be subtracted |\n *\n * All values default to 0\n *\n * @returns {Date} the new date with the seconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract the following duration from 15 June 2017 15:29:20\n * const result = sub(new Date(2017, 5, 15, 15, 29, 20), {\n *   years: 2,\n *   months: 9,\n *   weeks: 1,\n *   days: 7,\n *   hours: 5,\n *   minutes: 9,\n *   seconds: 30\n * })\n * //=> Mon Sep 1 2014 10:19:50\n */\n\nexport default function sub(dirtyDate, duration) {\n  requiredArgs(2, arguments);\n  if (!duration || typeof duration !== 'object') return new Date(NaN);\n  var years = 'years' in duration ? toInteger(duration.years) : 0;\n  var months = 'months' in duration ? toInteger(duration.months) : 0;\n  var weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0;\n  var days = 'days' in duration ? toInteger(duration.days) : 0;\n  var hours = 'hours' in duration ? toInteger(duration.hours) : 0;\n  var minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0;\n  var seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0; // Subtract years and months\n\n  var dateWithoutMonths = subMonths(toDate(dirtyDate), months + years * 12); // Subtract weeks and days\n\n  var dateWithoutDays = subDays(dateWithoutMonths, days + weeks * 7); // Subtract hours, minutes and seconds\n\n  var minutestoSub = minutes + hours * 60;\n  var secondstoSub = seconds + minutestoSub * 60;\n  var mstoSub = secondstoSub * 1000;\n  var finalDate = new Date(dateWithoutDays.getTime() - mstoSub);\n  return finalDate;\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addBusinessDays from '../addBusinessDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subBusinessDays\n * @category Day Helpers\n * @summary Substract the specified number of business days (mon - fri) to the given date.\n *\n * @description\n * Substract the specified number of business days (mon - fri) to the given date, ignoring weekends.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of business days to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the business days subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Substract 10 business days from 1 September 2014:\n * var result = subBusinessDays(new Date(2014, 8, 1), 10)\n * //=> Mon Aug 18 2014 00:00:00 (skipped weekend days)\n */\n\nexport default function subBusinessDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addBusinessDays(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addDays from '../addDays/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subDays\n * @category Day Helpers\n * @summary Subtract the specified number of days from the given date.\n *\n * @description\n * Subtract the specified number of days from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the days subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 10 days from 1 September 2014:\n * var result = subDays(new Date(2014, 8, 1), 10)\n * //=> Fri Aug 22 2014 00:00:00\n */\n\nexport default function subDays(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addDays(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addHours from '../addHours/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subHours\n * @category Hour Helpers\n * @summary Subtract the specified number of hours from the given date.\n *\n * @description\n * Subtract the specified number of hours from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of hours to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the hours subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 2 hours from 11 July 2014 01:00:00:\n * var result = subHours(new Date(2014, 6, 11, 1, 0), 2)\n * //=> Thu Jul 10 2014 23:00:00\n */\n\nexport default function subHours(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addHours(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addISOWeekYears from '../addISOWeekYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subISOWeekYears\n * @category ISO Week-Numbering Year Helpers\n * @summary Subtract the specified number of ISO week-numbering years from the given date.\n *\n * @description\n * Subtract the specified number of ISO week-numbering years from the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The function was renamed from `subISOYears` to `subISOWeekYears`.\n *   \"ISO week year\" is short for [ISO week-numbering year](https://en.wikipedia.org/wiki/ISO_week_date).\n *   This change makes the name consistent with\n *   locale-dependent week-numbering year helpers, e.g., `setWeekYear`.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of ISO week-numbering years to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the ISO week-numbering years subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 ISO week-numbering years from 1 September 2014:\n * var result = subISOWeekYears(new Date(2014, 8, 1), 5)\n * //=> Mon Aug 31 2009 00:00:00\n */\n\nexport default function subISOWeekYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addISOWeekYears(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMilliseconds from '../addMilliseconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMilliseconds\n * @category Millisecond Helpers\n * @summary Subtract the specified number of milliseconds from the given date.\n *\n * @description\n * Subtract the specified number of milliseconds from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of milliseconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the milliseconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 750 milliseconds from 10 July 2014 12:45:30.000:\n * var result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)\n * //=> Thu Jul 10 2014 12:45:29.250\n */\n\nexport default function subMilliseconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMilliseconds(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMinutes from '../addMinutes/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMinutes\n * @category Minute Helpers\n * @summary Subtract the specified number of minutes from the given date.\n *\n * @description\n * Subtract the specified number of minutes from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of minutes to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the minutes subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 30 minutes from 10 July 2014 12:00:00:\n * var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30)\n * //=> Thu Jul 10 2014 11:30:00\n */\n\nexport default function subMinutes(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMinutes(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addMonths from '../addMonths/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subMonths\n * @category Month Helpers\n * @summary Subtract the specified number of months from the given date.\n *\n * @description\n * Subtract the specified number of months from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of months to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the months subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 months from 1 February 2015:\n * var result = subMonths(new Date(2015, 1, 1), 5)\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function subMonths(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addMonths(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addQuarters from '../addQuarters/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subQuarters\n * @category Quarter Helpers\n * @summary Subtract the specified number of year quarters from the given date.\n *\n * @description\n * Subtract the specified number of year quarters from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of quarters to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the quarters subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 3 quarters from 1 September 2014:\n * var result = subQuarters(new Date(2014, 8, 1), 3)\n * //=> Sun Dec 01 2013 00:00:00\n */\n\nexport default function subQuarters(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addQuarters(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addSeconds from '../addSeconds/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subSeconds\n * @category Second Helpers\n * @summary Subtract the specified number of seconds from the given date.\n *\n * @description\n * Subtract the specified number of seconds from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 30 seconds from 10 July 2014 12:45:00:\n * var result = subSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:44:30\n */\n\nexport default function subSeconds(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addSeconds(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addWeeks from '../addWeeks/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subWeeks\n * @category Week Helpers\n * @summary Subtract the specified number of weeks from the given date.\n *\n * @description\n * Subtract the specified number of weeks from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of weeks to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the weeks subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 4 weeks from 1 September 2014:\n * var result = subWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Aug 04 2014 00:00:00\n */\n\nexport default function subWeeks(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addWeeks(dirtyDate, -amount);\n}","import toInteger from '../_lib/toInteger/index.js';\nimport addYears from '../addYears/index.js';\nimport requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name subYears\n * @category Year Helpers\n * @summary Subtract the specified number of years from the given date.\n *\n * @description\n * Subtract the specified number of years from the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 5 years from 1 September 2014:\n * var result = subYears(new Date(2014, 8, 1), 5)\n * //=> Tue Sep 01 2009 00:00:00\n */\n\nexport default function subYears(dirtyDate, dirtyAmount) {\n  requiredArgs(2, arguments);\n  var amount = toInteger(dirtyAmount);\n  return addYears(dirtyDate, -amount);\n}","import requiredArgs from '../_lib/requiredArgs/index.js';\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @param {Date|Number} argument - the value to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\n\nexport default function toDate(argument) {\n  requiredArgs(1, arguments);\n  var argStr = Object.prototype.toString.call(argument); // Clone the date\n\n  if (argument instanceof Date || typeof argument === 'object' && argStr === '[object Date]') {\n    // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n    return new Date(argument.getTime());\n  } else if (typeof argument === 'number' || argStr === '[object Number]') {\n    return new Date(argument);\n  } else {\n    if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {\n      // eslint-disable-next-line no-console\n      console.warn(\"Starting with v2.0.0-beta.1 date-fns doesn't accept strings as arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule\"); // eslint-disable-next-line no-console\n\n      console.warn(new Error().stack);\n    }\n\n    return new Date(NaN);\n  }\n}","/** @license React v16.13.1\n * react.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\nvar _assign = require('object-assign');\nvar checkPropTypes = require('prop-types/checkPropTypes');\n\nvar ReactVersion = '16.13.1';\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\nvar REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;\nvar REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;\nvar REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;\nvar REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;\nvar MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\nvar FAUX_ITERATOR_SYMBOL = '@@iterator';\nfunction getIteratorFn(maybeIterable) {\n  if (maybeIterable === null || typeof maybeIterable !== 'object') {\n    return null;\n  }\n\n  var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];\n\n  if (typeof maybeIterator === 'function') {\n    return maybeIterator;\n  }\n\n  return null;\n}\n\n/**\n * Keeps track of the current dispatcher.\n */\nvar ReactCurrentDispatcher = {\n  /**\n   * @internal\n   * @type {ReactComponent}\n   */\n  current: null\n};\n\n/**\n * Keeps track of the current batch's configuration such as how long an update\n * should suspend for if it needs to.\n */\nvar ReactCurrentBatchConfig = {\n  suspense: null\n};\n\n/**\n * Keeps track of the current owner.\n *\n * The current owner is the component who should own any components that are\n * currently being constructed.\n */\nvar ReactCurrentOwner = {\n  /**\n   * @internal\n   * @type {ReactComponent}\n   */\n  current: null\n};\n\nvar BEFORE_SLASH_RE = /^(.*)[\\\\\\/]/;\nfunction describeComponentFrame (name, source, ownerName) {\n  var sourceInfo = '';\n\n  if (source) {\n    var path = source.fileName;\n    var fileName = path.replace(BEFORE_SLASH_RE, '');\n\n    {\n      // In DEV, include code for a common special case:\n      // prefer \"folder/index.js\" instead of just \"index.js\".\n      if (/^index\\./.test(fileName)) {\n        var match = path.match(BEFORE_SLASH_RE);\n\n        if (match) {\n          var pathBeforeSlash = match[1];\n\n          if (pathBeforeSlash) {\n            var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');\n            fileName = folderName + '/' + fileName;\n          }\n        }\n      }\n    }\n\n    sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';\n  } else if (ownerName) {\n    sourceInfo = ' (created by ' + ownerName + ')';\n  }\n\n  return '\\n    in ' + (name || 'Unknown') + sourceInfo;\n}\n\nvar Resolved = 1;\nfunction refineResolvedLazyComponent(lazyComponent) {\n  return lazyComponent._status === Resolved ? lazyComponent._result : null;\n}\n\nfunction getWrappedName(outerType, innerType, wrapperName) {\n  var functionName = innerType.displayName || innerType.name || '';\n  return outerType.displayName || (functionName !== '' ? wrapperName + \"(\" + functionName + \")\" : wrapperName);\n}\n\nfunction getComponentName(type) {\n  if (type == null) {\n    // Host root, text node or just invalid type.\n    return null;\n  }\n\n  {\n    if (typeof type.tag === 'number') {\n      error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');\n    }\n  }\n\n  if (typeof type === 'function') {\n    return type.displayName || type.name || null;\n  }\n\n  if (typeof type === 'string') {\n    return type;\n  }\n\n  switch (type) {\n    case REACT_FRAGMENT_TYPE:\n      return 'Fragment';\n\n    case REACT_PORTAL_TYPE:\n      return 'Portal';\n\n    case REACT_PROFILER_TYPE:\n      return \"Profiler\";\n\n    case REACT_STRICT_MODE_TYPE:\n      return 'StrictMode';\n\n    case REACT_SUSPENSE_TYPE:\n      return 'Suspense';\n\n    case REACT_SUSPENSE_LIST_TYPE:\n      return 'SuspenseList';\n  }\n\n  if (typeof type === 'object') {\n    switch (type.$$typeof) {\n      case REACT_CONTEXT_TYPE:\n        return 'Context.Consumer';\n\n      case REACT_PROVIDER_TYPE:\n        return 'Context.Provider';\n\n      case REACT_FORWARD_REF_TYPE:\n        return getWrappedName(type, type.render, 'ForwardRef');\n\n      case REACT_MEMO_TYPE:\n        return getComponentName(type.type);\n\n      case REACT_BLOCK_TYPE:\n        return getComponentName(type.render);\n\n      case REACT_LAZY_TYPE:\n        {\n          var thenable = type;\n          var resolvedThenable = refineResolvedLazyComponent(thenable);\n\n          if (resolvedThenable) {\n            return getComponentName(resolvedThenable);\n          }\n\n          break;\n        }\n    }\n  }\n\n  return null;\n}\n\nvar ReactDebugCurrentFrame = {};\nvar currentlyValidatingElement = null;\nfunction setCurrentlyValidatingElement(element) {\n  {\n    currentlyValidatingElement = element;\n  }\n}\n\n{\n  // Stack implementation injected by the current renderer.\n  ReactDebugCurrentFrame.getCurrentStack = null;\n\n  ReactDebugCurrentFrame.getStackAddendum = function () {\n    var stack = ''; // Add an extra top frame while an element is being validated\n\n    if (currentlyValidatingElement) {\n      var name = getComponentName(currentlyValidatingElement.type);\n      var owner = currentlyValidatingElement._owner;\n      stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner.type));\n    } // Delegate to the injected renderer-specific implementation\n\n\n    var impl = ReactDebugCurrentFrame.getCurrentStack;\n\n    if (impl) {\n      stack += impl() || '';\n    }\n\n    return stack;\n  };\n}\n\n/**\n * Used by act() to track whether you're inside an act() scope.\n */\nvar IsSomeRendererActing = {\n  current: false\n};\n\nvar ReactSharedInternals = {\n  ReactCurrentDispatcher: ReactCurrentDispatcher,\n  ReactCurrentBatchConfig: ReactCurrentBatchConfig,\n  ReactCurrentOwner: ReactCurrentOwner,\n  IsSomeRendererActing: IsSomeRendererActing,\n  // Used by renderers to avoid bundling object-assign twice in UMD bundles:\n  assign: _assign\n};\n\n{\n  _assign(ReactSharedInternals, {\n    // These should not be included in production.\n    ReactDebugCurrentFrame: ReactDebugCurrentFrame,\n    // Shim for React DOM 16.0.0 which still destructured (but not used) this.\n    // TODO: remove in React 17.0.\n    ReactComponentTreeHook: {}\n  });\n}\n\n// by calls to these methods by a Babel plugin.\n//\n// In PROD (or in packages without access to React internals),\n// they are left as they are instead.\n\nfunction warn(format) {\n  {\n    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    printWarning('warn', format, args);\n  }\n}\nfunction error(format) {\n  {\n    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n      args[_key2 - 1] = arguments[_key2];\n    }\n\n    printWarning('error', format, args);\n  }\n}\n\nfunction printWarning(level, format, args) {\n  // When changing this logic, you might want to also\n  // update consoleWithStackDev.www.js as well.\n  {\n    var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\\n    in') === 0;\n\n    if (!hasExistingStack) {\n      var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n      var stack = ReactDebugCurrentFrame.getStackAddendum();\n\n      if (stack !== '') {\n        format += '%s';\n        args = args.concat([stack]);\n      }\n    }\n\n    var argsWithFormat = args.map(function (item) {\n      return '' + item;\n    }); // Careful: RN currently depends on this prefix\n\n    argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it\n    // breaks IE9: https://github.com/facebook/react/issues/13610\n    // eslint-disable-next-line react-internal/no-production-logging\n\n    Function.prototype.apply.call(console[level], console, argsWithFormat);\n\n    try {\n      // --- Welcome to debugging React ---\n      // This error was thrown as a convenience so that you can use this stack\n      // to find the callsite that caused this warning to fire.\n      var argIndex = 0;\n      var message = 'Warning: ' + format.replace(/%s/g, function () {\n        return args[argIndex++];\n      });\n      throw new Error(message);\n    } catch (x) {}\n  }\n}\n\nvar didWarnStateUpdateForUnmountedComponent = {};\n\nfunction warnNoop(publicInstance, callerName) {\n  {\n    var _constructor = publicInstance.constructor;\n    var componentName = _constructor && (_constructor.displayName || _constructor.name) || 'ReactClass';\n    var warningKey = componentName + \".\" + callerName;\n\n    if (didWarnStateUpdateForUnmountedComponent[warningKey]) {\n      return;\n    }\n\n    error(\"Can't call %s on a component that is not yet mounted. \" + 'This is a no-op, but it might indicate a bug in your application. ' + 'Instead, assign to `this.state` directly or define a `state = {};` ' + 'class property with the desired state in the %s component.', callerName, componentName);\n\n    didWarnStateUpdateForUnmountedComponent[warningKey] = true;\n  }\n}\n/**\n * This is the abstract API for an update queue.\n */\n\n\nvar ReactNoopUpdateQueue = {\n  /**\n   * Checks whether or not this composite component is mounted.\n   * @param {ReactClass} publicInstance The instance we want to test.\n   * @return {boolean} True if mounted, false otherwise.\n   * @protected\n   * @final\n   */\n  isMounted: function (publicInstance) {\n    return false;\n  },\n\n  /**\n   * Forces an update. This should only be invoked when it is known with\n   * certainty that we are **not** in a DOM transaction.\n   *\n   * You may want to call this when you know that some deeper aspect of the\n   * component's state has changed but `setState` was not called.\n   *\n   * This will not invoke `shouldComponentUpdate`, but it will invoke\n   * `componentWillUpdate` and `componentDidUpdate`.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {?function} callback Called after component is updated.\n   * @param {?string} callerName name of the calling function in the public API.\n   * @internal\n   */\n  enqueueForceUpdate: function (publicInstance, callback, callerName) {\n    warnNoop(publicInstance, 'forceUpdate');\n  },\n\n  /**\n   * Replaces all of the state. Always use this or `setState` to mutate state.\n   * You should treat `this.state` as immutable.\n   *\n   * There is no guarantee that `this.state` will be immediately updated, so\n   * accessing `this.state` after calling this method may return the old value.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} completeState Next state.\n   * @param {?function} callback Called after component is updated.\n   * @param {?string} callerName name of the calling function in the public API.\n   * @internal\n   */\n  enqueueReplaceState: function (publicInstance, completeState, callback, callerName) {\n    warnNoop(publicInstance, 'replaceState');\n  },\n\n  /**\n   * Sets a subset of the state. This only exists because _pendingState is\n   * internal. This provides a merging strategy that is not available to deep\n   * properties which is confusing. TODO: Expose pendingState or don't use it\n   * during the merge.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} partialState Next partial state to be merged with state.\n   * @param {?function} callback Called after component is updated.\n   * @param {?string} Name of the calling function in the public API.\n   * @internal\n   */\n  enqueueSetState: function (publicInstance, partialState, callback, callerName) {\n    warnNoop(publicInstance, 'setState');\n  }\n};\n\nvar emptyObject = {};\n\n{\n  Object.freeze(emptyObject);\n}\n/**\n * Base class helpers for the updating state of a component.\n */\n\n\nfunction Component(props, context, updater) {\n  this.props = props;\n  this.context = context; // If a component has string refs, we will assign a different object later.\n\n  this.refs = emptyObject; // We initialize the default updater but the real one gets injected by the\n  // renderer.\n\n  this.updater = updater || ReactNoopUpdateQueue;\n}\n\nComponent.prototype.isReactComponent = {};\n/**\n * Sets a subset of the state. Always use this to mutate\n * state. You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * There is no guarantee that calls to `setState` will run synchronously,\n * as they may eventually be batched together.  You can provide an optional\n * callback that will be executed when the call to setState is actually\n * completed.\n *\n * When a function is provided to setState, it will be called at some point in\n * the future (not synchronously). It will be called with the up to date\n * component arguments (state, props, context). These values can be different\n * from this.* because your function may be called after receiveProps but before\n * shouldComponentUpdate, and this new state, props, and context will not yet be\n * assigned to this.\n *\n * @param {object|function} partialState Next partial state or function to\n *        produce next partial state to be merged with current state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\n\nComponent.prototype.setState = function (partialState, callback) {\n  if (!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null)) {\n    {\n      throw Error( \"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\" );\n    }\n  }\n\n  this.updater.enqueueSetState(this, partialState, callback, 'setState');\n};\n/**\n * Forces an update. This should only be invoked when it is known with\n * certainty that we are **not** in a DOM transaction.\n *\n * You may want to call this when you know that some deeper aspect of the\n * component's state has changed but `setState` was not called.\n *\n * This will not invoke `shouldComponentUpdate`, but it will invoke\n * `componentWillUpdate` and `componentDidUpdate`.\n *\n * @param {?function} callback Called after update is complete.\n * @final\n * @protected\n */\n\n\nComponent.prototype.forceUpdate = function (callback) {\n  this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');\n};\n/**\n * Deprecated APIs. These APIs used to exist on classic React classes but since\n * we would like to deprecate them, we're not going to move them over to this\n * modern base class. Instead, we define a getter that warns if it's accessed.\n */\n\n\n{\n  var deprecatedAPIs = {\n    isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],\n    replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).']\n  };\n\n  var defineDeprecationWarning = function (methodName, info) {\n    Object.defineProperty(Component.prototype, methodName, {\n      get: function () {\n        warn('%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]);\n\n        return undefined;\n      }\n    });\n  };\n\n  for (var fnName in deprecatedAPIs) {\n    if (deprecatedAPIs.hasOwnProperty(fnName)) {\n      defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);\n    }\n  }\n}\n\nfunction ComponentDummy() {}\n\nComponentDummy.prototype = Component.prototype;\n/**\n * Convenience component with default shallow equality check for sCU.\n */\n\nfunction PureComponent(props, context, updater) {\n  this.props = props;\n  this.context = context; // If a component has string refs, we will assign a different object later.\n\n  this.refs = emptyObject;\n  this.updater = updater || ReactNoopUpdateQueue;\n}\n\nvar pureComponentPrototype = PureComponent.prototype = new ComponentDummy();\npureComponentPrototype.constructor = PureComponent; // Avoid an extra prototype jump for these methods.\n\n_assign(pureComponentPrototype, Component.prototype);\n\npureComponentPrototype.isPureReactComponent = true;\n\n// an immutable object with a single mutable value\nfunction createRef() {\n  var refObject = {\n    current: null\n  };\n\n  {\n    Object.seal(refObject);\n  }\n\n  return refObject;\n}\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar RESERVED_PROPS = {\n  key: true,\n  ref: true,\n  __self: true,\n  __source: true\n};\nvar specialPropKeyWarningShown, specialPropRefWarningShown, didWarnAboutStringRefs;\n\n{\n  didWarnAboutStringRefs = {};\n}\n\nfunction hasValidRef(config) {\n  {\n    if (hasOwnProperty.call(config, 'ref')) {\n      var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;\n\n      if (getter && getter.isReactWarning) {\n        return false;\n      }\n    }\n  }\n\n  return config.ref !== undefined;\n}\n\nfunction hasValidKey(config) {\n  {\n    if (hasOwnProperty.call(config, 'key')) {\n      var getter = Object.getOwnPropertyDescriptor(config, 'key').get;\n\n      if (getter && getter.isReactWarning) {\n        return false;\n      }\n    }\n  }\n\n  return config.key !== undefined;\n}\n\nfunction defineKeyPropWarningGetter(props, displayName) {\n  var warnAboutAccessingKey = function () {\n    {\n      if (!specialPropKeyWarningShown) {\n        specialPropKeyWarningShown = true;\n\n        error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName);\n      }\n    }\n  };\n\n  warnAboutAccessingKey.isReactWarning = true;\n  Object.defineProperty(props, 'key', {\n    get: warnAboutAccessingKey,\n    configurable: true\n  });\n}\n\nfunction defineRefPropWarningGetter(props, displayName) {\n  var warnAboutAccessingRef = function () {\n    {\n      if (!specialPropRefWarningShown) {\n        specialPropRefWarningShown = true;\n\n        error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName);\n      }\n    }\n  };\n\n  warnAboutAccessingRef.isReactWarning = true;\n  Object.defineProperty(props, 'ref', {\n    get: warnAboutAccessingRef,\n    configurable: true\n  });\n}\n\nfunction warnIfStringRefCannotBeAutoConverted(config) {\n  {\n    if (typeof config.ref === 'string' && ReactCurrentOwner.current && config.__self && ReactCurrentOwner.current.stateNode !== config.__self) {\n      var componentName = getComponentName(ReactCurrentOwner.current.type);\n\n      if (!didWarnAboutStringRefs[componentName]) {\n        error('Component \"%s\" contains the string ref \"%s\". ' + 'Support for string refs will be removed in a future major release. ' + 'This case cannot be automatically converted to an arrow function. ' + 'We ask you to manually fix this case by using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref', getComponentName(ReactCurrentOwner.current.type), config.ref);\n\n        didWarnAboutStringRefs[componentName] = true;\n      }\n    }\n  }\n}\n/**\n * Factory method to create a new React element. This no longer adheres to\n * the class pattern, so do not use new to call it. Also, instanceof check\n * will not work. Instead test $$typeof field against Symbol.for('react.element') to check\n * if something is a React Element.\n *\n * @param {*} type\n * @param {*} props\n * @param {*} key\n * @param {string|object} ref\n * @param {*} owner\n * @param {*} self A *temporary* helper to detect places where `this` is\n * different from the `owner` when React.createElement is called, so that we\n * can warn. We want to get rid of owner and replace string `ref`s with arrow\n * functions, and as long as `this` and owner are the same, there will be no\n * change in behavior.\n * @param {*} source An annotation object (added by a transpiler or otherwise)\n * indicating filename, line number, and/or other information.\n * @internal\n */\n\n\nvar ReactElement = function (type, key, ref, self, source, owner, props) {\n  var element = {\n    // This tag allows us to uniquely identify this as a React Element\n    $$typeof: REACT_ELEMENT_TYPE,\n    // Built-in properties that belong on the element\n    type: type,\n    key: key,\n    ref: ref,\n    props: props,\n    // Record the component responsible for creating this element.\n    _owner: owner\n  };\n\n  {\n    // The validation flag is currently mutative. We put it on\n    // an external backing store so that we can freeze the whole object.\n    // This can be replaced with a WeakMap once they are implemented in\n    // commonly used development environments.\n    element._store = {}; // To make comparing ReactElements easier for testing purposes, we make\n    // the validation flag non-enumerable (where possible, which should\n    // include every environment we run tests in), so the test framework\n    // ignores it.\n\n    Object.defineProperty(element._store, 'validated', {\n      configurable: false,\n      enumerable: false,\n      writable: true,\n      value: false\n    }); // self and source are DEV only properties.\n\n    Object.defineProperty(element, '_self', {\n      configurable: false,\n      enumerable: false,\n      writable: false,\n      value: self\n    }); // Two elements created in two different places should be considered\n    // equal for testing purposes and therefore we hide it from enumeration.\n\n    Object.defineProperty(element, '_source', {\n      configurable: false,\n      enumerable: false,\n      writable: false,\n      value: source\n    });\n\n    if (Object.freeze) {\n      Object.freeze(element.props);\n      Object.freeze(element);\n    }\n  }\n\n  return element;\n};\n/**\n * Create and return a new ReactElement of the given type.\n * See https://reactjs.org/docs/react-api.html#createelement\n */\n\nfunction createElement(type, config, children) {\n  var propName; // Reserved names are extracted\n\n  var props = {};\n  var key = null;\n  var ref = null;\n  var self = null;\n  var source = null;\n\n  if (config != null) {\n    if (hasValidRef(config)) {\n      ref = config.ref;\n\n      {\n        warnIfStringRefCannotBeAutoConverted(config);\n      }\n    }\n\n    if (hasValidKey(config)) {\n      key = '' + config.key;\n    }\n\n    self = config.__self === undefined ? null : config.__self;\n    source = config.__source === undefined ? null : config.__source; // Remaining properties are added to a new props object\n\n    for (propName in config) {\n      if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n        props[propName] = config[propName];\n      }\n    }\n  } // Children can be more than one argument, and those are transferred onto\n  // the newly allocated props object.\n\n\n  var childrenLength = arguments.length - 2;\n\n  if (childrenLength === 1) {\n    props.children = children;\n  } else if (childrenLength > 1) {\n    var childArray = Array(childrenLength);\n\n    for (var i = 0; i < childrenLength; i++) {\n      childArray[i] = arguments[i + 2];\n    }\n\n    {\n      if (Object.freeze) {\n        Object.freeze(childArray);\n      }\n    }\n\n    props.children = childArray;\n  } // Resolve default props\n\n\n  if (type && type.defaultProps) {\n    var defaultProps = type.defaultProps;\n\n    for (propName in defaultProps) {\n      if (props[propName] === undefined) {\n        props[propName] = defaultProps[propName];\n      }\n    }\n  }\n\n  {\n    if (key || ref) {\n      var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;\n\n      if (key) {\n        defineKeyPropWarningGetter(props, displayName);\n      }\n\n      if (ref) {\n        defineRefPropWarningGetter(props, displayName);\n      }\n    }\n  }\n\n  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n  var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);\n  return newElement;\n}\n/**\n * Clone and return a new ReactElement using element as the starting point.\n * See https://reactjs.org/docs/react-api.html#cloneelement\n */\n\nfunction cloneElement(element, config, children) {\n  if (!!(element === null || element === undefined)) {\n    {\n      throw Error( \"React.cloneElement(...): The argument must be a React element, but you passed \" + element + \".\" );\n    }\n  }\n\n  var propName; // Original props are copied\n\n  var props = _assign({}, element.props); // Reserved names are extracted\n\n\n  var key = element.key;\n  var ref = element.ref; // Self is preserved since the owner is preserved.\n\n  var self = element._self; // Source is preserved since cloneElement is unlikely to be targeted by a\n  // transpiler, and the original source is probably a better indicator of the\n  // true owner.\n\n  var source = element._source; // Owner will be preserved, unless ref is overridden\n\n  var owner = element._owner;\n\n  if (config != null) {\n    if (hasValidRef(config)) {\n      // Silently steal the ref from the parent.\n      ref = config.ref;\n      owner = ReactCurrentOwner.current;\n    }\n\n    if (hasValidKey(config)) {\n      key = '' + config.key;\n    } // Remaining properties override existing props\n\n\n    var defaultProps;\n\n    if (element.type && element.type.defaultProps) {\n      defaultProps = element.type.defaultProps;\n    }\n\n    for (propName in config) {\n      if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n        if (config[propName] === undefined && defaultProps !== undefined) {\n          // Resolve default props\n          props[propName] = defaultProps[propName];\n        } else {\n          props[propName] = config[propName];\n        }\n      }\n    }\n  } // Children can be more than one argument, and those are transferred onto\n  // the newly allocated props object.\n\n\n  var childrenLength = arguments.length - 2;\n\n  if (childrenLength === 1) {\n    props.children = children;\n  } else if (childrenLength > 1) {\n    var childArray = Array(childrenLength);\n\n    for (var i = 0; i < childrenLength; i++) {\n      childArray[i] = arguments[i + 2];\n    }\n\n    props.children = childArray;\n  }\n\n  return ReactElement(element.type, key, ref, self, source, owner, props);\n}\n/**\n * Verifies the object is a ReactElement.\n * See https://reactjs.org/docs/react-api.html#isvalidelement\n * @param {?object} object\n * @return {boolean} True if `object` is a ReactElement.\n * @final\n */\n\nfunction isValidElement(object) {\n  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n}\n\nvar SEPARATOR = '.';\nvar SUBSEPARATOR = ':';\n/**\n * Escape and wrap key so it is safe to use as a reactid\n *\n * @param {string} key to be escaped.\n * @return {string} the escaped key.\n */\n\nfunction escape(key) {\n  var escapeRegex = /[=:]/g;\n  var escaperLookup = {\n    '=': '=0',\n    ':': '=2'\n  };\n  var escapedString = ('' + key).replace(escapeRegex, function (match) {\n    return escaperLookup[match];\n  });\n  return '$' + escapedString;\n}\n/**\n * TODO: Test that a single child and an array with one item have the same key\n * pattern.\n */\n\n\nvar didWarnAboutMaps = false;\nvar userProvidedKeyEscapeRegex = /\\/+/g;\n\nfunction escapeUserProvidedKey(text) {\n  return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/');\n}\n\nvar POOL_SIZE = 10;\nvar traverseContextPool = [];\n\nfunction getPooledTraverseContext(mapResult, keyPrefix, mapFunction, mapContext) {\n  if (traverseContextPool.length) {\n    var traverseContext = traverseContextPool.pop();\n    traverseContext.result = mapResult;\n    traverseContext.keyPrefix = keyPrefix;\n    traverseContext.func = mapFunction;\n    traverseContext.context = mapContext;\n    traverseContext.count = 0;\n    return traverseContext;\n  } else {\n    return {\n      result: mapResult,\n      keyPrefix: keyPrefix,\n      func: mapFunction,\n      context: mapContext,\n      count: 0\n    };\n  }\n}\n\nfunction releaseTraverseContext(traverseContext) {\n  traverseContext.result = null;\n  traverseContext.keyPrefix = null;\n  traverseContext.func = null;\n  traverseContext.context = null;\n  traverseContext.count = 0;\n\n  if (traverseContextPool.length < POOL_SIZE) {\n    traverseContextPool.push(traverseContext);\n  }\n}\n/**\n * @param {?*} children Children tree container.\n * @param {!string} nameSoFar Name of the key path so far.\n * @param {!function} callback Callback to invoke with each child found.\n * @param {?*} traverseContext Used to pass information throughout the traversal\n * process.\n * @return {!number} The number of children in this subtree.\n */\n\n\nfunction traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {\n  var type = typeof children;\n\n  if (type === 'undefined' || type === 'boolean') {\n    // All of the above are perceived as null.\n    children = null;\n  }\n\n  var invokeCallback = false;\n\n  if (children === null) {\n    invokeCallback = true;\n  } else {\n    switch (type) {\n      case 'string':\n      case 'number':\n        invokeCallback = true;\n        break;\n\n      case 'object':\n        switch (children.$$typeof) {\n          case REACT_ELEMENT_TYPE:\n          case REACT_PORTAL_TYPE:\n            invokeCallback = true;\n        }\n\n    }\n  }\n\n  if (invokeCallback) {\n    callback(traverseContext, children, // If it's the only child, treat the name as if it was wrapped in an array\n    // so that it's consistent if the number of children grows.\n    nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);\n    return 1;\n  }\n\n  var child;\n  var nextName;\n  var subtreeCount = 0; // Count of children found in the current subtree.\n\n  var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;\n\n  if (Array.isArray(children)) {\n    for (var i = 0; i < children.length; i++) {\n      child = children[i];\n      nextName = nextNamePrefix + getComponentKey(child, i);\n      subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);\n    }\n  } else {\n    var iteratorFn = getIteratorFn(children);\n\n    if (typeof iteratorFn === 'function') {\n\n      {\n        // Warn about using Maps as children\n        if (iteratorFn === children.entries) {\n          if (!didWarnAboutMaps) {\n            warn('Using Maps as children is deprecated and will be removed in ' + 'a future major release. Consider converting children to ' + 'an array of keyed ReactElements instead.');\n          }\n\n          didWarnAboutMaps = true;\n        }\n      }\n\n      var iterator = iteratorFn.call(children);\n      var step;\n      var ii = 0;\n\n      while (!(step = iterator.next()).done) {\n        child = step.value;\n        nextName = nextNamePrefix + getComponentKey(child, ii++);\n        subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);\n      }\n    } else if (type === 'object') {\n      var addendum = '';\n\n      {\n        addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + ReactDebugCurrentFrame.getStackAddendum();\n      }\n\n      var childrenString = '' + children;\n\n      {\n        {\n          throw Error( \"Objects are not valid as a React child (found: \" + (childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString) + \").\" + addendum );\n        }\n      }\n    }\n  }\n\n  return subtreeCount;\n}\n/**\n * Traverses children that are typically specified as `props.children`, but\n * might also be specified through attributes:\n *\n * - `traverseAllChildren(this.props.children, ...)`\n * - `traverseAllChildren(this.props.leftPanelChildren, ...)`\n *\n * The `traverseContext` is an optional argument that is passed through the\n * entire traversal. It can be used to store accumulations or anything else that\n * the callback might find relevant.\n *\n * @param {?*} children Children tree object.\n * @param {!function} callback To invoke upon traversing each child.\n * @param {?*} traverseContext Context for traversal.\n * @return {!number} The number of children in this subtree.\n */\n\n\nfunction traverseAllChildren(children, callback, traverseContext) {\n  if (children == null) {\n    return 0;\n  }\n\n  return traverseAllChildrenImpl(children, '', callback, traverseContext);\n}\n/**\n * Generate a key string that identifies a component within a set.\n *\n * @param {*} component A component that could contain a manual key.\n * @param {number} index Index that is used if a manual key is not provided.\n * @return {string}\n */\n\n\nfunction getComponentKey(component, index) {\n  // Do some typechecking here since we call this blindly. We want to ensure\n  // that we don't block potential future ES APIs.\n  if (typeof component === 'object' && component !== null && component.key != null) {\n    // Explicit key\n    return escape(component.key);\n  } // Implicit key determined by the index in the set\n\n\n  return index.toString(36);\n}\n\nfunction forEachSingleChild(bookKeeping, child, name) {\n  var func = bookKeeping.func,\n      context = bookKeeping.context;\n  func.call(context, child, bookKeeping.count++);\n}\n/**\n * Iterates through children that are typically specified as `props.children`.\n *\n * See https://reactjs.org/docs/react-api.html#reactchildrenforeach\n *\n * The provided forEachFunc(child, index) will be called for each\n * leaf child.\n *\n * @param {?*} children Children tree container.\n * @param {function(*, int)} forEachFunc\n * @param {*} forEachContext Context for forEachContext.\n */\n\n\nfunction forEachChildren(children, forEachFunc, forEachContext) {\n  if (children == null) {\n    return children;\n  }\n\n  var traverseContext = getPooledTraverseContext(null, null, forEachFunc, forEachContext);\n  traverseAllChildren(children, forEachSingleChild, traverseContext);\n  releaseTraverseContext(traverseContext);\n}\n\nfunction mapSingleChildIntoContext(bookKeeping, child, childKey) {\n  var result = bookKeeping.result,\n      keyPrefix = bookKeeping.keyPrefix,\n      func = bookKeeping.func,\n      context = bookKeeping.context;\n  var mappedChild = func.call(context, child, bookKeeping.count++);\n\n  if (Array.isArray(mappedChild)) {\n    mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, function (c) {\n      return c;\n    });\n  } else if (mappedChild != null) {\n    if (isValidElement(mappedChild)) {\n      mappedChild = cloneAndReplaceKey(mappedChild, // Keep both the (mapped) and old keys if they differ, just as\n      // traverseAllChildren used to do for objects as children\n      keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey);\n    }\n\n    result.push(mappedChild);\n  }\n}\n\nfunction mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {\n  var escapedPrefix = '';\n\n  if (prefix != null) {\n    escapedPrefix = escapeUserProvidedKey(prefix) + '/';\n  }\n\n  var traverseContext = getPooledTraverseContext(array, escapedPrefix, func, context);\n  traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);\n  releaseTraverseContext(traverseContext);\n}\n/**\n * Maps children that are typically specified as `props.children`.\n *\n * See https://reactjs.org/docs/react-api.html#reactchildrenmap\n *\n * The provided mapFunction(child, key, index) will be called for each\n * leaf child.\n *\n * @param {?*} children Children tree container.\n * @param {function(*, int)} func The map function.\n * @param {*} context Context for mapFunction.\n * @return {object} Object containing the ordered map of results.\n */\n\n\nfunction mapChildren(children, func, context) {\n  if (children == null) {\n    return children;\n  }\n\n  var result = [];\n  mapIntoWithKeyPrefixInternal(children, result, null, func, context);\n  return result;\n}\n/**\n * Count the number of children that are typically specified as\n * `props.children`.\n *\n * See https://reactjs.org/docs/react-api.html#reactchildrencount\n *\n * @param {?*} children Children tree container.\n * @return {number} The number of children.\n */\n\n\nfunction countChildren(children) {\n  return traverseAllChildren(children, function () {\n    return null;\n  }, null);\n}\n/**\n * Flatten a children object (typically specified as `props.children`) and\n * return an array with appropriately re-keyed children.\n *\n * See https://reactjs.org/docs/react-api.html#reactchildrentoarray\n */\n\n\nfunction toArray(children) {\n  var result = [];\n  mapIntoWithKeyPrefixInternal(children, result, null, function (child) {\n    return child;\n  });\n  return result;\n}\n/**\n * Returns the first child in a collection of children and verifies that there\n * is only one child in the collection.\n *\n * See https://reactjs.org/docs/react-api.html#reactchildrenonly\n *\n * The current implementation of this function assumes that a single child gets\n * passed without a wrapper, but the purpose of this helper function is to\n * abstract away the particular structure of children.\n *\n * @param {?object} children Child collection structure.\n * @return {ReactElement} The first and only `ReactElement` contained in the\n * structure.\n */\n\n\nfunction onlyChild(children) {\n  if (!isValidElement(children)) {\n    {\n      throw Error( \"React.Children.only expected to receive a single React element child.\" );\n    }\n  }\n\n  return children;\n}\n\nfunction createContext(defaultValue, calculateChangedBits) {\n  if (calculateChangedBits === undefined) {\n    calculateChangedBits = null;\n  } else {\n    {\n      if (calculateChangedBits !== null && typeof calculateChangedBits !== 'function') {\n        error('createContext: Expected the optional second argument to be a ' + 'function. Instead received: %s', calculateChangedBits);\n      }\n    }\n  }\n\n  var context = {\n    $$typeof: REACT_CONTEXT_TYPE,\n    _calculateChangedBits: calculateChangedBits,\n    // As a workaround to support multiple concurrent renderers, we categorize\n    // some renderers as primary and others as secondary. We only expect\n    // there to be two concurrent renderers at most: React Native (primary) and\n    // Fabric (secondary); React DOM (primary) and React ART (secondary).\n    // Secondary renderers store their context values on separate fields.\n    _currentValue: defaultValue,\n    _currentValue2: defaultValue,\n    // Used to track how many concurrent renderers this context currently\n    // supports within in a single renderer. Such as parallel server rendering.\n    _threadCount: 0,\n    // These are circular\n    Provider: null,\n    Consumer: null\n  };\n  context.Provider = {\n    $$typeof: REACT_PROVIDER_TYPE,\n    _context: context\n  };\n  var hasWarnedAboutUsingNestedContextConsumers = false;\n  var hasWarnedAboutUsingConsumerProvider = false;\n\n  {\n    // A separate object, but proxies back to the original context object for\n    // backwards compatibility. It has a different $$typeof, so we can properly\n    // warn for the incorrect usage of Context as a Consumer.\n    var Consumer = {\n      $$typeof: REACT_CONTEXT_TYPE,\n      _context: context,\n      _calculateChangedBits: context._calculateChangedBits\n    }; // $FlowFixMe: Flow complains about not setting a value, which is intentional here\n\n    Object.defineProperties(Consumer, {\n      Provider: {\n        get: function () {\n          if (!hasWarnedAboutUsingConsumerProvider) {\n            hasWarnedAboutUsingConsumerProvider = true;\n\n            error('Rendering <Context.Consumer.Provider> is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Provider> instead?');\n          }\n\n          return context.Provider;\n        },\n        set: function (_Provider) {\n          context.Provider = _Provider;\n        }\n      },\n      _currentValue: {\n        get: function () {\n          return context._currentValue;\n        },\n        set: function (_currentValue) {\n          context._currentValue = _currentValue;\n        }\n      },\n      _currentValue2: {\n        get: function () {\n          return context._currentValue2;\n        },\n        set: function (_currentValue2) {\n          context._currentValue2 = _currentValue2;\n        }\n      },\n      _threadCount: {\n        get: function () {\n          return context._threadCount;\n        },\n        set: function (_threadCount) {\n          context._threadCount = _threadCount;\n        }\n      },\n      Consumer: {\n        get: function () {\n          if (!hasWarnedAboutUsingNestedContextConsumers) {\n            hasWarnedAboutUsingNestedContextConsumers = true;\n\n            error('Rendering <Context.Consumer.Consumer> is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');\n          }\n\n          return context.Consumer;\n        }\n      }\n    }); // $FlowFixMe: Flow complains about missing properties because it doesn't understand defineProperty\n\n    context.Consumer = Consumer;\n  }\n\n  {\n    context._currentRenderer = null;\n    context._currentRenderer2 = null;\n  }\n\n  return context;\n}\n\nfunction lazy(ctor) {\n  var lazyType = {\n    $$typeof: REACT_LAZY_TYPE,\n    _ctor: ctor,\n    // React uses these fields to store the result.\n    _status: -1,\n    _result: null\n  };\n\n  {\n    // In production, this would just set it on the object.\n    var defaultProps;\n    var propTypes;\n    Object.defineProperties(lazyType, {\n      defaultProps: {\n        configurable: true,\n        get: function () {\n          return defaultProps;\n        },\n        set: function (newDefaultProps) {\n          error('React.lazy(...): It is not supported to assign `defaultProps` to ' + 'a lazy component import. Either specify them where the component ' + 'is defined, or create a wrapping component around it.');\n\n          defaultProps = newDefaultProps; // Match production behavior more closely:\n\n          Object.defineProperty(lazyType, 'defaultProps', {\n            enumerable: true\n          });\n        }\n      },\n      propTypes: {\n        configurable: true,\n        get: function () {\n          return propTypes;\n        },\n        set: function (newPropTypes) {\n          error('React.lazy(...): It is not supported to assign `propTypes` to ' + 'a lazy component import. Either specify them where the component ' + 'is defined, or create a wrapping component around it.');\n\n          propTypes = newPropTypes; // Match production behavior more closely:\n\n          Object.defineProperty(lazyType, 'propTypes', {\n            enumerable: true\n          });\n        }\n      }\n    });\n  }\n\n  return lazyType;\n}\n\nfunction forwardRef(render) {\n  {\n    if (render != null && render.$$typeof === REACT_MEMO_TYPE) {\n      error('forwardRef requires a render function but received a `memo` ' + 'component. Instead of forwardRef(memo(...)), use ' + 'memo(forwardRef(...)).');\n    } else if (typeof render !== 'function') {\n      error('forwardRef requires a render function but was given %s.', render === null ? 'null' : typeof render);\n    } else {\n      if (render.length !== 0 && render.length !== 2) {\n        error('forwardRef render functions accept exactly two parameters: props and ref. %s', render.length === 1 ? 'Did you forget to use the ref parameter?' : 'Any additional parameter will be undefined.');\n      }\n    }\n\n    if (render != null) {\n      if (render.defaultProps != null || render.propTypes != null) {\n        error('forwardRef render functions do not support propTypes or defaultProps. ' + 'Did you accidentally pass a React component?');\n      }\n    }\n  }\n\n  return {\n    $$typeof: REACT_FORWARD_REF_TYPE,\n    render: render\n  };\n}\n\nfunction isValidElementType(type) {\n  return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.\n  type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);\n}\n\nfunction memo(type, compare) {\n  {\n    if (!isValidElementType(type)) {\n      error('memo: The first argument must be a component. Instead ' + 'received: %s', type === null ? 'null' : typeof type);\n    }\n  }\n\n  return {\n    $$typeof: REACT_MEMO_TYPE,\n    type: type,\n    compare: compare === undefined ? null : compare\n  };\n}\n\nfunction resolveDispatcher() {\n  var dispatcher = ReactCurrentDispatcher.current;\n\n  if (!(dispatcher !== null)) {\n    {\n      throw Error( \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.\" );\n    }\n  }\n\n  return dispatcher;\n}\n\nfunction useContext(Context, unstable_observedBits) {\n  var dispatcher = resolveDispatcher();\n\n  {\n    if (unstable_observedBits !== undefined) {\n      error('useContext() second argument is reserved for future ' + 'use in React. Passing it is not supported. ' + 'You passed: %s.%s', unstable_observedBits, typeof unstable_observedBits === 'number' && Array.isArray(arguments[2]) ? '\\n\\nDid you call array.map(useContext)? ' + 'Calling Hooks inside a loop is not supported. ' + 'Learn more at https://fb.me/rules-of-hooks' : '');\n    } // TODO: add a more generic warning for invalid values.\n\n\n    if (Context._context !== undefined) {\n      var realContext = Context._context; // Don't deduplicate because this legitimately causes bugs\n      // and nobody should be using this in existing code.\n\n      if (realContext.Consumer === Context) {\n        error('Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be ' + 'removed in a future major release. Did you mean to call useContext(Context) instead?');\n      } else if (realContext.Provider === Context) {\n        error('Calling useContext(Context.Provider) is not supported. ' + 'Did you mean to call useContext(Context) instead?');\n      }\n    }\n  }\n\n  return dispatcher.useContext(Context, unstable_observedBits);\n}\nfunction useState(initialState) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useState(initialState);\n}\nfunction useReducer(reducer, initialArg, init) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useReducer(reducer, initialArg, init);\n}\nfunction useRef(initialValue) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useRef(initialValue);\n}\nfunction useEffect(create, deps) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useEffect(create, deps);\n}\nfunction useLayoutEffect(create, deps) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useLayoutEffect(create, deps);\n}\nfunction useCallback(callback, deps) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useCallback(callback, deps);\n}\nfunction useMemo(create, deps) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useMemo(create, deps);\n}\nfunction useImperativeHandle(ref, create, deps) {\n  var dispatcher = resolveDispatcher();\n  return dispatcher.useImperativeHandle(ref, create, deps);\n}\nfunction useDebugValue(value, formatterFn) {\n  {\n    var dispatcher = resolveDispatcher();\n    return dispatcher.useDebugValue(value, formatterFn);\n  }\n}\n\nvar propTypesMisspellWarningShown;\n\n{\n  propTypesMisspellWarningShown = false;\n}\n\nfunction getDeclarationErrorAddendum() {\n  if (ReactCurrentOwner.current) {\n    var name = getComponentName(ReactCurrentOwner.current.type);\n\n    if (name) {\n      return '\\n\\nCheck the render method of `' + name + '`.';\n    }\n  }\n\n  return '';\n}\n\nfunction getSourceInfoErrorAddendum(source) {\n  if (source !== undefined) {\n    var fileName = source.fileName.replace(/^.*[\\\\\\/]/, '');\n    var lineNumber = source.lineNumber;\n    return '\\n\\nCheck your code at ' + fileName + ':' + lineNumber + '.';\n  }\n\n  return '';\n}\n\nfunction getSourceInfoErrorAddendumForProps(elementProps) {\n  if (elementProps !== null && elementProps !== undefined) {\n    return getSourceInfoErrorAddendum(elementProps.__source);\n  }\n\n  return '';\n}\n/**\n * Warn if there's no key explicitly set on dynamic arrays of children or\n * object keys are not valid. This allows us to keep track of children between\n * updates.\n */\n\n\nvar ownerHasKeyUseWarning = {};\n\nfunction getCurrentComponentErrorInfo(parentType) {\n  var info = getDeclarationErrorAddendum();\n\n  if (!info) {\n    var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;\n\n    if (parentName) {\n      info = \"\\n\\nCheck the top-level render call using <\" + parentName + \">.\";\n    }\n  }\n\n  return info;\n}\n/**\n * Warn if the element doesn't have an explicit key assigned to it.\n * This element is in an array. The array could grow and shrink or be\n * reordered. All children that haven't already been validated are required to\n * have a \"key\" property assigned to it. Error statuses are cached so a warning\n * will only be shown once.\n *\n * @internal\n * @param {ReactElement} element Element that requires a key.\n * @param {*} parentType element's parent's type.\n */\n\n\nfunction validateExplicitKey(element, parentType) {\n  if (!element._store || element._store.validated || element.key != null) {\n    return;\n  }\n\n  element._store.validated = true;\n  var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);\n\n  if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {\n    return;\n  }\n\n  ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a\n  // property, it may be the creator of the child that's responsible for\n  // assigning it a key.\n\n  var childOwner = '';\n\n  if (element && element._owner && element._owner !== ReactCurrentOwner.current) {\n    // Give the component that originally created this child.\n    childOwner = \" It was passed a child from \" + getComponentName(element._owner.type) + \".\";\n  }\n\n  setCurrentlyValidatingElement(element);\n\n  {\n    error('Each child in a list should have a unique \"key\" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.', currentComponentErrorInfo, childOwner);\n  }\n\n  setCurrentlyValidatingElement(null);\n}\n/**\n * Ensure that every element either is passed in a static location, in an\n * array with an explicit keys property defined, or in an object literal\n * with valid key property.\n *\n * @internal\n * @param {ReactNode} node Statically passed child of any type.\n * @param {*} parentType node's parent's type.\n */\n\n\nfunction validateChildKeys(node, parentType) {\n  if (typeof node !== 'object') {\n    return;\n  }\n\n  if (Array.isArray(node)) {\n    for (var i = 0; i < node.length; i++) {\n      var child = node[i];\n\n      if (isValidElement(child)) {\n        validateExplicitKey(child, parentType);\n      }\n    }\n  } else if (isValidElement(node)) {\n    // This element was passed in a valid location.\n    if (node._store) {\n      node._store.validated = true;\n    }\n  } else if (node) {\n    var iteratorFn = getIteratorFn(node);\n\n    if (typeof iteratorFn === 'function') {\n      // Entry iterators used to provide implicit keys,\n      // but now we print a separate warning for them later.\n      if (iteratorFn !== node.entries) {\n        var iterator = iteratorFn.call(node);\n        var step;\n\n        while (!(step = iterator.next()).done) {\n          if (isValidElement(step.value)) {\n            validateExplicitKey(step.value, parentType);\n          }\n        }\n      }\n    }\n  }\n}\n/**\n * Given an element, validate that its props follow the propTypes definition,\n * provided by the type.\n *\n * @param {ReactElement} element\n */\n\n\nfunction validatePropTypes(element) {\n  {\n    var type = element.type;\n\n    if (type === null || type === undefined || typeof type === 'string') {\n      return;\n    }\n\n    var name = getComponentName(type);\n    var propTypes;\n\n    if (typeof type === 'function') {\n      propTypes = type.propTypes;\n    } else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.\n    // Inner props are checked in the reconciler.\n    type.$$typeof === REACT_MEMO_TYPE)) {\n      propTypes = type.propTypes;\n    } else {\n      return;\n    }\n\n    if (propTypes) {\n      setCurrentlyValidatingElement(element);\n      checkPropTypes(propTypes, element.props, 'prop', name, ReactDebugCurrentFrame.getStackAddendum);\n      setCurrentlyValidatingElement(null);\n    } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {\n      propTypesMisspellWarningShown = true;\n\n      error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', name || 'Unknown');\n    }\n\n    if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {\n      error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');\n    }\n  }\n}\n/**\n * Given a fragment, validate that it can only be provided with fragment props\n * @param {ReactElement} fragment\n */\n\n\nfunction validateFragmentProps(fragment) {\n  {\n    setCurrentlyValidatingElement(fragment);\n    var keys = Object.keys(fragment.props);\n\n    for (var i = 0; i < keys.length; i++) {\n      var key = keys[i];\n\n      if (key !== 'children' && key !== 'key') {\n        error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);\n\n        break;\n      }\n    }\n\n    if (fragment.ref !== null) {\n      error('Invalid attribute `ref` supplied to `React.Fragment`.');\n    }\n\n    setCurrentlyValidatingElement(null);\n  }\n}\nfunction createElementWithValidation(type, props, children) {\n  var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to\n  // succeed and there will likely be errors in render.\n\n  if (!validType) {\n    var info = '';\n\n    if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {\n      info += ' You likely forgot to export your component from the file ' + \"it's defined in, or you might have mixed up default and named imports.\";\n    }\n\n    var sourceInfo = getSourceInfoErrorAddendumForProps(props);\n\n    if (sourceInfo) {\n      info += sourceInfo;\n    } else {\n      info += getDeclarationErrorAddendum();\n    }\n\n    var typeString;\n\n    if (type === null) {\n      typeString = 'null';\n    } else if (Array.isArray(type)) {\n      typeString = 'array';\n    } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {\n      typeString = \"<\" + (getComponentName(type.type) || 'Unknown') + \" />\";\n      info = ' Did you accidentally export a JSX literal instead of a component?';\n    } else {\n      typeString = typeof type;\n    }\n\n    {\n      error('React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);\n    }\n  }\n\n  var element = createElement.apply(this, arguments); // The result can be nullish if a mock or a custom function is used.\n  // TODO: Drop this when these are no longer allowed as the type argument.\n\n  if (element == null) {\n    return element;\n  } // Skip key warning if the type isn't valid since our key validation logic\n  // doesn't expect a non-string/function type and can throw confusing errors.\n  // We don't want exception behavior to differ between dev and prod.\n  // (Rendering will throw with a helpful message and as soon as the type is\n  // fixed, the key warnings will appear.)\n\n\n  if (validType) {\n    for (var i = 2; i < arguments.length; i++) {\n      validateChildKeys(arguments[i], type);\n    }\n  }\n\n  if (type === REACT_FRAGMENT_TYPE) {\n    validateFragmentProps(element);\n  } else {\n    validatePropTypes(element);\n  }\n\n  return element;\n}\nvar didWarnAboutDeprecatedCreateFactory = false;\nfunction createFactoryWithValidation(type) {\n  var validatedFactory = createElementWithValidation.bind(null, type);\n  validatedFactory.type = type;\n\n  {\n    if (!didWarnAboutDeprecatedCreateFactory) {\n      didWarnAboutDeprecatedCreateFactory = true;\n\n      warn('React.createFactory() is deprecated and will be removed in ' + 'a future major release. Consider using JSX ' + 'or use React.createElement() directly instead.');\n    } // Legacy hook: remove it\n\n\n    Object.defineProperty(validatedFactory, 'type', {\n      enumerable: false,\n      get: function () {\n        warn('Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.');\n\n        Object.defineProperty(this, 'type', {\n          value: type\n        });\n        return type;\n      }\n    });\n  }\n\n  return validatedFactory;\n}\nfunction cloneElementWithValidation(element, props, children) {\n  var newElement = cloneElement.apply(this, arguments);\n\n  for (var i = 2; i < arguments.length; i++) {\n    validateChildKeys(arguments[i], newElement.type);\n  }\n\n  validatePropTypes(newElement);\n  return newElement;\n}\n\n{\n\n  try {\n    var frozenObject = Object.freeze({});\n    var testMap = new Map([[frozenObject, null]]);\n    var testSet = new Set([frozenObject]); // This is necessary for Rollup to not consider these unused.\n    // https://github.com/rollup/rollup/issues/1771\n    // TODO: we can remove these if Rollup fixes the bug.\n\n    testMap.set(0, 0);\n    testSet.add(0);\n  } catch (e) {\n  }\n}\n\nvar createElement$1 =  createElementWithValidation ;\nvar cloneElement$1 =  cloneElementWithValidation ;\nvar createFactory =  createFactoryWithValidation ;\nvar Children = {\n  map: mapChildren,\n  forEach: forEachChildren,\n  count: countChildren,\n  toArray: toArray,\n  only: onlyChild\n};\n\nexports.Children = Children;\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactSharedInternals;\nexports.cloneElement = cloneElement$1;\nexports.createContext = createContext;\nexports.createElement = createElement$1;\nexports.createFactory = createFactory;\nexports.createRef = createRef;\nexports.forwardRef = forwardRef;\nexports.isValidElement = isValidElement;\nexports.lazy = lazy;\nexports.memo = memo;\nexports.useCallback = useCallback;\nexports.useContext = useContext;\nexports.useDebugValue = useDebugValue;\nexports.useEffect = useEffect;\nexports.useImperativeHandle = useImperativeHandle;\nexports.useLayoutEffect = useLayoutEffect;\nexports.useMemo = useMemo;\nexports.useReducer = useReducer;\nexports.useRef = useRef;\nexports.useState = useState;\nexports.version = ReactVersion;\n  })();\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/react.production.min.js');\n} else {\n  module.exports = require('./cjs/react.development.js');\n}\n","'use strict';\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n","'use strict';\n\nvar define = require('define-properties');\nvar callBind = require('es-abstract/helpers/callBind');\n\nvar implementation = require('./implementation');\nvar getPolyfill = require('./polyfill');\nvar shim = require('./shim');\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n","'use strict';\n\nvar implementation = require('./implementation');\n\nvar supportsDescriptors = require('define-properties').supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n","'use strict';\n\nvar supportsDescriptors = require('define-properties').supportsDescriptors;\nvar getPolyfill = require('./polyfill');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n","function isAbsolute(pathname) {\n  return pathname.charAt(0) === '/';\n}\n\n// About 1.5x faster than the two-arg version of Array#splice()\nfunction spliceOne(list, index) {\n  for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) {\n    list[i] = list[k];\n  }\n\n  list.pop();\n}\n\n// This implementation is based heavily on node's url.parse\nfunction resolvePathname(to, from) {\n  if (from === undefined) from = '';\n\n  var toParts = (to && to.split('/')) || [];\n  var fromParts = (from && from.split('/')) || [];\n\n  var isToAbs = to && isAbsolute(to);\n  var isFromAbs = from && isAbsolute(from);\n  var mustEndAbs = isToAbs || isFromAbs;\n\n  if (to && isAbsolute(to)) {\n    // to is absolute\n    fromParts = toParts;\n  } else if (toParts.length) {\n    // to is relative, drop the filename\n    fromParts.pop();\n    fromParts = fromParts.concat(toParts);\n  }\n\n  if (!fromParts.length) return '/';\n\n  var hasTrailingSlash;\n  if (fromParts.length) {\n    var last = fromParts[fromParts.length - 1];\n    hasTrailingSlash = last === '.' || last === '..' || last === '';\n  } else {\n    hasTrailingSlash = false;\n  }\n\n  var up = 0;\n  for (var i = fromParts.length; i >= 0; i--) {\n    var part = fromParts[i];\n\n    if (part === '.') {\n      spliceOne(fromParts, i);\n    } else if (part === '..') {\n      spliceOne(fromParts, i);\n      up++;\n    } else if (up) {\n      spliceOne(fromParts, i);\n      up--;\n    }\n  }\n\n  if (!mustEndAbs) for (; up--; up) fromParts.unshift('..');\n\n  if (\n    mustEndAbs &&\n    fromParts[0] !== '' &&\n    (!fromParts[0] || !isAbsolute(fromParts[0]))\n  )\n    fromParts.unshift('');\n\n  var result = fromParts.join('/');\n\n  if (hasTrailingSlash && result.substr(-1) !== '/') result += '/';\n\n  return result;\n}\n\nexport default resolvePathname;\n","/** @license React v0.19.1\n * scheduler-tracing.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\nvar DEFAULT_THREAD_ID = 0; // Counters used to generate unique IDs.\n\nvar interactionIDCounter = 0;\nvar threadIDCounter = 0; // Set of currently traced interactions.\n// Interactions \"stack\"–\n// Meaning that newly traced interactions are appended to the previously active set.\n// When an interaction goes out of scope, the previous set (if any) is restored.\n\nexports.__interactionsRef = null; // Listener(s) to notify when interactions begin and end.\n\nexports.__subscriberRef = null;\n\n{\n  exports.__interactionsRef = {\n    current: new Set()\n  };\n  exports.__subscriberRef = {\n    current: null\n  };\n}\nfunction unstable_clear(callback) {\n\n  var prevInteractions = exports.__interactionsRef.current;\n  exports.__interactionsRef.current = new Set();\n\n  try {\n    return callback();\n  } finally {\n    exports.__interactionsRef.current = prevInteractions;\n  }\n}\nfunction unstable_getCurrent() {\n  {\n    return exports.__interactionsRef.current;\n  }\n}\nfunction unstable_getThreadID() {\n  return ++threadIDCounter;\n}\nfunction unstable_trace(name, timestamp, callback) {\n  var threadID = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DEFAULT_THREAD_ID;\n\n  var interaction = {\n    __count: 1,\n    id: interactionIDCounter++,\n    name: name,\n    timestamp: timestamp\n  };\n  var prevInteractions = exports.__interactionsRef.current; // Traced interactions should stack/accumulate.\n  // To do that, clone the current interactions.\n  // The previous set will be restored upon completion.\n\n  var interactions = new Set(prevInteractions);\n  interactions.add(interaction);\n  exports.__interactionsRef.current = interactions;\n  var subscriber = exports.__subscriberRef.current;\n  var returnValue;\n\n  try {\n    if (subscriber !== null) {\n      subscriber.onInteractionTraced(interaction);\n    }\n  } finally {\n    try {\n      if (subscriber !== null) {\n        subscriber.onWorkStarted(interactions, threadID);\n      }\n    } finally {\n      try {\n        returnValue = callback();\n      } finally {\n        exports.__interactionsRef.current = prevInteractions;\n\n        try {\n          if (subscriber !== null) {\n            subscriber.onWorkStopped(interactions, threadID);\n          }\n        } finally {\n          interaction.__count--; // If no async work was scheduled for this interaction,\n          // Notify subscribers that it's completed.\n\n          if (subscriber !== null && interaction.__count === 0) {\n            subscriber.onInteractionScheduledWorkCompleted(interaction);\n          }\n        }\n      }\n    }\n  }\n\n  return returnValue;\n}\nfunction unstable_wrap(callback) {\n  var threadID = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_THREAD_ID;\n\n  var wrappedInteractions = exports.__interactionsRef.current;\n  var subscriber = exports.__subscriberRef.current;\n\n  if (subscriber !== null) {\n    subscriber.onWorkScheduled(wrappedInteractions, threadID);\n  } // Update the pending async work count for the current interactions.\n  // Update after calling subscribers in case of error.\n\n\n  wrappedInteractions.forEach(function (interaction) {\n    interaction.__count++;\n  });\n  var hasRun = false;\n\n  function wrapped() {\n    var prevInteractions = exports.__interactionsRef.current;\n    exports.__interactionsRef.current = wrappedInteractions;\n    subscriber = exports.__subscriberRef.current;\n\n    try {\n      var returnValue;\n\n      try {\n        if (subscriber !== null) {\n          subscriber.onWorkStarted(wrappedInteractions, threadID);\n        }\n      } finally {\n        try {\n          returnValue = callback.apply(undefined, arguments);\n        } finally {\n          exports.__interactionsRef.current = prevInteractions;\n\n          if (subscriber !== null) {\n            subscriber.onWorkStopped(wrappedInteractions, threadID);\n          }\n        }\n      }\n\n      return returnValue;\n    } finally {\n      if (!hasRun) {\n        // We only expect a wrapped function to be executed once,\n        // But in the event that it's executed more than once–\n        // Only decrement the outstanding interaction counts once.\n        hasRun = true; // Update pending async counts for all wrapped interactions.\n        // If this was the last scheduled async work for any of them,\n        // Mark them as completed.\n\n        wrappedInteractions.forEach(function (interaction) {\n          interaction.__count--;\n\n          if (subscriber !== null && interaction.__count === 0) {\n            subscriber.onInteractionScheduledWorkCompleted(interaction);\n          }\n        });\n      }\n    }\n  }\n\n  wrapped.cancel = function cancel() {\n    subscriber = exports.__subscriberRef.current;\n\n    try {\n      if (subscriber !== null) {\n        subscriber.onWorkCanceled(wrappedInteractions, threadID);\n      }\n    } finally {\n      // Update pending async counts for all wrapped interactions.\n      // If this was the last scheduled async work for any of them,\n      // Mark them as completed.\n      wrappedInteractions.forEach(function (interaction) {\n        interaction.__count--;\n\n        if (subscriber && interaction.__count === 0) {\n          subscriber.onInteractionScheduledWorkCompleted(interaction);\n        }\n      });\n    }\n  };\n\n  return wrapped;\n}\n\nvar subscribers = null;\n\n{\n  subscribers = new Set();\n}\n\nfunction unstable_subscribe(subscriber) {\n  {\n    subscribers.add(subscriber);\n\n    if (subscribers.size === 1) {\n      exports.__subscriberRef.current = {\n        onInteractionScheduledWorkCompleted: onInteractionScheduledWorkCompleted,\n        onInteractionTraced: onInteractionTraced,\n        onWorkCanceled: onWorkCanceled,\n        onWorkScheduled: onWorkScheduled,\n        onWorkStarted: onWorkStarted,\n        onWorkStopped: onWorkStopped\n      };\n    }\n  }\n}\nfunction unstable_unsubscribe(subscriber) {\n  {\n    subscribers.delete(subscriber);\n\n    if (subscribers.size === 0) {\n      exports.__subscriberRef.current = null;\n    }\n  }\n}\n\nfunction onInteractionTraced(interaction) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onInteractionTraced(interaction);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nfunction onInteractionScheduledWorkCompleted(interaction) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onInteractionScheduledWorkCompleted(interaction);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nfunction onWorkScheduled(interactions, threadID) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onWorkScheduled(interactions, threadID);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nfunction onWorkStarted(interactions, threadID) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onWorkStarted(interactions, threadID);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nfunction onWorkStopped(interactions, threadID) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onWorkStopped(interactions, threadID);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nfunction onWorkCanceled(interactions, threadID) {\n  var didCatchError = false;\n  var caughtError = null;\n  subscribers.forEach(function (subscriber) {\n    try {\n      subscriber.onWorkCanceled(interactions, threadID);\n    } catch (error) {\n      if (!didCatchError) {\n        didCatchError = true;\n        caughtError = error;\n      }\n    }\n  });\n\n  if (didCatchError) {\n    throw caughtError;\n  }\n}\n\nexports.unstable_clear = unstable_clear;\nexports.unstable_getCurrent = unstable_getCurrent;\nexports.unstable_getThreadID = unstable_getThreadID;\nexports.unstable_subscribe = unstable_subscribe;\nexports.unstable_trace = unstable_trace;\nexports.unstable_unsubscribe = unstable_unsubscribe;\nexports.unstable_wrap = unstable_wrap;\n  })();\n}\n","/** @license React v0.19.1\n * scheduler.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\nvar enableSchedulerDebugging = false;\nvar enableProfiling = true;\n\nvar requestHostCallback;\nvar requestHostTimeout;\nvar cancelHostTimeout;\nvar shouldYieldToHost;\nvar requestPaint;\n\nif ( // If Scheduler runs in a non-DOM environment, it falls back to a naive\n// implementation using setTimeout.\ntypeof window === 'undefined' || // Check if MessageChannel is supported, too.\ntypeof MessageChannel !== 'function') {\n  // If this accidentally gets imported in a non-browser environment, e.g. JavaScriptCore,\n  // fallback to a naive implementation.\n  var _callback = null;\n  var _timeoutID = null;\n\n  var _flushCallback = function () {\n    if (_callback !== null) {\n      try {\n        var currentTime = exports.unstable_now();\n        var hasRemainingTime = true;\n\n        _callback(hasRemainingTime, currentTime);\n\n        _callback = null;\n      } catch (e) {\n        setTimeout(_flushCallback, 0);\n        throw e;\n      }\n    }\n  };\n\n  var initialTime = Date.now();\n\n  exports.unstable_now = function () {\n    return Date.now() - initialTime;\n  };\n\n  requestHostCallback = function (cb) {\n    if (_callback !== null) {\n      // Protect against re-entrancy.\n      setTimeout(requestHostCallback, 0, cb);\n    } else {\n      _callback = cb;\n      setTimeout(_flushCallback, 0);\n    }\n  };\n\n  requestHostTimeout = function (cb, ms) {\n    _timeoutID = setTimeout(cb, ms);\n  };\n\n  cancelHostTimeout = function () {\n    clearTimeout(_timeoutID);\n  };\n\n  shouldYieldToHost = function () {\n    return false;\n  };\n\n  requestPaint = exports.unstable_forceFrameRate = function () {};\n} else {\n  // Capture local references to native APIs, in case a polyfill overrides them.\n  var performance = window.performance;\n  var _Date = window.Date;\n  var _setTimeout = window.setTimeout;\n  var _clearTimeout = window.clearTimeout;\n\n  if (typeof console !== 'undefined') {\n    // TODO: Scheduler no longer requires these methods to be polyfilled. But\n    // maybe we want to continue warning if they don't exist, to preserve the\n    // option to rely on it in the future?\n    var requestAnimationFrame = window.requestAnimationFrame;\n    var cancelAnimationFrame = window.cancelAnimationFrame; // TODO: Remove fb.me link\n\n    if (typeof requestAnimationFrame !== 'function') {\n      // Using console['error'] to evade Babel and ESLint\n      console['error'](\"This browser doesn't support requestAnimationFrame. \" + 'Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');\n    }\n\n    if (typeof cancelAnimationFrame !== 'function') {\n      // Using console['error'] to evade Babel and ESLint\n      console['error'](\"This browser doesn't support cancelAnimationFrame. \" + 'Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');\n    }\n  }\n\n  if (typeof performance === 'object' && typeof performance.now === 'function') {\n    exports.unstable_now = function () {\n      return performance.now();\n    };\n  } else {\n    var _initialTime = _Date.now();\n\n    exports.unstable_now = function () {\n      return _Date.now() - _initialTime;\n    };\n  }\n\n  var isMessageLoopRunning = false;\n  var scheduledHostCallback = null;\n  var taskTimeoutID = -1; // Scheduler periodically yields in case there is other work on the main\n  // thread, like user events. By default, it yields multiple times per frame.\n  // It does not attempt to align with frame boundaries, since most tasks don't\n  // need to be frame aligned; for those that do, use requestAnimationFrame.\n\n  var yieldInterval = 5;\n  var deadline = 0; // TODO: Make this configurable\n\n  {\n    // `isInputPending` is not available. Since we have no way of knowing if\n    // there's pending input, always yield at the end of the frame.\n    shouldYieldToHost = function () {\n      return exports.unstable_now() >= deadline;\n    }; // Since we yield every frame regardless, `requestPaint` has no effect.\n\n\n    requestPaint = function () {};\n  }\n\n  exports.unstable_forceFrameRate = function (fps) {\n    if (fps < 0 || fps > 125) {\n      // Using console['error'] to evade Babel and ESLint\n      console['error']('forceFrameRate takes a positive int between 0 and 125, ' + 'forcing framerates higher than 125 fps is not unsupported');\n      return;\n    }\n\n    if (fps > 0) {\n      yieldInterval = Math.floor(1000 / fps);\n    } else {\n      // reset the framerate\n      yieldInterval = 5;\n    }\n  };\n\n  var performWorkUntilDeadline = function () {\n    if (scheduledHostCallback !== null) {\n      var currentTime = exports.unstable_now(); // Yield after `yieldInterval` ms, regardless of where we are in the vsync\n      // cycle. This means there's always time remaining at the beginning of\n      // the message event.\n\n      deadline = currentTime + yieldInterval;\n      var hasTimeRemaining = true;\n\n      try {\n        var hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime);\n\n        if (!hasMoreWork) {\n          isMessageLoopRunning = false;\n          scheduledHostCallback = null;\n        } else {\n          // If there's more work, schedule the next message event at the end\n          // of the preceding one.\n          port.postMessage(null);\n        }\n      } catch (error) {\n        // If a scheduler task throws, exit the current browser task so the\n        // error can be observed.\n        port.postMessage(null);\n        throw error;\n      }\n    } else {\n      isMessageLoopRunning = false;\n    } // Yielding to the browser will give it a chance to paint, so we can\n  };\n\n  var channel = new MessageChannel();\n  var port = channel.port2;\n  channel.port1.onmessage = performWorkUntilDeadline;\n\n  requestHostCallback = function (callback) {\n    scheduledHostCallback = callback;\n\n    if (!isMessageLoopRunning) {\n      isMessageLoopRunning = true;\n      port.postMessage(null);\n    }\n  };\n\n  requestHostTimeout = function (callback, ms) {\n    taskTimeoutID = _setTimeout(function () {\n      callback(exports.unstable_now());\n    }, ms);\n  };\n\n  cancelHostTimeout = function () {\n    _clearTimeout(taskTimeoutID);\n\n    taskTimeoutID = -1;\n  };\n}\n\nfunction push(heap, node) {\n  var index = heap.length;\n  heap.push(node);\n  siftUp(heap, node, index);\n}\nfunction peek(heap) {\n  var first = heap[0];\n  return first === undefined ? null : first;\n}\nfunction pop(heap) {\n  var first = heap[0];\n\n  if (first !== undefined) {\n    var last = heap.pop();\n\n    if (last !== first) {\n      heap[0] = last;\n      siftDown(heap, last, 0);\n    }\n\n    return first;\n  } else {\n    return null;\n  }\n}\n\nfunction siftUp(heap, node, i) {\n  var index = i;\n\n  while (true) {\n    var parentIndex = index - 1 >>> 1;\n    var parent = heap[parentIndex];\n\n    if (parent !== undefined && compare(parent, node) > 0) {\n      // The parent is larger. Swap positions.\n      heap[parentIndex] = node;\n      heap[index] = parent;\n      index = parentIndex;\n    } else {\n      // The parent is smaller. Exit.\n      return;\n    }\n  }\n}\n\nfunction siftDown(heap, node, i) {\n  var index = i;\n  var length = heap.length;\n\n  while (index < length) {\n    var leftIndex = (index + 1) * 2 - 1;\n    var left = heap[leftIndex];\n    var rightIndex = leftIndex + 1;\n    var right = heap[rightIndex]; // If the left or right node is smaller, swap with the smaller of those.\n\n    if (left !== undefined && compare(left, node) < 0) {\n      if (right !== undefined && compare(right, left) < 0) {\n        heap[index] = right;\n        heap[rightIndex] = node;\n        index = rightIndex;\n      } else {\n        heap[index] = left;\n        heap[leftIndex] = node;\n        index = leftIndex;\n      }\n    } else if (right !== undefined && compare(right, node) < 0) {\n      heap[index] = right;\n      heap[rightIndex] = node;\n      index = rightIndex;\n    } else {\n      // Neither child is smaller. Exit.\n      return;\n    }\n  }\n}\n\nfunction compare(a, b) {\n  // Compare sort index first, then task id.\n  var diff = a.sortIndex - b.sortIndex;\n  return diff !== 0 ? diff : a.id - b.id;\n}\n\n// TODO: Use symbols?\nvar NoPriority = 0;\nvar ImmediatePriority = 1;\nvar UserBlockingPriority = 2;\nvar NormalPriority = 3;\nvar LowPriority = 4;\nvar IdlePriority = 5;\n\nvar runIdCounter = 0;\nvar mainThreadIdCounter = 0;\nvar profilingStateSize = 4;\nvar sharedProfilingBuffer =  // $FlowFixMe Flow doesn't know about SharedArrayBuffer\ntypeof SharedArrayBuffer === 'function' ? new SharedArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : // $FlowFixMe Flow doesn't know about ArrayBuffer\ntypeof ArrayBuffer === 'function' ? new ArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : null // Don't crash the init path on IE9\n;\nvar profilingState =  sharedProfilingBuffer !== null ? new Int32Array(sharedProfilingBuffer) : []; // We can't read this but it helps save bytes for null checks\n\nvar PRIORITY = 0;\nvar CURRENT_TASK_ID = 1;\nvar CURRENT_RUN_ID = 2;\nvar QUEUE_SIZE = 3;\n\n{\n  profilingState[PRIORITY] = NoPriority; // This is maintained with a counter, because the size of the priority queue\n  // array might include canceled tasks.\n\n  profilingState[QUEUE_SIZE] = 0;\n  profilingState[CURRENT_TASK_ID] = 0;\n} // Bytes per element is 4\n\n\nvar INITIAL_EVENT_LOG_SIZE = 131072;\nvar MAX_EVENT_LOG_SIZE = 524288; // Equivalent to 2 megabytes\n\nvar eventLogSize = 0;\nvar eventLogBuffer = null;\nvar eventLog = null;\nvar eventLogIndex = 0;\nvar TaskStartEvent = 1;\nvar TaskCompleteEvent = 2;\nvar TaskErrorEvent = 3;\nvar TaskCancelEvent = 4;\nvar TaskRunEvent = 5;\nvar TaskYieldEvent = 6;\nvar SchedulerSuspendEvent = 7;\nvar SchedulerResumeEvent = 8;\n\nfunction logEvent(entries) {\n  if (eventLog !== null) {\n    var offset = eventLogIndex;\n    eventLogIndex += entries.length;\n\n    if (eventLogIndex + 1 > eventLogSize) {\n      eventLogSize *= 2;\n\n      if (eventLogSize > MAX_EVENT_LOG_SIZE) {\n        // Using console['error'] to evade Babel and ESLint\n        console['error'](\"Scheduler Profiling: Event log exceeded maximum size. Don't \" + 'forget to call `stopLoggingProfilingEvents()`.');\n        stopLoggingProfilingEvents();\n        return;\n      }\n\n      var newEventLog = new Int32Array(eventLogSize * 4);\n      newEventLog.set(eventLog);\n      eventLogBuffer = newEventLog.buffer;\n      eventLog = newEventLog;\n    }\n\n    eventLog.set(entries, offset);\n  }\n}\n\nfunction startLoggingProfilingEvents() {\n  eventLogSize = INITIAL_EVENT_LOG_SIZE;\n  eventLogBuffer = new ArrayBuffer(eventLogSize * 4);\n  eventLog = new Int32Array(eventLogBuffer);\n  eventLogIndex = 0;\n}\nfunction stopLoggingProfilingEvents() {\n  var buffer = eventLogBuffer;\n  eventLogSize = 0;\n  eventLogBuffer = null;\n  eventLog = null;\n  eventLogIndex = 0;\n  return buffer;\n}\nfunction markTaskStart(task, ms) {\n  {\n    profilingState[QUEUE_SIZE]++;\n\n    if (eventLog !== null) {\n      // performance.now returns a float, representing milliseconds. When the\n      // event is logged, it's coerced to an int. Convert to microseconds to\n      // maintain extra degrees of precision.\n      logEvent([TaskStartEvent, ms * 1000, task.id, task.priorityLevel]);\n    }\n  }\n}\nfunction markTaskCompleted(task, ms) {\n  {\n    profilingState[PRIORITY] = NoPriority;\n    profilingState[CURRENT_TASK_ID] = 0;\n    profilingState[QUEUE_SIZE]--;\n\n    if (eventLog !== null) {\n      logEvent([TaskCompleteEvent, ms * 1000, task.id]);\n    }\n  }\n}\nfunction markTaskCanceled(task, ms) {\n  {\n    profilingState[QUEUE_SIZE]--;\n\n    if (eventLog !== null) {\n      logEvent([TaskCancelEvent, ms * 1000, task.id]);\n    }\n  }\n}\nfunction markTaskErrored(task, ms) {\n  {\n    profilingState[PRIORITY] = NoPriority;\n    profilingState[CURRENT_TASK_ID] = 0;\n    profilingState[QUEUE_SIZE]--;\n\n    if (eventLog !== null) {\n      logEvent([TaskErrorEvent, ms * 1000, task.id]);\n    }\n  }\n}\nfunction markTaskRun(task, ms) {\n  {\n    runIdCounter++;\n    profilingState[PRIORITY] = task.priorityLevel;\n    profilingState[CURRENT_TASK_ID] = task.id;\n    profilingState[CURRENT_RUN_ID] = runIdCounter;\n\n    if (eventLog !== null) {\n      logEvent([TaskRunEvent, ms * 1000, task.id, runIdCounter]);\n    }\n  }\n}\nfunction markTaskYield(task, ms) {\n  {\n    profilingState[PRIORITY] = NoPriority;\n    profilingState[CURRENT_TASK_ID] = 0;\n    profilingState[CURRENT_RUN_ID] = 0;\n\n    if (eventLog !== null) {\n      logEvent([TaskYieldEvent, ms * 1000, task.id, runIdCounter]);\n    }\n  }\n}\nfunction markSchedulerSuspended(ms) {\n  {\n    mainThreadIdCounter++;\n\n    if (eventLog !== null) {\n      logEvent([SchedulerSuspendEvent, ms * 1000, mainThreadIdCounter]);\n    }\n  }\n}\nfunction markSchedulerUnsuspended(ms) {\n  {\n    if (eventLog !== null) {\n      logEvent([SchedulerResumeEvent, ms * 1000, mainThreadIdCounter]);\n    }\n  }\n}\n\n/* eslint-disable no-var */\n// Math.pow(2, 30) - 1\n// 0b111111111111111111111111111111\n\nvar maxSigned31BitInt = 1073741823; // Times out immediately\n\nvar IMMEDIATE_PRIORITY_TIMEOUT = -1; // Eventually times out\n\nvar USER_BLOCKING_PRIORITY = 250;\nvar NORMAL_PRIORITY_TIMEOUT = 5000;\nvar LOW_PRIORITY_TIMEOUT = 10000; // Never times out\n\nvar IDLE_PRIORITY = maxSigned31BitInt; // Tasks are stored on a min heap\n\nvar taskQueue = [];\nvar timerQueue = []; // Incrementing id counter. Used to maintain insertion order.\n\nvar taskIdCounter = 1; // Pausing the scheduler is useful for debugging.\nvar currentTask = null;\nvar currentPriorityLevel = NormalPriority; // This is set while performing work, to prevent re-entrancy.\n\nvar isPerformingWork = false;\nvar isHostCallbackScheduled = false;\nvar isHostTimeoutScheduled = false;\n\nfunction advanceTimers(currentTime) {\n  // Check for tasks that are no longer delayed and add them to the queue.\n  var timer = peek(timerQueue);\n\n  while (timer !== null) {\n    if (timer.callback === null) {\n      // Timer was cancelled.\n      pop(timerQueue);\n    } else if (timer.startTime <= currentTime) {\n      // Timer fired. Transfer to the task queue.\n      pop(timerQueue);\n      timer.sortIndex = timer.expirationTime;\n      push(taskQueue, timer);\n\n      {\n        markTaskStart(timer, currentTime);\n        timer.isQueued = true;\n      }\n    } else {\n      // Remaining timers are pending.\n      return;\n    }\n\n    timer = peek(timerQueue);\n  }\n}\n\nfunction handleTimeout(currentTime) {\n  isHostTimeoutScheduled = false;\n  advanceTimers(currentTime);\n\n  if (!isHostCallbackScheduled) {\n    if (peek(taskQueue) !== null) {\n      isHostCallbackScheduled = true;\n      requestHostCallback(flushWork);\n    } else {\n      var firstTimer = peek(timerQueue);\n\n      if (firstTimer !== null) {\n        requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n      }\n    }\n  }\n}\n\nfunction flushWork(hasTimeRemaining, initialTime) {\n  {\n    markSchedulerUnsuspended(initialTime);\n  } // We'll need a host callback the next time work is scheduled.\n\n\n  isHostCallbackScheduled = false;\n\n  if (isHostTimeoutScheduled) {\n    // We scheduled a timeout but it's no longer needed. Cancel it.\n    isHostTimeoutScheduled = false;\n    cancelHostTimeout();\n  }\n\n  isPerformingWork = true;\n  var previousPriorityLevel = currentPriorityLevel;\n\n  try {\n    if (enableProfiling) {\n      try {\n        return workLoop(hasTimeRemaining, initialTime);\n      } catch (error) {\n        if (currentTask !== null) {\n          var currentTime = exports.unstable_now();\n          markTaskErrored(currentTask, currentTime);\n          currentTask.isQueued = false;\n        }\n\n        throw error;\n      }\n    } else {\n      // No catch in prod codepath.\n      return workLoop(hasTimeRemaining, initialTime);\n    }\n  } finally {\n    currentTask = null;\n    currentPriorityLevel = previousPriorityLevel;\n    isPerformingWork = false;\n\n    {\n      var _currentTime = exports.unstable_now();\n\n      markSchedulerSuspended(_currentTime);\n    }\n  }\n}\n\nfunction workLoop(hasTimeRemaining, initialTime) {\n  var currentTime = initialTime;\n  advanceTimers(currentTime);\n  currentTask = peek(taskQueue);\n\n  while (currentTask !== null && !(enableSchedulerDebugging )) {\n    if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) {\n      // This currentTask hasn't expired, and we've reached the deadline.\n      break;\n    }\n\n    var callback = currentTask.callback;\n\n    if (callback !== null) {\n      currentTask.callback = null;\n      currentPriorityLevel = currentTask.priorityLevel;\n      var didUserCallbackTimeout = currentTask.expirationTime <= currentTime;\n      markTaskRun(currentTask, currentTime);\n      var continuationCallback = callback(didUserCallbackTimeout);\n      currentTime = exports.unstable_now();\n\n      if (typeof continuationCallback === 'function') {\n        currentTask.callback = continuationCallback;\n        markTaskYield(currentTask, currentTime);\n      } else {\n        {\n          markTaskCompleted(currentTask, currentTime);\n          currentTask.isQueued = false;\n        }\n\n        if (currentTask === peek(taskQueue)) {\n          pop(taskQueue);\n        }\n      }\n\n      advanceTimers(currentTime);\n    } else {\n      pop(taskQueue);\n    }\n\n    currentTask = peek(taskQueue);\n  } // Return whether there's additional work\n\n\n  if (currentTask !== null) {\n    return true;\n  } else {\n    var firstTimer = peek(timerQueue);\n\n    if (firstTimer !== null) {\n      requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n    }\n\n    return false;\n  }\n}\n\nfunction unstable_runWithPriority(priorityLevel, eventHandler) {\n  switch (priorityLevel) {\n    case ImmediatePriority:\n    case UserBlockingPriority:\n    case NormalPriority:\n    case LowPriority:\n    case IdlePriority:\n      break;\n\n    default:\n      priorityLevel = NormalPriority;\n  }\n\n  var previousPriorityLevel = currentPriorityLevel;\n  currentPriorityLevel = priorityLevel;\n\n  try {\n    return eventHandler();\n  } finally {\n    currentPriorityLevel = previousPriorityLevel;\n  }\n}\n\nfunction unstable_next(eventHandler) {\n  var priorityLevel;\n\n  switch (currentPriorityLevel) {\n    case ImmediatePriority:\n    case UserBlockingPriority:\n    case NormalPriority:\n      // Shift down to normal priority\n      priorityLevel = NormalPriority;\n      break;\n\n    default:\n      // Anything lower than normal priority should remain at the current level.\n      priorityLevel = currentPriorityLevel;\n      break;\n  }\n\n  var previousPriorityLevel = currentPriorityLevel;\n  currentPriorityLevel = priorityLevel;\n\n  try {\n    return eventHandler();\n  } finally {\n    currentPriorityLevel = previousPriorityLevel;\n  }\n}\n\nfunction unstable_wrapCallback(callback) {\n  var parentPriorityLevel = currentPriorityLevel;\n  return function () {\n    // This is a fork of runWithPriority, inlined for performance.\n    var previousPriorityLevel = currentPriorityLevel;\n    currentPriorityLevel = parentPriorityLevel;\n\n    try {\n      return callback.apply(this, arguments);\n    } finally {\n      currentPriorityLevel = previousPriorityLevel;\n    }\n  };\n}\n\nfunction timeoutForPriorityLevel(priorityLevel) {\n  switch (priorityLevel) {\n    case ImmediatePriority:\n      return IMMEDIATE_PRIORITY_TIMEOUT;\n\n    case UserBlockingPriority:\n      return USER_BLOCKING_PRIORITY;\n\n    case IdlePriority:\n      return IDLE_PRIORITY;\n\n    case LowPriority:\n      return LOW_PRIORITY_TIMEOUT;\n\n    case NormalPriority:\n    default:\n      return NORMAL_PRIORITY_TIMEOUT;\n  }\n}\n\nfunction unstable_scheduleCallback(priorityLevel, callback, options) {\n  var currentTime = exports.unstable_now();\n  var startTime;\n  var timeout;\n\n  if (typeof options === 'object' && options !== null) {\n    var delay = options.delay;\n\n    if (typeof delay === 'number' && delay > 0) {\n      startTime = currentTime + delay;\n    } else {\n      startTime = currentTime;\n    }\n\n    timeout = typeof options.timeout === 'number' ? options.timeout : timeoutForPriorityLevel(priorityLevel);\n  } else {\n    timeout = timeoutForPriorityLevel(priorityLevel);\n    startTime = currentTime;\n  }\n\n  var expirationTime = startTime + timeout;\n  var newTask = {\n    id: taskIdCounter++,\n    callback: callback,\n    priorityLevel: priorityLevel,\n    startTime: startTime,\n    expirationTime: expirationTime,\n    sortIndex: -1\n  };\n\n  {\n    newTask.isQueued = false;\n  }\n\n  if (startTime > currentTime) {\n    // This is a delayed task.\n    newTask.sortIndex = startTime;\n    push(timerQueue, newTask);\n\n    if (peek(taskQueue) === null && newTask === peek(timerQueue)) {\n      // All tasks are delayed, and this is the task with the earliest delay.\n      if (isHostTimeoutScheduled) {\n        // Cancel an existing timeout.\n        cancelHostTimeout();\n      } else {\n        isHostTimeoutScheduled = true;\n      } // Schedule a timeout.\n\n\n      requestHostTimeout(handleTimeout, startTime - currentTime);\n    }\n  } else {\n    newTask.sortIndex = expirationTime;\n    push(taskQueue, newTask);\n\n    {\n      markTaskStart(newTask, currentTime);\n      newTask.isQueued = true;\n    } // Schedule a host callback, if needed. If we're already performing work,\n    // wait until the next time we yield.\n\n\n    if (!isHostCallbackScheduled && !isPerformingWork) {\n      isHostCallbackScheduled = true;\n      requestHostCallback(flushWork);\n    }\n  }\n\n  return newTask;\n}\n\nfunction unstable_pauseExecution() {\n}\n\nfunction unstable_continueExecution() {\n\n  if (!isHostCallbackScheduled && !isPerformingWork) {\n    isHostCallbackScheduled = true;\n    requestHostCallback(flushWork);\n  }\n}\n\nfunction unstable_getFirstCallbackNode() {\n  return peek(taskQueue);\n}\n\nfunction unstable_cancelCallback(task) {\n  {\n    if (task.isQueued) {\n      var currentTime = exports.unstable_now();\n      markTaskCanceled(task, currentTime);\n      task.isQueued = false;\n    }\n  } // Null out the callback to indicate the task has been canceled. (Can't\n  // remove from the queue because you can't remove arbitrary nodes from an\n  // array based heap, only the first one.)\n\n\n  task.callback = null;\n}\n\nfunction unstable_getCurrentPriorityLevel() {\n  return currentPriorityLevel;\n}\n\nfunction unstable_shouldYield() {\n  var currentTime = exports.unstable_now();\n  advanceTimers(currentTime);\n  var firstTask = peek(taskQueue);\n  return firstTask !== currentTask && currentTask !== null && firstTask !== null && firstTask.callback !== null && firstTask.startTime <= currentTime && firstTask.expirationTime < currentTask.expirationTime || shouldYieldToHost();\n}\n\nvar unstable_requestPaint = requestPaint;\nvar unstable_Profiling =  {\n  startLoggingProfilingEvents: startLoggingProfilingEvents,\n  stopLoggingProfilingEvents: stopLoggingProfilingEvents,\n  sharedProfilingBuffer: sharedProfilingBuffer\n} ;\n\nexports.unstable_IdlePriority = IdlePriority;\nexports.unstable_ImmediatePriority = ImmediatePriority;\nexports.unstable_LowPriority = LowPriority;\nexports.unstable_NormalPriority = NormalPriority;\nexports.unstable_Profiling = unstable_Profiling;\nexports.unstable_UserBlockingPriority = UserBlockingPriority;\nexports.unstable_cancelCallback = unstable_cancelCallback;\nexports.unstable_continueExecution = unstable_continueExecution;\nexports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;\nexports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;\nexports.unstable_next = unstable_next;\nexports.unstable_pauseExecution = unstable_pauseExecution;\nexports.unstable_requestPaint = unstable_requestPaint;\nexports.unstable_runWithPriority = unstable_runWithPriority;\nexports.unstable_scheduleCallback = unstable_scheduleCallback;\nexports.unstable_shouldYield = unstable_shouldYield;\nexports.unstable_wrapCallback = unstable_wrapCallback;\n  })();\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n  module.exports = require('./cjs/scheduler.development.js');\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/scheduler-tracing.production.min.js');\n} else {\n  module.exports = require('./cjs/scheduler-tracing.development.js');\n}\n","var api = require(\"!../style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n            var content = require(\"!!../css-loader/dist/cjs.js!./semantic.min.css\");\n\n            content = content.__esModule ? content.default : content;\n\n            if (typeof content === 'string') {\n              content = [[module.id, content, '']];\n            }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\nif (module.hot) {\n  if (!content.locals || module.hot.invalidate) {\n    var isEqualLocals = function isEqualLocals(a, b) {\n  if (!a && b || a && !b) {\n    return false;\n  }\n\n  var p;\n\n  for (p in a) {\n    if (a[p] !== b[p]) {\n      return false;\n    }\n  }\n\n  for (p in b) {\n    if (!a[p]) {\n      return false;\n    }\n  }\n\n  return true;\n};\n    var oldLocals = content.locals;\n\n    module.hot.accept(\n      \"!!../css-loader/dist/cjs.js!./semantic.min.css\",\n      function () {\n        content = require(\"!!../css-loader/dist/cjs.js!./semantic.min.css\");\n\n              content = content.__esModule ? content.default : content;\n\n              if (typeof content === 'string') {\n                content = [[module.id, content, '']];\n              }\n\n              if (!isEqualLocals(oldLocals, content.locals)) {\n                module.hot.invalidate();\n\n                return;\n              }\n\n              oldLocals = content.locals;\n\n              update(content);\n      }\n    )\n  }\n\n  module.hot.dispose(function() {\n    update();\n  });\n}\n\nmodule.exports = content.locals || {};","export default \"data:application/vnd.ms-fontobject;base64,UIEBAGSAAQABAAIAAAAAAAIABQMAAAAAAAABAJABAAAAAExQAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA3vSogwAAAAAAAAAAAAAAAAAAAAAAACoARgBvAG4AdAAgAEEAdwBlAHMAbwBtAGUAIAA1ACAAQgByAGEAbgBkAHMAAAAOAFIAZQBnAHUAbABhAHIAAAAWAFYAZQByAHMAaQBvAG4AIAA1AC4AMAAAADoARgBvAG4AdAAgAEEAdwBlAHMAbwBtAGUAIAA1ACAAQgByAGEAbgBkAHMAIABSAGUAZwB1AGwAYQByAAAAAAAAAQAAAAsAgAADADBHU1VCIIslegAAATgAAABUT1MvMkA6ULgAAAGMAAAAVmNtYXD/ORciAAAHEAAAFjZnbHlmmIZOAAAAH+AAAU5caGVhZA8Ug3oAAADgAAAANmhoZWEEPAN7AAAAvAAAACRobXR4cZv/YgAAAeQAAAUsbG9jYV5lsIQAAB1IAAACmG1heHACfAH/AAABGAAAACBuYW1lXwq07gABbjwAAAMqcG9zdK/tkvcAAXFoAAAO+QABAAABwP/AAAACgP/0/+8ChQABAAAAAAAAAAAAAAAAAAABSwABAAAAAQAAg6j03l8PPPUACwIAAAAAANa+IX4AAAAA1r4hfv/0/7kChQHIAAAACAACAAAAAAAAAAEAAAFLAfMAJwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAAAAAABAAAABAAAAAAAAAABAAAAAWxpZ2EACAAAAAEAAAABAAQABAAAAAEACAABAAYAAAABAAAAAQHkAZAABQAAAZYBZgAAAEcBlgFmAAAA9QAZAIQAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA8IH0WQHA/8AALgHIAEcAAAABAAAAAAAAAAAAAAHAAAABwAAAAoD//QHwAAACAAAAAgD//wHAAAACY///AcAAAAHAAAABwAAAAcAAAAKA//0BnwAAAcAAAAIAAAACgAAAAoD/+wF4AAACQAAAAoAAAAKAAAACAP/7AoAAAAIA//4B8AAAAcAAAAJAAAABwP//AgAAAAIAAAAB8P/3AcAAAAIAAAABwP//AcAAAAFAAAABwAAAAYAAAAHAAAABwAAAAkAAAAJA//8CQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAIAAAAB8P//AcAAAAFMAAACaAAAAgD//wHYAAACQAAAAgAAAAKA//sCAAAAAYAAAAIAAAABuAAAAkAAAAHAAAABwAAAAgD//wHg//4BQAAAAgAAAAIAAAABwAAAAcAAAAGgAAACgP/7AeAAAAHAAAACAAAAAhAAAAHAAAABoAAAAeD/+wIAAAABwP//AoD//wHwAAABwAAAAoAAAAFAAAABgAAAAfAAAAEIAAABwP/4AcAAAAHAAAAB4AAAAcAAAAGAAAABwAAAAcAAAAGAAAABwAAAAcAAAAHAAAABgAAAAcAAAAIAAAACAAAAAcAAAAFw//8CQAAAAcD/+gHAAAACAAAAAgAAAAHAAAABwAAAAeAAAAHAAAAB8AAAAlAAAAIA//8BgAAAAcAAAAHAAAABkP//AYAAAAHAAAACAAAAAgAAAAKAAAABwAAAAfAAAAHAAAAB6AAAAfAAAAIAAAABgAAAAYAAAAEAAAABwAAAAcAAAAKAAAACAAAAAoD//wHA//QBQAAAAYAAAAIAAAABwAAAAcD//wIAAAACgAAAAYD//wHAAAACAAAAAfD//gHAAAABwAAAAcAAAAJA//8CAAAAAYAAAAHAAAABvv//AoD/+gHAAAACAAAAAkAAAAKAAAABwP//AcD//wHA//8BwAAAAcAAAAIAAAABwAAAAgAAAAFAAAACAAAAAcAAAAIgAAACAP/+AcAAAAHAAAACgAAAAfAAAAHAAAAB8AAAAfD/+gHA//8BwAAAAoAAAAJAAAACgAAAAZAAAAHAAAABQAAAAoD//wHAAAAB8AAAAkD//wHvAAAB8AAAAYD//gJAAAACAAAAAYD//wHAAAAB8P//AoAAAAKAAAACQAAAAcAAAAKA//8BgAAAAcAAAAHw//8CQP//AgAAAAGw//0BwP//AcAAAAHpAAABwAAAAgAAAAIA//8CAAAAAcAAAAIAAAABwAAAAgAAAAHwAAACAAAAAcD//wHwAAABwAAAAfAAAAIAAAACgP/9AcAAAAGAAAABzAAAAcAAAAKAAAAB8AAAAcAAAAIAAAABwP//AoAAAAHAAAABwP/9AcD/+wIAAAACAP//AcAAAAHwAAACgAAAAcAAAAHwAAABwAAAAYAAAAG4//8BwAAAAcAAAAHwAAACQP/+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ASYAAPKIAADyiAAAAN4AAPKJAADyiQAAALwAAPKKAADyigAAAPQAAPKTAADykwAAACYAAPKUAADylAAAACUAAPKWAADylgAAAHwAAPKXAADylwAAAT0AAPKYAADymAAAAT8AAPKZAADymQAAAFkAAPKlAADypQAAAH8AAPKmAADypgAAAH4AAPKpAADyqQAAASsAAPKqAADyqgAAASoAAPKrAADyqwAAAQMAAPKsAADyrAAAAQEAAPKtAADyrQAAAQIAAPKuAADyrgAAANkAAPKwAADysAAAAGMAAPKxAADysQAAAUgAAPKyAADysgAAARkAAPKzAADyswAAAIcAAPK0AADytAAAAGoAAPK4AADyuAAAALAAAPLEAADyxAAAAOMAAPLFAADyxQAAAHEAAPLGAADyxgAAARcAAPLVAADy1QAAABoAAPLWAADy1gAAAIsAAPLXAADy1wAAAFwAAPLYAADy2AAAAJgAAPLZAADy2QAAAOQAAPLaAADy2gAAAPYAAPLdAADy3QAAARQAAPLeAADy3gAAAT4AAPLgAADy4AAAALkAAPNcAADzXAAAAGgAAPNoAADzaAAAAAIAAPNpAADzaQAAAAMAAPNqAADzagAAAAUAAPNrAADzawAAAAYAAPNsAADzbAAAAAcAAPNtAADzbQAAAAoAAPNuAADzbgAAAA0AAPNvAADzbwAAABAAAPNwAADzcAAAAA8AAPNxAADzcQAAABEAAPNyAADzcgAAABQAAPNzAADzcwAAABUAAPN0AADzdAAAABcAAPN1AADzdQAAABkAAPN4AADzeAAAAB0AAPN5AADzeQAAAB8AAPN6AADzegAAACAAAPN7AADzewAAACIAAPN8AADzfAAAACQAAPN9AADzfQAAACMAAPN/AADzfwAAACgAAPOAAADzgAAAADQAAPODAADzgwAAADYAAPOEAADzhAAAADcAAPOFAADzhQAAADgAAPOIAADziAAAAD0AAPOLAADziwAAAD8AAPOMAADzjAAAAEEAAPONAADzjQAAAEIAAPOOAADzjgAAAEUAAPOPAADzjwAAAEYAAPORAADzkQAAAEkAAPOSAADzkgAAAEoAAPOTAADzkwAAAEsAAPOUAADzlAAAAEwAAPOVAADzlQAAAE0AAPOWAADzlgAAAE4AAPOXAADzlwAAAE8AAPOZAADzmQAA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AEEAdwBlAHMAbwBtAGUAIAA1ACAAQgByAGEAbgBkAHMAIABSAGUAZwB1AGwAYQByAEYAbwBuAHQAIABBAHcAZQBzAG8AbQBlACAANQAgAEIAcgBhAG4AZABzACAAUgBlAGcAdQBsAGEAcgBWAGUAcgBzAGkAbwBuACAANQAuADAARgBvAG4AdABBAHcAZQBzAG8AbQBlADUAQgByAGEAbgBkAHMAUgBlAGcAdQBsAGEAcgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAACAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUsBAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8BgAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGoAakBqgGrAawBrQGuAa8BsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAAFNTAwcHgPYWNjZXNzaWJsZS1pY29uCGFjY3Vzb2Z0A2FkbghhZHZlcnNhbA5hZmZpbGlhdGV0aGVtZQdhbGdvbGlhCmFtYXpvbi1wYXkGYW1hem9uBmFtaWxpYQdhbmRyb2lkCWFuZ2VsbGlzdA1hbmdyeWNyZWF0aXZlB2FuZ3VsYXINYXBwLXN0b3JlLWlvcwlhcHAtc3RvcmUFYXBwZXIJYXBwbGUtcGF5BWFwcGxlCmFzeW1tZXRyaWsHYXVkaWJsZQxhdXRvcHJlZml4ZXIHYXZpYW5leAZhdmlhdG8DYXdzCGJhbmRjYW1wDmJlaGFuY2Utc3F1YXJlB2JlaGFuY2UJYmltb2JqZWN0CWJpdGJ1Y2tldAdiaXRjb2luBGJpdHkJYmxhY2stdGllCmJsYWNrYmVycnkJYmxvZ2dlci1iB2Jsb2dnZXILYmx1ZXRvb3RoLWIJYmx1ZXRvb3RoA2J0YxBidXJvbW9iZWxleHBlcnRlCmJ1eXNlbGxhZHMNY2MtYW1hem9uLXBheQdjYy1hbWV4DGNjLWFwcGxlLXBheQ5jYy1kaW5lcnMtY2x1YgtjYy1kaXNjb3ZlcgZjYy1qY2INY2MtbWFzdGVyY2FyZAljYy1wYXlwYWwJY2Mtc3RyaXBlB2NjLXZpc2EKY2VudGVyY29kZQZjaHJvbWUKY2xvdWRzY2FsZQpjbG91ZHNtaXRoDGNsb3VkdmVyc2lmeQdjb2RlcGVuCGNvZGllcGllDmNvbm5lY3RkZXZlbG9wBmNvbnRhbwZjcGFuZWwQY3JlYXRpdmUtY29tbW9ucwhjc3MzLWFsdARjc3MzCmN1dHRsZWZpc2gHZC1hbmQtZAhkYXNoY3ViZQlkZWxpY2lvdXMJZGVwbG95ZG9nB2Rlc2twcm8KZGV2aWFudGFydARkaWdnDWRpZ2l0YWwtb2NlYW4HZGlzY29yZAlkaXNjb3Vyc2UGZG9jaHViBmRvY2tlcg1kcmFmdDJkaWdpdGFsD2RyaWJiYmxlLXNxdWFyZQhkcmliYmJsZQdkcm9wYm94BmRydXBhbAZkeWFsb2cKZWFybHliaXJkcwRlZGdlCWVsZW1lbnRvcgVlbWJlcgZlbXBpcmUGZW52aXJhBmVybGFuZwhldGhlcmV1bQRldHN5DGV4cGVkaXRlZHNzbApmYWNlYm9vay1mEmZhY2Vib29rLW1lc3Nlbmdlcg9mYWNlYm9vay1zcXVhcmUIZmFjZWJvb2sHZmlyZWZveAtmaXJzdC1vcmRlcgpmaXJzdGRyYWZ0BmZsaWNrcglmbGlwYm9hcmQDZmx5EGZvbnQtYXdlc29tZS1hbHQRZm9udC1hd2Vzb21lLWZsYWcMZm9udC1hd2Vzb21lDGZvbnRpY29ucy1maQlmb250aWNvbnMQZm9ydC1hd2Vzb21lLWFsdAxmb3J0LWF3ZXNvbWUIZm9ydW1iZWUKZm91cnNxdWFyZQ5mcmVlLWNvZGUtY2FtcAdmcmVlYnNkCmdldC1wb2NrZXQJZ2ctY2lyY2xlAmdnCmdpdC1zcXVhcmUDZ2l0CmdpdGh1Yi1hbHQNZ2l0aHViLXNxdWFyZQZnaXRodWIJZ2l0a3Jha2VuBmdpdGxhYgZnaXR0ZXIHZ2xpZGUtZwVnbGlkZQZnb2ZvcmULZ29vZHJlYWRzLWcJZ29vZHJlYWRzDGdvb2dsZS1kcml2ZQtnb29nbGUtcGxheQ1nb29nbGUtcGx1cy1nEmdvb2dsZS1wbHVzLXNxdWFyZQtnb29nbGUtcGx1cw1nb29nbGUtd2FsbGV0Bmdvb2dsZQhncmF0aXBheQRncmF2CGdyaXBmaXJlBWdydW50BGd1bHASaGFja2VyLW5ld3Mtc3F1YXJlC2hhY2tlci1uZXdzBGhpcHMNaGlyZS1hLWhlbHBlcgVob29saQZob3RqYXIFaG91enoFaHRtbDUHaHVic3BvdARpbWRiCWluc3RhZ3JhbRFpbnRlcm5ldC1leHBsb3Jlcgdpb3hob3N0C2l0dW5lcy1ub3RlBml0dW5lcwdqZW5raW5zBWpvZ2V0Bmpvb21sYQlqcy1zcXVhcmUCanMIanNmaWRkbGUGa2V5Y2RuDWtpY2tzdGFydGVyLWsLa2lja3N0YXJ0ZXIGa29ydnVlB2xhcmF2ZWwNbGFzdGZtLXNxdWFyZQZsYXN0Zm0HbGVhbnB1YgRsZXNzBGxpbmULbGlua2VkaW4taW4IbGlua2VkaW4GbGlub2RlBWxpbnV4BGx5ZnQHbWFnZW50bwZtYXhjZG4HbWVkYXBwcwhtZWRpdW0tbQZtZWRpdW0FbWVkcnQGbWVldHVwCW1pY3Jvc29mdANtaXgIbWl4Y2xvdWQGbWl6dW5pBG1vZHgGbW9uZXJvB25hcHN0ZXIPbmludGVuZG8tc3dpdGNoB25vZGUtanMEbm9kZQNucG0DbnM4C251dHJpdGlvbml4FG9kbm9rbGFzc25pa2ktc3F1YXJlDW9kbm9rbGFzc25pa2kIb3BlbmNhcnQGb3BlbmlkBW9wZXJhDW9wdGluLW1vbnN0ZXIDb3NpBXBhZ2U0CXBhZ2VsaW5lcwZwYWxmZWQHcGF0cmVvbgZwYXlwYWwJcGVyaXNjb3BlC3BoYWJyaWNhdG9yEXBob2VuaXgtZnJhbWV3b3JrA3BocA5waWVkLXBpcGVyLWFsdA1waWVkLXBpcGVyLXBwCnBpZWQtcGlwZXILcGludGVyZXN0LXAQcGludGVyZXN0LXNxdWFyZQlwaW50ZXJlc3QLcGxheXN0YXRpb24McHJvZHVjdC1odW50BnB1c2hlZAZweXRob24CcXEJcXVpbnNjYXBlBXF1b3JhB3JhdmVscnkFcmVhY3QFcmViZWwJcmVkLXJpdmVyDHJlZGRpdC1hbGllbg1yZWRkaXQtc3F1YXJlBnJlZGRpdAdyZW5kYWN0BnJlbnJlbgZyZXBseWQJcmVzb2x2aW5nCnJvY2tldGNoYXQHcm9ja3JtcwZzYWZhcmkEc2FzcwZzY2hsaXgGc2NyaWJkC3NlYXJjaGVuZ2luCHNlbGxjYXN0BnNlbGxzeQxzZXJ2aWNlc3RhY2sMc2hpcnRzaW5idWxrC3NpbXBseWJ1aWx0B3Npc3RyaXgIc2t5YXRsYXMFc2t5cGUKc2xhY2staGFzaAVzbGFjawpzbGlkZXNoYXJlDnNuYXBjaGF0LWdob3N0D3NuYXBjaGF0LXNxdWFyZQhzbmFwY2hhdApzb3VuZGNsb3VkB3NwZWFrYXAHc3BvdGlmeQ5zdGFjay1leGNoYW5nZQ5zdGFjay1vdmVyZmxvdwpzdGF5bGlua2VkDHN0ZWFtLXNxdWFyZQxzdGVhbS1zeW1ib2wFc3RlYW0Mc3RpY2tlci1tdWxlBnN0cmF2YQhzdHJpcGUtcwZzdHJpcGUMc3R1ZGlvdmluYXJpEnN0dW1ibGV1cG9uLWNpcmNsZQtzdHVtYmxldXBvbgtzdXBlcnBvd2VycwZzdXBwbGUOdGVsZWdyYW0tcGxhbmUIdGVsZWdyYW0NdGVuY2VudC13ZWlibwl0aGVtZWlzbGUGdHJlbGxvC3RyaXBhZHZpc29yDXR1bWJsci1zcXVhcmUGdHVtYmxyBnR3aXRjaA50d2l0dGVyLXNxdWFyZQd0d2l0dGVyBXR5cG8zBHViZXIFdWlraXQLdW5pcmVnaXN0cnkHdW50YXBwZAN1c2IIdXNzdW5uYWgGdmFhZGluB3ZpYWNvaW4NdmlhZGVvLXNxdWFyZQZ2aWFkZW8FdmliZXIMdmltZW8tc3F1YXJlB3ZpbWVvLXYFdmltZW8EdmluZQJ2awN2bnYFdnVlanMFd2VpYm8Gd2VpeGluD3doYXRzYXBwLXNxdWFyZQh3aGF0c2FwcAV3aG1jcwt3aWtpcGVkaWEtdwd3aW5kb3dzEHdvcmRwcmVzcy1zaW1wbGUJd29yZHByZXNzCndwYmVnaW5uZXIKd3BleHBsb3Jlcgd3cGZvcm1zBHhib3gLeGluZy1zcXVhcmUEeGluZwx5LWNvbWJpbmF0b3IFeWFob28UeWFuZGV4LWludGVybmF0aW9uYWwGeWFuZGV4BHllbHAFeW9hc3QOeW91dHViZS1zcXVhcmUHeW91dHViZQAAAAAA\"","export default __webpack_public_path__ + \"6729d29753e000c17489ed43135ba8d5.svg\";","export default \"data:font/ttf;base64,AAEAAAALAIAAAwAwR1NVQiCLJXoAAAE4AAAAVE9TLzJAOlC4AAABjAAAAFZjbWFw/zkXIgAABxAAABY2Z2x5ZpiGTgAAAB/gAAFOXGhlYWQPFIN6AAAA4AAAADZoaGVhBDwDewAAALwAAAAkaG10eHGb/2IAAAHkAAAFLGxvY2FeZbCEAAAdSAAAAphtYXhwAnwB/wAAARgAAAAgbmFtZV8KtO4AAW48AAADKnBvc3Sv7ZL3AAFxaAAADvkAAQAAAcD/wAAAAoD/9P/vAoUAAQAAAAAAAAAAAAAAAAAAAUsAAQAAAAEAAIOiGXZfDzz1AAsCAAAAAADWviF+AAAAANa+IX7/9P+5AoUByAAAAAgAAgAAAAAAAAABAAABSwHzACcAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAEB5AGQAAUAAAGWAWYAAABHAZYBZgAAAPUAGQCEAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQPCB9FkBwP/AAC4ByABHAAAAAQAAAAAAAAAAAAABwAAAAcAAAAKA//0B8AAAAgAAAAIA//8BwAAAAmP//wHAAAABwAAAAcAAAAHAAAACgP/9AZ8AAAHAAAACAAAAAoAAAAKA//sBeAAAAkAAAAKAAAACgAAAAgD/+wKAAAACAP/+AfAAAAHAAAACQAAAAcD//wIAAAACAAAAAfD/9wHAAAACAAAAAcD//wHAAAABQAAAAcAAAAGAAAABwAAAAcAAAAJAAAACQP//AkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACAAAAAfD//wHAAAABTAAAAmgAAAIA//8B2AAAAkAAAAIAAAACgP/7AgAAAAGAAAACAAAAAbgAAAJAAAABwAAAAcAAAAIA//8B4P/+AUAAAAIAAAACAAAAAcAAAAHAAAABoAAAAoD/+wHgAAABwAAAAgAAAAIQAAABwAAAAaAAAAHg//sCAAAAAcD//wKA//8B8AAAAcAAAAKAAAABQAAAAYAAAAHwAAABCAAAAcD/+AHAAAABwAAAAeAAAAHAAAABgAAAAcAAAAHAAAABgAAAAcAAAAHAAAABwAAAAYAAAAHAAAACAAAAAgAAAAHAAAABcP//AkAAAAHA//oBwAAAAgAAAAIAAAABwAAAAcAAAAHgAAABwAAAAfAAAAJQAAACAP//AYAAAAHAAAABwAAAAZD//wGAAAABwAAAAgAAAAIAAAACgAAAAcAAAAHwAAABwAAAAegAAAHwAAACAAAAAYAAAAGAAAABAAAAAcAAAAHAAAACgAAAAgAAAAKA//8BwP/0AUAAAAGAAAACAAAAAcAAAAHA//8CAAAAAoAAAAGA//8BwAAAAgAAAAHw//4BwAAAAcAAAAHAAAACQP//AgAAAAGAAAABwAAAAb7//wKA//oBwAAAAgAAAAJAAAACgAAAAcD//wHA//8BwP//AcAAAAHAAAACAAAAAcAAAAIAAAABQAAAAgAAAAHAAAACIAAAAgD//gHAAAABwAAAAoAAAAHwAAABwAAAAfAAAAHw//oBwP//AcAAAAKAAAACQAAAAoAAAAGQAAABwAAAAUAAAAKA//8BwAAAAfAAAAJA//8B7wAAAfAAAAGA//4CQAAAAgAAAAGA//8BwAAAAfD//wKAAAACgAAAAkAAAAHAAAACgP//AYAAAAHAAAAB8P//AkD//wIAAAABsP/9AcD//wHAAAAB6QAAAcAAAAIAAAACAP//AgAAAAHAAAACAAAAAcAAAAIAAAAB8AAAAgAAAAHA//8B8AAAAcAAAAHwAAACAAAAAoD//QHAAAABgAAAAcwAAAHAAAACgAAAAfAAAAHAAAACAAAAAcD//wKAAAABwAAAAcD//QHA//sCAAAAAgD//wHAAAAB8AAAAoAAAAHAAAAB8AAAAcAAAAGAAAABuP//AcAAAAHAAAAB8AAAAkD//gFxAAABagAAAoAAAAIAAAAB8AAAAgAAAAHAAAACgP//AcD//wHwAAABgAAAAgD//wHAAAACQP/9AcAAAAFAAAABwAAAAcAAAAIA//8BsQAAAcAAAAHAAAABgAAAAoAAAAKA//8CAAAAAcAAAAGAAAABwAAAAcD//gIAAAABwAAAAcAAAAHA//8BgAAAAkAAAAKA//8BwAAAAgAAAAJAAAABwAAAAcAAAAHA//8CgP//AcAAAAIAAAACAAAAAgAAAAIAAAABwAAAAgAAAAHAAAABgP/+AcAAAAHAAAABQAAAAQAAAAGA//4BwP//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8JoAAABhAADwmwAA8JsAAAB6AADw0gAA8NIAAADcAADw0wAA8NMAAADbAADw1AAA8NQAAACGAADw1QAA8NUAAACFAADw4QAA8OEAAACuAADxEwAA8RMAAAB4AADxNgAA8TYAAAC0AADxOwAA8TsAAACWAADxPAAA8TwAAABAAADxWgAA8VoAAAAnAADxZwAA8WcAAAFKAADxaAAA8WgAAAFCAADxaQAA8WkAAAFBAADxawAA8WsAAABRAADxbAAA8WwAAAEIAADxbQAA8W0AAACZAADxbgAA8W4AAABlAADxcAAA8XAAAAAEAADxcQAA8XEAAAAeAADxcwAA8XMAAAEdAADxdAAA8XQAAAEcAADxeQAA8XkAAAATAADxegAA8XoAAAE6AADxewAA8XsAAAALAADxfAAA8XwAAACxAADxfQAA8X0AAABQAADxfgAA8X4AAAD9AADxgAAA8YAAAABwAADxgQAA8YEAAAEaAADxhAAA8YQAAACKAADxiQAA8YkAAAExAADxigAA8YoAAAE0AADxiwAA8YsAAADsAADxjAAA8YwAAADPAADxjQAA8Y0AAAEHAADxlAAA8ZQAAAEtAADxmAAA8ZgAAAD/AADxmgAA8ZoAAAE8AADxmwAA8ZsAAADKAADxngAA8Z4AAAFEAADxoAAA8aAAAACJAADxoQAA8aEAAADqAADxogAA8aIAAADpAADxowAA8aMAAAESAADxpAAA8aQAAAETAADxpQAA8aUAAABEAADxpgAA8aYAAABIAADxpwAA8acAAADYAADxqAAA8agAAADXAADxqQAA8akAAABSAADxqgAA8aoAAACgAADxtAAA8bQAAAAcAADxtQAA8bUAAAAbAADxtgAA8bYAAAEMAADxtwAA8bcAAAEKAADxvAAA8bwAAAEGAADxvQAA8b0AAABHAADxvgAA8b4AAAEEAADxygAA8coAAAEwAADxywAA8csAAAA5AADxzAAA8cwAAACjAADx0AAA8dAAAADmAADx0QAA8dEAAABYAADx0gAA8dIAAAB2AADx0wAA8dMAAAB3AADx1AAA8dQAAACQAADx1QAA8dUAAAEYAADx1gAA8dYAAADhAADx1wAA8dcAAAE1AADx5wAA8ecAAAEAAADx6AAA8egAAAEeAADx6QAA8ekAAAFHAADx7QAA8e0AAADSAADx7gAA8e4AAACIAADx8AAA8fAAAAAzAADx8QAA8fEAAAAwAADx8gAA8fIAAAAuAADx8wAA8fMAAAArAADx9AAA8fQAAAAxAADx9QAA8fUAAAAyAADyAgAA8gIAAACqAADyAwAA8gMAAACpAADyCAAA8ggAAACbAADyCQAA8gkAAAAMAADyDQAA8g0AAAApAADyDgAA8g4AAAA7AADyEAAA8hAAAABDAADyEQAA8hEAAABvAADyEgAA8hIAAACrAADyEwAA8hMAAAD3AADyFAAA8hQAAAD5AADyFQAA8hUAAAD6AADyFgAA8hYAAAD8AADyMQAA8jEAAADaAADyMgAA8jIAAAE3AADyNwAA8jcAAAEpAADyOgAA8joAAAC3AADyOwAA8jsAAAFDAADyPAAA8jwAAADMAADyPQAA8j0AAADJAADyPgAA8j4AAABdAADySwAA8ksAAAAvAADyTAAA8kwAAAAtAADyXgAA8l4AAAA+AADyYAAA8mAAAAB1AADyYQAA8mEAAAB0AADyYgAA8mIAAAEbAADyYwAA8mMAAADIAADyZAAA8mQAAADHAADyZQAA8mUAAABzAADyZgAA8mYAAAE5AADyZwAA8mcAAADxAADyaAAA8mgAAAA1AADyaQAA8mkAAABiAADyagAA8moAAADLAADyawAA8msAAACaAADybQAA8m0AAAA8AADybgAA8m4AAAABAADycAAA8nAAAAAJAADyfAAA8nwAAACVAADyfQAA8n0AAAEuAADyfgAA8n4AAAAhAADygAAA8oAAAABsAADygQAA8oEAAADoAADyggAA8oIAAABVAADyhAAA8oQAAAA6AADyhQAA8oUAAAC+AADyhgAA8oYAAABuAADyhwAA8ocAAAEmAADyiAAA8ogAAADeAADyiQAA8okAAAC8AADyigAA8ooAAAD0AADykwAA8pMAAAAmAADylAAA8pQAAAAlAADylgAA8pYAAAB8AADylwAA8pcAAAE9AADymAAA8pgAAAE/AADymQAA8pkAAABZAADypQAA8qUAAAB/AADypgAA8qYAAAB+AADyqQAA8qkAAAErAADyqgAA8qoAAAEqAADyqwAA8qsAAAEDAADyrAAA8qwAAAEBAADyrQAA8q0AAAECAADyrgAA8q4AAADZAADysAAA8rAAAABjAADysQAA8rEAAAFIAADysgAA8rIAAAEZAADyswAA8rMAAACHAADytAAA8rQAAABqAADyuAAA8rgAAACwAADyxAAA8sQAAADjAADyxQAA8sUAAABxAADyxgAA8sYAAAEXAADy1QAA8tUAAAAaAADy1gAA8tYAAACLAADy1wAA8tcAAABcAADy2AAA8tgAAACYAADy2QAA8tkAAADkAADy2gAA8toAAAD2AADy3QAA8t0AAAEUAADy3gAA8t4AAAE+AADy4AAA8uAAAAC5AADzXAAA81wAAABoAADzaAAA82gAAAACAADzaQAA82kAAAADAADzagAA82oAAAAFAADzawAA82sAAAAGAADzbAAA82wAAAAHAADzbQAA820AAAAKAADzbgAA824AAAANAADzbwAA828AAAAQAADzcAAA83AAAAAPAADzcQAA83EAAAARAADzcgAA83IAAAAUAADzcwAA83MAAAAVAADzdAAA83QAAAAXAADzdQAA83UAAAAZAADzeAAA83gAAAAdAADzeQAA83kAAAAfAADzegAA83oAAAAgAADzewAA83sAAAAiAADzfAAA83wAAAAkAADzfQAA830AAAAjAADzfwAA838AAAAoAADzgAAA84AAAAA0AADzgwAA84MAAAA2AADzhAAA84QAAAA3AADzhQAA84UAAAA4AADziAAA84gAAAA9AADziwAA84sAAAA/AADzjAAA84wAAABBAADzjQAA840AAABCAADzjgAA844AAABFAADzjwAA848AAABGAADzkQAA85EAAABJAADzkgAA85IAAABKAADzkwAA85MAAABLAADzlAAA85QAAABMAADzlQAA85UAAABNAADzlgAA85YAAABOAADzlwAA85cAAABPAADzmQAA85kAAABTAADzmgAA85oAAABUAADznQAA850AAABaAADzngAA854AAABeAADznwAA858AAABfAADzoQAA86EAAABkAADzogAA86IAAABrAADzowAA86MAAABtAADzpAAA86QAAAByAADzpgAA86YAAAB7AADzpwAA86cAAACAAADzqAAA86gAAACCAADzqQAA86kAAACBAADzqgAA86oAAACDAADzqwAA86sAAACEAADzrAAA86wAAACMAADzrQAA860AAACNAADzrgAA864AAACOAADzrwAA868AAACPAADzsAAA87AAAACSAADzsQAA87EAAACUAADzsgAA87IAAACXAADztAAA87QAAACdAADztQAA87UAAACcAADztgAA87YAAACeAADztwAA87cAAACfAADzuAAA87gAAACiAADzuQAA87kAAAChAADzugAA87oAAACkAADzuwAA87sAAACmAADzvAAA87wAAAClAADzvQAA870AAACoAADzwAAA88AAAACtAADzwwAA88MAAACyAADzxAAA88QAAACzAADzxgAA88YAAAC1AADzxwAA88cAAAC2AADzyAAA88gAAAC4AADzygAA88oAAAC6AADzywAA88sAAAC7AADzzAAA88wAAAC9AADz0AAA89AAAAC/AADz0gAA89IAAADAAADz0wAA89MAAADCAADz1AAA89QAAADEAADz1QAA89UAAADFAADz1gAA89YAAADGAADz1wAA89cAAADOAADz2AAA89gAAADQAADz2QAA89kAAADRAADz2gAA89oAAADTAADz2wAA89sAAADUAADz3AAA89wAAADVAADz3wAA898AAADdAADz4QAA8+EAAADfAADz4gAA8+IAAADgAADz4wAA8+MAAADnAADz5AAA8+QAAADrAADz5gAA8+YAAADtAADz5wAA8+cAAADuAADz6AAA8+gAAADvAADz6QAA8+kAAADwAADz6gAA8+oAAADzAADz6wAA8+sAAAD1AADz7AAA8+wAAAD4AADz7gAA8+4AAAD7AADz7wAA8+8AAAD+AADz8wAA8/MAAAEFAADz9QAA8/UAAAEJAADz9gAA8/YAAAELAADz9wAA8/cAAAENAADz+AAA8/gAAAERAADz+QAA8/kAAAEVAADz/gAA8/4AAAEWAAD0AgAA9AIAAAEiAAD0AwAA9AMAAAEjAAD0BAAA9AQAAAEkAAD0BQAA9AUAAAElAAD0BwAA9AcAAAEnAAD0CAAA9AgAAAEoAAD0CQAA9AkAAAEsAAD0CgAA9AoAAAEvAAD0CwAA9AsAAAEyAAD0DAAA9AwAAAE2AAD0DQAA9A0AAAE4AAD0EQAA9BEAAAE7AAD0EgAA9BIAAAFAAAD0EwAA9BMAAAFGAAD0FAAA9BQAAAFFAAD0FQAA9BUAAAASAAD0FgAA9BYAAAAsAAD0FwAA9BcAAABnAAD0GAAA9BgAAADBAAD0GQAA9BkAAADDAAD0GgAA9BoAAADNAAD0GwAA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AHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFLAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wIAAgECAgIDAgQCBQIGAgcCCAIJAgoCCwIMAg0CDgIPAhACEQISAhMCFAIVAhYCFwIYAhkCGgIbAhwCHQIeAh8CIAIhAiICIwIkAiUCJgInAigCKQIqAisCLAItAi4CLwIwAjECMgIzAjQCNQI2AjcCOAI5AjoCOwI8Aj0CPgI/AkACQQJCAkMCRAJFAkYCRwJIAkkCSgJLAkwABTUwMHB4D2FjY2Vzc2libGUtaWNvbghhY2N1c29mdANhZG4IYWR2ZXJzYWwOYWZmaWxpYXRldGhlbWUHYWxnb2xpYQphbWF6b24tcGF5BmFtYXpvbgZhbWlsaWEHYW5kcm9pZAlhbmdlbGxpc3QNYW5ncnljcmVhdGl2ZQdhbmd1bGFyDWFwcC1zdG9yZS1pb3MJYXBwLXN0b3JlBWFwcGVyCWFwcGxlLXBheQVhcHBsZQphc3ltbWV0cmlrB2F1ZGlibGUMYXV0b3ByZWZpeGVyB2F2aWFuZXgGYXZpYXRvA2F3cwhiYW5kY2FtcA5iZWhhbmNlLXNxdWFyZQdiZWhhbmNlCWJpbW9iamVjdAliaXRidWNrZXQHYml0Y29pbgRiaXR5CWJsYWNrLXRpZQpibGFja2JlcnJ5CWJsb2dnZXItYgdibG9nZ2VyC2JsdWV0b290aC1iCWJsdWV0b290aANidGMQYnVyb21vYmVsZXhwZXJ0ZQpidXlzZWxsYWRzDWNjLWFtYXpvbi1wYXkHY2MtYW1leAxjYy1hcHBsZS1wYXkOY2MtZGluZXJzLWNsdWILY2MtZGlzY292ZXIGY2MtamNiDWNjLW1hc3RlcmNhcmQJY2MtcGF5cGFsCWNjLXN0cmlwZQdjYy12aXNhCmNlbnRlcmNvZGUGY2hyb21lCmNsb3Vkc2NhbGUKY2xvdWRzbWl0aAxjbG91ZHZlcnNpZnkHY29kZXBlbghjb2RpZXBpZQ5jb25uZWN0ZGV2ZWxvcAZjb250YW8GY3BhbmVsEGNyZWF0aXZlLWNvbW1vbnMIY3NzMy1hbHQEY3NzMwpjdXR0bGVmaXNoB2QtYW5kLWQIZGFzaGN1YmUJZGVsaWNpb3VzCWRlcGxveWRvZwdkZXNrcHJvCmRldmlhbnRhcnQEZGlnZw1kaWdpdGFsLW9jZWFuB2Rpc2NvcmQJZGlzY291cnNlBmRvY2h1YgZkb2NrZXINZHJhZnQyZGlnaXRhbA9kcmliYmJsZS1zcXVhcmUIZHJpYmJibGUHZHJvcGJveAZkcnVwYWwGZHlhbG9nCmVhcmx5YmlyZHMEZWRnZQllbGVtZW50b3IFZW1iZXIGZW1waXJlBmVudmlyYQZlcmxhbmcIZXRoZXJldW0EZXRzeQxleHBlZGl0ZWRzc2wKZmFjZWJvb2stZhJmYWNlYm9vay1tZXNzZW5nZXIPZmFjZWJvb2stc3F1YXJlCGZhY2Vib29rB2ZpcmVmb3gLZmlyc3Qtb3JkZXIKZmlyc3RkcmFmdAZmbGlja3IJZmxpcGJvYXJkA2ZseRBmb250LWF3ZXNvbWUtYWx0EWZvbnQtYXdlc29tZS1mbGFnDGZvbnQtYXdlc29tZQxmb250aWNvbnMtZmkJZm9udGljb25zEGZvcnQtYXdlc29tZS1hbHQMZm9ydC1hd2Vzb21lCGZvcnVtYmVlCmZvdXJzcXVhcmUOZnJlZS1jb2RlLWNhbXAHZnJlZWJzZApnZXQtcG9ja2V0CWdnLWNpcmNsZQJnZwpnaXQtc3F1YXJlA2dpdApnaXRodWItYWx0DWdpdGh1Yi1zcXVhcmUGZ2l0aHViCWdpdGtyYWtlbgZnaXRsYWIGZ2l0dGVyB2dsaWRlLWcFZ2xpZGUGZ29mb3JlC2dvb2RyZWFkcy1nCWdvb2RyZWFkcwxnb29nbGUtZHJpdmULZ29vZ2xlLXBsYXkNZ29vZ2xlLXBsdXMtZxJnb29nbGUtcGx1cy1zcXVhcmULZ29vZ2xlLXBsdXMNZ29vZ2xlLXdhbGxldAZnb29nbGUIZ3JhdGlwYXkEZ3JhdghncmlwZmlyZQVncnVudARndWxwEmhhY2tlci1uZXdzLXNxdWFyZQtoYWNrZXItbmV3cwRoaXBzDWhpcmUtYS1oZWxwZXIFaG9vbGkGaG90amFyBWhvdXp6BWh0bWw1B2h1YnNwb3QEaW1kYglpbnN0YWdyYW0RaW50ZXJuZXQtZXhwbG9yZXIHaW94aG9zdAtpdHVuZXMtbm90ZQZpdHVuZXMHamVua2lucwVqb2dldAZqb29tbGEJanMtc3F1YXJlAmpzCGpzZmlkZGxlBmtleWNkbg1raWNrc3RhcnRlci1rC2tpY2tzdGFydGVyBmtvcnZ1ZQdsYXJhdmVsDWxhc3RmbS1zcXVhcmUGbGFzdGZtB2xlYW5wdWIEbGVzcwRsaW5lC2xpbmtlZGluLWluCGxpbmtlZGluBmxpbm9kZQVsaW51eARseWZ0B21hZ2VudG8GbWF4Y2RuB21lZGFwcHMIbWVkaXVtLW0GbWVkaXVtBW1lZHJ0Bm1lZXR1cAltaWNyb3NvZnQDbWl4CG1peGNsb3VkBm1penVuaQRtb2R4Bm1vbmVybwduYXBzdGVyD25pbnRlbmRvLXN3aXRjaAdub2RlLWpzBG5vZGUDbnBtA25zOAtudXRyaXRpb25peBRvZG5va2xhc3NuaWtpLXNxdWFyZQ1vZG5va2xhc3NuaWtpCG9wZW5jYXJ0Bm9wZW5pZAVvcGVyYQ1vcHRpbi1tb25zdGVyA29zaQVwYWdlNAlwYWdlbGluZXMGcGFsZmVkB3BhdHJlb24GcGF5cGFsCXBlcmlzY29wZQtwaGFicmljYXRvchFwaG9lbml4LWZyYW1ld29yawNwaHAOcGllZC1waXBlci1hbHQNcGllZC1waXBlci1wcApwaWVkLXBpcGVyC3BpbnRlcmVzdC1wEHBpbnRlcmVzdC1zcXVhcmUJcGludGVyZXN0C3BsYXlzdGF0aW9uDHByb2R1Y3QtaHVudAZwdXNoZWQGcHl0aG9uAnFxCXF1aW5zY2FwZQVxdW9yYQdyYXZlbHJ5BXJlYWN0BXJlYmVsCXJlZC1yaXZlcgxyZWRkaXQtYWxpZW4NcmVkZGl0LXNxdWFyZQZyZWRkaXQHcmVuZGFjdAZyZW5yZW4GcmVwbHlkCXJlc29sdmluZwpyb2NrZXRjaGF0B3JvY2tybXMGc2FmYXJpBHNhc3MGc2NobGl4BnNjcmliZAtzZWFyY2hlbmdpbghzZWxsY2FzdAZzZWxsc3kMc2VydmljZXN0YWNrDHNoaXJ0c2luYnVsawtzaW1wbHlidWlsdAdzaXN0cml4CHNreWF0bGFzBXNreXBlCnNsYWNrLWhhc2gFc2xhY2sKc2xpZGVzaGFyZQ5zbmFwY2hhdC1naG9zdA9zbmFwY2hhdC1zcXVhcmUIc25hcGNoYXQKc291bmRjbG91ZAdzcGVha2FwB3Nwb3RpZnkOc3RhY2stZXhjaGFuZ2UOc3RhY2stb3ZlcmZsb3cKc3RheWxpbmtlZAxzdGVhbS1zcXVhcmUMc3RlYW0tc3ltYm9sBXN0ZWFtDHN0aWNrZXItbXVsZQZzdHJhdmEIc3RyaXBlLXMGc3RyaXBlDHN0dWRpb3ZpbmFyaRJzdHVtYmxldXBvbi1jaXJjbGULc3R1bWJsZXVwb24Lc3VwZXJwb3dlcnMGc3VwcGxlDnRlbGVncmFtLXBsYW5lCHRlbGVncmFtDXRlbmNlbnQtd2VpYm8JdGhlbWVpc2xlBnRyZWxsbwt0cmlwYWR2aXNvcg10dW1ibHItc3F1YXJlBnR1bWJscgZ0d2l0Y2gOdHdpdHRlci1zcXVhcmUHdHdpdHRlcgV0eXBvMwR1YmVyBXVpa2l0C3VuaXJlZ2lzdHJ5B3VudGFwcGQDdXNiCHVzc3VubmFoBnZhYWRpbgd2aWFjb2luDXZpYWRlby1zcXVhcmUGdmlhZGVvBXZpYmVyDHZpbWVvLXNxdWFyZQd2aW1lby12BXZpbWVvBHZpbmUCdmsDdm52BXZ1ZWpzBXdlaWJvBndlaXhpbg93aGF0c2FwcC1zcXVhcmUId2hhdHNhcHAFd2htY3MLd2lraXBlZGlhLXcHd2luZG93cxB3b3JkcHJlc3Mtc2ltcGxlCXdvcmRwcmVzcwp3cGJlZ2lubmVyCndwZXhwbG9yZXIHd3Bmb3JtcwR4Ym94C3hpbmctc3F1YXJlBHhpbmcMeS1jb21iaW5hdG9yBXlhaG9vFHlhbmRleC1pbnRlcm5hdGlvbmFsBnlhbmRleAR5ZWxwBXlvYXN0DnlvdXR1YmUtc3F1YXJlB3lvdXR1YmUAAAAAAA==\"","export default \"data:font/woff;base64,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\"","export default \"data:font/woff2;base64,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\"","export default __webpack_public_path__ + \"a01e3f2d6c83dc3aee175e2482b3f777.eot\";","export default __webpack_public_path__ + \"62d9dae4e0040e81c980950003df0e07.svg\";","export default __webpack_public_path__ + \"c656b8caa454ed19b9a2ef7f4f5b8fea.ttf\";","export default \"data:font/woff;base64,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\"","export default \"data:font/woff2;base64,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\"","export default \"data:application/vnd.ms-fontobject;base64,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AR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AAxhZGRyZXNzLWJvb2sMYWRkcmVzcy1jYXJkFWFycm93LWFsdC1jaXJjbGUtZG93bhVhcnJvdy1hbHQtY2lyY2xlLWxlZnQWYXJyb3ctYWx0LWNpcmNsZS1yaWdodBNhcnJvdy1hbHQtY2lyY2xlLXVwCmJlbGwtc2xhc2gEYmVsbAhib29rbWFyawhidWlsZGluZwxjYWxlbmRhci1hbHQOY2FsZW5kYXItY2hlY2sOY2FsZW5kYXItbWludXMNY2FsZW5kYXItcGx1cw5jYWxlbmRhci10aW1lcwhjYWxlbmRhchFjYXJldC1zcXVhcmUtZG93bhFjYXJldC1zcXVhcmUtbGVmdBJjYXJldC1zcXVhcmUtcmlnaHQPY2FyZXQtc3F1YXJlLXVwCWNoYXJ0LWJhcgxjaGVjay1jaXJjbGUMY2hlY2stc3F1YXJlBmNpcmNsZQljbGlwYm9hcmQFY2xvY2sFY2xvbmURY2xvc2VkLWNhcHRpb25pbmcLY29tbWVudC1hbHQHY29tbWVudAhjb21tZW50cwdjb21wYXNzBGNvcHkJY29weXJpZ2h0C2NyZWRpdC1jYXJkCmRvdC1jaXJjbGUEZWRpdA1lbnZlbG9wZS1vcGVuCGVudmVsb3BlCWV5ZS1zbGFzaAhmaWxlLWFsdAxmaWxlLWFyY2hpdmUKZmlsZS1hdWRpbwlmaWxlLWNvZGUKZmlsZS1leGNlbApmaWxlLWltYWdlCGZpbGUtcGRmD2ZpbGUtcG93ZXJwb2ludApmaWxlLXZpZGVvCWZpbGUtd29yZARmaWxlBGZsYWcLZm9sZGVyLW9wZW4GZm9sZGVyBWZyb3duBmZ1dGJvbANnZW0LaGFuZC1saXphcmQKaGFuZC1wYXBlcgpoYW5kLXBlYWNlD2hhbmQtcG9pbnQtZG93bg9oYW5kLXBvaW50LWxlZnQQaGFuZC1wb2ludC1yaWdodA1oYW5kLXBvaW50LXVwDGhhbmQtcG9pbnRlcgloYW5kLXJvY2sNaGFuZC1zY2lzc29ycwpoYW5kLXNwb2NrCWhhbmRzaGFrZQNoZGQFaGVhcnQIaG9zcGl0YWwJaG91cmdsYXNzCGlkLWJhZGdlB2lkLWNhcmQFaW1hZ2UGaW1hZ2VzCGtleWJvYXJkBWxlbW9uCWxpZmUtcmluZwlsaWdodGJ1bGIIbGlzdC1hbHQDbWFwA21laAxtaW51cy1zcXVhcmUObW9uZXktYmlsbC1hbHQEbW9vbgluZXdzcGFwZXIMb2JqZWN0LWdyb3VwDm9iamVjdC11bmdyb3VwC3BhcGVyLXBsYW5lDHBhdXNlLWNpcmNsZQtwbGF5LWNpcmNsZQtwbHVzLXNxdWFyZQ9xdWVzdGlvbi1jaXJjbGUKcmVnaXN0ZXJlZARzYXZlDHNoYXJlLXNxdWFyZQVzbWlsZQlzbm93Zmxha2UGc3F1YXJlCXN0YXItaGFsZgRzdGFyC3N0aWNreS1ub3RlC3N0b3AtY2lyY2xlA3N1bgt0aHVtYnMtZG93bgl0aHVtYnMtdXAMdGltZXMtY2lyY2xlCXRyYXNoLWFsdAt1c2VyLWNpcmNsZQR1c2VyDHdpbmRvdy1jbG9zZQ93aW5kb3ctbWF4aW1pemUPd2luZG93LW1pbmltaXplDndpbmRvdy1yZXN0b3JlAAAAAA==\"","export default __webpack_public_path__ + \"9c4845b4b41ef40a22faee76144fa816.svg\";","export default \"data:font/ttf;base64,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AAoAVgG4AAMAAQQJAAsAJgIORm9udCBBd2Vzb21lRm9udCBBd2Vzb21lIDUgRnJlZVJlZ3VsYXJGb250IEF3ZXNvbWUgNSBGcmVlIFJlZ3VsYXJGb250IEF3ZXNvbWUgNSBGcmVlIFJlZ3VsYXJWZXJzaW9uIDUuMEZvbnRBd2Vzb21lNUZyZWVSZWd1bGFyR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20ARgBvAG4AdAAgAEEAdwBlAHMAbwBtAGUARgBvAG4AdAAgAEEAdwBlAHMAbwBtAGUAIAA1ACAARgByAGUAZQBSAGUAZwB1AGwAYQByAEYAbwBuAHQAIABBAHcAZQBzAG8AbQBlACAANQAgAEYAcgBlAGUAIABSAGUAZwB1AGwAYQByAEYAbwBuAHQAIABBAHcAZQBzAG8AbQBlACAANQAgAEYAcgBlAGUAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAA1AC4AMABGAG8AbgB0AEEAdwBlAHMAbwBtAGUANQBGAHIAZQBlAFIAZQBnAHUAbABhAHIARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AAxhZGRyZXNzLWJvb2sMYWRkcmVzcy1jYXJkFWFycm93LWFsdC1jaXJjbGUtZG93bhVhcnJvdy1hbHQtY2lyY2xlLWxlZnQWYXJyb3ctYWx0LWNpcmNsZS1yaWdodBNhcnJvdy1hbHQtY2lyY2xlLXVwCmJlbGwtc2xhc2gEYmVsbAhib29rbWFyawhidWlsZGluZwxjYWxlbmRhci1hbHQOY2FsZW5kYXItY2hlY2sOY2FsZW5kYXItbWludXMNY2FsZW5kYXItcGx1cw5jYWxlbmRhci10aW1lcwhjYWxlbmRhchFjYXJldC1zcXVhcmUtZG93bhFjYXJldC1zcXVhcmUtbGVmdBJjYXJldC1zcXVhcmUtcmlnaHQPY2FyZXQtc3F1YXJlLXVwCWNoYXJ0LWJhcgxjaGVjay1jaXJjbGUMY2hlY2stc3F1YXJlBmNpcmNsZQljbGlwYm9hcmQFY2xvY2sFY2xvbmURY2xvc2VkLWNhcHRpb25pbmcLY29tbWVudC1hbHQHY29tbWVudAhjb21tZW50cwdjb21wYXNzBGNvcHkJY29weXJpZ2h0C2NyZWRpdC1jYXJkCmRvdC1jaXJjbGUEZWRpdA1lbnZlbG9wZS1vcGVuCGVudmVsb3BlCWV5ZS1zbGFzaAhmaWxlLWFsdAxmaWxlLWFyY2hpdmUKZmlsZS1hdWRpbwlmaWxlLWNvZGUKZmlsZS1leGNlbApmaWxlLWltYWdlCGZpbGUtcGRmD2ZpbGUtcG93ZXJwb2ludApmaWxlLXZpZGVvCWZpbGUtd29yZARmaWxlBGZsYWcLZm9sZGVyLW9wZW4GZm9sZGVyBWZyb3duBmZ1dGJvbANnZW0LaGFuZC1saXphcmQKaGFuZC1wYXBlcgpoYW5kLXBlYWNlD2hhbmQtcG9pbnQtZG93bg9oYW5kLXBvaW50LWxlZnQQaGFuZC1wb2ludC1yaWdodA1oYW5kLXBvaW50LXVwDGhhbmQtcG9pbnRlcgloYW5kLXJvY2sNaGFuZC1zY2lzc29ycwpoYW5kLXNwb2NrCWhhbmRzaGFrZQNoZGQFaGVhcnQIaG9zcGl0YWwJaG91cmdsYXNzCGlkLWJhZGdlB2lkLWNhcmQFaW1hZ2UGaW1hZ2VzCGtleWJvYXJkBWxlbW9uCWxpZmUtcmluZwlsaWdodGJ1bGIIbGlzdC1hbHQDbWFwA21laAxtaW51cy1zcXVhcmUObW9uZXktYmlsbC1hbHQEbW9vbgluZXdzcGFwZXIMb2JqZWN0LWdyb3VwDm9iamVjdC11bmdyb3VwC3BhcGVyLXBsYW5lDHBhdXNlLWNpcmNsZQtwbGF5LWNpcmNsZQtwbHVzLXNxdWFyZQ9xdWVzdGlvbi1jaXJjbGUKcmVnaXN0ZXJlZARzYXZlDHNoYXJlLXNxdWFyZQVzbWlsZQlzbm93Zmxha2UGc3F1YXJlCXN0YXItaGFsZgRzdGFyC3N0aWNreS1ub3RlC3N0b3AtY2lyY2xlA3N1bgt0aHVtYnMtZG93bgl0aHVtYnMtdXAMdGltZXMtY2lyY2xlCXRyYXNoLWFsdAt1c2VyLWNpcmNsZQR1c2VyDHdpbmRvdy1jbG9zZQ93aW5kb3ctbWF4aW1pemUPd2luZG93LW1pbmltaXplDndpbmRvdy1yZXN0b3JlAAAAAA==\"","export default \"data:font/woff;base64,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\"","export default \"data:font/woff2;base64,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\"","export default \"data:image/png;base64,ZXhwb3J0IGRlZmF1bHQgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyAiaW1hZ2VzL2ZsYWdzLTk5ZjYzYWU3YTc0M2YyMWFiMzA4NDdlZDA2YTY5OGQ5LnBuZyI7\"","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _has from \"lodash/has\";\nimport _invoke from \"lodash/invoke\";\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { customPropTypes, getUnhandledProps } from '../../lib';\nimport Button from '../../elements/Button';\nimport Modal from '../../modules/Modal';\n/**\n * A Confirm modal gives the user a choice to confirm or cancel an action/\n * @see Modal\n */\n\nvar Confirm = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Confirm, _Component);\n\n  function Confirm() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleCancel = function (e) {\n      _invoke(_this.props, 'onCancel', e, _this.props);\n    };\n\n    _this.handleCancelOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, buttonProps) {\n          _invoke(predefinedProps, 'onClick', e, buttonProps);\n\n          _this.handleCancel(e);\n        }\n      };\n    };\n\n    _this.handleConfirmOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, buttonProps) {\n          _invoke(predefinedProps, 'onClick', e, buttonProps);\n\n          _invoke(_this.props, 'onConfirm', e, _this.props);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = Confirm.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        cancelButton = _this$props.cancelButton,\n        confirmButton = _this$props.confirmButton,\n        content = _this$props.content,\n        header = _this$props.header,\n        open = _this$props.open,\n        size = _this$props.size;\n    var rest = getUnhandledProps(Confirm, this.props); // `open` is auto controlled by the Modal\n    // It cannot be present (even undefined) with `defaultOpen`\n    // only apply it if the user provided an open prop\n\n    var openProp = {};\n    if (_has(this.props, 'open')) openProp.open = open;\n    return /*#__PURE__*/React.createElement(Modal, _extends({}, rest, openProp, {\n      size: size,\n      onClose: this.handleCancel\n    }), Modal.Header.create(header, {\n      autoGenerateKey: false\n    }), Modal.Content.create(content, {\n      autoGenerateKey: false\n    }), /*#__PURE__*/React.createElement(Modal.Actions, null, Button.create(cancelButton, {\n      autoGenerateKey: false,\n      overrideProps: this.handleCancelOverrides\n    }), Button.create(confirmButton, {\n      autoGenerateKey: false,\n      defaultProps: {\n        primary: true\n      },\n      overrideProps: this.handleConfirmOverrides\n    })));\n  };\n\n  return Confirm;\n}(Component);\n\nConfirm.handledProps = [\"cancelButton\", \"confirmButton\", \"content\", \"header\", \"onCancel\", \"onConfirm\", \"open\", \"size\"];\nConfirm.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** The cancel button text. */\n  cancelButton: customPropTypes.itemShorthand,\n\n  /** The OK button text. */\n  confirmButton: customPropTypes.itemShorthand,\n\n  /** The ModalContent text. */\n  content: customPropTypes.itemShorthand,\n\n  /** The ModalHeader text. */\n  header: customPropTypes.itemShorthand,\n\n  /**\n   * Called when the Modal is closed without clicking confirm.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onCancel: PropTypes.func,\n\n  /**\n   * Called when the OK button is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onConfirm: PropTypes.func,\n\n  /** Whether or not the modal is visible. */\n  open: PropTypes.bool,\n\n  /** A Confirm can vary in size */\n  size: PropTypes.oneOf(['mini', 'tiny', 'small', 'large', 'fullscreen'])\n} : {};\nConfirm.defaultProps = {\n  cancelButton: 'Cancel',\n  confirmButton: 'OK',\n  content: 'Are you sure?',\n  size: 'small'\n};\nexport default Confirm;","import _default from './Confirm';\nexport { _default as default };","import PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, useClassNamesOnNode } from '../../lib';\n/**\n * A component that allows to manage classNames on a DOM node in declarative manner.\n *\n * @deprecated This component is deprecated and will be removed in next major release.\n */\n\nfunction MountNode(props) {\n  useClassNamesOnNode(props.node, props.className); // A workaround for `react-docgen`: https://github.com/reactjs/react-docgen/issues/336\n\n  if (process.env.NODE_ENV === 'test') {\n    return /*#__PURE__*/React.createElement(\"div\", null);\n  }\n  /* istanbul ignore next */\n\n\n  return null;\n}\n\nMountNode.handledProps = [\"className\", \"node\"];\nMountNode.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** The DOM node where we will apply class names. Defaults to document.body. */\n  node: PropTypes.oneOfType([customPropTypes.domNode, customPropTypes.refObject])\n} : {};\nexport default MountNode;","import _default from './MountNode';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _map from \"lodash/map\";\nimport _isNil from \"lodash/isNil\";\nimport _invoke from \"lodash/invoke\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, createPaginationItems, customPropTypes, getUnhandledProps } from '../../lib';\nimport Menu from '../../collections/Menu';\nimport PaginationItem from './PaginationItem';\n/**\n * A component to render a pagination.\n */\n\nvar Pagination = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Pagination, _Component);\n\n  function Pagination() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleItemClick = function (e, _ref) {\n      var nextActivePage = _ref.value;\n      var prevActivePage = _this.state.activePage; // Heads up! We need the cast to the \"number\" type there, as `activePage` can be a string\n\n      if (+prevActivePage === +nextActivePage) return;\n\n      _this.setState({\n        activePage: nextActivePage\n      });\n\n      _invoke(_this.props, 'onPageChange', e, _extends({}, _this.props, {\n        activePage: nextActivePage\n      }));\n    };\n\n    _this.handleItemOverrides = function (active, type, value) {\n      return function (predefinedProps) {\n        return {\n          active: active,\n          type: type,\n          key: type + \"-\" + value,\n          onClick: function onClick(e, itemProps) {\n            _invoke(predefinedProps, 'onClick', e, itemProps);\n\n            if (itemProps.type !== 'ellipsisItem') _this.handleItemClick(e, itemProps);\n          }\n        };\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = Pagination.prototype;\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props = this.props,\n        ariaLabel = _this$props['aria-label'],\n        boundaryRange = _this$props.boundaryRange,\n        disabled = _this$props.disabled,\n        ellipsisItem = _this$props.ellipsisItem,\n        siblingRange = _this$props.siblingRange,\n        totalPages = _this$props.totalPages;\n    var activePage = this.state.activePage;\n    var items = createPaginationItems({\n      activePage: activePage,\n      boundaryRange: boundaryRange,\n      hideEllipsis: _isNil(ellipsisItem),\n      siblingRange: siblingRange,\n      totalPages: totalPages\n    });\n    var rest = getUnhandledProps(Pagination, this.props);\n    return /*#__PURE__*/React.createElement(Menu, _extends({}, rest, {\n      \"aria-label\": ariaLabel,\n      pagination: true,\n      role: \"navigation\"\n    }), _map(items, function (_ref2) {\n      var active = _ref2.active,\n          type = _ref2.type,\n          value = _ref2.value;\n      return PaginationItem.create(_this2.props[type], {\n        defaultProps: {\n          content: value,\n          disabled: disabled,\n          value: value\n        },\n        overrideProps: _this2.handleItemOverrides(active, type, value)\n      });\n    }));\n  };\n\n  return Pagination;\n}(Component);\n\nPagination.handledProps = [\"activePage\", \"aria-label\", \"boundaryRange\", \"defaultActivePage\", \"disabled\", \"ellipsisItem\", \"firstItem\", \"lastItem\", \"nextItem\", \"onPageChange\", \"pageItem\", \"prevItem\", \"siblingRange\", \"totalPages\"];\nexport { Pagination as default };\nPagination.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** A pagination item can have an aria label. */\n  'aria-label': PropTypes.string,\n\n  /** Initial activePage value. */\n  defaultActivePage: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Index of the currently active page. */\n  activePage: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Number of always visible pages at the beginning and end. */\n  boundaryRange: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** A pagination can be disabled. */\n  disabled: PropTypes.bool,\n\n  /** A shorthand for PaginationItem. */\n  ellipsisItem: customPropTypes.itemShorthand,\n\n  /** A shorthand for PaginationItem. */\n  firstItem: customPropTypes.itemShorthand,\n\n  /** A shorthand for PaginationItem. */\n  lastItem: customPropTypes.itemShorthand,\n\n  /** A shorthand for PaginationItem. */\n  nextItem: customPropTypes.itemShorthand,\n\n  /** A shorthand for PaginationItem. */\n  pageItem: customPropTypes.itemShorthand,\n\n  /** A shorthand for PaginationItem. */\n  prevItem: customPropTypes.itemShorthand,\n\n  /**\n   * Called on change of an active page.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onPageChange: PropTypes.func,\n\n  /** Number of always visible pages before and after the current one. */\n  siblingRange: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Total number of pages. */\n  totalPages: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired\n} : {};\nPagination.autoControlledProps = ['activePage'];\nPagination.defaultProps = {\n  'aria-label': 'Pagination Navigation',\n  boundaryRange: 1,\n  ellipsisItem: '...',\n  firstItem: {\n    'aria-label': 'First item',\n    content: '«'\n  },\n  lastItem: {\n    'aria-label': 'Last item',\n    content: '»'\n  },\n  nextItem: {\n    'aria-label': 'Next item',\n    content: '⟩'\n  },\n  pageItem: {},\n  prevItem: {\n    'aria-label': 'Previous item',\n    content: '⟨'\n  },\n  siblingRange: 1\n};\nPagination.Item = PaginationItem;","import _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport keyboardKey from 'keyboard-key';\nimport PropTypes from 'prop-types';\nimport { Component } from 'react';\nimport { createShorthandFactory } from '../../lib';\nimport MenuItem from '../../collections/Menu/MenuItem';\n/**\n * An item of a pagination.\n */\n\nvar PaginationItem = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(PaginationItem, _Component);\n\n  function PaginationItem() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    _this.handleKeyDown = function (e) {\n      _invoke(_this.props, 'onKeyDown', e, _this.props);\n\n      if (keyboardKey.getCode(e) === keyboardKey.Enter) _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    _this.handleOverrides = function () {\n      return {\n        onClick: _this.handleClick,\n        onKeyDown: _this.handleKeyDown\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = PaginationItem.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        type = _this$props.type;\n    var disabled = this.props.disabled || type === 'ellipsisItem';\n    return MenuItem.create(this.props, {\n      defaultProps: {\n        active: active,\n        'aria-current': active,\n        'aria-disabled': disabled,\n        disabled: disabled,\n        onClick: this.handleClick,\n        onKeyDown: this.handleKeyDown,\n        tabIndex: disabled ? -1 : 0\n      },\n      overrideProps: this.handleOverrides\n    });\n  };\n\n  return PaginationItem;\n}(Component);\n\nPaginationItem.handledProps = [\"active\", \"disabled\", \"onClick\", \"onKeyDown\", \"type\"];\nPaginationItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** A pagination item can be active. */\n  active: PropTypes.bool,\n\n  /** A pagination item can be disabled. */\n  disabled: PropTypes.bool,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Called on key down.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onKeyDown: PropTypes.func,\n\n  /** A pagination should have a type. */\n  type: PropTypes.oneOf(['ellipsisItem', 'firstItem', 'prevItem', 'pageItem', 'nextItem', 'lastItem'])\n} : {};\nPaginationItem.create = createShorthandFactory(PaginationItem, function (content) {\n  return {\n    content: content\n  };\n});\nexport default PaginationItem;","import _default from './Pagination';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport EventStack from '@semantic-ui-react/event-stack';\nimport { handleRef, Ref } from '@stardust-ui/react-component-ref';\nimport keyboardKey from 'keyboard-key';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, customPropTypes, doesNodeContainClick } from '../../lib';\nimport validateTrigger from './utils/validateTrigger';\nimport PortalInner from './PortalInner';\n\n/**\n * A component that allows you to render children outside their parent.\n * @see Modal\n * @see Popup\n * @see Dimmer\n * @see Confirm\n */\nvar Portal = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Portal, _Component);\n\n  function Portal() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.contentRef = /*#__PURE__*/React.createRef();\n    _this.triggerRef = /*#__PURE__*/React.createRef();\n    _this.latestDocumentMouseDownEvent = null;\n\n    _this.handleDocumentMouseDown = function (e) {\n      _this.latestDocumentMouseDownEvent = e;\n    };\n\n    _this.handleDocumentClick = function (e) {\n      var closeOnDocumentClick = _this.props.closeOnDocumentClick;\n      var currentMouseDownEvent = _this.latestDocumentMouseDownEvent;\n      _this.latestDocumentMouseDownEvent = null;\n\n      if (!_this.contentRef.current || // no portal\n      doesNodeContainClick(_this.triggerRef.current, e) || // event happened in trigger (delegate to trigger handlers)\n      currentMouseDownEvent && doesNodeContainClick(_this.contentRef.current, currentMouseDownEvent) || // event originated in the portal but was ended outside\n      doesNodeContainClick(_this.contentRef.current, e) // event happened in the portal\n      ) {\n          return;\n        } // ignore the click\n\n\n      if (closeOnDocumentClick) {\n        _this.close(e);\n      }\n    };\n\n    _this.handleEscape = function (e) {\n      if (!_this.props.closeOnEscape) return;\n      if (keyboardKey.getCode(e) !== keyboardKey.Escape) return;\n\n      _this.close(e);\n    };\n\n    _this.handlePortalMouseLeave = function (e) {\n      var _this$props = _this.props,\n          closeOnPortalMouseLeave = _this$props.closeOnPortalMouseLeave,\n          mouseLeaveDelay = _this$props.mouseLeaveDelay;\n      if (!closeOnPortalMouseLeave) return; // Do not close the portal when 'mouseleave' is triggered by children\n\n      if (e.target !== _this.contentRef.current) return;\n      _this.mouseLeaveTimer = _this.closeWithTimeout(e, mouseLeaveDelay);\n    };\n\n    _this.handlePortalMouseEnter = function () {\n      // In order to enable mousing from the trigger to the portal, we need to\n      // clear the mouseleave timer that was set when leaving the trigger.\n      var closeOnPortalMouseLeave = _this.props.closeOnPortalMouseLeave;\n      if (!closeOnPortalMouseLeave) return;\n      clearTimeout(_this.mouseLeaveTimer);\n    };\n\n    _this.handleTriggerBlur = function (e) {\n      var _this$props2 = _this.props,\n          trigger = _this$props2.trigger,\n          closeOnTriggerBlur = _this$props2.closeOnTriggerBlur; // Call original event handler\n\n      for (var _len2 = arguments.length, rest = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n        rest[_key2 - 1] = arguments[_key2];\n      }\n\n      _invoke.apply(void 0, [trigger, 'props.onBlur', e].concat(rest)); // IE 11 doesn't work with relatedTarget in blur events\n\n\n      var target = e.relatedTarget || document.activeElement; // do not close if focus is given to the portal\n\n      var didFocusPortal = _invoke(_this.contentRef.current, 'contains', target);\n\n      if (!closeOnTriggerBlur || didFocusPortal) return;\n\n      _this.close(e);\n    };\n\n    _this.handleTriggerClick = function (e) {\n      var _this$props3 = _this.props,\n          trigger = _this$props3.trigger,\n          closeOnTriggerClick = _this$props3.closeOnTriggerClick,\n          openOnTriggerClick = _this$props3.openOnTriggerClick;\n      var open = _this.state.open; // Call original event handler\n\n      for (var _len3 = arguments.length, rest = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n        rest[_key3 - 1] = arguments[_key3];\n      }\n\n      _invoke.apply(void 0, [trigger, 'props.onClick', e].concat(rest));\n\n      if (open && closeOnTriggerClick) {\n        _this.close(e);\n      } else if (!open && openOnTriggerClick) {\n        _this.open(e);\n      }\n    };\n\n    _this.handleTriggerFocus = function (e) {\n      var _this$props4 = _this.props,\n          trigger = _this$props4.trigger,\n          openOnTriggerFocus = _this$props4.openOnTriggerFocus; // Call original event handler\n\n      for (var _len4 = arguments.length, rest = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {\n        rest[_key4 - 1] = arguments[_key4];\n      }\n\n      _invoke.apply(void 0, [trigger, 'props.onFocus', e].concat(rest));\n\n      if (!openOnTriggerFocus) return;\n\n      _this.open(e);\n    };\n\n    _this.handleTriggerMouseLeave = function (e) {\n      clearTimeout(_this.mouseEnterTimer);\n      var _this$props5 = _this.props,\n          trigger = _this$props5.trigger,\n          closeOnTriggerMouseLeave = _this$props5.closeOnTriggerMouseLeave,\n          mouseLeaveDelay = _this$props5.mouseLeaveDelay; // Call original event handler\n\n      for (var _len5 = arguments.length, rest = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {\n        rest[_key5 - 1] = arguments[_key5];\n      }\n\n      _invoke.apply(void 0, [trigger, 'props.onMouseLeave', e].concat(rest));\n\n      if (!closeOnTriggerMouseLeave) return;\n      _this.mouseLeaveTimer = _this.closeWithTimeout(e, mouseLeaveDelay);\n    };\n\n    _this.handleTriggerMouseEnter = function (e) {\n      clearTimeout(_this.mouseLeaveTimer);\n      var _this$props6 = _this.props,\n          trigger = _this$props6.trigger,\n          mouseEnterDelay = _this$props6.mouseEnterDelay,\n          openOnTriggerMouseEnter = _this$props6.openOnTriggerMouseEnter; // Call original event handler\n\n      for (var _len6 = arguments.length, rest = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {\n        rest[_key6 - 1] = arguments[_key6];\n      }\n\n      _invoke.apply(void 0, [trigger, 'props.onMouseEnter', e].concat(rest));\n\n      if (!openOnTriggerMouseEnter) return;\n      _this.mouseEnterTimer = _this.openWithTimeout(e, mouseEnterDelay);\n    };\n\n    _this.open = function (e) {\n      var onOpen = _this.props.onOpen;\n      if (onOpen) onOpen(e, _this.props);\n\n      _this.setState({\n        open: true\n      });\n    };\n\n    _this.openWithTimeout = function (e, delay) {\n      // React wipes the entire event object and suggests using e.persist() if\n      // you need the event for async access. However, even with e.persist\n      // certain required props (e.g. currentTarget) are null so we're forced to clone.\n      var eventClone = _extends({}, e);\n\n      return setTimeout(function () {\n        return _this.open(eventClone);\n      }, delay || 0);\n    };\n\n    _this.close = function (e) {\n      var onClose = _this.props.onClose;\n      if (onClose) onClose(e, _this.props);\n\n      _this.setState({\n        open: false\n      });\n    };\n\n    _this.closeWithTimeout = function (e, delay) {\n      // React wipes the entire event object and suggests using e.persist() if\n      // you need the event for async access. However, even with e.persist\n      // certain required props (e.g. currentTarget) are null so we're forced to clone.\n      var eventClone = _extends({}, e);\n\n      return setTimeout(function () {\n        return _this.close(eventClone);\n      }, delay || 0);\n    };\n\n    _this.handleMount = function () {\n      _invoke(_this.props, 'onMount', null, _this.props);\n    };\n\n    _this.handleUnmount = function () {\n      _invoke(_this.props, 'onUnmount', null, _this.props);\n    };\n\n    _this.handleTriggerRef = function (c) {\n      _this.triggerRef.current = c;\n      handleRef(_this.props.triggerRef, c);\n    };\n\n    return _this;\n  }\n\n  var _proto = Portal.prototype;\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    // Clean up timers\n    clearTimeout(this.mouseEnterTimer);\n    clearTimeout(this.mouseLeaveTimer);\n  } // ----------------------------------------\n  // Document Event Handlers\n  // ----------------------------------------\n  ;\n\n  _proto.render = function render() {\n    var _this$props7 = this.props,\n        children = _this$props7.children,\n        eventPool = _this$props7.eventPool,\n        mountNode = _this$props7.mountNode,\n        trigger = _this$props7.trigger;\n    var open = this.state.open;\n    /* istanbul ignore else */\n\n    if (process.env.NODE_ENV !== 'production') {\n      validateTrigger(trigger);\n    }\n\n    return /*#__PURE__*/React.createElement(React.Fragment, null, open && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PortalInner, {\n      innerRef: this.contentRef,\n      mountNode: mountNode,\n      onMount: this.handleMount,\n      onUnmount: this.handleUnmount\n    }, children), /*#__PURE__*/React.createElement(EventStack, {\n      name: \"mouseleave\",\n      on: this.handlePortalMouseLeave,\n      pool: eventPool,\n      target: this.contentRef\n    }), /*#__PURE__*/React.createElement(EventStack, {\n      name: \"mouseenter\",\n      on: this.handlePortalMouseEnter,\n      pool: eventPool,\n      target: this.contentRef\n    }), /*#__PURE__*/React.createElement(EventStack, {\n      name: \"mousedown\",\n      on: this.handleDocumentMouseDown,\n      pool: eventPool\n    }), /*#__PURE__*/React.createElement(EventStack, {\n      name: \"click\",\n      on: this.handleDocumentClick,\n      pool: eventPool\n    }), /*#__PURE__*/React.createElement(EventStack, {\n      name: \"keydown\",\n      on: this.handleEscape,\n      pool: eventPool\n    })), trigger && /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.handleTriggerRef\n    }, /*#__PURE__*/React.cloneElement(trigger, {\n      onBlur: this.handleTriggerBlur,\n      onClick: this.handleTriggerClick,\n      onFocus: this.handleTriggerFocus,\n      onMouseLeave: this.handleTriggerMouseLeave,\n      onMouseEnter: this.handleTriggerMouseEnter\n    })));\n  };\n\n  return Portal;\n}(Component);\n\nPortal.handledProps = [\"children\", \"closeOnDocumentClick\", \"closeOnEscape\", \"closeOnPortalMouseLeave\", \"closeOnTriggerBlur\", \"closeOnTriggerClick\", \"closeOnTriggerMouseLeave\", \"defaultOpen\", \"eventPool\", \"mountNode\", \"mouseEnterDelay\", \"mouseLeaveDelay\", \"onClose\", \"onMount\", \"onOpen\", \"onUnmount\", \"open\", \"openOnTriggerClick\", \"openOnTriggerFocus\", \"openOnTriggerMouseEnter\", \"trigger\", \"triggerRef\"];\nPortal.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Primary content. */\n  children: PropTypes.node.isRequired,\n\n  /** Controls whether or not the portal should close when the document is clicked. */\n  closeOnDocumentClick: PropTypes.bool,\n\n  /** Controls whether or not the portal should close when escape is pressed is displayed. */\n  closeOnEscape: PropTypes.bool,\n\n  /**\n   * Controls whether or not the portal should close when mousing out of the portal.\n   * NOTE: This will prevent `closeOnTriggerMouseLeave` when mousing over the\n   * gap from the trigger to the portal.\n   */\n  closeOnPortalMouseLeave: PropTypes.bool,\n\n  /** Controls whether or not the portal should close on blur of the trigger. */\n  closeOnTriggerBlur: PropTypes.bool,\n\n  /** Controls whether or not the portal should close on click of the trigger. */\n  closeOnTriggerClick: PropTypes.bool,\n\n  /** Controls whether or not the portal should close when mousing out of the trigger. */\n  closeOnTriggerMouseLeave: PropTypes.bool,\n\n  /** Initial value of open. */\n  defaultOpen: PropTypes.bool,\n\n  /** Event pool namespace that is used to handle component events */\n  eventPool: PropTypes.string,\n\n  /** The node where the portal should mount. */\n  mountNode: PropTypes.any,\n\n  /** Milliseconds to wait before opening on mouse over */\n  mouseEnterDelay: PropTypes.number,\n\n  /** Milliseconds to wait before closing on mouse leave */\n  mouseLeaveDelay: PropTypes.number,\n\n  /**\n   * Called when a close event happens\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClose: PropTypes.func,\n\n  /**\n   * Called when the portal is mounted on the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onMount: PropTypes.func,\n\n  /**\n   * Called when an open event happens\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onOpen: PropTypes.func,\n\n  /**\n   * Called when the portal is unmounted from the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onUnmount: PropTypes.func,\n\n  /** Controls whether or not the portal is displayed. */\n  open: PropTypes.bool,\n\n  /** Controls whether or not the portal should open when the trigger is clicked. */\n  openOnTriggerClick: PropTypes.bool,\n\n  /** Controls whether or not the portal should open on focus of the trigger. */\n  openOnTriggerFocus: PropTypes.bool,\n\n  /** Controls whether or not the portal should open when mousing over the trigger. */\n  openOnTriggerMouseEnter: PropTypes.bool,\n\n  /** Element to be rendered in-place where the portal is defined. */\n  trigger: PropTypes.node,\n\n  /** Called with a ref to the trigger node. */\n  triggerRef: customPropTypes.ref\n} : {};\nPortal.defaultProps = {\n  closeOnDocumentClick: true,\n  closeOnEscape: true,\n  eventPool: 'default',\n  openOnTriggerClick: true\n};\nPortal.autoControlledProps = ['open'];\nPortal.Inner = PortalInner;\nexport default Portal;","import _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport { handleRef, Ref } from '@stardust-ui/react-component-ref';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { createPortal } from 'react-dom';\nimport { customPropTypes, isBrowser } from '../../lib';\n\n/**\n * An inner component that allows you to render children outside their parent.\n */\nvar PortalInner = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(PortalInner, _Component);\n\n  function PortalInner() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleRef = function (c) {\n      handleRef(_this.props.innerRef, c);\n    };\n\n    return _this;\n  }\n\n  var _proto = PortalInner.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    _invoke(this.props, 'onMount', null, this.props);\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    _invoke(this.props, 'onUnmount', null, this.props);\n  };\n\n  _proto.render = function render() {\n    if (!isBrowser()) return null;\n    var _this$props = this.props,\n        children = _this$props.children,\n        _this$props$mountNode = _this$props.mountNode,\n        mountNode = _this$props$mountNode === void 0 ? document.body : _this$props$mountNode;\n    return /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.handleRef\n    }, children), mountNode);\n  };\n\n  return PortalInner;\n}(Component);\n\nPortalInner.handledProps = [\"children\", \"innerRef\", \"mountNode\", \"onMount\", \"onUnmount\"];\nPortalInner.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Primary content. */\n  children: PropTypes.node.isRequired,\n\n  /** Called with a ref to the inner node. */\n  innerRef: customPropTypes.ref,\n\n  /** The node where the portal should mount. */\n  mountNode: PropTypes.any,\n\n  /**\n   * Called when the portal is mounted on the DOM\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onMount: PropTypes.func,\n\n  /**\n   * Called when the portal is unmounted from the DOM\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onUnmount: PropTypes.func\n} : {};\nexport default PortalInner;","import _default from './Portal';\nexport { _default as default };","import React from 'react';\nimport * as ReactIs from 'react-is';\n/**\n * Asserts that a passed element can be used cloned a props will be applied properly.\n */\n\nexport default function validateTrigger(element) {\n  if (element) {\n    React.Children.only(element);\n\n    if (ReactIs.isFragment(element)) {\n      throw new Error('An \"React.Fragment\" cannot be used as a `trigger`.');\n    }\n  }\n}","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport React from 'react';\nimport { getUnhandledProps } from '../../lib';\nimport Checkbox from '../../modules/Checkbox';\n/**\n * A Radio is sugar for <Checkbox radio />.\n * Useful for exclusive groups of sliders or toggles.\n * @see Checkbox\n * @see Form\n */\n\nfunction Radio(props) {\n  var slider = props.slider,\n      toggle = props.toggle,\n      type = props.type;\n  var rest = getUnhandledProps(Radio, props); // const ElementType = getElementType(Radio, props)\n  // radio, slider, toggle are exclusive\n  // use an undefined radio if slider or toggle are present\n\n  var radio = !(slider || toggle) || undefined;\n  return /*#__PURE__*/React.createElement(Checkbox, _extends({}, rest, {\n    type: type,\n    radio: radio,\n    slider: slider,\n    toggle: toggle\n  }));\n}\n\nRadio.handledProps = [\"slider\", \"toggle\", \"type\"];\nRadio.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Format to emphasize the current selection state. */\n  slider: Checkbox.propTypes.slider,\n\n  /** Format to show an on or off choice. */\n  toggle: Checkbox.propTypes.toggle,\n\n  /** HTML input type, either checkbox or radio. */\n  type: Checkbox.propTypes.type\n} : {};\nRadio.defaultProps = {\n  type: 'radio'\n};\nexport default Radio;","import _default from './Radio';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { eventStack, getElementType, getUnhandledProps, isBrowser } from '../../lib';\nimport isVisible from './lib/isVisible';\n/**\n * Responsive can control visibility of content.\n *\n * @deprecated This component is deprecated and will be removed in next major release.\n */\n\nvar Responsive = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Responsive, _Component);\n\n  function Responsive() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.state = {\n      visible: true\n    };\n\n    _this.handleResize = function (e) {\n      if (_this.ticking) return;\n      _this.ticking = true;\n      _this.frameId = requestAnimationFrame(function () {\n        return _this.handleUpdate(e);\n      });\n    };\n\n    _this.handleUpdate = function (e) {\n      _this.ticking = false;\n      var visible = _this.state.visible;\n\n      var width = _invoke(_this.props, 'getWidth');\n\n      var nextVisible = isVisible(width, _this.props);\n      if (visible !== nextVisible) _this.setState({\n        visible: nextVisible\n      });\n\n      _invoke(_this.props, 'onUpdate', e, _extends({}, _this.props, {\n        width: width\n      }));\n    };\n\n    return _this;\n  }\n\n  Responsive.getDerivedStateFromProps = function getDerivedStateFromProps(props) {\n    var width = _invoke(props, 'getWidth');\n\n    var visible = isVisible(width, props);\n    return {\n      visible: visible\n    };\n  };\n\n  var _proto = Responsive.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    var fireOnMount = this.props.fireOnMount;\n\n    if (process.env.NODE_ENV !== 'production') {\n      if (!Responsive.__deprecationWarningWasRaised) {\n        Responsive.__deprecationWarningWasRaised = true; // eslint-disable-next-line no-console\n\n        console.warn('Warning: \"Responsive\" component from Semantic UI React is deprecated and will be removed in the next major release. Please follow our upgrade guide: https://github.com/Semantic-Org/Semantic-UI-React/pull/4008');\n      }\n    }\n\n    eventStack.sub('resize', this.handleResize, {\n      target: 'window'\n    });\n    if (fireOnMount) this.handleUpdate();\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    eventStack.unsub('resize', this.handleResize, {\n      target: 'window'\n    });\n    cancelAnimationFrame(this.frameId);\n  } // ----------------------------------------\n  // Event handlers\n  // ----------------------------------------\n  ;\n\n  // ----------------------------------------\n  // Render\n  // ----------------------------------------\n  _proto.render = function render() {\n    var children = this.props.children;\n    var visible = this.state.visible;\n    var ElementType = getElementType(Responsive, this.props);\n    var rest = getUnhandledProps(Responsive, this.props);\n    if (visible) return /*#__PURE__*/React.createElement(ElementType, rest, children);\n    return null;\n  };\n\n  return Responsive;\n}(Component);\n\nResponsive.handledProps = [\"as\", \"children\", \"fireOnMount\", \"getWidth\", \"maxWidth\", \"minWidth\", \"onUpdate\"];\nexport { Responsive as default };\nResponsive.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Fires callbacks immediately after mount. */\n  fireOnMount: PropTypes.bool,\n\n  /**\n   * Called to get width of screen. Defaults to using `window.innerWidth` when in a browser;\n   * otherwise, assumes a width of 0.\n   */\n  getWidth: PropTypes.func,\n\n  /** The maximum width at which content will be displayed. */\n  maxWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** The minimum width at which content will be displayed. */\n  minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /**\n   * Called on update.\n   *\n   * @param {SyntheticEvent} event - The React SyntheticEvent object\n   * @param {object} data - All props and the event value.\n   */\n  onUpdate: PropTypes.func\n} : {};\nResponsive.defaultProps = {\n  getWidth: function getWidth() {\n    return isBrowser() ? window.innerWidth : 0;\n  }\n};\nResponsive.onlyMobile = {\n  minWidth: 320,\n  maxWidth: 767\n};\nResponsive.onlyTablet = {\n  minWidth: 768,\n  maxWidth: 991\n};\nResponsive.onlyComputer = {\n  minWidth: 992\n};\nResponsive.onlyLargeScreen = {\n  minWidth: 1200,\n  maxWidth: 1919\n};\nResponsive.onlyWidescreen = {\n  minWidth: 1920\n};\n\nif (process.env.NODE_ENV !== 'production') {\n  Responsive.__deprecationWarningWasRaised = false;\n}","import _default from './Responsive';\nexport { _default as default };","import _isNil from \"lodash/isNil\";\n\nvar fitsMaxWidth = function fitsMaxWidth(width, maxWidth) {\n  return _isNil(maxWidth) ? true : width <= maxWidth;\n};\n\nvar fitsMinWidth = function fitsMinWidth(width, minWidth) {\n  return _isNil(minWidth) ? true : width >= minWidth;\n};\n\nvar isVisible = function isVisible(width, _ref) {\n  var maxWidth = _ref.maxWidth,\n      minWidth = _ref.minWidth;\n  return fitsMinWidth(width, minWidth) && fitsMaxWidth(width, maxWidth);\n};\n\nexport default isVisible;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport Dropdown from '../../modules/Dropdown';\n/**\n * A Select is sugar for <Dropdown selection />.\n * @see Dropdown\n * @see Form\n */\n\nfunction Select(props) {\n  return /*#__PURE__*/React.createElement(Dropdown, _extends({}, props, {\n    selection: true\n  }));\n}\n\nSelect.handledProps = [\"options\"];\nSelect.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Array of Dropdown.Item props e.g. `{ text: '', value: '' }` */\n  options: PropTypes.arrayOf(PropTypes.shape(Dropdown.Item.propTypes)).isRequired\n} : {};\nSelect.Divider = Dropdown.Divider;\nSelect.Header = Dropdown.Header;\nSelect.Item = Dropdown.Item;\nSelect.Menu = Dropdown.Menu;\nexport default Select;","import _default from './Select';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport _get from \"lodash/get\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\n/**\n * A TextArea can be used to allow for extended user input.\n * @see Form\n */\n\nvar TextArea = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(TextArea, _Component);\n\n  function TextArea() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.ref = /*#__PURE__*/createRef();\n\n    _this.focus = function () {\n      return _this.ref.current.focus();\n    };\n\n    _this.handleChange = function (e) {\n      var value = _get(e, 'target.value');\n\n      _invoke(_this.props, 'onChange', e, _extends({}, _this.props, {\n        value: value\n      }));\n    };\n\n    _this.handleInput = function (e) {\n      var value = _get(e, 'target.value');\n\n      _invoke(_this.props, 'onInput', e, _extends({}, _this.props, {\n        value: value\n      }));\n    };\n\n    return _this;\n  }\n\n  var _proto = TextArea.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        rows = _this$props.rows,\n        value = _this$props.value;\n    var rest = getUnhandledProps(TextArea, this.props);\n    var ElementType = getElementType(TextArea, this.props);\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.ref\n    }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      onChange: this.handleChange,\n      onInput: this.handleInput,\n      rows: rows,\n      value: value\n    })));\n  };\n\n  return TextArea;\n}(Component);\n\nTextArea.handledProps = [\"as\", \"onChange\", \"onInput\", \"rows\", \"value\"];\nTextArea.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /**\n   * Called on change.\n   * @param {SyntheticEvent} event - The React SyntheticEvent object\n   * @param {object} data - All props and the event value.\n   */\n  onChange: PropTypes.func,\n\n  /**\n   * Called on input.\n   * @param {SyntheticEvent} event - The React SyntheticEvent object\n   * @param {object} data - All props and the event value.\n   */\n  onInput: PropTypes.func,\n\n  /** Indicates row count for a TextArea. */\n  rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** The value of the textarea. */\n  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n} : {};\nTextArea.defaultProps = {\n  as: 'textarea',\n  rows: 3\n};\nexport default TextArea;","import _default from './TextArea';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport Portal from '../Portal';\nimport Transition from '../../modules/Transition';\nimport { TRANSITION_STATUS_ENTERING } from '../../modules/Transition/utils/computeStatuses';\nimport { getUnhandledProps } from '../../lib';\n\n/**\n * A sugar for `Portal` and `Transition`.\n * @see Portal\n * @see Transition\n */\nvar TransitionablePortal = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(TransitionablePortal, _Component);\n\n  function TransitionablePortal() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.state = {};\n\n    _this.handlePortalClose = function () {\n      _this.setState({\n        portalOpen: -1\n      });\n    };\n\n    _this.handlePortalOpen = function () {\n      _this.setState({\n        portalOpen: true\n      });\n    };\n\n    _this.handleTransitionHide = function (nothing, data) {\n      var portalOpen = _this.state.portalOpen;\n\n      _this.setState({\n        transitionVisible: false\n      });\n\n      _invoke(_this.props, 'onClose', null, _extends({}, data, {\n        portalOpen: false,\n        transitionVisible: false\n      }));\n\n      _invoke(_this.props, 'onHide', null, _extends({}, data, {\n        portalOpen: portalOpen,\n        transitionVisible: false\n      }));\n    };\n\n    _this.handleTransitionStart = function (nothing, data) {\n      var portalOpen = _this.state.portalOpen;\n      var status = data.status;\n      var transitionVisible = status === TRANSITION_STATUS_ENTERING;\n\n      _invoke(_this.props, 'onStart', null, _extends({}, data, {\n        portalOpen: portalOpen,\n        transitionVisible: transitionVisible\n      })); // Heads up! TransitionablePortal fires onOpen callback on the start of transition animation\n\n\n      if (!transitionVisible) return;\n\n      _this.setState({\n        transitionVisible: transitionVisible\n      });\n\n      _invoke(_this.props, 'onOpen', null, _extends({}, data, {\n        transitionVisible: transitionVisible,\n        portalOpen: true\n      }));\n    };\n\n    return _this;\n  }\n\n  // ----------------------------------------\n  // Lifecycle\n  // ----------------------------------------\n  TransitionablePortal.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    // This is definitely a hack :(\n    //\n    // It's coupled with handlePortalClose() for force set the state of `portalOpen` omitting\n    // props.open. It's related to implementation of the component itself as `onClose()` will be\n    // called after a transition will end.\n    // https://github.com/Semantic-Org/Semantic-UI-React/issues/2382\n    if (state.portalOpen === -1) {\n      return {\n        portalOpen: false\n      };\n    }\n\n    if (_isUndefined(props.open)) {\n      return null;\n    }\n\n    return {\n      portalOpen: props.open\n    };\n  } // ----------------------------------------\n  // Callback handling\n  // ----------------------------------------\n  ;\n\n  var _proto = TransitionablePortal.prototype;\n\n  // ----------------------------------------\n  // Render\n  // ----------------------------------------\n  _proto.render = function render() {\n    var _this$props = this.props,\n        children = _this$props.children,\n        transition = _this$props.transition;\n    var _this$state = this.state,\n        portalOpen = _this$state.portalOpen,\n        transitionVisible = _this$state.transitionVisible;\n    var open = portalOpen || transitionVisible;\n    var rest = getUnhandledProps(TransitionablePortal, this.props);\n    return /*#__PURE__*/React.createElement(Portal, _extends({}, rest, {\n      open: open,\n      onOpen: this.handlePortalOpen,\n      onClose: this.handlePortalClose\n    }), /*#__PURE__*/React.createElement(Transition, _extends({}, transition, {\n      transitionOnMount: true,\n      onStart: this.handleTransitionStart,\n      onHide: this.handleTransitionHide,\n      visible: portalOpen\n    }), children));\n  };\n\n  return TransitionablePortal;\n}(Component);\n\nTransitionablePortal.handledProps = [\"children\", \"onClose\", \"onHide\", \"onOpen\", \"onStart\", \"open\", \"transition\"];\nexport { TransitionablePortal as default };\nTransitionablePortal.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Primary content. */\n  children: PropTypes.node.isRequired,\n\n  /**\n   * Called when a close event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and internal state.\n   */\n  onClose: PropTypes.func,\n\n  /**\n   * Callback on each transition that changes visibility to hidden.\n   *\n   * @param {null}\n   * @param {object} data - All props with transition status and internal state.\n   */\n  onHide: PropTypes.func,\n\n  /**\n   * Called when an open event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and internal state.\n   */\n  onOpen: PropTypes.func,\n\n  /**\n   * Callback on animation start.\n   *\n   * @param {null}\n   * @param {object} data - All props with transition status and internal state.\n   */\n  onStart: PropTypes.func,\n\n  /** Controls whether or not the portal is displayed. */\n  open: PropTypes.bool,\n\n  /** Transition props. */\n  transition: PropTypes.object\n} : {};\nTransitionablePortal.defaultProps = {\n  transition: {\n    animation: 'scale',\n    duration: 400\n  }\n};","import _default from './TransitionablePortal';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport _forEach from \"lodash/forEach\";\nimport _without from \"lodash/without\";\nimport _includes from \"lodash/includes\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { eventStack, getElementType, getUnhandledProps, normalizeOffset, isBrowser } from '../../lib';\n/**\n * Visibility provides a set of callbacks for when a content appears in the viewport.\n */\n\nvar Visibility = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Visibility, _Component);\n\n  function Visibility() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.calculations = {\n      bottomPassed: false,\n      bottomVisible: false,\n      fits: false,\n      passing: false,\n      offScreen: false,\n      onScreen: false,\n      topPassed: false,\n      topVisible: false\n    };\n    _this.firedCallbacks = [];\n    _this.ref = /*#__PURE__*/createRef();\n\n    _this.fire = function (_ref, value, reverse) {\n      var callback = _ref.callback,\n          name = _ref.name;\n\n      if (reverse === void 0) {\n        reverse = false;\n      }\n\n      var _this$props = _this.props,\n          continuous = _this$props.continuous,\n          once = _this$props.once; // Heads up! For the execution is required:\n      // - current value correspond to the fired direction\n      // - `continuous` is true or calculation values are different\n\n      var matchesDirection = _this.calculations[value] !== reverse;\n      var executionPossible = continuous || _this.calculations[value] !== _this.oldCalculations[value];\n      if (matchesDirection && executionPossible) _this.execute(callback, name); // Heads up! We should remove callback from the happened when it's not `once`\n\n      if (!once) _this.firedCallbacks = _without(_this.firedCallbacks, name);\n    };\n\n    _this.handleUpdate = function () {\n      if (_this.ticking) return;\n      _this.ticking = true;\n      _this.frameId = requestAnimationFrame(_this.update);\n    };\n\n    _this.update = function () {\n      if (!_this.mounted) return;\n      _this.ticking = false;\n      _this.oldCalculations = _this.calculations;\n      _this.calculations = _this.computeCalculations();\n      _this.pageYOffset = _this.getPageYOffset();\n      var _this$props2 = _this.props,\n          onBottomPassed = _this$props2.onBottomPassed,\n          onBottomPassedReverse = _this$props2.onBottomPassedReverse,\n          onBottomVisible = _this$props2.onBottomVisible,\n          onBottomVisibleReverse = _this$props2.onBottomVisibleReverse,\n          onPassing = _this$props2.onPassing,\n          onPassingReverse = _this$props2.onPassingReverse,\n          onTopPassed = _this$props2.onTopPassed,\n          onTopPassedReverse = _this$props2.onTopPassedReverse,\n          onTopVisible = _this$props2.onTopVisible,\n          onTopVisibleReverse = _this$props2.onTopVisibleReverse,\n          onOffScreen = _this$props2.onOffScreen,\n          onOnScreen = _this$props2.onOnScreen,\n          updateOn = _this$props2.updateOn;\n      var forward = {\n        bottomPassed: {\n          callback: onBottomPassed,\n          name: 'onBottomPassed'\n        },\n        bottomVisible: {\n          callback: onBottomVisible,\n          name: 'onBottomVisible'\n        },\n        passing: {\n          callback: onPassing,\n          name: 'onPassing'\n        },\n        offScreen: {\n          callback: onOffScreen,\n          name: 'onOffScreen'\n        },\n        onScreen: {\n          callback: onOnScreen,\n          name: 'onOnScreen'\n        },\n        topPassed: {\n          callback: onTopPassed,\n          name: 'onTopPassed'\n        },\n        topVisible: {\n          callback: onTopVisible,\n          name: 'onTopVisible'\n        }\n      };\n      var reverse = {\n        bottomPassed: {\n          callback: onBottomPassedReverse,\n          name: 'onBottomPassedReverse'\n        },\n        bottomVisible: {\n          callback: onBottomVisibleReverse,\n          name: 'onBottomVisibleReverse'\n        },\n        passing: {\n          callback: onPassingReverse,\n          name: 'onPassingReverse'\n        },\n        topPassed: {\n          callback: onTopPassedReverse,\n          name: 'onTopPassedReverse'\n        },\n        topVisible: {\n          callback: onTopVisibleReverse,\n          name: 'onTopVisibleReverse'\n        }\n      };\n\n      _invoke(_this.props, 'onUpdate', null, _extends({}, _this.props, {\n        calculations: _this.calculations\n      }));\n\n      _this.fireOnPassed(); // Heads up! Reverse callbacks should be fired first\n\n\n      _forEach(reverse, function (data, value) {\n        return _this.fire(data, value, true);\n      });\n\n      _forEach(forward, function (data, value) {\n        return _this.fire(data, value);\n      });\n\n      if (updateOn === 'repaint') _this.handleUpdate();\n    };\n\n    return _this;\n  }\n\n  var _proto = Visibility.prototype;\n\n  // ----------------------------------------\n  // Lifecycle\n  // ----------------------------------------\n  _proto.componentDidMount = function componentDidMount() {\n    this.mounted = true;\n    if (!isBrowser()) return;\n    var _this$props3 = this.props,\n        context = _this$props3.context,\n        fireOnMount = _this$props3.fireOnMount,\n        updateOn = _this$props3.updateOn;\n    this.pageYOffset = this.getPageYOffset();\n    this.attachHandlers(context, updateOn);\n    if (fireOnMount) this.update();\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n    var cleanHappened = prevProps.continuous !== this.props.continuous || prevProps.once !== this.props.once || prevProps.updateOn !== this.props.updateOn; // Heads up! We should clean up array of happened callbacks, if values of these props are changed\n\n    if (cleanHappened) this.firedCallbacks = [];\n\n    if (prevProps.context !== this.props.context || prevProps.updateOn !== this.props.updateOn) {\n      this.unattachHandlers(prevProps.context);\n      this.attachHandlers(this.props.context, this.props.updateOn);\n    }\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    var context = this.props.context;\n    this.unattachHandlers(context);\n    this.mounted = false;\n  };\n\n  _proto.attachHandlers = function attachHandlers(context, updateOn) {\n    if (updateOn === 'events') {\n      if (context) {\n        eventStack.sub('resize', this.handleUpdate, {\n          target: context\n        });\n        eventStack.sub('scroll', this.handleUpdate, {\n          target: context\n        });\n      }\n\n      return;\n    } // Heads up!\n    // We will deal with `repaint` there\n\n\n    this.handleUpdate();\n  };\n\n  _proto.unattachHandlers = function unattachHandlers(context) {\n    if (context) {\n      eventStack.unsub('resize', this.handleUpdate, {\n        target: context\n      });\n      eventStack.unsub('scroll', this.handleUpdate, {\n        target: context\n      });\n    }\n\n    if (this.frameId) cancelAnimationFrame(this.frameId);\n  } // ----------------------------------------\n  // Callback handling\n  // ----------------------------------------\n  ;\n\n  _proto.execute = function execute(callback, name) {\n    var continuous = this.props.continuous;\n    if (!callback) return; // Heads up! When `continuous` is true, callback will be fired always\n\n    if (!continuous && _includes(this.firedCallbacks, name)) return;\n    callback(null, _extends({}, this.props, {\n      calculations: this.calculations\n    }));\n    this.firedCallbacks.push(name);\n  };\n\n  _proto.fireOnPassed = function fireOnPassed() {\n    var _this2 = this;\n\n    var _this$calculations = this.calculations,\n        percentagePassed = _this$calculations.percentagePassed,\n        pixelsPassed = _this$calculations.pixelsPassed;\n    var onPassed = this.props.onPassed;\n\n    _forEach(onPassed, function (callback, passed) {\n      var pixelsValue = Number(passed);\n\n      if (pixelsValue && pixelsPassed >= pixelsValue) {\n        _this2.execute(callback, passed);\n\n        return;\n      }\n\n      var matchPercentage = (\"\" + passed).match(/^(\\d+)%$/);\n      if (!matchPercentage) return;\n      var percentageValue = Number(matchPercentage[1]) / 100;\n      if (percentagePassed >= percentageValue) _this2.execute(callback, passed);\n    });\n  };\n\n  // ----------------------------------------\n  // Helpers\n  // ----------------------------------------\n  _proto.computeCalculations = function computeCalculations() {\n    var offset = this.props.offset;\n\n    var _this$ref$current$get = this.ref.current.getBoundingClientRect(),\n        bottom = _this$ref$current$get.bottom,\n        height = _this$ref$current$get.height,\n        top = _this$ref$current$get.top,\n        width = _this$ref$current$get.width;\n\n    var _normalizeOffset = normalizeOffset(offset),\n        topOffset = _normalizeOffset[0],\n        bottomOffset = _normalizeOffset[1];\n\n    var newOffset = this.getPageYOffset();\n    var direction = newOffset > this.pageYOffset ? 'down' : 'up';\n    var topPassed = top < topOffset;\n    var bottomPassed = bottom < bottomOffset;\n    var pixelsPassed = bottomPassed ? 0 : Math.max(top * -1, 0);\n    var percentagePassed = pixelsPassed / height;\n    var bottomVisible = bottom >= bottomOffset && bottom <= window.innerHeight;\n    var topVisible = top >= topOffset && top <= window.innerHeight;\n    var fits = topVisible && bottomVisible;\n    var passing = topPassed && !bottomPassed;\n    var onScreen = (topVisible || topPassed) && !bottomPassed;\n    var offScreen = !onScreen;\n    return {\n      bottomPassed: bottomPassed,\n      bottomVisible: bottomVisible,\n      direction: direction,\n      fits: fits,\n      height: height,\n      passing: passing,\n      percentagePassed: percentagePassed,\n      pixelsPassed: pixelsPassed,\n      offScreen: offScreen,\n      onScreen: onScreen,\n      topPassed: topPassed,\n      topVisible: topVisible,\n      width: width\n    };\n  };\n\n  _proto.getPageYOffset = function getPageYOffset() {\n    var context = this.props.context;\n\n    if (context) {\n      // Heads up! `window` doesn't have `pageYOffset` property\n      return context === window ? window.pageYOffset : context.scrollTop;\n    }\n\n    return 0;\n  } // ----------------------------------------\n  // Render\n  // ----------------------------------------\n  ;\n\n  _proto.render = function render() {\n    var children = this.props.children;\n    var ElementType = getElementType(Visibility, this.props);\n    var rest = getUnhandledProps(Visibility, this.props);\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.ref\n    }, /*#__PURE__*/React.createElement(ElementType, rest, children));\n  };\n\n  return Visibility;\n}(Component);\n\nVisibility.handledProps = [\"as\", \"children\", \"context\", \"continuous\", \"fireOnMount\", \"offset\", \"onBottomPassed\", \"onBottomPassedReverse\", \"onBottomVisible\", \"onBottomVisibleReverse\", \"onOffScreen\", \"onOnScreen\", \"onPassed\", \"onPassing\", \"onPassingReverse\", \"onTopPassed\", \"onTopPassedReverse\", \"onTopVisible\", \"onTopVisibleReverse\", \"onUpdate\", \"once\", \"updateOn\"];\nexport { Visibility as default };\nVisibility.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Context which visibility should attach onscroll events. */\n  context: PropTypes.object,\n\n  /**\n   * When set to true a callback will occur anytime an element passes a condition not just immediately after the\n   * threshold is met.\n   */\n  continuous: PropTypes.bool,\n\n  /** Fires callbacks immediately after mount. */\n  fireOnMount: PropTypes.bool,\n\n  /**\n   * Element's bottom edge has passed top of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onBottomPassed: PropTypes.func,\n\n  /**\n   * Element's bottom edge has not passed top of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onBottomPassedReverse: PropTypes.func,\n\n  /**\n   * Element's bottom edge has passed bottom of screen\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onBottomVisible: PropTypes.func,\n\n  /**\n   * Element's bottom edge has not passed bottom of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onBottomVisibleReverse: PropTypes.func,\n\n  /**\n   * Value that context should be adjusted in pixels. Useful for making content appear below content fixed to the\n   * page.\n   */\n  offset: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]))]),\n\n  /** When set to false a callback will occur each time an element passes the threshold for a condition. */\n  once: PropTypes.bool,\n\n  /** Element is not visible on the screen. */\n  onPassed: PropTypes.object,\n\n  /**\n   * Any part of an element is visible on screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onPassing: PropTypes.func,\n\n  /**\n   * Element's top has not passed top of screen but bottom has.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onPassingReverse: PropTypes.func,\n\n  /**\n   * Element is not visible on the screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onOffScreen: PropTypes.func,\n\n  /**\n   * Element is visible on the screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onOnScreen: PropTypes.func,\n\n  /**\n   * Element's top edge has passed top of the screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onTopPassed: PropTypes.func,\n\n  /**\n   * Element's top edge has not passed top of the screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onTopPassedReverse: PropTypes.func,\n\n  /**\n   * Element's top edge has passed bottom of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onTopVisible: PropTypes.func,\n\n  /**\n   * Element's top edge has not passed bottom of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onTopVisibleReverse: PropTypes.func,\n\n  /**\n   * Element's top edge has passed bottom of screen.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onUpdate: PropTypes.func,\n\n  /**\n   * Allows to choose the mode of the position calculations:\n   * - `events` - (default) update and fire callbacks only on scroll/resize events\n   * - `repaint` - update and fire callbacks on browser repaint (animation frames)\n   */\n  updateOn: PropTypes.oneOf(['events', 'repaint'])\n} : {};\nVisibility.defaultProps = {\n  context: isBrowser() ? window : null,\n  continuous: false,\n  offset: [0, 0],\n  once: true,\n  updateOn: 'events'\n};","import _default from './Visibility';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _each from \"lodash/each\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getUnhandledProps, getElementType, SUI } from '../../lib';\nimport BreadcrumbDivider from './BreadcrumbDivider';\nimport BreadcrumbSection from './BreadcrumbSection';\n/**\n * A breadcrumb is used to show hierarchy between content.\n */\n\nfunction Breadcrumb(props) {\n  var children = props.children,\n      className = props.className,\n      divider = props.divider,\n      icon = props.icon,\n      sections = props.sections,\n      size = props.size;\n  var classes = cx('ui', size, 'breadcrumb', className);\n  var rest = getUnhandledProps(Breadcrumb, props);\n  var ElementType = getElementType(Breadcrumb, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  var childElements = [];\n\n  _each(sections, function (section, index) {\n    // section\n    var breadcrumbElement = BreadcrumbSection.create(section);\n    childElements.push(breadcrumbElement); // divider\n\n    if (index !== sections.length - 1) {\n      var key = breadcrumbElement.key + \"_divider\" || JSON.stringify(section);\n      childElements.push(BreadcrumbDivider.create({\n        content: divider,\n        icon: icon,\n        key: key\n      }));\n    }\n  });\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childElements);\n}\n\nBreadcrumb.handledProps = [\"as\", \"children\", \"className\", \"divider\", \"icon\", \"sections\", \"size\"];\nBreadcrumb.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content of the Breadcrumb.Divider. */\n  divider: customPropTypes.every([customPropTypes.disallow(['icon']), customPropTypes.contentShorthand]),\n\n  /** For use with the sections prop. Render as an `Icon` component with `divider` class instead of a `div` in\n   *  Breadcrumb.Divider. */\n  icon: customPropTypes.every([customPropTypes.disallow(['divider']), customPropTypes.itemShorthand]),\n\n  /** Shorthand array of props for Breadcrumb.Section. */\n  sections: customPropTypes.collectionShorthand,\n\n  /** Size of Breadcrumb. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium'))\n} : {};\nBreadcrumb.Divider = BreadcrumbDivider;\nBreadcrumb.Section = BreadcrumbSection;\nexport default Breadcrumb;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getUnhandledProps, getElementType } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A divider sub-component for Breadcrumb component.\n */\n\nfunction BreadcrumbDivider(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      icon = props.icon;\n  var classes = cx('divider', className);\n  var rest = getUnhandledProps(BreadcrumbDivider, props);\n  var ElementType = getElementType(BreadcrumbDivider, props);\n\n  if (!_isNil(icon)) {\n    return Icon.create(icon, {\n      defaultProps: _extends({}, rest, {\n        className: classes\n      }),\n      autoGenerateKey: false\n    });\n  }\n\n  if (!_isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? '/' : children);\n}\n\nBreadcrumbDivider.handledProps = [\"as\", \"children\", \"className\", \"content\", \"icon\"];\nBreadcrumbDivider.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Render as an `Icon` component with `divider` class instead of a `div`. */\n  icon: customPropTypes.itemShorthand\n} : {};\nBreadcrumbDivider.create = createShorthandFactory(BreadcrumbDivider, function (icon) {\n  return {\n    icon: icon\n  };\n});\nexport default BreadcrumbDivider;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getUnhandledProps, getElementType, useKeyOnly } from '../../lib';\n/**\n * A section sub-component for Breadcrumb component.\n */\n\nvar BreadcrumbSection = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(BreadcrumbSection, _Component);\n\n  function BreadcrumbSection() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.computeElementType = function () {\n      var _this$props = _this.props,\n          link = _this$props.link,\n          onClick = _this$props.onClick;\n      if (link || onClick) return 'a';\n    };\n\n    _this.handleClick = function (e) {\n      return _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = BreadcrumbSection.prototype;\n\n  _proto.render = function render() {\n    var _this$props2 = this.props,\n        active = _this$props2.active,\n        children = _this$props2.children,\n        className = _this$props2.className,\n        content = _this$props2.content,\n        href = _this$props2.href;\n    var classes = cx(useKeyOnly(active, 'active'), 'section', className);\n    var rest = getUnhandledProps(BreadcrumbSection, this.props);\n    var ElementType = getElementType(BreadcrumbSection, this.props, this.computeElementType);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      href: href,\n      onClick: this.handleClick\n    }), childrenUtils.isNil(children) ? content : children);\n  };\n\n  return BreadcrumbSection;\n}(Component);\n\nBreadcrumbSection.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"href\", \"link\", \"onClick\"];\nexport { BreadcrumbSection as default };\nBreadcrumbSection.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Style as the currently active section. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Render as an `a` tag instead of a `div` and adds the href attribute. */\n  href: customPropTypes.every([customPropTypes.disallow(['link']), PropTypes.string]),\n\n  /** Render as an `a` tag instead of a `div`. */\n  link: customPropTypes.every([customPropTypes.disallow(['href']), PropTypes.bool]),\n\n  /**\n   * Called on click. When passed, the component will render as an `a`\n   * tag by default instead of a `div`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func\n} : {};\nBreadcrumbSection.create = createShorthandFactory(BreadcrumbSection, function (content) {\n  return {\n    content: content,\n    link: true\n  };\n});","import _default from './Breadcrumb';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { getElementType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib';\nimport FormButton from './FormButton';\nimport FormCheckbox from './FormCheckbox';\nimport FormDropdown from './FormDropdown';\nimport FormField from './FormField';\nimport FormGroup from './FormGroup';\nimport FormInput from './FormInput';\nimport FormRadio from './FormRadio';\nimport FormSelect from './FormSelect';\nimport FormTextArea from './FormTextArea';\n/**\n * A Form displays a set of related user input fields in a structured way.\n * @see Button\n * @see Checkbox\n * @see Dropdown\n * @see Input\n * @see Message\n * @see Radio\n * @see Select\n * @see Visibility\n */\n\nvar Form = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Form, _Component);\n\n  function Form() {\n    var _this;\n\n    for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {\n      _args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(_args)) || this;\n\n    _this.handleSubmit = function (e) {\n      var action = _this.props.action; // Heads up! Third party libs can pass own data as first argument, we need to check that it has preventDefault()\n      // method.\n\n      if (typeof action !== 'string') _invoke(e, 'preventDefault');\n\n      for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n        args[_key2 - 1] = arguments[_key2];\n      }\n\n      _invoke.apply(void 0, [_this.props, 'onSubmit', e, _this.props].concat(args));\n    };\n\n    return _this;\n  }\n\n  var _proto = Form.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        action = _this$props.action,\n        children = _this$props.children,\n        className = _this$props.className,\n        error = _this$props.error,\n        inverted = _this$props.inverted,\n        loading = _this$props.loading,\n        reply = _this$props.reply,\n        size = _this$props.size,\n        success = _this$props.success,\n        unstackable = _this$props.unstackable,\n        warning = _this$props.warning,\n        widths = _this$props.widths;\n    var classes = cx('ui', size, useKeyOnly(error, 'error'), useKeyOnly(inverted, 'inverted'), useKeyOnly(loading, 'loading'), useKeyOnly(reply, 'reply'), useKeyOnly(success, 'success'), useKeyOnly(unstackable, 'unstackable'), useKeyOnly(warning, 'warning'), useWidthProp(widths, null, true), 'form', className);\n    var rest = getUnhandledProps(Form, this.props);\n    var ElementType = getElementType(Form, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      action: action,\n      className: classes,\n      onSubmit: this.handleSubmit\n    }), children);\n  };\n\n  return Form;\n}(Component);\n\nForm.handledProps = [\"action\", \"as\", \"children\", \"className\", \"error\", \"inverted\", \"loading\", \"onSubmit\", \"reply\", \"size\", \"success\", \"unstackable\", \"warning\", \"widths\"];\nForm.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** The HTML form action */\n  action: PropTypes.string,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Automatically show any error Message children. */\n  error: PropTypes.bool,\n\n  /** A form can have its color inverted for contrast. */\n  inverted: PropTypes.bool,\n\n  /** Automatically show a loading indicator. */\n  loading: PropTypes.bool,\n\n  /** The HTML form submit handler. */\n  onSubmit: PropTypes.func,\n\n  /** A comment can contain a form to reply to a comment. This may have arbitrary content. */\n  reply: PropTypes.bool,\n\n  /** A form can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** Automatically show any success Message children. */\n  success: PropTypes.bool,\n\n  /** A form can prevent itself from stacking on mobile. */\n  unstackable: PropTypes.bool,\n\n  /** Automatically show any warning Message children. */\n  warning: PropTypes.bool,\n\n  /** Forms can automatically divide fields to be equal width. */\n  widths: PropTypes.oneOf(['equal'])\n} : {};\nForm.defaultProps = {\n  as: 'form'\n};\nForm.Field = FormField;\nForm.Button = FormButton;\nForm.Checkbox = FormCheckbox;\nForm.Dropdown = FormDropdown;\nForm.Group = FormGroup;\nForm.Input = FormInput;\nForm.Radio = FormRadio;\nForm.Select = FormSelect;\nForm.TextArea = FormTextArea;\nexport default Form;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Button from '../../elements/Button';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Button} />.\n * @see Button\n * @see Form\n */\n\nfunction FormButton(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormButton, props);\n  var ElementType = getElementType(FormButton, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormButton.handledProps = [\"as\", \"control\"];\nFormButton.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormButton.defaultProps = {\n  as: FormField,\n  control: Button\n};\nexport default FormButton;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Checkbox from '../../modules/Checkbox';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Checkbox} />.\n * @see Checkbox\n * @see Form\n */\n\nfunction FormCheckbox(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormCheckbox, props);\n  var ElementType = getElementType(FormCheckbox, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormCheckbox.handledProps = [\"as\", \"control\"];\nFormCheckbox.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormCheckbox.defaultProps = {\n  as: FormField,\n  control: Checkbox\n};\nexport default FormCheckbox;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Dropdown from '../../modules/Dropdown';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Dropdown} />.\n * @see Dropdown\n * @see Form\n */\n\nfunction FormDropdown(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormDropdown, props);\n  var ElementType = getElementType(FormDropdown, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormDropdown.handledProps = [\"as\", \"control\"];\nFormDropdown.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormDropdown.defaultProps = {\n  as: FormField,\n  control: Dropdown\n};\nexport default FormDropdown;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _isNil from \"lodash/isNil\";\nimport _get from \"lodash/get\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { createElement } from 'react';\nimport { childrenUtils, createHTMLLabel, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib';\nimport Label from '../../elements/Label';\nimport Checkbox from '../../modules/Checkbox';\nimport Radio from '../../addons/Radio';\n/**\n * A field is a form element containing a label and an input.\n * @see Form\n * @see Button\n * @see Checkbox\n * @see Dropdown\n * @see Input\n * @see Radio\n * @see Select\n * @see Visibility\n */\n\nfunction FormField(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      control = props.control,\n      disabled = props.disabled,\n      error = props.error,\n      inline = props.inline,\n      label = props.label,\n      required = props.required,\n      type = props.type,\n      width = props.width,\n      id = props.id;\n  var classes = cx(useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(inline, 'inline'), useKeyOnly(required, 'required'), useWidthProp(width, 'wide'), 'field', className);\n  var rest = getUnhandledProps(FormField, props);\n  var ElementType = getElementType(FormField, props);\n\n  var errorPointing = _get(error, 'pointing', 'above');\n\n  var errorLabel = Label.create(error, {\n    autoGenerateKey: false,\n    defaultProps: {\n      prompt: true,\n      pointing: errorPointing,\n      id: id ? id + \"-error-message\" : undefined,\n      role: 'alert',\n      'aria-atomic': true\n    }\n  });\n  var errorLabelBefore = (errorPointing === 'below' || errorPointing === 'right') && errorLabel;\n  var errorLabelAfter = (errorPointing === 'above' || errorPointing === 'left') && errorLabel; // ----------------------------------------\n  // No Control\n  // ----------------------------------------\n\n  if (_isNil(control)) {\n    if (_isNil(label)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        id: id\n      }), childrenUtils.isNil(children) ? content : children);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      id: id\n    }), errorLabelBefore, createHTMLLabel(label, {\n      autoGenerateKey: false\n    }), errorLabelAfter);\n  } // ----------------------------------------\n  // Checkbox/Radio Control\n  // ----------------------------------------\n\n\n  var ariaDescribedBy = id && error ? id + \"-error-message\" : null;\n  var ariaAttrs = {\n    'aria-describedby': ariaDescribedBy,\n    'aria-invalid': error !== undefined ? true : undefined\n  };\n\n  var controlProps = _extends({}, rest, {\n    content: content,\n    children: children,\n    disabled: disabled,\n    required: required,\n    type: type,\n    id: id\n  }); // wrap HTML checkboxes/radios in the label\n\n\n  if (control === 'input' && (type === 'checkbox' || type === 'radio')) {\n    return /*#__PURE__*/React.createElement(ElementType, {\n      className: classes\n    }, /*#__PURE__*/React.createElement(\"label\", null, errorLabelBefore, /*#__PURE__*/createElement(control, _extends({}, ariaAttrs, controlProps)), \" \", label, errorLabelAfter));\n  } // pass label prop to controls that support it\n\n\n  if (control === Checkbox || control === Radio) {\n    return /*#__PURE__*/React.createElement(ElementType, {\n      className: classes\n    }, errorLabelBefore, /*#__PURE__*/createElement(control, _extends({}, ariaAttrs, controlProps, {\n      label: label\n    })), errorLabelAfter);\n  } // ----------------------------------------\n  // Other Control\n  // ----------------------------------------\n\n\n  return /*#__PURE__*/React.createElement(ElementType, {\n    className: classes\n  }, createHTMLLabel(label, {\n    defaultProps: {\n      htmlFor: id\n    },\n    autoGenerateKey: false\n  }), errorLabelBefore, /*#__PURE__*/createElement(control, _extends({}, ariaAttrs, controlProps)), errorLabelAfter);\n}\n\nFormField.handledProps = [\"as\", \"children\", \"className\", \"content\", \"control\", \"disabled\", \"error\", \"id\", \"inline\", \"label\", \"required\", \"type\", \"width\"];\nFormField.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /**\n   * A form control component (i.e. Dropdown) or HTML tagName (i.e. 'input').\n   * Extra FormField props are passed to the control component.\n   * Mutually exclusive with children.\n   */\n  control: customPropTypes.some([PropTypes.func, PropTypes.oneOf(['button', 'input', 'select', 'textarea'])]),\n\n  /** Individual fields may be disabled. */\n  disabled: PropTypes.bool,\n\n  /** Individual fields may display an error state along with a message. */\n  error: PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand]),\n\n  /** The id of the control */\n  id: PropTypes.string,\n\n  /** A field can have its label next to instead of above it. */\n  inline: PropTypes.bool,\n  // Heads Up!\n  // Do not disallow children with `label` shorthand\n  // The `control` might accept a `label` prop and `children`\n\n  /** Mutually exclusive with children. */\n  label: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),\n\n  /** A field can show that input is mandatory. */\n  required: PropTypes.bool,\n\n  /** Passed to the control component (i.e. <input type='password' />) */\n  type: customPropTypes.every([customPropTypes.demand(['control']) // don't strictly validate HTML types\n  // a control might be passed that uses a `type` prop with unknown values\n  // let the control validate if for us\n  ]),\n\n  /** A field can specify its width in grid columns */\n  width: PropTypes.oneOf(SUI.WIDTHS)\n} : {};\nexport default FormField;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib';\n/**\n * A set of fields can appear grouped together.\n * @see Form\n */\n\nfunction FormGroup(props) {\n  var children = props.children,\n      className = props.className,\n      grouped = props.grouped,\n      inline = props.inline,\n      unstackable = props.unstackable,\n      widths = props.widths;\n  var classes = cx(useKeyOnly(grouped, 'grouped'), useKeyOnly(inline, 'inline'), useKeyOnly(unstackable, 'unstackable'), useWidthProp(widths, null, true), 'fields', className);\n  var rest = getUnhandledProps(FormGroup, props);\n  var ElementType = getElementType(FormGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), children);\n}\n\nFormGroup.handledProps = [\"as\", \"children\", \"className\", \"grouped\", \"inline\", \"unstackable\", \"widths\"];\nFormGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Fields can show related choices. */\n  grouped: customPropTypes.every([customPropTypes.disallow(['inline']), PropTypes.bool]),\n\n  /** Multiple fields may be inline in a row. */\n  inline: customPropTypes.every([customPropTypes.disallow(['grouped']), PropTypes.bool]),\n\n  /** A form group can prevent itself from stacking on mobile. */\n  unstackable: PropTypes.bool,\n\n  /** Fields Groups can specify their width in grid columns or automatically divide fields to be equal width. */\n  widths: PropTypes.oneOf([].concat(SUI.WIDTHS, ['equal']))\n} : {};\nexport default FormGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Input from '../../elements/Input';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Input} />.\n * @see Form\n * @see Input\n */\n\nfunction FormInput(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormInput, props);\n  var ElementType = getElementType(FormInput, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormInput.handledProps = [\"as\", \"control\"];\nFormInput.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormInput.defaultProps = {\n  as: FormField,\n  control: Input\n};\nexport default FormInput;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Radio from '../../addons/Radio';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Radio} />.\n * @see Form\n * @see Radio\n */\n\nfunction FormRadio(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormRadio, props);\n  var ElementType = getElementType(FormRadio, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormRadio.handledProps = [\"as\", \"control\"];\nFormRadio.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormRadio.defaultProps = {\n  as: FormField,\n  control: Radio\n};\nexport default FormRadio;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport Select from '../../addons/Select';\nimport Dropdown from '../../modules/Dropdown';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={Select} />.\n * @see Form\n * @see Select\n */\n\nfunction FormSelect(props) {\n  var control = props.control,\n      options = props.options;\n  var rest = getUnhandledProps(FormSelect, props);\n  var ElementType = getElementType(FormSelect, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control,\n    options: options\n  }));\n}\n\nFormSelect.handledProps = [\"as\", \"control\", \"options\"];\nFormSelect.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control,\n\n  /** Array of Dropdown.Item props e.g. `{ text: '', value: '' }` */\n  options: PropTypes.arrayOf(PropTypes.shape(Dropdown.Item.propTypes)).isRequired\n} : {};\nFormSelect.defaultProps = {\n  as: FormField,\n  control: Select\n};\nexport default FormSelect;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\nimport TextArea from '../../addons/TextArea';\nimport FormField from './FormField';\n/**\n * Sugar for <Form.Field control={TextArea} />.\n * @see Form\n * @see TextArea\n */\n\nfunction FormTextArea(props) {\n  var control = props.control;\n  var rest = getUnhandledProps(FormTextArea, props);\n  var ElementType = getElementType(FormTextArea, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    control: control\n  }));\n}\n\nFormTextArea.handledProps = [\"as\", \"control\"];\nFormTextArea.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A FormField control prop. */\n  control: FormField.propTypes.control\n} : {};\nFormTextArea.defaultProps = {\n  as: FormField,\n  control: TextArea\n};\nexport default FormTextArea;","import _default from './Form';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useMultipleProp, useTextAlignProp, useVerticalAlignProp, useWidthProp } from '../../lib';\nimport GridColumn from './GridColumn';\nimport GridRow from './GridRow';\n/**\n * A grid is used to harmonize negative space in a layout.\n */\n\nfunction Grid(props) {\n  var celled = props.celled,\n      centered = props.centered,\n      children = props.children,\n      className = props.className,\n      columns = props.columns,\n      container = props.container,\n      divided = props.divided,\n      doubling = props.doubling,\n      inverted = props.inverted,\n      padded = props.padded,\n      relaxed = props.relaxed,\n      reversed = props.reversed,\n      stackable = props.stackable,\n      stretched = props.stretched,\n      textAlign = props.textAlign,\n      verticalAlign = props.verticalAlign;\n  var classes = cx('ui', useKeyOnly(centered, 'centered'), useKeyOnly(container, 'container'), useKeyOnly(doubling, 'doubling'), useKeyOnly(inverted, 'inverted'), useKeyOnly(stackable, 'stackable'), useKeyOnly(stretched, 'stretched'), useKeyOrValueAndKey(celled, 'celled'), useKeyOrValueAndKey(divided, 'divided'), useKeyOrValueAndKey(padded, 'padded'), useKeyOrValueAndKey(relaxed, 'relaxed'), useMultipleProp(reversed, 'reversed'), useTextAlignProp(textAlign), useVerticalAlignProp(verticalAlign), useWidthProp(columns, 'column', true), 'grid', className);\n  var rest = getUnhandledProps(Grid, props);\n  var ElementType = getElementType(Grid, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), children);\n}\n\nGrid.handledProps = [\"as\", \"celled\", \"centered\", \"children\", \"className\", \"columns\", \"container\", \"divided\", \"doubling\", \"inverted\", \"padded\", \"relaxed\", \"reversed\", \"stackable\", \"stretched\", \"textAlign\", \"verticalAlign\"];\nGrid.Column = GridColumn;\nGrid.Row = GridRow;\nGrid.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A grid can have rows divided into cells. */\n  celled: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['internally'])]),\n\n  /** A grid can have its columns centered. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Represents column count per row in Grid. */\n  columns: PropTypes.oneOf([].concat(SUI.WIDTHS, ['equal'])),\n\n  /** A grid can be combined with a container to use the available layout and alignment. */\n  container: PropTypes.bool,\n\n  /** A grid can have dividers between its columns. */\n  divided: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['vertically'])]),\n\n  /** A grid can double its column width on tablet and mobile sizes. */\n  doubling: PropTypes.bool,\n\n  /** A grid's colors can be inverted. */\n  inverted: PropTypes.bool,\n\n  /** A grid can preserve its vertical and horizontal gutters on first and last columns. */\n  padded: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['horizontally', 'vertically'])]),\n\n  /** A grid can increase its gutters to allow for more negative space. */\n  relaxed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** A grid can specify that its columns should reverse order at different device sizes. */\n  reversed: customPropTypes.multipleProp(['computer', 'computer vertically', 'mobile', 'mobile vertically', 'tablet', 'tablet vertically']),\n\n  /** A grid can have its columns stack on-top of each other after reaching mobile breakpoints. */\n  stackable: PropTypes.bool,\n\n  /** A grid can stretch its contents to take up the entire grid height. */\n  stretched: PropTypes.bool,\n\n  /** A grid can specify its text alignment. */\n  textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS),\n\n  /** A grid can specify its vertical alignment to have all its columns vertically centered. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nexport default Grid;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, createShorthandFactory, getElementType, getUnhandledProps, SUI, useKeyOnly, useMultipleProp, useTextAlignProp, useValueAndKey, useVerticalAlignProp, useWidthProp } from '../../lib';\n/**\n * A column sub-component for Grid.\n */\n\nfunction GridColumn(props) {\n  var children = props.children,\n      className = props.className,\n      computer = props.computer,\n      color = props.color,\n      floated = props.floated,\n      largeScreen = props.largeScreen,\n      mobile = props.mobile,\n      only = props.only,\n      stretched = props.stretched,\n      tablet = props.tablet,\n      textAlign = props.textAlign,\n      verticalAlign = props.verticalAlign,\n      widescreen = props.widescreen,\n      width = props.width;\n  var classes = cx(color, useKeyOnly(stretched, 'stretched'), useMultipleProp(only, 'only'), useTextAlignProp(textAlign), useValueAndKey(floated, 'floated'), useVerticalAlignProp(verticalAlign), useWidthProp(computer, 'wide computer'), useWidthProp(largeScreen, 'wide large screen'), useWidthProp(mobile, 'wide mobile'), useWidthProp(tablet, 'wide tablet'), useWidthProp(widescreen, 'wide widescreen'), useWidthProp(width, 'wide'), 'column', className);\n  var rest = getUnhandledProps(GridColumn, props);\n  var ElementType = getElementType(GridColumn, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), children);\n}\n\nGridColumn.handledProps = [\"as\", \"children\", \"className\", \"color\", \"computer\", \"floated\", \"largeScreen\", \"mobile\", \"only\", \"stretched\", \"tablet\", \"textAlign\", \"verticalAlign\", \"widescreen\", \"width\"];\nGridColumn.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A grid column can be colored. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** A column can specify a width for a computer. */\n  computer: customPropTypes.every([customPropTypes.disallow(['width']), PropTypes.oneOf(SUI.WIDTHS)]),\n\n  /** A column can sit flush against the left or right edge of a row. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** A column can specify a width for a large screen device. */\n  largeScreen: customPropTypes.every([customPropTypes.disallow(['width']), PropTypes.oneOf(SUI.WIDTHS)]),\n\n  /** A column can specify a width for a mobile device. */\n  mobile: customPropTypes.every([customPropTypes.disallow(['width']), PropTypes.oneOf(SUI.WIDTHS)]),\n\n  /** A column can appear only for a specific device, or screen sizes. */\n  only: customPropTypes.multipleProp(SUI.VISIBILITY),\n\n  /** A column can stretch its contents to take up the entire grid or row height. */\n  stretched: PropTypes.bool,\n\n  /** A column can specify a width for a tablet device. */\n  tablet: customPropTypes.every([customPropTypes.disallow(['width']), PropTypes.oneOf(SUI.WIDTHS)]),\n\n  /** A column can specify its text alignment. */\n  textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS),\n\n  /** A column can specify its vertical alignment to have all its columns vertically centered. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),\n\n  /** A column can specify a width for a wide screen device. */\n  widescreen: customPropTypes.every([customPropTypes.disallow(['width']), PropTypes.oneOf(SUI.WIDTHS)]),\n\n  /** Represents width of column. */\n  width: customPropTypes.every([customPropTypes.disallow(['computer', 'largeScreen', 'mobile', 'tablet', 'widescreen']), PropTypes.oneOf(SUI.WIDTHS)])\n} : {};\nGridColumn.create = createShorthandFactory(GridColumn, function (children) {\n  return {\n    children: children\n  };\n});\nexport default GridColumn;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useMultipleProp, useTextAlignProp, useVerticalAlignProp, useWidthProp } from '../../lib';\n/**\n * A row sub-component for Grid.\n */\n\nfunction GridRow(props) {\n  var centered = props.centered,\n      children = props.children,\n      className = props.className,\n      color = props.color,\n      columns = props.columns,\n      divided = props.divided,\n      only = props.only,\n      reversed = props.reversed,\n      stretched = props.stretched,\n      textAlign = props.textAlign,\n      verticalAlign = props.verticalAlign;\n  var classes = cx(color, useKeyOnly(centered, 'centered'), useKeyOnly(divided, 'divided'), useKeyOnly(stretched, 'stretched'), useMultipleProp(only, 'only'), useMultipleProp(reversed, 'reversed'), useTextAlignProp(textAlign), useVerticalAlignProp(verticalAlign), useWidthProp(columns, 'column', true), 'row', className);\n  var rest = getUnhandledProps(GridRow, props);\n  var ElementType = getElementType(GridRow, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), children);\n}\n\nGridRow.handledProps = [\"as\", \"centered\", \"children\", \"className\", \"color\", \"columns\", \"divided\", \"only\", \"reversed\", \"stretched\", \"textAlign\", \"verticalAlign\"];\nGridRow.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A row can have its columns centered. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A grid row can be colored. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Represents column count per line in Row. */\n  columns: PropTypes.oneOf([].concat(SUI.WIDTHS, ['equal'])),\n\n  /** A row can have dividers between its columns. */\n  divided: PropTypes.bool,\n\n  /** A row can appear only for a specific device, or screen sizes. */\n  only: customPropTypes.multipleProp(SUI.VISIBILITY),\n\n  /** A row can specify that its columns should reverse order at different device sizes. */\n  reversed: customPropTypes.multipleProp(['computer', 'computer vertically', 'mobile', 'mobile vertically', 'tablet', 'tablet vertically']),\n\n  /** A row can stretch its contents to take up the entire column height. */\n  stretched: PropTypes.bool,\n\n  /** A row can specify its text alignment. */\n  textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS),\n\n  /** A row can specify its vertical alignment to have all its columns vertically centered. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nexport default GridRow;","import _default from './Grid';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, childrenUtils, customPropTypes, createShorthandFactory, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useWidthProp } from '../../lib';\nimport MenuHeader from './MenuHeader';\nimport MenuItem from './MenuItem';\nimport MenuMenu from './MenuMenu';\n/**\n * A menu displays grouped navigation actions.\n * @see Dropdown\n */\n\nvar Menu = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Menu, _Component);\n\n  function Menu() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleItemOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, itemProps) {\n          var index = itemProps.index;\n\n          _this.setState({\n            activeIndex: index\n          });\n\n          _invoke(predefinedProps, 'onClick', e, itemProps);\n\n          _invoke(_this.props, 'onItemClick', e, itemProps);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = Menu.prototype;\n\n  _proto.renderItems = function renderItems() {\n    var _this2 = this;\n\n    var items = this.props.items;\n    var activeIndex = this.state.activeIndex;\n    return _map(items, function (item, index) {\n      return MenuItem.create(item, {\n        defaultProps: {\n          active: parseInt(activeIndex, 10) === index,\n          index: index\n        },\n        overrideProps: _this2.handleItemOverrides\n      });\n    });\n  };\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        attached = _this$props.attached,\n        borderless = _this$props.borderless,\n        children = _this$props.children,\n        className = _this$props.className,\n        color = _this$props.color,\n        compact = _this$props.compact,\n        fixed = _this$props.fixed,\n        floated = _this$props.floated,\n        fluid = _this$props.fluid,\n        icon = _this$props.icon,\n        inverted = _this$props.inverted,\n        pagination = _this$props.pagination,\n        pointing = _this$props.pointing,\n        secondary = _this$props.secondary,\n        size = _this$props.size,\n        stackable = _this$props.stackable,\n        tabular = _this$props.tabular,\n        text = _this$props.text,\n        vertical = _this$props.vertical,\n        widths = _this$props.widths;\n    var classes = cx('ui', color, size, useKeyOnly(borderless, 'borderless'), useKeyOnly(compact, 'compact'), useKeyOnly(fluid, 'fluid'), useKeyOnly(inverted, 'inverted'), useKeyOnly(pagination, 'pagination'), useKeyOnly(pointing, 'pointing'), useKeyOnly(secondary, 'secondary'), useKeyOnly(stackable, 'stackable'), useKeyOnly(text, 'text'), useKeyOnly(vertical, 'vertical'), useKeyOrValueAndKey(attached, 'attached'), useKeyOrValueAndKey(floated, 'floated'), useKeyOrValueAndKey(icon, 'icon'), useKeyOrValueAndKey(tabular, 'tabular'), useValueAndKey(fixed, 'fixed'), useWidthProp(widths, 'item'), className, 'menu');\n    var rest = getUnhandledProps(Menu, this.props);\n    var ElementType = getElementType(Menu, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), childrenUtils.isNil(children) ? this.renderItems() : children);\n  };\n\n  return Menu;\n}(Component);\n\nMenu.handledProps = [\"activeIndex\", \"as\", \"attached\", \"borderless\", \"children\", \"className\", \"color\", \"compact\", \"defaultActiveIndex\", \"fixed\", \"floated\", \"fluid\", \"icon\", \"inverted\", \"items\", \"onItemClick\", \"pagination\", \"pointing\", \"secondary\", \"size\", \"stackable\", \"tabular\", \"text\", \"vertical\", \"widths\"];\nMenu.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Index of the currently active item. */\n  activeIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** A menu may be attached to other content segments. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top', 'bottom'])]),\n\n  /** A menu item or menu can have no borders. */\n  borderless: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Additional colors can be specified. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** A menu can take up only the space necessary to fit its content. */\n  compact: PropTypes.bool,\n\n  /** Initial activeIndex value. */\n  defaultActiveIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** A menu can be fixed to a side of its context. */\n  fixed: PropTypes.oneOf(['left', 'right', 'bottom', 'top']),\n\n  /** A menu can be floated. */\n  floated: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['right'])]),\n\n  /** A vertical menu may take the size of its container. */\n  fluid: PropTypes.bool,\n\n  /** A menu may have just icons (bool) or labeled icons. */\n  icon: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['labeled'])]),\n\n  /** A menu may have its colors inverted to show greater contrast. */\n  inverted: PropTypes.bool,\n\n  /** Shorthand array of props for Menu. */\n  items: customPropTypes.collectionShorthand,\n\n  /**\n   * onClick handler for MenuItem. Mutually exclusive with children.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All item props.\n   */\n  onItemClick: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.func]),\n\n  /** A pagination menu is specially formatted to present links to pages of content. */\n  pagination: PropTypes.bool,\n\n  /** A menu can point to show its relationship to nearby content. */\n  pointing: PropTypes.bool,\n\n  /** A menu can adjust its appearance to de-emphasize its contents. */\n  secondary: PropTypes.bool,\n\n  /** A menu can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium', 'big')),\n\n  /** A menu can stack at mobile resolutions. */\n  stackable: PropTypes.bool,\n\n  /** A menu can be formatted to show tabs of information. */\n  tabular: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['right'])]),\n\n  /** A menu can be formatted for text content. */\n  text: PropTypes.bool,\n\n  /** A vertical menu displays elements vertically. */\n  vertical: PropTypes.bool,\n\n  /** A menu can have its items divided evenly. */\n  widths: PropTypes.oneOf(SUI.WIDTHS)\n} : {};\nMenu.autoControlledProps = ['activeIndex'];\nMenu.Header = MenuHeader;\nMenu.Item = MenuItem;\nMenu.Menu = MenuMenu;\nMenu.create = createShorthandFactory(Menu, function (items) {\n  return {\n    items: items\n  };\n});\nexport default Menu;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A menu item may include a header or may itself be a header.\n */\n\nfunction MenuHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(MenuHeader, props);\n  var ElementType = getElementType(MenuHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nMenuHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nMenuHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default MenuHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _startCase from \"lodash/startCase\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A menu can contain an item.\n */\n\nvar MenuItem = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(MenuItem, _Component);\n\n  function MenuItem() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var disabled = _this.props.disabled;\n      if (!disabled) _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = MenuItem.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        color = _this$props.color,\n        content = _this$props.content,\n        disabled = _this$props.disabled,\n        fitted = _this$props.fitted,\n        header = _this$props.header,\n        icon = _this$props.icon,\n        link = _this$props.link,\n        name = _this$props.name,\n        onClick = _this$props.onClick,\n        position = _this$props.position;\n    var classes = cx(color, position, useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(icon === true || icon && !(name || content), 'icon'), useKeyOnly(header, 'header'), useKeyOnly(link, 'link'), useKeyOrValueAndKey(fitted, 'fitted'), 'item', className);\n    var ElementType = getElementType(MenuItem, this.props, function () {\n      if (onClick) return 'a';\n    });\n    var rest = getUnhandledProps(MenuItem, this.props);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick\n    }), Icon.create(icon, {\n      autoGenerateKey: false\n    }), childrenUtils.isNil(content) ? _startCase(name) : content);\n  };\n\n  return MenuItem;\n}(Component);\n\nMenuItem.handledProps = [\"active\", \"as\", \"children\", \"className\", \"color\", \"content\", \"disabled\", \"fitted\", \"header\", \"icon\", \"index\", \"link\", \"name\", \"onClick\", \"position\"];\nexport { MenuItem as default };\nMenuItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A menu item can be active. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Additional colors can be specified. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A menu item can be disabled. */\n  disabled: PropTypes.bool,\n\n  /** A menu item or menu can remove element padding, vertically or horizontally. */\n  fitted: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['horizontally', 'vertically'])]),\n\n  /** A menu item may include a header or may itself be a header. */\n  header: PropTypes.bool,\n\n  /** MenuItem can be only icon. */\n  icon: PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand]),\n\n  /** MenuItem index inside Menu. */\n  index: PropTypes.number,\n\n  /** A menu item can be link. */\n  link: PropTypes.bool,\n\n  /** Internal name of the MenuItem. */\n  name: PropTypes.string,\n\n  /**\n   * Called on click. When passed, the component will render as an `a`\n   * tag by default instead of a `div`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /** A menu item can take left or right position. */\n  position: PropTypes.oneOf(['left', 'right'])\n} : {};\nMenuItem.create = createShorthandFactory(MenuItem, function (val) {\n  return {\n    content: val,\n    name: val\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A menu can contain a sub menu.\n */\n\nfunction MenuMenu(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      position = props.position;\n  var classes = cx(position, 'menu', className);\n  var rest = getUnhandledProps(MenuMenu, props);\n  var ElementType = getElementType(MenuMenu, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nMenuMenu.handledProps = [\"as\", \"children\", \"className\", \"content\", \"position\"];\nMenuMenu.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A sub menu can take left or right position. */\n  position: PropTypes.oneOf(['left', 'right'])\n} : {};\nexport default MenuMenu;","import _default from './Menu';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createHTMLParagraph, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\nimport Icon from '../../elements/Icon';\nimport MessageContent from './MessageContent';\nimport MessageHeader from './MessageHeader';\nimport MessageList from './MessageList';\nimport MessageItem from './MessageItem';\n/**\n * A message displays information that explains nearby content.\n * @see Form\n */\n\nvar Message = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Message, _Component);\n\n  function Message() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleDismiss = function (e) {\n      var onDismiss = _this.props.onDismiss;\n      if (onDismiss) onDismiss(e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = Message.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        attached = _this$props.attached,\n        children = _this$props.children,\n        className = _this$props.className,\n        color = _this$props.color,\n        compact = _this$props.compact,\n        content = _this$props.content,\n        error = _this$props.error,\n        floating = _this$props.floating,\n        header = _this$props.header,\n        hidden = _this$props.hidden,\n        icon = _this$props.icon,\n        info = _this$props.info,\n        list = _this$props.list,\n        negative = _this$props.negative,\n        onDismiss = _this$props.onDismiss,\n        positive = _this$props.positive,\n        size = _this$props.size,\n        success = _this$props.success,\n        visible = _this$props.visible,\n        warning = _this$props.warning;\n    var classes = cx('ui', color, size, useKeyOnly(compact, 'compact'), useKeyOnly(error, 'error'), useKeyOnly(floating, 'floating'), useKeyOnly(hidden, 'hidden'), useKeyOnly(icon, 'icon'), useKeyOnly(info, 'info'), useKeyOnly(negative, 'negative'), useKeyOnly(positive, 'positive'), useKeyOnly(success, 'success'), useKeyOnly(visible, 'visible'), useKeyOnly(warning, 'warning'), useKeyOrValueAndKey(attached, 'attached'), 'message', className);\n    var dismissIcon = onDismiss && /*#__PURE__*/React.createElement(Icon, {\n      name: \"close\",\n      onClick: this.handleDismiss\n    });\n    var rest = getUnhandledProps(Message, this.props);\n    var ElementType = getElementType(Message, this.props);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes\n      }), dismissIcon, children);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), dismissIcon, Icon.create(icon, {\n      autoGenerateKey: false\n    }), (!_isNil(header) || !_isNil(content) || !_isNil(list)) && /*#__PURE__*/React.createElement(MessageContent, null, MessageHeader.create(header, {\n      autoGenerateKey: false\n    }), MessageList.create(list, {\n      autoGenerateKey: false\n    }), createHTMLParagraph(content, {\n      autoGenerateKey: false\n    })));\n  };\n\n  return Message;\n}(Component);\n\nMessage.handledProps = [\"as\", \"attached\", \"children\", \"className\", \"color\", \"compact\", \"content\", \"error\", \"floating\", \"header\", \"hidden\", \"icon\", \"info\", \"list\", \"negative\", \"onDismiss\", \"positive\", \"size\", \"success\", \"visible\", \"warning\"];\nexport { Message as default };\nMessage.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A message can be formatted to attach itself to other content. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['bottom', 'top'])]),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A message can be formatted to be different colors. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** A message can only take up the width of its content. */\n  compact: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A message may be formatted to display a negative message. Same as `negative`. */\n  error: PropTypes.bool,\n\n  /** A message can float above content that it is related to. */\n  floating: PropTypes.bool,\n\n  /** Shorthand for MessageHeader. */\n  header: customPropTypes.itemShorthand,\n\n  /** A message can be hidden. */\n  hidden: PropTypes.bool,\n\n  /** A message can contain an icon. */\n  icon: PropTypes.oneOfType([customPropTypes.itemShorthand, PropTypes.bool]),\n\n  /** A message may be formatted to display information. */\n  info: PropTypes.bool,\n\n  /** Array shorthand items for the MessageList. Mutually exclusive with children. */\n  list: customPropTypes.collectionShorthand,\n\n  /** A message may be formatted to display a negative message. Same as `error`. */\n  negative: PropTypes.bool,\n\n  /**\n   * A message that the user can choose to hide.\n   * Called when the user clicks the \"x\" icon. This also adds the \"x\" icon.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onDismiss: PropTypes.func,\n\n  /** A message may be formatted to display a positive message.  Same as `success`. */\n  positive: PropTypes.bool,\n\n  /** A message can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** A message may be formatted to display a positive message.  Same as `positive`. */\n  success: PropTypes.bool,\n\n  /** A message can be set to visible to force itself to be shown. */\n  visible: PropTypes.bool,\n\n  /** A message may be formatted to display warning messages. */\n  warning: PropTypes.bool\n} : {};\nMessage.Content = MessageContent;\nMessage.Header = MessageHeader;\nMessage.List = MessageList;\nMessage.Item = MessageItem;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A message can contain a content.\n */\n\nfunction MessageContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(MessageContent, props);\n  var ElementType = getElementType(MessageContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nMessageContent.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nMessageContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default MessageContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A message can contain a header.\n */\n\nfunction MessageHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(MessageHeader, props);\n  var ElementType = getElementType(MessageHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nMessageHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nMessageHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nMessageHeader.create = createShorthandFactory(MessageHeader, function (val) {\n  return {\n    content: val\n  };\n});\nexport default MessageHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A message list can contain an item.\n */\n\nfunction MessageItem(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(MessageItem, props);\n  var ElementType = getElementType(MessageItem, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nMessageItem.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nMessageItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nMessageItem.defaultProps = {\n  as: 'li'\n};\nMessageItem.create = createShorthandFactory(MessageItem, function (content) {\n  return {\n    content: content\n  };\n});\nexport default MessageItem;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport MessageItem from './MessageItem';\n/**\n * A message can contain a list of items.\n */\n\nfunction MessageList(props) {\n  var children = props.children,\n      className = props.className,\n      items = props.items;\n  var classes = cx('list', className);\n  var rest = getUnhandledProps(MessageList, props);\n  var ElementType = getElementType(MessageList, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? _map(items, MessageItem.create) : children);\n}\n\nMessageList.handledProps = [\"as\", \"children\", \"className\", \"items\"];\nMessageList.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand Message.Items. */\n  items: customPropTypes.collectionShorthand\n} : {};\nMessageList.defaultProps = {\n  as: 'ul'\n};\nMessageList.create = createShorthandFactory(MessageList, function (val) {\n  return {\n    items: val\n  };\n});\nexport default MessageList;","import _default from './Message';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useTextAlignProp, useVerticalAlignProp, useWidthProp } from '../../lib';\nimport TableBody from './TableBody';\nimport TableCell from './TableCell';\nimport TableFooter from './TableFooter';\nimport TableHeader from './TableHeader';\nimport TableHeaderCell from './TableHeaderCell';\nimport TableRow from './TableRow';\n/**\n * A table displays a collections of data grouped into rows.\n */\n\nfunction Table(props) {\n  var attached = props.attached,\n      basic = props.basic,\n      celled = props.celled,\n      children = props.children,\n      className = props.className,\n      collapsing = props.collapsing,\n      color = props.color,\n      columns = props.columns,\n      compact = props.compact,\n      definition = props.definition,\n      fixed = props.fixed,\n      footerRow = props.footerRow,\n      headerRow = props.headerRow,\n      headerRows = props.headerRows,\n      inverted = props.inverted,\n      padded = props.padded,\n      renderBodyRow = props.renderBodyRow,\n      selectable = props.selectable,\n      singleLine = props.singleLine,\n      size = props.size,\n      sortable = props.sortable,\n      stackable = props.stackable,\n      striped = props.striped,\n      structured = props.structured,\n      tableData = props.tableData,\n      textAlign = props.textAlign,\n      unstackable = props.unstackable,\n      verticalAlign = props.verticalAlign;\n  var classes = cx('ui', color, size, useKeyOnly(celled, 'celled'), useKeyOnly(collapsing, 'collapsing'), useKeyOnly(definition, 'definition'), useKeyOnly(fixed, 'fixed'), useKeyOnly(inverted, 'inverted'), useKeyOnly(selectable, 'selectable'), useKeyOnly(singleLine, 'single line'), useKeyOnly(sortable, 'sortable'), useKeyOnly(stackable, 'stackable'), useKeyOnly(striped, 'striped'), useKeyOnly(structured, 'structured'), useKeyOnly(unstackable, 'unstackable'), useKeyOrValueAndKey(attached, 'attached'), useKeyOrValueAndKey(basic, 'basic'), useKeyOrValueAndKey(compact, 'compact'), useKeyOrValueAndKey(padded, 'padded'), useTextAlignProp(textAlign), useVerticalAlignProp(verticalAlign), useWidthProp(columns, 'column'), 'table', className);\n  var rest = getUnhandledProps(Table, props);\n  var ElementType = getElementType(Table, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  var hasHeaderRows = headerRow || headerRows;\n  var headerShorthandOptions = {\n    defaultProps: {\n      cellAs: 'th'\n    }\n  };\n  var headerElement = hasHeaderRows && /*#__PURE__*/React.createElement(TableHeader, null, TableRow.create(headerRow, headerShorthandOptions), _map(headerRows, function (data) {\n    return TableRow.create(data, headerShorthandOptions);\n  }));\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), headerElement, /*#__PURE__*/React.createElement(TableBody, null, renderBodyRow && _map(tableData, function (data, index) {\n    return TableRow.create(renderBodyRow(data, index));\n  })), footerRow && /*#__PURE__*/React.createElement(TableFooter, null, TableRow.create(footerRow)));\n}\n\nTable.handledProps = [\"as\", \"attached\", \"basic\", \"celled\", \"children\", \"className\", \"collapsing\", \"color\", \"columns\", \"compact\", \"definition\", \"fixed\", \"footerRow\", \"headerRow\", \"headerRows\", \"inverted\", \"padded\", \"renderBodyRow\", \"selectable\", \"singleLine\", \"size\", \"sortable\", \"stackable\", \"striped\", \"structured\", \"tableData\", \"textAlign\", \"unstackable\", \"verticalAlign\"];\nTable.defaultProps = {\n  as: 'table'\n};\nTable.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Attach table to other content */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top', 'bottom'])]),\n\n  /** A table can reduce its complexity to increase readability. */\n  basic: PropTypes.oneOfType([PropTypes.oneOf(['very']), PropTypes.bool]),\n\n  /** A table may be divided each row into separate cells. */\n  celled: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A table can be collapsing, taking up only as much space as its rows. */\n  collapsing: PropTypes.bool,\n\n  /** A table can be given a color to distinguish it from other tables. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** A table can specify its column count to divide its content evenly. */\n  columns: PropTypes.oneOf(SUI.WIDTHS),\n\n  /** A table may sometimes need to be more compact to make more rows visible at a time. */\n  compact: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** A table may be formatted to emphasize a first column that defines a rows content. */\n  definition: PropTypes.bool,\n\n  /**\n   * A table can use fixed a special faster form of table rendering that does not resize table cells based on content\n   */\n  fixed: PropTypes.bool,\n\n  /** Shorthand for a TableRow to be placed within Table.Footer. */\n  footerRow: customPropTypes.itemShorthand,\n\n  /** Shorthand for a TableRow to be placed within Table.Header. */\n  headerRow: customPropTypes.every([customPropTypes.disallow(['headerRows']), customPropTypes.itemShorthand]),\n\n  /** Shorthand for multiple TableRows to be placed within Table.Header. */\n  headerRows: customPropTypes.every([customPropTypes.disallow(['headerRow']), customPropTypes.collectionShorthand]),\n\n  /** A table's colors can be inverted. */\n  inverted: PropTypes.bool,\n\n  /** A table may sometimes need to be more padded for legibility. */\n  padded: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /**\n   * Mapped over `tableData` and should return shorthand for each Table.Row to be placed within Table.Body.\n   *\n   * @param {*} data - An element in the `tableData` array.\n   * @param {number} index - The index of the current element in `tableData`.\n   * @returns {*} Shorthand for a Table.Row.\n   */\n  renderBodyRow: customPropTypes.every([customPropTypes.disallow(['children']), customPropTypes.demand(['tableData']), PropTypes.func]),\n\n  /** A table can have its rows appear selectable. */\n  selectable: PropTypes.bool,\n\n  /** A table can specify that its cell contents should remain on a single line and not wrap. */\n  singleLine: PropTypes.bool,\n\n  /** A table can also be small or large. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'mini', 'tiny', 'medium', 'big', 'huge', 'massive')),\n\n  /** A table may allow a user to sort contents by clicking on a table header. */\n  sortable: PropTypes.bool,\n\n  /** A table can specify how it stacks table content responsively. */\n  stackable: PropTypes.bool,\n\n  /** A table can stripe alternate rows of content with a darker color to increase contrast. */\n  striped: PropTypes.bool,\n\n  /** A table can be formatted to display complex structured data. */\n  structured: PropTypes.bool,\n\n  /** Data to be passed to the renderBodyRow function. */\n  tableData: customPropTypes.every([customPropTypes.disallow(['children']), customPropTypes.demand(['renderBodyRow']), PropTypes.array]),\n\n  /** A table can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified')),\n\n  /** A table can specify how it stacks table content responsively. */\n  unstackable: PropTypes.bool,\n\n  /** A table can adjust its text alignment. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nTable.Body = TableBody;\nTable.Cell = TableCell;\nTable.Footer = TableFooter;\nTable.Header = TableHeader;\nTable.HeaderCell = TableHeaderCell;\nTable.Row = TableRow;\nexport default Table;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\n\nfunction TableBody(props) {\n  var children = props.children,\n      className = props.className;\n  var classes = cx(className);\n  var rest = getUnhandledProps(TableBody, props);\n  var ElementType = getElementType(TableBody, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), children);\n}\n\nTableBody.handledProps = [\"as\", \"children\", \"className\"];\nTableBody.defaultProps = {\n  as: 'tbody'\n};\nTableBody.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string\n} : {};\nexport default TableBody;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useTextAlignProp, useVerticalAlignProp, useWidthProp } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A table row can have cells.\n */\n\nfunction TableCell(props) {\n  var active = props.active,\n      children = props.children,\n      className = props.className,\n      collapsing = props.collapsing,\n      content = props.content,\n      disabled = props.disabled,\n      error = props.error,\n      icon = props.icon,\n      negative = props.negative,\n      positive = props.positive,\n      selectable = props.selectable,\n      singleLine = props.singleLine,\n      textAlign = props.textAlign,\n      verticalAlign = props.verticalAlign,\n      warning = props.warning,\n      width = props.width;\n  var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(collapsing, 'collapsing'), useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(negative, 'negative'), useKeyOnly(positive, 'positive'), useKeyOnly(selectable, 'selectable'), useKeyOnly(singleLine, 'single line'), useKeyOnly(warning, 'warning'), useTextAlignProp(textAlign), useVerticalAlignProp(verticalAlign), useWidthProp(width, 'wide'), className);\n  var rest = getUnhandledProps(TableCell, props);\n  var ElementType = getElementType(TableCell, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), Icon.create(icon), content);\n}\n\nTableCell.handledProps = [\"active\", \"as\", \"children\", \"className\", \"collapsing\", \"content\", \"disabled\", \"error\", \"icon\", \"negative\", \"positive\", \"selectable\", \"singleLine\", \"textAlign\", \"verticalAlign\", \"warning\", \"width\"];\nTableCell.defaultProps = {\n  as: 'td'\n};\nTableCell.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A cell can be active or selected by a user. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A cell can be collapsing so that it only uses as much space as required. */\n  collapsing: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A cell can be disabled. */\n  disabled: PropTypes.bool,\n\n  /** A cell may call attention to an error or a negative value. */\n  error: PropTypes.bool,\n\n  /** Add an Icon by name, props object, or pass an <Icon /> */\n  icon: customPropTypes.itemShorthand,\n\n  /** A cell may let a user know whether a value is bad. */\n  negative: PropTypes.bool,\n\n  /** A cell may let a user know whether a value is good. */\n  positive: PropTypes.bool,\n\n  /** A cell can be selectable. */\n  selectable: PropTypes.bool,\n\n  /** A cell can specify that its contents should remain on a single line and not wrap. */\n  singleLine: PropTypes.bool,\n\n  /** A table cell can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified')),\n\n  /** A table cell can adjust its text alignment. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),\n\n  /** A cell may warn a user. */\n  warning: PropTypes.bool,\n\n  /** A table can specify the width of individual columns independently. */\n  width: PropTypes.oneOf(SUI.WIDTHS)\n} : {};\nTableCell.create = createShorthandFactory(TableCell, function (content) {\n  return {\n    content: content\n  };\n});\nexport default TableCell;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getUnhandledProps } from '../../lib';\nimport TableHeader from './TableHeader';\n/**\n * A table can have a footer.\n */\n\nfunction TableFooter(props) {\n  var as = props.as;\n  var rest = getUnhandledProps(TableFooter, props);\n  return /*#__PURE__*/React.createElement(TableHeader, _extends({}, rest, {\n    as: as\n  }));\n}\n\nTableFooter.handledProps = [\"as\"];\nTableFooter.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType\n} : {};\nTableFooter.defaultProps = {\n  as: 'tfoot'\n};\nexport default TableFooter;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A table can have a header.\n */\n\nfunction TableHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      fullWidth = props.fullWidth;\n  var classes = cx(useKeyOnly(fullWidth, 'full-width'), className);\n  var rest = getUnhandledProps(TableHeader, props);\n  var ElementType = getElementType(TableHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nTableHeader.handledProps = [\"as\", \"children\", \"className\", \"content\", \"fullWidth\"];\nTableHeader.defaultProps = {\n  as: 'thead'\n};\nTableHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A definition table can have a full width header or footer, filling in the gap left by the first column. */\n  fullWidth: PropTypes.bool\n} : {};\nexport default TableHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getUnhandledProps, useValueAndKey } from '../../lib';\nimport TableCell from './TableCell';\n/**\n * A table can have a header cell.\n */\n\nfunction TableHeaderCell(props) {\n  var as = props.as,\n      className = props.className,\n      sorted = props.sorted;\n  var classes = cx(useValueAndKey(sorted, 'sorted'), className);\n  var rest = getUnhandledProps(TableHeaderCell, props);\n  return /*#__PURE__*/React.createElement(TableCell, _extends({}, rest, {\n    as: as,\n    className: classes\n  }));\n}\n\nTableHeaderCell.handledProps = [\"as\", \"className\", \"sorted\"];\nTableHeaderCell.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A header cell can be sorted in ascending or descending order. */\n  sorted: PropTypes.oneOf(['ascending', 'descending'])\n} : {};\nTableHeaderCell.defaultProps = {\n  as: 'th'\n};\nexport default TableHeaderCell;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useTextAlignProp, useVerticalAlignProp } from '../../lib';\nimport TableCell from './TableCell';\n/**\n * A table can have rows.\n */\n\nfunction TableRow(props) {\n  var active = props.active,\n      cellAs = props.cellAs,\n      cells = props.cells,\n      children = props.children,\n      className = props.className,\n      disabled = props.disabled,\n      error = props.error,\n      negative = props.negative,\n      positive = props.positive,\n      textAlign = props.textAlign,\n      verticalAlign = props.verticalAlign,\n      warning = props.warning;\n  var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(negative, 'negative'), useKeyOnly(positive, 'positive'), useKeyOnly(warning, 'warning'), useTextAlignProp(textAlign), useVerticalAlignProp(verticalAlign), className);\n  var rest = getUnhandledProps(TableRow, props);\n  var ElementType = getElementType(TableRow, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), _map(cells, function (cell) {\n    return TableCell.create(cell, {\n      defaultProps: {\n        as: cellAs\n      }\n    });\n  }));\n}\n\nTableRow.handledProps = [\"active\", \"as\", \"cellAs\", \"cells\", \"children\", \"className\", \"disabled\", \"error\", \"negative\", \"positive\", \"textAlign\", \"verticalAlign\", \"warning\"];\nTableRow.defaultProps = {\n  as: 'tr',\n  cellAs: 'td'\n};\nTableRow.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A row can be active or selected by a user. */\n  active: PropTypes.bool,\n\n  /** An element type to render as (string or function). */\n  cellAs: PropTypes.elementType,\n\n  /** Shorthand array of props for TableCell. */\n  cells: customPropTypes.collectionShorthand,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A row can be disabled. */\n  disabled: PropTypes.bool,\n\n  /** A row may call attention to an error or a negative value. */\n  error: PropTypes.bool,\n\n  /** A row may let a user know whether a value is bad. */\n  negative: PropTypes.bool,\n\n  /** A row may let a user know whether a value is good. */\n  positive: PropTypes.bool,\n\n  /** A table row can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified')),\n\n  /** A table row can adjust its vertical alignment. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),\n\n  /** A row may warn a user. */\n  warning: PropTypes.bool\n} : {};\nTableRow.create = createShorthandFactory(TableRow, function (cells) {\n  return {\n    cells: cells\n  };\n});\nexport default TableRow;","import _default from './Table';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport _isNil from \"lodash/isNil\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { childrenUtils, customPropTypes, createShorthandFactory, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey } from '../../lib';\nimport Icon from '../Icon/Icon';\nimport Label from '../Label/Label';\nimport ButtonContent from './ButtonContent';\nimport ButtonGroup from './ButtonGroup';\nimport ButtonOr from './ButtonOr';\n/**\n * A Button indicates a possible user action.\n * @see Form\n * @see Icon\n * @see Label\n */\n\nvar Button = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Button, _Component);\n\n  function Button() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.ref = /*#__PURE__*/createRef();\n\n    _this.computeElementType = function () {\n      var _this$props = _this.props,\n          attached = _this$props.attached,\n          label = _this$props.label;\n      if (!_isNil(attached) || !_isNil(label)) return 'div';\n    };\n\n    _this.computeTabIndex = function (ElementType) {\n      var _this$props2 = _this.props,\n          disabled = _this$props2.disabled,\n          tabIndex = _this$props2.tabIndex;\n      if (!_isNil(tabIndex)) return tabIndex;\n      if (disabled) return -1;\n      if (ElementType === 'div') return 0;\n    };\n\n    _this.focus = function () {\n      return _invoke(_this.ref.current, 'focus');\n    };\n\n    _this.handleClick = function (e) {\n      var disabled = _this.props.disabled;\n\n      if (disabled) {\n        e.preventDefault();\n        return;\n      }\n\n      _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    _this.hasIconClass = function () {\n      var _this$props3 = _this.props,\n          labelPosition = _this$props3.labelPosition,\n          children = _this$props3.children,\n          content = _this$props3.content,\n          icon = _this$props3.icon;\n      if (icon === true) return true;\n      return icon && (labelPosition || childrenUtils.isNil(children) && _isNil(content));\n    };\n\n    return _this;\n  }\n\n  var _proto = Button.prototype;\n\n  _proto.computeButtonAriaRole = function computeButtonAriaRole(ElementType) {\n    var role = this.props.role;\n    if (!_isNil(role)) return role;\n    if (ElementType !== 'button') return 'button';\n  };\n\n  _proto.render = function render() {\n    var _this$props4 = this.props,\n        active = _this$props4.active,\n        animated = _this$props4.animated,\n        attached = _this$props4.attached,\n        basic = _this$props4.basic,\n        children = _this$props4.children,\n        circular = _this$props4.circular,\n        className = _this$props4.className,\n        color = _this$props4.color,\n        compact = _this$props4.compact,\n        content = _this$props4.content,\n        disabled = _this$props4.disabled,\n        floated = _this$props4.floated,\n        fluid = _this$props4.fluid,\n        icon = _this$props4.icon,\n        inverted = _this$props4.inverted,\n        label = _this$props4.label,\n        labelPosition = _this$props4.labelPosition,\n        loading = _this$props4.loading,\n        negative = _this$props4.negative,\n        positive = _this$props4.positive,\n        primary = _this$props4.primary,\n        secondary = _this$props4.secondary,\n        size = _this$props4.size,\n        toggle = _this$props4.toggle;\n    var baseClasses = cx(color, size, useKeyOnly(active, 'active'), useKeyOnly(basic, 'basic'), useKeyOnly(circular, 'circular'), useKeyOnly(compact, 'compact'), useKeyOnly(fluid, 'fluid'), useKeyOnly(this.hasIconClass(), 'icon'), useKeyOnly(inverted, 'inverted'), useKeyOnly(loading, 'loading'), useKeyOnly(negative, 'negative'), useKeyOnly(positive, 'positive'), useKeyOnly(primary, 'primary'), useKeyOnly(secondary, 'secondary'), useKeyOnly(toggle, 'toggle'), useKeyOrValueAndKey(animated, 'animated'), useKeyOrValueAndKey(attached, 'attached'));\n    var labeledClasses = cx(useKeyOrValueAndKey(labelPosition || !!label, 'labeled'));\n    var wrapperClasses = cx(useKeyOnly(disabled, 'disabled'), useValueAndKey(floated, 'floated'));\n    var rest = getUnhandledProps(Button, this.props);\n    var ElementType = getElementType(Button, this.props, this.computeElementType);\n    var tabIndex = this.computeTabIndex(ElementType);\n\n    if (!_isNil(label)) {\n      var buttonClasses = cx('ui', baseClasses, 'button', className);\n      var containerClasses = cx('ui', labeledClasses, 'button', className, wrapperClasses);\n      var labelElement = Label.create(label, {\n        defaultProps: {\n          basic: true,\n          pointing: labelPosition === 'left' ? 'right' : 'left'\n        },\n        autoGenerateKey: false\n      });\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: containerClasses,\n        onClick: this.handleClick\n      }), labelPosition === 'left' && labelElement, /*#__PURE__*/React.createElement(Ref, {\n        innerRef: this.ref\n      }, /*#__PURE__*/React.createElement(\"button\", {\n        className: buttonClasses,\n        \"aria-pressed\": toggle ? !!active : undefined,\n        disabled: disabled,\n        tabIndex: tabIndex\n      }, Icon.create(icon, {\n        autoGenerateKey: false\n      }), \" \", content)), (labelPosition === 'right' || !labelPosition) && labelElement);\n    }\n\n    var classes = cx('ui', baseClasses, wrapperClasses, labeledClasses, 'button', className);\n    var hasChildren = !childrenUtils.isNil(children);\n    var role = this.computeButtonAriaRole(ElementType);\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.ref\n    }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      \"aria-pressed\": toggle ? !!active : undefined,\n      disabled: disabled && ElementType === 'button' || undefined,\n      onClick: this.handleClick,\n      role: role,\n      tabIndex: tabIndex\n    }), hasChildren && children, !hasChildren && Icon.create(icon, {\n      autoGenerateKey: false\n    }), !hasChildren && content));\n  };\n\n  return Button;\n}(Component);\n\nButton.handledProps = [\"active\", \"animated\", \"as\", \"attached\", \"basic\", \"children\", \"circular\", \"className\", \"color\", \"compact\", \"content\", \"disabled\", \"floated\", \"fluid\", \"icon\", \"inverted\", \"label\", \"labelPosition\", \"loading\", \"negative\", \"onClick\", \"positive\", \"primary\", \"role\", \"secondary\", \"size\", \"tabIndex\", \"toggle\"];\nButton.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A button can show it is currently the active user selection. */\n  active: PropTypes.bool,\n\n  /** A button can animate to show hidden content. */\n  animated: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['fade', 'vertical'])]),\n\n  /** A button can be attached to other content. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right', 'top', 'bottom'])]),\n\n  /** A basic button is less pronounced. */\n  basic: PropTypes.bool,\n\n  /** Primary content. */\n  children: customPropTypes.every([PropTypes.node, customPropTypes.disallow(['label']), customPropTypes.givenProps({\n    icon: PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.object.isRequired, PropTypes.element.isRequired])\n  }, customPropTypes.disallow(['icon']))]),\n\n  /** A button can be circular. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A button can have different colors */\n  color: PropTypes.oneOf([].concat(SUI.COLORS, ['facebook', 'google plus', 'instagram', 'linkedin', 'twitter', 'vk', 'youtube'])),\n\n  /** A button can reduce its padding to fit into tighter spaces. */\n  compact: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A button can show it is currently unable to be interacted with. */\n  disabled: PropTypes.bool,\n\n  /** A button can be aligned to the left or right of its container. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** A button can take the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** Add an Icon by name, props object, or pass an <Icon />. */\n  icon: customPropTypes.some([PropTypes.bool, PropTypes.string, PropTypes.object, PropTypes.element]),\n\n  /** A button can be formatted to appear on dark backgrounds. */\n  inverted: PropTypes.bool,\n\n  /** Add a Label by text, props object, or pass a <Label />. */\n  label: customPropTypes.some([PropTypes.string, PropTypes.object, PropTypes.element]),\n\n  /** A labeled button can format a Label or Icon to appear on the left or right. */\n  labelPosition: PropTypes.oneOf(['right', 'left']),\n\n  /** A button can show a loading indicator. */\n  loading: PropTypes.bool,\n\n  /** A button can hint towards a negative consequence. */\n  negative: PropTypes.bool,\n\n  /**\n   * Called after user's click.\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /** A button can hint towards a positive consequence. */\n  positive: PropTypes.bool,\n\n  /** A button can be formatted to show different levels of emphasis. */\n  primary: PropTypes.bool,\n\n  /** The role of the HTML element. */\n  role: PropTypes.string,\n\n  /** A button can be formatted to show different levels of emphasis. */\n  secondary: PropTypes.bool,\n\n  /** A button can have different sizes. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** A button can receive focus. */\n  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** A button can be formatted to toggle on and off. */\n  toggle: PropTypes.bool\n} : {};\nButton.defaultProps = {\n  as: 'button'\n};\nButton.Content = ButtonContent;\nButton.Group = ButtonGroup;\nButton.Or = ButtonOr;\nButton.create = createShorthandFactory(Button, function (value) {\n  return {\n    content: value\n  };\n});\nexport default Button;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * Used in some Button types, such as `animated`.\n */\n\nfunction ButtonContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      hidden = props.hidden,\n      visible = props.visible;\n  var classes = cx(useKeyOnly(visible, 'visible'), useKeyOnly(hidden, 'hidden'), 'content', className);\n  var rest = getUnhandledProps(ButtonContent, props);\n  var ElementType = getElementType(ButtonContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nButtonContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"hidden\", \"visible\"];\nButtonContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Initially hidden, visible on hover. */\n  hidden: PropTypes.bool,\n\n  /** Initially visible, hidden on hover. */\n  visible: PropTypes.bool\n} : {};\nexport default ButtonContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _map from \"lodash/map\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useWidthProp } from '../../lib';\nimport Button from './Button';\n/**\n * Buttons can be grouped.\n */\n\nfunction ButtonGroup(props) {\n  var attached = props.attached,\n      basic = props.basic,\n      buttons = props.buttons,\n      children = props.children,\n      className = props.className,\n      color = props.color,\n      compact = props.compact,\n      content = props.content,\n      floated = props.floated,\n      fluid = props.fluid,\n      icon = props.icon,\n      inverted = props.inverted,\n      labeled = props.labeled,\n      negative = props.negative,\n      positive = props.positive,\n      primary = props.primary,\n      secondary = props.secondary,\n      size = props.size,\n      toggle = props.toggle,\n      vertical = props.vertical,\n      widths = props.widths;\n  var classes = cx('ui', color, size, useKeyOnly(basic, 'basic'), useKeyOnly(compact, 'compact'), useKeyOnly(fluid, 'fluid'), useKeyOnly(icon, 'icon'), useKeyOnly(inverted, 'inverted'), useKeyOnly(labeled, 'labeled'), useKeyOnly(negative, 'negative'), useKeyOnly(positive, 'positive'), useKeyOnly(primary, 'primary'), useKeyOnly(secondary, 'secondary'), useKeyOnly(toggle, 'toggle'), useKeyOnly(vertical, 'vertical'), useKeyOrValueAndKey(attached, 'attached'), useValueAndKey(floated, 'floated'), useWidthProp(widths), 'buttons', className);\n  var rest = getUnhandledProps(ButtonGroup, props);\n  var ElementType = getElementType(ButtonGroup, props);\n\n  if (_isNil(buttons)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), childrenUtils.isNil(children) ? content : children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), _map(buttons, function (button) {\n    return Button.create(button);\n  }));\n}\n\nButtonGroup.handledProps = [\"as\", \"attached\", \"basic\", \"buttons\", \"children\", \"className\", \"color\", \"compact\", \"content\", \"floated\", \"fluid\", \"icon\", \"inverted\", \"labeled\", \"negative\", \"positive\", \"primary\", \"secondary\", \"size\", \"toggle\", \"vertical\", \"widths\"];\nButtonGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Groups can be attached to other content. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right', 'top', 'bottom'])]),\n\n  /** Groups can be less pronounced. */\n  basic: PropTypes.bool,\n\n  /** Array of shorthand Button values. */\n  buttons: customPropTypes.collectionShorthand,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Groups can have a shared color. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Groups can reduce their padding to fit into tighter spaces. */\n  compact: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Groups can be aligned to the left or right of its container. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** Groups can take the width of their container. */\n  fluid: PropTypes.bool,\n\n  /** Groups can be formatted as icons. */\n  icon: PropTypes.bool,\n\n  /** Groups can be formatted to appear on dark backgrounds. */\n  inverted: PropTypes.bool,\n\n  /** Groups can be formatted as labeled icon buttons. */\n  labeled: PropTypes.bool,\n\n  /** Groups can hint towards a negative consequence. */\n  negative: PropTypes.bool,\n\n  /** Groups can hint towards a positive consequence. */\n  positive: PropTypes.bool,\n\n  /** Groups can be formatted to show different levels of emphasis. */\n  primary: PropTypes.bool,\n\n  /** Groups can be formatted to show different levels of emphasis. */\n  secondary: PropTypes.bool,\n\n  /** Groups can have different sizes. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** Groups can be formatted to toggle on and off. */\n  toggle: PropTypes.bool,\n\n  /** Groups can be formatted to appear vertically. */\n  vertical: PropTypes.bool,\n\n  /** Groups can have their widths divided evenly. */\n  widths: PropTypes.oneOf(SUI.WIDTHS)\n} : {};\nexport default ButtonGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\n/**\n * Button groups can contain conditionals.\n */\n\nfunction ButtonOr(props) {\n  var className = props.className,\n      text = props.text;\n  var classes = cx('or', className);\n  var rest = getUnhandledProps(ButtonOr, props);\n  var ElementType = getElementType(ButtonOr, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes,\n    \"data-text\": text\n  }));\n}\n\nButtonOr.handledProps = [\"as\", \"className\", \"text\"];\nButtonOr.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Or buttons can have their text localized, or adjusted by using the text prop. */\n  text: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n} : {};\nexport default ButtonOr;","import _default from './Button';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useTextAlignProp } from '../../lib';\n/**\n * A container limits content to a maximum width.\n */\n\nfunction Container(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      fluid = props.fluid,\n      text = props.text,\n      textAlign = props.textAlign;\n  var classes = cx('ui', useKeyOnly(text, 'text'), useKeyOnly(fluid, 'fluid'), useTextAlignProp(textAlign), 'container', className);\n  var rest = getUnhandledProps(Container, props);\n  var ElementType = getElementType(Container, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nContainer.handledProps = [\"as\", \"children\", \"className\", \"content\", \"fluid\", \"text\", \"textAlign\"];\nContainer.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Container has no maximum width. */\n  fluid: PropTypes.bool,\n\n  /** Reduce maximum width to more naturally accommodate text. */\n  text: PropTypes.bool,\n\n  /** Align container text. */\n  textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS)\n} : {};\nexport default Container;","import _default from './Container';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A divider visually segments content into groups.\n */\n\nfunction Divider(props) {\n  var children = props.children,\n      className = props.className,\n      clearing = props.clearing,\n      content = props.content,\n      fitted = props.fitted,\n      hidden = props.hidden,\n      horizontal = props.horizontal,\n      inverted = props.inverted,\n      section = props.section,\n      vertical = props.vertical;\n  var classes = cx('ui', useKeyOnly(clearing, 'clearing'), useKeyOnly(fitted, 'fitted'), useKeyOnly(hidden, 'hidden'), useKeyOnly(horizontal, 'horizontal'), useKeyOnly(inverted, 'inverted'), useKeyOnly(section, 'section'), useKeyOnly(vertical, 'vertical'), 'divider', className);\n  var rest = getUnhandledProps(Divider, props);\n  var ElementType = getElementType(Divider, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nDivider.handledProps = [\"as\", \"children\", \"className\", \"clearing\", \"content\", \"fitted\", \"hidden\", \"horizontal\", \"inverted\", \"section\", \"vertical\"];\nDivider.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Divider can clear the content above it. */\n  clearing: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Divider can be fitted without any space above or below it. */\n  fitted: PropTypes.bool,\n\n  /** Divider can divide content without creating a dividing line. */\n  hidden: PropTypes.bool,\n\n  /** Divider can segment content horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** Divider can have its colours inverted. */\n  inverted: PropTypes.bool,\n\n  /** Divider can provide greater margins to divide sections of content. */\n  section: PropTypes.bool,\n\n  /** Divider can segment content vertically. */\n  vertical: PropTypes.bool\n} : {};\nexport default Divider;","import _default from './Divider';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { PureComponent } from 'react';\nimport { createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nexport var names = ['ad', 'andorra', 'ae', 'united arab emirates', 'uae', 'af', 'afghanistan', 'ag', 'antigua', 'ai', 'anguilla', 'al', 'albania', 'am', 'armenia', 'an', 'netherlands antilles', 'ao', 'angola', 'ar', 'argentina', 'as', 'american samoa', 'at', 'austria', 'au', 'australia', 'aw', 'aruba', 'ax', 'aland islands', 'az', 'azerbaijan', 'ba', 'bosnia', 'bb', 'barbados', 'bd', 'bangladesh', 'be', 'belgium', 'bf', 'burkina faso', 'bg', 'bulgaria', 'bh', 'bahrain', 'bi', 'burundi', 'bj', 'benin', 'bm', 'bermuda', 'bn', 'brunei', 'bo', 'bolivia', 'br', 'brazil', 'bs', 'bahamas', 'bt', 'bhutan', 'bv', 'bouvet island', 'bw', 'botswana', 'by', 'belarus', 'bz', 'belize', 'ca', 'canada', 'cc', 'cocos islands', 'cd', 'congo', 'cf', 'central african republic', 'cg', 'congo brazzaville', 'ch', 'switzerland', 'ci', 'cote divoire', 'ck', 'cook islands', 'cl', 'chile', 'cm', 'cameroon', 'cn', 'china', 'co', 'colombia', 'cr', 'costa rica', 'cs', 'cu', 'cuba', 'cv', 'cape verde', 'cx', 'christmas island', 'cy', 'cyprus', 'cz', 'czech republic', 'de', 'germany', 'dj', 'djibouti', 'dk', 'denmark', 'dm', 'dominica', 'do', 'dominican republic', 'dz', 'algeria', 'ec', 'ecuador', 'england', 'gb eng', 'ee', 'estonia', 'eg', 'egypt', 'eh', 'western sahara', 'er', 'eritrea', 'es', 'spain', 'et', 'ethiopia', 'eu', 'european union', 'fi', 'finland', 'fj', 'fiji', 'fk', 'falkland islands', 'fm', 'micronesia', 'fo', 'faroe islands', 'fr', 'france', 'ga', 'gabon', 'gb', 'uk', 'united kingdom', 'gd', 'grenada', 'ge', 'georgia', 'gf', 'french guiana', 'gh', 'ghana', 'gi', 'gibraltar', 'gl', 'greenland', 'gm', 'gambia', 'gn', 'guinea', 'gp', 'guadeloupe', 'gq', 'equatorial guinea', 'gr', 'greece', 'gs', 'sandwich islands', 'gt', 'guatemala', 'gu', 'guam', 'gw', 'guinea-bissau', 'gy', 'guyana', 'hk', 'hong kong', 'hm', 'heard island', 'hn', 'honduras', 'hr', 'croatia', 'ht', 'haiti', 'hu', 'hungary', 'id', 'indonesia', 'ie', 'ireland', 'il', 'israel', 'in', 'india', 'io', 'indian ocean territory', 'iq', 'iraq', 'ir', 'iran', 'is', 'iceland', 'it', 'italy', 'jm', 'jamaica', 'jo', 'jordan', 'jp', 'japan', 'ke', 'kenya', 'kg', 'kyrgyzstan', 'kh', 'cambodia', 'ki', 'kiribati', 'km', 'comoros', 'kn', 'saint kitts and nevis', 'kp', 'north korea', 'kr', 'south korea', 'kw', 'kuwait', 'ky', 'cayman islands', 'kz', 'kazakhstan', 'la', 'laos', 'lb', 'lebanon', 'lc', 'saint lucia', 'li', 'liechtenstein', 'lk', 'sri lanka', 'lr', 'liberia', 'ls', 'lesotho', 'lt', 'lithuania', 'lu', 'luxembourg', 'lv', 'latvia', 'ly', 'libya', 'ma', 'morocco', 'mc', 'monaco', 'md', 'moldova', 'me', 'montenegro', 'mg', 'madagascar', 'mh', 'marshall islands', 'mk', 'macedonia', 'ml', 'mali', 'mm', 'myanmar', 'burma', 'mn', 'mongolia', 'mo', 'macau', 'mp', 'northern mariana islands', 'mq', 'martinique', 'mr', 'mauritania', 'ms', 'montserrat', 'mt', 'malta', 'mu', 'mauritius', 'mv', 'maldives', 'mw', 'malawi', 'mx', 'mexico', 'my', 'malaysia', 'mz', 'mozambique', 'na', 'namibia', 'nc', 'new caledonia', 'ne', 'niger', 'nf', 'norfolk island', 'ng', 'nigeria', 'ni', 'nicaragua', 'nl', 'netherlands', 'no', 'norway', 'np', 'nepal', 'nr', 'nauru', 'nu', 'niue', 'nz', 'new zealand', 'om', 'oman', 'pa', 'panama', 'pe', 'peru', 'pf', 'french polynesia', 'pg', 'new guinea', 'ph', 'philippines', 'pk', 'pakistan', 'pl', 'poland', 'pm', 'saint pierre', 'pn', 'pitcairn islands', 'pr', 'puerto rico', 'ps', 'palestine', 'pt', 'portugal', 'pw', 'palau', 'py', 'paraguay', 'qa', 'qatar', 're', 'reunion', 'ro', 'romania', 'rs', 'serbia', 'ru', 'russia', 'rw', 'rwanda', 'sa', 'saudi arabia', 'sb', 'solomon islands', 'sc', 'seychelles', 'gb sct', 'scotland', 'sd', 'sudan', 'se', 'sweden', 'sg', 'singapore', 'sh', 'saint helena', 'si', 'slovenia', 'sj', 'svalbard', 'jan mayen', 'sk', 'slovakia', 'sl', 'sierra leone', 'sm', 'san marino', 'sn', 'senegal', 'so', 'somalia', 'sr', 'suriname', 'st', 'sao tome', 'sv', 'el salvador', 'sy', 'syria', 'sz', 'swaziland', 'tc', 'caicos islands', 'td', 'chad', 'tf', 'french territories', 'tg', 'togo', 'th', 'thailand', 'tj', 'tajikistan', 'tk', 'tokelau', 'tl', 'timorleste', 'tm', 'turkmenistan', 'tn', 'tunisia', 'to', 'tonga', 'tr', 'turkey', 'tt', 'trinidad', 'tv', 'tuvalu', 'tw', 'taiwan', 'tz', 'tanzania', 'ua', 'ukraine', 'ug', 'uganda', 'um', 'us minor islands', 'us', 'america', 'united states', 'uy', 'uruguay', 'uz', 'uzbekistan', 'va', 'vatican city', 'vc', 'saint vincent', 've', 'venezuela', 'vg', 'british virgin islands', 'vi', 'us virgin islands', 'vn', 'vietnam', 'vu', 'vanuatu', 'gb wls', 'wales', 'wf', 'wallis and futuna', 'ws', 'samoa', 'ye', 'yemen', 'yt', 'mayotte', 'za', 'south africa', 'zm', 'zambia', 'zw', 'zimbabwe'];\n/**\n * A flag is is used to represent a political state.\n */\n\nvar Flag = /*#__PURE__*/function (_PureComponent) {\n  _inheritsLoose(Flag, _PureComponent);\n\n  function Flag() {\n    return _PureComponent.apply(this, arguments) || this;\n  }\n\n  var _proto = Flag.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        className = _this$props.className,\n        name = _this$props.name;\n    var classes = cx(name, 'flag', className);\n    var rest = getUnhandledProps(Flag, this.props);\n    var ElementType = getElementType(Flag, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }));\n  };\n\n  return Flag;\n}(PureComponent);\n\nFlag.handledProps = [\"as\", \"className\", \"name\"];\nFlag.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Flag name, can use the two digit country code, the full name, or a common alias. */\n  name: customPropTypes.suggest(names)\n} : {};\nFlag.defaultProps = {\n  as: 'i'\n};\nFlag.create = createShorthandFactory(Flag, function (value) {\n  return {\n    name: value\n  };\n});\nexport default Flag;","import _default from './Flag';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useValueAndKey, useTextAlignProp, useKeyOrValueAndKey, useKeyOnly } from '../../lib';\nimport Icon from '../Icon';\nimport Image from '../Image';\nimport HeaderSubheader from './HeaderSubheader';\nimport HeaderContent from './HeaderContent';\n/**\n * A header provides a short summary of content\n */\n\nfunction Header(props) {\n  var attached = props.attached,\n      block = props.block,\n      children = props.children,\n      className = props.className,\n      color = props.color,\n      content = props.content,\n      disabled = props.disabled,\n      dividing = props.dividing,\n      floated = props.floated,\n      icon = props.icon,\n      image = props.image,\n      inverted = props.inverted,\n      size = props.size,\n      sub = props.sub,\n      subheader = props.subheader,\n      textAlign = props.textAlign;\n  var classes = cx('ui', color, size, useKeyOnly(block, 'block'), useKeyOnly(disabled, 'disabled'), useKeyOnly(dividing, 'dividing'), useValueAndKey(floated, 'floated'), useKeyOnly(icon === true, 'icon'), useKeyOnly(image === true, 'image'), useKeyOnly(inverted, 'inverted'), useKeyOnly(sub, 'sub'), useKeyOrValueAndKey(attached, 'attached'), useTextAlignProp(textAlign), 'header', className);\n  var rest = getUnhandledProps(Header, props);\n  var ElementType = getElementType(Header, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  var iconElement = Icon.create(icon, {\n    autoGenerateKey: false\n  });\n  var imageElement = Image.create(image, {\n    autoGenerateKey: false\n  });\n  var subheaderElement = HeaderSubheader.create(subheader, {\n    autoGenerateKey: false\n  });\n\n  if (iconElement || imageElement) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), iconElement || imageElement, (content || subheaderElement) && /*#__PURE__*/React.createElement(HeaderContent, null, content, subheaderElement));\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), content, subheaderElement);\n}\n\nHeader.handledProps = [\"as\", \"attached\", \"block\", \"children\", \"className\", \"color\", \"content\", \"disabled\", \"dividing\", \"floated\", \"icon\", \"image\", \"inverted\", \"size\", \"sub\", \"subheader\", \"textAlign\"];\nHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Attach header  to other content, like a segment. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top', 'bottom'])]),\n\n  /** Format header to appear inside a content block. */\n  block: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Color of the header. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Show that the header is inactive. */\n  disabled: PropTypes.bool,\n\n  /** Divide header from the content below it. */\n  dividing: PropTypes.bool,\n\n  /** Header can sit to the left or right of other content. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** Add an icon by icon name or pass an Icon. */\n  icon: customPropTypes.every([customPropTypes.disallow(['image']), PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand])]),\n\n  /** Add an image by img src or pass an Image. */\n  image: customPropTypes.every([customPropTypes.disallow(['icon']), PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand])]),\n\n  /** Inverts the color of the header for dark backgrounds. */\n  inverted: PropTypes.bool,\n\n  /** Content headings are sized with em and are based on the font-size of their container. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'big', 'massive', 'mini')),\n\n  /** Headers may be formatted to label smaller or de-emphasized content. */\n  sub: PropTypes.bool,\n\n  /** Shorthand for Header.Subheader. */\n  subheader: customPropTypes.itemShorthand,\n\n  /** Align header content. */\n  textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS)\n} : {};\nHeader.Content = HeaderContent;\nHeader.Subheader = HeaderSubheader;\nexport default Header;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * Header content wraps the main content when there is an adjacent Icon or Image.\n */\n\nfunction HeaderContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(HeaderContent, props);\n  var ElementType = getElementType(HeaderContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nHeaderContent.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nHeaderContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default HeaderContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * Headers may contain subheaders.\n */\n\nfunction HeaderSubheader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('sub header', className);\n  var rest = getUnhandledProps(HeaderSubheader, props);\n  var ElementType = getElementType(HeaderSubheader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nHeaderSubheader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nHeaderSubheader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nHeaderSubheader.create = createShorthandFactory(HeaderSubheader, function (content) {\n  return {\n    content: content\n  };\n});\nexport default HeaderSubheader;","import _default from './Header';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _invoke from \"lodash/invoke\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { PureComponent } from 'react';\nimport { createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey } from '../../lib';\nimport IconGroup from './IconGroup';\n/**\n * An icon is a glyph used to represent something else.\n * @see Image\n */\n\nvar Icon = /*#__PURE__*/function (_PureComponent) {\n  _inheritsLoose(Icon, _PureComponent);\n\n  function Icon() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _PureComponent.call.apply(_PureComponent, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var disabled = _this.props.disabled;\n\n      if (disabled) {\n        e.preventDefault();\n        return;\n      }\n\n      _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = Icon.prototype;\n\n  _proto.getIconAriaOptions = function getIconAriaOptions() {\n    var ariaOptions = {};\n    var _this$props = this.props,\n        ariaLabel = _this$props['aria-label'],\n        ariaHidden = _this$props['aria-hidden'];\n\n    if (_isNil(ariaLabel)) {\n      ariaOptions['aria-hidden'] = 'true';\n    } else {\n      ariaOptions['aria-label'] = ariaLabel;\n    }\n\n    if (!_isNil(ariaHidden)) {\n      ariaOptions['aria-hidden'] = ariaHidden;\n    }\n\n    return ariaOptions;\n  };\n\n  _proto.render = function render() {\n    var _this$props2 = this.props,\n        bordered = _this$props2.bordered,\n        circular = _this$props2.circular,\n        className = _this$props2.className,\n        color = _this$props2.color,\n        corner = _this$props2.corner,\n        disabled = _this$props2.disabled,\n        fitted = _this$props2.fitted,\n        flipped = _this$props2.flipped,\n        inverted = _this$props2.inverted,\n        link = _this$props2.link,\n        loading = _this$props2.loading,\n        name = _this$props2.name,\n        rotated = _this$props2.rotated,\n        size = _this$props2.size;\n    var classes = cx(color, name, size, useKeyOnly(bordered, 'bordered'), useKeyOnly(circular, 'circular'), useKeyOnly(disabled, 'disabled'), useKeyOnly(fitted, 'fitted'), useKeyOnly(inverted, 'inverted'), useKeyOnly(link, 'link'), useKeyOnly(loading, 'loading'), useKeyOrValueAndKey(corner, 'corner'), useValueAndKey(flipped, 'flipped'), useValueAndKey(rotated, 'rotated'), 'icon', className);\n    var rest = getUnhandledProps(Icon, this.props);\n    var ElementType = getElementType(Icon, this.props);\n    var ariaOptions = this.getIconAriaOptions();\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, ariaOptions, {\n      className: classes,\n      onClick: this.handleClick\n    }));\n  };\n\n  return Icon;\n}(PureComponent);\n\nIcon.handledProps = [\"aria-hidden\", \"aria-label\", \"as\", \"bordered\", \"circular\", \"className\", \"color\", \"corner\", \"disabled\", \"fitted\", \"flipped\", \"inverted\", \"link\", \"loading\", \"name\", \"rotated\", \"size\"];\nIcon.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Formatted to appear bordered. */\n  bordered: PropTypes.bool,\n\n  /** Icon can formatted to appear circular. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Color of the icon. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Icons can display a smaller corner icon. */\n  corner: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top left', 'top right', 'bottom left', 'bottom right'])]),\n\n  /** Show that the icon is inactive. */\n  disabled: PropTypes.bool,\n\n  /** Fitted, without space to left or right of Icon. */\n  fitted: PropTypes.bool,\n\n  /** Icon can be flipped. */\n  flipped: PropTypes.oneOf(['horizontally', 'vertically']),\n\n  /** Formatted to have its colors inverted for contrast. */\n  inverted: PropTypes.bool,\n\n  /** Icon can be formatted as a link. */\n  link: PropTypes.bool,\n\n  /** Icon can be used as a simple loader. */\n  loading: PropTypes.bool,\n\n  /** Name of the icon. */\n  name: customPropTypes.suggest(SUI.ALL_ICONS_IN_ALL_CONTEXTS),\n\n  /** Icon can rotated. */\n  rotated: PropTypes.oneOf(['clockwise', 'counterclockwise']),\n\n  /** Size of the icon. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** Icon can have an aria label. */\n  'aria-hidden': PropTypes.string,\n\n  /** Icon can have an aria label. */\n  'aria-label': PropTypes.string\n} : {};\nIcon.defaultProps = {\n  as: 'i'\n};\nIcon.Group = IconGroup;\nIcon.create = createShorthandFactory(Icon, function (value) {\n  return {\n    name: value\n  };\n});\nexport default Icon;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI } from '../../lib';\n/**\n * Several icons can be used together as a group.\n */\n\nfunction IconGroup(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      size = props.size;\n  var classes = cx(size, 'icons', className);\n  var rest = getUnhandledProps(IconGroup, props);\n  var ElementType = getElementType(IconGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nIconGroup.handledProps = [\"as\", \"children\", \"className\", \"content\", \"size\"];\nIconGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Size of the icon group. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium'))\n} : {};\nIconGroup.defaultProps = {\n  as: 'i'\n};\nexport default IconGroup;","import _default from './Icon';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, htmlImageProps, partitionHTMLProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useVerticalAlignProp } from '../../lib';\nimport Dimmer from '../../modules/Dimmer';\nimport Label from '../Label/Label';\nimport ImageGroup from './ImageGroup';\n/**\n * An image is a graphic representation of something.\n * @see Icon\n */\n\nfunction Image(props) {\n  var avatar = props.avatar,\n      bordered = props.bordered,\n      centered = props.centered,\n      children = props.children,\n      circular = props.circular,\n      className = props.className,\n      content = props.content,\n      dimmer = props.dimmer,\n      disabled = props.disabled,\n      floated = props.floated,\n      fluid = props.fluid,\n      hidden = props.hidden,\n      href = props.href,\n      inline = props.inline,\n      label = props.label,\n      rounded = props.rounded,\n      size = props.size,\n      spaced = props.spaced,\n      verticalAlign = props.verticalAlign,\n      wrapped = props.wrapped,\n      ui = props.ui;\n  var classes = cx(useKeyOnly(ui, 'ui'), size, useKeyOnly(avatar, 'avatar'), useKeyOnly(bordered, 'bordered'), useKeyOnly(circular, 'circular'), useKeyOnly(centered, 'centered'), useKeyOnly(disabled, 'disabled'), useKeyOnly(fluid, 'fluid'), useKeyOnly(hidden, 'hidden'), useKeyOnly(inline, 'inline'), useKeyOnly(rounded, 'rounded'), useKeyOrValueAndKey(spaced, 'spaced'), useValueAndKey(floated, 'floated'), useVerticalAlignProp(verticalAlign, 'aligned'), 'image', className);\n  var rest = getUnhandledProps(Image, props);\n\n  var _partitionHTMLProps = partitionHTMLProps(rest, {\n    htmlProps: htmlImageProps\n  }),\n      imgTagProps = _partitionHTMLProps[0],\n      rootProps = _partitionHTMLProps[1];\n\n  var ElementType = getElementType(Image, props, function () {\n    if (!_isNil(dimmer) || !_isNil(label) || !_isNil(wrapped) || !childrenUtils.isNil(children)) {\n      return 'div';\n    }\n  });\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  if (ElementType === 'img') {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rootProps, imgTagProps, {\n      className: classes\n    }));\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rootProps, {\n    className: classes,\n    href: href\n  }), Dimmer.create(dimmer, {\n    autoGenerateKey: false\n  }), Label.create(label, {\n    autoGenerateKey: false\n  }), /*#__PURE__*/React.createElement(\"img\", imgTagProps));\n}\n\nImage.handledProps = [\"as\", \"avatar\", \"bordered\", \"centered\", \"children\", \"circular\", \"className\", \"content\", \"dimmer\", \"disabled\", \"floated\", \"fluid\", \"hidden\", \"href\", \"inline\", \"label\", \"rounded\", \"size\", \"spaced\", \"ui\", \"verticalAlign\", \"wrapped\"];\nImage.Group = ImageGroup;\nImage.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An image may be formatted to appear inline with text as an avatar. */\n  avatar: PropTypes.bool,\n\n  /** An image may include a border to emphasize the edges of white or transparent content. */\n  bordered: PropTypes.bool,\n\n  /** An image can appear centered in a content block. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** An image may appear circular. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** An image can show that it is disabled and cannot be selected. */\n  disabled: PropTypes.bool,\n\n  /** Shorthand for Dimmer. */\n  dimmer: customPropTypes.itemShorthand,\n\n  /** An image can sit to the left or right of other content. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** An image can take up the width of its container. */\n  fluid: customPropTypes.every([PropTypes.bool, customPropTypes.disallow(['size'])]),\n\n  /** An image can be hidden. */\n  hidden: PropTypes.bool,\n\n  /** Renders the Image as an <a> tag with this href. */\n  href: PropTypes.string,\n\n  /** An image may appear inline. */\n  inline: PropTypes.bool,\n\n  /** Shorthand for Label. */\n  label: customPropTypes.itemShorthand,\n\n  /** An image may appear rounded. */\n  rounded: PropTypes.bool,\n\n  /** An image may appear at different sizes. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** An image can specify that it needs an additional spacing to separate it from nearby content. */\n  spaced: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right'])]),\n\n  /** Whether or not to add the ui className. */\n  ui: PropTypes.bool,\n\n  /** An image can specify its vertical alignment. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),\n\n  /** An image can render wrapped in a `div.ui.image` as alternative HTML markup. */\n  wrapped: PropTypes.bool\n} : {};\nImage.defaultProps = {\n  as: 'img',\n  ui: true\n};\nImage.create = createShorthandFactory(Image, function (value) {\n  return {\n    src: value\n  };\n});\nexport default Image;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI } from '../../lib';\n/**\n * A group of images.\n */\n\nfunction ImageGroup(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      size = props.size;\n  var classes = cx('ui', size, className, 'images');\n  var rest = getUnhandledProps(ImageGroup, props);\n  var ElementType = getElementType(ImageGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nImageGroup.handledProps = [\"as\", \"children\", \"className\", \"content\", \"size\"];\nImageGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A group of images can be formatted to have the same size. */\n  size: PropTypes.oneOf(SUI.SIZES)\n} : {};\nexport default ImageGroup;","import _default from './Image';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _includes from \"lodash/includes\";\nimport _map from \"lodash/map\";\nimport _invoke from \"lodash/invoke\";\nimport _get from \"lodash/get\";\nimport _isNil from \"lodash/isNil\";\nimport { handleRef } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Children, cloneElement, Component, createRef } from 'react';\nimport { childrenUtils, createHTMLInput, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, partitionHTMLProps, useKeyOnly, useValueAndKey } from '../../lib';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport Label from '../Label';\n/**\n * An Input is a field used to elicit a response from a user.\n * @see Button\n * @see Form\n * @see Icon\n * @see Label\n */\n\nvar Input = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Input, _Component);\n\n  function Input() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.inputRef = /*#__PURE__*/createRef();\n\n    _this.computeIcon = function () {\n      var _this$props = _this.props,\n          loading = _this$props.loading,\n          icon = _this$props.icon;\n      if (!_isNil(icon)) return icon;\n      if (loading) return 'spinner';\n    };\n\n    _this.computeTabIndex = function () {\n      var _this$props2 = _this.props,\n          disabled = _this$props2.disabled,\n          tabIndex = _this$props2.tabIndex;\n      if (!_isNil(tabIndex)) return tabIndex;\n      if (disabled) return -1;\n    };\n\n    _this.focus = function () {\n      return _this.inputRef.current.focus();\n    };\n\n    _this.select = function () {\n      return _this.inputRef.current.select();\n    };\n\n    _this.handleChange = function (e) {\n      var value = _get(e, 'target.value');\n\n      _invoke(_this.props, 'onChange', e, _extends({}, _this.props, {\n        value: value\n      }));\n    };\n\n    _this.handleChildOverrides = function (child, defaultProps) {\n      return _extends({}, defaultProps, child.props, {\n        ref: function ref(c) {\n          handleRef(child.ref, c);\n          _this.inputRef.current = c;\n        }\n      });\n    };\n\n    _this.partitionProps = function () {\n      var _this$props3 = _this.props,\n          disabled = _this$props3.disabled,\n          type = _this$props3.type;\n\n      var tabIndex = _this.computeTabIndex();\n\n      var unhandled = getUnhandledProps(Input, _this.props);\n\n      var _partitionHTMLProps = partitionHTMLProps(unhandled),\n          htmlInputProps = _partitionHTMLProps[0],\n          rest = _partitionHTMLProps[1];\n\n      return [_extends({}, htmlInputProps, {\n        disabled: disabled,\n        type: type,\n        tabIndex: tabIndex,\n        onChange: _this.handleChange,\n        ref: _this.inputRef\n      }), rest];\n    };\n\n    return _this;\n  }\n\n  var _proto = Input.prototype;\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props4 = this.props,\n        action = _this$props4.action,\n        actionPosition = _this$props4.actionPosition,\n        children = _this$props4.children,\n        className = _this$props4.className,\n        disabled = _this$props4.disabled,\n        error = _this$props4.error,\n        fluid = _this$props4.fluid,\n        focus = _this$props4.focus,\n        icon = _this$props4.icon,\n        iconPosition = _this$props4.iconPosition,\n        input = _this$props4.input,\n        inverted = _this$props4.inverted,\n        label = _this$props4.label,\n        labelPosition = _this$props4.labelPosition,\n        loading = _this$props4.loading,\n        size = _this$props4.size,\n        transparent = _this$props4.transparent,\n        type = _this$props4.type;\n    var classes = cx('ui', size, useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(fluid, 'fluid'), useKeyOnly(focus, 'focus'), useKeyOnly(inverted, 'inverted'), useKeyOnly(loading, 'loading'), useKeyOnly(transparent, 'transparent'), useValueAndKey(actionPosition, 'action') || useKeyOnly(action, 'action'), useValueAndKey(iconPosition, 'icon') || useKeyOnly(icon || loading, 'icon'), useValueAndKey(labelPosition, 'labeled') || useKeyOnly(label, 'labeled'), 'input', className);\n    var ElementType = getElementType(Input, this.props);\n\n    var _this$partitionProps = this.partitionProps(),\n        htmlInputProps = _this$partitionProps[0],\n        rest = _this$partitionProps[1]; // Render with children\n    // ----------------------------------------\n\n\n    if (!childrenUtils.isNil(children)) {\n      // add htmlInputProps to the `<input />` child\n      var childElements = _map(Children.toArray(children), function (child) {\n        if (child.type !== 'input') return child;\n        return /*#__PURE__*/cloneElement(child, _this2.handleChildOverrides(child, htmlInputProps));\n      });\n\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes\n      }), childElements);\n    } // Render Shorthand\n    // ----------------------------------------\n\n\n    var actionElement = Button.create(action, {\n      autoGenerateKey: false\n    });\n    var labelElement = Label.create(label, {\n      defaultProps: {\n        className: cx('label', // add 'left|right corner'\n        _includes(labelPosition, 'corner') && labelPosition)\n      },\n      autoGenerateKey: false\n    });\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), actionPosition === 'left' && actionElement, labelPosition !== 'right' && labelElement, createHTMLInput(input || type, {\n      defaultProps: htmlInputProps,\n      autoGenerateKey: false\n    }), Icon.create(this.computeIcon(), {\n      autoGenerateKey: false\n    }), actionPosition !== 'left' && actionElement, labelPosition === 'right' && labelElement);\n  };\n\n  return Input;\n}(Component);\n\nInput.handledProps = [\"action\", \"actionPosition\", \"as\", \"children\", \"className\", \"disabled\", \"error\", \"fluid\", \"focus\", \"icon\", \"iconPosition\", \"input\", \"inverted\", \"label\", \"labelPosition\", \"loading\", \"onChange\", \"size\", \"tabIndex\", \"transparent\", \"type\"];\nInput.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An Input can be formatted to alert the user to an action they may perform. */\n  action: PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand]),\n\n  /** An action can appear along side an Input on the left or right. */\n  actionPosition: PropTypes.oneOf(['left']),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** An Input field can show that it is disabled. */\n  disabled: PropTypes.bool,\n\n  /** An Input field can show the data contains errors. */\n  error: PropTypes.bool,\n\n  /** Take on the size of its container. */\n  fluid: PropTypes.bool,\n\n  /** An Input field can show a user is currently interacting with it. */\n  focus: PropTypes.bool,\n\n  /** Optional Icon to display inside the Input. */\n  icon: PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand]),\n\n  /** An Icon can appear inside an Input on the left or right. */\n  iconPosition: PropTypes.oneOf(['left']),\n\n  /** Shorthand for creating the HTML Input. */\n  input: customPropTypes.itemShorthand,\n\n  /** Format to appear on dark backgrounds. */\n  inverted: PropTypes.bool,\n\n  /** Optional Label to display along side the Input. */\n  label: customPropTypes.itemShorthand,\n\n  /** A Label can appear outside an Input on the left or right. */\n  labelPosition: PropTypes.oneOf(['left', 'right', 'left corner', 'right corner']),\n\n  /** An Icon Input field can show that it is currently loading data. */\n  loading: PropTypes.bool,\n\n  /**\n   * Called on change.\n   *\n   * @param {ChangeEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and a proposed value.\n   */\n  onChange: PropTypes.func,\n\n  /** An Input can vary in size. */\n  size: PropTypes.oneOf(['mini', 'small', 'large', 'big', 'huge', 'massive']),\n\n  /** An Input can receive focus. */\n  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Transparent Input has no background. */\n  transparent: PropTypes.bool,\n\n  /** The HTML input type. */\n  type: PropTypes.string\n} : {};\nInput.defaultProps = {\n  type: 'text'\n};\nInput.create = createShorthandFactory(Input, function (type) {\n  return {\n    type: type\n  };\n});\nexport default Input;","import _default from './Input';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey } from '../../lib';\nimport Icon from '../Icon/Icon';\nimport Image from '../Image/Image';\nimport LabelDetail from './LabelDetail';\nimport LabelGroup from './LabelGroup';\n/**\n * A label displays content classification.\n */\n\nvar Label = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Label, _Component);\n\n  function Label() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var onClick = _this.props.onClick;\n      if (onClick) onClick(e, _this.props);\n    };\n\n    _this.handleIconOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e) {\n          _invoke(predefinedProps, 'onClick', e);\n\n          _invoke(_this.props, 'onRemove', e, _this.props);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = Label.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        attached = _this$props.attached,\n        basic = _this$props.basic,\n        children = _this$props.children,\n        circular = _this$props.circular,\n        className = _this$props.className,\n        color = _this$props.color,\n        content = _this$props.content,\n        corner = _this$props.corner,\n        detail = _this$props.detail,\n        empty = _this$props.empty,\n        floating = _this$props.floating,\n        horizontal = _this$props.horizontal,\n        icon = _this$props.icon,\n        image = _this$props.image,\n        onRemove = _this$props.onRemove,\n        pointing = _this$props.pointing,\n        prompt = _this$props.prompt,\n        removeIcon = _this$props.removeIcon,\n        ribbon = _this$props.ribbon,\n        size = _this$props.size,\n        tag = _this$props.tag;\n    var pointingClass = pointing === true && 'pointing' || (pointing === 'left' || pointing === 'right') && pointing + \" pointing\" || (pointing === 'above' || pointing === 'below') && \"pointing \" + pointing;\n    var classes = cx('ui', color, pointingClass, size, useKeyOnly(active, 'active'), useKeyOnly(basic, 'basic'), useKeyOnly(circular, 'circular'), useKeyOnly(empty, 'empty'), useKeyOnly(floating, 'floating'), useKeyOnly(horizontal, 'horizontal'), useKeyOnly(image === true, 'image'), useKeyOnly(prompt, 'prompt'), useKeyOnly(tag, 'tag'), useKeyOrValueAndKey(corner, 'corner'), useKeyOrValueAndKey(ribbon, 'ribbon'), useValueAndKey(attached, 'attached'), 'label', className);\n    var rest = getUnhandledProps(Label, this.props);\n    var ElementType = getElementType(Label, this.props);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    var removeIconShorthand = _isUndefined(removeIcon) ? 'delete' : removeIcon;\n    return /*#__PURE__*/React.createElement(ElementType, _extends({\n      className: classes,\n      onClick: this.handleClick\n    }, rest), Icon.create(icon, {\n      autoGenerateKey: false\n    }), typeof image !== 'boolean' && Image.create(image, {\n      autoGenerateKey: false\n    }), content, LabelDetail.create(detail, {\n      autoGenerateKey: false\n    }), onRemove && Icon.create(removeIconShorthand, {\n      autoGenerateKey: false,\n      overrideProps: this.handleIconOverrides\n    }));\n  };\n\n  return Label;\n}(Component);\n\nLabel.handledProps = [\"active\", \"as\", \"attached\", \"basic\", \"children\", \"circular\", \"className\", \"color\", \"content\", \"corner\", \"detail\", \"empty\", \"floating\", \"horizontal\", \"icon\", \"image\", \"onClick\", \"onRemove\", \"pointing\", \"prompt\", \"removeIcon\", \"ribbon\", \"size\", \"tag\"];\nexport { Label as default };\nLabel.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A label can be active. */\n  active: PropTypes.bool,\n\n  /** A label can attach to a content segment. */\n  attached: PropTypes.oneOf(['top', 'bottom', 'top right', 'top left', 'bottom left', 'bottom right']),\n\n  /** A label can reduce its complexity. */\n  basic: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** A label can be circular. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Color of the label. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A label can position itself in the corner of an element. */\n  corner: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right'])]),\n\n  /** Shorthand for LabelDetail. */\n  detail: customPropTypes.itemShorthand,\n\n  /** Formats the label as a dot. */\n  empty: customPropTypes.every([PropTypes.bool, customPropTypes.demand(['circular'])]),\n\n  /** Float above another element in the upper right corner. */\n  floating: PropTypes.bool,\n\n  /** A horizontal label is formatted to label content along-side it horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** Shorthand for Icon. */\n  icon: customPropTypes.itemShorthand,\n\n  /** A label can be formatted to emphasize an image or prop can be used as shorthand for Image. */\n  image: PropTypes.oneOfType([PropTypes.bool, customPropTypes.itemShorthand]),\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Adds an \"x\" icon, called when \"x\" is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onRemove: PropTypes.func,\n\n  /** A label can point to content next to it. */\n  pointing: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['above', 'below', 'left', 'right'])]),\n\n  /** A label can prompt for an error in your forms. */\n  prompt: PropTypes.bool,\n\n  /** Shorthand for Icon to appear as the last child and trigger onRemove. */\n  removeIcon: customPropTypes.itemShorthand,\n\n  /** A label can appear as a ribbon attaching itself to an element. */\n  ribbon: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['right'])]),\n\n  /** A label can have different sizes. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** A label can appear as a tag. */\n  tag: PropTypes.bool\n} : {};\nLabel.Detail = LabelDetail;\nLabel.Group = LabelGroup;\nLabel.create = createShorthandFactory(Label, function (value) {\n  return {\n    content: value\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n\nfunction LabelDetail(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('detail', className);\n  var rest = getUnhandledProps(LabelDetail, props);\n  var ElementType = getElementType(LabelDetail, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nLabelDetail.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nLabelDetail.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nLabelDetail.create = createShorthandFactory(LabelDetail, function (val) {\n  return {\n    content: val\n  };\n});\nexport default LabelDetail;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly } from '../../lib';\n/**\n * A label can be grouped.\n */\n\nfunction LabelGroup(props) {\n  var children = props.children,\n      circular = props.circular,\n      className = props.className,\n      color = props.color,\n      content = props.content,\n      size = props.size,\n      tag = props.tag;\n  var classes = cx('ui', color, size, useKeyOnly(circular, 'circular'), useKeyOnly(tag, 'tag'), 'labels', className);\n  var rest = getUnhandledProps(LabelGroup, props);\n  var ElementType = getElementType(LabelGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nLabelGroup.handledProps = [\"as\", \"children\", \"circular\", \"className\", \"color\", \"content\", \"size\", \"tag\"];\nLabelGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Labels can share shapes. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Label group can share colors together. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Label group can share sizes together. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** Label group can share tag formatting. */\n  tag: PropTypes.bool\n} : {};\nexport default LabelGroup;","import _default from './Label';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _map from \"lodash/map\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useVerticalAlignProp } from '../../lib';\nimport ListContent from './ListContent';\nimport ListDescription from './ListDescription';\nimport ListHeader from './ListHeader';\nimport ListIcon from './ListIcon';\nimport ListItem from './ListItem';\nimport ListList from './ListList';\n/**\n * A list groups related content.\n */\n\nvar List = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(List, _Component);\n\n  function List() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleItemOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, itemProps) {\n          _invoke(predefinedProps, 'onClick', e, itemProps);\n\n          _invoke(_this.props, 'onItemClick', e, itemProps);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = List.prototype;\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props = this.props,\n        animated = _this$props.animated,\n        bulleted = _this$props.bulleted,\n        celled = _this$props.celled,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content,\n        divided = _this$props.divided,\n        floated = _this$props.floated,\n        horizontal = _this$props.horizontal,\n        inverted = _this$props.inverted,\n        items = _this$props.items,\n        link = _this$props.link,\n        ordered = _this$props.ordered,\n        relaxed = _this$props.relaxed,\n        selection = _this$props.selection,\n        size = _this$props.size,\n        verticalAlign = _this$props.verticalAlign;\n    var classes = cx('ui', size, useKeyOnly(animated, 'animated'), useKeyOnly(bulleted, 'bulleted'), useKeyOnly(celled, 'celled'), useKeyOnly(divided, 'divided'), useKeyOnly(horizontal, 'horizontal'), useKeyOnly(inverted, 'inverted'), useKeyOnly(link, 'link'), useKeyOnly(ordered, 'ordered'), useKeyOnly(selection, 'selection'), useKeyOrValueAndKey(relaxed, 'relaxed'), useValueAndKey(floated, 'floated'), useVerticalAlignProp(verticalAlign), 'list', className);\n    var rest = getUnhandledProps(List, this.props);\n    var ElementType = getElementType(List, this.props);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({\n        role: \"list\",\n        className: classes\n      }, rest), children);\n    }\n\n    if (!childrenUtils.isNil(content)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({\n        role: \"list\",\n        className: classes\n      }, rest), content);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({\n      role: \"list\",\n      className: classes\n    }, rest), _map(items, function (item) {\n      return ListItem.create(item, {\n        overrideProps: _this2.handleItemOverrides\n      });\n    }));\n  };\n\n  return List;\n}(Component);\n\nList.handledProps = [\"animated\", \"as\", \"bulleted\", \"celled\", \"children\", \"className\", \"content\", \"divided\", \"floated\", \"horizontal\", \"inverted\", \"items\", \"link\", \"onItemClick\", \"ordered\", \"relaxed\", \"selection\", \"size\", \"verticalAlign\"];\nList.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A list can animate to set the current item apart from the list. */\n  animated: PropTypes.bool,\n\n  /** A list can mark items with a bullet. */\n  bulleted: PropTypes.bool,\n\n  /** A list can divide its items into cells. */\n  celled: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A list can show divisions between content. */\n  divided: PropTypes.bool,\n\n  /** An list can be floated left or right. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** A list can be formatted to have items appear horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** A list can be inverted to appear on a dark background. */\n  inverted: PropTypes.bool,\n\n  /** Shorthand array of props for ListItem. */\n  items: customPropTypes.collectionShorthand,\n\n  /** A list can be specially formatted for navigation links. */\n  link: PropTypes.bool,\n\n  /**\n   * onClick handler for ListItem. Mutually exclusive with children.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All item props.\n   */\n  onItemClick: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.func]),\n\n  /** A list can be ordered numerically. */\n  ordered: PropTypes.bool,\n\n  /** A list can relax its padding to provide more negative space. */\n  relaxed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** A selection list formats list items as possible choices. */\n  selection: PropTypes.bool,\n\n  /** A list can vary in size. */\n  size: PropTypes.oneOf(SUI.SIZES),\n\n  /** An element inside a list can be vertically aligned. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nList.Content = ListContent;\nList.Description = ListDescription;\nList.Header = ListHeader;\nList.Icon = ListIcon;\nList.Item = ListItem;\nList.List = ListList;\nexport default List;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useValueAndKey, useVerticalAlignProp } from '../../lib';\nimport ListDescription from './ListDescription';\nimport ListHeader from './ListHeader';\n/**\n * A list item can contain a content.\n */\n\nfunction ListContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      description = props.description,\n      floated = props.floated,\n      header = props.header,\n      verticalAlign = props.verticalAlign;\n  var classes = cx(useValueAndKey(floated, 'floated'), useVerticalAlignProp(verticalAlign), 'content', className);\n  var rest = getUnhandledProps(ListContent, props);\n  var ElementType = getElementType(ListContent, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), ListHeader.create(header), ListDescription.create(description), content);\n}\n\nListContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"description\", \"floated\", \"header\", \"verticalAlign\"];\nListContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for ListDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** An list content can be floated left or right. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** Shorthand for ListHeader. */\n  header: customPropTypes.itemShorthand,\n\n  /** An element inside a list can be vertically aligned. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nListContent.create = createShorthandFactory(ListContent, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ListContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A list item can contain a description.\n */\n\nfunction ListDescription(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx(className, 'description');\n  var rest = getUnhandledProps(ListDescription, props);\n  var ElementType = getElementType(ListDescription, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nListDescription.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nListDescription.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nListDescription.create = createShorthandFactory(ListDescription, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ListDescription;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A list item can contain a header.\n */\n\nfunction ListHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(ListHeader, props);\n  var ElementType = getElementType(ListHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nListHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nListHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nListHeader.create = createShorthandFactory(ListHeader, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ListHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { createShorthandFactory, getUnhandledProps, SUI, useVerticalAlignProp } from '../../lib';\nimport Icon from '../Icon/Icon';\n/**\n * A list item can contain an icon.\n */\n\nfunction ListIcon(props) {\n  var className = props.className,\n      verticalAlign = props.verticalAlign;\n  var classes = cx(useVerticalAlignProp(verticalAlign), className);\n  var rest = getUnhandledProps(ListIcon, props);\n  return /*#__PURE__*/React.createElement(Icon, _extends({}, rest, {\n    className: classes\n  }));\n}\n\nListIcon.handledProps = [\"className\", \"verticalAlign\"];\nListIcon.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** An element inside a list can be vertically aligned. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nListIcon.create = createShorthandFactory(ListIcon, function (name) {\n  return {\n    name: name\n  };\n});\nexport default ListIcon;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isPlainObject from \"lodash/isPlainObject\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, isValidElement } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Image from '../Image';\nimport ListContent from './ListContent';\nimport ListDescription from './ListDescription';\nimport ListHeader from './ListHeader';\nimport ListIcon from './ListIcon';\n/**\n * A list item can contain a set of items.\n */\n\nvar ListItem = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(ListItem, _Component);\n\n  function ListItem() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var disabled = _this.props.disabled;\n      if (!disabled) _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = ListItem.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content,\n        description = _this$props.description,\n        disabled = _this$props.disabled,\n        header = _this$props.header,\n        icon = _this$props.icon,\n        image = _this$props.image,\n        value = _this$props.value;\n    var ElementType = getElementType(ListItem, this.props);\n    var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(ElementType !== 'li', 'item'), className);\n    var rest = getUnhandledProps(ListItem, this.props);\n    var valueProp = ElementType === 'li' ? {\n      value: value\n    } : {\n      'data-value': value\n    };\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, valueProp, {\n        role: \"listitem\",\n        className: classes,\n        onClick: this.handleClick\n      }, rest), children);\n    }\n\n    var iconElement = ListIcon.create(icon, {\n      autoGenerateKey: false\n    });\n    var imageElement = Image.create(image, {\n      autoGenerateKey: false\n    }); // See description of `content` prop for explanation about why this is necessary.\n\n    if (! /*#__PURE__*/isValidElement(content) && _isPlainObject(content)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, valueProp, {\n        role: \"listitem\",\n        className: classes,\n        onClick: this.handleClick\n      }, rest), iconElement || imageElement, ListContent.create(content, {\n        autoGenerateKey: false,\n        defaultProps: {\n          header: header,\n          description: description\n        }\n      }));\n    }\n\n    var headerElement = ListHeader.create(header, {\n      autoGenerateKey: false\n    });\n    var descriptionElement = ListDescription.create(description, {\n      autoGenerateKey: false\n    });\n\n    if (iconElement || imageElement) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, valueProp, {\n        role: \"listitem\",\n        className: classes,\n        onClick: this.handleClick\n      }, rest), iconElement || imageElement, (content || headerElement || descriptionElement) && /*#__PURE__*/React.createElement(ListContent, null, headerElement, descriptionElement, content));\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, valueProp, {\n      role: \"listitem\",\n      className: classes,\n      onClick: this.handleClick\n    }, rest), headerElement, descriptionElement, content);\n  };\n\n  return ListItem;\n}(Component);\n\nListItem.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"description\", \"disabled\", \"header\", \"icon\", \"image\", \"onClick\", \"value\"];\nListItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A list item can active. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /**\n   * Shorthand for primary content.\n   *\n   * Heads up!\n   *\n   * This is handled slightly differently than the typical `content` prop since\n   * the wrapping ListContent is not used when there's no icon or image.\n   *\n   * If you pass content as:\n   * - an element/literal, it's treated as the sibling node to\n   * header/description (whether wrapped in Item.Content or not).\n   * - a props object, it forces the presence of Item.Content and passes those\n   * props to it. If you pass a content prop within that props object, it\n   * will be treated as the sibling node to header/description.\n   */\n  content: customPropTypes.itemShorthand,\n\n  /** Shorthand for ListDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** A list item can disabled. */\n  disabled: PropTypes.bool,\n\n  /** Shorthand for ListHeader. */\n  header: customPropTypes.itemShorthand,\n\n  /** Shorthand for ListIcon. */\n  icon: customPropTypes.every([customPropTypes.disallow(['image']), customPropTypes.itemShorthand]),\n\n  /** Shorthand for Image. */\n  image: customPropTypes.every([customPropTypes.disallow(['icon']), customPropTypes.itemShorthand]),\n\n  /** A ListItem can be clicked */\n  onClick: PropTypes.func,\n\n  /** A value for an ordered list. */\n  value: PropTypes.string\n} : {};\nListItem.create = createShorthandFactory(ListItem, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ListItem;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A list can contain a sub list.\n */\n\nfunction ListList(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var rest = getUnhandledProps(ListList, props);\n  var ElementType = getElementType(ListList, props);\n  var classes = cx(useKeyOnly(ElementType !== 'ul' && ElementType !== 'ol', 'list'), className);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nListList.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nListList.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default ListList;","import _default from './List';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\n/**\n * A loader alerts a user to wait for an activity to complete.\n * @see Dimmer\n */\n\nfunction Loader(props) {\n  var active = props.active,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      disabled = props.disabled,\n      indeterminate = props.indeterminate,\n      inline = props.inline,\n      inverted = props.inverted,\n      size = props.size;\n  var classes = cx('ui', size, useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(indeterminate, 'indeterminate'), useKeyOnly(inverted, 'inverted'), useKeyOnly(children || content, 'text'), useKeyOrValueAndKey(inline, 'inline'), 'loader', className);\n  var rest = getUnhandledProps(Loader, props);\n  var ElementType = getElementType(Loader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nLoader.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"disabled\", \"indeterminate\", \"inline\", \"inverted\", \"size\"];\nLoader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A loader can be active or visible. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A loader can be disabled or hidden. */\n  disabled: PropTypes.bool,\n\n  /** A loader can show it's unsure of how long a task will take. */\n  indeterminate: PropTypes.bool,\n\n  /** Loaders can appear inline with content. */\n  inline: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['centered'])]),\n\n  /** Loaders can have their colors inverted. */\n  inverted: PropTypes.bool,\n\n  /** Loaders can have different sizes. */\n  size: PropTypes.oneOf(SUI.SIZES)\n} : {};\nexport default Loader;","import _default from './Loader';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport PlaceholderHeader from './PlaceholderHeader';\nimport PlaceholderImage from './PlaceholderImage';\nimport PlaceholderLine from './PlaceholderLine';\nimport PlaceholderParagraph from './PlaceholderParagraph';\n/**\n * A placeholder is used to reserve splace for content that soon will appear in a layout.\n */\n\nfunction Placeholder(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      fluid = props.fluid,\n      inverted = props.inverted;\n  var classes = cx('ui', useKeyOnly(fluid, 'fluid'), useKeyOnly(inverted, 'inverted'), 'placeholder', className);\n  var rest = getUnhandledProps(Placeholder, props);\n  var ElementType = getElementType(Placeholder, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nPlaceholder.handledProps = [\"as\", \"children\", \"className\", \"content\", \"fluid\", \"inverted\"];\nPlaceholder.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A fluid placeholder takes up the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** A placeholder can have their colors inverted. */\n  inverted: PropTypes.bool\n} : {};\nPlaceholder.Header = PlaceholderHeader;\nPlaceholder.Image = PlaceholderImage;\nPlaceholder.Line = PlaceholderLine;\nPlaceholder.Paragraph = PlaceholderParagraph;\nexport default Placeholder;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A placeholder can contain a header.\n */\n\nfunction PlaceholderHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      image = props.image;\n  var classes = cx(useKeyOnly(image, 'image'), 'header', className);\n  var rest = getUnhandledProps(PlaceholderHeader, props);\n  var ElementType = getElementType(PlaceholderHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nPlaceholderHeader.handledProps = [\"as\", \"children\", \"className\", \"content\", \"image\"];\nPlaceholderHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A placeholder can contain an image. */\n  image: PropTypes.bool\n} : {};\nexport default PlaceholderHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A placeholder can contain an image.\n */\n\nfunction PlaceholderImage(props) {\n  var className = props.className,\n      square = props.square,\n      rectangular = props.rectangular;\n  var classes = cx(useKeyOnly(square, 'square'), useKeyOnly(rectangular, 'rectangular'), 'image', className);\n  var rest = getUnhandledProps(PlaceholderImage, props);\n  var ElementType = getElementType(PlaceholderImage, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }));\n}\n\nPlaceholderImage.handledProps = [\"as\", \"className\", \"rectangular\", \"square\"];\nPlaceholderImage.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** An image can modify size correctly with responsive styles. */\n  square: customPropTypes.every([customPropTypes.disallow(['rectangular']), PropTypes.bool]),\n\n  /** An image can modify size correctly with responsive styles. */\n  rectangular: customPropTypes.every([customPropTypes.disallow(['square']), PropTypes.bool])\n} : {};\nexport default PlaceholderImage;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\n/**\n * A placeholder can contain have lines of text.\n */\n\nfunction PlaceholderLine(props) {\n  var className = props.className,\n      length = props.length;\n  var classes = cx('line', length, className);\n  var rest = getUnhandledProps(PlaceholderLine, props);\n  var ElementType = getElementType(PlaceholderLine, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }));\n}\n\nPlaceholderLine.handledProps = [\"as\", \"className\", \"length\"];\nPlaceholderLine.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A line can specify how long its contents should appear. */\n  length: PropTypes.oneOf(['full', 'very long', 'long', 'medium', 'short', 'very short'])\n} : {};\nexport default PlaceholderLine;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A placeholder can contain a paragraph.\n */\n\nfunction PlaceholderParagraph(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('paragraph', className);\n  var rest = getUnhandledProps(PlaceholderParagraph, props);\n  var ElementType = getElementType(PlaceholderParagraph, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nPlaceholderParagraph.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nPlaceholderParagraph.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default PlaceholderParagraph;","import _default from './Placeholder';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\n/**\n * A rail is used to show accompanying content outside the boundaries of the main view of a site.\n */\n\nfunction Rail(props) {\n  var attached = props.attached,\n      children = props.children,\n      className = props.className,\n      close = props.close,\n      content = props.content,\n      dividing = props.dividing,\n      internal = props.internal,\n      position = props.position,\n      size = props.size;\n  var classes = cx('ui', position, size, useKeyOnly(attached, 'attached'), useKeyOnly(dividing, 'dividing'), useKeyOnly(internal, 'internal'), useKeyOrValueAndKey(close, 'close'), 'rail', className);\n  var rest = getUnhandledProps(Rail, props);\n  var ElementType = getElementType(Rail, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nRail.handledProps = [\"as\", \"attached\", \"children\", \"className\", \"close\", \"content\", \"dividing\", \"internal\", \"position\", \"size\"];\nRail.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A rail can appear attached to the main viewport. */\n  attached: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A rail can appear closer to the main viewport. */\n  close: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A rail can create a division between itself and a container. */\n  dividing: PropTypes.bool,\n\n  /** A rail can attach itself to the inside of a container. */\n  internal: PropTypes.bool,\n\n  /** A rail can be presented on the left or right side of a container. */\n  position: PropTypes.oneOf(SUI.FLOATS).isRequired,\n\n  /** A rail can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium'))\n} : {};\nexport default Rail;","import _default from './Rail';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport RevealContent from './RevealContent';\n/**\n * A reveal displays additional content in place of previous content when activated.\n */\n\nfunction Reveal(props) {\n  var active = props.active,\n      animated = props.animated,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      disabled = props.disabled,\n      instant = props.instant;\n  var classes = cx('ui', animated, useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(instant, 'instant'), 'reveal', className);\n  var rest = getUnhandledProps(Reveal, props);\n  var ElementType = getElementType(Reveal, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nReveal.handledProps = [\"active\", \"animated\", \"as\", \"children\", \"className\", \"content\", \"disabled\", \"instant\"];\nReveal.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An active reveal displays its hidden content. */\n  active: PropTypes.bool,\n\n  /** An animation name that will be applied to Reveal. */\n  animated: PropTypes.oneOf(['fade', 'small fade', 'move', 'move right', 'move up', 'move down', 'rotate', 'rotate left']),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A disabled reveal will not animate when hovered. */\n  disabled: PropTypes.bool,\n\n  /** An element can show its content without delay. */\n  instant: PropTypes.bool\n} : {};\nReveal.Content = RevealContent;\nexport default Reveal;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A content sub-component for the Reveal.\n */\n\nfunction RevealContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      hidden = props.hidden,\n      visible = props.visible;\n  var classes = cx('ui', useKeyOnly(hidden, 'hidden'), useKeyOnly(visible, 'visible'), 'content', className);\n  var rest = getUnhandledProps(RevealContent, props);\n  var ElementType = getElementType(RevealContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nRevealContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"hidden\", \"visible\"];\nRevealContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A reveal may contain content that is visible before interaction. */\n  hidden: PropTypes.bool,\n\n  /** A reveal may contain content that is hidden before user interaction. */\n  visible: PropTypes.bool\n} : {};\nexport default RevealContent;","import _default from './Reveal';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey, useTextAlignProp, useValueAndKey } from '../../lib';\nimport SegmentGroup from './SegmentGroup';\nimport SegmentInline from './SegmentInline';\n/**\n * A segment is used to create a grouping of related content.\n */\n\nfunction Segment(props) {\n  var attached = props.attached,\n      basic = props.basic,\n      children = props.children,\n      circular = props.circular,\n      className = props.className,\n      clearing = props.clearing,\n      color = props.color,\n      compact = props.compact,\n      content = props.content,\n      disabled = props.disabled,\n      floated = props.floated,\n      inverted = props.inverted,\n      loading = props.loading,\n      placeholder = props.placeholder,\n      padded = props.padded,\n      piled = props.piled,\n      raised = props.raised,\n      secondary = props.secondary,\n      size = props.size,\n      stacked = props.stacked,\n      tertiary = props.tertiary,\n      textAlign = props.textAlign,\n      vertical = props.vertical;\n  var classes = cx('ui', color, size, useKeyOnly(basic, 'basic'), useKeyOnly(circular, 'circular'), useKeyOnly(clearing, 'clearing'), useKeyOnly(compact, 'compact'), useKeyOnly(disabled, 'disabled'), useKeyOnly(inverted, 'inverted'), useKeyOnly(loading, 'loading'), useKeyOnly(placeholder, 'placeholder'), useKeyOnly(piled, 'piled'), useKeyOnly(raised, 'raised'), useKeyOnly(secondary, 'secondary'), useKeyOnly(stacked, 'stacked'), useKeyOnly(tertiary, 'tertiary'), useKeyOnly(vertical, 'vertical'), useKeyOrValueAndKey(attached, 'attached'), useKeyOrValueAndKey(padded, 'padded'), useTextAlignProp(textAlign), useValueAndKey(floated, 'floated'), 'segment', className);\n  var rest = getUnhandledProps(Segment, props);\n  var ElementType = getElementType(Segment, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSegment.handledProps = [\"as\", \"attached\", \"basic\", \"children\", \"circular\", \"className\", \"clearing\", \"color\", \"compact\", \"content\", \"disabled\", \"floated\", \"inverted\", \"loading\", \"padded\", \"piled\", \"placeholder\", \"raised\", \"secondary\", \"size\", \"stacked\", \"tertiary\", \"textAlign\", \"vertical\"];\nSegment.Group = SegmentGroup;\nSegment.Inline = SegmentInline;\nSegment.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Attach segment to other content, like a header. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top', 'bottom'])]),\n\n  /** A basic segment has no special formatting. */\n  basic: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** A segment can be circular. */\n  circular: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A segment can clear floated content. */\n  clearing: PropTypes.bool,\n\n  /** Segment can be colored. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** A segment may take up only as much space as is necessary. */\n  compact: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A segment may show its content is disabled. */\n  disabled: PropTypes.bool,\n\n  /** Segment content can be floated to the left or right. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** A segment can have its colors inverted for contrast. */\n  inverted: PropTypes.bool,\n\n  /** A segment may show its content is being loaded. */\n  loading: PropTypes.bool,\n\n  /** A segment can increase its padding. */\n  padded: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** A segment can be used to reserve space for conditionally displayed content. */\n  placeholder: PropTypes.bool,\n\n  /** Formatted to look like a pile of pages. */\n  piled: PropTypes.bool,\n\n  /** A segment may be formatted to raise above the page. */\n  raised: PropTypes.bool,\n\n  /** A segment can be formatted to appear less noticeable. */\n  secondary: PropTypes.bool,\n\n  /** A segment can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** Formatted to show it contains multiple pages. */\n  stacked: PropTypes.bool,\n\n  /** A segment can be formatted to appear even less noticeable. */\n  tertiary: PropTypes.bool,\n\n  /** Formats content to be aligned as part of a vertical group. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified')),\n\n  /** Formats content to be aligned vertically. */\n  vertical: PropTypes.bool\n} : {};\nexport default Segment;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly } from '../../lib';\n/**\n * A group of segments can be formatted to appear together.\n */\n\nfunction SegmentGroup(props) {\n  var children = props.children,\n      className = props.className,\n      compact = props.compact,\n      content = props.content,\n      horizontal = props.horizontal,\n      piled = props.piled,\n      raised = props.raised,\n      size = props.size,\n      stacked = props.stacked;\n  var classes = cx('ui', size, useKeyOnly(compact, 'compact'), useKeyOnly(horizontal, 'horizontal'), useKeyOnly(piled, 'piled'), useKeyOnly(raised, 'raised'), useKeyOnly(stacked, 'stacked'), 'segments', className);\n  var rest = getUnhandledProps(SegmentGroup, props);\n  var ElementType = getElementType(SegmentGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSegmentGroup.handledProps = [\"as\", \"children\", \"className\", \"compact\", \"content\", \"horizontal\", \"piled\", \"raised\", \"size\", \"stacked\"];\nSegmentGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A segment may take up only as much space as is necessary. */\n  compact: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Formats content to be aligned horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** Formatted to look like a pile of pages. */\n  piled: PropTypes.bool,\n\n  /** A segment group may be formatted to raise above the page. */\n  raised: PropTypes.bool,\n\n  /** A segment group can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** Formatted to show it contains multiple pages. */\n  stacked: PropTypes.bool\n} : {};\nexport default SegmentGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A placeholder segment can be inline.\n */\n\nfunction SegmentInline(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('inline', className);\n  var rest = getUnhandledProps(SegmentInline, props);\n  var ElementType = getElementType(SegmentInline, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSegmentInline.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nSegmentInline.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default SegmentInline;","import _default from './Segment';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Icon from '../Icon';\nimport StepContent from './StepContent';\nimport StepDescription from './StepDescription';\nimport StepGroup from './StepGroup';\nimport StepTitle from './StepTitle';\n/**\n * A step shows the completion status of an activity in a series of activities.\n */\n\nvar Step = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Step, _Component);\n\n  function Step() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.computeElementType = function () {\n      var onClick = _this.props.onClick;\n      if (onClick) return 'a';\n    };\n\n    _this.handleClick = function (e) {\n      var disabled = _this.props.disabled;\n      if (!disabled) _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = Step.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        completed = _this$props.completed,\n        content = _this$props.content,\n        description = _this$props.description,\n        disabled = _this$props.disabled,\n        href = _this$props.href,\n        icon = _this$props.icon,\n        link = _this$props.link,\n        title = _this$props.title;\n    var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(completed, 'completed'), useKeyOnly(disabled, 'disabled'), useKeyOnly(link, 'link'), 'step', className);\n    var rest = getUnhandledProps(Step, this.props);\n    var ElementType = getElementType(Step, this.props, this.computeElementType);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        href: href,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    if (!childrenUtils.isNil(content)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        href: href,\n        onClick: this.handleClick\n      }), content);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      href: href,\n      onClick: this.handleClick\n    }), Icon.create(icon, {\n      autoGenerateKey: false\n    }), StepContent.create({\n      description: description,\n      title: title\n    }, {\n      autoGenerateKey: false\n    }));\n  };\n\n  return Step;\n}(Component);\n\nStep.handledProps = [\"active\", \"as\", \"children\", \"className\", \"completed\", \"content\", \"description\", \"disabled\", \"href\", \"icon\", \"link\", \"onClick\", \"ordered\", \"title\"];\nStep.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A step can be highlighted as active. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A step can show that a user has completed it. */\n  completed: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for StepDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** Show that the Loader is inactive. */\n  disabled: PropTypes.bool,\n\n  /** Render as an `a` tag instead of a `div` and adds the href attribute. */\n  href: PropTypes.string,\n\n  /** Shorthand for Icon. */\n  icon: customPropTypes.itemShorthand,\n\n  /** A step can be link. */\n  link: PropTypes.bool,\n\n  /**\n   * Called on click. When passed, the component will render as an `a`\n   * tag by default instead of a `div`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /** A step can show a ordered sequence of steps. Passed from StepGroup. */\n  ordered: PropTypes.bool,\n\n  /** Shorthand for StepTitle. */\n  title: customPropTypes.itemShorthand\n} : {};\nStep.Content = StepContent;\nStep.Description = StepDescription;\nStep.Group = StepGroup;\nStep.Title = StepTitle;\nStep.create = createShorthandFactory(Step, function (content) {\n  return {\n    content: content\n  };\n});\nexport default Step;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport StepDescription from './StepDescription';\nimport StepTitle from './StepTitle';\n/**\n * A step can contain a content.\n */\n\nfunction StepContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      description = props.description,\n      title = props.title;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(StepContent, props);\n  var ElementType = getElementType(StepContent, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), StepTitle.create(title, {\n    autoGenerateKey: false\n  }), StepDescription.create(description, {\n    autoGenerateKey: false\n  }));\n}\n\nStepContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"description\", \"title\"];\nStepContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for StepDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** Shorthand for StepTitle. */\n  title: customPropTypes.itemShorthand\n} : {};\nStepContent.create = createShorthandFactory(StepContent, function (content) {\n  return {\n    content: content\n  };\n});\nexport default StepContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n\nfunction StepDescription(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('description', className);\n  var rest = getUnhandledProps(StepDescription, props);\n  var ElementType = getElementType(StepDescription, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nStepDescription.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nStepDescription.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nStepDescription.create = createShorthandFactory(StepDescription, function (content) {\n  return {\n    content: content\n  };\n});\nexport default StepDescription;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _values from \"lodash/values\";\nimport _keys from \"lodash/keys\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport _pickBy from \"lodash/pickBy\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, numberToWordMap, SUI, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useWidthProp } from '../../lib';\nimport Step from './Step';\nvar numberMap = process.env.NODE_ENV !== \"production\" ? _pickBy(numberToWordMap, function (val, key) {\n  return key <= 8;\n}) : {};\n/**\n * A set of steps.\n */\n\nfunction StepGroup(props) {\n  var attached = props.attached,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      fluid = props.fluid,\n      items = props.items,\n      ordered = props.ordered,\n      size = props.size,\n      stackable = props.stackable,\n      unstackable = props.unstackable,\n      vertical = props.vertical,\n      widths = props.widths;\n  var classes = cx('ui', size, useKeyOnly(fluid, 'fluid'), useKeyOnly(ordered, 'ordered'), useKeyOnly(unstackable, 'unstackable'), useKeyOnly(vertical, 'vertical'), useKeyOrValueAndKey(attached, 'attached'), useValueAndKey(stackable, 'stackable'), useWidthProp(widths), 'steps', className);\n  var rest = getUnhandledProps(StepGroup, props);\n  var ElementType = getElementType(StepGroup, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), _map(items, function (item) {\n    return Step.create(item);\n  }));\n}\n\nStepGroup.handledProps = [\"as\", \"attached\", \"children\", \"className\", \"content\", \"fluid\", \"items\", \"ordered\", \"size\", \"stackable\", \"unstackable\", \"vertical\", \"widths\"];\nStepGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Steps can be attached to other elements. */\n  attached: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['top', 'bottom'])]),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A fluid step takes up the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** Shorthand array of props for Step. */\n  items: customPropTypes.collectionShorthand,\n\n  /** A step can show a ordered sequence of steps. */\n  ordered: PropTypes.bool,\n\n  /** Steps can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** A step can stack vertically only on smaller screens. */\n  stackable: PropTypes.oneOf(['tablet']),\n\n  /** A step can prevent itself from stacking on mobile. */\n  unstackable: PropTypes.bool,\n\n  /** A step can be displayed stacked vertically. */\n  vertical: PropTypes.bool,\n\n  /** Steps can be divided evenly inside their parent. */\n  widths: PropTypes.oneOf([].concat(_keys(numberMap), _keys(numberMap).map(Number), _values(numberMap)))\n} : {};\nexport default StepGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A step can contain a title.\n */\n\nfunction StepTitle(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('title', className);\n  var rest = getUnhandledProps(StepTitle, props);\n  var ElementType = getElementType(StepTitle, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nStepTitle.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nStepTitle.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nStepTitle.create = createShorthandFactory(StepTitle, function (content) {\n  return {\n    content: content\n  };\n});\nexport default StepTitle;","import _default from './Step';\nexport { _default as default };","// Third party\nexport { Ref } from '@stardust-ui/react-component-ref'; // Addons\n\nimport _Confirm from './addons/Confirm';\nexport { _Confirm as Confirm };\nimport _MountNode from './addons/MountNode';\nexport { _MountNode as MountNode };\nimport _Pagination from './addons/Pagination';\nexport { _Pagination as Pagination };\nimport _PaginationItem from './addons/Pagination/PaginationItem';\nexport { _PaginationItem as PaginationItem };\nimport _Portal from './addons/Portal';\nexport { _Portal as Portal };\nimport _PortalInner from './addons/Portal/PortalInner';\nexport { _PortalInner as PortalInner };\nimport _Radio from './addons/Radio';\nexport { _Radio as Radio };\nimport _Responsive from './addons/Responsive';\nexport { _Responsive as Responsive };\nimport _Select from './addons/Select';\nexport { _Select as Select };\nimport _TextArea from './addons/TextArea';\nexport { _TextArea as TextArea };\nimport _TransitionablePortal from './addons/TransitionablePortal';\nexport { _TransitionablePortal as TransitionablePortal }; // Behaviors\n\nimport _Visibility from './behaviors/Visibility';\nexport { _Visibility as Visibility }; // Collections\n\nimport _Breadcrumb from './collections/Breadcrumb';\nexport { _Breadcrumb as Breadcrumb };\nimport _BreadcrumbDivider from './collections/Breadcrumb/BreadcrumbDivider';\nexport { _BreadcrumbDivider as BreadcrumbDivider };\nimport _BreadcrumbSection from './collections/Breadcrumb/BreadcrumbSection';\nexport { _BreadcrumbSection as BreadcrumbSection };\nimport _Form from './collections/Form';\nexport { _Form as Form };\nimport _FormButton from './collections/Form/FormButton';\nexport { _FormButton as FormButton };\nimport _FormCheckbox from './collections/Form/FormCheckbox';\nexport { _FormCheckbox as FormCheckbox };\nimport _FormDropdown from './collections/Form/FormDropdown';\nexport { _FormDropdown as FormDropdown };\nimport _FormField from './collections/Form/FormField';\nexport { _FormField as FormField };\nimport _FormGroup from './collections/Form/FormGroup';\nexport { _FormGroup as FormGroup };\nimport _FormInput from './collections/Form/FormInput';\nexport { _FormInput as FormInput };\nimport _FormRadio from './collections/Form/FormRadio';\nexport { _FormRadio as FormRadio };\nimport _FormSelect from './collections/Form/FormSelect';\nexport { _FormSelect as FormSelect };\nimport _FormTextArea from './collections/Form/FormTextArea';\nexport { _FormTextArea as FormTextArea };\nimport _Grid from './collections/Grid';\nexport { _Grid as Grid };\nimport _GridColumn from './collections/Grid/GridColumn';\nexport { _GridColumn as GridColumn };\nimport _GridRow from './collections/Grid/GridRow';\nexport { _GridRow as GridRow };\nimport _Menu from './collections/Menu';\nexport { _Menu as Menu };\nimport _MenuHeader from './collections/Menu/MenuHeader';\nexport { _MenuHeader as MenuHeader };\nimport _MenuItem from './collections/Menu/MenuItem';\nexport { _MenuItem as MenuItem };\nimport _MenuMenu from './collections/Menu/MenuMenu';\nexport { _MenuMenu as MenuMenu };\nimport _Message from './collections/Message';\nexport { _Message as Message };\nimport _MessageContent from './collections/Message/MessageContent';\nexport { _MessageContent as MessageContent };\nimport _MessageHeader from './collections/Message/MessageHeader';\nexport { _MessageHeader as MessageHeader };\nimport _MessageItem from './collections/Message/MessageItem';\nexport { _MessageItem as MessageItem };\nimport _MessageList from './collections/Message/MessageList';\nexport { _MessageList as MessageList };\nimport _Table from './collections/Table';\nexport { _Table as Table };\nimport _TableBody from './collections/Table/TableBody';\nexport { _TableBody as TableBody };\nimport _TableCell from './collections/Table/TableCell';\nexport { _TableCell as TableCell };\nimport _TableFooter from './collections/Table/TableFooter';\nexport { _TableFooter as TableFooter };\nimport _TableHeader from './collections/Table/TableHeader';\nexport { _TableHeader as TableHeader };\nimport _TableHeaderCell from './collections/Table/TableHeaderCell';\nexport { _TableHeaderCell as TableHeaderCell };\nimport _TableRow from './collections/Table/TableRow';\nexport { _TableRow as TableRow }; // Elements\n\nimport _Button from './elements/Button/Button';\nexport { _Button as Button };\nimport _ButtonContent from './elements/Button/ButtonContent';\nexport { _ButtonContent as ButtonContent };\nimport _ButtonGroup from './elements/Button/ButtonGroup';\nexport { _ButtonGroup as ButtonGroup };\nimport _ButtonOr from './elements/Button/ButtonOr';\nexport { _ButtonOr as ButtonOr };\nimport _Container from './elements/Container';\nexport { _Container as Container };\nimport _Divider from './elements/Divider';\nexport { _Divider as Divider };\nimport _Flag from './elements/Flag';\nexport { _Flag as Flag };\nimport _Header from './elements/Header';\nexport { _Header as Header };\nimport _HeaderContent from './elements/Header/HeaderContent';\nexport { _HeaderContent as HeaderContent };\nimport _HeaderSubheader from './elements/Header/HeaderSubheader';\nexport { _HeaderSubheader as HeaderSubheader };\nimport _Icon from './elements/Icon';\nexport { _Icon as Icon };\nimport _IconGroup from './elements/Icon/IconGroup';\nexport { _IconGroup as IconGroup };\nimport _Image from './elements/Image';\nexport { _Image as Image };\nimport _ImageGroup from './elements/Image/ImageGroup';\nexport { _ImageGroup as ImageGroup };\nimport _Input from './elements/Input';\nexport { _Input as Input };\nimport _Label from './elements/Label';\nexport { _Label as Label };\nimport _LabelDetail from './elements/Label/LabelDetail';\nexport { _LabelDetail as LabelDetail };\nimport _LabelGroup from './elements/Label/LabelGroup';\nexport { _LabelGroup as LabelGroup };\nimport _List from './elements/List';\nexport { _List as List };\nimport _ListContent from './elements/List/ListContent';\nexport { _ListContent as ListContent };\nimport _ListDescription from './elements/List/ListDescription';\nexport { _ListDescription as ListDescription };\nimport _ListHeader from './elements/List/ListHeader';\nexport { _ListHeader as ListHeader };\nimport _ListIcon from './elements/List/ListIcon';\nexport { _ListIcon as ListIcon };\nimport _ListItem from './elements/List/ListItem';\nexport { _ListItem as ListItem };\nimport _ListList from './elements/List/ListList';\nexport { _ListList as ListList };\nimport _Loader from './elements/Loader';\nexport { _Loader as Loader };\nimport _Placeholder from './elements/Placeholder';\nexport { _Placeholder as Placeholder };\nimport _PlaceholderHeader from './elements/Placeholder/PlaceholderHeader';\nexport { _PlaceholderHeader as PlaceholderHeader };\nimport _PlaceholderImage from './elements/Placeholder/PlaceholderImage';\nexport { _PlaceholderImage as PlaceholderImage };\nimport _PlaceholderLine from './elements/Placeholder/PlaceholderLine';\nexport { _PlaceholderLine as PlaceholderLine };\nimport _PlaceholderParagraph from './elements/Placeholder/PlaceholderParagraph';\nexport { _PlaceholderParagraph as PlaceholderParagraph };\nimport _Rail from './elements/Rail';\nexport { _Rail as Rail };\nimport _Reveal from './elements/Reveal';\nexport { _Reveal as Reveal };\nimport _RevealContent from './elements/Reveal/RevealContent';\nexport { _RevealContent as RevealContent };\nimport _Segment from './elements/Segment';\nexport { _Segment as Segment };\nimport _SegmentGroup from './elements/Segment/SegmentGroup';\nexport { _SegmentGroup as SegmentGroup };\nimport _SegmentInline from './elements/Segment/SegmentInline';\nexport { _SegmentInline as SegmentInline };\nimport _Step from './elements/Step';\nexport { _Step as Step };\nimport _StepContent from './elements/Step/StepContent';\nexport { _StepContent as StepContent };\nimport _StepDescription from './elements/Step/StepDescription';\nexport { _StepDescription as StepDescription };\nimport _StepGroup from './elements/Step/StepGroup';\nexport { _StepGroup as StepGroup };\nimport _StepTitle from './elements/Step/StepTitle';\nexport { _StepTitle as StepTitle }; // Modules\n\nimport _Accordion from './modules/Accordion/Accordion';\nexport { _Accordion as Accordion };\nimport _AccordionAccordion from './modules/Accordion/AccordionAccordion';\nexport { _AccordionAccordion as AccordionAccordion };\nimport _AccordionContent from './modules/Accordion/AccordionContent';\nexport { _AccordionContent as AccordionContent };\nimport _AccordionPanel from './modules/Accordion/AccordionPanel';\nexport { _AccordionPanel as AccordionPanel };\nimport _AccordionTitle from './modules/Accordion/AccordionTitle';\nexport { _AccordionTitle as AccordionTitle };\nimport _Checkbox from './modules/Checkbox';\nexport { _Checkbox as Checkbox };\nimport _Dimmer from './modules/Dimmer';\nexport { _Dimmer as Dimmer };\nimport _DimmerDimmable from './modules/Dimmer/DimmerDimmable';\nexport { _DimmerDimmable as DimmerDimmable };\nimport _DimmerInner from './modules/Dimmer/DimmerInner';\nexport { _DimmerInner as DimmerInner };\nimport _Dropdown from './modules/Dropdown';\nexport { _Dropdown as Dropdown };\nimport _DropdownDivider from './modules/Dropdown/DropdownDivider';\nexport { _DropdownDivider as DropdownDivider };\nimport _DropdownHeader from './modules/Dropdown/DropdownHeader';\nexport { _DropdownHeader as DropdownHeader };\nimport _DropdownItem from './modules/Dropdown/DropdownItem';\nexport { _DropdownItem as DropdownItem };\nimport _DropdownMenu from './modules/Dropdown/DropdownMenu';\nexport { _DropdownMenu as DropdownMenu };\nimport _DropdownSearchInput from './modules/Dropdown/DropdownSearchInput';\nexport { _DropdownSearchInput as DropdownSearchInput };\nimport _DropdownText from './modules/Dropdown/DropdownText';\nexport { _DropdownText as DropdownText };\nimport _Embed from './modules/Embed';\nexport { _Embed as Embed };\nimport _Modal from './modules/Modal';\nexport { _Modal as Modal };\nimport _ModalActions from './modules/Modal/ModalActions';\nexport { _ModalActions as ModalActions };\nimport _ModalContent from './modules/Modal/ModalContent';\nexport { _ModalContent as ModalContent };\nimport _ModalDescription from './modules/Modal/ModalDescription';\nexport { _ModalDescription as ModalDescription };\nimport _ModalDimmer from './modules/Modal/ModalDimmer';\nexport { _ModalDimmer as ModalDimmer };\nimport _ModalHeader from './modules/Modal/ModalHeader';\nexport { _ModalHeader as ModalHeader };\nimport _Popup from './modules/Popup';\nexport { _Popup as Popup };\nimport _PopupContent from './modules/Popup/PopupContent';\nexport { _PopupContent as PopupContent };\nimport _PopupHeader from './modules/Popup/PopupHeader';\nexport { _PopupHeader as PopupHeader };\nimport _Progress from './modules/Progress';\nexport { _Progress as Progress };\nimport _Rating from './modules/Rating';\nexport { _Rating as Rating };\nimport _RatingIcon from './modules/Rating/RatingIcon';\nexport { _RatingIcon as RatingIcon };\nimport _Search from './modules/Search';\nexport { _Search as Search };\nimport _SearchCategory from './modules/Search/SearchCategory';\nexport { _SearchCategory as SearchCategory };\nimport _SearchResult from './modules/Search/SearchResult';\nexport { _SearchResult as SearchResult };\nimport _SearchResults from './modules/Search/SearchResults';\nexport { _SearchResults as SearchResults };\nimport _Sidebar from './modules/Sidebar';\nexport { _Sidebar as Sidebar };\nimport _SidebarPushable from './modules/Sidebar/SidebarPushable';\nexport { _SidebarPushable as SidebarPushable };\nimport _SidebarPusher from './modules/Sidebar/SidebarPusher';\nexport { _SidebarPusher as SidebarPusher };\nimport _Sticky from './modules/Sticky';\nexport { _Sticky as Sticky };\nimport _Tab from './modules/Tab';\nexport { _Tab as Tab };\nimport _TabPane from './modules/Tab/TabPane';\nexport { _TabPane as TabPane };\nimport _Transition from './modules/Transition';\nexport { _Transition as Transition };\nimport _TransitionGroup from './modules/Transition/TransitionGroup';\nexport { _TransitionGroup as TransitionGroup }; // Views\n\nimport _Advertisement from './views/Advertisement';\nexport { _Advertisement as Advertisement };\nimport _Card from './views/Card/Card';\nexport { _Card as Card };\nimport _CardContent from './views/Card/CardContent';\nexport { _CardContent as CardContent };\nimport _CardDescription from './views/Card/CardDescription';\nexport { _CardDescription as CardDescription };\nimport _CardGroup from './views/Card/CardGroup';\nexport { _CardGroup as CardGroup };\nimport _CardHeader from './views/Card/CardHeader';\nexport { _CardHeader as CardHeader };\nimport _CardMeta from './views/Card/CardMeta';\nexport { _CardMeta as CardMeta };\nimport _Comment from './views/Comment';\nexport { _Comment as Comment };\nimport _CommentAction from './views/Comment/CommentAction';\nexport { _CommentAction as CommentAction };\nimport _CommentActions from './views/Comment/CommentActions';\nexport { _CommentActions as CommentActions };\nimport _CommentAuthor from './views/Comment/CommentAuthor';\nexport { _CommentAuthor as CommentAuthor };\nimport _CommentAvatar from './views/Comment/CommentAvatar';\nexport { _CommentAvatar as CommentAvatar };\nimport _CommentContent from './views/Comment/CommentContent';\nexport { _CommentContent as CommentContent };\nimport _CommentGroup from './views/Comment/CommentGroup';\nexport { _CommentGroup as CommentGroup };\nimport _CommentMetadata from './views/Comment/CommentMetadata';\nexport { _CommentMetadata as CommentMetadata };\nimport _CommentText from './views/Comment/CommentText';\nexport { _CommentText as CommentText };\nimport _Feed from './views/Feed';\nexport { _Feed as Feed };\nimport _FeedContent from './views/Feed/FeedContent';\nexport { _FeedContent as FeedContent };\nimport _FeedDate from './views/Feed/FeedDate';\nexport { _FeedDate as FeedDate };\nimport _FeedEvent from './views/Feed/FeedEvent';\nexport { _FeedEvent as FeedEvent };\nimport _FeedExtra from './views/Feed/FeedExtra';\nexport { _FeedExtra as FeedExtra };\nimport _FeedLabel from './views/Feed/FeedLabel';\nexport { _FeedLabel as FeedLabel };\nimport _FeedLike from './views/Feed/FeedLike';\nexport { _FeedLike as FeedLike };\nimport _FeedMeta from './views/Feed/FeedMeta';\nexport { _FeedMeta as FeedMeta };\nimport _FeedSummary from './views/Feed/FeedSummary';\nexport { _FeedSummary as FeedSummary };\nimport _FeedUser from './views/Feed/FeedUser';\nexport { _FeedUser as FeedUser };\nimport _Item from './views/Item';\nexport { _Item as Item };\nimport _ItemContent from './views/Item/ItemContent';\nexport { _ItemContent as ItemContent };\nimport _ItemDescription from './views/Item/ItemDescription';\nexport { _ItemDescription as ItemDescription };\nimport _ItemExtra from './views/Item/ItemExtra';\nexport { _ItemExtra as ItemExtra };\nimport _ItemGroup from './views/Item/ItemGroup';\nexport { _ItemGroup as ItemGroup };\nimport _ItemHeader from './views/Item/ItemHeader';\nexport { _ItemHeader as ItemHeader };\nimport _ItemImage from './views/Item/ItemImage';\nexport { _ItemImage as ItemImage };\nimport _ItemMeta from './views/Item/ItemMeta';\nexport { _ItemMeta as ItemMeta };\nimport _Statistic from './views/Statistic';\nexport { _Statistic as Statistic };\nimport _StatisticGroup from './views/Statistic/StatisticGroup';\nexport { _StatisticGroup as StatisticGroup };\nimport _StatisticLabel from './views/Statistic/StatisticLabel';\nexport { _StatisticLabel as StatisticLabel };\nimport _StatisticValue from './views/Statistic/StatisticValue';\nexport { _StatisticValue as StatisticValue };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/esm/assertThisInitialized\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport _startsWith from \"lodash/startsWith\";\nimport _filter from \"lodash/filter\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _keys from \"lodash/keys\";\nimport _intersection from \"lodash/intersection\";\nimport _has from \"lodash/has\";\nimport _each from \"lodash/each\";\nimport _invoke from \"lodash/invoke\";\nimport React from 'react';\n\nvar getDefaultPropName = function getDefaultPropName(prop) {\n  return \"default\" + (prop[0].toUpperCase() + prop.slice(1));\n};\n/**\n * Return the auto controlled state value for a give prop. The initial value is chosen in this order:\n *  - regular props\n *  - then, default props\n *  - then, initial state\n *  - then, `checked` defaults to false\n *  - then, `value` defaults to '' or [] if props.multiple\n *  - else, undefined\n *\n *  @param {string} propName A prop name\n *  @param {object} [props] A props object\n *  @param {object} [state] A state object\n *  @param {boolean} [includeDefaults=false] Whether or not to heed the default props or initial state\n */\n\n\nvar getAutoControlledStateValue = function getAutoControlledStateValue(propName, props, state, includeDefaults) {\n  if (includeDefaults === void 0) {\n    includeDefaults = false;\n  }\n\n  // regular props\n  var propValue = props[propName];\n  if (propValue !== undefined) return propValue;\n\n  if (includeDefaults) {\n    // defaultProps\n    var defaultProp = props[getDefaultPropName(propName)];\n    if (defaultProp !== undefined) return defaultProp; // initial state - state may be null or undefined\n\n    if (state) {\n      var initialState = state[propName];\n      if (initialState !== undefined) return initialState;\n    }\n  } // React doesn't allow changing from uncontrolled to controlled components,\n  // default checked/value if they were not present.\n\n\n  if (propName === 'checked') return false;\n  if (propName === 'value') return props.multiple ? [] : ''; // otherwise, undefined\n};\n\nvar ModernAutoControlledComponent = /*#__PURE__*/function (_React$Component) {\n  _inheritsLoose(ModernAutoControlledComponent, _React$Component);\n\n  function ModernAutoControlledComponent() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n    var _this$constructor = _this.constructor,\n        autoControlledProps = _this$constructor.autoControlledProps,\n        getAutoControlledStateFromProps = _this$constructor.getAutoControlledStateFromProps;\n    var state = _invoke(_assertThisInitialized(_this), 'getInitialAutoControlledState', _this.props) || {};\n\n    if (process.env.NODE_ENV !== 'production') {\n      var _this$constructor2 = _this.constructor,\n          defaultProps = _this$constructor2.defaultProps,\n          name = _this$constructor2.name,\n          propTypes = _this$constructor2.propTypes,\n          getDerivedStateFromProps = _this$constructor2.getDerivedStateFromProps; // require usage of getAutoControlledStateFromProps()\n\n      if (getDerivedStateFromProps !== ModernAutoControlledComponent.getDerivedStateFromProps) {\n        /* eslint-disable-next-line no-console */\n        console.error(\"Auto controlled \" + name + \" must specify a static getAutoControlledStateFromProps() instead of getDerivedStateFromProps().\");\n      } // require propTypes\n\n\n      _each(autoControlledProps, function (prop) {\n        var defaultProp = getDefaultPropName(prop); // regular prop\n\n        if (!_has(propTypes, defaultProp)) {\n          console.error(name + \" is missing \\\"\" + defaultProp + \"\\\" propTypes validation for auto controlled prop \\\"\" + prop + \"\\\".\");\n        } // its default prop\n\n\n        if (!_has(propTypes, prop)) {\n          console.error(name + \" is missing propTypes validation for auto controlled prop \\\"\" + prop + \"\\\".\");\n        }\n      }); // prevent autoControlledProps in defaultProps\n      //\n      // When setting state, auto controlled props values always win (so the parent can manage them).\n      // It is not reasonable to decipher the difference between props from the parent and defaultProps.\n      // Allowing defaultProps results in trySetState always deferring to the defaultProp value.\n      // Auto controlled props also listed in defaultProps can never be updated.\n      //\n      // To set defaults for an AutoControlled prop, you can set the initial state in the\n      // constructor or by using an ES7 property initializer:\n      // https://babeljs.io/blog/2015/06/07/react-on-es6-plus#property-initializers\n\n\n      var illegalDefaults = _intersection(autoControlledProps, _keys(defaultProps));\n\n      if (!_isEmpty(illegalDefaults)) {\n        console.error(['Do not set defaultProps for autoControlledProps. You can set defaults by', 'setting state in the constructor or using an ES7 property initializer', '(https://babeljs.io/blog/2015/06/07/react-on-es6-plus#property-initializers)', \"See \" + name + \" props: \\\"\" + illegalDefaults + \"\\\".\"].join(' '));\n      } // prevent listing defaultProps in autoControlledProps\n      //\n      // Default props are automatically handled.\n      // Listing defaults in autoControlledProps would result in allowing defaultDefaultValue props.\n\n\n      var illegalAutoControlled = _filter(autoControlledProps, function (prop) {\n        return _startsWith(prop, 'default');\n      });\n\n      if (!_isEmpty(illegalAutoControlled)) {\n        console.error(['Do not add default props to autoControlledProps.', 'Default props are automatically handled.', \"See \" + name + \" autoControlledProps: \\\"\" + illegalAutoControlled + \"\\\".\"].join(' '));\n      }\n    } // Auto controlled props are copied to state.\n    // Set initial state by copying auto controlled props to state.\n    // Also look for the default prop for any auto controlled props (foo => defaultFoo)\n    // so we can set initial values from defaults.\n\n\n    var initialAutoControlledState = autoControlledProps.reduce(function (acc, prop) {\n      acc[prop] = getAutoControlledStateValue(prop, _this.props, state, true);\n\n      if (process.env.NODE_ENV !== 'production') {\n        var defaultPropName = getDefaultPropName(prop);\n        var _name = _this.constructor.name; // prevent defaultFoo={} along side foo={}\n\n        if (!_isUndefined(_this.props[defaultPropName]) && !_isUndefined(_this.props[prop])) {\n          console.error(_name + \" prop \\\"\" + prop + \"\\\" is auto controlled. Specify either \" + defaultPropName + \" or \" + prop + \", but not both.\");\n        }\n      }\n\n      return acc;\n    }, {});\n    _this.state = _extends({}, state, initialAutoControlledState, {\n      autoControlledProps: autoControlledProps,\n      getAutoControlledStateFromProps: getAutoControlledStateFromProps\n    });\n    return _this;\n  }\n\n  ModernAutoControlledComponent.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    var autoControlledProps = state.autoControlledProps,\n        getAutoControlledStateFromProps = state.getAutoControlledStateFromProps; // Solve the next state for autoControlledProps\n\n    var newStateFromProps = autoControlledProps.reduce(function (acc, prop) {\n      var isNextDefined = !_isUndefined(props[prop]); // if next is defined then use its value\n\n      if (isNextDefined) acc[prop] = props[prop];\n      return acc;\n    }, {}); // Due to the inheritance of the AutoControlledComponent we should call its\n    // getAutoControlledStateFromProps() and merge it with the existing state\n\n    if (getAutoControlledStateFromProps) {\n      var computedState = getAutoControlledStateFromProps(props, _extends({}, state, newStateFromProps), state); // We should follow the idea of getDerivedStateFromProps() and return only modified state\n\n      return _extends({}, newStateFromProps, computedState);\n    }\n\n    return newStateFromProps;\n  }\n  /**\n   * Override this method to use getDerivedStateFromProps() in child components.\n   */\n  ;\n\n  ModernAutoControlledComponent.getAutoControlledStateFromProps = function getAutoControlledStateFromProps() {\n    return null;\n  };\n\n  return ModernAutoControlledComponent;\n}(React.Component);\n\nexport { ModernAutoControlledComponent as default };","import _uniq from \"lodash/uniq\";\nimport _values from \"lodash/values\";\nimport _keys from \"lodash/keys\";\nimport { numberToWordMap } from './numberToWord';\nexport var COLORS = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue', 'violet', 'purple', 'pink', 'brown', 'grey', 'black'];\nexport var FLOATS = ['left', 'right'];\nexport var SIZES = ['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive'];\nexport var TEXT_ALIGNMENTS = ['left', 'center', 'right', 'justified'];\nexport var VERTICAL_ALIGNMENTS = ['bottom', 'middle', 'top'];\nexport var VISIBILITY = ['mobile', 'tablet', 'computer', 'large screen', 'widescreen'];\nexport var WIDTHS = [].concat(_keys(numberToWordMap), _keys(numberToWordMap).map(Number), _values(numberToWordMap));\nexport var DIRECTIONAL_TRANSITIONS = ['browse', 'browse right', 'drop', 'fade', 'fade up', 'fade down', 'fade left', 'fade right', 'fly up', 'fly down', 'fly left', 'fly right', 'horizontal flip', 'vertical flip', 'scale', 'slide up', 'slide down', 'slide left', 'slide right', 'swing up', 'swing down', 'swing left', 'swing right', 'zoom'];\nexport var STATIC_TRANSITIONS = ['jiggle', 'flash', 'shake', 'pulse', 'tada', 'bounce', 'glow'];\nexport var TRANSITIONS = [].concat(DIRECTIONAL_TRANSITIONS, STATIC_TRANSITIONS); // Generated from:\n// https://github.com/Semantic-Org/Semantic-UI/blob/master/dist/components/icon.css\n\nexport var ACCESSIBILITY = ['american sign language interpreting', 'assistive listening systems', 'audio description', 'blind', 'braille', 'closed captioning', 'closed captioning outline', 'deaf', 'low vision', 'phone volume', 'question circle', 'question circle outline', 'sign language', 'tty', 'universal access', 'wheelchair'];\nexport var ARROWS = ['angle double down', 'angle double left', 'angle double right', 'angle double up', 'angle down', 'angle left', 'angle right', 'angle up', 'arrow alternate circle down', 'arrow alternate circle down outline', 'arrow alternate circle left', 'arrow alternate circle left outline', 'arrow alternate circle right', 'arrow alternate circle right outline', 'arrow alternate circle up', 'arrow alternate circle up outline', 'arrow circle down', 'arrow circle left', 'arrow circle right', 'arrow circle up', 'arrow down', 'arrow left', 'arrow right', 'arrow up', 'arrows alternate', 'arrows alternate horizontal', 'arrows alternate vertical', 'caret down', 'caret left', 'caret right', 'caret square down', 'caret square down outline', 'caret square left', 'caret square left outline', 'caret square right', 'caret square right outline', 'caret square up', 'caret square up outline', 'caret up', 'cart arrow down', 'chart line', 'chevron circle down', 'chevron circle left', 'chevron circle right', 'chevron circle up', 'chevron down', 'chevron left', 'chevron right', 'chevron up', 'cloud download', 'cloud upload', 'download', 'exchange', 'expand arrows alternate', 'external alternate', 'external square alternate', 'hand point down', 'hand point down outline', 'hand point left', 'hand point left outline', 'hand point right', 'hand point right outline', 'hand point up', 'hand point up outline', 'hand pointer', 'hand pointer outline', 'history', 'level down alternate', 'level up alternate', 'location arrow', 'long arrow alternate down', 'long arrow alternate left', 'long arrow alternate right', 'long arrow alternate up', 'mouse pointer', 'play', 'random', 'recycle', 'redo', 'redo alternate', 'reply', 'reply all', 'retweet', 'share', 'share square', 'share square outline', 'sign-in', 'sign-out', 'sign-in alternate', 'sign-out alternate', 'sort', 'sort alphabet down', 'sort alphabet up', 'sort amount down', 'sort amount up', 'sort down', 'sort numeric down', 'sort numeric up', 'sort up', 'sync', 'sync alternate', 'text height', 'text width', 'undo', 'undo alternate', 'upload', 'zoom-in', 'zoom-out'];\nexport var AUDIO_VIDEO = ['audio description', 'backward', 'circle', 'circle outline', 'closed captioning', 'closed captioning outline', 'compress', 'eject', 'expand', 'expand arrows alternate', 'fast backward', 'fast forward', 'file audio', 'file audio outline', 'file video', 'file video outline', 'film', 'forward', 'headphones', 'microphone', 'microphone slash', 'music', 'pause', 'pause circle', 'pause circle outline', 'phone volume', 'play', 'play circle', 'play circle outline', 'podcast', 'random', 'redo', 'redo alternate', 'rss', 'rss square', 'step backward', 'step forward', 'stop', 'stop circle', 'stop circle outline', 'sync', 'sync alternate', 'undo', 'undo alternate', 'video', 'volume down', 'volume off', 'volume up'];\nexport var BUSINESS = ['address book', 'address book outline', 'address card', 'address card outline', 'archive', 'balance scale', 'birthday cake', 'book', 'briefcase', 'building', 'building outline', 'bullhorn', 'bullseye', 'calculator', 'calendar', 'calendar outline', 'calendar alternate', 'calendar alternate outline', 'certificate', 'chart area', 'chart bar', 'chart bar outline', 'chart line', 'chart pie', 'clipboard', 'clipboard outline', 'coffee', 'columns', 'compass', 'compass outline', 'copy', 'copy outline', 'copyright', 'copyright outline', 'cut', 'edit', 'edit outline', 'envelope', 'envelope outline', 'envelope open', 'envelope open outline', 'envelope square', 'eraser', 'fax', 'file', 'file outline', 'file alternate', 'file alternate outline', 'folder', 'folder outline', 'folder open', 'folder open outline', 'globe', 'industry', 'paperclip', 'paste', 'pen square', 'pencil alternate', 'percent', 'phone', 'phone square', 'phone volume', 'registered', 'registered outline', 'save', 'save outline', 'sitemap', 'sticky note', 'sticky note outline', 'suitcase', 'table', 'tag', 'tags', 'tasks', 'thumbtack', 'trademark'];\nexport var CHESS = ['chess', 'chess bishop', 'chess board', 'chess king', 'chess knight', 'chess pawn', 'chess queen', 'chess rook', 'square full'];\nexport var CODE = ['archive', 'barcode', 'bath', 'bug', 'code', 'code branch', 'coffee', 'file', 'file outline', 'file alternate', 'file alternate outline', 'file code', 'file code outline', 'filter', 'fire extinguisher', 'folder', 'folder outline', 'folder open', 'folder open outline', 'keyboard', 'keyboard outline', 'microchip', 'qrcode', 'shield alternate', 'sitemap', 'terminal', 'user secret', 'window close', 'window close outline', 'window maximize', 'window maximize outline', 'window minimize', 'window minimize outline', 'window restore', 'window restore outline'];\nexport var COMMUNICATION = ['address book', 'address book outline', 'address card', 'address card outline', 'american sign language interpreting', 'assistive listening systems', 'at', 'bell', 'bell outline', 'bell slash', 'bell slash outline', 'bullhorn', 'comment', 'comment outline', 'comment alternate', 'comment alternate outline', 'comments', 'comments outline', 'envelope', 'envelope outline', 'envelope open', 'envelope open outline', 'envelope square', 'fax', 'inbox', 'language', 'microphone', 'microphone slash', 'mobile', 'mobile alternate', 'paper plane', 'paper plane outline', 'phone', 'phone square', 'phone volume', 'rss', 'rss square', 'tty', 'wifi'];\nexport var COMPUTERS = ['desktop', 'download', 'hdd', 'hdd outline', 'headphones', 'keyboard', 'keyboard outline', 'laptop', 'microchip', 'mobile', 'mobile alternate', 'plug', 'power off', 'print', 'save', 'save outline', 'server', 'tablet', 'tablet alternate', 'tv', 'upload'];\nexport var CURRENCY = ['dollar sign', 'euro sign', 'lira sign', 'money bill alternate', 'money bill alternate outline', 'pound sign', 'ruble sign', 'rupee sign', 'shekel sign', 'won sign', 'yen sign'];\nexport var DATE_TIME = ['bell', 'bell outline', 'bell slash', 'bell slash outline', 'calendar', 'calendar outline', 'calendar alternate', 'calendar alternate outline', 'calendar check', 'calendar check outline', 'calendar minus', 'calendar minus outline', 'calendar plus', 'calendar plus outline', 'calendar times', 'calendar times outline', 'clock', 'clock outline', 'hourglass', 'hourglass outline', 'hourglass end', 'hourglass half', 'hourglass start', 'stopwatch'];\nexport var DESIGN = ['adjust', 'clone', 'clone outline', 'copy', 'copy outline', 'crop', 'crosshairs', 'cut', 'edit', 'edit outline', 'eraser', 'eye', 'eye dropper', 'eye slash', 'eye slash outline', 'object group', 'object group outline', 'object ungroup', 'object ungroup outline', 'paint brush', 'paste', 'pencil alternate', 'save', 'save outline', 'tint'];\nexport var EDITORS = ['align center', 'align justify', 'align left', 'align right', 'bold', 'clipboard', 'clipboard outline', 'clone', 'clone outline', 'columns', 'copy', 'copy outline', 'cut', 'edit', 'edit outline', 'eraser', 'file', 'file outline', 'file alternate', 'file alternate outline', 'font', 'heading', 'i cursor', 'indent', 'italic', 'linkify', 'list', 'list alternate', 'list alternate outline', 'list ol', 'list ul', 'outdent', 'paper plane', 'paper plane outline', 'paperclip', 'paragraph', 'paste', 'pencil alternate', 'print', 'quote left', 'quote right', 'redo', 'redo alternate', 'reply', 'reply all', 'share', 'strikethrough', 'subscript', 'superscript', 'sync', 'sync alternate', 'table', 'tasks', 'text height', 'text width', 'th', 'th large', 'th list', 'trash', 'trash alternate', 'trash alternate outline', 'underline', 'undo', 'undo alternate', 'unlink'];\nexport var FILES = ['archive', 'clone', 'clone outline', 'copy', 'copy outline', 'cut', 'file', 'file outline', 'file alternate', 'file alternate outline', 'file archive', 'file archive outline', 'file audio', 'file audio outline', 'file code', 'file code outline', 'file excel', 'file excel outline', 'file image', 'file image outline', 'file pdf', 'file pdf outline', 'file powerpoint', 'file powerpoint outline', 'file video', 'file video outline', 'file word', 'file word outline', 'folder', 'folder outline', 'folder open', 'folder open outline', 'paste', 'save', 'save outline', 'sticky note', 'sticky note outline'];\nexport var GENDERS = ['genderless', 'mars', 'mars double', 'mars stroke', 'mars stroke horizontal', 'mars stroke vertical', 'mercury', 'neuter', 'transgender', 'transgender alternate', 'venus', 'venus double', 'venus mars'];\nexport var HANDS_GESTURES = ['hand lizard', 'hand lizard outline', 'hand paper', 'hand paper outline', 'hand peace', 'hand peace outline', 'hand point down', 'hand point down outline', 'hand point left', 'hand point left outline', 'hand point right', 'hand point right outline', 'hand point up', 'hand point up outline', 'hand pointer', 'hand pointer outline', 'hand rock', 'hand rock outline', 'hand scissors', 'hand scissors outline', 'hand spock', 'hand spock outline', 'handshake', 'handshake outline', 'thumbs down', 'thumbs down outline', 'thumbs up', 'thumbs up outline'];\nexport var HEALTH = ['ambulance', 'h square', 'heart', 'heart outline', 'heartbeat', 'hospital', 'hospital outline', 'medkit', 'plus square', 'plus square outline', 'stethoscope', 'user md', 'wheelchair'];\nexport var IMAGES = ['adjust', 'bolt', 'camera', 'camera retro', 'clone', 'clone outline', 'compress', 'expand', 'eye', 'eye dropper', 'eye slash', 'eye slash outline', 'file image', 'file image outline', 'film', 'id badge', 'id badge outline', 'id card', 'id card outline', 'image', 'image outline', 'images', 'images outline', 'sliders horizontal', 'tint'];\nexport var INTERFACES = ['ban', 'barcode', 'bars', 'beer', 'bell', 'bell outline', 'bell slash', 'bell slash outline', 'bug', 'bullhorn', 'bullseye', 'calculator', 'calendar', 'calendar outline', 'calendar alternate', 'calendar alternate outline', 'calendar check', 'calendar check outline', 'calendar minus', 'calendar minus outline', 'calendar plus', 'calendar plus outline', 'calendar times', 'calendar times outline', 'certificate', 'check', 'check circle', 'check circle outline', 'check square', 'check square outline', 'circle', 'circle outline', 'clipboard', 'clipboard outline', 'clone', 'clone outline', 'cloud', 'cloud download', 'cloud upload', 'coffee', 'cog', 'cogs', 'copy', 'copy outline', 'cut', 'database', 'dot circle', 'dot circle outline', 'download', 'edit', 'edit outline', 'ellipsis horizontal', 'ellipsis vertical', 'envelope', 'envelope outline', 'envelope open', 'envelope open outline', 'eraser', 'exclamation', 'exclamation circle', 'exclamation triangle', 'external alternate', 'external square alternate', 'eye', 'eye slash', 'eye slash outline', 'file', 'file outline', 'file alternate', 'file alternate outline', 'filter', 'flag', 'flag outline', 'flag checkered', 'folder', 'folder outline', 'folder open', 'folder open outline', 'frown', 'frown outline', 'hashtag', 'heart', 'heart outline', 'history', 'home', 'i cursor', 'info', 'info circle', 'language', 'magic', 'meh', 'meh outline', 'microphone', 'microphone slash', 'minus', 'minus circle', 'minus square', 'minus square outline', 'paste', 'pencil alternate', 'plus', 'plus circle', 'plus square', 'plus square outline', 'qrcode', 'question', 'question circle', 'question circle outline', 'quote left', 'quote right', 'redo', 'redo alternate', 'reply', 'reply all', 'rss', 'rss square', 'save', 'save outline', 'search', 'search minus', 'search plus', 'share', 'share alternate', 'share alternate square', 'share square', 'share square outline', 'shield alternate', 'sign-in', 'sign-out', 'signal', 'sitemap', 'sliders horizontal', 'smile', 'smile outline', 'sort', 'sort alphabet down', 'sort alphabet up', 'sort amount down', 'sort amount up', 'sort down', 'sort numeric down', 'sort numeric up', 'sort up', 'star', 'star outline', 'star half', 'star half outline', 'sync', 'sync alternate', 'thumbs down', 'thumbs down outline', 'thumbs up', 'thumbs up outline', 'times', 'times circle', 'times circle outline', 'toggle off', 'toggle on', 'trash', 'trash alternate', 'trash alternate outline', 'trophy', 'undo', 'undo alternate', 'upload', 'user', 'user outline', 'user circle', 'user circle outline', 'wifi'];\nexport var LOGISTICS = ['box', 'boxes', 'clipboard check', 'clipboard list', 'dolly', 'dolly flatbed', 'pallet', 'shipping fast', 'truck', 'warehouse'];\nexport var MAPS = ['ambulance', 'anchor', 'balance scale', 'bath', 'bed', 'beer', 'bell', 'bell outline', 'bell slash', 'bell slash outline', 'bicycle', 'binoculars', 'birthday cake', 'blind', 'bomb', 'book', 'bookmark', 'bookmark outline', 'briefcase', 'building', 'building outline', 'car', 'coffee', 'crosshairs', 'dollar sign', 'eye', 'eye slash', 'eye slash outline', 'fighter jet', 'fire', 'fire extinguisher', 'flag', 'flag outline', 'flag checkered', 'flask', 'gamepad', 'gavel', 'gift', 'glass martini', 'globe', 'graduation cap', 'h square', 'heart', 'heart outline', 'heartbeat', 'home', 'hospital', 'hospital outline', 'image', 'image outline', 'images', 'images outline', 'industry', 'info', 'info circle', 'key', 'leaf', 'lemon', 'lemon outline', 'life ring', 'life ring outline', 'lightbulb', 'lightbulb outline', 'location arrow', 'low vision', 'magnet', 'male', 'map', 'map outline', 'map marker', 'map marker alternate', 'map pin', 'map signs', 'medkit', 'money bill alternate', 'money bill alternate outline', 'motorcycle', 'music', 'newspaper', 'newspaper outline', 'paw', 'phone', 'phone square', 'phone volume', 'plane', 'plug', 'plus', 'plus square', 'plus square outline', 'print', 'recycle', 'road', 'rocket', 'search', 'search minus', 'search plus', 'ship', 'shopping bag', 'shopping basket', 'shopping cart', 'shower', 'street view', 'subway', 'suitcase', 'tag', 'tags', 'taxi', 'thumbtack', 'ticket alternate', 'tint', 'train', 'tree', 'trophy', 'truck', 'tty', 'umbrella', 'university', 'utensil spoon', 'utensils', 'wheelchair', 'wifi', 'wrench'];\nexport var MEDICAL = ['ambulance', 'band aid', 'dna', 'first aid', 'heart', 'heart outline', 'heartbeat', 'hospital', 'hospital outline', 'hospital symbol', 'pills', 'plus', 'stethoscope', 'syringe', 'thermometer', 'user md', 'weight'];\nexport var OBJECTS = ['ambulance', 'anchor', 'archive', 'balance scale', 'bath', 'bed', 'beer', 'bell', 'bell outline', 'bicycle', 'binoculars', 'birthday cake', 'bomb', 'book', 'bookmark', 'bookmark outline', 'briefcase', 'bug', 'building', 'building outline', 'bullhorn', 'bullseye', 'bus', 'calculator', 'calendar', 'calendar outline', 'calendar alternate', 'calendar alternate outline', 'camera', 'camera retro', 'car', 'clipboard', 'clipboard outline', 'cloud', 'coffee', 'cog', 'cogs', 'compass', 'compass outline', 'copy', 'copy outline', 'cube', 'cubes', 'cut', 'envelope', 'envelope outline', 'envelope open', 'envelope open outline', 'eraser', 'eye', 'eye dropper', 'fax', 'fighter jet', 'file', 'file outline', 'file alternate', 'file alternate outline', 'film', 'fire', 'fire extinguisher', 'flag', 'flag outline', 'flag checkered', 'flask', 'futbol', 'futbol outline', 'gamepad', 'gavel', 'gem', 'gem outline', 'gift', 'glass martini', 'globe', 'graduation cap', 'hdd', 'hdd outline', 'headphones', 'heart', 'heart outline', 'home', 'hospital', 'hospital outline', 'hourglass', 'hourglass outline', 'image', 'image outline', 'images', 'images outline', 'industry', 'key', 'keyboard', 'keyboard outline', 'laptop', 'leaf', 'lemon', 'lemon outline', 'life ring', 'life ring outline', 'lightbulb', 'lightbulb outline', 'lock', 'lock open', 'magic', 'magnet', 'map', 'map outline', 'map marker', 'map marker alternate', 'map pin', 'map signs', 'medkit', 'microchip', 'microphone', 'mobile', 'mobile alternate', 'money bill alternate', 'money bill alternate outline', 'moon', 'moon outline', 'motorcycle', 'newspaper', 'newspaper outline', 'paint brush', 'paper plane', 'paper plane outline', 'paperclip', 'paste', 'paw', 'pencil alternate', 'phone', 'plane', 'plug', 'print', 'puzzle piece', 'road', 'rocket', 'save', 'save outline', 'search', 'shield alternate', 'shopping bag', 'shopping basket', 'shopping cart', 'shower', 'snowflake', 'snowflake outline', 'space shuttle', 'star', 'star outline', 'sticky note', 'sticky note outline', 'stopwatch', 'subway', 'suitcase', 'sun', 'sun outline', 'tablet', 'tablet alternate', 'tachometer alternate', 'tag', 'tags', 'taxi', 'thumbtack', 'ticket alternate', 'train', 'trash', 'trash alternate', 'trash alternate outline', 'tree', 'trophy', 'truck', 'tv', 'umbrella', 'university', 'unlock', 'unlock alternate', 'utensil spoon', 'utensils', 'wheelchair', 'wrench'];\nexport var PAYMENTS_SHOPPING = ['bell', 'bell outline', 'bookmark', 'bookmark outline', 'bullhorn', 'camera', 'camera retro', 'cart arrow down', 'cart plus', 'certificate', 'credit card', 'credit card outline', 'gem', 'gem outline', 'gift', 'handshake', 'handshake outline', 'heart', 'heart outline', 'key', 'shopping bag', 'shopping basket', 'shopping cart', 'star', 'star outline', 'tag', 'tags', 'thumbs down', 'thumbs down outline', 'thumbs up', 'thumbs up outline', 'trophy'];\nexport var SHAPES = ['bookmark', 'bookmark outline', 'calendar', 'calendar outline', 'certificate', 'circle', 'circle outline', 'cloud', 'comment', 'comment outline', 'file', 'file outline', 'folder', 'folder outline', 'heart', 'heart outline', 'map marker', 'play', 'square', 'square outline', 'star', 'star outline'];\nexport var SPINNERS = ['asterisk', 'certificate', 'circle notch', 'cog', 'compass', 'compass outline', 'crosshairs', 'life ring', 'life ring outline', 'snowflake', 'snowflake outline', 'spinner', 'sun', 'sun outline', 'sync'];\nexport var SPORTS = ['baseball ball', 'basketball ball', 'bowling ball', 'football ball', 'futbol', 'futbol outline', 'golf ball', 'hockey puck', 'quidditch', 'table tennis', 'volleyball ball'];\nexport var STATUS = ['ban', 'battery empty', 'battery full', 'battery half', 'battery quarter', 'battery three quarters', 'bell', 'bell outline', 'bell slash', 'bell slash outline', 'calendar', 'calendar outline', 'calendar alternate', 'calendar alternate outline', 'calendar check', 'calendar check outline', 'calendar minus', 'calendar minus outline', 'calendar plus', 'calendar plus outline', 'calendar times', 'calendar times outline', 'cart arrow down', 'cart plus', 'exclamation', 'exclamation circle', 'exclamation triangle', 'eye', 'eye slash', 'eye slash outline', 'file', 'file outline', 'file alternate', 'file alternate outline', 'folder', 'folder outline', 'folder open', 'folder open outline', 'info', 'info circle', 'lock', 'lock open', 'minus', 'minus circle', 'minus square', 'minus square outline', 'plus', 'plus circle', 'plus square', 'plus square outline', 'question', 'question circle', 'question circle outline', 'shield alternate', 'shopping cart', 'sign in alternate', 'sign out alternate', 'thermometer empty', 'thermometer full', 'thermometer half', 'thermometer quarter', 'thermometer three quarters', 'thumbs down', 'thumbs down outline', 'thumbs up', 'thumbs up outline', 'toggle off', 'toggle on', 'unlock', 'unlock alternate'];\nexport var USERS_PEOPLE = ['address book', 'address book outline', 'address card', 'address card outline', 'bed', 'blind', 'child', 'female', 'frown', 'frown outline', 'id badge', 'id badge outline', 'id card', 'id card outline', 'male', 'meh', 'meh outline', 'power off', 'smile', 'smile outline', 'street view', 'user', 'user outline', 'user circle', 'user circle outline', 'user md', 'user plus', 'user secret', 'user times', 'users', 'wheelchair'];\nexport var VEHICLES = ['ambulance', 'bicycle', 'bus', 'car', 'fighter jet', 'motorcycle', 'paper plane', 'paper plane outline', 'plane', 'rocket', 'ship', 'shopping cart', 'space shuttle', 'subway', 'taxi', 'train', 'truck', 'wheelchair'];\nexport var WRITING = ['archive', 'book', 'bookmark', 'bookmark outline', 'edit', 'edit outline', 'envelope', 'envelope outline', 'envelope open', 'envelope open outline', 'eraser', 'file', 'file outline', 'file alternate', 'file alternate outline', 'folder', 'folder outline', 'folder open', 'folder open outline', 'keyboard', 'keyboard outline', 'newspaper', 'newspaper outline', 'paper plane', 'paper plane outline', 'paperclip', 'paragraph', 'pen square', 'pencil alternate', 'quote left', 'quote right', 'sticky note', 'sticky note outline', 'thumbtack'];\nexport var BRANDS = ['500px', 'accessible', 'accusoft', 'adn', 'adversal', 'affiliatetheme', 'algolia', 'amazon', 'amazon pay', 'amilia', 'android', 'angellist', 'angrycreative', 'angular', 'app store', 'app store ios', 'apper', 'apple', 'apple pay', 'asymmetrik', 'audible', 'autoprefixer', 'avianex', 'aviato', 'aws', 'bandcamp', 'behance', 'behance square', 'bimobject', 'bitbucket', 'bitcoin', 'bity', 'black tie', 'blackberry', 'blogger', 'blogger b', 'bluetooth', 'bluetooth b', 'btc', 'buromobelexperte', 'buysellads', 'cc amazon pay', 'cc amex', 'cc apple pay', 'cc diners club', 'cc discover', 'cc jcb', 'cc mastercard', 'cc paypal', 'cc stripe', 'cc visa', 'centercode', 'chrome', 'cloudscale', 'cloudsmith', 'cloudversify', 'codepen', 'codiepie', 'connectdevelop', 'contao', 'cpanel', 'creative commons', 'css3', 'css3 alternate', 'cuttlefish', 'd and d', 'dashcube', 'delicious', 'deploydog', 'deskpro', 'deviantart', 'digg', 'digital ocean', 'discord', 'discourse', 'dochub', 'docker', 'draft2digital', 'dribbble', 'dribbble square', 'dropbox', 'drupal', 'dyalog', 'earlybirds', 'edge', 'elementor', 'ember', 'empire', 'envira', 'erlang', 'ethereum', 'etsy', 'expeditedssl', 'facebook', 'facebook f', 'facebook messenger', 'facebook square', 'firefox', 'first order', 'firstdraft', 'flickr', 'flipboard', 'fly', 'font awesome', 'font awesome alternate', 'font awesome flag', 'fonticons', 'fonticons fi', 'fort awesome', 'fort awesome alternate', 'forumbee', 'foursquare', 'free code camp', 'freebsd', 'get pocket', 'gg', 'gg circle', 'git', 'git square', 'github', 'github alternate', 'github square', 'gitkraken', 'gitlab', 'gitter', 'glide', 'glide g', 'gofore', 'goodreads', 'goodreads g', 'google', 'google drive', 'google play', 'google plus', 'google plus g', 'google plus square', 'google wallet', 'gratipay', 'grav', 'gripfire', 'grunt', 'gulp', 'hacker news', 'hacker news square', 'hips', 'hire a helper', 'hooli', 'hotjar', 'houzz', 'html5', 'hubspot', 'imdb', 'instagram', 'internet explorer', 'ioxhost', 'itunes', 'itunes note', 'jenkins', 'joget', 'joomla', 'js', 'js square', 'jsfiddle', 'keycdn', 'kickstarter', 'kickstarter k', 'korvue', 'laravel', 'lastfm', 'lastfm square', 'leanpub', 'less', 'linechat', 'linkedin', 'linkedin alternate', 'linode', 'linux', 'lyft', 'magento', 'maxcdn', 'medapps', 'medium', 'medium m', 'medrt', 'meetup', 'microsoft', 'mix', 'mixcloud', 'mizuni', 'modx', 'monero', 'napster', 'nintendo switch', 'node', 'node js', 'npm', 'ns8', 'nutritionix', 'odnoklassniki', 'odnoklassniki square', 'opencart', 'openid', 'opera', 'optin monster', 'osi', 'page4', 'pagelines', 'palfed', 'patreon', 'paypal', 'periscope', 'phabricator', 'phoenix framework', 'php', 'pied piper', 'pied piper alternate', 'pied piper pp', 'pinterest', 'pinterest p', 'pinterest square', 'playstation', 'product hunt', 'pushed', 'python', 'qq', 'quinscape', 'quora', 'ravelry', 'react', 'rebel', 'redriver', 'reddit', 'reddit alien', 'reddit square', 'rendact', 'renren', 'replyd', 'resolving', 'rocketchat', 'rockrms', 'safari', 'sass', 'schlix', 'scribd', 'searchengin', 'sellcast', 'sellsy', 'servicestack', 'shirtsinbulk', 'simplybuilt', 'sistrix', 'skyatlas', 'skype', 'slack', 'slack hash', 'slideshare', 'snapchat', 'snapchat ghost', 'snapchat square', 'soundcloud', 'speakap', 'spotify', 'stack exchange', 'stack overflow', 'staylinked', 'steam', 'steam square', 'steam symbol', 'sticker mule', 'strava', 'stripe', 'stripe s', 'studiovinari', 'stumbleupon', 'stumbleupon circle', 'superpowers', 'supple', 'telegram', 'telegram plane', 'tencent weibo', 'themeisle', 'trello', 'tripadvisor', 'tumblr', 'tumblr square', 'twitch', 'twitter', 'twitter square', 'typo3', 'uber', 'uikit', 'uniregistry', 'untappd', 'usb', 'ussunnah', 'vaadin', 'viacoin', 'viadeo', 'viadeo square', 'viber', 'vimeo', 'vimeo square', 'vimeo v', 'vine', 'vk', 'vnv', 'vuejs', 'wechat', 'weibo', 'weixin', 'whatsapp', 'whatsapp square', 'whmcs', 'wikipedia w', 'windows', 'wordpress', 'wordpress simple', 'wpbeginner', 'wpexplorer', 'wpforms', 'xbox', 'xing', 'xing square', 'y combinator', 'yahoo', 'yandex', 'yandex international', 'yelp', 'yoast', 'youtube', 'youtube square'];\nexport var ICONS = _uniq([].concat(ACCESSIBILITY, ARROWS, AUDIO_VIDEO, BUSINESS, CHESS, CODE, COMMUNICATION, COMPUTERS, CURRENCY, DATE_TIME, DESIGN, EDITORS, FILES, GENDERS, HANDS_GESTURES, HEALTH, IMAGES, INTERFACES, LOGISTICS, MAPS, MEDICAL, OBJECTS, PAYMENTS_SHOPPING, SHAPES, SPINNERS, SPORTS, STATUS, USERS_PEOPLE, VEHICLES, WRITING, BRANDS));\nexport var ICON_ALIASES = ['chess rock', 'ordered list', 'unordered list', 'user doctor', 'shield', 'puzzle', 'add circle', 'add square', 'add to calendar', 'add to cart', 'add user', 'add', 'alarm mute', 'alarm', 'ald', 'als', 'announcement', 'area chart', 'area graph', 'arrow down cart', 'asexual', 'asl interpreting', 'asl', 'assistive listening devices', 'attach', 'attention', 'balance', 'bar', 'bathtub', 'battery four', 'battery high', 'battery low', 'battery one', 'battery three', 'battery two', 'battery zero', 'birthday', 'block layout', 'bluetooth alternative', 'broken chain', 'browser', 'call square', 'call', 'cancel', 'cart', 'cc', 'chain', 'chat', 'checked calendar', 'checkmark', 'circle notched', 'close', 'cny', 'cocktail', 'commenting', 'computer', 'configure', 'content', 'deafness', 'delete calendar', 'delete', 'detective', 'discussions', 'doctor', 'dollar', 'dont', 'drivers license', 'dropdown', 'emergency', 'envira gallery', 'erase', 'eur', 'euro', 'eyedropper', 'factory', 'favorite', 'feed', 'female homosexual', 'file text', 'file text outline', 'find', 'first aid', 'fork', 'game', 'gay', 'gbp', 'google plus circle', 'google plus official', 'grab', 'graduation', 'grid layout', 'group', 'h', 'hand victory', 'handicap', 'hard of hearing', 'header', 'help circle', 'help', 'heterosexual', 'hide', 'hotel', 'hourglass four', 'hourglass full', 'hourglass one', 'hourglass three', 'hourglass two', 'idea', 'ils', 'in cart', 'inr', 'intergender', 'intersex', 'jpy', 'krw', 'lab', 'law', 'legal', 'lesbian', 'lightning', 'like', 'line graph', 'linkedin square', 'linkify', 'lira', 'list layout', 'magnify', 'mail forward', 'mail outline', 'mail square', 'mail', 'male homosexual', 'man', 'marker', 'mars alternate', 'mars horizontal', 'mars vertical', 'microsoft edge', 'military', 'ms edge', 'mute', 'new pied piper', 'non binary transgender', 'numbered list', 'options', 'other gender horizontal', 'other gender vertical', 'other gender', 'payment', 'paypal card', 'pencil square', 'photo', 'picture', 'pie chart', 'pie graph', 'pied piper hat', 'pin', 'plus cart', 'point', 'pointing down', 'pointing left', 'pointing right', 'pointing up', 'pound', 'power cord', 'power', 'privacy', 'r circle', 'rain', 'record', 'refresh', 'remove circle', 'remove from calendar', 'remove user', 'remove', 'repeat', 'rmb', 'rouble', 'rub', 'ruble', 'rupee', 's15', 'selected radio', 'send', 'setting', 'settings', 'shekel', 'sheqel', 'shipping', 'shop', 'shuffle', 'shutdown', 'sidebar', 'signing', 'signup', 'sliders', 'soccer', 'sort alphabet ascending', 'sort alphabet descending', 'sort ascending', 'sort content ascending', 'sort content descending', 'sort descending', 'sort numeric ascending', 'sort numeric descending', 'sound', 'spy', 'stripe card', 'student', 'talk', 'target', 'teletype', 'television', 'text cursor', 'text telephone', 'theme', 'thermometer', 'thumb tack', 'time', 'tm', 'toggle down', 'toggle left', 'toggle right', 'toggle up', 'translate', 'travel', 'treatment', 'triangle down', 'triangle left', 'triangle right', 'triangle up', 'try', 'unhide', 'unlinkify', 'unmute', 'usd', 'user cancel', 'user close', 'user delete', 'user x', 'vcard', 'video camera', 'video play', 'volume control phone', 'wait', 'warning circle', 'warning sign', 'warning', 'wi-fi', 'winner', 'wizard', 'woman', 'won', 'wordpress beginner', 'wordpress forms', 'world', 'write square', 'x', 'yen', 'zip', 'zoom in', 'zoom out', 'zoom', 'bitbucket square', 'checkmark box', 'circle thin', 'cloud download', 'cloud upload', 'compose', 'conversation', 'credit card alternative', 'currency', 'dashboard', 'diamond', 'disk', 'exchange', 'external share', 'external square', 'external', 'facebook official', 'food', 'hourglass zero', 'level down', 'level up', 'log out', 'meanpath', 'money', 'move', 'pencil', 'protect', 'radio', 'remove bookmark', 'resize horizontal', 'resize vertical', 'sign in', 'sign out', 'spoon', 'star half empty', 'star half full', 'ticket', 'times rectangle', 'write', 'youtube play'];\nexport var ICONS_AND_ALIASES = _uniq([].concat(ICONS, ICON_ALIASES)); // Some icon names are not part of icons.css.\n// These are only valid as children of other components.\n// Their CSS rules are defined by a specific component's CSS.\n// We don't want to show name warnings for those usages so we add them as valid names here.\n\nexport var COMPONENT_CONTEXT_SPECIFIC_ICONS = ['left dropdown' // nested dropdown menu direction icon\n];\nexport var ALL_ICONS_IN_ALL_CONTEXTS = _uniq([].concat(ICONS_AND_ALIASES, COMPONENT_CONTEXT_SPECIFIC_ICONS));","import _find from \"lodash/find\";\nimport _some from \"lodash/some\";\nimport { Children } from 'react';\n/**\n * Determine if child by type exists in children.\n * @param {Object} children The children prop of a component.\n * @param {string|Function} type An html tag name string or React component.\n * @returns {Boolean}\n */\n\nexport var someByType = function someByType(children, type) {\n  return _some(Children.toArray(children), {\n    type: type\n  });\n};\n/**\n * Find child by type.\n * @param {Object} children The children prop of a component.\n * @param {string|Function} type An html tag name string or React component.\n * @returns {undefined|Object}\n */\n\nexport var findByType = function findByType(children, type) {\n  return _find(Children.toArray(children), {\n    type: type\n  });\n};\n/**\n * Tests if children are nil in React and Preact.\n * @param {Object} children The children prop of a component.\n * @returns {Boolean}\n */\n\nexport var isNil = function isNil(children) {\n  return children === null || children === undefined || Array.isArray(children) && children.length === 0;\n};","import { numberToWord } from './numberToWord';\n/*\n * There are 3 prop patterns used to build up the className for a component.\n * Each utility here is meant for use in a classnames() argument.\n *\n * There is no util for valueOnly() because it would simply return val.\n * Use the prop value inline instead.\n *   <Label size='big' />\n *   <div class=\"ui big label\"></div>\n */\n\n/**\n * Props where only the prop key is used in the className.\n * @param {*} val A props value\n * @param {string} key A props key\n *\n * @example\n * <Label tag />\n * <div class=\"ui tag label\"></div>\n */\n\nexport var useKeyOnly = function useKeyOnly(val, key) {\n  return val && key;\n};\n/**\n * Props that require both a key and value to create a className.\n * @param {*} val A props value\n * @param {string} key A props key\n *\n * @example\n * <Label corner='left' />\n * <div class=\"ui left corner label\"></div>\n */\n\nexport var useValueAndKey = function useValueAndKey(val, key) {\n  return val && val !== true && val + \" \" + key;\n};\n/**\n * Props whose key will be used in className, or value and key.\n * @param {*} val A props value\n * @param {string} key A props key\n *\n * @example Key Only\n * <Label pointing />\n * <div class=\"ui pointing label\"></div>\n *\n * @example Key and Value\n * <Label pointing='left' />\n * <div class=\"ui left pointing label\"></div>\n */\n\nexport var useKeyOrValueAndKey = function useKeyOrValueAndKey(val, key) {\n  return val && (val === true ? key : val + \" \" + key);\n}; //\n// Prop to className exceptions\n//\n\n/**\n * The \"multiple\" prop implements control of visibility and reserved classes for Grid subcomponents.\n *\n * @param {*} val The value of the \"multiple\" prop\n * @param {*} key A props key\n *\n * @example\n * <Grid.Row only='mobile' />\n * <Grid.Row only='mobile tablet' />\n * <div class=\"mobile only row\"></div>\n * <div class=\"mobile only tablet only row\"></div>\n */\n\nexport var useMultipleProp = function useMultipleProp(val, key) {\n  if (!val || val === true) return null;\n  return val.replace('large screen', 'large-screen').replace(/ vertically/g, '-vertically').split(' ').map(function (prop) {\n    return prop.replace('-', ' ') + \" \" + key;\n  }).join(' ');\n};\n/**\n * The \"textAlign\" prop follows the useValueAndKey except when the value is \"justified'.\n * In this case, only the class \"justified\" is used, ignoring the \"aligned\" class.\n * @param {*} val The value of the \"textAlign\" prop\n *\n * @example\n * <Container textAlign='justified' />\n * <div class=\"ui justified container\"></div>\n *\n * @example\n * <Container textAlign='left' />\n * <div class=\"ui left aligned container\"></div>\n */\n\nexport var useTextAlignProp = function useTextAlignProp(val) {\n  return val === 'justified' ? 'justified' : useValueAndKey(val, 'aligned');\n};\n/**\n * The \"verticalAlign\" prop follows the useValueAndKey.\n *\n * @param {*} val The value of the \"verticalAlign\" prop\n *\n * @example\n * <Grid verticalAlign='middle' />\n * <div class=\"ui middle aligned grid\"></div>\n */\n\nexport var useVerticalAlignProp = function useVerticalAlignProp(val) {\n  return useValueAndKey(val, 'aligned');\n};\n/**\n * Create \"X\", \"X wide\" and \"equal width\" classNames.\n * \"X\" is a numberToWord value and \"wide\" is configurable.\n * @param {*} val The prop value\n * @param {string} [widthClass=''] The class\n * @param {boolean} [canEqual=false] Flag that indicates possibility of \"equal\" value\n *\n * @example\n * <Grid columns='equal' />\n * <div class=\"ui equal width grid\"></div>\n *\n * <Form widths='equal' />\n * <div class=\"ui equal width form\"></div>\n *\n * <FieldGroup widths='equal' />\n * <div class=\"equal width fields\"></div>\n *\n * @example\n * <Grid columns={4} />\n * <div class=\"ui four column grid\"></div>\n */\n\nexport var useWidthProp = function useWidthProp(val, widthClass, canEqual) {\n  if (widthClass === void 0) {\n    widthClass = '';\n  }\n\n  if (canEqual === void 0) {\n    canEqual = false;\n  }\n\n  if (canEqual && val === 'equal') {\n    return 'equal width';\n  }\n\n  var valType = typeof val;\n\n  if ((valType === 'string' || valType === 'number') && widthClass) {\n    return numberToWord(val) + \" \" + widthClass;\n  }\n\n  return numberToWord(val);\n};","import { createFirstPage, createLastItem, createNextItem, createPageFactory, createPrevItem } from './itemFactories';\nimport { createComplexRange, createSimpleRange } from './rangeFactories';\nimport { isSimplePagination, typifyOptions } from './paginationUtils';\n/**\n * @param {object} rawOptions\n * @param {number|string} rawOptions.activePage\n * @param {number|string} rawOptions.boundaryRange Number of always visible pages at the beginning and end.\n * @param {boolean} rawOptions.hideEllipsis Marks if ellipsis should be hidden.\n * @param {number|string} rawOptions.siblingRange Number of always visible pages before and after the current one.\n * @param {number|string} rawOptions.totalPages Total number of pages.\n */\n\nvar createPaginationItems = function createPaginationItems(rawOptions) {\n  var options = typifyOptions(rawOptions);\n  var activePage = options.activePage,\n      totalPages = options.totalPages;\n  var pageFactory = createPageFactory(activePage);\n  var innerRange = isSimplePagination(options) ? createSimpleRange(1, totalPages, pageFactory) : createComplexRange(options, pageFactory);\n  return [createFirstPage(), createPrevItem(activePage)].concat(innerRange, [createNextItem(activePage, totalPages), createLastItem(totalPages)]);\n};\n\nexport default createPaginationItems;","import _default from './createPaginationItems';\nexport { _default as default };","/**\n * @param {number} pageNumber\n * @return {Object}\n */\nexport var createEllipsisItem = function createEllipsisItem(pageNumber) {\n  return {\n    active: false,\n    type: 'ellipsisItem',\n    value: pageNumber\n  };\n};\n/**\n * @return {Object}\n */\n\nexport var createFirstPage = function createFirstPage() {\n  return {\n    active: false,\n    type: 'firstItem',\n    value: 1\n  };\n};\n/**\n * @param {number} activePage\n * @return {Object}\n */\n\nexport var createPrevItem = function createPrevItem(activePage) {\n  return {\n    active: false,\n    type: 'prevItem',\n    value: Math.max(1, activePage - 1)\n  };\n};\n/**\n * @param {number} activePage\n * @return {function}\n */\n\nexport var createPageFactory = function createPageFactory(activePage) {\n  return function (pageNumber) {\n    return {\n      active: activePage === pageNumber,\n      type: 'pageItem',\n      value: pageNumber\n    };\n  };\n};\n/**\n * @param {number} activePage\n * @param {number} totalPages\n * @return {Object}\n */\n\nexport var createNextItem = function createNextItem(activePage, totalPages) {\n  return {\n    active: false,\n    type: 'nextItem',\n    value: Math.min(activePage + 1, totalPages)\n  };\n};\n/**\n * @param {number} totalPages\n * @return {Object}\n */\n\nexport var createLastItem = function createLastItem(totalPages) {\n  return {\n    active: false,\n    type: 'lastItem',\n    value: totalPages\n  };\n};","/**\n * Checks the possibility of using simple range generation, if number of generated pages is equal\n * or greater than total pages to show.\n *\n * @param {object} options\n * @param {number} options.boundaryRange Number of always visible pages at the beginning and end.\n * @param {number} options.siblingRange Number of always visible pages before and after the current one.\n * @param {number} options.totalPages Total number of pages.\n * @return {boolean}\n */\nexport var isSimplePagination = function isSimplePagination(_ref) {\n  var boundaryRange = _ref.boundaryRange,\n      hideEllipsis = _ref.hideEllipsis,\n      siblingRange = _ref.siblingRange,\n      totalPages = _ref.totalPages;\n  var boundaryRangeSize = 2 * boundaryRange;\n  var ellipsisSize = hideEllipsis ? 0 : 2;\n  var siblingRangeSize = 2 * siblingRange;\n  return 1 + ellipsisSize + siblingRangeSize + boundaryRangeSize >= totalPages;\n};\nexport var typifyOptions = function typifyOptions(_ref2) {\n  var activePage = _ref2.activePage,\n      boundaryRange = _ref2.boundaryRange,\n      hideEllipsis = _ref2.hideEllipsis,\n      siblingRange = _ref2.siblingRange,\n      totalPages = _ref2.totalPages;\n  return {\n    activePage: +activePage,\n    boundaryRange: +boundaryRange,\n    hideEllipsis: !!hideEllipsis,\n    siblingRange: +siblingRange,\n    totalPages: +totalPages\n  };\n};","import _range from \"lodash/range\";\nimport _map from \"lodash/map\";\nimport { createInnerPrefix, createInnerSuffix } from './suffixFactories';\nexport var createSimpleRange = function createSimpleRange(start, end, pageFactory) {\n  return _map(_range(start, end + 1), pageFactory);\n};\nexport var createComplexRange = function createComplexRange(options, pageFactory) {\n  var activePage = options.activePage,\n      boundaryRange = options.boundaryRange,\n      hideEllipsis = options.hideEllipsis,\n      siblingRange = options.siblingRange,\n      totalPages = options.totalPages;\n  var ellipsisSize = hideEllipsis ? 0 : 1;\n  var firstGroupEnd = boundaryRange;\n  var firstGroup = createSimpleRange(1, firstGroupEnd, pageFactory);\n  var lastGroupStart = totalPages + 1 - boundaryRange;\n  var lastGroup = createSimpleRange(lastGroupStart, totalPages, pageFactory);\n  var innerGroupStart = Math.min(Math.max(activePage - siblingRange, firstGroupEnd + ellipsisSize + 1), lastGroupStart - ellipsisSize - 2 * siblingRange - 1);\n  var innerGroupEnd = innerGroupStart + 2 * siblingRange;\n  var innerGroup = createSimpleRange(innerGroupStart, innerGroupEnd, pageFactory);\n  return [].concat(firstGroup, [!hideEllipsis && createInnerPrefix(firstGroupEnd, innerGroupStart, pageFactory)], innerGroup, [!hideEllipsis && createInnerSuffix(innerGroupEnd, lastGroupStart, pageFactory)], lastGroup).filter(Boolean);\n};","import { createEllipsisItem } from './itemFactories';\nexport var createInnerPrefix = function createInnerPrefix(firstGroupEnd, innerGroupStart, pageFactory) {\n  var prefixPage = innerGroupStart - 1;\n  var showEllipsis = prefixPage !== firstGroupEnd + 1;\n  var prefixFactory = showEllipsis ? createEllipsisItem : pageFactory;\n  return prefixFactory(prefixPage);\n};\nexport var createInnerSuffix = function createInnerSuffix(innerGroupEnd, lastGroupStart, pageFactory) {\n  var suffixPage = innerGroupEnd + 1;\n  var showEllipsis = suffixPage !== lastGroupStart - 1;\n  var suffixFactory = showEllipsis ? createEllipsisItem : pageFactory;\n  return suffixFactory(suffixPage);\n};","import _difference from \"lodash/fp/difference\";\nimport _trim from \"lodash/fp/trim\";\nimport _isObject from \"lodash/fp/isObject\";\nimport _pick from \"lodash/fp/pick\";\nimport _keys from \"lodash/fp/keys\";\nimport _isPlainObject from \"lodash/fp/isPlainObject\";\nimport _isFunction from \"lodash/fp/isFunction\";\nimport _compact from \"lodash/fp/compact\";\nimport _isNil from \"lodash/fp/isNil\";\nimport _take from \"lodash/fp/take\";\nimport _sortBy from \"lodash/fp/sortBy\";\nimport _sum from \"lodash/fp/sum\";\nimport _min from \"lodash/fp/min\";\nimport _map from \"lodash/fp/map\";\nimport _flow from \"lodash/fp/flow\";\nimport _memoize from \"lodash/fp/memoize\";\nimport PropTypes from 'prop-types';\nimport leven from './leven';\n\nvar typeOf = function typeOf() {\n  var _Object$prototype$toS;\n\n  return (_Object$prototype$toS = Object.prototype.toString).call.apply(_Object$prototype$toS, arguments);\n};\n/**\n * Ensure a prop is a valid DOM node.\n */\n\n\nexport var domNode = function domNode(props, propName) {\n  // skip if prop is undefined\n  if (props[propName] === undefined) return; // short circle for SSR env\n\n  if (typeof Element === 'undefined') return; // skip if prop is valid\n\n  if (props[propName] instanceof Element) return;\n  return new Error(\"Invalid prop \\\"\" + propName + \"\\\" supplied, expected a DOM node.\");\n};\n/**\n * Similar to PropTypes.oneOf but shows closest matches.\n * Word order is ignored allowing `left chevron` to match `chevron left`.\n * Useful for very large lists of options (e.g. Icon name, Flag name, etc.)\n * @param {string[]} suggestions An array of allowed values.\n */\n\nexport var suggest = function suggest(suggestions) {\n  if (!Array.isArray(suggestions)) {\n    throw new Error('Invalid argument supplied to suggest, expected an instance of array.');\n  }\n  /* eslint-disable max-nested-callbacks */\n\n\n  var findBestSuggestions = _memoize(function (str) {\n    var propValueWords = str.split(' ');\n    return _flow(_map(function (suggestion) {\n      var suggestionWords = suggestion.split(' ');\n\n      var propValueScore = _flow(_map(function (x) {\n        return _map(function (y) {\n          return leven(x, y);\n        }, suggestionWords);\n      }), _map(_min), _sum)(propValueWords);\n\n      var suggestionScore = _flow(_map(function (x) {\n        return _map(function (y) {\n          return leven(x, y);\n        }, propValueWords);\n      }), _map(_min), _sum)(suggestionWords);\n\n      return {\n        suggestion: suggestion,\n        score: propValueScore + suggestionScore\n      };\n    }), _sortBy(['score', 'suggestion']), _take(3))(suggestions);\n  });\n  /* eslint-enable max-nested-callbacks */\n  // Convert the suggestions list into a hash map for O(n) lookup times. Ensure\n  // the words in each key are sorted alphabetically so that we have a consistent\n  // way of looking up a value in the map, i.e. we can sort the words in the\n  // incoming propValue and look that up without having to check all permutations.\n\n\n  var suggestionsLookup = suggestions.reduce(function (acc, key) {\n    acc[key.split(' ').sort().join(' ')] = true;\n    return acc;\n  }, {});\n  return function (props, propName, componentName) {\n    var propValue = props[propName]; // skip if prop is undefined or is included in the suggestions\n\n    if (!propValue || suggestionsLookup[propValue]) return; // check if the words were correct but ordered differently.\n    // Since we're matching for classNames we need to allow any word order\n    // to pass validation, e.g. `left chevron` vs `chevron left`.\n\n    var propValueSorted = propValue.split(' ').sort().join(' ');\n    if (suggestionsLookup[propValueSorted]) return; // find best suggestions\n\n    var bestMatches = findBestSuggestions(propValue); // skip if a match scored 0\n\n    if (bestMatches.some(function (x) {\n      return x.score === 0;\n    })) return;\n    return new Error([\"Invalid prop `\" + propName + \"` of value `\" + propValue + \"` supplied to `\" + componentName + \"`.\", \"\\n\\nInstead of `\" + propValue + \"`, did you mean:\", bestMatches.map(function (x) {\n      return \"\\n  - \" + x.suggestion;\n    }).join(''), '\\n'].join(''));\n  };\n};\n/**\n * Disallow other props from being defined with this prop.\n * @param {string[]} disallowedProps An array of props that cannot be used with this prop.\n */\n\nexport var disallow = function disallow(disallowedProps) {\n  return function (props, propName, componentName) {\n    if (!Array.isArray(disallowedProps)) {\n      throw new Error(['Invalid argument supplied to disallow, expected an instance of array.', \" See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(''));\n    } // skip if prop is undefined\n\n\n    if (_isNil(props[propName]) || props[propName] === false) return; // find disallowed props with values\n\n    var disallowed = disallowedProps.reduce(function (acc, disallowedProp) {\n      if (!_isNil(props[disallowedProp]) && props[disallowedProp] !== false) {\n        return [].concat(acc, [disallowedProp]);\n      }\n\n      return acc;\n    }, []);\n\n    if (disallowed.length > 0) {\n      return new Error([\"Prop `\" + propName + \"` in `\" + componentName + \"` conflicts with props: `\" + disallowed.join('`, `') + \"`.\", 'They cannot be defined together, choose one or the other.'].join(' '));\n    }\n  };\n};\n/**\n * Ensure a prop adherers to multiple prop type validators.\n * @param {function[]} validators An array of propType functions.\n */\n\nexport var every = function every(validators) {\n  return function (props, propName, componentName) {\n    for (var _len = arguments.length, rest = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {\n      rest[_key - 3] = arguments[_key];\n    }\n\n    if (!Array.isArray(validators)) {\n      throw new Error(['Invalid argument supplied to every, expected an instance of array.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    }\n\n    var errors = _flow(_map(function (validator) {\n      if (typeof validator !== 'function') {\n        throw new Error(\"every() argument \\\"validators\\\" should contain functions, found: \" + typeOf(validator) + \".\");\n      }\n\n      return validator.apply(void 0, [props, propName, componentName].concat(rest));\n    }), _compact)(validators); // we can only return one error at a time\n\n\n    return errors[0];\n  };\n};\n/**\n * Ensure a prop adherers to at least one of the given prop type validators.\n * @param {function[]} validators An array of propType functions.\n */\n\nexport var some = function some(validators) {\n  return function (props, propName, componentName) {\n    for (var _len2 = arguments.length, rest = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {\n      rest[_key2 - 3] = arguments[_key2];\n    }\n\n    if (!Array.isArray(validators)) {\n      throw new Error(['Invalid argument supplied to some, expected an instance of array.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    }\n\n    var errors = _compact(_map(validators, function (validator) {\n      if (!_isFunction(validator)) {\n        throw new Error(\"some() argument \\\"validators\\\" should contain functions, found: \" + typeOf(validator) + \".\");\n      }\n\n      return validator.apply(void 0, [props, propName, componentName].concat(rest));\n    })); // fail only if all validators failed\n\n\n    if (errors.length === validators.length) {\n      var error = new Error('One of these validators must pass:');\n      error.message += \"\\n\" + _map(errors, function (err, i) {\n        return \"[\" + (i + 1) + \"]: \" + err.message;\n      }).join('\\n');\n      return error;\n    }\n  };\n};\n/**\n * Ensure a validator passes only when a component has a given propsShape.\n * @param {object} propsShape An object describing the prop shape.\n * @param {function} validator A propType function.\n */\n\nexport var givenProps = function givenProps(propsShape, validator) {\n  return function (props, propName, componentName) {\n    for (var _len3 = arguments.length, rest = new Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {\n      rest[_key3 - 3] = arguments[_key3];\n    }\n\n    if (!_isPlainObject(propsShape)) {\n      throw new Error(['Invalid argument supplied to givenProps, expected an object.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    }\n\n    if (typeof validator !== 'function') {\n      throw new Error(['Invalid argument supplied to givenProps, expected a function.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    }\n\n    var shouldValidate = _keys(propsShape).every(function (key) {\n      var val = propsShape[key]; // require propShape validators to pass or prop values to match\n\n      return typeof val === 'function' ? !val.apply(void 0, [props, key, componentName].concat(rest)) : val === props[propName];\n    });\n\n    if (!shouldValidate) return;\n    var error = validator.apply(void 0, [props, propName, componentName].concat(rest));\n\n    if (error) {\n      // poor mans shallow pretty print, prevents JSON circular reference errors\n      var prettyProps = \"{ \" + _keys(_pick(_keys(propsShape), props)).map(function (key) {\n        var val = props[key];\n        var renderedValue = val;\n        if (typeof val === 'string') renderedValue = \"\\\"\" + val + \"\\\"\";else if (Array.isArray(val)) renderedValue = \"[\" + val.join(', ') + \"]\";else if (_isObject(val)) renderedValue = '{...}';\n        return key + \": \" + renderedValue;\n      }).join(', ') + \" }\";\n      error.message = \"Given props \" + prettyProps + \": \" + error.message;\n      return error;\n    }\n  };\n};\n/**\n * Define prop dependencies by requiring other props.\n * @param {string[]} requiredProps An array of required prop names.\n */\n\nexport var demand = function demand(requiredProps) {\n  return function (props, propName, componentName) {\n    if (!Array.isArray(requiredProps)) {\n      throw new Error(['Invalid `requiredProps` argument supplied to require, expected an instance of array.', \" See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(''));\n    } // skip if prop is undefined\n\n\n    if (props[propName] === undefined) return;\n    var missingRequired = requiredProps.filter(function (requiredProp) {\n      return props[requiredProp] === undefined;\n    });\n\n    if (missingRequired.length > 0) {\n      return new Error(\"`\" + propName + \"` prop in `\" + componentName + \"` requires props: `\" + missingRequired.join('`, `') + \"`.\");\n    }\n  };\n};\n/**\n * Ensure an multiple prop contains a string with only possible values.\n * @param {string[]} possible An array of possible values to prop.\n */\n\nexport var multipleProp = function multipleProp(possible) {\n  return function (props, propName, componentName) {\n    if (!Array.isArray(possible)) {\n      throw new Error(['Invalid argument supplied to some, expected an instance of array.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    }\n\n    var propValue = props[propName]; // skip if prop is undefined\n\n    if (_isNil(propValue) || propValue === false) return;\n    var values = propValue.replace('large screen', 'large-screen').replace(/ vertically/g, '-vertically').split(' ').map(function (val) {\n      return _trim(val).replace('-', ' ');\n    });\n\n    var invalid = _difference(values, possible); // fail only if there are invalid values\n\n\n    if (invalid.length > 0) {\n      return new Error(\"`\" + propName + \"` prop in `\" + componentName + \"` has invalid values: `\" + invalid.join('`, `') + \"`.\");\n    }\n  };\n};\n/**\n * Ensure a component can render as a node passed as a prop value in place of children.\n */\n\nexport var contentShorthand = function contentShorthand() {\n  return every([disallow(['children']), PropTypes.node]).apply(void 0, arguments);\n};\n/**\n * Item shorthand is a description of a component that can be a literal,\n * a props object, or an element.\n */\n\nexport var itemShorthand = function itemShorthand() {\n  return every([disallow(['children']), PropTypes.oneOfType([PropTypes.func, PropTypes.node, PropTypes.object, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.object]))])]).apply(void 0, arguments);\n};\n/**\n * Collection shorthand ensures a prop is an array of item shorthand.\n */\n\nexport var collectionShorthand = function collectionShorthand() {\n  return every([disallow(['children']), PropTypes.arrayOf(itemShorthand)]).apply(void 0, arguments);\n};\n/**\n * Show a deprecated warning for component props with a help message and optional validator.\n * @param {string} help A help message to display with the deprecation warning.\n * @param {function} [validator] A propType function.\n */\n\nexport var deprecate = function deprecate(help, validator) {\n  return function (props, propName, componentName) {\n    if (typeof help !== 'string') {\n      throw new Error(['Invalid `help` argument supplied to deprecate, expected a string.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n    } // skip if prop is undefined\n\n\n    if (props[propName] === undefined) return; // deprecation error and help\n\n    var error = new Error(\"The `\" + propName + \"` prop in `\" + componentName + \"` is deprecated.\");\n    if (help) error.message += \" \" + help; // add optional validation error message\n\n    if (validator) {\n      if (typeof validator === 'function') {\n        for (var _len4 = arguments.length, args = new Array(_len4 > 3 ? _len4 - 3 : 0), _key4 = 3; _key4 < _len4; _key4++) {\n          args[_key4 - 3] = arguments[_key4];\n        }\n\n        var validationError = validator.apply(void 0, [props, propName, componentName].concat(args));\n\n        if (validationError) {\n          error.message = error.message + \" \" + validationError.message;\n        }\n      } else {\n        throw new Error(['Invalid argument supplied to deprecate, expected a function.', \"See `\" + propName + \"` prop in `\" + componentName + \"`.\"].join(' '));\n      }\n    }\n\n    return error;\n  };\n};\n/** A checker that matches the React.RefObject type. */\n\nexport var refObject = PropTypes.shape({\n  current: PropTypes.object\n});\n/** A checker that matches the React.Ref type. */\n\nexport var ref = PropTypes.oneOfType([PropTypes.func, refObject]);","import _inRange from \"lodash/inRange\";\nimport _first from \"lodash/first\";\nimport _invoke from \"lodash/invoke\";\nimport _isNil from \"lodash/isNil\";\nimport _some from \"lodash/some\";\n\n/**\n * Determines if a click's coordinates are within the bounds of a node.\n *\n * @see https://github.com/Semantic-Org/Semantic-UI-React/pull/2384\n *\n * @param {object} node - A DOM node.\n * @param {object} e - A SyntheticEvent or DOM Event.\n * @returns {boolean}\n */\nvar doesNodeContainClick = function doesNodeContainClick(node, e) {\n  if (_some([e, node], _isNil)) return false; // if there is an e.target and it is in the document, use a simple node.contains() check\n\n  if (e.target) {\n    _invoke(e.target, 'setAttribute', 'data-suir-click-target', true);\n\n    if (document.querySelector('[data-suir-click-target=true]')) {\n      _invoke(e.target, 'removeAttribute', 'data-suir-click-target');\n\n      return node.contains(e.target);\n    }\n  } // Below logic handles cases where the e.target is no longer in the document.\n  // The result of the click likely has removed the e.target node.\n  // Instead of node.contains(), we'll identify the click by X/Y position.\n  // return early if the event properties aren't available\n  // prevent measuring the node and repainting if we don't need to\n\n\n  var clientX = e.clientX,\n      clientY = e.clientY;\n  if (_some([clientX, clientY], _isNil)) return false; // false if the node is not visible\n\n  var clientRects = node.getClientRects(); // Heads Up!\n  // getClientRects returns a DOMRectList, not an array nor a plain object\n  // We explicitly avoid _.isEmpty and check .length to cover all possible shapes\n\n  if (!node.offsetWidth || !node.offsetHeight || !clientRects || !clientRects.length) return false; // false if the node doesn't have a valid bounding rect\n\n  var _first2 = _first(clientRects),\n      top = _first2.top,\n      bottom = _first2.bottom,\n      left = _first2.left,\n      right = _first2.right;\n\n  if (_some([top, bottom, left, right], _isNil)) return false; // we add a small decimal to the upper bound just to make it inclusive\n  // don't add an whole pixel (1) as the event/node values may be decimal sensitive\n\n  return _inRange(clientY, top, bottom + 0.001) && _inRange(clientX, left, right + 0.001);\n};\n\nexport default doesNodeContainClick;","import { instance } from '@semantic-ui-react/event-stack';\nexport default instance;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _uniq from \"lodash/uniq\";\nimport _isArray from \"lodash/isArray\";\nimport _isPlainObject from \"lodash/isPlainObject\";\nimport _isFunction from \"lodash/isFunction\";\nimport _isNumber from \"lodash/isNumber\";\nimport _isString from \"lodash/isString\";\nimport _isBoolean from \"lodash/isBoolean\";\nimport _isNil from \"lodash/isNil\";\nimport cx from 'clsx';\nimport * as React from 'react'; // ============================================================\n// Factories\n// ============================================================\n\n/**\n * A more robust React.createElement. It can create elements from primitive values.\n *\n * @param {function|string} Component A ReactClass or string\n * @param {function} mapValueToProps A function that maps a primitive value to the Component props\n * @param {string|object|function} val The value to create a ReactElement from\n * @param {Object} [options={}]\n * @param {object} [options.defaultProps={}] Default props object\n * @param {object|function} [options.overrideProps={}] Override props object or function (called with regular props)\n * @param {boolean} [options.autoGenerateKey=true] Whether or not automatic key generation is allowed\n * @returns {object|null}\n */\n\nexport function createShorthand(Component, mapValueToProps, val, options) {\n  if (options === void 0) {\n    options = {};\n  }\n\n  if (typeof Component !== 'function' && typeof Component !== 'string') {\n    throw new Error('createShorthand() Component must be a string or function.');\n  } // short circuit noop values\n\n\n  if (_isNil(val) || _isBoolean(val)) return null;\n\n  var valIsString = _isString(val);\n\n  var valIsNumber = _isNumber(val);\n\n  var valIsFunction = _isFunction(val);\n\n  var valIsReactElement = /*#__PURE__*/React.isValidElement(val);\n\n  var valIsPropsObject = _isPlainObject(val);\n\n  var valIsPrimitiveValue = valIsString || valIsNumber || _isArray(val); // unhandled type return null\n\n  /* eslint-disable no-console */\n\n\n  if (!valIsFunction && !valIsReactElement && !valIsPropsObject && !valIsPrimitiveValue) {\n    if (process.env.NODE_ENV !== 'production') {\n      console.error(['Shorthand value must be a string|number|array|object|ReactElement|function.', ' Use null|undefined|boolean for none', \" Received \" + typeof val + \".\"].join(''));\n    }\n\n    return null;\n  }\n  /* eslint-enable no-console */\n  // ----------------------------------------\n  // Build up props\n  // ----------------------------------------\n\n\n  var _options = options,\n      _options$defaultProps = _options.defaultProps,\n      defaultProps = _options$defaultProps === void 0 ? {} : _options$defaultProps; // User's props\n\n  var usersProps = valIsReactElement && val.props || valIsPropsObject && val || valIsPrimitiveValue && mapValueToProps(val); // Override props\n\n  var _options2 = options,\n      _options2$overridePro = _options2.overrideProps,\n      overrideProps = _options2$overridePro === void 0 ? {} : _options2$overridePro;\n  overrideProps = _isFunction(overrideProps) ? overrideProps(_extends({}, defaultProps, usersProps)) : overrideProps; // Merge props\n\n  /* eslint-disable react/prop-types */\n\n  var props = _extends({}, defaultProps, usersProps, overrideProps); // Merge className\n\n\n  if (defaultProps.className || overrideProps.className || usersProps.className) {\n    var mergedClassesNames = cx(defaultProps.className, overrideProps.className, usersProps.className);\n    props.className = _uniq(mergedClassesNames.split(' ')).join(' ');\n  } // Merge style\n\n\n  if (defaultProps.style || overrideProps.style || usersProps.style) {\n    props.style = _extends({}, defaultProps.style, usersProps.style, overrideProps.style);\n  } // ----------------------------------------\n  // Get key\n  // ----------------------------------------\n  // Use key, childKey, or generate key\n\n\n  if (_isNil(props.key)) {\n    var childKey = props.childKey;\n    var _options3 = options,\n        _options3$autoGenerat = _options3.autoGenerateKey,\n        autoGenerateKey = _options3$autoGenerat === void 0 ? true : _options3$autoGenerat;\n\n    if (!_isNil(childKey)) {\n      // apply and consume the childKey\n      props.key = typeof childKey === 'function' ? childKey(props) : childKey;\n      delete props.childKey;\n    } else if (autoGenerateKey && (valIsString || valIsNumber)) {\n      // use string/number shorthand values as the key\n      props.key = val;\n    }\n  } // ----------------------------------------\n  // Create Element\n  // ----------------------------------------\n  // Clone ReactElements\n\n\n  if (valIsReactElement) return /*#__PURE__*/React.cloneElement(val, props); // Create ReactElements from built up props\n\n  if (valIsPrimitiveValue || valIsPropsObject) {\n    return /*#__PURE__*/React.createElement(Component, props);\n  } // Call functions with args similar to createElement()\n\n\n  if (valIsFunction) return val(Component, props, props.children);\n  /* eslint-enable react/prop-types */\n} // ============================================================\n// Factory Creators\n// ============================================================\n\n/**\n * Creates a `createShorthand` function that is waiting for a value and options.\n *\n * @param {function|string} Component A ReactClass or string\n * @param {function} mapValueToProps A function that maps a primitive value to the Component props\n * @returns {function} A shorthand factory function waiting for `val` and `defaultProps`.\n */\n\nexport function createShorthandFactory(Component, mapValueToProps) {\n  if (typeof Component !== 'function' && typeof Component !== 'string') {\n    throw new Error('createShorthandFactory() Component must be a string or function.');\n  }\n\n  return function (val, options) {\n    return createShorthand(Component, mapValueToProps, val, options);\n  };\n} // ============================================================\n// HTML Factories\n// ============================================================\n\nexport var createHTMLDivision = /* #__PURE__ */createShorthandFactory('div', function (val) {\n  return {\n    children: val\n  };\n});\nexport var createHTMLIframe = /* #__PURE__ */createShorthandFactory('iframe', function (src) {\n  return {\n    src: src\n  };\n});\nexport var createHTMLImage = /* #__PURE__ */createShorthandFactory('img', function (val) {\n  return {\n    src: val\n  };\n});\nexport var createHTMLInput = /* #__PURE__ */createShorthandFactory('input', function (val) {\n  return {\n    type: val\n  };\n});\nexport var createHTMLLabel = /* #__PURE__ */createShorthandFactory('label', function (val) {\n  return {\n    children: val\n  };\n});\nexport var createHTMLParagraph = /* #__PURE__ */createShorthandFactory('p', function (val) {\n  return {\n    children: val\n  };\n});","/**\n * Returns a createElement() type based on the props of the Component.\n * Useful for calculating what type a component should render as.\n *\n * @param {function} Component A function or ReactClass.\n * @param {object} props A ReactElement props object\n * @param {function} [getDefault] A function that returns a default element type.\n * @returns {string|function} A ReactElement type\n */\nfunction getElementType(Component, props, getDefault) {\n  var _Component$defaultPro = Component.defaultProps,\n      defaultProps = _Component$defaultPro === void 0 ? {} : _Component$defaultPro; // ----------------------------------------\n  // user defined \"as\" element type\n\n  if (props.as && props.as !== defaultProps.as) return props.as; // ----------------------------------------\n  // computed default element type\n\n  if (getDefault) {\n    var computedDefault = getDefault();\n    if (computedDefault) return computedDefault;\n  } // ----------------------------------------\n  // infer anchor links\n\n\n  if (props.href) return 'a'; // ----------------------------------------\n  // use defaultProp or 'div'\n\n  return defaultProps.as || 'div';\n}\n\nexport default getElementType;","/**\n * Returns an object consisting of props beyond the scope of the Component.\n * Useful for getting and spreading unknown props from the user.\n * @param {function} Component A function or ReactClass.\n * @param {object} props A ReactElement props object\n * @returns {{}} A shallow copy of the prop object\n */\nvar getUnhandledProps = function getUnhandledProps(Component, props) {\n  // Note that `handledProps` are generated automatically during build with `babel-plugin-transform-react-handled-props`\n  var _Component$handledPro = Component.handledProps,\n      handledProps = _Component$handledPro === void 0 ? [] : _Component$handledPro;\n  return Object.keys(props).reduce(function (acc, prop) {\n    if (prop === 'childKey') return acc;\n    if (handledProps.indexOf(prop) === -1) acc[prop] = props[prop];\n    return acc;\n  }, {});\n};\n\nexport default getUnhandledProps;","import React from 'react';\nimport { isRefObject } from '@stardust-ui/react-component-ref';\nimport useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect';\nvar CLASS_NAME_DELITIMITER = /\\s+/;\n/**\n * Accepts a set of ref objects that contain classnames as a string and returns an array of unique\n * classNames.\n *\n * @param {Set<React.RefObject>|undefined} classNameRefs\n * @returns String[]\n */\n\nexport function computeClassNames(classNameRefs) {\n  var classNames = [];\n\n  if (classNameRefs) {\n    classNameRefs.forEach(function (classNameRef) {\n      if (typeof classNameRef.current === 'string') {\n        var classNamesForRef = classNameRef.current.split(CLASS_NAME_DELITIMITER);\n        classNamesForRef.forEach(function (className) {\n          classNames.push(className);\n        });\n      }\n    });\n    return classNames.filter(function (className, i, array) {\n      return className.length > 0 && array.indexOf(className) === i;\n    });\n  }\n\n  return [];\n}\n/**\n * Computes classnames that should be removed and added to a node based on input differences.\n *\n * @param {String[]} prevClassNames\n * @param {String[]} currentClassNames\n */\n\nexport function computeClassNamesDifference(prevClassNames, currentClassNames) {\n  return [currentClassNames.filter(function (className) {\n    return prevClassNames.indexOf(className) === -1;\n  }), prevClassNames.filter(function (className) {\n    return currentClassNames.indexOf(className) === -1;\n  })];\n}\nvar prevClassNames = new Map();\n/**\n * @param {HTMLElement} node\n * @param {Set<React.RefObject>|undefined} classNameRefs\n */\n\nexport var handleClassNamesChange = function handleClassNamesChange(node, classNameRefs) {\n  var currentClassNames = computeClassNames(classNameRefs);\n\n  var _computeClassNamesDif = computeClassNamesDifference(prevClassNames.get(node) || [], currentClassNames),\n      forAdd = _computeClassNamesDif[0],\n      forRemoval = _computeClassNamesDif[1];\n\n  if (node) {\n    forAdd.forEach(function (className) {\n      return node.classList.add(className);\n    });\n    forRemoval.forEach(function (className) {\n      return node.classList.remove(className);\n    });\n  }\n\n  prevClassNames.set(node, currentClassNames);\n};\nexport var NodeRegistry = function NodeRegistry() {\n  var _this = this;\n\n  this.add = function (node, classNameRef) {\n    if (_this.nodes.has(node)) {\n      var _set = _this.nodes.get(node);\n\n      _set.add(classNameRef);\n\n      return;\n    } // IE11 does not support constructor params\n\n\n    var set = new Set();\n    set.add(classNameRef);\n\n    _this.nodes.set(node, set);\n  };\n\n  this.del = function (node, classNameRef) {\n    if (!_this.nodes.has(node)) {\n      return;\n    }\n\n    var set = _this.nodes.get(node);\n\n    if (set.size === 1) {\n      _this.nodes.delete(node);\n\n      return;\n    }\n\n    set.delete(classNameRef);\n  };\n\n  this.emit = function (node, callback) {\n    callback(node, _this.nodes.get(node));\n  };\n\n  this.nodes = new Map();\n};\nvar nodeRegistry = new NodeRegistry();\n/**\n * A React hooks that allows to manage classNames on a DOM node in declarative manner. Accepts\n * a HTML element or React ref objects with it.\n *\n * @param {HTMLElement|React.RefObject} node\n * @param {String} className\n */\n\nexport default function useClassNamesOnNode(node, className) {\n  var classNameRef = React.useRef();\n  var isMounted = React.useRef(false);\n  useIsomorphicLayoutEffect(function () {\n    classNameRef.current = className;\n\n    if (isMounted.current) {\n      var element = isRefObject(node) ? node.current : node;\n      nodeRegistry.emit(element, handleClassNamesChange);\n    }\n\n    isMounted.current = true;\n  }, [className]);\n  useIsomorphicLayoutEffect(function () {\n    var element = isRefObject(node) ? node.current : node;\n    nodeRegistry.add(element, classNameRef);\n    nodeRegistry.emit(element, handleClassNamesChange);\n    return function () {\n      nodeRegistry.del(element, classNameRef);\n      nodeRegistry.emit(element, handleClassNamesChange);\n    };\n  }, [node]);\n}","import React from 'react';\nimport isBrowser from '../isBrowser'; // useLayoutEffect() produces a warning with SSR rendering\n// https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a\n\nvar useIsomorphicLayoutEffect = isBrowser() && process.env.NODE_ENV !== 'test' ? React.useLayoutEffect : React.useEffect;\nexport default useIsomorphicLayoutEffect;","import _includes from \"lodash/includes\";\nimport _forEach from \"lodash/forEach\";\nexport var htmlInputAttrs = [// REACT\n'selected', 'defaultValue', 'defaultChecked', // LIMITED HTML PROPS\n'accept', 'autoCapitalize', 'autoComplete', 'autoCorrect', 'autoFocus', 'checked', 'disabled', 'form', 'id', 'inputMode', 'lang', 'list', 'max', 'maxLength', 'min', 'minLength', 'multiple', 'name', 'pattern', 'placeholder', 'readOnly', 'required', 'step', 'title', 'type', 'value'];\nexport var htmlInputEvents = [// EVENTS\n// keyboard\n'onKeyDown', 'onKeyPress', 'onKeyUp', // focus\n'onFocus', 'onBlur', // form\n'onChange', 'onInput', // mouse\n'onClick', 'onContextMenu', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragExit', 'onDragLeave', 'onDragOver', 'onDragStart', 'onDrop', 'onMouseDown', 'onMouseEnter', 'onMouseLeave', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', // selection\n'onSelect', // touch\n'onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart'];\nexport var htmlInputProps = [].concat(htmlInputAttrs, htmlInputEvents);\nexport var htmlImageProps = ['alt', 'height', 'src', 'srcSet', 'width'];\n/**\n * Returns an array of objects consisting of: props of html input element and rest.\n * @param {object} props A ReactElement props object\n * @param {Object} [options={}]\n * @param {Array} [options.htmlProps] An array of html input props\n * @param {boolean} [options.includeAria] Includes all input props that starts with \"aria-\"\n * @returns {[{}, {}]} An array of objects\n */\n\nexport var partitionHTMLProps = function partitionHTMLProps(props, options) {\n  if (options === void 0) {\n    options = {};\n  }\n\n  var _options = options,\n      _options$htmlProps = _options.htmlProps,\n      htmlProps = _options$htmlProps === void 0 ? htmlInputProps : _options$htmlProps,\n      _options$includeAria = _options.includeAria,\n      includeAria = _options$includeAria === void 0 ? true : _options$includeAria;\n  var inputProps = {};\n  var rest = {};\n\n  _forEach(props, function (val, prop) {\n    var possibleAria = includeAria && (/^aria-.*$/.test(prop) || prop === 'role');\n    var target = _includes(htmlProps, prop) || possibleAria ? inputProps : rest;\n    target[prop] = val;\n  });\n\n  return [inputProps, rest];\n};","import _ModernAutoControlledComponent from './ModernAutoControlledComponent';\nexport { _ModernAutoControlledComponent as ModernAutoControlledComponent };\nimport * as _childrenUtils from './childrenUtils';\nexport { _childrenUtils as childrenUtils };\nexport { useKeyOnly, useKeyOrValueAndKey, useValueAndKey, useMultipleProp, useTextAlignProp, useVerticalAlignProp, useWidthProp } from './classNameBuilders';\nimport * as _customPropTypes from './customPropTypes';\nexport { _customPropTypes as customPropTypes };\nimport _eventStack from './eventStack';\nexport { _eventStack as eventStack };\nexport * from './factories';\nimport _getUnhandledProps from './getUnhandledProps';\nexport { _getUnhandledProps as getUnhandledProps };\nimport _getElementType from './getElementType';\nexport { _getElementType as getElementType };\nexport { htmlInputAttrs, htmlInputEvents, htmlInputProps, htmlImageProps, partitionHTMLProps } from './htmlPropsUtils';\nimport _isBrowser from './isBrowser';\nexport { _isBrowser as isBrowser };\nimport _doesNodeContainClick from './doesNodeContainClick';\nexport { _doesNodeContainClick as doesNodeContainClick };\nimport _leven from './leven';\nexport { _leven as leven };\nimport _createPaginationItems from './createPaginationItems';\nexport { _createPaginationItems as createPaginationItems };\nimport * as _SUI from './SUI';\nexport { _SUI as SUI };\nexport { numberToWordMap, numberToWord } from './numberToWord';\nimport _normalizeOffset from './normalizeOffset';\nexport { _normalizeOffset as normalizeOffset };\nimport _normalizeTransitionDuration from './normalizeTransitionDuration';\nexport { _normalizeTransitionDuration as normalizeTransitionDuration };\nimport _objectDiff from './objectDiff';\nexport { _objectDiff as objectDiff }; // Heads up! We import/export for this module to safely remove it with \"babel-plugin-filter-imports\"\n\n//\n// Hooks\n//\nimport _useClassNamesOnNode from './hooks/useClassNamesOnNode';\nexport { _useClassNamesOnNode as useClassNamesOnNode };","import _isNil from \"lodash/isNil\";\nvar hasDocument = typeof document === 'object' && document !== null;\nvar hasWindow = typeof window === 'object' && window !== null && window.self === window; // eslint-disable-next-line no-confusing-arrow\n\nvar isBrowser = function isBrowser() {\n  return !_isNil(isBrowser.override) ? isBrowser.override : hasDocument && hasWindow;\n};\n\nexport default isBrowser;","// Copy of sindre's leven, wrapped in dead code elimination for production\n// https://github.com/sindresorhus/leven/blob/master/index.js\n\n/* eslint-disable complexity, import/no-mutable-exports, no-multi-assign, no-nested-ternary, no-plusplus */\nvar leven = function leven() {\n  return 0;\n};\n\nif (process.env.NODE_ENV !== 'production') {\n  var arr = [];\n  var charCodeCache = [];\n\n  leven = function leven(a, b) {\n    if (a === b) return 0;\n    var aLen = a.length;\n    var bLen = b.length;\n    if (aLen === 0) return bLen;\n    if (bLen === 0) return aLen;\n    var bCharCode;\n    var ret;\n    var tmp;\n    var tmp2;\n    var i = 0;\n    var j = 0;\n\n    while (i < aLen) {\n      charCodeCache[i] = a.charCodeAt(i);\n      arr[i] = ++i;\n    }\n\n    while (j < bLen) {\n      bCharCode = b.charCodeAt(j);\n      tmp = j++;\n      ret = j;\n\n      for (i = 0; i < aLen; i++) {\n        tmp2 = bCharCode === charCodeCache[i] ? tmp : tmp + 1;\n        tmp = arr[i];\n        ret = arr[i] = tmp > ret ? tmp2 > ret ? ret + 1 : tmp2 : tmp2 > tmp ? tmp + 1 : tmp2;\n      }\n    }\n\n    return ret;\n  };\n}\n\nexport default leven;","/**\n * Normalizes the offset value.\n * @param {number|array} value The value to normalize.\n * @returns {number}\n */\nexport default (function (value) {\n  return typeof value === 'number' || typeof value === 'string' ? [value, value] : value;\n});","/**\n * Normalizes the duration of a transition.\n * @param {number|object} duration The value to normalize.\n * @param {'hide'|'show'} type The type of transition.\n * @returns {number}\n */\nexport default (function (duration, type) {\n  return typeof duration === 'number' || typeof duration === 'string' ? duration : duration[type];\n});","export var numberToWordMap = {\n  1: 'one',\n  2: 'two',\n  3: 'three',\n  4: 'four',\n  5: 'five',\n  6: 'six',\n  7: 'seven',\n  8: 'eight',\n  9: 'nine',\n  10: 'ten',\n  11: 'eleven',\n  12: 'twelve',\n  13: 'thirteen',\n  14: 'fourteen',\n  15: 'fifteen',\n  16: 'sixteen'\n};\n/**\n * Return the number word for numbers 1-16.\n * Returns strings or numbers as is if there is no corresponding word.\n * Returns an empty string if value is not a string or number.\n * @param {string|number} value The value to convert to a word.\n * @returns {string}\n */\n\nexport function numberToWord(value) {\n  var type = typeof value;\n\n  if (type === 'string' || type === 'number') {\n    return numberToWordMap[value] || value;\n  }\n\n  return '';\n}","import _isEqual from \"lodash/isEqual\";\nimport _has from \"lodash/has\";\nimport _transform from \"lodash/transform\";\n\n/**\n * Naive and inefficient object difference, intended for development / debugging use only.\n * Deleted keys are shown as [DELETED].\n * @param {{}} source The source object\n * @param {{}} target The target object.\n * @returns {{}} A new object containing new/modified/deleted keys.\n * @example\n * import { objectDiff } from 'src/lib'\n *\n * const a = { key: 'val', foo: 'bar' }\n * const b = { key: 'val', foo: 'baz' }\n *\n * objectDiff(a, b)\n * //=> { foo: 'baz' }\n */\nexport default (function (source, target) {\n  return _transform(source, function (res, val, key) {\n    // deleted keys\n    if (!_has(target, key)) res[key] = '[DELETED]'; // new keys / changed values\n    // Note, we tolerate isEqual here as this is a dev only utility and not included in production code\n    else if (!_isEqual(val, target[key])) res[key] = target[key];\n  }, {});\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getUnhandledProps, useKeyOnly } from '../../lib';\nimport AccordionAccordion from './AccordionAccordion';\nimport AccordionContent from './AccordionContent';\nimport AccordionPanel from './AccordionPanel';\nimport AccordionTitle from './AccordionTitle';\n/**\n * An accordion allows users to toggle the display of sections of content.\n */\n\nfunction Accordion(props) {\n  var className = props.className,\n      fluid = props.fluid,\n      inverted = props.inverted,\n      styled = props.styled;\n  var classes = cx('ui', useKeyOnly(fluid, 'fluid'), useKeyOnly(inverted, 'inverted'), useKeyOnly(styled, 'styled'), className);\n  var rest = getUnhandledProps(Accordion, props);\n  return /*#__PURE__*/React.createElement(AccordionAccordion, _extends({}, rest, {\n    className: classes\n  }));\n}\n\nAccordion.handledProps = [\"className\", \"fluid\", \"inverted\", \"styled\"];\nAccordion.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Format to take up the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** Format for dark backgrounds. */\n  inverted: PropTypes.bool,\n\n  /** Adds some basic styling to accordion panels. */\n  styled: PropTypes.bool\n} : {};\nAccordion.Accordion = AccordionAccordion;\nAccordion.Content = AccordionContent;\nAccordion.Panel = AccordionPanel;\nAccordion.Title = AccordionTitle;\nexport default Accordion;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _map from \"lodash/map\";\nimport _invoke from \"lodash/invoke\";\nimport _without from \"lodash/without\";\nimport _includes from \"lodash/includes\";\nimport _isArray from \"lodash/isArray\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport AccordionPanel from './AccordionPanel';\n\nvar warnIfPropsAreInvalid = function warnIfPropsAreInvalid(props, state) {\n  var exclusive = props.exclusive;\n  var activeIndex = state.activeIndex;\n  /* eslint-disable no-console */\n\n  if (exclusive && typeof activeIndex !== 'number') {\n    console.error('`activeIndex` must be a number if `exclusive` is true');\n  } else if (!exclusive && !_isArray(activeIndex)) {\n    console.error('`activeIndex` must be an array if `exclusive` is false');\n  }\n  /* eslint-enable no-console */\n\n};\n/**\n * An Accordion can contain sub-accordions.\n */\n\n\nvar AccordionAccordion = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(AccordionAccordion, _Component);\n\n  function AccordionAccordion() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.computeNewIndex = function (index) {\n      var exclusive = _this.props.exclusive;\n      var activeIndex = _this.state.activeIndex;\n      if (exclusive) return index === activeIndex ? -1 : index; // check to see if index is in array, and remove it, if not then add it\n\n      return _includes(activeIndex, index) ? _without(activeIndex, index) : [].concat(activeIndex, [index]);\n    };\n\n    _this.handleTitleClick = function (e, titleProps) {\n      var index = titleProps.index;\n\n      _this.setState({\n        activeIndex: _this.computeNewIndex(index)\n      });\n\n      _invoke(_this.props, 'onTitleClick', e, titleProps);\n    };\n\n    _this.isIndexActive = function (index) {\n      var exclusive = _this.props.exclusive;\n      var activeIndex = _this.state.activeIndex;\n      return exclusive ? activeIndex === index : _includes(activeIndex, index);\n    };\n\n    return _this;\n  }\n\n  var _proto = AccordionAccordion.prototype;\n\n  _proto.getInitialAutoControlledState = function getInitialAutoControlledState(_ref) {\n    var exclusive = _ref.exclusive;\n    return {\n      activeIndex: exclusive ? -1 : []\n    };\n  };\n\n  _proto.componentDidMount = function componentDidMount() {\n    if (process.env.NODE_ENV !== 'production') {\n      warnIfPropsAreInvalid(this.props, this.state);\n    }\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate() {\n    if (process.env.NODE_ENV !== 'production') {\n      warnIfPropsAreInvalid(this.props, this.state);\n    }\n  };\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props = this.props,\n        className = _this$props.className,\n        children = _this$props.children,\n        panels = _this$props.panels;\n    var classes = cx('accordion', className);\n    var rest = getUnhandledProps(AccordionAccordion, this.props);\n    var ElementType = getElementType(AccordionAccordion, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), childrenUtils.isNil(children) ? _map(panels, function (panel, index) {\n      return AccordionPanel.create(panel, {\n        defaultProps: {\n          active: _this2.isIndexActive(index),\n          index: index,\n          onTitleClick: _this2.handleTitleClick\n        }\n      });\n    }) : children);\n  };\n\n  return AccordionAccordion;\n}(Component);\n\nAccordionAccordion.handledProps = [\"activeIndex\", \"as\", \"children\", \"className\", \"defaultActiveIndex\", \"exclusive\", \"onTitleClick\", \"panels\"];\nexport { AccordionAccordion as default };\nAccordionAccordion.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Index of the currently active panel. */\n  activeIndex: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number])]),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Initial activeIndex value. */\n  defaultActiveIndex: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number])]),\n\n  /** Only allow one panel open at a time. */\n  exclusive: PropTypes.bool,\n\n  /**\n   * Called when a panel title is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All item props.\n   */\n  onTitleClick: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.func]),\n\n  /** Shorthand array of props for Accordion. */\n  panels: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.arrayOf(PropTypes.shape({\n    content: customPropTypes.itemShorthand,\n    title: customPropTypes.itemShorthand\n  }))])\n} : {};\nAccordionAccordion.defaultProps = {\n  exclusive: true\n};\nAccordionAccordion.autoControlledProps = ['activeIndex'];\nAccordionAccordion.create = createShorthandFactory(AccordionAccordion, function (content) {\n  return {\n    content: content\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A content sub-component for Accordion component.\n */\n\nfunction AccordionContent(props) {\n  var active = props.active,\n      children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('content', useKeyOnly(active, 'active'), className);\n  var rest = getUnhandledProps(AccordionContent, props);\n  var ElementType = getElementType(AccordionContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nAccordionContent.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\"];\nAccordionContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Whether or not the content is visible. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nAccordionContent.create = createShorthandFactory(AccordionContent, function (content) {\n  return {\n    content: content\n  };\n});\nexport default AccordionContent;","import _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { createShorthandFactory, customPropTypes } from '../../lib';\nimport AccordionTitle from './AccordionTitle';\nimport AccordionContent from './AccordionContent';\n/**\n * A panel sub-component for Accordion component.\n */\n\nvar AccordionPanel = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(AccordionPanel, _Component);\n\n  function AccordionPanel() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleTitleOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, titleProps) {\n          _invoke(predefinedProps, 'onClick', e, titleProps);\n\n          _invoke(_this.props, 'onTitleClick', e, titleProps);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = AccordionPanel.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        content = _this$props.content,\n        index = _this$props.index,\n        title = _this$props.title;\n    return /*#__PURE__*/React.createElement(React.Fragment, null, AccordionTitle.create(title, {\n      autoGenerateKey: false,\n      defaultProps: {\n        active: active,\n        index: index\n      },\n      overrideProps: this.handleTitleOverrides\n    }), AccordionContent.create(content, {\n      autoGenerateKey: false,\n      defaultProps: {\n        active: active\n      }\n    }));\n  };\n\n  return AccordionPanel;\n}(Component);\n\nAccordionPanel.handledProps = [\"active\", \"content\", \"index\", \"onTitleClick\", \"title\"];\nAccordionPanel.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Whether or not the title is in the open state. */\n  active: PropTypes.bool,\n\n  /** A shorthand for Accordion.Content. */\n  content: customPropTypes.itemShorthand,\n\n  /** A panel index. */\n  index: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /**\n   * Called when a panel title is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All item props.\n   */\n  onTitleClick: PropTypes.func,\n\n  /** A shorthand for Accordion.Title. */\n  title: customPropTypes.itemShorthand\n} : {};\nAccordionPanel.create = createShorthandFactory(AccordionPanel, null);\nexport default AccordionPanel;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isNil from \"lodash/isNil\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A title sub-component for Accordion component.\n */\n\nvar AccordionTitle = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(AccordionTitle, _Component);\n\n  function AccordionTitle() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      return _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = AccordionTitle.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content,\n        icon = _this$props.icon;\n    var classes = cx(useKeyOnly(active, 'active'), 'title', className);\n    var rest = getUnhandledProps(AccordionTitle, this.props);\n    var ElementType = getElementType(AccordionTitle, this.props);\n    var iconValue = _isNil(icon) ? 'dropdown' : icon;\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick\n    }), Icon.create(iconValue, {\n      autoGenerateKey: false\n    }), content);\n  };\n\n  return AccordionTitle;\n}(Component);\n\nAccordionTitle.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"icon\", \"index\", \"onClick\"];\nexport { AccordionTitle as default };\nAccordionTitle.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Whether or not the title is in the open state. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for Icon. */\n  icon: customPropTypes.itemShorthand,\n\n  /** AccordionTitle index inside Accordion. */\n  index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func\n} : {};\nAccordionTitle.create = createShorthandFactory(AccordionTitle, function (content) {\n  return {\n    content: content\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _set from \"lodash/set\";\nimport _invoke from \"lodash/invoke\";\nimport _get from \"lodash/get\";\nimport _isNil from \"lodash/isNil\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { createRef } from 'react';\nimport { ModernAutoControlledComponent as Component, createHTMLLabel, customPropTypes, getElementType, getUnhandledProps, htmlInputAttrs, partitionHTMLProps, useKeyOnly } from '../../lib';\n\n/**\n * A checkbox allows a user to select a value from a small set of options, often binary.\n * @see Form\n * @see Radio\n */\nvar Checkbox = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Checkbox, _Component);\n\n  function Checkbox() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.inputRef = /*#__PURE__*/createRef();\n    _this.labelRef = /*#__PURE__*/createRef();\n\n    _this.canToggle = function () {\n      var _this$props = _this.props,\n          disabled = _this$props.disabled,\n          radio = _this$props.radio,\n          readOnly = _this$props.readOnly;\n      var checked = _this.state.checked;\n      return !disabled && !readOnly && !(radio && checked);\n    };\n\n    _this.computeTabIndex = function () {\n      var _this$props2 = _this.props,\n          disabled = _this$props2.disabled,\n          tabIndex = _this$props2.tabIndex;\n      if (!_isNil(tabIndex)) return tabIndex;\n      return disabled ? -1 : 0;\n    };\n\n    _this.handleClick = function (e) {\n      var id = _this.props.id;\n      var _this$state = _this.state,\n          checked = _this$state.checked,\n          indeterminate = _this$state.indeterminate;\n\n      var isInputClick = _invoke(_this.inputRef.current, 'contains', e.target);\n\n      var isLabelClick = _invoke(_this.labelRef.current, 'contains', e.target);\n\n      var isRootClick = !isLabelClick && !isInputClick;\n      var hasId = !_isNil(id);\n      var isLabelClickAndForwardedToInput = isLabelClick && hasId; // https://github.com/Semantic-Org/Semantic-UI-React/pull/3351\n\n      if (!isLabelClickAndForwardedToInput) {\n        _invoke(_this.props, 'onClick', e, _extends({}, _this.props, {\n          checked: !checked,\n          indeterminate: !!indeterminate\n        }));\n      }\n\n      if (_this.isClickFromMouse) {\n        _this.isClickFromMouse = false;\n\n        if (isLabelClick && !hasId) {\n          _this.handleChange(e);\n        } // Changes should be triggered for the slider variation\n\n\n        if (isRootClick) {\n          _this.handleChange(e);\n        }\n\n        if (isLabelClick && hasId) {\n          // To prevent two clicks from being fired from the component we have to stop the propagation\n          // from the \"input\" click: https://github.com/Semantic-Org/Semantic-UI-React/issues/3433\n          e.stopPropagation();\n        }\n      }\n    };\n\n    _this.handleChange = function (e) {\n      var checked = _this.state.checked;\n      if (!_this.canToggle()) return;\n\n      _invoke(_this.props, 'onChange', e, _extends({}, _this.props, {\n        checked: !checked,\n        indeterminate: false\n      }));\n\n      _this.setState({\n        checked: !checked,\n        indeterminate: false\n      });\n    };\n\n    _this.handleMouseDown = function (e) {\n      var _this$state2 = _this.state,\n          checked = _this$state2.checked,\n          indeterminate = _this$state2.indeterminate;\n\n      _invoke(_this.props, 'onMouseDown', e, _extends({}, _this.props, {\n        checked: !!checked,\n        indeterminate: !!indeterminate\n      }));\n\n      if (!e.defaultPrevented) {\n        _invoke(_this.inputRef.current, 'focus');\n      } // Heads up!\n      // We need to call \"preventDefault\" to keep element focused.\n\n\n      e.preventDefault();\n    };\n\n    _this.handleMouseUp = function (e) {\n      var _this$state3 = _this.state,\n          checked = _this$state3.checked,\n          indeterminate = _this$state3.indeterminate;\n      _this.isClickFromMouse = true;\n\n      _invoke(_this.props, 'onMouseUp', e, _extends({}, _this.props, {\n        checked: !!checked,\n        indeterminate: !!indeterminate\n      }));\n    };\n\n    _this.setIndeterminate = function () {\n      var indeterminate = _this.state.indeterminate;\n\n      _set(_this.inputRef, 'current.indeterminate', !!indeterminate);\n    };\n\n    return _this;\n  }\n\n  var _proto = Checkbox.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    this.setIndeterminate();\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate() {\n    this.setIndeterminate();\n  };\n\n  _proto.render = function render() {\n    var _this$props3 = this.props,\n        className = _this$props3.className,\n        disabled = _this$props3.disabled,\n        label = _this$props3.label,\n        id = _this$props3.id,\n        name = _this$props3.name,\n        radio = _this$props3.radio,\n        readOnly = _this$props3.readOnly,\n        slider = _this$props3.slider,\n        toggle = _this$props3.toggle,\n        type = _this$props3.type,\n        value = _this$props3.value;\n    var _this$state4 = this.state,\n        checked = _this$state4.checked,\n        indeterminate = _this$state4.indeterminate;\n    var classes = cx('ui', useKeyOnly(checked, 'checked'), useKeyOnly(disabled, 'disabled'), useKeyOnly(indeterminate, 'indeterminate'), // auto apply fitted class to compact white space when there is no label\n    // https://semantic-ui.com/modules/checkbox.html#fitted\n    useKeyOnly(_isNil(label), 'fitted'), useKeyOnly(radio, 'radio'), useKeyOnly(readOnly, 'read-only'), useKeyOnly(slider, 'slider'), useKeyOnly(toggle, 'toggle'), 'checkbox', className);\n    var unhandled = getUnhandledProps(Checkbox, this.props);\n    var ElementType = getElementType(Checkbox, this.props);\n\n    var _partitionHTMLProps = partitionHTMLProps(unhandled, {\n      htmlProps: htmlInputAttrs\n    }),\n        htmlInputProps = _partitionHTMLProps[0],\n        rest = _partitionHTMLProps[1]; // Heads Up!\n    // Do not remove empty labels, they are required by SUI CSS\n\n\n    var labelElement = createHTMLLabel(label, {\n      defaultProps: {\n        htmlFor: id\n      },\n      autoGenerateKey: false\n    }) || /*#__PURE__*/React.createElement(\"label\", {\n      htmlFor: id\n    });\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick,\n      onChange: this.handleChange,\n      onMouseDown: this.handleMouseDown,\n      onMouseUp: this.handleMouseUp\n    }), /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.inputRef\n    }, /*#__PURE__*/React.createElement(\"input\", _extends({}, htmlInputProps, {\n      checked: checked,\n      className: \"hidden\",\n      disabled: disabled,\n      id: id,\n      name: name,\n      readOnly: true,\n      tabIndex: this.computeTabIndex(),\n      type: type,\n      value: value\n    }))), /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.labelRef\n    }, labelElement));\n  };\n\n  return Checkbox;\n}(Component);\n\nCheckbox.handledProps = [\"as\", \"checked\", \"className\", \"defaultChecked\", \"defaultIndeterminate\", \"disabled\", \"fitted\", \"id\", \"indeterminate\", \"label\", \"name\", \"onChange\", \"onClick\", \"onMouseDown\", \"onMouseUp\", \"radio\", \"readOnly\", \"slider\", \"tabIndex\", \"toggle\", \"type\", \"value\"];\nexport { Checkbox as default };\nCheckbox.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Whether or not checkbox is checked. */\n  checked: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** The initial value of checked. */\n  defaultChecked: PropTypes.bool,\n\n  /** Whether or not checkbox is indeterminate. */\n  defaultIndeterminate: PropTypes.bool,\n\n  /** A checkbox can appear disabled and be unable to change states */\n  disabled: PropTypes.bool,\n\n  /** Removes padding for a label. Auto applied when there is no label. */\n  fitted: PropTypes.bool,\n\n  /** A unique identifier. */\n  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Whether or not checkbox is indeterminate. */\n  indeterminate: PropTypes.bool,\n\n  /** The text of the associated label element. */\n  label: customPropTypes.itemShorthand,\n\n  /** The HTML input name. */\n  name: PropTypes.string,\n\n  /**\n   * Called when the user attempts to change the checked state.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and proposed checked/indeterminate state.\n   */\n  onChange: PropTypes.func,\n\n  /**\n   * Called when the checkbox or label is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and current checked/indeterminate state.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Called when the user presses down on the mouse.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and current checked/indeterminate state.\n   */\n  onMouseDown: PropTypes.func,\n\n  /**\n   * Called when the user releases the mouse.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and current checked/indeterminate state.\n   */\n  onMouseUp: PropTypes.func,\n\n  /** Format as a radio element. This means it is an exclusive option. */\n  radio: customPropTypes.every([PropTypes.bool, customPropTypes.disallow(['slider', 'toggle'])]),\n\n  /** A checkbox can be read-only and unable to change states. */\n  readOnly: PropTypes.bool,\n\n  /** Format to emphasize the current selection state. */\n  slider: customPropTypes.every([PropTypes.bool, customPropTypes.disallow(['radio', 'toggle'])]),\n\n  /** A checkbox can receive focus. */\n  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Format to show an on or off choice. */\n  toggle: customPropTypes.every([PropTypes.bool, customPropTypes.disallow(['radio', 'slider'])]),\n\n  /** HTML input type, either checkbox or radio. */\n  type: PropTypes.oneOf(['checkbox', 'radio']),\n\n  /** The HTML input value. */\n  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])\n} : {};\nCheckbox.defaultProps = {\n  type: 'checkbox'\n};\nCheckbox.autoControlledProps = ['checked', 'indeterminate'];","import _default from './Checkbox';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { createShorthandFactory, getUnhandledProps, isBrowser } from '../../lib';\nimport Portal from '../../addons/Portal';\nimport DimmerDimmable from './DimmerDimmable';\nimport DimmerInner from './DimmerInner';\n/**\n * A dimmer hides distractions to focus attention on particular content.\n */\n\nvar Dimmer = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Dimmer, _Component);\n\n  function Dimmer() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handlePortalMount = function () {\n      if (!isBrowser()) return; // Heads up, IE doesn't support second argument in add()\n\n      document.body.classList.add('dimmed');\n      document.body.classList.add('dimmable');\n    };\n\n    _this.handlePortalUnmount = function () {\n      if (!isBrowser()) return; // Heads up, IE doesn't support second argument in add()\n\n      document.body.classList.remove('dimmed');\n      document.body.classList.remove('dimmable');\n    };\n\n    return _this;\n  }\n\n  var _proto = Dimmer.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        page = _this$props.page;\n    var rest = getUnhandledProps(Dimmer, this.props);\n\n    if (page) {\n      return /*#__PURE__*/React.createElement(Portal, {\n        closeOnEscape: false,\n        closeOnDocumentClick: false,\n        onMount: this.handlePortalMount,\n        onUnmount: this.handlePortalUnmount,\n        open: active,\n        openOnTriggerClick: false\n      }, /*#__PURE__*/React.createElement(DimmerInner, _extends({}, rest, {\n        active: active,\n        page: page\n      })));\n    }\n\n    return /*#__PURE__*/React.createElement(DimmerInner, _extends({}, rest, {\n      active: active,\n      page: page\n    }));\n  };\n\n  return Dimmer;\n}(Component);\n\nDimmer.handledProps = [\"active\", \"page\"];\nexport { Dimmer as default };\nDimmer.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An active dimmer will dim its parent container. */\n  active: PropTypes.bool,\n\n  /** A dimmer can be formatted to be fixed to the page. */\n  page: PropTypes.bool\n} : {};\nDimmer.Dimmable = DimmerDimmable;\nDimmer.Inner = DimmerInner;\nDimmer.create = createShorthandFactory(Dimmer, function (value) {\n  return {\n    content: value\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A dimmable sub-component for Dimmer.\n */\n\nfunction DimmerDimmable(props) {\n  var blurring = props.blurring,\n      className = props.className,\n      children = props.children,\n      content = props.content,\n      dimmed = props.dimmed;\n  var classes = cx(useKeyOnly(blurring, 'blurring'), useKeyOnly(dimmed, 'dimmed'), 'dimmable', className);\n  var rest = getUnhandledProps(DimmerDimmable, props);\n  var ElementType = getElementType(DimmerDimmable, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nDimmerDimmable.handledProps = [\"as\", \"blurring\", \"children\", \"className\", \"content\", \"dimmed\"];\nDimmerDimmable.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A dimmable element can blur its contents. */\n  blurring: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Controls whether or not the dim is displayed. */\n  dimmed: PropTypes.bool\n} : {};\nexport default DimmerDimmable;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { childrenUtils, customPropTypes, doesNodeContainClick, getElementType, getUnhandledProps, useKeyOnly, useVerticalAlignProp } from '../../lib';\n/**\n * An inner element for a Dimmer.\n */\n\nvar DimmerInner = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(DimmerInner, _Component);\n\n  function DimmerInner() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.containerRef = /*#__PURE__*/createRef();\n    _this.contentRef = /*#__PURE__*/createRef();\n\n    _this.handleClick = function (e) {\n      var contentRef = _this.contentRef.current;\n\n      _invoke(_this.props, 'onClick', e, _this.props);\n\n      if (contentRef && contentRef !== e.target && doesNodeContainClick(contentRef, e)) {\n        return;\n      }\n\n      _invoke(_this.props, 'onClickOutside', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = DimmerInner.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    var active = this.props.active;\n    this.toggleStyles(active);\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n    var currentActive = this.props.active;\n    var prevActive = prevProps.active;\n    if (prevActive !== currentActive) this.toggleStyles(currentActive);\n  };\n\n  _proto.toggleStyles = function toggleStyles(active) {\n    var containerRef = this.containerRef.current;\n    if (!containerRef || !containerRef.style) return;\n\n    if (active) {\n      containerRef.style.setProperty('display', 'flex', 'important');\n    } else {\n      containerRef.style.removeProperty('display');\n    }\n  };\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content,\n        disabled = _this$props.disabled,\n        inverted = _this$props.inverted,\n        page = _this$props.page,\n        simple = _this$props.simple,\n        verticalAlign = _this$props.verticalAlign;\n    var classes = cx('ui', useKeyOnly(active, 'active transition visible'), useKeyOnly(disabled, 'disabled'), useKeyOnly(inverted, 'inverted'), useKeyOnly(page, 'page'), useKeyOnly(simple, 'simple'), useVerticalAlignProp(verticalAlign), 'dimmer', className);\n    var rest = getUnhandledProps(DimmerInner, this.props);\n    var ElementType = getElementType(DimmerInner, this.props);\n    var childrenContent = childrenUtils.isNil(children) ? content : children;\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.containerRef\n    }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick\n    }), childrenContent && /*#__PURE__*/React.createElement(\"div\", {\n      className: \"content\",\n      ref: this.contentRef\n    }, childrenContent)));\n  };\n\n  return DimmerInner;\n}(Component);\n\nDimmerInner.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"disabled\", \"inverted\", \"onClick\", \"onClickOutside\", \"page\", \"simple\", \"verticalAlign\"];\nexport { DimmerInner as default };\nDimmerInner.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An active dimmer will dim its parent container. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A disabled dimmer cannot be activated */\n  disabled: PropTypes.bool,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Handles click outside Dimmer's content, but inside Dimmer area.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClickOutside: PropTypes.func,\n\n  /** A dimmer can be formatted to have its colors inverted. */\n  inverted: PropTypes.bool,\n\n  /** A dimmer can be formatted to be fixed to the page. */\n  page: PropTypes.bool,\n\n  /** A dimmer can be controlled with simple prop. */\n  simple: PropTypes.bool,\n\n  /** A dimmer can have its content top or bottom aligned. */\n  verticalAlign: PropTypes.oneOf(['bottom', 'top'])\n} : {};","import _default from './Dimmer';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _includes from \"lodash/includes\";\nimport _compact from \"lodash/compact\";\nimport _map from \"lodash/map\";\nimport _every from \"lodash/every\";\nimport _without from \"lodash/without\";\nimport _find from \"lodash/find\";\nimport _dropRight from \"lodash/dropRight\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _size from \"lodash/size\";\nimport _difference from \"lodash/difference\";\nimport _union from \"lodash/union\";\nimport _get from \"lodash/get\";\nimport _noop from \"lodash/noop\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport _invoke from \"lodash/invoke\";\nimport _has from \"lodash/has\";\nimport _isEqual from \"lodash/isEqual\";\nimport _isFunction from \"lodash/isFunction\";\nimport _pick from \"lodash/pick\";\nimport _isNil from \"lodash/isNil\";\nimport EventStack from '@semantic-ui-react/event-stack';\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport keyboardKey from 'keyboard-key';\nimport PropTypes from 'prop-types';\nimport React, { Children, cloneElement, createRef } from 'react';\nimport shallowEqual from 'shallowequal';\nimport { ModernAutoControlledComponent as Component, childrenUtils, customPropTypes, doesNodeContainClick, getElementType, getUnhandledProps, objectDiff, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\nimport Icon from '../../elements/Icon';\nimport Label from '../../elements/Label';\nimport Flag from '../../elements/Flag';\nimport Image from '../../elements/Image';\nimport DropdownDivider from './DropdownDivider';\nimport DropdownItem from './DropdownItem';\nimport DropdownHeader from './DropdownHeader';\nimport DropdownMenu from './DropdownMenu';\nimport DropdownSearchInput from './DropdownSearchInput';\nimport DropdownText from './DropdownText';\nimport getMenuOptions from './utils/getMenuOptions';\nimport getSelectedIndex from './utils/getSelectedIndex';\n\nvar getKeyOrValue = function getKeyOrValue(key, value) {\n  return _isNil(key) ? value : key;\n};\n\nvar getKeyAndValues = function getKeyAndValues(options) {\n  return options ? options.map(function (option) {\n    return _pick(option, ['key', 'value']);\n  }) : options;\n};\n\nfunction renderItemContent(item) {\n  var flag = item.flag,\n      image = item.image,\n      text = item.text; // TODO: remove this in v2\n  // This maintains compatibility with Shorthand API in v1 as this might be called in \"Label.create()\"\n\n  if ( /*#__PURE__*/React.isValidElement(text) || _isFunction(text)) {\n    return text;\n  }\n\n  return {\n    content: /*#__PURE__*/React.createElement(React.Fragment, null, Flag.create(flag), Image.create(image), text)\n  };\n}\n/**\n * A dropdown allows a user to select a value from a series of options.\n * @see Form\n * @see Select\n * @see Menu\n */\n\n\nvar Dropdown = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Dropdown, _Component);\n\n  function Dropdown() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.searchRef = /*#__PURE__*/createRef();\n    _this.sizerRef = /*#__PURE__*/createRef();\n    _this.ref = /*#__PURE__*/createRef();\n\n    _this.handleChange = function (e, value) {\n      _invoke(_this.props, 'onChange', e, _extends({}, _this.props, {\n        value: value\n      }));\n    };\n\n    _this.closeOnChange = function (e) {\n      var _this$props = _this.props,\n          closeOnChange = _this$props.closeOnChange,\n          multiple = _this$props.multiple;\n      var shouldClose = _isUndefined(closeOnChange) ? !multiple : closeOnChange;\n\n      if (shouldClose) {\n        _this.close(e, _noop);\n      }\n    };\n\n    _this.closeOnEscape = function (e) {\n      if (!_this.props.closeOnEscape) return;\n      if (keyboardKey.getCode(e) !== keyboardKey.Escape) return;\n      e.preventDefault();\n\n      _this.close(e);\n    };\n\n    _this.moveSelectionOnKeyDown = function (e) {\n      var _moves;\n\n      var _this$props2 = _this.props,\n          multiple = _this$props2.multiple,\n          selectOnNavigation = _this$props2.selectOnNavigation;\n      var open = _this.state.open;\n\n      if (!open) {\n        return;\n      }\n\n      var moves = (_moves = {}, _moves[keyboardKey.ArrowDown] = 1, _moves[keyboardKey.ArrowUp] = -1, _moves);\n      var move = moves[keyboardKey.getCode(e)];\n\n      if (move === undefined) {\n        return;\n      }\n\n      e.preventDefault();\n\n      var nextIndex = _this.getSelectedIndexAfterMove(move);\n\n      if (!multiple && selectOnNavigation) {\n        _this.makeSelectedItemActive(e, nextIndex);\n      }\n\n      _this.setState({\n        selectedIndex: nextIndex\n      });\n    };\n\n    _this.openOnSpace = function (e) {\n      if (keyboardKey.getCode(e) !== keyboardKey.Spacebar) return;\n      e.preventDefault();\n\n      _this.open(e);\n    };\n\n    _this.openOnArrow = function (e) {\n      var _this$state = _this.state,\n          focus = _this$state.focus,\n          open = _this$state.open;\n\n      if (focus && !open) {\n        var code = keyboardKey.getCode(e);\n\n        if (code === keyboardKey.ArrowDown || code === keyboardKey.ArrowUp) {\n          e.preventDefault();\n\n          _this.open(e);\n        }\n      }\n    };\n\n    _this.makeSelectedItemActive = function (e, selectedIndex) {\n      var _this$state2 = _this.state,\n          open = _this$state2.open,\n          value = _this$state2.value;\n      var multiple = _this.props.multiple;\n\n      var item = _this.getSelectedItem(selectedIndex);\n\n      var selectedValue = _get(item, 'value'); // prevent selecting null if there was no selected item value\n      // prevent selecting duplicate items when the dropdown is closed\n\n\n      if (_isNil(selectedValue) || !open) {\n        return value;\n      } // state value may be undefined\n\n\n      var newValue = multiple ? _union(value, [selectedValue]) : selectedValue;\n      var valueHasChanged = multiple ? !!_difference(newValue, value).length : newValue !== value;\n\n      if (valueHasChanged) {\n        // notify the onChange prop that the user is trying to change value\n        _this.setState({\n          value: newValue\n        });\n\n        _this.handleChange(e, newValue); // Heads up! This event handler should be called after `onChange`\n        // Notify the onAddItem prop if this is a new value\n\n\n        if (item['data-additional']) {\n          _invoke(_this.props, 'onAddItem', e, _extends({}, _this.props, {\n            value: selectedValue\n          }));\n        }\n      }\n\n      return value;\n    };\n\n    _this.selectItemOnEnter = function (e) {\n      var search = _this.props.search;\n      var _this$state3 = _this.state,\n          open = _this$state3.open,\n          selectedIndex = _this$state3.selectedIndex;\n\n      if (!open) {\n        return;\n      }\n\n      var shouldSelect = keyboardKey.getCode(e) === keyboardKey.Enter || // https://github.com/Semantic-Org/Semantic-UI-React/pull/3766\n      !search && keyboardKey.getCode(e) === keyboardKey.Spacebar;\n\n      if (!shouldSelect) {\n        return;\n      }\n\n      e.preventDefault();\n\n      var optionSize = _size(getMenuOptions({\n        value: _this.state.value,\n        options: _this.props.options,\n        searchQuery: _this.state.searchQuery,\n        additionLabel: _this.props.additionLabel,\n        additionPosition: _this.props.additionPosition,\n        allowAdditions: _this.props.allowAdditions,\n        deburr: _this.props.deburr,\n        multiple: _this.props.multiple,\n        search: _this.props.search\n      }));\n\n      if (search && optionSize === 0) {\n        return;\n      }\n\n      var nextValue = _this.makeSelectedItemActive(e, selectedIndex); // This is required as selected value may be the same\n\n\n      _this.setState({\n        selectedIndex: getSelectedIndex({\n          additionLabel: _this.props.additionLabel,\n          additionPosition: _this.props.additionPosition,\n          allowAdditions: _this.props.allowAdditions,\n          deburr: _this.props.deburr,\n          multiple: _this.props.multiple,\n          search: _this.props.search,\n          selectedIndex: selectedIndex,\n          value: nextValue,\n          options: _this.props.options,\n          searchQuery: ''\n        })\n      });\n\n      _this.closeOnChange(e);\n\n      _this.clearSearchQuery();\n\n      if (search) {\n        _invoke(_this.searchRef.current, 'focus');\n      }\n    };\n\n    _this.removeItemOnBackspace = function (e) {\n      var _this$props3 = _this.props,\n          multiple = _this$props3.multiple,\n          search = _this$props3.search;\n      var _this$state4 = _this.state,\n          searchQuery = _this$state4.searchQuery,\n          value = _this$state4.value;\n      if (keyboardKey.getCode(e) !== keyboardKey.Backspace) return;\n      if (searchQuery || !search || !multiple || _isEmpty(value)) return;\n      e.preventDefault(); // remove most recent value\n\n      var newValue = _dropRight(value);\n\n      _this.setState({\n        value: newValue\n      });\n\n      _this.handleChange(e, newValue);\n    };\n\n    _this.closeOnDocumentClick = function (e) {\n      if (!_this.props.closeOnBlur) return; // If event happened in the dropdown, ignore it\n\n      if (_this.ref.current && doesNodeContainClick(_this.ref.current, e)) return;\n\n      _this.close();\n    };\n\n    _this.handleMouseDown = function (e) {\n      _this.isMouseDown = true;\n\n      _invoke(_this.props, 'onMouseDown', e, _this.props);\n\n      document.addEventListener('mouseup', _this.handleDocumentMouseUp);\n    };\n\n    _this.handleDocumentMouseUp = function () {\n      _this.isMouseDown = false;\n      document.removeEventListener('mouseup', _this.handleDocumentMouseUp);\n    };\n\n    _this.handleClick = function (e) {\n      var _this$props4 = _this.props,\n          minCharacters = _this$props4.minCharacters,\n          search = _this$props4.search;\n      var _this$state5 = _this.state,\n          open = _this$state5.open,\n          searchQuery = _this$state5.searchQuery;\n\n      _invoke(_this.props, 'onClick', e, _this.props); // prevent closeOnDocumentClick()\n\n\n      e.stopPropagation();\n      if (!search) return _this.toggle(e);\n\n      if (open) {\n        _invoke(_this.searchRef.current, 'focus');\n\n        return;\n      }\n\n      if (searchQuery.length >= minCharacters || minCharacters === 1) {\n        _this.open(e);\n\n        return;\n      }\n\n      _invoke(_this.searchRef.current, 'focus');\n    };\n\n    _this.handleIconClick = function (e) {\n      var clearable = _this.props.clearable;\n\n      var hasValue = _this.hasValue();\n\n      _invoke(_this.props, 'onClick', e, _this.props); // prevent handleClick()\n\n\n      e.stopPropagation();\n\n      if (clearable && hasValue) {\n        _this.clearValue(e);\n      } else {\n        _this.toggle(e);\n      }\n    };\n\n    _this.handleItemClick = function (e, item) {\n      var _this$props5 = _this.props,\n          multiple = _this$props5.multiple,\n          search = _this$props5.search;\n      var currentValue = _this.state.value;\n      var value = item.value; // prevent toggle() in handleClick()\n\n      e.stopPropagation(); // prevent closeOnDocumentClick() if multiple or item is disabled\n\n      if (multiple || item.disabled) {\n        e.nativeEvent.stopImmediatePropagation();\n      }\n\n      if (item.disabled) {\n        return;\n      }\n\n      var isAdditionItem = item['data-additional'];\n      var newValue = multiple ? _union(_this.state.value, [value]) : value;\n      var valueHasChanged = multiple ? !!_difference(newValue, currentValue).length : newValue !== currentValue; // notify the onChange prop that the user is trying to change value\n\n      if (valueHasChanged) {\n        _this.setState({\n          value: newValue\n        });\n\n        _this.handleChange(e, newValue);\n      }\n\n      _this.clearSearchQuery();\n\n      if (search) {\n        _invoke(_this.searchRef.current, 'focus');\n      } else {\n        _invoke(_this.ref.current, 'focus');\n      }\n\n      _this.closeOnChange(e); // Heads up! This event handler should be called after `onChange`\n      // Notify the onAddItem prop if this is a new value\n\n\n      if (isAdditionItem) {\n        _invoke(_this.props, 'onAddItem', e, _extends({}, _this.props, {\n          value: value\n        }));\n      }\n    };\n\n    _this.handleFocus = function (e) {\n      var focus = _this.state.focus;\n      if (focus) return;\n\n      _invoke(_this.props, 'onFocus', e, _this.props);\n\n      _this.setState({\n        focus: true\n      });\n    };\n\n    _this.handleBlur = function (e) {\n      // Heads up! Don't remove this.\n      // https://github.com/Semantic-Org/Semantic-UI-React/issues/1315\n      var currentTarget = _get(e, 'currentTarget');\n\n      if (currentTarget && currentTarget.contains(document.activeElement)) return;\n      var _this$props6 = _this.props,\n          closeOnBlur = _this$props6.closeOnBlur,\n          multiple = _this$props6.multiple,\n          selectOnBlur = _this$props6.selectOnBlur; // do not \"blur\" when the mouse is down inside of the Dropdown\n\n      if (_this.isMouseDown) return;\n\n      _invoke(_this.props, 'onBlur', e, _this.props);\n\n      if (selectOnBlur && !multiple) {\n        _this.makeSelectedItemActive(e, _this.state.selectedIndex);\n\n        if (closeOnBlur) _this.close();\n      }\n\n      _this.setState({\n        focus: false\n      });\n\n      _this.clearSearchQuery();\n    };\n\n    _this.handleSearchChange = function (e, _ref) {\n      var value = _ref.value;\n      // prevent propagating to this.props.onChange()\n      e.stopPropagation();\n      var minCharacters = _this.props.minCharacters;\n      var open = _this.state.open;\n      var newQuery = value;\n\n      _invoke(_this.props, 'onSearchChange', e, _extends({}, _this.props, {\n        searchQuery: newQuery\n      }));\n\n      _this.setState({\n        searchQuery: newQuery,\n        selectedIndex: 0\n      }); // open search dropdown on search query\n\n\n      if (!open && newQuery.length >= minCharacters) {\n        _this.open();\n\n        return;\n      } // close search dropdown if search query is too small\n\n\n      if (open && minCharacters !== 1 && newQuery.length < minCharacters) _this.close();\n    };\n\n    _this.handleKeyDown = function (e) {\n      _this.moveSelectionOnKeyDown(e);\n\n      _this.openOnArrow(e);\n\n      _this.selectItemOnEnter(e);\n\n      _invoke(_this.props, 'onKeyDown', e);\n    };\n\n    _this.getSelectedItem = function (selectedIndex) {\n      var options = getMenuOptions({\n        value: _this.state.value,\n        options: _this.props.options,\n        searchQuery: _this.state.searchQuery,\n        additionLabel: _this.props.additionLabel,\n        additionPosition: _this.props.additionPosition,\n        allowAdditions: _this.props.allowAdditions,\n        deburr: _this.props.deburr,\n        multiple: _this.props.multiple,\n        search: _this.props.search\n      });\n      return _get(options, \"[\" + selectedIndex + \"]\");\n    };\n\n    _this.getItemByValue = function (value) {\n      var options = _this.props.options;\n      return _find(options, {\n        value: value\n      });\n    };\n\n    _this.getDropdownAriaOptions = function () {\n      var _this$props7 = _this.props,\n          loading = _this$props7.loading,\n          disabled = _this$props7.disabled,\n          search = _this$props7.search,\n          multiple = _this$props7.multiple;\n      var open = _this.state.open;\n      var ariaOptions = {\n        role: search ? 'combobox' : 'listbox',\n        'aria-busy': loading,\n        'aria-disabled': disabled,\n        'aria-expanded': !!open\n      };\n\n      if (ariaOptions.role === 'listbox') {\n        ariaOptions['aria-multiselectable'] = multiple;\n      }\n\n      return ariaOptions;\n    };\n\n    _this.clearSearchQuery = function () {\n      var searchQuery = _this.state.searchQuery;\n      if (searchQuery === undefined || searchQuery === '') return;\n\n      _this.setState({\n        searchQuery: ''\n      });\n    };\n\n    _this.handleLabelClick = function (e, labelProps) {\n      // prevent focusing search input on click\n      e.stopPropagation();\n\n      _this.setState({\n        selectedLabel: labelProps.value\n      });\n\n      _invoke(_this.props, 'onLabelClick', e, labelProps);\n    };\n\n    _this.handleLabelRemove = function (e, labelProps) {\n      // prevent focusing search input on click\n      e.stopPropagation();\n      var value = _this.state.value;\n\n      var newValue = _without(value, labelProps.value);\n\n      _this.setState({\n        value: newValue\n      });\n\n      _this.handleChange(e, newValue);\n    };\n\n    _this.getSelectedIndexAfterMove = function (offset, startIndex) {\n      if (startIndex === void 0) {\n        startIndex = _this.state.selectedIndex;\n      }\n\n      var options = getMenuOptions({\n        value: _this.state.value,\n        options: _this.props.options,\n        searchQuery: _this.state.searchQuery,\n        additionLabel: _this.props.additionLabel,\n        additionPosition: _this.props.additionPosition,\n        allowAdditions: _this.props.allowAdditions,\n        deburr: _this.props.deburr,\n        multiple: _this.props.multiple,\n        search: _this.props.search\n      }); // Prevent infinite loop\n      // TODO: remove left part of condition after children API will be removed\n\n      if (options === undefined || _every(options, 'disabled')) return;\n      var lastIndex = options.length - 1;\n      var wrapSelection = _this.props.wrapSelection; // next is after last, wrap to beginning\n      // next is before first, wrap to end\n\n      var nextIndex = startIndex + offset; // if 'wrapSelection' is set to false and selection is after last or before first, it just does not change\n\n      if (!wrapSelection && (nextIndex > lastIndex || nextIndex < 0)) {\n        nextIndex = startIndex;\n      } else if (nextIndex > lastIndex) {\n        nextIndex = 0;\n      } else if (nextIndex < 0) {\n        nextIndex = lastIndex;\n      }\n\n      if (options[nextIndex].disabled) {\n        return _this.getSelectedIndexAfterMove(offset, nextIndex);\n      }\n\n      return nextIndex;\n    };\n\n    _this.handleIconOverrides = function (predefinedProps) {\n      var clearable = _this.props.clearable;\n      var classes = cx(clearable && _this.hasValue() && 'clear', predefinedProps.className);\n      return {\n        className: classes,\n        onClick: function onClick(e) {\n          _invoke(predefinedProps, 'onClick', e, predefinedProps);\n\n          _this.handleIconClick(e);\n        }\n      };\n    };\n\n    _this.clearValue = function (e) {\n      var multiple = _this.props.multiple;\n      var newValue = multiple ? [] : '';\n\n      _this.setState({\n        value: newValue\n      });\n\n      _this.handleChange(e, newValue);\n    };\n\n    _this.computeSearchInputTabIndex = function () {\n      var _this$props8 = _this.props,\n          disabled = _this$props8.disabled,\n          tabIndex = _this$props8.tabIndex;\n      if (!_isNil(tabIndex)) return tabIndex;\n      return disabled ? -1 : 0;\n    };\n\n    _this.computeSearchInputWidth = function () {\n      var searchQuery = _this.state.searchQuery;\n\n      if (_this.sizerRef.current && searchQuery) {\n        // resize the search input, temporarily show the sizer so we can measure it\n        _this.sizerRef.current.style.display = 'inline';\n        _this.sizerRef.current.textContent = searchQuery;\n        var searchWidth = Math.ceil(_this.sizerRef.current.getBoundingClientRect().width);\n\n        _this.sizerRef.current.style.removeProperty('display');\n\n        return searchWidth;\n      }\n    };\n\n    _this.computeTabIndex = function () {\n      var _this$props9 = _this.props,\n          disabled = _this$props9.disabled,\n          search = _this$props9.search,\n          tabIndex = _this$props9.tabIndex; // don't set a root node tabIndex as the search input has its own tabIndex\n\n      if (search) return undefined;\n      if (disabled) return -1;\n      return _isNil(tabIndex) ? 0 : tabIndex;\n    };\n\n    _this.handleSearchInputOverrides = function (predefinedProps) {\n      return {\n        onChange: function onChange(e, inputProps) {\n          _invoke(predefinedProps, 'onChange', e, inputProps);\n\n          _this.handleSearchChange(e, inputProps);\n        }\n      };\n    };\n\n    _this.hasValue = function () {\n      var multiple = _this.props.multiple;\n      var value = _this.state.value;\n      return multiple ? !_isEmpty(value) : !_isNil(value) && value !== '';\n    };\n\n    _this.scrollSelectedItemIntoView = function () {\n      if (!_this.ref.current) return;\n\n      var menu = _this.ref.current.querySelector('.menu.visible');\n\n      if (!menu) return;\n      var item = menu.querySelector('.item.selected');\n      if (!item) return;\n      var isOutOfUpperView = item.offsetTop < menu.scrollTop;\n      var isOutOfLowerView = item.offsetTop + item.clientHeight > menu.scrollTop + menu.clientHeight;\n\n      if (isOutOfUpperView) {\n        menu.scrollTop = item.offsetTop;\n      } else if (isOutOfLowerView) {\n        // eslint-disable-next-line no-mixed-operators\n        menu.scrollTop = item.offsetTop + item.clientHeight - menu.clientHeight;\n      }\n    };\n\n    _this.setOpenDirection = function () {\n      if (!_this.ref.current) return;\n\n      var menu = _this.ref.current.querySelector('.menu.visible');\n\n      if (!menu) return;\n\n      var dropdownRect = _this.ref.current.getBoundingClientRect();\n\n      var menuHeight = menu.clientHeight;\n      var spaceAtTheBottom = document.documentElement.clientHeight - dropdownRect.top - dropdownRect.height - menuHeight;\n      var spaceAtTheTop = dropdownRect.top - menuHeight;\n      var upward = spaceAtTheBottom < 0 && spaceAtTheTop > spaceAtTheBottom; // set state only if there's a relevant difference\n\n      if (!upward !== !_this.state.upward) {\n        _this.setState({\n          upward: upward\n        });\n      }\n    };\n\n    _this.open = function (e, triggerSetState) {\n      if (e === void 0) {\n        e = null;\n      }\n\n      if (triggerSetState === void 0) {\n        triggerSetState = true;\n      }\n\n      var _this$props10 = _this.props,\n          disabled = _this$props10.disabled,\n          search = _this$props10.search;\n      if (disabled) return;\n      if (search) _invoke(_this.searchRef.current, 'focus');\n\n      _invoke(_this.props, 'onOpen', e, _this.props);\n\n      if (triggerSetState) {\n        _this.setState({\n          open: true\n        });\n      }\n\n      _this.scrollSelectedItemIntoView();\n    };\n\n    _this.close = function (e, callback) {\n      if (callback === void 0) {\n        callback = _this.handleClose;\n      }\n\n      if (_this.state.open) {\n        _invoke(_this.props, 'onClose', e, _this.props);\n\n        _this.setState({\n          open: false\n        }, callback);\n      }\n    };\n\n    _this.handleClose = function () {\n      var hasSearchFocus = document.activeElement === _this.searchRef.current; // https://github.com/Semantic-Org/Semantic-UI-React/issues/627\n      // Blur the Dropdown on close so it is blurred after selecting an item.\n      // This is to prevent it from re-opening when switching tabs after selecting an item.\n\n      if (!hasSearchFocus && _this.ref.current) {\n        _this.ref.current.blur();\n      }\n\n      var hasDropdownFocus = document.activeElement === _this.ref.current;\n      var hasFocus = hasSearchFocus || hasDropdownFocus; // We need to keep the virtual model in sync with the browser focus change\n      // https://github.com/Semantic-Org/Semantic-UI-React/issues/692\n\n      _this.setState({\n        focus: hasFocus\n      });\n    };\n\n    _this.toggle = function (e) {\n      return _this.state.open ? _this.close(e) : _this.open(e);\n    };\n\n    _this.renderText = function () {\n      var _this$props11 = _this.props,\n          multiple = _this$props11.multiple,\n          placeholder = _this$props11.placeholder,\n          search = _this$props11.search,\n          text = _this$props11.text;\n      var _this$state6 = _this.state,\n          searchQuery = _this$state6.searchQuery,\n          selectedIndex = _this$state6.selectedIndex,\n          value = _this$state6.value,\n          open = _this$state6.open;\n\n      var hasValue = _this.hasValue();\n\n      var classes = cx(placeholder && !hasValue && 'default', 'text', search && searchQuery && 'filtered');\n      var _text = placeholder;\n      var selectedItem;\n\n      if (text) {\n        _text = text;\n      } else if (open && !multiple) {\n        selectedItem = _this.getSelectedItem(selectedIndex);\n      } else if (hasValue) {\n        selectedItem = _this.getItemByValue(value);\n      }\n\n      return DropdownText.create(selectedItem ? renderItemContent(selectedItem) : _text, {\n        defaultProps: {\n          className: classes\n        }\n      });\n    };\n\n    _this.renderSearchInput = function () {\n      var _this$props12 = _this.props,\n          search = _this$props12.search,\n          searchInput = _this$props12.searchInput;\n      var searchQuery = _this.state.searchQuery;\n      return search && /*#__PURE__*/React.createElement(Ref, {\n        innerRef: _this.searchRef\n      }, DropdownSearchInput.create(searchInput, {\n        defaultProps: {\n          style: {\n            width: _this.computeSearchInputWidth()\n          },\n          tabIndex: _this.computeSearchInputTabIndex(),\n          value: searchQuery\n        },\n        overrideProps: _this.handleSearchInputOverrides\n      }));\n    };\n\n    _this.renderSearchSizer = function () {\n      var _this$props13 = _this.props,\n          search = _this$props13.search,\n          multiple = _this$props13.multiple;\n      return search && multiple && /*#__PURE__*/React.createElement(\"span\", {\n        className: \"sizer\",\n        ref: _this.sizerRef\n      });\n    };\n\n    _this.renderLabels = function () {\n      var _this$props14 = _this.props,\n          multiple = _this$props14.multiple,\n          renderLabel = _this$props14.renderLabel;\n      var _this$state7 = _this.state,\n          selectedLabel = _this$state7.selectedLabel,\n          value = _this$state7.value;\n\n      if (!multiple || _isEmpty(value)) {\n        return;\n      }\n\n      var selectedItems = _map(value, _this.getItemByValue);\n\n      // if no item could be found for a given state value the selected item will be undefined\n      // compact the selectedItems so we only have actual objects left\n      return _map(_compact(selectedItems), function (item, index) {\n        var defaultProps = {\n          active: item.value === selectedLabel,\n          as: 'a',\n          key: getKeyOrValue(item.key, item.value),\n          onClick: _this.handleLabelClick,\n          onRemove: _this.handleLabelRemove,\n          value: item.value\n        };\n        return Label.create(renderLabel(item, index, defaultProps), {\n          defaultProps: defaultProps\n        });\n      });\n    };\n\n    _this.renderOptions = function () {\n      var _this$props15 = _this.props,\n          lazyLoad = _this$props15.lazyLoad,\n          multiple = _this$props15.multiple,\n          search = _this$props15.search,\n          noResultsMessage = _this$props15.noResultsMessage;\n      var _this$state8 = _this.state,\n          open = _this$state8.open,\n          selectedIndex = _this$state8.selectedIndex,\n          value = _this$state8.value; // lazy load, only render options when open\n\n      if (lazyLoad && !open) return null;\n      var options = getMenuOptions({\n        value: _this.state.value,\n        options: _this.props.options,\n        searchQuery: _this.state.searchQuery,\n        additionLabel: _this.props.additionLabel,\n        additionPosition: _this.props.additionPosition,\n        allowAdditions: _this.props.allowAdditions,\n        deburr: _this.props.deburr,\n        multiple: _this.props.multiple,\n        search: _this.props.search\n      });\n\n      if (noResultsMessage !== null && search && _isEmpty(options)) {\n        return /*#__PURE__*/React.createElement(\"div\", {\n          className: \"message\"\n        }, noResultsMessage);\n      }\n\n      var isActive = multiple ? function (optValue) {\n        return _includes(value, optValue);\n      } : function (optValue) {\n        return optValue === value;\n      };\n      return _map(options, function (opt, i) {\n        return DropdownItem.create(_extends({\n          active: isActive(opt.value),\n          onClick: _this.handleItemClick,\n          selected: selectedIndex === i\n        }, opt, {\n          key: getKeyOrValue(opt.key, opt.value),\n          // Needed for handling click events on disabled items\n          style: _extends({}, opt.style, {\n            pointerEvents: 'all'\n          })\n        }));\n      });\n    };\n\n    _this.renderMenu = function () {\n      var _this$props16 = _this.props,\n          children = _this$props16.children,\n          direction = _this$props16.direction,\n          header = _this$props16.header;\n      var open = _this.state.open;\n\n      var ariaOptions = _this.getDropdownMenuAriaOptions(); // single menu child\n\n\n      if (!childrenUtils.isNil(children)) {\n        var menuChild = Children.only(children);\n        var className = cx(direction, useKeyOnly(open, 'visible'), menuChild.props.className);\n        return /*#__PURE__*/cloneElement(menuChild, _extends({\n          className: className\n        }, ariaOptions));\n      }\n\n      return /*#__PURE__*/React.createElement(DropdownMenu, _extends({}, ariaOptions, {\n        direction: direction,\n        open: open\n      }), DropdownHeader.create(header, {\n        autoGenerateKey: false\n      }), _this.renderOptions());\n    };\n\n    return _this;\n  }\n\n  var _proto = Dropdown.prototype;\n\n  _proto.getInitialAutoControlledState = function getInitialAutoControlledState() {\n    return {\n      focus: false,\n      searchQuery: ''\n    };\n  };\n\n  Dropdown.getAutoControlledStateFromProps = function getAutoControlledStateFromProps(nextProps, computedState, prevState) {\n    // These values are stored only for a comparison on next getAutoControlledStateFromProps()\n    var derivedState = {\n      __options: nextProps.options,\n      __value: computedState.value\n    }; // The selected index is only dependent:\n\n    var shouldComputeSelectedIndex = // On value change\n    !shallowEqual(prevState.__value, computedState.value) || // On option keys/values, we only check those properties to avoid recursive performance impacts.\n    // https://github.com/Semantic-Org/Semantic-UI-React/issues/3000\n    !_isEqual(getKeyAndValues(nextProps.options), getKeyAndValues(prevState.__options));\n\n    if (shouldComputeSelectedIndex) {\n      derivedState.selectedIndex = getSelectedIndex({\n        additionLabel: nextProps.additionLabel,\n        additionPosition: nextProps.additionPosition,\n        allowAdditions: nextProps.allowAdditions,\n        deburr: nextProps.deburr,\n        multiple: nextProps.multiple,\n        search: nextProps.search,\n        selectedIndex: computedState.selectedIndex,\n        value: computedState.value,\n        options: nextProps.options,\n        searchQuery: computedState.searchQuery\n      });\n    }\n\n    return derivedState;\n  };\n\n  _proto.componentDidMount = function componentDidMount() {\n    var open = this.state.open;\n\n    if (open) {\n      this.open(null, false);\n    }\n  };\n\n  _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {\n    return !shallowEqual(nextProps, this.props) || !shallowEqual(nextState, this.state);\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    // eslint-disable-line complexity\n    var _this$props17 = this.props,\n        closeOnBlur = _this$props17.closeOnBlur,\n        minCharacters = _this$props17.minCharacters,\n        openOnFocus = _this$props17.openOnFocus,\n        search = _this$props17.search;\n    /* eslint-disable no-console */\n\n    if (process.env.NODE_ENV !== 'production') {\n      // in development, validate value type matches dropdown type\n      var isNextValueArray = Array.isArray(this.props.value);\n\n      var hasValue = _has(this.props, 'value');\n\n      if (hasValue && this.props.multiple && !isNextValueArray) {\n        console.error('Dropdown `value` must be an array when `multiple` is set.' + (\" Received type: `\" + Object.prototype.toString.call(this.props.value) + \"`.\"));\n      } else if (hasValue && !this.props.multiple && isNextValueArray) {\n        console.error('Dropdown `value` must not be an array when `multiple` is not set.' + ' Either set `multiple={true}` or use a string or number value.');\n      }\n    }\n    /* eslint-enable no-console */\n    // focused / blurred\n\n\n    if (!prevState.focus && this.state.focus) {\n      if (!this.isMouseDown) {\n        var openable = !search || search && minCharacters === 1 && !this.state.open;\n        if (openOnFocus && openable) this.open();\n      }\n    } else if (prevState.focus && !this.state.focus) {\n      if (!this.isMouseDown && closeOnBlur) {\n        this.close();\n      }\n    } // opened / closed\n\n\n    if (!prevState.open && this.state.open) {\n      this.setOpenDirection();\n      this.scrollSelectedItemIntoView();\n    } else if (prevState.open && !this.state.open) {}\n\n    if (prevState.selectedIndex !== this.state.selectedIndex) {\n      this.scrollSelectedItemIntoView();\n    }\n  } // ----------------------------------------\n  // Document Event Handlers\n  // ----------------------------------------\n  // onChange needs to receive a value\n  // can't rely on props.value if we are controlled\n  ;\n\n  _proto.getDropdownMenuAriaOptions = function getDropdownMenuAriaOptions() {\n    var _this$props18 = this.props,\n        search = _this$props18.search,\n        multiple = _this$props18.multiple;\n    var ariaOptions = {};\n\n    if (search) {\n      ariaOptions['aria-multiselectable'] = multiple;\n      ariaOptions.role = 'listbox';\n    }\n\n    return ariaOptions;\n  } // ----------------------------------------\n  // Setters\n  // ----------------------------------------\n  ;\n\n  _proto.render = function render() {\n    var _this$props19 = this.props,\n        basic = _this$props19.basic,\n        button = _this$props19.button,\n        className = _this$props19.className,\n        compact = _this$props19.compact,\n        disabled = _this$props19.disabled,\n        error = _this$props19.error,\n        fluid = _this$props19.fluid,\n        floating = _this$props19.floating,\n        icon = _this$props19.icon,\n        inline = _this$props19.inline,\n        item = _this$props19.item,\n        labeled = _this$props19.labeled,\n        loading = _this$props19.loading,\n        multiple = _this$props19.multiple,\n        pointing = _this$props19.pointing,\n        search = _this$props19.search,\n        selection = _this$props19.selection,\n        scrolling = _this$props19.scrolling,\n        simple = _this$props19.simple,\n        trigger = _this$props19.trigger;\n    var _this$state9 = this.state,\n        focus = _this$state9.focus,\n        open = _this$state9.open,\n        upward = _this$state9.upward; // Classes\n\n    var classes = cx('ui', useKeyOnly(open, 'active visible'), useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(loading, 'loading'), useKeyOnly(basic, 'basic'), useKeyOnly(button, 'button'), useKeyOnly(compact, 'compact'), useKeyOnly(fluid, 'fluid'), useKeyOnly(floating, 'floating'), useKeyOnly(inline, 'inline'), // TODO: consider augmentation to render Dropdowns as Button/Menu, solves icon/link item issues\n    // https://github.com/Semantic-Org/Semantic-UI-React/issues/401#issuecomment-240487229\n    // TODO: the icon class is only required when a dropdown is a button\n    // useKeyOnly(icon, 'icon'),\n    useKeyOnly(labeled, 'labeled'), useKeyOnly(item, 'item'), useKeyOnly(multiple, 'multiple'), useKeyOnly(search, 'search'), useKeyOnly(selection, 'selection'), useKeyOnly(simple, 'simple'), useKeyOnly(scrolling, 'scrolling'), useKeyOnly(upward, 'upward'), useKeyOrValueAndKey(pointing, 'pointing'), 'dropdown', className);\n    var rest = getUnhandledProps(Dropdown, this.props);\n    var ElementType = getElementType(Dropdown, this.props);\n    var ariaOptions = this.getDropdownAriaOptions(ElementType, this.props);\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.ref\n    }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, ariaOptions, {\n      className: classes,\n      onBlur: this.handleBlur,\n      onClick: this.handleClick,\n      onKeyDown: this.handleKeyDown,\n      onMouseDown: this.handleMouseDown,\n      onFocus: this.handleFocus,\n      onChange: this.handleChange,\n      tabIndex: this.computeTabIndex()\n    }), this.renderLabels(), this.renderSearchInput(), this.renderSearchSizer(), trigger || this.renderText(), Icon.create(icon, {\n      overrideProps: this.handleIconOverrides,\n      autoGenerateKey: false\n    }), this.renderMenu(), open && /*#__PURE__*/React.createElement(EventStack, {\n      name: \"keydown\",\n      on: this.closeOnEscape\n    }), open && /*#__PURE__*/React.createElement(EventStack, {\n      name: \"click\",\n      on: this.closeOnDocumentClick\n    }), focus && /*#__PURE__*/React.createElement(EventStack, {\n      name: \"keydown\",\n      on: this.removeItemOnBackspace\n    }), focus && !open && /*#__PURE__*/React.createElement(EventStack, {\n      name: \"keydown\",\n      on: this.openOnSpace\n    })));\n  };\n\n  return Dropdown;\n}(Component);\n\nDropdown.handledProps = [\"additionLabel\", \"additionPosition\", \"allowAdditions\", \"as\", \"basic\", \"button\", \"children\", \"className\", \"clearable\", \"closeOnBlur\", \"closeOnChange\", \"closeOnEscape\", \"compact\", \"deburr\", \"defaultOpen\", \"defaultSearchQuery\", \"defaultSelectedLabel\", \"defaultUpward\", \"defaultValue\", \"direction\", \"disabled\", \"error\", \"floating\", \"fluid\", \"header\", \"icon\", \"inline\", \"item\", \"labeled\", \"lazyLoad\", \"loading\", \"minCharacters\", \"multiple\", \"noResultsMessage\", \"onAddItem\", \"onBlur\", \"onChange\", \"onClick\", \"onClose\", \"onFocus\", \"onLabelClick\", \"onMouseDown\", \"onOpen\", \"onSearchChange\", \"open\", \"openOnFocus\", \"options\", \"placeholder\", \"pointing\", \"renderLabel\", \"scrolling\", \"search\", \"searchInput\", \"searchQuery\", \"selectOnBlur\", \"selectOnNavigation\", \"selectedLabel\", \"selection\", \"simple\", \"tabIndex\", \"text\", \"trigger\", \"upward\", \"value\", \"wrapSelection\"];\nexport { Dropdown as default };\nDropdown.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Label prefixed to an option added by a user. */\n  additionLabel: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),\n\n  /** Position of the `Add: ...` option in the dropdown list ('top' or 'bottom'). */\n  additionPosition: PropTypes.oneOf(['top', 'bottom']),\n\n  /**\n   * Allow user additions to the list of options (boolean).\n   * Requires the use of `selection`, `options` and `search`.\n   */\n  allowAdditions: customPropTypes.every([customPropTypes.demand(['options', 'selection', 'search']), PropTypes.bool]),\n\n  /** A Dropdown can reduce its complexity. */\n  basic: PropTypes.bool,\n\n  /** Format the Dropdown to appear as a button. */\n  button: PropTypes.bool,\n\n  /** Primary content. */\n  children: customPropTypes.every([customPropTypes.disallow(['options', 'selection']), customPropTypes.givenProps({\n    children: PropTypes.any.isRequired\n  }, PropTypes.element.isRequired)]),\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Using the clearable setting will let users remove their selection from a dropdown. */\n  clearable: PropTypes.bool,\n\n  /** Whether or not the menu should close when the dropdown is blurred. */\n  closeOnBlur: PropTypes.bool,\n\n  /** Whether or not the dropdown should close when the escape key is pressed. */\n  closeOnEscape: PropTypes.bool,\n\n  /**\n   * Whether or not the menu should close when a value is selected from the dropdown.\n   * By default, multiple selection dropdowns will remain open on change, while single\n   * selection dropdowns will close on change.\n   */\n  closeOnChange: PropTypes.bool,\n\n  /** A compact dropdown has no minimum width. */\n  compact: PropTypes.bool,\n\n  /** Whether or not the dropdown should strip diacritics in options and input search */\n  deburr: PropTypes.bool,\n\n  /** Initial value of open. */\n  defaultOpen: PropTypes.bool,\n\n  /** Initial value of searchQuery. */\n  defaultSearchQuery: PropTypes.string,\n\n  /** Currently selected label in multi-select. */\n  defaultSelectedLabel: customPropTypes.every([customPropTypes.demand(['multiple']), PropTypes.oneOfType([PropTypes.number, PropTypes.string])]),\n\n  /** Initial value of upward. */\n  defaultUpward: PropTypes.bool,\n\n  /** Initial value or value array if multiple. */\n  defaultValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.bool, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]))]),\n\n  /** A dropdown menu can open to the left or to the right. */\n  direction: PropTypes.oneOf(['left', 'right']),\n\n  /** A disabled dropdown menu or item does not allow user interaction. */\n  disabled: PropTypes.bool,\n\n  /** An errored dropdown can alert a user to a problem. */\n  error: PropTypes.bool,\n\n  /** A dropdown menu can contain floated content. */\n  floating: PropTypes.bool,\n\n  /** A dropdown can take the full width of its parent */\n  fluid: PropTypes.bool,\n\n  /** A dropdown menu can contain a header. */\n  header: PropTypes.node,\n\n  /** Shorthand for Icon. */\n  icon: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),\n\n  /** A dropdown can be formatted to appear inline in other content. */\n  inline: PropTypes.bool,\n\n  /** A dropdown can be formatted as a Menu item. */\n  item: PropTypes.bool,\n\n  /** A dropdown can be labeled. */\n  labeled: PropTypes.bool,\n\n  /** A dropdown can defer rendering its options until it is open. */\n  lazyLoad: PropTypes.bool,\n\n  /** A dropdown can show that it is currently loading data. */\n  loading: PropTypes.bool,\n\n  /** The minimum characters for a search to begin showing results. */\n  minCharacters: PropTypes.number,\n\n  /** A selection dropdown can allow multiple selections. */\n  multiple: PropTypes.bool,\n\n  /** Message to display when there are no results. */\n  noResultsMessage: PropTypes.node,\n\n  /**\n   * Called when a user adds a new item. Use this to update the options list.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and the new item's value.\n   */\n  onAddItem: PropTypes.func,\n\n  /**\n   * Called on blur.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onBlur: PropTypes.func,\n\n  /**\n   * Called when the user attempts to change the value.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and proposed value.\n   */\n  onChange: PropTypes.func,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Called when a close event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClose: PropTypes.func,\n\n  /**\n   * Called on focus.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onFocus: PropTypes.func,\n\n  /**\n   * Called when a multi-select label is clicked.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All label props.\n   */\n  onLabelClick: PropTypes.func,\n\n  /**\n   * Called on mousedown.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onMouseDown: PropTypes.func,\n\n  /**\n   * Called when an open event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onOpen: PropTypes.func,\n\n  /**\n   * Called on search input change.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props, includes current value of searchQuery.\n   */\n  onSearchChange: PropTypes.func,\n\n  /** Controls whether or not the dropdown menu is displayed. */\n  open: PropTypes.bool,\n\n  /** Whether or not the menu should open when the dropdown is focused. */\n  openOnFocus: PropTypes.bool,\n\n  /** Array of Dropdown.Item props e.g. `{ text: '', value: '' }` */\n  options: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.arrayOf(PropTypes.shape(DropdownItem.propTypes))]),\n\n  /** Placeholder text. */\n  placeholder: PropTypes.string,\n\n  /** A dropdown can be formatted so that its menu is pointing. */\n  pointing: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right', 'top', 'top left', 'top right', 'bottom', 'bottom left', 'bottom right'])]),\n\n  /**\n   * Mapped over the active items and returns shorthand for the active item Labels.\n   * Only applies to `multiple` Dropdowns.\n   *\n   * @param {object} item - A currently active dropdown item.\n   * @param {number} index - The current index.\n   * @param {object} defaultLabelProps - The default props for an active item Label.\n   * @returns {*} Shorthand for a Label.\n   */\n  renderLabel: PropTypes.func,\n\n  /** A dropdown can have its menu scroll. */\n  scrolling: PropTypes.bool,\n\n  /**\n   * A selection dropdown can allow a user to search through a large list of choices.\n   * Pass a function here to replace the default search.\n   */\n  search: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),\n\n  /** A shorthand for a search input. */\n  searchInput: PropTypes.oneOfType([PropTypes.array, PropTypes.node, PropTypes.object]),\n\n  /** Current value of searchQuery. Creates a controlled component. */\n  searchQuery: PropTypes.string,\n  // TODO 'searchInMenu' or 'search='in menu' or ???  How to handle this markup and functionality?\n\n  /** Define whether the highlighted item should be selected on blur. */\n  selectOnBlur: PropTypes.bool,\n\n  /**\n   * Whether or not to change the value when navigating the menu using arrow keys.\n   * Setting to false will require enter or left click to confirm a choice.\n   */\n  selectOnNavigation: PropTypes.bool,\n\n  /** Currently selected label in multi-select. */\n  selectedLabel: customPropTypes.every([customPropTypes.demand(['multiple']), PropTypes.oneOfType([PropTypes.string, PropTypes.number])]),\n\n  /** A dropdown can be used to select between choices in a form. */\n  selection: customPropTypes.every([customPropTypes.disallow(['children']), customPropTypes.demand(['options']), PropTypes.bool]),\n\n  /** A simple dropdown can open without Javascript. */\n  simple: PropTypes.bool,\n\n  /** A dropdown can receive focus. */\n  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** The text displayed in the dropdown, usually for the active item. */\n  text: PropTypes.string,\n\n  /** Custom element to trigger the menu to become visible. Takes place of 'text'. */\n  trigger: customPropTypes.every([customPropTypes.disallow(['selection', 'text']), PropTypes.node]),\n\n  /** Current value or value array if multiple. Creates a controlled component. */\n  value: PropTypes.oneOfType([PropTypes.bool, PropTypes.string, PropTypes.number, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.bool, PropTypes.string, PropTypes.number]))]),\n\n  /** Controls whether the dropdown will open upward. */\n  upward: PropTypes.bool,\n\n  /**\n   * A dropdown will go to the last element when ArrowUp is pressed on the first,\n   * or go to the first when ArrowDown is pressed on the last( aka infinite selection )\n   */\n  wrapSelection: PropTypes.bool\n} : {};\nDropdown.defaultProps = {\n  additionLabel: 'Add ',\n  additionPosition: 'top',\n  closeOnBlur: true,\n  closeOnEscape: true,\n  deburr: false,\n  icon: 'dropdown',\n  minCharacters: 1,\n  noResultsMessage: 'No results found.',\n  openOnFocus: true,\n  renderLabel: renderItemContent,\n  searchInput: 'text',\n  selectOnBlur: true,\n  selectOnNavigation: true,\n  wrapSelection: true\n};\nDropdown.autoControlledProps = ['open', 'searchQuery', 'selectedLabel', 'value', 'upward'];\nDropdown.Divider = DropdownDivider;\nDropdown.Header = DropdownHeader;\nDropdown.Item = DropdownItem;\nDropdown.Menu = DropdownMenu;\nDropdown.SearchInput = DropdownSearchInput;\nDropdown.Text = DropdownText;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps } from '../../lib';\n/**\n * A dropdown menu can contain dividers to separate related content.\n */\n\nfunction DropdownDivider(props) {\n  var className = props.className;\n  var classes = cx('divider', className);\n  var rest = getUnhandledProps(DropdownDivider, props);\n  var ElementType = getElementType(DropdownDivider, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }));\n}\n\nDropdownDivider.handledProps = [\"as\", \"className\"];\nDropdownDivider.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string\n} : {};\nexport default DropdownDivider;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A dropdown menu can contain a header.\n */\n\nfunction DropdownHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      icon = props.icon;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(DropdownHeader, props);\n  var ElementType = getElementType(DropdownHeader, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), Icon.create(icon, {\n    autoGenerateKey: false\n  }), content);\n}\n\nDropdownHeader.handledProps = [\"as\", \"children\", \"className\", \"content\", \"icon\"];\nDropdownHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function) */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for Icon. */\n  icon: customPropTypes.itemShorthand\n} : {};\nDropdownHeader.create = createShorthandFactory(DropdownHeader, function (content) {\n  return {\n    content: content\n  };\n});\nexport default DropdownHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isNil from \"lodash/isNil\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthand, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Flag from '../../elements/Flag';\nimport Icon from '../../elements/Icon';\nimport Image from '../../elements/Image';\nimport Label from '../../elements/Label';\n/**\n * An item sub-component for Dropdown component.\n */\n\nvar DropdownItem = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(DropdownItem, _Component);\n\n  function DropdownItem() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = DropdownItem.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content,\n        disabled = _this$props.disabled,\n        description = _this$props.description,\n        flag = _this$props.flag,\n        icon = _this$props.icon,\n        image = _this$props.image,\n        label = _this$props.label,\n        selected = _this$props.selected,\n        text = _this$props.text;\n    var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(selected, 'selected'), 'item', className); // add default dropdown icon if item contains another menu\n\n    var iconName = _isNil(icon) ? childrenUtils.someByType(children, 'DropdownMenu') && 'dropdown' : icon;\n    var rest = getUnhandledProps(DropdownItem, this.props);\n    var ElementType = getElementType(DropdownItem, this.props);\n    var ariaOptions = {\n      role: 'option',\n      'aria-disabled': disabled,\n      'aria-checked': active,\n      'aria-selected': selected\n    };\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, ariaOptions, {\n        className: classes,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    var flagElement = Flag.create(flag, {\n      autoGenerateKey: false\n    });\n    var iconElement = Icon.create(iconName, {\n      autoGenerateKey: false\n    });\n    var imageElement = Image.create(image, {\n      autoGenerateKey: false\n    });\n    var labelElement = Label.create(label, {\n      autoGenerateKey: false\n    });\n    var descriptionElement = createShorthand('span', function (val) {\n      return {\n        children: val\n      };\n    }, description, {\n      defaultProps: {\n        className: 'description'\n      },\n      autoGenerateKey: false\n    });\n    var textElement = createShorthand('span', function (val) {\n      return {\n        children: val\n      };\n    }, childrenUtils.isNil(content) ? text : content, {\n      defaultProps: {\n        className: 'text'\n      },\n      autoGenerateKey: false\n    });\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, ariaOptions, {\n      className: classes,\n      onClick: this.handleClick\n    }), imageElement, iconElement, flagElement, labelElement, descriptionElement, textElement);\n  };\n\n  return DropdownItem;\n}(Component);\n\nDropdownItem.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"description\", \"disabled\", \"flag\", \"icon\", \"image\", \"label\", \"onClick\", \"selected\", \"text\", \"value\"];\nDropdownItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Style as the currently chosen item. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Additional text with less emphasis. */\n  description: customPropTypes.itemShorthand,\n\n  /** A dropdown item can be disabled. */\n  disabled: PropTypes.bool,\n\n  /** Shorthand for Flag. */\n  flag: customPropTypes.itemShorthand,\n\n  /** Shorthand for Icon. */\n  icon: customPropTypes.itemShorthand,\n\n  /** Shorthand for Image. */\n  image: customPropTypes.itemShorthand,\n\n  /** Shorthand for Label. */\n  label: customPropTypes.itemShorthand,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * The item currently selected by keyboard shortcut.\n   * This is not the active item.\n   */\n  selected: PropTypes.bool,\n\n  /** Display text. */\n  text: customPropTypes.contentShorthand,\n\n  /** Stored value. */\n  value: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string])\n} : {};\nDropdownItem.create = createShorthandFactory(DropdownItem, function (opts) {\n  return opts;\n});\nexport default DropdownItem;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A dropdown menu can contain a menu.\n */\n\nfunction DropdownMenu(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      direction = props.direction,\n      open = props.open,\n      scrolling = props.scrolling;\n  var classes = cx(direction, useKeyOnly(open, 'visible'), useKeyOnly(scrolling, 'scrolling'), 'menu transition', className);\n  var rest = getUnhandledProps(DropdownMenu, props);\n  var ElementType = getElementType(DropdownMenu, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nDropdownMenu.handledProps = [\"as\", \"children\", \"className\", \"content\", \"direction\", \"open\", \"scrolling\"];\nDropdownMenu.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A dropdown menu can open to the left or to the right. */\n  direction: PropTypes.oneOf(['left', 'right']),\n\n  /** Whether or not the dropdown menu is displayed. */\n  open: PropTypes.bool,\n\n  /** A dropdown menu can scroll. */\n  scrolling: PropTypes.bool\n} : {};\nexport default DropdownMenu;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport _get from \"lodash/get\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { createShorthandFactory, getUnhandledProps } from '../../lib';\n/**\n * A search item sub-component for Dropdown component.\n */\n\nvar DropdownSearchInput = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(DropdownSearchInput, _Component);\n\n  function DropdownSearchInput() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleChange = function (e) {\n      var value = _get(e, 'target.value');\n\n      _invoke(_this.props, 'onChange', e, _extends({}, _this.props, {\n        value: value\n      }));\n    };\n\n    return _this;\n  }\n\n  var _proto = DropdownSearchInput.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        autoComplete = _this$props.autoComplete,\n        className = _this$props.className,\n        tabIndex = _this$props.tabIndex,\n        type = _this$props.type,\n        value = _this$props.value;\n    var classes = cx('search', className);\n    var rest = getUnhandledProps(DropdownSearchInput, this.props);\n    return /*#__PURE__*/React.createElement(\"input\", _extends({}, rest, {\n      \"aria-autocomplete\": \"list\",\n      autoComplete: autoComplete,\n      className: classes,\n      onChange: this.handleChange,\n      tabIndex: tabIndex,\n      type: type,\n      value: value\n    }));\n  };\n\n  return DropdownSearchInput;\n}(Component);\n\nDropdownSearchInput.handledProps = [\"as\", \"autoComplete\", \"className\", \"tabIndex\", \"type\", \"value\"];\nDropdownSearchInput.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An input can have the auto complete. */\n  autoComplete: PropTypes.string,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** An input can receive focus. */\n  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** The HTML input type. */\n  type: PropTypes.string,\n\n  /** Stored value. */\n  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n} : {};\nDropdownSearchInput.defaultProps = {\n  autoComplete: 'off',\n  type: 'text'\n};\nDropdownSearchInput.create = createShorthandFactory(DropdownSearchInput, function (type) {\n  return {\n    type: type\n  };\n});\nexport default DropdownSearchInput;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A dropdown contains a selected value.\n */\n\nfunction DropdownText(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('divider', className);\n  var rest = getUnhandledProps(DropdownText, props);\n  var ElementType = getElementType(DropdownText, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({\n    \"aria-atomic\": true,\n    \"aria-live\": \"polite\",\n    role: \"alert\"\n  }, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nDropdownText.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nDropdownText.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nDropdownText.create = createShorthandFactory(DropdownText, function (val) {\n  return {\n    content: val\n  };\n});\nexport default DropdownText;","import _default from './Dropdown';\nexport { _default as default };","import _some from \"lodash/some\";\nimport _escapeRegExp from \"lodash/escapeRegExp\";\nimport _deburr from \"lodash/deburr\";\nimport _isFunction from \"lodash/isFunction\";\nimport _includes from \"lodash/includes\";\nimport _filter from \"lodash/filter\";\nimport React from 'react'; // There are times when we need to calculate the options based on a value\n// that hasn't yet been persisted to state.\n\nexport default function getMenuOptions(config) {\n  var additionLabel = config.additionLabel,\n      additionPosition = config.additionPosition,\n      allowAdditions = config.allowAdditions,\n      deburr = config.deburr,\n      multiple = config.multiple,\n      options = config.options,\n      search = config.search,\n      searchQuery = config.searchQuery,\n      value = config.value;\n  var filteredOptions = options; // filter out active options\n\n  if (multiple) {\n    filteredOptions = _filter(filteredOptions, function (opt) {\n      return !_includes(value, opt.value);\n    });\n  } // filter by search query\n\n\n  if (search && searchQuery) {\n    if (_isFunction(search)) {\n      filteredOptions = search(filteredOptions, searchQuery);\n    } else {\n      // remove diacritics on search input and options, if deburr prop is set\n      var strippedQuery = deburr ? _deburr(searchQuery) : searchQuery;\n      var re = new RegExp(_escapeRegExp(strippedQuery), 'i');\n      filteredOptions = _filter(filteredOptions, function (opt) {\n        return re.test(deburr ? _deburr(opt.text) : opt.text);\n      });\n    }\n  } // insert the \"add\" item\n\n\n  if (allowAdditions && search && searchQuery && !_some(filteredOptions, {\n    text: searchQuery\n  })) {\n    var additionLabelElement = /*#__PURE__*/React.isValidElement(additionLabel) ? /*#__PURE__*/React.cloneElement(additionLabel, {\n      key: 'addition-label'\n    }) : additionLabel || '';\n    var addItem = {\n      key: 'addition',\n      // by using an array, we can pass multiple elements, but when doing so\n      // we must specify a `key` for React to know which one is which\n      text: [additionLabelElement, /*#__PURE__*/React.createElement(\"b\", {\n        key: \"addition-query\"\n      }, searchQuery)],\n      value: searchQuery,\n      className: 'addition',\n      'data-additional': true\n    };\n    if (additionPosition === 'top') filteredOptions.unshift(addItem);else filteredOptions.push(addItem);\n  }\n\n  return filteredOptions;\n}\ngetMenuOptions.handledProps = [];","import _includes from \"lodash/includes\";\nimport _find from \"lodash/find\";\nimport _findIndex from \"lodash/findIndex\";\nimport _reduce from \"lodash/reduce\";\nimport getMenuOptions from './getMenuOptions';\nexport default function getSelectedIndex(config) {\n  var additionLabel = config.additionLabel,\n      additionPosition = config.additionPosition,\n      allowAdditions = config.allowAdditions,\n      deburr = config.deburr,\n      multiple = config.multiple,\n      options = config.options,\n      search = config.search,\n      searchQuery = config.searchQuery,\n      selectedIndex = config.selectedIndex,\n      value = config.value;\n  var menuOptions = getMenuOptions({\n    value: value,\n    options: options,\n    searchQuery: searchQuery,\n    additionLabel: additionLabel,\n    additionPosition: additionPosition,\n    allowAdditions: allowAdditions,\n    deburr: deburr,\n    multiple: multiple,\n    search: search\n  });\n\n  var enabledIndexes = _reduce(menuOptions, function (memo, item, index) {\n    if (!item.disabled) memo.push(index);\n    return memo;\n  }, []);\n\n  var newSelectedIndex; // update the selected index\n\n  if (!selectedIndex || selectedIndex < 0) {\n    var firstIndex = enabledIndexes[0]; // Select the currently active item, if none, use the first item.\n    // Multiple selects remove active items from the list,\n    // their initial selected index should be 0.\n\n    newSelectedIndex = multiple ? firstIndex : _findIndex(menuOptions, ['value', value]) || enabledIndexes[0];\n  } else if (multiple) {\n    newSelectedIndex = _find(enabledIndexes, function (index) {\n      return index >= selectedIndex;\n    }); // multiple selects remove options from the menu as they are made active\n    // keep the selected index within range of the remaining items\n\n    if (selectedIndex >= menuOptions.length - 1) {\n      newSelectedIndex = enabledIndexes[enabledIndexes.length - 1];\n    }\n  } else {\n    var activeIndex = _findIndex(menuOptions, ['value', value]); // regular selects can only have one active item\n    // set the selected index to the currently active item\n\n\n    newSelectedIndex = _includes(enabledIndexes, activeIndex) ? activeIndex : undefined;\n  }\n\n  if (!newSelectedIndex || newSelectedIndex < 0) {\n    newSelectedIndex = enabledIndexes[0];\n  }\n\n  return newSelectedIndex;\n}","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, childrenUtils, createHTMLIframe, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * An embed displays content from other websites like YouTube videos or Google Maps.\n */\n\nvar Embed = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Embed, _Component);\n\n  function Embed() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var onClick = _this.props.onClick;\n      var active = _this.state.active;\n      if (onClick) onClick(e, _extends({}, _this.props, {\n        active: true\n      }));\n      if (!active) _this.setState({\n        active: true\n      });\n    };\n\n    return _this;\n  }\n\n  var _proto = Embed.prototype;\n\n  _proto.getSrc = function getSrc() {\n    var _this$props = this.props,\n        _this$props$autoplay = _this$props.autoplay,\n        autoplay = _this$props$autoplay === void 0 ? true : _this$props$autoplay,\n        _this$props$brandedUI = _this$props.brandedUI,\n        brandedUI = _this$props$brandedUI === void 0 ? false : _this$props$brandedUI,\n        _this$props$color = _this$props.color,\n        color = _this$props$color === void 0 ? '#444444' : _this$props$color,\n        _this$props$hd = _this$props.hd,\n        hd = _this$props$hd === void 0 ? true : _this$props$hd,\n        id = _this$props.id,\n        source = _this$props.source,\n        url = _this$props.url;\n\n    if (source === 'youtube') {\n      return [\"//www.youtube.com/embed/\" + id, '?autohide=true', \"&amp;autoplay=\" + autoplay, \"&amp;color=\" + encodeURIComponent(color), \"&amp;hq=\" + hd, '&amp;jsapi=false', \"&amp;modestbranding=\" + brandedUI, \"&amp;rel=\" + (brandedUI ? 0 : 1)].join('');\n    }\n\n    if (source === 'vimeo') {\n      return [\"//player.vimeo.com/video/\" + id, '?api=false', \"&amp;autoplay=\" + autoplay, '&amp;byline=false', \"&amp;color=\" + encodeURIComponent(color), '&amp;portrait=false', '&amp;title=false'].join('');\n    }\n\n    return url;\n  };\n\n  _proto.render = function render() {\n    var _this$props2 = this.props,\n        aspectRatio = _this$props2.aspectRatio,\n        className = _this$props2.className,\n        icon = _this$props2.icon,\n        placeholder = _this$props2.placeholder;\n    var active = this.state.active;\n    var classes = cx('ui', aspectRatio, useKeyOnly(active, 'active'), 'embed', className);\n    var rest = getUnhandledProps(Embed, this.props);\n    var ElementType = getElementType(Embed, this.props);\n    var iconShorthand = icon !== undefined ? icon : 'video play';\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick\n    }), Icon.create(iconShorthand, {\n      autoGenerateKey: false\n    }), placeholder && /*#__PURE__*/React.createElement(\"img\", {\n      className: \"placeholder\",\n      src: placeholder\n    }), this.renderEmbed());\n  };\n\n  _proto.renderEmbed = function renderEmbed() {\n    var _this$props3 = this.props,\n        children = _this$props3.children,\n        content = _this$props3.content,\n        iframe = _this$props3.iframe,\n        source = _this$props3.source;\n    var active = this.state.active;\n    if (!active) return null;\n    if (!childrenUtils.isNil(children)) return /*#__PURE__*/React.createElement(\"div\", {\n      className: \"embed\"\n    }, children);\n    if (!childrenUtils.isNil(content)) return /*#__PURE__*/React.createElement(\"div\", {\n      className: \"embed\"\n    }, content);\n    return /*#__PURE__*/React.createElement(\"div\", {\n      className: \"embed\"\n    }, createHTMLIframe(childrenUtils.isNil(iframe) ? this.getSrc() : iframe, {\n      defaultProps: {\n        allowFullScreen: false,\n        frameBorder: 0,\n        height: '100%',\n        scrolling: 'no',\n        src: this.getSrc(),\n        title: \"Embedded content from \" + source + \".\",\n        width: '100%'\n      },\n      autoGenerateKey: false\n    }));\n  };\n\n  return Embed;\n}(Component);\n\nEmbed.handledProps = [\"active\", \"as\", \"aspectRatio\", \"autoplay\", \"brandedUI\", \"children\", \"className\", \"color\", \"content\", \"defaultActive\", \"hd\", \"icon\", \"id\", \"iframe\", \"onClick\", \"placeholder\", \"source\", \"url\"];\nexport { Embed as default };\nEmbed.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** An embed can be active. */\n  active: PropTypes.bool,\n\n  /** An embed can specify an alternative aspect ratio. */\n  aspectRatio: PropTypes.oneOf(['4:3', '16:9', '21:9']),\n\n  /** Setting to true or false will force autoplay. */\n  autoplay: customPropTypes.every([customPropTypes.demand(['source']), PropTypes.bool]),\n\n  /** Whether to show networks branded UI like title cards, or after video calls to action. */\n  brandedUI: customPropTypes.every([customPropTypes.demand(['source']), PropTypes.bool]),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Specifies a default chrome color with Vimeo or YouTube. */\n  color: customPropTypes.every([customPropTypes.demand(['source']), PropTypes.string]),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Initial value of active. */\n  defaultActive: PropTypes.bool,\n\n  /** Whether to prefer HD content. */\n  hd: customPropTypes.every([customPropTypes.demand(['source']), PropTypes.bool]),\n\n  /** Specifies an icon to use with placeholder content. */\n  icon: customPropTypes.itemShorthand,\n\n  /** Specifies an id for source. */\n  id: customPropTypes.every([customPropTypes.demand(['source']), PropTypes.string]),\n\n  /** Shorthand for HTML iframe. */\n  iframe: customPropTypes.every([customPropTypes.demand(['source']), customPropTypes.itemShorthand]),\n\n  /**\n   * Сalled on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and proposed value.\n   */\n  onClick: PropTypes.func,\n\n  /** A placeholder image for embed. */\n  placeholder: PropTypes.string,\n\n  /** Specifies a source to use. */\n  source: customPropTypes.every([customPropTypes.disallow(['sourceUrl']), PropTypes.oneOf(['youtube', 'vimeo'])]),\n\n  /** Specifies a url to use for embed. */\n  url: customPropTypes.every([customPropTypes.disallow(['source']), PropTypes.string])\n} : {};\nEmbed.autoControlledProps = ['active'];","import _default from './Embed';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _isPlainObject from \"lodash/isPlainObject\";\nimport _pick from \"lodash/pick\";\nimport _includes from \"lodash/includes\";\nimport _reduce from \"lodash/reduce\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _invoke from \"lodash/invoke\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { createRef, isValidElement } from 'react';\nimport shallowEqual from 'shallowequal';\nimport { ModernAutoControlledComponent as Component, childrenUtils, customPropTypes, doesNodeContainClick, eventStack, getElementType, getUnhandledProps, isBrowser, useKeyOnly } from '../../lib';\nimport Icon from '../../elements/Icon';\nimport Portal from '../../addons/Portal';\nimport ModalActions from './ModalActions';\nimport ModalContent from './ModalContent';\nimport ModalDescription from './ModalDescription';\nimport ModalDimmer from './ModalDimmer';\nimport ModalHeader from './ModalHeader';\nimport { canFit, getLegacyStyles, isLegacy } from './utils';\n\n/**\n * A modal displays content that temporarily blocks interactions with the main view of a site.\n * @see Confirm\n * @see Portal\n */\nvar Modal = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Modal, _Component);\n\n  function Modal() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.legacy = isBrowser() && isLegacy();\n    _this.ref = /*#__PURE__*/createRef();\n    _this.dimmerRef = /*#__PURE__*/createRef();\n    _this.latestDocumentMouseDownEvent = null;\n\n    _this.getMountNode = function () {\n      return isBrowser() ? _this.props.mountNode || document.body : null;\n    };\n\n    _this.handleActionsOverrides = function (predefinedProps) {\n      return {\n        onActionClick: function onActionClick(e, actionProps) {\n          _invoke(predefinedProps, 'onActionClick', e, actionProps);\n\n          _invoke(_this.props, 'onActionClick', e, _this.props);\n\n          _this.handleClose(e);\n        }\n      };\n    };\n\n    _this.handleClose = function (e) {\n      _invoke(_this.props, 'onClose', e, _this.props);\n\n      _this.setState({\n        open: false\n      });\n    };\n\n    _this.handleDocumentMouseDown = function (e) {\n      _this.latestDocumentMouseDownEvent = e;\n    };\n\n    _this.handleDocumentClick = function (e) {\n      var closeOnDimmerClick = _this.props.closeOnDimmerClick;\n      var currentDocumentMouseDownEvent = _this.latestDocumentMouseDownEvent;\n      _this.latestDocumentMouseDownEvent = null;\n      if (!closeOnDimmerClick || doesNodeContainClick(_this.ref.current, currentDocumentMouseDownEvent) || doesNodeContainClick(_this.ref.current, e)) return;\n\n      _invoke(_this.props, 'onClose', e, _this.props);\n\n      _this.setState({\n        open: false\n      });\n    };\n\n    _this.handleIconOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e) {\n          _invoke(predefinedProps, 'onClick', e);\n\n          _this.handleClose(e);\n        }\n      };\n    };\n\n    _this.handleOpen = function (e) {\n      _invoke(_this.props, 'onOpen', e, _this.props);\n\n      _this.setState({\n        open: true\n      });\n    };\n\n    _this.handlePortalMount = function (e) {\n      var eventPool = _this.props.eventPool;\n\n      _this.setState({\n        scrolling: false\n      });\n\n      _this.setPositionAndClassNames();\n\n      eventStack.sub('mousedown', _this.handleDocumentMouseDown, {\n        pool: eventPool,\n        target: _this.dimmerRef.current\n      });\n      eventStack.sub('click', _this.handleDocumentClick, {\n        pool: eventPool,\n        target: _this.dimmerRef.current\n      });\n\n      _invoke(_this.props, 'onMount', e, _this.props);\n    };\n\n    _this.handlePortalUnmount = function (e) {\n      var eventPool = _this.props.eventPool;\n      cancelAnimationFrame(_this.animationRequestId);\n      eventStack.unsub('mousedown', _this.handleDocumentMouseDown, {\n        pool: eventPool,\n        target: _this.dimmerRef.current\n      });\n      eventStack.unsub('click', _this.handleDocumentClick, {\n        pool: eventPool,\n        target: _this.dimmerRef.current\n      });\n\n      _invoke(_this.props, 'onUnmount', e, _this.props);\n    };\n\n    _this.setPositionAndClassNames = function () {\n      var centered = _this.props.centered;\n      var scrolling;\n      var newState = {};\n\n      if (_this.ref.current) {\n        var rect = _this.ref.current.getBoundingClientRect();\n\n        var isFitted = canFit(rect);\n        scrolling = !isFitted; // Styles should be computed for IE11\n\n        var legacyStyles = _this.legacy ? getLegacyStyles(isFitted, centered, rect) : {};\n\n        if (!shallowEqual(_this.state.legacyStyles, legacyStyles)) {\n          newState.legacyStyles = legacyStyles;\n        }\n\n        if (_this.state.scrolling !== scrolling) {\n          newState.scrolling = scrolling;\n        }\n      }\n\n      if (!_isEmpty(newState)) _this.setState(newState);\n      _this.animationRequestId = requestAnimationFrame(_this.setPositionAndClassNames);\n    };\n\n    _this.renderContent = function (rest) {\n      var _this$props = _this.props,\n          actions = _this$props.actions,\n          basic = _this$props.basic,\n          children = _this$props.children,\n          className = _this$props.className,\n          closeIcon = _this$props.closeIcon,\n          content = _this$props.content,\n          header = _this$props.header,\n          size = _this$props.size,\n          style = _this$props.style;\n      var _this$state = _this.state,\n          legacyStyles = _this$state.legacyStyles,\n          scrolling = _this$state.scrolling;\n      var classes = cx('ui', size, useKeyOnly(basic, 'basic'), useKeyOnly(_this.legacy, 'legacy'), useKeyOnly(scrolling, 'scrolling'), 'modal transition visible active', className);\n      var ElementType = getElementType(Modal, _this.props);\n      var closeIconName = closeIcon === true ? 'close' : closeIcon;\n      var closeIconJSX = Icon.create(closeIconName, {\n        overrideProps: _this.handleIconOverrides\n      });\n      return /*#__PURE__*/React.createElement(Ref, {\n        innerRef: _this.ref\n      }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        style: _extends({}, legacyStyles, style)\n      }), closeIconJSX, childrenUtils.isNil(children) ? /*#__PURE__*/React.createElement(React.Fragment, null, ModalHeader.create(header, {\n        autoGenerateKey: false\n      }), ModalContent.create(content, {\n        autoGenerateKey: false\n      }), ModalActions.create(actions, {\n        overrideProps: _this.handleActionsOverrides\n      })) : children));\n    };\n\n    return _this;\n  }\n\n  var _proto = Modal.prototype;\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    this.handlePortalUnmount();\n  } // Do not access document when server side rendering\n  ;\n\n  _proto.render = function render() {\n    var _this$props2 = this.props,\n        centered = _this$props2.centered,\n        closeOnDocumentClick = _this$props2.closeOnDocumentClick,\n        dimmer = _this$props2.dimmer,\n        eventPool = _this$props2.eventPool,\n        trigger = _this$props2.trigger;\n    var _this$state2 = this.state,\n        open = _this$state2.open,\n        scrolling = _this$state2.scrolling;\n    var mountNode = this.getMountNode(); // Short circuit when server side rendering\n\n    if (!isBrowser()) {\n      return /*#__PURE__*/isValidElement(trigger) ? trigger : null;\n    }\n\n    var unhandled = getUnhandledProps(Modal, this.props);\n    var portalPropNames = Portal.handledProps;\n\n    var rest = _reduce(unhandled, function (acc, val, key) {\n      if (!_includes(portalPropNames, key)) acc[key] = val;\n      return acc;\n    }, {});\n\n    var portalProps = _pick(unhandled, portalPropNames); // Heads up!\n    //\n    // The SUI CSS selector to prevent the modal itself from blurring requires an immediate .dimmer child:\n    // .blurring.dimmed.dimmable>:not(.dimmer) { ... }\n    //\n    // The .blurring.dimmed.dimmable is the body, so that all body content inside is blurred.\n    // We need the immediate child to be the dimmer to :not() blur the modal itself!\n    // Otherwise, the portal div is also blurred, blurring the modal.\n    //\n    // We cannot them wrap the modalJSX in an actual <Dimmer /> instead, we apply the dimmer classes to the <Portal />.\n\n\n    return /*#__PURE__*/React.createElement(Portal, _extends({\n      closeOnDocumentClick: closeOnDocumentClick\n    }, portalProps, {\n      trigger: trigger,\n      eventPool: eventPool,\n      mountNode: mountNode,\n      open: open,\n      onClose: this.handleClose,\n      onMount: this.handlePortalMount,\n      onOpen: this.handleOpen,\n      onUnmount: this.handlePortalUnmount\n    }), /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.dimmerRef\n    }, ModalDimmer.create(_isPlainObject(dimmer) ? dimmer : {}, {\n      autoGenerateKey: false,\n      defaultProps: {\n        blurring: dimmer === 'blurring',\n        inverted: dimmer === 'inverted'\n      },\n      overrideProps: {\n        children: this.renderContent(rest),\n        centered: centered,\n        mountNode: mountNode,\n        scrolling: scrolling\n      }\n    })));\n  };\n\n  return Modal;\n}(Component);\n\nModal.handledProps = [\"actions\", \"as\", \"basic\", \"centered\", \"children\", \"className\", \"closeIcon\", \"closeOnDimmerClick\", \"closeOnDocumentClick\", \"content\", \"defaultOpen\", \"dimmer\", \"eventPool\", \"header\", \"mountNode\", \"onActionClick\", \"onClose\", \"onMount\", \"onOpen\", \"onUnmount\", \"open\", \"size\", \"style\", \"trigger\"];\nModal.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Shorthand for Modal.Actions. Typically an array of button shorthand. */\n  actions: customPropTypes.itemShorthand,\n\n  /** A modal can reduce its complexity */\n  basic: PropTypes.bool,\n\n  /** A modal can be vertically centered in the viewport */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for the close icon. Closes the modal on click. */\n  closeIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.object, PropTypes.bool]),\n\n  /** Whether or not the Modal should close when the dimmer is clicked. */\n  closeOnDimmerClick: PropTypes.bool,\n\n  /** Whether or not the Modal should close when the document is clicked. */\n  closeOnDocumentClick: PropTypes.bool,\n\n  /** Simple text content for the Modal. */\n  content: customPropTypes.itemShorthand,\n\n  /** Initial value of open. */\n  defaultOpen: PropTypes.bool,\n\n  /** A Modal can appear in a dimmer. */\n  dimmer: PropTypes.oneOfType([PropTypes.bool, PropTypes.func, PropTypes.object, PropTypes.oneOf(['inverted', 'blurring'])]),\n\n  /** Event pool namespace that is used to handle component events */\n  eventPool: PropTypes.string,\n\n  /** Modal displayed above the content in bold. */\n  header: customPropTypes.itemShorthand,\n\n  /** The node where the modal should mount. Defaults to document.body. */\n  mountNode: PropTypes.any,\n\n  /**\n   * Action onClick handler when using shorthand `actions`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onActionClick: PropTypes.func,\n\n  /**\n   * Called when a close event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClose: PropTypes.func,\n\n  /**\n   * Called when the portal is mounted on the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onMount: PropTypes.func,\n\n  /**\n   * Called when an open event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onOpen: PropTypes.func,\n\n  /**\n   * Called when the portal is unmounted from the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onUnmount: PropTypes.func,\n\n  /** Controls whether or not the Modal is displayed. */\n  open: PropTypes.bool,\n\n  /** A modal can vary in size */\n  size: PropTypes.oneOf(['mini', 'tiny', 'small', 'large', 'fullscreen']),\n\n  /** Custom styles. */\n  style: PropTypes.object,\n\n  /** Element to be rendered in-place where the portal is defined. */\n  trigger: PropTypes.node\n  /**\n   * NOTE: Any unhandled props that are defined in Portal are passed-through\n   * to the wrapping Portal.\n   */\n\n} : {};\nModal.defaultProps = {\n  centered: true,\n  dimmer: true,\n  closeOnDimmerClick: true,\n  closeOnDocumentClick: false,\n  eventPool: 'Modal'\n};\nModal.autoControlledProps = ['open'];\nModal.Actions = ModalActions;\nModal.Content = ModalContent;\nModal.Description = ModalDescription;\nModal.Dimmer = ModalDimmer;\nModal.Header = ModalHeader;\nexport default Modal;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _map from \"lodash/map\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport Button from '../../elements/Button';\n/**\n * A modal can contain a row of actions.\n */\n\nvar ModalActions = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(ModalActions, _Component);\n\n  function ModalActions() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleButtonOverrides = function (predefinedProps) {\n      return {\n        onClick: function onClick(e, buttonProps) {\n          _invoke(predefinedProps, 'onClick', e, buttonProps);\n\n          _invoke(_this.props, 'onActionClick', e, buttonProps);\n        }\n      };\n    };\n\n    return _this;\n  }\n\n  var _proto = ModalActions.prototype;\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props = this.props,\n        actions = _this$props.actions,\n        children = _this$props.children,\n        className = _this$props.className,\n        content = _this$props.content;\n    var classes = cx('actions', className);\n    var rest = getUnhandledProps(ModalActions, this.props);\n    var ElementType = getElementType(ModalActions, this.props);\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes\n      }), children);\n    }\n\n    if (!childrenUtils.isNil(content)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes\n      }), content);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), _map(actions, function (action) {\n      return Button.create(action, {\n        overrideProps: _this2.handleButtonOverrides\n      });\n    }));\n  };\n\n  return ModalActions;\n}(Component);\n\nModalActions.handledProps = [\"actions\", \"as\", \"children\", \"className\", \"content\", \"onActionClick\"];\nexport { ModalActions as default };\nModalActions.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Array of shorthand buttons. */\n  actions: customPropTypes.collectionShorthand,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /**\n   * Action onClick handler when using shorthand `actions`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props from the clicked action.\n   */\n  onActionClick: customPropTypes.every([customPropTypes.disallow(['children']), PropTypes.func])\n} : {};\nModalActions.create = createShorthandFactory(ModalActions, function (actions) {\n  return {\n    actions: actions\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A modal can contain content.\n */\n\nfunction ModalContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      image = props.image,\n      scrolling = props.scrolling;\n  var classes = cx(className, useKeyOnly(image, 'image'), useKeyOnly(scrolling, 'scrolling'), 'content');\n  var rest = getUnhandledProps(ModalContent, props);\n  var ElementType = getElementType(ModalContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nModalContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"image\", \"scrolling\"];\nModalContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A modal can contain image content. */\n  image: PropTypes.bool,\n\n  /** A modal can use the entire size of the screen. */\n  scrolling: PropTypes.bool\n} : {};\nModalContent.create = createShorthandFactory(ModalContent, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ModalContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A modal can contain a description with one or more paragraphs.\n */\n\nfunction ModalDescription(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('description', className);\n  var rest = getUnhandledProps(ModalDescription, props);\n  var ElementType = getElementType(ModalDescription, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nModalDescription.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nModalDescription.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default ModalDescription;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useClassNamesOnNode, useKeyOnly } from '../../lib';\n/**\n * A modal has a dimmer.\n */\n\nfunction ModalDimmer(props) {\n  var blurring = props.blurring,\n      children = props.children,\n      className = props.className,\n      centered = props.centered,\n      content = props.content,\n      inverted = props.inverted,\n      mountNode = props.mountNode,\n      scrolling = props.scrolling;\n  var ref = React.useRef();\n  var classes = cx('ui', useKeyOnly(inverted, 'inverted'), useKeyOnly(!centered, 'top aligned'), 'page modals dimmer transition visible active', className);\n  var bodyClasses = cx('dimmable dimmed', useKeyOnly(blurring, 'blurring'), useKeyOnly(scrolling, 'scrolling'));\n  var rest = getUnhandledProps(ModalDimmer, props);\n  var ElementType = getElementType(ModalDimmer, props);\n  useClassNamesOnNode(mountNode, bodyClasses);\n  React.useEffect(function () {\n    if (ref.current && ref.current.style) {\n      ref.current.style.setProperty('display', 'flex', 'important');\n    }\n  }, []);\n  return /*#__PURE__*/React.createElement(Ref, {\n    innerRef: ref\n  }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children));\n}\n\nModalDimmer.handledProps = [\"as\", \"blurring\", \"centered\", \"children\", \"className\", \"content\", \"inverted\", \"mountNode\", \"scrolling\"];\nModalDimmer.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A dimmer can be blurred. */\n  blurring: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A dimmer can center its contents in the viewport. */\n  centered: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A dimmer can be inverted. */\n  inverted: PropTypes.bool,\n\n  /** The node where the modal should mount. Defaults to document.body. */\n  mountNode: PropTypes.any,\n\n  /** A dimmer can make body scrollable. */\n  scrolling: PropTypes.bool\n} : {};\nModalDimmer.create = createShorthandFactory(ModalDimmer, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ModalDimmer;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A modal can have a header.\n */\n\nfunction ModalHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(ModalHeader, props);\n  var ElementType = getElementType(ModalHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nModalHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nModalHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nModalHeader.create = createShorthandFactory(ModalHeader, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ModalHeader;","import _default from './Modal';\nexport { _default as default };","// https://github.com/Semantic-Org/Semantic-UI/blob/2.4.1/src/definitions/modules/modal.js#L956\nvar OFFSET = 0; // https://github.com/Semantic-Org/Semantic-UI/blob/2.4.1/src/definitions/modules/modal.js#L990\n\nvar PADDING = 50;\n/**\n * Ensures that modal can fit viewport without scroll.\n *\n * @param modalRect {DOMRect}\n *\n * @see https://github.com/Semantic-Org/Semantic-UI/blob/2.4.1/src/definitions/modules/modal.js#L608\n */\n\nexport var canFit = function canFit(modalRect) {\n  // original: scrollHeight = $module.prop('scrollHeight'),\n  // is replaced by .height because scrollHeight provides integer which produces glitches\n  // https://github.com/Semantic-Org/Semantic-UI-React/issues/2221\n  var scrollHeight = modalRect.height + OFFSET; // $module.outerHeight() + settings.offset\n\n  var height = modalRect.height + OFFSET; // original: $(window).height()\n\n  var contextHeight = window.innerHeight;\n  var verticalCenter = contextHeight / 2;\n  var topOffset = -(height / 2); // padding with edge of page\n\n  var paddingHeight = PADDING;\n  var startPosition = verticalCenter + topOffset; // 0\n  // original: scrollHeight > height\n  //     ? startPosition + scrollHeight + paddingHeight < contextHeight\n  //     : height + paddingHeight * 2 < contextHeight\n\n  return startPosition + scrollHeight + paddingHeight < contextHeight;\n};\n/**\n * Creates legacy styles for IE11.\n *\n * @param isFitted {Boolean}\n * @param centered {Boolean}\n * @param modalRect {DOMRect}\n *\n * @see https://github.com/Semantic-Org/Semantic-UI/blob/2.4.1/src/definitions/modules/modal.js#L718\n */\n\nexport var getLegacyStyles = function getLegacyStyles(isFitted, centered, modalRect) {\n  var marginTop = centered && isFitted ? -(modalRect.height / 2) : 0;\n  var marginLeft = -(modalRect.width / 2);\n  return {\n    marginLeft: marginLeft,\n    marginTop: marginTop\n  };\n}; // https://github.com/Semantic-Org/Semantic-UI/blob/2.4.1/src/definitions/modules/modal.js#L631\n\n/* istanbul ignore next */\n\nexport var isLegacy = function isLegacy() {\n  return !window.ActiveXObject && 'ActiveXObject' in window;\n};","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _isNil from \"lodash/isNil\";\nimport _merge from \"lodash/merge\";\nimport _invoke from \"lodash/invoke\";\nimport _isArray from \"lodash/isArray\";\nimport _pick from \"lodash/pick\";\nimport _includes from \"lodash/includes\";\nimport _reduce from \"lodash/reduce\";\nimport EventStack from '@semantic-ui-react/event-stack';\nimport { Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { Popper } from 'react-popper';\nimport shallowEqual from 'shallowequal';\nimport { eventStack, childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\nimport Portal from '../../addons/Portal';\nimport { placementMapping, positions, positionsMapping } from './lib/positions';\nimport createReferenceProxy from './lib/createReferenceProxy';\nimport PopupContent from './PopupContent';\nimport PopupHeader from './PopupHeader';\n\n/**\n * A Popup displays additional information on top of a page.\n */\nvar Popup = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Popup, _Component);\n\n  function Popup() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.state = {};\n    _this.open = false;\n    _this.triggerRef = /*#__PURE__*/createRef();\n\n    _this.getPortalProps = function () {\n      var portalProps = {};\n      var _this$props = _this.props,\n          on = _this$props.on,\n          hoverable = _this$props.hoverable;\n      var normalizedOn = _isArray(on) ? on : [on];\n\n      if (hoverable) {\n        portalProps.closeOnPortalMouseLeave = true;\n        portalProps.mouseLeaveDelay = 300;\n      }\n\n      if (_includes(normalizedOn, 'hover')) {\n        portalProps.openOnTriggerClick = false;\n        portalProps.closeOnTriggerClick = false;\n        portalProps.openOnTriggerMouseEnter = true;\n        portalProps.closeOnTriggerMouseLeave = true; // Taken from SUI: https://git.io/vPmCm\n\n        portalProps.mouseLeaveDelay = 70;\n        portalProps.mouseEnterDelay = 50;\n      }\n\n      if (_includes(normalizedOn, 'click')) {\n        portalProps.openOnTriggerClick = true;\n        portalProps.closeOnTriggerClick = true;\n        portalProps.closeOnDocumentClick = true;\n      }\n\n      if (_includes(normalizedOn, 'focus')) {\n        portalProps.openOnTriggerFocus = true;\n        portalProps.closeOnTriggerBlur = true;\n      }\n\n      return portalProps;\n    };\n\n    _this.hideOnScroll = function (e) {\n      _this.setState({\n        closed: true\n      });\n\n      eventStack.unsub('scroll', _this.hideOnScroll, {\n        target: window\n      });\n      _this.timeoutId = setTimeout(function () {\n        _this.setState({\n          closed: false\n        });\n      }, 50);\n\n      _this.handleClose(e);\n    };\n\n    _this.handleClose = function (e) {\n      _invoke(_this.props, 'onClose', e, _this.props);\n    };\n\n    _this.handleOpen = function (e) {\n      _invoke(_this.props, 'onOpen', e, _this.props);\n    };\n\n    _this.handlePortalMount = function (e) {\n      _invoke(_this.props, 'onMount', e, _this.props);\n    };\n\n    _this.handlePortalUnmount = function (e) {\n      _this.positionUpdate = null;\n\n      _invoke(_this.props, 'onUnmount', e, _this.props);\n    };\n\n    _this.renderContent = function (_ref) {\n      var popperPlacement = _ref.placement,\n          popperRef = _ref.ref,\n          scheduleUpdate = _ref.scheduleUpdate,\n          popperStyle = _ref.style;\n      var _this$props2 = _this.props,\n          basic = _this$props2.basic,\n          children = _this$props2.children,\n          className = _this$props2.className,\n          content = _this$props2.content,\n          hideOnScroll = _this$props2.hideOnScroll,\n          flowing = _this$props2.flowing,\n          header = _this$props2.header,\n          inverted = _this$props2.inverted,\n          size = _this$props2.size,\n          style = _this$props2.style,\n          wide = _this$props2.wide;\n      var contentRestProps = _this.state.contentRestProps;\n      _this.positionUpdate = scheduleUpdate;\n      var classes = cx('ui', placementMapping[popperPlacement], size, useKeyOrValueAndKey(wide, 'wide'), useKeyOnly(basic, 'basic'), useKeyOnly(flowing, 'flowing'), useKeyOnly(inverted, 'inverted'), 'popup transition visible', className);\n      var ElementType = getElementType(Popup, _this.props);\n\n      var styles = _extends({\n        // Heads up! We need default styles to get working correctly `flowing`\n        left: 'auto',\n        right: 'auto'\n      }, popperStyle, style);\n\n      return /*#__PURE__*/React.createElement(Ref, {\n        innerRef: popperRef\n      }, /*#__PURE__*/React.createElement(ElementType, _extends({}, contentRestProps, {\n        className: classes,\n        style: styles\n      }), childrenUtils.isNil(children) ? /*#__PURE__*/React.createElement(React.Fragment, null, PopupHeader.create(header, {\n        autoGenerateKey: false\n      }), PopupContent.create(content, {\n        autoGenerateKey: false\n      })) : children, hideOnScroll && /*#__PURE__*/React.createElement(EventStack, {\n        on: _this.hideOnScroll,\n        name: \"scroll\",\n        target: \"window\"\n      })));\n    };\n\n    return _this;\n  }\n\n  Popup.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    if (state.closed || state.disabled) return {};\n    var unhandledProps = getUnhandledProps(Popup, props);\n\n    var contentRestProps = _reduce(unhandledProps, function (acc, val, key) {\n      if (!_includes(Portal.handledProps, key)) acc[key] = val;\n      return acc;\n    }, {});\n\n    var portalRestProps = _pick(unhandledProps, Portal.handledProps);\n\n    return {\n      contentRestProps: contentRestProps,\n      portalRestProps: portalRestProps\n    };\n  };\n\n  var _proto = Popup.prototype;\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n    var depsEqual = shallowEqual(this.props.popperDependencies, prevProps.popperDependencies);\n\n    if (!depsEqual) {\n      this.handleUpdate();\n    }\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    clearTimeout(this.timeoutId);\n  };\n\n  _proto.handleUpdate = function handleUpdate() {\n    if (this.positionUpdate) this.positionUpdate();\n  };\n\n  _proto.render = function render() {\n    var _this$props3 = this.props,\n        context = _this$props3.context,\n        disabled = _this$props3.disabled,\n        eventsEnabled = _this$props3.eventsEnabled,\n        offset = _this$props3.offset,\n        pinned = _this$props3.pinned,\n        popperModifiers = _this$props3.popperModifiers,\n        position = _this$props3.position,\n        positionFixed = _this$props3.positionFixed,\n        trigger = _this$props3.trigger;\n    var _this$state = this.state,\n        closed = _this$state.closed,\n        portalRestProps = _this$state.portalRestProps;\n\n    if (closed || disabled) {\n      return trigger;\n    }\n\n    var modifiers = _merge({\n      arrow: {\n        enabled: false\n      },\n      flip: {\n        enabled: !pinned\n      },\n      // There are issues with `keepTogether` and `offset`\n      // https://github.com/FezVrasta/popper.js/issues/557\n      keepTogether: {\n        enabled: !!offset\n      },\n      offset: {\n        offset: offset\n      }\n    }, popperModifiers);\n\n    var referenceElement = createReferenceProxy(_isNil(context) ? this.triggerRef : context);\n\n    var mergedPortalProps = _extends({}, this.getPortalProps(), portalRestProps);\n\n    return /*#__PURE__*/React.createElement(Portal, _extends({}, mergedPortalProps, {\n      onClose: this.handleClose,\n      onMount: this.handlePortalMount,\n      onOpen: this.handleOpen,\n      onUnmount: this.handlePortalUnmount,\n      trigger: trigger,\n      triggerRef: this.triggerRef\n    }), /*#__PURE__*/React.createElement(Popper, {\n      eventsEnabled: eventsEnabled,\n      modifiers: modifiers,\n      placement: positionsMapping[position],\n      positionFixed: positionFixed,\n      referenceElement: referenceElement\n    }, this.renderContent));\n  };\n\n  return Popup;\n}(Component);\n\nPopup.handledProps = [\"as\", \"basic\", \"children\", \"className\", \"content\", \"context\", \"disabled\", \"eventsEnabled\", \"flowing\", \"header\", \"hideOnScroll\", \"hoverable\", \"inverted\", \"offset\", \"on\", \"onClose\", \"onMount\", \"onOpen\", \"onUnmount\", \"pinned\", \"popperDependencies\", \"popperModifiers\", \"position\", \"positionFixed\", \"size\", \"style\", \"trigger\", \"wide\"];\nexport { Popup as default };\nPopup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Display the popup without the pointing arrow. */\n  basic: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Simple text content for the popover. */\n  content: customPropTypes.itemShorthand,\n\n  /** Existing element the pop-up should be bound to. */\n  context: PropTypes.oneOfType([PropTypes.object, customPropTypes.refObject]),\n\n  /** A disabled popup only renders its trigger. */\n  disabled: PropTypes.bool,\n\n  /** Enables the Popper.js event listeners. */\n  eventsEnabled: PropTypes.bool,\n\n  /** A flowing Popup has no maximum width and continues to flow to fit its content. */\n  flowing: PropTypes.bool,\n\n  /** Takes up the entire width of its offset container. */\n  // TODO: implement the Popup fluid layout\n  // fluid: PropTypes.bool,\n\n  /** Header displayed above the content in bold. */\n  header: customPropTypes.itemShorthand,\n\n  /** Hide the Popup when scrolling the window. */\n  hideOnScroll: PropTypes.bool,\n\n  /** Whether the popup should not close on hover. */\n  hoverable: PropTypes.bool,\n\n  /** Invert the colors of the Popup. */\n  inverted: PropTypes.bool,\n\n  /** Offset value to apply to rendered popup. Accepts the following units:\n   * - px or unit-less, interpreted as pixels\n   * - %, percentage relative to the length of the trigger element\n   * - %p, percentage relative to the length of the popup element\n   * - vw, CSS viewport width unit\n   * - vh, CSS viewport height unit\n   */\n  offset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Events triggering the popup. */\n  on: PropTypes.oneOfType([PropTypes.oneOf(['hover', 'click', 'focus']), PropTypes.arrayOf(PropTypes.oneOf(['hover', 'click', 'focus']))]),\n\n  /**\n   * Called when a close event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClose: PropTypes.func,\n\n  /**\n   * Called when the portal is mounted on the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onMount: PropTypes.func,\n\n  /**\n   * Called when an open event happens.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onOpen: PropTypes.func,\n\n  /**\n   * Called when the portal is unmounted from the DOM.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onUnmount: PropTypes.func,\n\n  /** Disables automatic repositioning of the component, it will always be placed according to the position value. */\n  pinned: PropTypes.bool,\n\n  /** Position for the popover. */\n  position: PropTypes.oneOf(positions),\n\n  /** Tells `Popper.js` to use the `position: fixed` strategy to position the popover. */\n  positionFixed: PropTypes.bool,\n\n  /** An object containing custom settings for the Popper.js modifiers. */\n  popperModifiers: PropTypes.object,\n\n  /** A popup can have dependencies which update will schedule a position update. */\n  popperDependencies: PropTypes.array,\n\n  /** Popup size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium', 'big', 'massive')),\n\n  /** Custom Popup style. */\n  style: PropTypes.object,\n\n  /** Element to be rendered in-place where the popup is defined. */\n  trigger: PropTypes.node,\n\n  /** Popup width. */\n  wide: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])])\n} : {};\nPopup.defaultProps = {\n  disabled: false,\n  eventsEnabled: true,\n  offset: 0,\n  on: ['click', 'hover'],\n  pinned: false,\n  position: 'top left'\n};\nPopup.Content = PopupContent;\nPopup.Header = PopupHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A PopupContent displays the content body of a Popover.\n */\n\nexport default function PopupContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(PopupContent, props);\n  var ElementType = getElementType(PopupContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\nPopupContent.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nPopupContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** The content of the Popup */\n  children: PropTypes.node,\n\n  /** Classes to add to the Popup content className. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nPopupContent.create = createShorthandFactory(PopupContent, function (children) {\n  return {\n    children: children\n  };\n});","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A PopupHeader displays a header in a Popover.\n */\n\nexport default function PopupHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(PopupHeader, props);\n  var ElementType = getElementType(PopupHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\nPopupHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nPopupHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nPopupHeader.create = createShorthandFactory(PopupHeader, function (children) {\n  return {\n    children: children\n  };\n});","import _default from './Popup';\nexport { _default as default };","import _createClass from \"@babel/runtime/helpers/esm/createClass\";\nimport _memoize from \"lodash/memoize\";\nimport _invoke from \"lodash/invoke\";\nimport { isRefObject, toRefObject } from '@stardust-ui/react-component-ref';\n\nvar ReferenceProxy = /*#__PURE__*/function () {\n  function ReferenceProxy(refObject) {\n    this.ref = refObject;\n  }\n\n  var _proto = ReferenceProxy.prototype;\n\n  _proto.getBoundingClientRect = function getBoundingClientRect() {\n    return _invoke(this.ref.current, 'getBoundingClientRect') || {};\n  };\n\n  _createClass(ReferenceProxy, [{\n    key: \"clientWidth\",\n    get: function get() {\n      return this.getBoundingClientRect().width;\n    }\n  }, {\n    key: \"clientHeight\",\n    get: function get() {\n      return this.getBoundingClientRect().height;\n    }\n  }, {\n    key: \"parentNode\",\n    get: function get() {\n      return this.ref.current ? this.ref.current.parentNode : undefined;\n    }\n  }]);\n\n  return ReferenceProxy;\n}();\n/**\n * Popper.js does not support ref objects from `createRef()` as referenceElement. If we will pass\n * directly `ref`, `ref.current` will be `null` at the render process. We use memoize to keep the\n * same reference between renders.\n *\n * @see https://popper.js.org/popper-documentation.html#referenceObject\n */\n\n\nvar createReferenceProxy = _memoize(function (reference) {\n  return new ReferenceProxy(isRefObject(reference) ? reference : toRefObject(reference));\n});\n\nexport default createReferenceProxy;","import _invert from \"lodash/invert\";\nimport _keys from \"lodash/keys\";\nexport var positionsMapping = {\n  'top center': 'top',\n  'top left': 'top-start',\n  'top right': 'top-end',\n  'bottom center': 'bottom',\n  'bottom left': 'bottom-start',\n  'bottom right': 'bottom-end',\n  'right center': 'right',\n  'left center': 'left'\n};\nexport var positions = _keys(positionsMapping);\nexport var placementMapping = _invert(positionsMapping);","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _round from \"lodash/round\";\nimport _clamp from \"lodash/clamp\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, createHTMLDivision, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useValueAndKey } from '../../lib';\n/**\n * A progress bar shows the progression of a task.\n */\n\nvar Progress = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Progress, _Component);\n\n  function Progress() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.calculatePercent = function () {\n      var _this$props = _this.props,\n          percent = _this$props.percent,\n          total = _this$props.total,\n          value = _this$props.value;\n      if (!_isUndefined(percent)) return percent;\n      if (!_isUndefined(total) && !_isUndefined(value)) return value / total * 100;\n    };\n\n    _this.computeValueText = function (percent) {\n      var _this$props2 = _this.props,\n          progress = _this$props2.progress,\n          total = _this$props2.total,\n          value = _this$props2.value;\n      if (progress === 'value') return value;\n      if (progress === 'ratio') return value + \"/\" + total;\n      return percent + \"%\";\n    };\n\n    _this.getPercent = function () {\n      var _this$props3 = _this.props,\n          precision = _this$props3.precision,\n          progress = _this$props3.progress,\n          total = _this$props3.total,\n          value = _this$props3.value;\n\n      var percent = _clamp(_this.calculatePercent(), 0, 100);\n\n      if (!_isUndefined(total) && !_isUndefined(value) && progress === 'value') {\n        return value / total * 100;\n      }\n\n      if (progress === 'value') return value;\n      if (_isUndefined(precision)) return percent;\n      return _round(percent, precision);\n    };\n\n    _this.isAutoSuccess = function () {\n      var _this$props4 = _this.props,\n          autoSuccess = _this$props4.autoSuccess,\n          percent = _this$props4.percent,\n          total = _this$props4.total,\n          value = _this$props4.value;\n      return autoSuccess && (percent >= 100 || value >= total);\n    };\n\n    _this.renderLabel = function () {\n      var _this$props5 = _this.props,\n          children = _this$props5.children,\n          content = _this$props5.content,\n          label = _this$props5.label;\n      if (!childrenUtils.isNil(children)) return /*#__PURE__*/React.createElement(\"div\", {\n        className: \"label\"\n      }, children);\n      if (!childrenUtils.isNil(content)) return /*#__PURE__*/React.createElement(\"div\", {\n        className: \"label\"\n      }, content);\n      return createHTMLDivision(label, {\n        autoGenerateKey: false,\n        defaultProps: {\n          className: 'label'\n        }\n      });\n    };\n\n    _this.renderProgress = function (percent) {\n      var _this$props6 = _this.props,\n          precision = _this$props6.precision,\n          progress = _this$props6.progress;\n      if (!progress && _isUndefined(precision)) return;\n      return /*#__PURE__*/React.createElement(\"div\", {\n        className: \"progress\"\n      }, _this.computeValueText(percent));\n    };\n\n    return _this;\n  }\n\n  var _proto = Progress.prototype;\n\n  _proto.render = function render() {\n    var _this$props7 = this.props,\n        active = _this$props7.active,\n        attached = _this$props7.attached,\n        className = _this$props7.className,\n        color = _this$props7.color,\n        disabled = _this$props7.disabled,\n        error = _this$props7.error,\n        indicating = _this$props7.indicating,\n        inverted = _this$props7.inverted,\n        size = _this$props7.size,\n        success = _this$props7.success,\n        warning = _this$props7.warning;\n    var classes = cx('ui', color, size, useKeyOnly(active || indicating, 'active'), useKeyOnly(disabled, 'disabled'), useKeyOnly(error, 'error'), useKeyOnly(indicating, 'indicating'), useKeyOnly(inverted, 'inverted'), useKeyOnly(success || this.isAutoSuccess(), 'success'), useKeyOnly(warning, 'warning'), useValueAndKey(attached, 'attached'), 'progress', className);\n    var rest = getUnhandledProps(Progress, this.props);\n    var ElementType = getElementType(Progress, this.props);\n    var percent = this.getPercent() || 0;\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      \"data-percent\": Math.floor(percent)\n    }), /*#__PURE__*/React.createElement(\"div\", {\n      className: \"bar\",\n      style: {\n        width: percent + \"%\"\n      }\n    }, this.renderProgress(percent)), this.renderLabel());\n  };\n\n  return Progress;\n}(Component);\n\nProgress.handledProps = [\"active\", \"as\", \"attached\", \"autoSuccess\", \"children\", \"className\", \"color\", \"content\", \"disabled\", \"error\", \"indicating\", \"inverted\", \"label\", \"percent\", \"precision\", \"progress\", \"size\", \"success\", \"total\", \"value\", \"warning\"];\nProgress.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A progress bar can show activity. */\n  active: PropTypes.bool,\n\n  /** A progress bar can attach to and show the progress of an element (i.e. Card or Segment). */\n  attached: PropTypes.oneOf(['top', 'bottom']),\n\n  /** Whether success state should automatically trigger when progress completes. */\n  autoSuccess: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A progress bar can have different colors. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A progress bar be disabled. */\n  disabled: PropTypes.bool,\n\n  /** A progress bar can show a error state. */\n  error: PropTypes.bool,\n\n  /** An indicating progress bar visually indicates the current level of progress of a task. */\n  indicating: PropTypes.bool,\n\n  /** A progress bar can have its colors inverted. */\n  inverted: PropTypes.bool,\n\n  /** Can be set to either to display progress as percent or ratio. */\n  label: customPropTypes.itemShorthand,\n\n  /** Current percent complete. */\n  percent: customPropTypes.every([customPropTypes.disallow(['total', 'value']), PropTypes.oneOfType([PropTypes.number, PropTypes.string])]),\n\n  /** Decimal point precision for calculated progress. */\n  precision: PropTypes.number,\n\n  /** A progress bar can contain a text value indicating current progress. */\n  progress: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['percent', 'ratio', 'value'])]),\n\n  /** A progress bar can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'mini', 'huge', 'massive')),\n\n  /** A progress bar can show a success state. */\n  success: PropTypes.bool,\n\n  /** For use with value. Together, these will calculate the percent. Mutually excludes percent. */\n  total: customPropTypes.every([customPropTypes.demand(['value']), customPropTypes.disallow(['percent']), PropTypes.oneOfType([PropTypes.number, PropTypes.string])]),\n\n  /** For use with total. Together, these will calculate the percent. Mutually excludes percent. */\n  value: customPropTypes.every([customPropTypes.disallow(['percent']), PropTypes.oneOfType([PropTypes.number, PropTypes.string])]),\n\n  /** A progress bar can show a warning state. */\n  warning: PropTypes.bool\n} : {};\nexport default Progress;","import _default from './Progress';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _without from \"lodash/without\";\nimport _times from \"lodash/times\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, getElementType, getUnhandledProps, SUI, useKeyOnly } from '../../lib';\nimport RatingIcon from './RatingIcon';\n/**\n * A rating indicates user interest in content.\n */\n\nvar Rating = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Rating, _Component);\n\n  function Rating() {\n    var _this;\n\n    for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {\n      _args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(_args)) || this;\n\n    _this.handleIconClick = function (e, _ref) {\n      var index = _ref.index;\n      var _this$props = _this.props,\n          clearable = _this$props.clearable,\n          disabled = _this$props.disabled,\n          maxRating = _this$props.maxRating,\n          onRate = _this$props.onRate;\n      var rating = _this.state.rating;\n      if (disabled) return; // default newRating is the clicked icon\n      // allow toggling a binary rating\n      // allow clearing ratings\n\n      var newRating = index + 1;\n\n      if (clearable === 'auto' && maxRating === 1) {\n        newRating = +!rating;\n      } else if (clearable === true && newRating === rating) {\n        newRating = 0;\n      } // set rating\n\n\n      _this.setState({\n        rating: newRating,\n        isSelecting: false\n      });\n\n      if (onRate) onRate(e, _extends({}, _this.props, {\n        rating: newRating\n      }));\n    };\n\n    _this.handleIconMouseEnter = function (e, _ref2) {\n      var index = _ref2.index;\n      if (_this.props.disabled) return;\n\n      _this.setState({\n        selectedIndex: index,\n        isSelecting: true\n      });\n    };\n\n    _this.handleMouseLeave = function () {\n      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n        args[_key2] = arguments[_key2];\n      }\n\n      _invoke.apply(void 0, [_this.props, 'onMouseLeave'].concat(args));\n\n      if (_this.props.disabled) return;\n\n      _this.setState({\n        selectedIndex: -1,\n        isSelecting: false\n      });\n    };\n\n    return _this;\n  }\n\n  var _proto = Rating.prototype;\n\n  _proto.render = function render() {\n    var _this2 = this;\n\n    var _this$props2 = this.props,\n        className = _this$props2.className,\n        disabled = _this$props2.disabled,\n        icon = _this$props2.icon,\n        maxRating = _this$props2.maxRating,\n        size = _this$props2.size;\n    var _this$state = this.state,\n        rating = _this$state.rating,\n        selectedIndex = _this$state.selectedIndex,\n        isSelecting = _this$state.isSelecting;\n    var classes = cx('ui', icon, size, useKeyOnly(disabled, 'disabled'), useKeyOnly(isSelecting && !disabled && selectedIndex >= 0, 'selected'), 'rating', className);\n    var rest = getUnhandledProps(Rating, this.props);\n    var ElementType = getElementType(Rating, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      role: \"radiogroup\",\n      onMouseLeave: this.handleMouseLeave,\n      tabIndex: disabled ? 0 : -1\n    }), _times(maxRating, function (i) {\n      return /*#__PURE__*/React.createElement(RatingIcon, {\n        tabIndex: disabled ? -1 : 0,\n        active: rating >= i + 1,\n        \"aria-checked\": rating === i + 1,\n        \"aria-posinset\": i + 1,\n        \"aria-setsize\": maxRating,\n        index: i,\n        key: i,\n        onClick: _this2.handleIconClick,\n        onMouseEnter: _this2.handleIconMouseEnter,\n        selected: selectedIndex >= i && isSelecting\n      });\n    }));\n  };\n\n  return Rating;\n}(Component);\n\nRating.handledProps = [\"as\", \"className\", \"clearable\", \"defaultRating\", \"disabled\", \"icon\", \"maxRating\", \"onRate\", \"rating\", \"size\"];\nexport { Rating as default };\nRating.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /**\n   * You can clear the rating by clicking on the current start rating.\n   * By default a rating will be only clearable if there is 1 icon.\n   * Setting to `true`/`false` will allow or disallow a user to clear their rating.\n   */\n  clearable: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['auto'])]),\n\n  /** The initial rating value. */\n  defaultRating: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** You can disable or enable interactive rating.  Makes a read-only rating. */\n  disabled: PropTypes.bool,\n\n  /** A rating can use a set of star or heart icons. */\n  icon: PropTypes.oneOf(['star', 'heart']),\n\n  /** The total number of icons. */\n  maxRating: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /**\n   * Called after user selects a new rating.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and proposed rating.\n   */\n  onRate: PropTypes.func,\n\n  /** The current number of active icons. */\n  rating: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** A progress bar can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium', 'big'))\n} : {};\nRating.autoControlledProps = ['rating'];\nRating.defaultProps = {\n  clearable: 'auto',\n  maxRating: 1\n};\nRating.Icon = RatingIcon;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport cx from 'clsx';\nimport keyboardKey from 'keyboard-key';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * An internal icon sub-component for Rating component\n */\n\nvar RatingIcon = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(RatingIcon, _Component);\n\n  function RatingIcon() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      _invoke(_this.props, 'onClick', e, _this.props);\n    };\n\n    _this.handleKeyUp = function (e) {\n      _invoke(_this.props, 'onKeyUp', e, _this.props);\n\n      switch (keyboardKey.getCode(e)) {\n        case keyboardKey.Enter:\n        case keyboardKey.Spacebar:\n          e.preventDefault();\n\n          _invoke(_this.props, 'onClick', e, _this.props);\n\n          break;\n\n        default:\n      }\n    };\n\n    _this.handleMouseEnter = function (e) {\n      _invoke(_this.props, 'onMouseEnter', e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = RatingIcon.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        className = _this$props.className,\n        selected = _this$props.selected;\n    var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(selected, 'selected'), 'icon', className);\n    var rest = getUnhandledProps(RatingIcon, this.props);\n    var ElementType = getElementType(RatingIcon, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick,\n      onKeyUp: this.handleKeyUp,\n      onMouseEnter: this.handleMouseEnter,\n      role: \"radio\"\n    }));\n  };\n\n  return RatingIcon;\n}(Component);\n\nRatingIcon.handledProps = [\"active\", \"as\", \"className\", \"index\", \"onClick\", \"onKeyUp\", \"onMouseEnter\", \"selected\"];\nexport { RatingIcon as default };\nRatingIcon.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Indicates activity of an icon. */\n  active: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** An index of icon inside Rating. */\n  index: PropTypes.number,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * Called on keyup.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onKeyUp: PropTypes.func,\n\n  /**\n   * Called on mouseenter.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onMouseEnter: PropTypes.func,\n\n  /** Indicates selection of an icon. */\n  selected: PropTypes.bool\n} : {};\nRatingIcon.defaultProps = {\n  as: 'i'\n};","import _default from './Rating';\nexport { _default as default };","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _partialRight from \"lodash/partialRight\";\nimport _inRange from \"lodash/inRange\";\nimport _map from \"lodash/map\";\nimport _get from \"lodash/get\";\nimport _reduce from \"lodash/reduce\";\nimport _invoke from \"lodash/invoke\";\nimport _isPlainObject from \"lodash/isPlainObject\";\nimport _isUndefined from \"lodash/isUndefined\";\nimport cx from 'clsx';\nimport keyboardKey from 'keyboard-key';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport shallowEqual from 'shallowequal';\nimport { ModernAutoControlledComponent as Component, customPropTypes, eventStack, getElementType, getUnhandledProps, htmlInputAttrs, isBrowser, objectDiff, partitionHTMLProps, SUI, useKeyOnly, useValueAndKey } from '../../lib';\nimport Input from '../../elements/Input';\nimport SearchCategory from './SearchCategory';\nimport SearchResult from './SearchResult';\nimport SearchResults from './SearchResults';\n\nvar overrideSearchInputProps = function overrideSearchInputProps(predefinedProps) {\n  var input = predefinedProps.input;\n\n  if (_isUndefined(input)) {\n    return _extends({}, predefinedProps, {\n      input: {\n        className: 'prompt'\n      }\n    });\n  }\n\n  if (_isPlainObject(input)) {\n    return _extends({}, predefinedProps, {\n      input: _extends({}, input, {\n        className: cx(input.className, 'prompt')\n      })\n    });\n  }\n\n  return predefinedProps;\n};\n/**\n * A search module allows a user to query for results from a selection of data\n */\n\n\nvar Search = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Search, _Component);\n\n  function Search() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleResultSelect = function (e, result) {\n      _invoke(_this.props, 'onResultSelect', e, _extends({}, _this.props, {\n        result: result\n      }));\n    };\n\n    _this.handleSelectionChange = function (e) {\n      var result = _this.getSelectedResult();\n\n      _invoke(_this.props, 'onSelectionChange', e, _extends({}, _this.props, {\n        result: result\n      }));\n    };\n\n    _this.closeOnEscape = function (e) {\n      if (keyboardKey.getCode(e) !== keyboardKey.Escape) return;\n      e.preventDefault();\n\n      _this.close();\n    };\n\n    _this.moveSelectionOnKeyDown = function (e) {\n      switch (keyboardKey.getCode(e)) {\n        case keyboardKey.ArrowDown:\n          e.preventDefault();\n\n          _this.moveSelectionBy(e, 1);\n\n          break;\n\n        case keyboardKey.ArrowUp:\n          e.preventDefault();\n\n          _this.moveSelectionBy(e, -1);\n\n          break;\n\n        default:\n          break;\n      }\n    };\n\n    _this.selectItemOnEnter = function (e) {\n      if (keyboardKey.getCode(e) !== keyboardKey.Enter) return;\n\n      var result = _this.getSelectedResult(); // prevent selecting null if there was no selected item value\n\n\n      if (!result) return;\n      e.preventDefault(); // notify the onResultSelect prop that the user is trying to change value\n\n      _this.setValue(result.title);\n\n      _this.handleResultSelect(e, result);\n\n      _this.close();\n    };\n\n    _this.closeOnDocumentClick = function (e) {\n      _this.close();\n    };\n\n    _this.handleMouseDown = function (e) {\n      _this.isMouseDown = true;\n\n      _invoke(_this.props, 'onMouseDown', e, _this.props);\n\n      eventStack.sub('mouseup', _this.handleDocumentMouseUp);\n    };\n\n    _this.handleDocumentMouseUp = function () {\n      _this.isMouseDown = false;\n      eventStack.unsub('mouseup', _this.handleDocumentMouseUp);\n    };\n\n    _this.handleInputClick = function (e) {\n      // prevent closeOnDocumentClick()\n      e.nativeEvent.stopImmediatePropagation();\n\n      _this.tryOpen();\n    };\n\n    _this.handleItemClick = function (e, _ref) {\n      var id = _ref.id;\n\n      var result = _this.getSelectedResult(id); // prevent closeOnDocumentClick()\n\n\n      e.nativeEvent.stopImmediatePropagation(); // notify the onResultSelect prop that the user is trying to change value\n\n      _this.setValue(result.title);\n\n      _this.handleResultSelect(e, result);\n\n      _this.close();\n    };\n\n    _this.handleItemMouseDown = function (e) {\n      // Heads up! We should prevent default to prevent blur events.\n      // https://github.com/Semantic-Org/Semantic-UI-React/issues/3298\n      e.preventDefault();\n    };\n\n    _this.handleFocus = function (e) {\n      _invoke(_this.props, 'onFocus', e, _this.props);\n\n      _this.setState({\n        focus: true\n      });\n    };\n\n    _this.handleBlur = function (e) {\n      _invoke(_this.props, 'onBlur', e, _this.props);\n\n      _this.setState({\n        focus: false\n      });\n    };\n\n    _this.handleSearchChange = function (e) {\n      // prevent propagating to this.props.onChange()\n      e.stopPropagation();\n      var minCharacters = _this.props.minCharacters;\n      var open = _this.state.open;\n      var newQuery = e.target.value;\n\n      _invoke(_this.props, 'onSearchChange', e, _extends({}, _this.props, {\n        value: newQuery\n      })); // open search dropdown on search query\n\n\n      if (newQuery.length < minCharacters) {\n        _this.close();\n      } else if (!open) {\n        _this.tryOpen(newQuery);\n      }\n\n      _this.setValue(newQuery);\n    };\n\n    _this.getFlattenedResults = function () {\n      var _this$props = _this.props,\n          category = _this$props.category,\n          results = _this$props.results;\n      return !category ? results : _reduce(results, function (memo, categoryData) {\n        return memo.concat(categoryData.results);\n      }, []);\n    };\n\n    _this.getSelectedResult = function (index) {\n      if (index === void 0) {\n        index = _this.state.selectedIndex;\n      }\n\n      var results = _this.getFlattenedResults();\n\n      return _get(results, index);\n    };\n\n    _this.setValue = function (value) {\n      var selectFirstResult = _this.props.selectFirstResult;\n\n      _this.setState({\n        value: value,\n        selectedIndex: selectFirstResult ? 0 : -1\n      });\n    };\n\n    _this.moveSelectionBy = function (e, offset) {\n      var selectedIndex = _this.state.selectedIndex;\n\n      var results = _this.getFlattenedResults();\n\n      var lastIndex = results.length - 1; // next is after last, wrap to beginning\n      // next is before first, wrap to end\n\n      var nextIndex = selectedIndex + offset;\n      if (nextIndex > lastIndex) nextIndex = 0;else if (nextIndex < 0) nextIndex = lastIndex;\n\n      _this.setState({\n        selectedIndex: nextIndex\n      });\n\n      _this.scrollSelectedItemIntoView();\n\n      _this.handleSelectionChange(e);\n    };\n\n    _this.scrollSelectedItemIntoView = function () {\n      // Do not access document when server side rendering\n      if (!isBrowser()) return;\n      var menu = document.querySelector('.ui.search.active.visible .results.visible');\n      if (!menu) return;\n      var item = menu.querySelector('.result.active');\n      if (!item) return;\n      var isOutOfUpperView = item.offsetTop < menu.scrollTop;\n      var isOutOfLowerView = item.offsetTop + item.clientHeight > menu.scrollTop + menu.clientHeight;\n\n      if (isOutOfUpperView) {\n        menu.scrollTop = item.offsetTop;\n      } else if (isOutOfLowerView) {\n        menu.scrollTop = item.offsetTop + item.clientHeight - menu.clientHeight;\n      }\n    };\n\n    _this.tryOpen = function (currentValue) {\n      if (currentValue === void 0) {\n        currentValue = _this.state.value;\n      }\n\n      var minCharacters = _this.props.minCharacters;\n      if (currentValue.length < minCharacters) return;\n\n      _this.open();\n    };\n\n    _this.open = function () {\n      _this.setState({\n        open: true\n      });\n    };\n\n    _this.close = function () {\n      _this.setState({\n        open: false\n      });\n    };\n\n    _this.renderSearchInput = function (rest) {\n      var _this$props2 = _this.props,\n          icon = _this$props2.icon,\n          input = _this$props2.input;\n      var value = _this.state.value;\n      return Input.create(input, {\n        autoGenerateKey: false,\n        defaultProps: _extends({}, rest, {\n          autoComplete: 'off',\n          icon: icon,\n          onChange: _this.handleSearchChange,\n          onClick: _this.handleInputClick,\n          tabIndex: '0',\n          value: value\n        }),\n        // Nested shorthand props need special treatment to survive the shallow merge\n        overrideProps: overrideSearchInputProps\n      });\n    };\n\n    _this.renderNoResults = function () {\n      var _this$props3 = _this.props,\n          noResultsDescription = _this$props3.noResultsDescription,\n          noResultsMessage = _this$props3.noResultsMessage;\n      return /*#__PURE__*/React.createElement(\"div\", {\n        className: \"message empty\"\n      }, /*#__PURE__*/React.createElement(\"div\", {\n        className: \"header\"\n      }, noResultsMessage), noResultsDescription && /*#__PURE__*/React.createElement(\"div\", {\n        className: \"description\"\n      }, noResultsDescription));\n    };\n\n    _this.renderResult = function (_ref2, index, _array, offset) {\n      var childKey = _ref2.childKey,\n          result = _objectWithoutPropertiesLoose(_ref2, [\"childKey\"]);\n\n      if (offset === void 0) {\n        offset = 0;\n      }\n\n      var resultRenderer = _this.props.resultRenderer;\n      var selectedIndex = _this.state.selectedIndex;\n      var offsetIndex = index + offset;\n      return /*#__PURE__*/React.createElement(SearchResult, _extends({\n        key: childKey || result.id || result.title,\n        active: selectedIndex === offsetIndex,\n        onClick: _this.handleItemClick,\n        onMouseDown: _this.handleItemMouseDown,\n        renderer: resultRenderer\n      }, result, {\n        id: offsetIndex // Used to lookup the result on item click\n\n      }));\n    };\n\n    _this.renderResults = function () {\n      var results = _this.props.results;\n      return _map(results, _this.renderResult);\n    };\n\n    _this.renderCategories = function () {\n      var _this$props4 = _this.props,\n          categoryLayoutRenderer = _this$props4.categoryLayoutRenderer,\n          categoryRenderer = _this$props4.categoryRenderer,\n          categories = _this$props4.results;\n      var selectedIndex = _this.state.selectedIndex;\n      var count = 0;\n      return _map(categories, function (_ref3) {\n        var childKey = _ref3.childKey,\n            category = _objectWithoutPropertiesLoose(_ref3, [\"childKey\"]);\n\n        var categoryProps = _extends({\n          key: childKey || category.name,\n          active: _inRange(selectedIndex, count, count + category.results.length),\n          layoutRenderer: categoryLayoutRenderer,\n          renderer: categoryRenderer\n        }, category);\n\n        var renderFn = _partialRight(_this.renderResult, count);\n\n        count += category.results.length;\n        return /*#__PURE__*/React.createElement(SearchCategory, categoryProps, category.results.map(renderFn));\n      });\n    };\n\n    _this.renderMenuContent = function () {\n      var _this$props5 = _this.props,\n          category = _this$props5.category,\n          showNoResults = _this$props5.showNoResults,\n          results = _this$props5.results;\n\n      if (_isEmpty(results)) {\n        return showNoResults ? _this.renderNoResults() : null;\n      }\n\n      return category ? _this.renderCategories() : _this.renderResults();\n    };\n\n    _this.renderResultsMenu = function () {\n      var open = _this.state.open;\n      var resultsClasses = open ? 'visible' : '';\n\n      var menuContent = _this.renderMenuContent();\n\n      if (!menuContent) return;\n      return /*#__PURE__*/React.createElement(SearchResults, {\n        className: resultsClasses\n      }, menuContent);\n    };\n\n    return _this;\n  }\n\n  Search.getAutoControlledStateFromProps = function getAutoControlledStateFromProps(props, state) {\n    // We need to store a `prevValue` to compare as in `getDerivedStateFromProps` we don't have\n    // prevState\n    if (typeof state.prevValue !== 'undefined' && shallowEqual(state.prevValue, state.value)) {\n      return {\n        prevValue: state.value\n      };\n    }\n\n    var selectedIndex = props.selectFirstResult ? 0 : -1;\n    return {\n      prevValue: state.value,\n      selectedIndex: selectedIndex\n    };\n  };\n\n  var _proto = Search.prototype;\n\n  _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {\n    return !shallowEqual(nextProps, this.props) || !shallowEqual(nextState, this.state);\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    // eslint-disable-line complexity\n    // focused / blurred\n    if (!prevState.focus && this.state.focus) {\n      if (!this.isMouseDown) {\n        this.tryOpen();\n      }\n\n      if (this.state.open) {\n        eventStack.sub('keydown', [this.moveSelectionOnKeyDown, this.selectItemOnEnter]);\n      }\n    } else if (prevState.focus && !this.state.focus) {\n      if (!this.isMouseDown) {\n        this.close();\n      }\n\n      eventStack.unsub('keydown', [this.moveSelectionOnKeyDown, this.selectItemOnEnter]);\n    } // opened / closed\n\n\n    if (!prevState.open && this.state.open) {\n      this.open();\n      eventStack.sub('click', this.closeOnDocumentClick);\n      eventStack.sub('keydown', [this.closeOnEscape, this.moveSelectionOnKeyDown, this.selectItemOnEnter]);\n    } else if (prevState.open && !this.state.open) {\n      this.close();\n      eventStack.unsub('click', this.closeOnDocumentClick);\n      eventStack.unsub('keydown', [this.closeOnEscape, this.moveSelectionOnKeyDown, this.selectItemOnEnter]);\n    }\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    eventStack.unsub('click', this.closeOnDocumentClick);\n    eventStack.unsub('keydown', [this.closeOnEscape, this.moveSelectionOnKeyDown, this.selectItemOnEnter]);\n  } // ----------------------------------------\n  // Document Event Handlers\n  // ----------------------------------------\n  ;\n\n  _proto.render = function render() {\n    var _this$state = this.state,\n        searchClasses = _this$state.searchClasses,\n        focus = _this$state.focus,\n        open = _this$state.open;\n    var _this$props6 = this.props,\n        aligned = _this$props6.aligned,\n        category = _this$props6.category,\n        className = _this$props6.className,\n        fluid = _this$props6.fluid,\n        loading = _this$props6.loading,\n        size = _this$props6.size; // Classes\n\n    var classes = cx('ui', open && 'active visible', size, searchClasses, useKeyOnly(category, 'category'), useKeyOnly(focus, 'focus'), useKeyOnly(fluid, 'fluid'), useKeyOnly(loading, 'loading'), useValueAndKey(aligned, 'aligned'), 'search', className);\n    var unhandled = getUnhandledProps(Search, this.props);\n    var ElementType = getElementType(Search, this.props);\n\n    var _partitionHTMLProps = partitionHTMLProps(unhandled, {\n      htmlProps: htmlInputAttrs\n    }),\n        htmlInputProps = _partitionHTMLProps[0],\n        rest = _partitionHTMLProps[1];\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onBlur: this.handleBlur,\n      onFocus: this.handleFocus,\n      onMouseDown: this.handleMouseDown\n    }), this.renderSearchInput(htmlInputProps), this.renderResultsMenu());\n  };\n\n  return Search;\n}(Component);\n\nSearch.handledProps = [\"aligned\", \"as\", \"category\", \"categoryLayoutRenderer\", \"categoryRenderer\", \"className\", \"defaultOpen\", \"defaultValue\", \"fluid\", \"icon\", \"input\", \"loading\", \"minCharacters\", \"noResultsDescription\", \"noResultsMessage\", \"onBlur\", \"onFocus\", \"onMouseDown\", \"onResultSelect\", \"onSearchChange\", \"onSelectionChange\", \"open\", \"resultRenderer\", \"results\", \"selectFirstResult\", \"showNoResults\", \"size\", \"value\"];\nexport { Search as default };\nSearch.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n  // ------------------------------------\n  // Behavior\n  // ------------------------------------\n\n  /** Initial value of open. */\n  defaultOpen: PropTypes.bool,\n\n  /** Initial value. */\n  defaultValue: PropTypes.string,\n\n  /** Shorthand for Icon. */\n  icon: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),\n\n  /** Minimum characters to query for results */\n  minCharacters: PropTypes.number,\n\n  /** Additional text for \"No Results\" message with less emphasis. */\n  noResultsDescription: PropTypes.node,\n\n  /** Message to display when there are no results. */\n  noResultsMessage: PropTypes.node,\n\n  /** Controls whether or not the results menu is displayed. */\n  open: PropTypes.bool,\n\n  /**\n   * One of:\n   * - array of Search.Result props e.g. `{ title: '', description: '' }` or\n   * - object of categories e.g. `{ name: '', results: [{ title: '', description: '' }]`\n   */\n  results: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.shape(SearchResult.propTypes)), PropTypes.shape(SearchCategory.propTypes)]),\n\n  /** Whether the search should automatically select the first result after searching. */\n  selectFirstResult: PropTypes.bool,\n\n  /** Whether a \"no results\" message should be shown if no results are found. */\n  showNoResults: PropTypes.bool,\n\n  /** Current value of the search input. Creates a controlled component. */\n  value: PropTypes.string,\n  // ------------------------------------\n  // Rendering\n  // ------------------------------------\n\n  /**\n   * Renders the SearchCategory layout.\n   *\n   * @param {object} categoryContent - The Renderable SearchCategory contents.\n   * @param {object} resultsContent - The Renderable SearchResult contents.\n   * @returns {*} - Renderable SearchCategory layout.\n   */\n  categoryLayoutRenderer: PropTypes.func,\n\n  /**\n   * Renders the SearchCategory contents.\n   *\n   * @param {object} props - The SearchCategory props object.\n   * @returns {*} - Renderable SearchCategory contents.\n   */\n  categoryRenderer: PropTypes.func,\n\n  /**\n   * Renders the SearchResult contents.\n   *\n   * @param {object} props - The SearchResult props object.\n   * @returns {*} - Renderable SearchResult contents.\n   */\n  resultRenderer: PropTypes.func,\n  // ------------------------------------\n  // Callbacks\n  // ------------------------------------\n\n  /**\n   * Called on blur.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onBlur: PropTypes.func,\n\n  /**\n   * Called on focus.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onFocus: PropTypes.func,\n\n  /**\n   * Called on mousedown.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onMouseDown: PropTypes.func,\n\n  /**\n   * Called when a result is selected.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onResultSelect: PropTypes.func,\n\n  /**\n   * Called on search input change.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props, includes current value of search input.\n   */\n  onSearchChange: PropTypes.func,\n\n  /**\n   * Called when the active selection index is changed.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onSelectionChange: PropTypes.func,\n  // ------------------------------------\n  // Style\n  // ------------------------------------\n\n  /** A search can have its results aligned to its left or right container edge. */\n  aligned: PropTypes.string,\n\n  /** A search can display results from remote content ordered by categories. */\n  category: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A search can have its results take up the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** Shorthand for input element. */\n  input: customPropTypes.itemShorthand,\n\n  /** A search can show a loading indicator. */\n  loading: PropTypes.bool,\n\n  /** A search can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium'))\n} : {};\nSearch.defaultProps = {\n  icon: 'search',\n  input: 'text',\n  minCharacters: 1,\n  noResultsMessage: 'No results found.',\n  showNoResults: true\n};\nSearch.autoControlledProps = ['open', 'value'];\nSearch.Category = SearchCategory;\nSearch.Result = SearchResult;\nSearch.Results = SearchResults;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport SearchCategoryLayout from './SearchCategoryLayout';\n\nfunction SearchCategory(props) {\n  var active = props.active,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      layoutRenderer = props.layoutRenderer,\n      renderer = props.renderer;\n  var classes = cx(useKeyOnly(active, 'active'), 'category', className);\n  var rest = getUnhandledProps(SearchCategory, props);\n  var ElementType = getElementType(SearchCategory, props);\n  var categoryContent = renderer(props);\n  var resultsContent = childrenUtils.isNil(children) ? content : children;\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), layoutRenderer({\n    categoryContent: categoryContent,\n    resultsContent: resultsContent\n  }));\n}\n\nSearchCategory.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"layoutRenderer\", \"name\", \"renderer\", \"results\"];\nSearchCategory.defaultProps = {\n  layoutRenderer: SearchCategoryLayout,\n  renderer: function renderer(_ref) {\n    var name = _ref.name;\n    return name;\n  }\n};\nSearchCategory.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** The item currently selected by keyboard shortcut. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Display name. */\n  name: PropTypes.string,\n\n  /**\n   * Renders the category layout contents.\n   *\n   * @param {object} props - The SearchCategoryLayout props object.\n   * @returns {*} - Renderable category layout contents.\n   */\n  layoutRenderer: PropTypes.func,\n\n  /**\n   * Renders the category contents.\n   *\n   * @param {object} props - The SearchCategory props object.\n   * @returns {*} - Renderable category contents.\n   */\n  renderer: PropTypes.func,\n\n  /** Array of Search.Result props. */\n  results: PropTypes.array\n} : {};\nexport default SearchCategory;","import PropTypes from 'prop-types';\nimport React from 'react';\n\nfunction SearchCategoryLayout(props) {\n  var categoryContent = props.categoryContent,\n      resultsContent = props.resultsContent;\n  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"div\", {\n    className: \"name\"\n  }, categoryContent), /*#__PURE__*/React.createElement(\"div\", {\n    className: \"results\"\n  }, resultsContent));\n}\n\nSearchCategoryLayout.handledProps = [\"categoryContent\", \"resultsContent\"];\nSearchCategoryLayout.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** The rendered category content */\n  categoryContent: PropTypes.element.isRequired,\n\n  /** The rendered results content */\n  resultsContent: PropTypes.element.isRequired\n} : {};\nexport default SearchCategoryLayout;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { createHTMLImage, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib'; // Note: You technically only need the 'content' wrapper when there's an\n// image. However, optionally wrapping it makes this function a lot more\n// complicated and harder to read. Since always wrapping it doesn't affect\n// the style in any way let's just do that.\n//\n// Note: To avoid requiring a wrapping div, we return an array here so to\n// prevent rendering issues each node needs a unique key.\n\nvar defaultRenderer = function defaultRenderer(_ref) {\n  var image = _ref.image,\n      price = _ref.price,\n      title = _ref.title,\n      description = _ref.description;\n  return [image && /*#__PURE__*/React.createElement(\"div\", {\n    key: \"image\",\n    className: \"image\"\n  }, createHTMLImage(image, {\n    autoGenerateKey: false\n  })), /*#__PURE__*/React.createElement(\"div\", {\n    key: \"content\",\n    className: \"content\"\n  }, price && /*#__PURE__*/React.createElement(\"div\", {\n    className: \"price\"\n  }, price), title && /*#__PURE__*/React.createElement(\"div\", {\n    className: \"title\"\n  }, title), description && /*#__PURE__*/React.createElement(\"div\", {\n    className: \"description\"\n  }, description))];\n};\n\ndefaultRenderer.handledProps = [];\n\nvar SearchResult = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(SearchResult, _Component);\n\n  function SearchResult() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var onClick = _this.props.onClick;\n      if (onClick) onClick(e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = SearchResult.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        active = _this$props.active,\n        className = _this$props.className,\n        renderer = _this$props.renderer;\n    var classes = cx(useKeyOnly(active, 'active'), 'result', className);\n    var rest = getUnhandledProps(SearchResult, this.props);\n    var ElementType = getElementType(SearchResult, this.props); // Note: You technically only need the 'content' wrapper when there's an\n    // image. However, optionally wrapping it makes this function a lot more\n    // complicated and harder to read. Since always wrapping it doesn't affect\n    // the style in any way let's just do that.\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      onClick: this.handleClick\n    }), renderer(this.props));\n  };\n\n  return SearchResult;\n}(Component);\n\nSearchResult.handledProps = [\"active\", \"as\", \"className\", \"content\", \"description\", \"id\", \"image\", \"onClick\", \"price\", \"renderer\", \"title\"];\nexport { SearchResult as default };\nSearchResult.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** The item currently selected by keyboard shortcut. */\n  active: PropTypes.bool,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Additional text with less emphasis. */\n  description: PropTypes.string,\n\n  /** A unique identifier. */\n  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Add an image to the item. */\n  image: PropTypes.string,\n\n  /**\n   * Called on click.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /** Customized text for price. */\n  price: PropTypes.string,\n\n  /**\n   * Renders the result contents.\n   *\n   * @param {object} props - The SearchResult props object.\n   * @returns {*} - Renderable result contents.\n   */\n  renderer: PropTypes.func,\n\n  /** Display title. */\n  title: PropTypes.string.isRequired\n} : {};\nSearchResult.defaultProps = {\n  renderer: defaultRenderer\n};","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n\nfunction SearchResults(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('results transition', className);\n  var rest = getUnhandledProps(SearchResults, props);\n  var ElementType = getElementType(SearchResults, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSearchResults.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nSearchResults.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default SearchResults;","import _default from './Search';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport { EventListener, documentRef } from '@stardust-ui/react-component-event-listener';\nimport { isRefObject, toRefObject, Ref } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { childrenUtils, customPropTypes, doesNodeContainClick, getUnhandledProps, getElementType, useKeyOnly } from '../../lib';\nimport SidebarPushable from './SidebarPushable';\nimport SidebarPusher from './SidebarPusher';\n/**\n * A sidebar hides additional content beside a page.\n */\n\nvar Sidebar = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Sidebar, _Component);\n\n  function Sidebar(props) {\n    var _this;\n\n    _this = _Component.call(this, props) || this;\n    _this.ref = /*#__PURE__*/createRef();\n\n    _this.handleAnimationStart = function () {\n      var visible = _this.props.visible;\n      var callback = visible ? 'onVisible' : 'onHide';\n      clearTimeout(_this.animationTimer);\n      _this.animationTimer = setTimeout(_this.handleAnimationEnd, Sidebar.animationDuration);\n\n      if (_this.skipNextCallback) {\n        _this.skipNextCallback = false;\n        return;\n      }\n\n      _invoke(_this.props, callback, null, _this.props);\n    };\n\n    _this.handleAnimationEnd = function () {\n      var visible = _this.props.visible;\n      var callback = visible ? 'onShow' : 'onHidden';\n\n      _this.setState({\n        animationTick: 0\n      });\n\n      _invoke(_this.props, callback, null, _this.props);\n    };\n\n    _this.handleDocumentClick = function (e) {\n      if (!doesNodeContainClick(_this.ref.current, e)) {\n        _this.skipNextCallback = true;\n\n        _invoke(_this.props, 'onHide', e, _extends({}, _this.props, {\n          visible: false\n        }));\n      }\n    };\n\n    _this.state = {\n      animationTick: 0,\n      visible: props.visible\n    };\n    return _this;\n  }\n\n  Sidebar.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    // We use `animationTick` to understand when an animation should be scheduled\n    var tickIncrement = !!props.visible === !!state.visible ? 0 : 1;\n    return {\n      animationTick: state.animationTick + tickIncrement,\n      visible: props.visible\n    };\n  };\n\n  var _proto = Sidebar.prototype;\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    if (this.state.animationTick > prevState.animationTick) {\n      this.handleAnimationStart();\n    }\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    clearTimeout(this.animationTimer);\n  };\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        animation = _this$props.animation,\n        className = _this$props.className,\n        children = _this$props.children,\n        content = _this$props.content,\n        direction = _this$props.direction,\n        target = _this$props.target,\n        visible = _this$props.visible,\n        width = _this$props.width;\n    var animationTick = this.state.animationTick;\n    var classes = cx('ui', animation, direction, width, useKeyOnly(animationTick > 0, 'animating'), useKeyOnly(visible, 'visible'), 'sidebar', className);\n    var rest = getUnhandledProps(Sidebar, this.props);\n    var ElementType = getElementType(Sidebar, this.props);\n    var targetRef = isRefObject(target) ? target : toRefObject(target);\n    return /*#__PURE__*/React.createElement(Ref, {\n      innerRef: this.ref\n    }, /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), childrenUtils.isNil(children) ? content : children, visible && /*#__PURE__*/React.createElement(EventListener, {\n      listener: this.handleDocumentClick,\n      targetRef: targetRef,\n      type: \"click\"\n    })));\n  };\n\n  return Sidebar;\n}(Component);\n\nSidebar.handledProps = [\"animation\", \"as\", \"children\", \"className\", \"content\", \"direction\", \"onHidden\", \"onHide\", \"onShow\", \"onVisible\", \"target\", \"visible\", \"width\"];\nSidebar.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Animation style. */\n  animation: PropTypes.oneOf(['overlay', 'push', 'scale down', 'uncover', 'slide out', 'slide along']),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Direction the sidebar should appear on. */\n  direction: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),\n\n  /**\n   * Called before a sidebar begins to animate out.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onHide: PropTypes.func,\n\n  /**\n   * Called after a sidebar has finished animating out.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onHidden: PropTypes.func,\n\n  /**\n   * Called when a sidebar has finished animating in.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onShow: PropTypes.func,\n\n  /**\n   * Called when a sidebar begins animating in.\n   *\n   * @param {null}\n   * @param {object} data - All props.\n   */\n  onVisible: PropTypes.func,\n\n  /** A sidebar can handle clicks on the passed element. */\n  target: PropTypes.oneOfType([customPropTypes.domNode, customPropTypes.refObject]),\n\n  /** Controls whether or not the sidebar is visible on the page. */\n  visible: PropTypes.bool,\n\n  /** Sidebar width. */\n  width: PropTypes.oneOf(['very thin', 'thin', 'wide', 'very wide'])\n} : {};\nSidebar.defaultProps = {\n  direction: 'left',\n  target: documentRef,\n  visible: false\n};\nSidebar.animationDuration = 500;\nSidebar.autoControlledProps = ['visible'];\nSidebar.Pushable = SidebarPushable;\nSidebar.Pusher = SidebarPusher;\nexport default Sidebar;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A pushable sub-component for Sidebar.\n */\n\nfunction SidebarPushable(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx('pushable', className);\n  var rest = getUnhandledProps(SidebarPushable, props);\n  var ElementType = getElementType(SidebarPushable, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSidebarPushable.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nSidebarPushable.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default SidebarPushable;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A pushable sub-component for Sidebar.\n */\n\nfunction SidebarPusher(props) {\n  var className = props.className,\n      dimmed = props.dimmed,\n      children = props.children,\n      content = props.content;\n  var classes = cx('pusher', useKeyOnly(dimmed, 'dimmed'), className);\n  var rest = getUnhandledProps(SidebarPusher, props);\n  var ElementType = getElementType(SidebarPusher, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nSidebarPusher.handledProps = [\"as\", \"children\", \"className\", \"content\", \"dimmed\"];\nSidebarPusher.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Controls whether or not the dim is displayed. */\n  dimmed: PropTypes.bool\n} : {};\nexport default SidebarPusher;","import _default from './Sidebar';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _invoke from \"lodash/invoke\";\nimport { isRefObject } from '@stardust-ui/react-component-ref';\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component, createRef } from 'react';\nimport { customPropTypes, eventStack, getElementType, getUnhandledProps, isBrowser } from '../../lib';\n/**\n * Sticky content stays fixed to the browser viewport while another column of content is visible on the page.\n */\n\nvar Sticky = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Sticky, _Component);\n\n  function Sticky() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.state = {\n      active: true,\n      sticky: false\n    };\n    _this.stickyRef = /*#__PURE__*/createRef();\n    _this.triggerRef = /*#__PURE__*/createRef();\n\n    _this.addListeners = function (scrollContext) {\n      var scrollContextNode = isRefObject(scrollContext) ? scrollContext.current : scrollContext;\n\n      if (scrollContextNode) {\n        eventStack.sub('resize', _this.handleUpdate, {\n          target: scrollContextNode\n        });\n        eventStack.sub('scroll', _this.handleUpdate, {\n          target: scrollContextNode\n        });\n      }\n    };\n\n    _this.removeListeners = function (scrollContext) {\n      var scrollContextNode = isRefObject(scrollContext) ? scrollContext.current : scrollContext;\n\n      if (scrollContextNode) {\n        eventStack.unsub('resize', _this.handleUpdate, {\n          target: scrollContextNode\n        });\n        eventStack.unsub('scroll', _this.handleUpdate, {\n          target: scrollContextNode\n        });\n      }\n    };\n\n    _this.update = function (e) {\n      var pushing = _this.state.pushing;\n      _this.ticking = false;\n\n      _this.assignRects();\n\n      if (pushing) {\n        if (_this.didReachStartingPoint()) return _this.stickToContextTop(e);\n        if (_this.didTouchScreenBottom()) return _this.stickToScreenBottom(e);\n        return _this.stickToContextBottom(e);\n      }\n\n      if (_this.isOversized()) {\n        if (_this.contextRect.top > 0) return _this.stickToContextTop(e);\n        if (_this.contextRect.bottom < window.innerHeight) return _this.stickToContextBottom(e);\n      }\n\n      if (_this.didTouchScreenTop()) {\n        if (_this.didReachContextBottom()) return _this.stickToContextBottom(e);\n        return _this.stickToScreenTop(e);\n      }\n\n      return _this.stickToContextTop(e);\n    };\n\n    _this.handleUpdate = function (e) {\n      if (!_this.ticking) {\n        _this.ticking = true;\n        _this.frameId = requestAnimationFrame(function () {\n          return _this.update(e);\n        });\n      }\n    };\n\n    _this.assignRects = function () {\n      var context = _this.props.context;\n      var contextNode = isRefObject(context) ? context.current : context || document.body;\n      _this.triggerRect = _this.triggerRef.current.getBoundingClientRect();\n      _this.contextRect = contextNode.getBoundingClientRect();\n      _this.stickyRect = _this.stickyRef.current.getBoundingClientRect();\n    };\n\n    _this.didReachContextBottom = function () {\n      var offset = _this.props.offset;\n      return _this.stickyRect.height + offset >= _this.contextRect.bottom;\n    };\n\n    _this.didReachStartingPoint = function () {\n      return _this.stickyRect.top <= _this.triggerRect.top;\n    };\n\n    _this.didTouchScreenTop = function () {\n      return _this.triggerRect.top < _this.props.offset;\n    };\n\n    _this.didTouchScreenBottom = function () {\n      var bottomOffset = _this.props.bottomOffset;\n      return _this.contextRect.bottom + bottomOffset > window.innerHeight;\n    };\n\n    _this.isOversized = function () {\n      return _this.stickyRect.height > window.innerHeight;\n    };\n\n    _this.pushing = function (pushing) {\n      var possible = _this.props.pushing;\n      if (possible) _this.setState({\n        pushing: pushing\n      });\n    };\n\n    _this.stick = function (e, bound) {\n      _this.setState({\n        bound: bound,\n        sticky: true\n      });\n\n      _invoke(_this.props, 'onStick', e, _this.props);\n    };\n\n    _this.unstick = function (e, bound) {\n      _this.setState({\n        bound: bound,\n        sticky: false\n      });\n\n      _invoke(_this.props, 'onUnstick', e, _this.props);\n    };\n\n    _this.stickToContextBottom = function (e) {\n      _invoke(_this.props, 'onBottom', e, _this.props);\n\n      _this.stick(e, true);\n\n      _this.pushing(true);\n    };\n\n    _this.stickToContextTop = function (e) {\n      _invoke(_this.props, 'onTop', e, _this.props);\n\n      _this.unstick(e, false);\n\n      _this.pushing(false);\n    };\n\n    _this.stickToScreenBottom = function (e) {\n      var bottom = _this.props.bottomOffset;\n\n      _this.stick(e, false);\n\n      _this.setState({\n        bottom: bottom,\n        top: null\n      });\n    };\n\n    _this.stickToScreenTop = function (e) {\n      var top = _this.props.offset;\n\n      _this.stick(e, false);\n\n      _this.setState({\n        top: top,\n        bottom: null\n      });\n    };\n\n    return _this;\n  }\n\n  var _proto = Sticky.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    if (!isBrowser()) return;\n    var active = this.state.active;\n\n    if (active) {\n      this.handleUpdate();\n      this.addListeners(this.props.scrollContext);\n    }\n  };\n\n  Sticky.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    if (state.active !== props.active && !props.active) {\n      return {\n        active: props.active,\n        sticky: false\n      };\n    }\n\n    return {\n      active: props.active\n    };\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    if (prevState.active === this.state.active) {\n      if (prevProps.scrollContext !== this.props.scrollContext) {\n        this.removeListeners(prevProps.scrollContext);\n        this.addListeners(this.props.scrollContext);\n      }\n\n      return;\n    }\n\n    if (this.state.active) {\n      this.handleUpdate();\n      this.addListeners(this.props.scrollContext);\n      return;\n    }\n\n    this.removeListeners(prevProps.scrollContext);\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    if (!isBrowser()) return;\n    var active = this.state.active;\n\n    if (active) {\n      this.removeListeners(this.props.scrollContext);\n      cancelAnimationFrame(this.frameId);\n    }\n  } // ----------------------------------------\n  // Events\n  // ----------------------------------------\n  ;\n\n  _proto.computeStyle = function computeStyle() {\n    var styleElement = this.props.styleElement;\n    var _this$state = this.state,\n        bottom = _this$state.bottom,\n        bound = _this$state.bound,\n        sticky = _this$state.sticky,\n        top = _this$state.top;\n    if (!sticky) return styleElement;\n    return _extends({\n      bottom: bound ? 0 : bottom,\n      top: bound ? undefined : top,\n      width: this.triggerRect.width\n    }, styleElement);\n  } // Return true when the component reached the bottom of the context\n  ;\n\n  // ----------------------------------------\n  // Render\n  // ----------------------------------------\n  _proto.render = function render() {\n    var _this$props = this.props,\n        children = _this$props.children,\n        className = _this$props.className;\n    var _this$state2 = this.state,\n        bottom = _this$state2.bottom,\n        bound = _this$state2.bound,\n        sticky = _this$state2.sticky;\n    var rest = getUnhandledProps(Sticky, this.props);\n    var ElementType = getElementType(Sticky, this.props);\n    var containerClasses = cx(sticky && 'ui', sticky && 'stuck-container', sticky && (bound ? 'bound-container' : 'fixed-container'), className);\n    var elementClasses = cx('ui', sticky && (bound ? 'bound bottom' : 'fixed'), sticky && !bound && (bottom === null ? 'top' : 'bottom'), 'sticky');\n    var triggerStyles = sticky && this.stickyRect ? {\n      height: this.stickyRect.height\n    } : {};\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: containerClasses\n    }), /*#__PURE__*/React.createElement(\"div\", {\n      ref: this.triggerRef,\n      style: triggerStyles\n    }), /*#__PURE__*/React.createElement(\"div\", {\n      className: elementClasses,\n      ref: this.stickyRef,\n      style: this.computeStyle()\n    }, children));\n  };\n\n  return Sticky;\n}(Component);\n\nSticky.handledProps = [\"active\", \"as\", \"bottomOffset\", \"children\", \"className\", \"context\", \"offset\", \"onBottom\", \"onStick\", \"onTop\", \"onUnstick\", \"pushing\", \"scrollContext\", \"styleElement\"];\nexport { Sticky as default };\nSticky.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A Sticky can be active. */\n  active: PropTypes.bool,\n\n  /** Offset in pixels from the bottom of the screen when fixing element to viewport. */\n  bottomOffset: PropTypes.number,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Context which sticky element should stick to. */\n  context: PropTypes.oneOfType([customPropTypes.domNode, customPropTypes.refObject]),\n\n  /** Offset in pixels from the top of the screen when fixing element to viewport. */\n  offset: PropTypes.number,\n\n  /**\n   * Callback when element is bound to bottom of parent container.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onBottom: PropTypes.func,\n\n  /**\n   * Callback when element is fixed to page.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onStick: PropTypes.func,\n\n  /**\n   * Callback when element is bound to top of parent container.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onTop: PropTypes.func,\n\n  /**\n   * Callback when element is unfixed from page.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onUnstick: PropTypes.func,\n\n  /** Whether element should be \"pushed\" by the viewport, attaching to the bottom of the screen when scrolling up. */\n  pushing: PropTypes.bool,\n\n  /** Context which sticky should attach onscroll events. */\n  scrollContext: PropTypes.oneOfType([customPropTypes.domNode, customPropTypes.refObject]),\n\n  /** Custom style for sticky element. */\n  styleElement: PropTypes.object\n} : {};\nSticky.defaultProps = {\n  active: true,\n  bottomOffset: 0,\n  offset: 0,\n  scrollContext: isBrowser() ? window : null\n};","import _default from './Sticky';\nexport { _default as default };","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _map from \"lodash/map\";\nimport _get from \"lodash/get\";\nimport _invoke from \"lodash/invoke\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { ModernAutoControlledComponent as Component, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport Grid from '../../collections/Grid/Grid';\nimport GridColumn from '../../collections/Grid/GridColumn';\nimport Menu from '../../collections/Menu/Menu';\nimport TabPane from './TabPane';\n/**\n * A Tab is a hidden section of content activated by a Menu.\n * @see Menu\n * @see Segment\n */\n\nvar Tab = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Tab, _Component);\n\n  function Tab() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleItemClick = function (e, _ref) {\n      var index = _ref.index;\n\n      _invoke(_this.props, 'onTabChange', e, _extends({}, _this.props, {\n        activeIndex: index\n      }));\n\n      _this.setState({\n        activeIndex: index\n      });\n    };\n\n    return _this;\n  }\n\n  var _proto = Tab.prototype;\n\n  _proto.getInitialAutoControlledState = function getInitialAutoControlledState() {\n    return {\n      activeIndex: 0\n    };\n  };\n\n  _proto.renderItems = function renderItems() {\n    var _this$props = this.props,\n        panes = _this$props.panes,\n        renderActiveOnly = _this$props.renderActiveOnly;\n    var activeIndex = this.state.activeIndex;\n    if (renderActiveOnly) return _invoke(_get(panes, \"[\" + activeIndex + \"]\"), 'render', this.props);\n    return _map(panes, function (_ref2, index) {\n      var pane = _ref2.pane;\n      return TabPane.create(pane, {\n        overrideProps: {\n          active: index === activeIndex\n        }\n      });\n    });\n  };\n\n  _proto.renderMenu = function renderMenu() {\n    var _this$props2 = this.props,\n        menu = _this$props2.menu,\n        panes = _this$props2.panes,\n        menuPosition = _this$props2.menuPosition;\n    var activeIndex = this.state.activeIndex;\n\n    if (menu.tabular === true && menuPosition === 'right') {\n      menu.tabular = 'right';\n    }\n\n    return Menu.create(menu, {\n      autoGenerateKey: false,\n      overrideProps: {\n        items: _map(panes, 'menuItem'),\n        onItemClick: this.handleItemClick,\n        activeIndex: activeIndex\n      }\n    });\n  };\n\n  _proto.renderVertical = function renderVertical(menu) {\n    var _this$props3 = this.props,\n        grid = _this$props3.grid,\n        menuPosition = _this$props3.menuPosition;\n\n    var paneWidth = grid.paneWidth,\n        tabWidth = grid.tabWidth,\n        gridProps = _objectWithoutPropertiesLoose(grid, [\"paneWidth\", \"tabWidth\"]);\n\n    var position = menuPosition || menu.props.tabular === 'right' && 'right' || 'left';\n    return /*#__PURE__*/React.createElement(Grid, gridProps, position === 'left' && GridColumn.create({\n      width: tabWidth,\n      children: menu\n    }, {\n      autoGenerateKey: false\n    }), GridColumn.create({\n      width: paneWidth,\n      children: this.renderItems(),\n      stretched: true\n    }, {\n      autoGenerateKey: false\n    }), position === 'right' && GridColumn.create({\n      width: tabWidth,\n      children: menu\n    }, {\n      autoGenerateKey: false\n    }));\n  };\n\n  _proto.render = function render() {\n    var menu = this.renderMenu();\n    var rest = getUnhandledProps(Tab, this.props);\n    var ElementType = getElementType(Tab, this.props);\n\n    if (menu.props.vertical) {\n      return /*#__PURE__*/React.createElement(ElementType, rest, this.renderVertical(menu));\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, rest, menu.props.attached !== 'bottom' && menu, this.renderItems(), menu.props.attached === 'bottom' && menu);\n  };\n\n  return Tab;\n}(Component);\n\nTab.handledProps = [\"activeIndex\", \"as\", \"defaultActiveIndex\", \"grid\", \"menu\", \"menuPosition\", \"onTabChange\", \"panes\", \"renderActiveOnly\"];\nTab.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** The initial activeIndex. */\n  defaultActiveIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /** Index of the currently active tab. */\n  activeIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n  /**\n   * Shorthand props for the Menu.\n   * tabular, if true, will derive final value from `menuPosition`, otherwise set 'left' or 'right' explicitly.\n   */\n  menu: PropTypes.object,\n\n  /** Align vertical menu */\n  menuPosition: PropTypes.oneOf(['left', 'right']),\n\n  /** Shorthand props for the Grid. Only applicable to vertical menus. */\n  grid: PropTypes.object,\n\n  /**\n   * Called on tab change.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props and proposed new activeIndex.\n   * @param {object} data.activeIndex - The new proposed activeIndex.\n   */\n  onTabChange: PropTypes.func,\n\n  /**\n   * Array of objects describing each Menu.Item and Tab.Pane:\n   * { menuItem: 'Home', render: () => <Tab.Pane /> }\n   * or\n   * { menuItem: 'Home', pane: 'Welcome' }\n   */\n  panes: PropTypes.arrayOf(PropTypes.shape({\n    menuItem: customPropTypes.itemShorthand,\n    pane: customPropTypes.itemShorthand,\n    render: PropTypes.func\n  })),\n\n  /** A Tab can render only active pane. */\n  renderActiveOnly: PropTypes.bool\n} : {};\nTab.autoControlledProps = ['activeIndex'];\nTab.defaultProps = {\n  grid: {\n    paneWidth: 12,\n    tabWidth: 4\n  },\n  menu: {\n    attached: true,\n    tabular: true\n  },\n  renderActiveOnly: true\n};\nTab.Pane = TabPane;\nexport default Tab;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport Segment from '../../elements/Segment/Segment';\n/**\n * A tab pane holds the content of a tab.\n */\n\nfunction TabPane(props) {\n  var active = props.active,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      loading = props.loading;\n  var classes = cx(useKeyOnly(active, 'active'), useKeyOnly(loading, 'loading'), 'tab', className);\n  var rest = getUnhandledProps(TabPane, props);\n  var ElementType = getElementType(TabPane, props);\n  var calculatedDefaultProps = {};\n\n  if (ElementType === Segment) {\n    calculatedDefaultProps.attached = 'bottom';\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, calculatedDefaultProps, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nTabPane.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\", \"loading\"];\nTabPane.defaultProps = {\n  as: Segment,\n  active: true\n};\nTabPane.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A tab pane can be active. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A Tab.Pane can display a loading indicator. */\n  loading: PropTypes.bool\n} : {};\nTabPane.create = createShorthandFactory(TabPane, function (content) {\n  return {\n    content: content\n  };\n});\nexport default TabPane;","import _default from './Tab';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _includes from \"lodash/includes\";\nimport _isNil from \"lodash/isNil\";\nimport _get from \"lodash/get\";\nimport _invoke from \"lodash/invoke\";\n\nvar _TRANSITION_CALLBACK_, _TRANSITION_STYLE_TYP;\n\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport { cloneElement, Component } from 'react';\nimport { normalizeTransitionDuration, SUI, useKeyOnly } from '../../lib';\nimport TransitionGroup from './TransitionGroup';\nimport { computeStatuses, TRANSITION_STATUS_ENTERED, TRANSITION_STATUS_ENTERING, TRANSITION_STATUS_EXITED, TRANSITION_STATUS_EXITING, TRANSITION_STATUS_INITIAL, TRANSITION_STATUS_UNMOUNTED } from './utils/computeStatuses';\nvar TRANSITION_CALLBACK_TYPE = (_TRANSITION_CALLBACK_ = {}, _TRANSITION_CALLBACK_[TRANSITION_STATUS_ENTERED] = 'show', _TRANSITION_CALLBACK_[TRANSITION_STATUS_EXITED] = 'hide', _TRANSITION_CALLBACK_);\nvar TRANSITION_STYLE_TYPE = (_TRANSITION_STYLE_TYP = {}, _TRANSITION_STYLE_TYP[TRANSITION_STATUS_ENTERING] = 'show', _TRANSITION_STYLE_TYP[TRANSITION_STATUS_EXITING] = 'hide', _TRANSITION_STYLE_TYP);\n/**\n * A transition is an animation usually used to move content in or out of view.\n */\n\nvar Transition = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Transition, _Component);\n\n  function Transition() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n    _this.state = {\n      status: TRANSITION_STATUS_INITIAL\n    };\n\n    _this.handleStart = function (nextStatus) {\n      var duration = _this.props.duration;\n      var durationType = TRANSITION_CALLBACK_TYPE[nextStatus];\n      var durationValue = normalizeTransitionDuration(duration, durationType);\n      clearTimeout(_this.timeoutId);\n      _this.timeoutId = setTimeout(function () {\n        return _this.setState(function (state) {\n          return {\n            status: state.nextStatus\n          };\n        });\n      }, durationValue);\n    };\n\n    _this.updateStatus = function (prevState) {\n      if (_this.state.status !== _this.state.nextStatus && _this.state.nextStatus) {\n        _this.handleStart(_this.state.nextStatus);\n      }\n\n      if (!prevState.animating && _this.state.animating) {\n        _invoke(_this.props, 'onStart', null, _extends({}, _this.props, {\n          status: _this.state.status\n        }));\n      }\n\n      if (prevState.animating && !_this.state.animating) {\n        var callback = _this.state.status === TRANSITION_STATUS_ENTERED ? 'onShow' : 'onHide';\n\n        _invoke(_this.props, 'onComplete', null, _extends({}, _this.props, {\n          status: _this.state.status\n        }));\n\n        _invoke(_this.props, callback, null, _extends({}, _this.props, {\n          status: _this.state.status\n        }));\n      }\n    };\n\n    _this.computeClasses = function () {\n      var _this$props = _this.props,\n          animation = _this$props.animation,\n          directional = _this$props.directional,\n          children = _this$props.children;\n      var _this$state = _this.state,\n          animating = _this$state.animating,\n          status = _this$state.status;\n\n      var childClasses = _get(children, 'props.className');\n\n      var isDirectional = _isNil(directional) ? _includes(SUI.DIRECTIONAL_TRANSITIONS, animation) : directional;\n\n      if (isDirectional) {\n        return cx(animation, childClasses, useKeyOnly(animating, 'animating'), useKeyOnly(status === TRANSITION_STATUS_ENTERING, 'in'), useKeyOnly(status === TRANSITION_STATUS_EXITING, 'out'), useKeyOnly(status === TRANSITION_STATUS_EXITED, 'hidden'), useKeyOnly(status !== TRANSITION_STATUS_EXITED, 'visible'), 'transition');\n      }\n\n      return cx(animation, childClasses, useKeyOnly(animating, 'animating transition'));\n    };\n\n    _this.computeStyle = function () {\n      var _this$props2 = _this.props,\n          children = _this$props2.children,\n          duration = _this$props2.duration;\n      var status = _this.state.status;\n\n      var childStyle = _get(children, 'props.style');\n\n      var type = TRANSITION_STYLE_TYPE[status];\n      var animationDuration = type && normalizeTransitionDuration(duration, type) + \"ms\";\n      return _extends({}, childStyle, {\n        animationDuration: animationDuration\n      });\n    };\n\n    return _this;\n  }\n\n  // ----------------------------------------\n  // Lifecycle\n  // ----------------------------------------\n  Transition.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    var derivedState = computeStatuses({\n      mountOnShow: props.mountOnShow,\n      status: state.status,\n      transitionOnMount: props.transitionOnMount,\n      visible: props.visible,\n      unmountOnHide: props.unmountOnHide\n    });\n    return derivedState;\n  };\n\n  var _proto = Transition.prototype;\n\n  _proto.componentDidMount = function componentDidMount() {\n    this.updateStatus({});\n  };\n\n  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {\n    this.updateStatus(prevState);\n  };\n\n  _proto.componentWillUnmount = function componentWillUnmount() {\n    clearTimeout(this.timeoutId);\n  } // ----------------------------------------\n  // Callback handling\n  // ----------------------------------------\n  ;\n\n  // ----------------------------------------\n  // Render\n  // ----------------------------------------\n  _proto.render = function render() {\n    var children = this.props.children;\n    var status = this.state.status;\n\n    if (status === TRANSITION_STATUS_UNMOUNTED) {\n      return null;\n    }\n\n    return /*#__PURE__*/cloneElement(children, {\n      className: this.computeClasses(),\n      style: this.computeStyle()\n    });\n  };\n\n  return Transition;\n}(Component);\n\nTransition.INITIAL = TRANSITION_STATUS_INITIAL;\nTransition.ENTERED = TRANSITION_STATUS_ENTERED;\nTransition.ENTERING = TRANSITION_STATUS_ENTERING;\nTransition.EXITED = TRANSITION_STATUS_EXITED;\nTransition.EXITING = TRANSITION_STATUS_EXITING;\nTransition.UNMOUNTED = TRANSITION_STATUS_UNMOUNTED;\nTransition.Group = TransitionGroup;\nTransition.handledProps = [\"animation\", \"children\", \"directional\", \"duration\", \"mountOnShow\", \"onComplete\", \"onHide\", \"onShow\", \"onStart\", \"reactKey\", \"transitionOnMount\", \"unmountOnHide\", \"visible\"];\nexport { Transition as default };\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** Named animation event to used. Must be defined in CSS. */\n  animation: PropTypes.oneOfType([PropTypes.oneOf(SUI.TRANSITIONS), PropTypes.string]),\n\n  /** Primary content. */\n  children: PropTypes.element.isRequired,\n\n  /** Whether it is directional animation event or not. Use it only for custom transitions. */\n  directional: PropTypes.bool,\n\n  /** Duration of the CSS transition animation in milliseconds. */\n  duration: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({\n    hide: PropTypes.number,\n    show: PropTypes.number\n  }), PropTypes.string]),\n\n  /** Show the component; triggers the enter or exit animation. */\n  visible: PropTypes.bool,\n\n  /** Wait until the first \"enter\" transition to mount the component (add it to the DOM). */\n  mountOnShow: PropTypes.bool,\n\n  /**\n   * Callback on each transition that changes visibility to shown.\n   *\n   * @param {null}\n   * @param {object} data - All props with status.\n   */\n  onComplete: PropTypes.func,\n\n  /**\n   * Callback on each transition that changes visibility to hidden.\n   *\n   * @param {null}\n   * @param {object} data - All props with status.\n   */\n  onHide: PropTypes.func,\n\n  /**\n   * Callback on each transition that changes visibility to shown.\n   *\n   * @param {null}\n   * @param {object} data - All props with status.\n   */\n  onShow: PropTypes.func,\n\n  /**\n   * Callback on animation start.\n   *\n   * @param {null}\n   * @param {object} data - All props with status.\n   */\n  onStart: PropTypes.func,\n\n  /** React's key of the element. */\n  reactKey: PropTypes.string,\n\n  /** Run the enter animation when the component mounts, if it is initially shown. */\n  transitionOnMount: PropTypes.bool,\n\n  /** Unmount the component (remove it from the DOM) when it is not shown. */\n  unmountOnHide: PropTypes.bool\n} : {};\nTransition.defaultProps = {\n  animation: 'fade',\n  duration: 500,\n  visible: true,\n  mountOnShow: true,\n  transitionOnMount: false,\n  unmountOnHide: false\n};","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport _values from \"lodash/values\";\nimport _get from \"lodash/get\";\nimport _has from \"lodash/has\";\nimport _forEach from \"lodash/forEach\";\nimport _mapValues from \"lodash/mapValues\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { getElementType, getUnhandledProps, SUI } from '../../lib';\nimport { getChildMapping, mergeChildMappings } from './utils/childMapping';\nimport wrapChild from './utils/wrapChild';\n\n/**\n * A Transition.Group animates children as they mount and unmount.\n */\nvar TransitionGroup = /*#__PURE__*/function (_React$Component) {\n  _inheritsLoose(TransitionGroup, _React$Component);\n\n  function TransitionGroup() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n    _this.state = {\n      // Keeping a callback under the state is a hack to make it accessible under getDerivedStateFromProps()\n      handleOnHide: function handleOnHide(nothing, childProps) {\n        var reactKey = childProps.reactKey;\n\n        _this.setState(function (state) {\n          var children = _extends({}, state.children);\n\n          delete children[reactKey];\n          return {\n            children: children\n          };\n        });\n      }\n    };\n    return _this;\n  }\n\n  TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {\n    var animation = props.animation,\n        duration = props.duration,\n        directional = props.directional;\n    var prevMapping = state.children; // A short circuit for an initial render as there will be no `prevMapping`\n\n    if (typeof prevMapping === 'undefined') {\n      return {\n        children: _mapValues(getChildMapping(props.children), function (child) {\n          return wrapChild(child, state.handleOnHide, {\n            animation: animation,\n            duration: duration,\n            directional: directional\n          });\n        })\n      };\n    }\n\n    var nextMapping = getChildMapping(props.children);\n    var children = mergeChildMappings(prevMapping, nextMapping);\n\n    _forEach(children, function (child, key) {\n      var hasPrev = _has(prevMapping, key);\n\n      var hasNext = _has(nextMapping, key);\n\n      var prevChild = prevMapping[key];\n      var isLeaving = !_get(prevChild, 'props.visible'); // Heads up!\n      // An item is new (entering), it will be picked from `nextChildren`, so it should be wrapped\n\n      if (hasNext && (!hasPrev || isLeaving)) {\n        children[key] = wrapChild(child, state.handleOnHide, {\n          animation: animation,\n          duration: duration,\n          directional: directional,\n          transitionOnMount: true\n        });\n        return;\n      } // Heads up!\n      // An item is old (exiting), it will be picked from `prevChildren`, so it has been already\n      // wrapped, so should be only updated\n\n\n      if (!hasNext && hasPrev && !isLeaving) {\n        children[key] = /*#__PURE__*/React.cloneElement(prevChild, {\n          visible: false\n        });\n        return;\n      } // Heads up!\n      // An item item hasn't changed transition states, but it will be picked from `nextChildren`,\n      // so we should wrap it again\n\n\n      var _prevChild$props = prevChild.props,\n          visible = _prevChild$props.visible,\n          transitionOnMount = _prevChild$props.transitionOnMount;\n      children[key] = wrapChild(child, state.handleOnHide, {\n        animation: animation,\n        duration: duration,\n        directional: directional,\n        transitionOnMount: transitionOnMount,\n        visible: visible\n      });\n    });\n\n    return {\n      children: children\n    };\n  };\n\n  var _proto = TransitionGroup.prototype;\n\n  _proto.render = function render() {\n    var children = this.state.children;\n    var ElementType = getElementType(TransitionGroup, this.props);\n    var rest = getUnhandledProps(TransitionGroup, this.props);\n    return /*#__PURE__*/React.createElement(ElementType, rest, _values(children));\n  };\n\n  return TransitionGroup;\n}(React.Component);\n\nTransitionGroup.handledProps = [\"animation\", \"as\", \"children\", \"directional\", \"duration\"];\nexport { TransitionGroup as default };\nTransitionGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Named animation event to used. Must be defined in CSS. */\n  animation: PropTypes.oneOfType([PropTypes.oneOf(SUI.TRANSITIONS), PropTypes.string]),\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Whether it is directional animation event or not. Use it only for custom transitions. */\n  directional: PropTypes.bool,\n\n  /** Duration of the CSS transition animation in milliseconds. */\n  duration: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({\n    hide: PropTypes.number.isRequired,\n    show: PropTypes.number.isRequired\n  }), PropTypes.string])\n} : {};\nTransitionGroup.defaultProps = {\n  as: React.Fragment,\n  animation: 'fade',\n  duration: 500\n};","import _default from './Transition';\nexport { _default as default };","import _has from \"lodash/has\";\nimport _keys from \"lodash/keys\";\nimport _forEach from \"lodash/forEach\";\nimport _filter from \"lodash/filter\";\nimport _keyBy from \"lodash/keyBy\";\nimport { Children, isValidElement } from 'react';\n/**\n * Given `this.props.children`, return an object mapping key to child.\n *\n * @param {object} children Element's children\n * @return {object} Mapping of key to child\n */\n\nexport var getChildMapping = function getChildMapping(children) {\n  return _keyBy(_filter(Children.toArray(children), isValidElement), 'key');\n};\n\nvar getPendingKeys = function getPendingKeys(prev, next) {\n  var nextKeysPending = {};\n  var pendingKeys = [];\n\n  _forEach(_keys(prev), function (prevKey) {\n    if (!_has(next, prevKey)) {\n      pendingKeys.push(prevKey);\n      return;\n    }\n\n    if (pendingKeys.length) {\n      nextKeysPending[prevKey] = pendingKeys;\n      pendingKeys = [];\n    }\n  });\n\n  return [nextKeysPending, pendingKeys];\n};\n\nvar getValue = function getValue(key, prev, next) {\n  return _has(next, key) ? next[key] : prev[key];\n};\n/**\n * When you're adding or removing children some may be added or removed in the same render pass. We want to show *both*\n * since we want to simultaneously animate elements in and out. This function takes a previous set of keys and a new set\n * of keys and merges them with its best guess of the correct ordering.\n *\n * @param {object} prev Prev children as returned from `getChildMapping()`\n * @param {object} next Next children as returned from `getChildMapping()`\n * @return {object} A key set that contains all keys in `prev` and all keys in `next` in a reasonable order\n */\n\n\nexport var mergeChildMappings = function mergeChildMappings(prev, next) {\n  if (prev === void 0) {\n    prev = {};\n  }\n\n  if (next === void 0) {\n    next = {};\n  }\n\n  var childMapping = {};\n\n  var _getPendingKeys = getPendingKeys(prev, next),\n      nextKeysPending = _getPendingKeys[0],\n      pendingKeys = _getPendingKeys[1];\n\n  _forEach(_keys(next), function (nextKey) {\n    if (_has(nextKeysPending, nextKey)) {\n      _forEach(nextKeysPending[nextKey], function (pendingKey) {\n        childMapping[pendingKey] = getValue(pendingKey, prev, next);\n      });\n    }\n\n    childMapping[nextKey] = getValue(nextKey, prev, next);\n  });\n\n  _forEach(pendingKeys, function (pendingKey) {\n    childMapping[pendingKey] = getValue(pendingKey, prev, next);\n  });\n\n  return childMapping;\n};","export var TRANSITION_STATUS_INITIAL = 'INITIAL';\nexport var TRANSITION_STATUS_ENTERED = 'ENTERED';\nexport var TRANSITION_STATUS_ENTERING = 'ENTERING';\nexport var TRANSITION_STATUS_EXITED = 'EXITED';\nexport var TRANSITION_STATUS_EXITING = 'EXITING';\nexport var TRANSITION_STATUS_UNMOUNTED = 'UNMOUNTED';\n/**\n * @param {Object} [options]\n * @param {String} [options.status]\n * @param {Boolean} [options.mountOnShow]\n * @param {Boolean} [options.transitionOnMount]\n * @param {Boolean} [options.visible]\n * @param {Boolean} [options.unmountOnHide]\n */\n\nexport function computeStatuses(options) {\n  var mountOnShow = options.mountOnShow,\n      status = options.status,\n      transitionOnMount = options.transitionOnMount,\n      visible = options.visible,\n      unmountOnHide = options.unmountOnHide;\n\n  if (visible) {\n    if (status === TRANSITION_STATUS_INITIAL) {\n      if (transitionOnMount) {\n        return {\n          animating: true,\n          status: TRANSITION_STATUS_ENTERING,\n          nextStatus: TRANSITION_STATUS_ENTERED\n        };\n      }\n\n      return {\n        animating: false,\n        status: TRANSITION_STATUS_ENTERED,\n        nextStatus: undefined\n      };\n    }\n\n    if (status === TRANSITION_STATUS_UNMOUNTED) {\n      return {\n        animating: true,\n        status: TRANSITION_STATUS_ENTERING,\n        nextStatus: TRANSITION_STATUS_ENTERED\n      };\n    }\n\n    if (status === TRANSITION_STATUS_EXITED || status === TRANSITION_STATUS_EXITING) {\n      return {\n        animating: true,\n        status: TRANSITION_STATUS_ENTERING,\n        nextStatus: TRANSITION_STATUS_ENTERED\n      };\n    }\n\n    if (status === TRANSITION_STATUS_ENTERING) {\n      return {};\n    }\n    /* istanbul ignore else */\n\n\n    if (status === TRANSITION_STATUS_ENTERED) {\n      return {\n        animating: false,\n        status: TRANSITION_STATUS_ENTERED,\n        nextStatus: undefined\n      };\n    }\n  }\n\n  if (status === TRANSITION_STATUS_INITIAL) {\n    if (mountOnShow || unmountOnHide) {\n      return {\n        animating: false,\n        status: TRANSITION_STATUS_UNMOUNTED,\n        nextStatus: undefined\n      };\n    }\n\n    return {\n      animating: false,\n      status: TRANSITION_STATUS_EXITED,\n      nextStatus: undefined\n    };\n  }\n\n  if (status === TRANSITION_STATUS_ENTERED || status === TRANSITION_STATUS_ENTERING) {\n    return {\n      animating: true,\n      status: TRANSITION_STATUS_EXITING,\n      nextStatus: unmountOnHide ? TRANSITION_STATUS_UNMOUNTED : TRANSITION_STATUS_EXITED\n    };\n  }\n\n  if (status === TRANSITION_STATUS_EXITING) {\n    return {};\n  }\n\n  if (status === TRANSITION_STATUS_EXITED) {\n    return {\n      animating: false,\n      status: TRANSITION_STATUS_EXITED,\n      nextStatus: undefined\n    };\n  }\n  /* istanbul ignore else */\n\n\n  if (status === TRANSITION_STATUS_UNMOUNTED) {\n    return {\n      animating: false,\n      status: TRANSITION_STATUS_UNMOUNTED,\n      nextStatus: undefined\n    };\n  }\n  /* istanbul ignore next */\n\n\n  throw new Error(\"Transition:computeStatuses(): an unexpected status transition: { visible: \" + visible + \", status: \" + status + \" }\");\n}","import React from 'react';\nimport Transition from '../Transition';\n/**\n * Wraps a React element with a Transition component.\n *\n * @param {React.ReactElement} child\n * @param {Function} onHide\n * @param {Object} [options={}]\n * @param {String} [options.animation]\n * @param {Number} [options.duration]\n * @param {Boolean} [options.directional]\n * @param {Boolean} [options.transitionOnMount=false]\n * @param {Boolean} [options.visible=true]\n */\n\nexport default function wrapChild(child, onHide, options) {\n  if (options === void 0) {\n    options = {};\n  }\n\n  var key = child.key;\n  var _options = options,\n      animation = _options.animation,\n      directional = _options.directional,\n      duration = _options.duration,\n      _options$transitionOn = _options.transitionOnMount,\n      transitionOnMount = _options$transitionOn === void 0 ? false : _options$transitionOn,\n      _options$visible = _options.visible,\n      visible = _options$visible === void 0 ? true : _options$visible;\n  return /*#__PURE__*/React.createElement(Transition, {\n    animation: animation,\n    directional: directional,\n    duration: duration,\n    key: key,\n    onHide: onHide,\n    reactKey: key,\n    transitionOnMount: transitionOnMount,\n    visible: visible\n  }, child);\n}\nwrapChild.handledProps = [];","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * An ad displays third-party promotional content.\n */\n\nfunction Advertisement(props) {\n  var centered = props.centered,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      test = props.test,\n      unit = props.unit;\n  var classes = cx('ui', unit, useKeyOnly(centered, 'centered'), useKeyOnly(test, 'test'), 'ad', className);\n  var rest = getUnhandledProps(Advertisement, props);\n  var ElementType = getElementType(Advertisement, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes,\n    \"data-text\": test\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nAdvertisement.handledProps = [\"as\", \"centered\", \"children\", \"className\", \"content\", \"test\", \"unit\"];\nAdvertisement.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Center the advertisement. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Text to be displayed on the advertisement. */\n  test: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string]),\n\n  /** Varies the size of the advertisement. */\n  unit: PropTypes.oneOf(['medium rectangle', 'large rectangle', 'vertical rectangle', 'small rectangle', 'mobile banner', 'banner', 'vertical banner', 'top banner', 'half banner', 'button', 'square button', 'small button', 'skyscraper', 'wide skyscraper', 'leaderboard', 'large leaderboard', 'mobile leaderboard', 'billboard', 'panorama', 'netboard', 'half page', 'square', 'small square']).isRequired\n} : {};\nexport default Advertisement;","import _default from './Advertisement';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly } from '../../lib';\nimport Image from '../../elements/Image';\nimport CardContent from './CardContent';\nimport CardDescription from './CardDescription';\nimport CardGroup from './CardGroup';\nimport CardHeader from './CardHeader';\nimport CardMeta from './CardMeta';\n/**\n * A card displays site content in a manner similar to a playing card.\n */\n\nvar Card = /*#__PURE__*/function (_Component) {\n  _inheritsLoose(Card, _Component);\n\n  function Card() {\n    var _this;\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _Component.call.apply(_Component, [this].concat(args)) || this;\n\n    _this.handleClick = function (e) {\n      var onClick = _this.props.onClick;\n      if (onClick) onClick(e, _this.props);\n    };\n\n    return _this;\n  }\n\n  var _proto = Card.prototype;\n\n  _proto.render = function render() {\n    var _this$props = this.props,\n        centered = _this$props.centered,\n        children = _this$props.children,\n        className = _this$props.className,\n        color = _this$props.color,\n        content = _this$props.content,\n        description = _this$props.description,\n        extra = _this$props.extra,\n        fluid = _this$props.fluid,\n        header = _this$props.header,\n        href = _this$props.href,\n        image = _this$props.image,\n        link = _this$props.link,\n        meta = _this$props.meta,\n        onClick = _this$props.onClick,\n        raised = _this$props.raised;\n    var classes = cx('ui', color, useKeyOnly(centered, 'centered'), useKeyOnly(fluid, 'fluid'), useKeyOnly(link, 'link'), useKeyOnly(raised, 'raised'), 'card', className);\n    var rest = getUnhandledProps(Card, this.props);\n    var ElementType = getElementType(Card, this.props, function () {\n      if (onClick) return 'a';\n    });\n\n    if (!childrenUtils.isNil(children)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        href: href,\n        onClick: this.handleClick\n      }), children);\n    }\n\n    if (!childrenUtils.isNil(content)) {\n      return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n        className: classes,\n        href: href,\n        onClick: this.handleClick\n      }), content);\n    }\n\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes,\n      href: href,\n      onClick: this.handleClick\n    }), Image.create(image, {\n      autoGenerateKey: false,\n      defaultProps: {\n        ui: false,\n        wrapped: true\n      }\n    }), (description || header || meta) && /*#__PURE__*/React.createElement(CardContent, {\n      description: description,\n      header: header,\n      meta: meta\n    }), extra && /*#__PURE__*/React.createElement(CardContent, {\n      extra: true\n    }, extra));\n  };\n\n  return Card;\n}(Component);\n\nCard.handledProps = [\"as\", \"centered\", \"children\", \"className\", \"color\", \"content\", \"description\", \"extra\", \"fluid\", \"header\", \"href\", \"image\", \"link\", \"meta\", \"onClick\", \"raised\"];\nexport { Card as default };\nCard.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A Card can center itself inside its container. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A Card can be formatted to display different colors. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for CardDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** Shorthand for primary content of CardContent. */\n  extra: customPropTypes.contentShorthand,\n\n  /** A Card can be formatted to take up the width of its container. */\n  fluid: PropTypes.bool,\n\n  /** Shorthand for CardHeader. */\n  header: customPropTypes.itemShorthand,\n\n  /** Render as an `a` tag instead of a `div` and adds the href attribute. */\n  href: PropTypes.string,\n\n  /** A card can contain an Image component. */\n  image: customPropTypes.itemShorthand,\n\n  /** A card can be formatted to link to other content. */\n  link: PropTypes.bool,\n\n  /** Shorthand for CardMeta. */\n  meta: customPropTypes.itemShorthand,\n\n  /**\n   * Called on click. When passed, the component renders as an `a`\n   * tag by default instead of a `div`.\n   *\n   * @param {SyntheticEvent} event - React's original SyntheticEvent.\n   * @param {object} data - All props.\n   */\n  onClick: PropTypes.func,\n\n  /** A Card can be formatted to raise above the page. */\n  raised: PropTypes.bool\n} : {};\nCard.Content = CardContent;\nCard.Description = CardDescription;\nCard.Group = CardGroup;\nCard.Header = CardHeader;\nCard.Meta = CardMeta;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthand, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useTextAlignProp } from '../../lib';\nimport CardDescription from './CardDescription';\nimport CardHeader from './CardHeader';\nimport CardMeta from './CardMeta';\n/**\n * A card can contain blocks of content or extra content meant to be formatted separately from the main content.\n */\n\nfunction CardContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      description = props.description,\n      extra = props.extra,\n      header = props.header,\n      meta = props.meta,\n      textAlign = props.textAlign;\n  var classes = cx(useKeyOnly(extra, 'extra'), useTextAlignProp(textAlign), 'content', className);\n  var rest = getUnhandledProps(CardContent, props);\n  var ElementType = getElementType(CardContent, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), createShorthand(CardHeader, function (val) {\n    return {\n      content: val\n    };\n  }, header, {\n    autoGenerateKey: false\n  }), createShorthand(CardMeta, function (val) {\n    return {\n      content: val\n    };\n  }, meta, {\n    autoGenerateKey: false\n  }), createShorthand(CardDescription, function (val) {\n    return {\n      content: val\n    };\n  }, description, {\n    autoGenerateKey: false\n  }));\n}\n\nCardContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"description\", \"extra\", \"header\", \"meta\", \"textAlign\"];\nCardContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for CardDescription. */\n  description: customPropTypes.itemShorthand,\n\n  /** A card can contain extra content meant to be formatted separately from the main content. */\n  extra: PropTypes.bool,\n\n  /** Shorthand for CardHeader. */\n  header: customPropTypes.itemShorthand,\n\n  /** Shorthand for CardMeta. */\n  meta: customPropTypes.itemShorthand,\n\n  /** A card content can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified'))\n} : {};\nexport default CardContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useTextAlignProp } from '../../lib';\n/**\n * A card can contain a description with one or more paragraphs.\n */\n\nfunction CardDescription(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      textAlign = props.textAlign;\n  var classes = cx(useTextAlignProp(textAlign), 'description', className);\n  var rest = getUnhandledProps(CardDescription, props);\n  var ElementType = getElementType(CardDescription, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCardDescription.handledProps = [\"as\", \"children\", \"className\", \"content\", \"textAlign\"];\nCardDescription.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A card content can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified'))\n} : {};\nexport default CardDescription;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useTextAlignProp, useWidthProp } from '../../lib';\nimport Card from './Card';\n/**\n * A group of cards.\n */\n\nfunction CardGroup(props) {\n  var centered = props.centered,\n      children = props.children,\n      className = props.className,\n      content = props.content,\n      doubling = props.doubling,\n      items = props.items,\n      itemsPerRow = props.itemsPerRow,\n      stackable = props.stackable,\n      textAlign = props.textAlign;\n  var classes = cx('ui', useKeyOnly(centered, 'centered'), useKeyOnly(doubling, 'doubling'), useKeyOnly(stackable, 'stackable'), useTextAlignProp(textAlign), useWidthProp(itemsPerRow), 'cards', className);\n  var rest = getUnhandledProps(CardGroup, props);\n  var ElementType = getElementType(CardGroup, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  var itemsJSX = _map(items, function (item) {\n    var key = item.key || [item.header, item.description].join('-');\n    return /*#__PURE__*/React.createElement(Card, _extends({\n      key: key\n    }, item));\n  });\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), itemsJSX);\n}\n\nCardGroup.handledProps = [\"as\", \"centered\", \"children\", \"className\", \"content\", \"doubling\", \"items\", \"itemsPerRow\", \"stackable\", \"textAlign\"];\nCardGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** A group of cards can center itself inside its container. */\n  centered: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A group of cards can double its column width for mobile. */\n  doubling: PropTypes.bool,\n\n  /** Shorthand array of props for Card. */\n  items: customPropTypes.collectionShorthand,\n\n  /** A group of cards can set how many cards should exist in a row. */\n  itemsPerRow: PropTypes.oneOf(SUI.WIDTHS),\n\n  /** A group of cards can automatically stack rows to a single columns on mobile devices. */\n  stackable: PropTypes.bool,\n\n  /** A card group can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified'))\n} : {};\nexport default CardGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useTextAlignProp } from '../../lib';\n/**\n * A card can contain a header.\n */\n\nfunction CardHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      textAlign = props.textAlign;\n  var classes = cx(useTextAlignProp(textAlign), 'header', className);\n  var rest = getUnhandledProps(CardHeader, props);\n  var ElementType = getElementType(CardHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCardHeader.handledProps = [\"as\", \"children\", \"className\", \"content\", \"textAlign\"];\nCardHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A card header can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified'))\n} : {};\nexport default CardHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useTextAlignProp } from '../../lib';\n/**\n * A card can contain content metadata.\n */\n\nfunction CardMeta(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      textAlign = props.textAlign;\n  var classes = cx(useTextAlignProp(textAlign), 'meta', className);\n  var rest = getUnhandledProps(CardMeta, props);\n  var ElementType = getElementType(CardMeta, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCardMeta.handledProps = [\"as\", \"children\", \"className\", \"content\", \"textAlign\"];\nCardMeta.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A card meta can adjust its text alignment. */\n  textAlign: PropTypes.oneOf(_without(SUI.TEXT_ALIGNMENTS, 'justified'))\n} : {};\nexport default CardMeta;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\nimport CommentAction from './CommentAction';\nimport CommentActions from './CommentActions';\nimport CommentAuthor from './CommentAuthor';\nimport CommentAvatar from './CommentAvatar';\nimport CommentContent from './CommentContent';\nimport CommentGroup from './CommentGroup';\nimport CommentMetadata from './CommentMetadata';\nimport CommentText from './CommentText';\n/**\n * A comment displays user feedback to site content.\n */\n\nfunction Comment(props) {\n  var className = props.className,\n      children = props.children,\n      collapsed = props.collapsed,\n      content = props.content;\n  var classes = cx(useKeyOnly(collapsed, 'collapsed'), 'comment', className);\n  var rest = getUnhandledProps(Comment, props);\n  var ElementType = getElementType(Comment, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nComment.handledProps = [\"as\", \"children\", \"className\", \"collapsed\", \"content\"];\nComment.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Comment can be collapsed, or hidden from view. */\n  collapsed: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nComment.Author = CommentAuthor;\nComment.Action = CommentAction;\nComment.Actions = CommentActions;\nComment.Avatar = CommentAvatar;\nComment.Content = CommentContent;\nComment.Group = CommentGroup;\nComment.Metadata = CommentMetadata;\nComment.Text = CommentText;\nexport default Comment;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A comment can contain an action.\n */\n\nfunction CommentAction(props) {\n  var active = props.active,\n      className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx(useKeyOnly(active, 'active'), className);\n  var rest = getUnhandledProps(CommentAction, props);\n  var ElementType = getElementType(CommentAction, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentAction.handledProps = [\"active\", \"as\", \"children\", \"className\", \"content\"];\nCommentAction.defaultProps = {\n  as: 'a'\n};\nCommentAction.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Style as the currently active action. */\n  active: PropTypes.bool,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentAction;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A comment can contain an list of actions a user may perform related to this comment.\n */\n\nfunction CommentActions(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx('actions', className);\n  var rest = getUnhandledProps(CommentActions, props);\n  var ElementType = getElementType(CommentActions, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentActions.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nCommentActions.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentActions;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A comment can contain an author.\n */\n\nfunction CommentAuthor(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx('author', className);\n  var rest = getUnhandledProps(CommentAuthor, props);\n  var ElementType = getElementType(CommentAuthor, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentAuthor.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nCommentAuthor.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentAuthor;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { createHTMLImage, getElementType, getUnhandledProps, htmlImageProps, partitionHTMLProps } from '../../lib';\n/**\n * A comment can contain an image or avatar.\n */\n\nfunction CommentAvatar(props) {\n  var className = props.className,\n      src = props.src;\n  var classes = cx('avatar', className);\n  var rest = getUnhandledProps(CommentAvatar, props);\n\n  var _partitionHTMLProps = partitionHTMLProps(rest, {\n    htmlProps: htmlImageProps\n  }),\n      imageProps = _partitionHTMLProps[0],\n      rootProps = _partitionHTMLProps[1];\n\n  var ElementType = getElementType(CommentAvatar, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rootProps, {\n    className: classes\n  }), createHTMLImage(src, {\n    autoGenerateKey: false,\n    defaultProps: imageProps\n  }));\n}\n\nCommentAvatar.handledProps = [\"as\", \"className\", \"src\"];\nCommentAvatar.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Specifies the URL of the image. */\n  src: PropTypes.string\n} : {};\nexport default CommentAvatar;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A comment can contain content.\n */\n\nfunction CommentContent(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx(className, 'content');\n  var rest = getUnhandledProps(CommentContent, props);\n  var ElementType = getElementType(CommentContent, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentContent.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nCommentContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly } from '../../lib';\n/**\n * Comments can be grouped.\n */\n\nfunction CommentGroup(props) {\n  var className = props.className,\n      children = props.children,\n      collapsed = props.collapsed,\n      content = props.content,\n      minimal = props.minimal,\n      size = props.size,\n      threaded = props.threaded;\n  var classes = cx('ui', size, useKeyOnly(collapsed, 'collapsed'), useKeyOnly(minimal, 'minimal'), useKeyOnly(threaded, 'threaded'), 'comments', className);\n  var rest = getUnhandledProps(CommentGroup, props);\n  var ElementType = getElementType(CommentGroup, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentGroup.handledProps = [\"as\", \"children\", \"className\", \"collapsed\", \"content\", \"minimal\", \"size\", \"threaded\"];\nCommentGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Comments can be collapsed, or hidden from view. */\n  collapsed: PropTypes.bool,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Comments can hide extra information unless a user shows intent to interact with a comment. */\n  minimal: PropTypes.bool,\n\n  /** Comments can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'medium')),\n\n  /** A comment list can be threaded to showing the relationship between conversations. */\n  threaded: PropTypes.bool\n} : {};\nexport default CommentGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A comment can contain metadata about the comment, an arbitrary amount of metadata may be defined.\n */\n\nfunction CommentMetadata(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx('metadata', className);\n  var rest = getUnhandledProps(CommentMetadata, props);\n  var ElementType = getElementType(CommentMetadata, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentMetadata.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nCommentMetadata.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentMetadata;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A comment can contain text.\n */\n\nfunction CommentText(props) {\n  var className = props.className,\n      children = props.children,\n      content = props.content;\n  var classes = cx(className, 'text');\n  var rest = getUnhandledProps(CommentText, props);\n  var ElementType = getElementType(CommentText, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nCommentText.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nCommentText.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default CommentText;","import _default from './Comment';\nexport { _default as default };","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI } from '../../lib';\nimport FeedContent from './FeedContent';\nimport FeedDate from './FeedDate';\nimport FeedEvent from './FeedEvent';\nimport FeedExtra from './FeedExtra';\nimport FeedLabel from './FeedLabel';\nimport FeedLike from './FeedLike';\nimport FeedMeta from './FeedMeta';\nimport FeedSummary from './FeedSummary';\nimport FeedUser from './FeedUser';\n/**\n * A feed presents user activity chronologically.\n */\n\nfunction Feed(props) {\n  var children = props.children,\n      className = props.className,\n      events = props.events,\n      size = props.size;\n  var classes = cx('ui', size, 'feed', className);\n  var rest = getUnhandledProps(Feed, props);\n  var ElementType = getElementType(Feed, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  var eventElements = _map(events, function (eventProps) {\n    var childKey = eventProps.childKey,\n        date = eventProps.date,\n        meta = eventProps.meta,\n        summary = eventProps.summary,\n        eventData = _objectWithoutPropertiesLoose(eventProps, [\"childKey\", \"date\", \"meta\", \"summary\"]);\n\n    var finalKey = childKey || [date, meta, summary].join('-');\n    return /*#__PURE__*/React.createElement(FeedEvent, _extends({\n      date: date,\n      key: finalKey,\n      meta: meta,\n      summary: summary\n    }, eventData));\n  });\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), eventElements);\n}\n\nFeed.handledProps = [\"as\", \"children\", \"className\", \"events\", \"size\"];\nFeed.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand array of props for FeedEvent. */\n  events: customPropTypes.collectionShorthand,\n\n  /** A feed can have different sizes. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'mini', 'tiny', 'medium', 'big', 'huge', 'massive'))\n} : {};\nFeed.Content = FeedContent;\nFeed.Date = FeedDate;\nFeed.Event = FeedEvent;\nFeed.Extra = FeedExtra;\nFeed.Label = FeedLabel;\nFeed.Like = FeedLike;\nFeed.Meta = FeedMeta;\nFeed.Summary = FeedSummary;\nFeed.User = FeedUser;\nexport default Feed;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthand, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport FeedDate from './FeedDate';\nimport FeedExtra from './FeedExtra';\nimport FeedMeta from './FeedMeta';\nimport FeedSummary from './FeedSummary';\n\nfunction FeedContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      extraImages = props.extraImages,\n      extraText = props.extraText,\n      date = props.date,\n      meta = props.meta,\n      summary = props.summary;\n  var classes = cx('content', className);\n  var rest = getUnhandledProps(FeedContent, props);\n  var ElementType = getElementType(FeedContent, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), createShorthand(FeedDate, function (val) {\n    return {\n      content: val\n    };\n  }, date, {\n    autoGenerateKey: false\n  }), createShorthand(FeedSummary, function (val) {\n    return {\n      content: val\n    };\n  }, summary, {\n    autoGenerateKey: false\n  }), content, createShorthand(FeedExtra, function (val) {\n    return {\n      text: true,\n      content: val\n    };\n  }, extraText, {\n    autoGenerateKey: false\n  }), createShorthand(FeedExtra, function (val) {\n    return {\n      images: val\n    };\n  }, extraImages, {\n    autoGenerateKey: false\n  }), createShorthand(FeedMeta, function (val) {\n    return {\n      content: val\n    };\n  }, meta, {\n    autoGenerateKey: false\n  }));\n}\n\nFeedContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"date\", \"extraImages\", \"extraText\", \"meta\", \"summary\"];\nFeedContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** An event can contain a date. */\n  date: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedExtra with images. */\n  extraImages: FeedExtra.propTypes.images,\n\n  /** Shorthand for FeedExtra with text. */\n  extraText: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedMeta. */\n  meta: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedSummary. */\n  summary: customPropTypes.itemShorthand\n} : {};\nexport default FeedContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * An event or an event summary can contain a date.\n */\n\nfunction FeedDate(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('date', className);\n  var rest = getUnhandledProps(FeedDate, props);\n  var ElementType = getElementType(FeedDate, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nFeedDate.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nFeedDate.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nexport default FeedDate;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { createShorthand, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport FeedContent from './FeedContent';\nimport FeedLabel from './FeedLabel';\n/**\n * A feed contains an event.\n */\n\nfunction FeedEvent(props) {\n  var content = props.content,\n      children = props.children,\n      className = props.className,\n      date = props.date,\n      extraImages = props.extraImages,\n      extraText = props.extraText,\n      image = props.image,\n      icon = props.icon,\n      meta = props.meta,\n      summary = props.summary;\n  var classes = cx('event', className);\n  var rest = getUnhandledProps(FeedEvent, props);\n  var ElementType = getElementType(FeedEvent, props);\n  var hasContentProp = content || date || extraImages || extraText || meta || summary;\n  var contentProps = {\n    content: content,\n    date: date,\n    extraImages: extraImages,\n    extraText: extraText,\n    meta: meta,\n    summary: summary\n  };\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), createShorthand(FeedLabel, function (val) {\n    return {\n      icon: val\n    };\n  }, icon, {\n    autoGenerateKey: false\n  }), createShorthand(FeedLabel, function (val) {\n    return {\n      image: val\n    };\n  }, image, {\n    autoGenerateKey: false\n  }), hasContentProp && /*#__PURE__*/React.createElement(FeedContent, contentProps), children);\n}\n\nFeedEvent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"date\", \"extraImages\", \"extraText\", \"icon\", \"image\", \"meta\", \"summary\"];\nFeedEvent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for FeedContent. */\n  content: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedDate. */\n  date: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedExtra with images. */\n  extraImages: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedExtra with content. */\n  extraText: customPropTypes.itemShorthand,\n\n  /** An event can contain icon label. */\n  icon: customPropTypes.itemShorthand,\n\n  /** An event can contain image label. */\n  image: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedMeta. */\n  meta: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedSummary. */\n  summary: customPropTypes.itemShorthand\n} : {};\nexport default FeedEvent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createHTMLImage, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A feed can contain an extra content.\n */\n\nfunction FeedExtra(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      images = props.images,\n      text = props.text;\n  var classes = cx(useKeyOnly(images, 'images'), useKeyOnly(content || text, 'text'), 'extra', className);\n  var rest = getUnhandledProps(FeedExtra, props);\n  var ElementType = getElementType(FeedExtra, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  } // TODO need a \"collection factory\" to handle creating multiple image elements and their keys\n\n\n  var imageElements = _map(images, function (image, index) {\n    var key = [index, image].join('-');\n    return createHTMLImage(image, {\n      key: key\n    });\n  });\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), content, imageElements);\n}\n\nFeedExtra.handledProps = [\"as\", \"children\", \"className\", \"content\", \"images\", \"text\"];\nFeedExtra.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** An event can contain additional information like a set of images. */\n  images: customPropTypes.every([customPropTypes.disallow(['text']), PropTypes.oneOfType([PropTypes.bool, customPropTypes.collectionShorthand])]),\n\n  /** An event can contain additional text information. */\n  text: PropTypes.bool\n} : {};\nexport default FeedExtra;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createHTMLImage, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * An event can contain an image or icon label.\n */\n\nfunction FeedLabel(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      icon = props.icon,\n      image = props.image;\n  var classes = cx('label', className);\n  var rest = getUnhandledProps(FeedLabel, props);\n  var ElementType = getElementType(FeedLabel, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), content, Icon.create(icon, {\n    autoGenerateKey: false\n  }), createHTMLImage(image));\n}\n\nFeedLabel.handledProps = [\"as\", \"children\", \"className\", \"content\", \"icon\", \"image\"];\nFeedLabel.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** An event can contain icon label. */\n  icon: customPropTypes.itemShorthand,\n\n  /** An event can contain image label. */\n  image: customPropTypes.itemShorthand\n} : {};\nexport default FeedLabel;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport Icon from '../../elements/Icon';\n/**\n * A feed can contain a like element.\n */\n\nfunction FeedLike(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      icon = props.icon;\n  var classes = cx('like', className);\n  var rest = getUnhandledProps(FeedLike, props);\n  var ElementType = getElementType(FeedLike, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), Icon.create(icon, {\n    autoGenerateKey: false\n  }), content);\n}\n\nFeedLike.handledProps = [\"as\", \"children\", \"className\", \"content\", \"icon\"];\nFeedLike.defaultProps = {\n  as: 'a'\n};\nFeedLike.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for icon. Mutually exclusive with children. */\n  icon: customPropTypes.itemShorthand\n} : {};\nexport default FeedLike;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthand, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport FeedLike from './FeedLike';\n/**\n * A feed can contain a meta.\n */\n\nfunction FeedMeta(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      like = props.like;\n  var classes = cx('meta', className);\n  var rest = getUnhandledProps(FeedMeta, props);\n  var ElementType = getElementType(FeedMeta, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), createShorthand(FeedLike, function (val) {\n    return {\n      content: val\n    };\n  }, like, {\n    autoGenerateKey: false\n  }), content);\n}\n\nFeedMeta.handledProps = [\"as\", \"children\", \"className\", \"content\", \"like\"];\nFeedMeta.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for FeedLike. */\n  like: customPropTypes.itemShorthand\n} : {};\nexport default FeedMeta;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthand, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport FeedDate from './FeedDate';\nimport FeedUser from './FeedUser';\n/**\n * A feed can contain a summary.\n */\n\nfunction FeedSummary(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      date = props.date,\n      user = props.user;\n  var classes = cx('summary', className);\n  var rest = getUnhandledProps(FeedSummary, props);\n  var ElementType = getElementType(FeedSummary, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), createShorthand(FeedUser, function (val) {\n    return {\n      content: val\n    };\n  }, user, {\n    autoGenerateKey: false\n  }), content && ' ', content, content && ' ', createShorthand(FeedDate, function (val) {\n    return {\n      content: val\n    };\n  }, date, {\n    autoGenerateKey: false\n  }));\n}\n\nFeedSummary.handledProps = [\"as\", \"children\", \"className\", \"content\", \"date\", \"user\"];\nFeedSummary.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for FeedDate. */\n  date: customPropTypes.itemShorthand,\n\n  /** Shorthand for FeedUser. */\n  user: customPropTypes.itemShorthand\n} : {};\nexport default FeedSummary;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A feed can contain a user element.\n */\n\nfunction FeedUser(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('user', className);\n  var rest = getUnhandledProps(FeedUser, props);\n  var ElementType = getElementType(FeedUser, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nFeedUser.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nFeedUser.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nFeedUser.defaultProps = {\n  as: 'a'\n};\nexport default FeedUser;","import _default from './Feed';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\nimport ItemContent from './ItemContent';\nimport ItemDescription from './ItemDescription';\nimport ItemExtra from './ItemExtra';\nimport ItemGroup from './ItemGroup';\nimport ItemHeader from './ItemHeader';\nimport ItemImage from './ItemImage';\nimport ItemMeta from './ItemMeta';\n/**\n * An item view presents large collections of site content for display.\n */\n\nfunction Item(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      description = props.description,\n      extra = props.extra,\n      header = props.header,\n      image = props.image,\n      meta = props.meta;\n  var classes = cx('item', className);\n  var rest = getUnhandledProps(Item, props);\n  var ElementType = getElementType(Item, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), ItemImage.create(image, {\n    autoGenerateKey: false\n  }), /*#__PURE__*/React.createElement(ItemContent, {\n    content: content,\n    description: description,\n    extra: extra,\n    header: header,\n    meta: meta\n  }));\n}\n\nItem.handledProps = [\"as\", \"children\", \"className\", \"content\", \"description\", \"extra\", \"header\", \"image\", \"meta\"];\nItem.Content = ItemContent;\nItem.Description = ItemDescription;\nItem.Extra = ItemExtra;\nItem.Group = ItemGroup;\nItem.Header = ItemHeader;\nItem.Image = ItemImage;\nItem.Meta = ItemMeta;\nItem.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for ItemContent component. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for ItemDescription component. */\n  description: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemExtra component. */\n  extra: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemHeader component. */\n  header: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemImage component. */\n  image: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemMeta component. */\n  meta: customPropTypes.itemShorthand\n} : {};\nexport default Item;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useVerticalAlignProp } from '../../lib';\nimport ItemHeader from './ItemHeader';\nimport ItemDescription from './ItemDescription';\nimport ItemExtra from './ItemExtra';\nimport ItemMeta from './ItemMeta';\n/**\n * An item can contain content.\n */\n\nfunction ItemContent(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      description = props.description,\n      extra = props.extra,\n      header = props.header,\n      meta = props.meta,\n      verticalAlign = props.verticalAlign;\n  var classes = cx(useVerticalAlignProp(verticalAlign), 'content', className);\n  var rest = getUnhandledProps(ItemContent, props);\n  var ElementType = getElementType(ItemContent, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), ItemHeader.create(header, {\n    autoGenerateKey: false\n  }), ItemMeta.create(meta, {\n    autoGenerateKey: false\n  }), ItemDescription.create(description, {\n    autoGenerateKey: false\n  }), ItemExtra.create(extra, {\n    autoGenerateKey: false\n  }), content);\n}\n\nItemContent.handledProps = [\"as\", \"children\", \"className\", \"content\", \"description\", \"extra\", \"header\", \"meta\", \"verticalAlign\"];\nItemContent.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Shorthand for ItemDescription component. */\n  description: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemExtra component. */\n  extra: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemHeader component. */\n  header: customPropTypes.itemShorthand,\n\n  /** Shorthand for ItemMeta component. */\n  meta: customPropTypes.itemShorthand,\n\n  /** Content can specify its vertical alignment. */\n  verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS)\n} : {};\nexport default ItemContent;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * An item can contain a description with a single or multiple paragraphs.\n */\n\nfunction ItemDescription(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('description', className);\n  var rest = getUnhandledProps(ItemDescription, props);\n  var ElementType = getElementType(ItemDescription, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nItemDescription.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nItemDescription.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nItemDescription.create = createShorthandFactory(ItemDescription, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ItemDescription;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * An item can contain extra content meant to be formatted separately from the main content.\n */\n\nfunction ItemExtra(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('extra', className);\n  var rest = getUnhandledProps(ItemExtra, props);\n  var ElementType = getElementType(ItemExtra, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nItemExtra.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nItemExtra.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nItemExtra.create = createShorthandFactory(ItemExtra, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ItemExtra;","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, useKeyOnly, useKeyOrValueAndKey } from '../../lib';\nimport Item from './Item';\n/**\n * A group of items.\n */\n\nfunction ItemGroup(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      divided = props.divided,\n      items = props.items,\n      link = props.link,\n      relaxed = props.relaxed,\n      unstackable = props.unstackable;\n  var classes = cx('ui', useKeyOnly(divided, 'divided'), useKeyOnly(link, 'link'), useKeyOnly(unstackable, 'unstackable'), useKeyOrValueAndKey(relaxed, 'relaxed'), 'items', className);\n  var rest = getUnhandledProps(ItemGroup, props);\n  var ElementType = getElementType(ItemGroup, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  var itemsJSX = _map(items, function (item) {\n    var childKey = item.childKey,\n        itemProps = _objectWithoutPropertiesLoose(item, [\"childKey\"]);\n\n    var finalKey = childKey || [itemProps.content, itemProps.description, itemProps.header, itemProps.meta].join('-');\n    return /*#__PURE__*/React.createElement(Item, _extends({}, itemProps, {\n      key: finalKey\n    }));\n  });\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), itemsJSX);\n}\n\nItemGroup.handledProps = [\"as\", \"children\", \"className\", \"content\", \"divided\", \"items\", \"link\", \"relaxed\", \"unstackable\"];\nItemGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Items can be divided to better distinguish between grouped content. */\n  divided: PropTypes.bool,\n\n  /** Shorthand array of props for Item. */\n  items: customPropTypes.collectionShorthand,\n\n  /** An item can be formatted so that the entire contents link to another page. */\n  link: PropTypes.bool,\n\n  /** A group of items can relax its padding to provide more negative space. */\n  relaxed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['very'])]),\n\n  /** Prevent items from stacking on mobile. */\n  unstackable: PropTypes.bool\n} : {};\nexport default ItemGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * An item can contain a header.\n */\n\nfunction ItemHeader(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('header', className);\n  var rest = getUnhandledProps(ItemHeader, props);\n  var ElementType = getElementType(ItemHeader, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nItemHeader.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nItemHeader.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nItemHeader.create = createShorthandFactory(ItemHeader, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ItemHeader;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport React from 'react';\nimport { createShorthandFactory, getUnhandledProps } from '../../lib';\nimport Image from '../../elements/Image';\n/**\n * An item can contain an image.\n */\n\nfunction ItemImage(props) {\n  var size = props.size;\n  var rest = getUnhandledProps(ItemImage, props);\n  return /*#__PURE__*/React.createElement(Image, _extends({}, rest, {\n    size: size,\n    ui: !!size,\n    wrapped: true\n  }));\n}\n\nItemImage.handledProps = [\"size\"];\nItemImage.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An image may appear at different sizes. */\n  size: Image.propTypes.size\n} : {};\nItemImage.create = createShorthandFactory(ItemImage, function (src) {\n  return {\n    src: src\n  };\n});\nexport default ItemImage;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * An item can contain content metadata.\n */\n\nfunction ItemMeta(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('meta', className);\n  var rest = getUnhandledProps(ItemMeta, props);\n  var ElementType = getElementType(ItemMeta, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nItemMeta.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nItemMeta.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nItemMeta.create = createShorthandFactory(ItemMeta, function (content) {\n  return {\n    content: content\n  };\n});\nexport default ItemMeta;","import _default from './Item';\nexport { _default as default };","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useValueAndKey } from '../../lib';\nimport StatisticGroup from './StatisticGroup';\nimport StatisticLabel from './StatisticLabel';\nimport StatisticValue from './StatisticValue';\n/**\n * A statistic emphasizes the current value of an attribute.\n */\n\nfunction Statistic(props) {\n  var children = props.children,\n      className = props.className,\n      color = props.color,\n      content = props.content,\n      floated = props.floated,\n      horizontal = props.horizontal,\n      inverted = props.inverted,\n      label = props.label,\n      size = props.size,\n      text = props.text,\n      value = props.value;\n  var classes = cx('ui', color, size, useValueAndKey(floated, 'floated'), useKeyOnly(horizontal, 'horizontal'), useKeyOnly(inverted, 'inverted'), 'statistic', className);\n  var rest = getUnhandledProps(Statistic, props);\n  var ElementType = getElementType(Statistic, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), StatisticValue.create(value, {\n    defaultProps: {\n      text: text\n    },\n    autoGenerateKey: false\n  }), StatisticLabel.create(label, {\n    autoGenerateKey: false\n  }));\n}\n\nStatistic.handledProps = [\"as\", \"children\", \"className\", \"color\", \"content\", \"floated\", \"horizontal\", \"inverted\", \"label\", \"size\", \"text\", \"value\"];\nStatistic.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A statistic can be formatted to be different colors. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A statistic can sit to the left or right of other content. */\n  floated: PropTypes.oneOf(SUI.FLOATS),\n\n  /** A statistic can present its measurement horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** A statistic can be formatted to fit on a dark background. */\n  inverted: PropTypes.bool,\n\n  /** Label content of the Statistic. */\n  label: customPropTypes.contentShorthand,\n\n  /** A statistic can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'big', 'massive', 'medium')),\n\n  /** Format the StatisticValue with smaller font size to fit nicely beside number values. */\n  text: PropTypes.bool,\n\n  /** Value content of the Statistic. */\n  value: customPropTypes.contentShorthand\n} : {};\nStatistic.Group = StatisticGroup;\nStatistic.Label = StatisticLabel;\nStatistic.Value = StatisticValue;\nStatistic.create = createShorthandFactory(Statistic, function (content) {\n  return {\n    content: content\n  };\n});\nexport default Statistic;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _without from \"lodash/without\";\nimport _map from \"lodash/map\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib';\nimport Statistic from './Statistic';\n/**\n * A group of statistics.\n */\n\nfunction StatisticGroup(props) {\n  var children = props.children,\n      className = props.className,\n      color = props.color,\n      content = props.content,\n      horizontal = props.horizontal,\n      inverted = props.inverted,\n      items = props.items,\n      size = props.size,\n      widths = props.widths;\n  var classes = cx('ui', color, size, useKeyOnly(horizontal, 'horizontal'), useKeyOnly(inverted, 'inverted'), useWidthProp(widths), 'statistics', className);\n  var rest = getUnhandledProps(StatisticGroup, props);\n  var ElementType = getElementType(StatisticGroup, props);\n\n  if (!childrenUtils.isNil(children)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), children);\n  }\n\n  if (!childrenUtils.isNil(content)) {\n    return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n      className: classes\n    }), content);\n  }\n\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), _map(items, function (item) {\n    return Statistic.create(item);\n  }));\n}\n\nStatisticGroup.handledProps = [\"as\", \"children\", \"className\", \"color\", \"content\", \"horizontal\", \"inverted\", \"items\", \"size\", \"widths\"];\nStatisticGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** A statistic group can be formatted to be different colors. */\n  color: PropTypes.oneOf(SUI.COLORS),\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** A statistic group can present its measurement horizontally. */\n  horizontal: PropTypes.bool,\n\n  /** A statistic group can be formatted to fit on a dark background. */\n  inverted: PropTypes.bool,\n\n  /** Array of props for Statistic. */\n  items: customPropTypes.collectionShorthand,\n\n  /** A statistic group can vary in size. */\n  size: PropTypes.oneOf(_without(SUI.SIZES, 'big', 'massive', 'medium')),\n\n  /** A statistic group can have its items divided evenly. */\n  widths: PropTypes.oneOf(SUI.WIDTHS)\n} : {};\nexport default StatisticGroup;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps } from '../../lib';\n/**\n * A statistic can contain a label to help provide context for the presented value.\n */\n\nfunction StatisticLabel(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content;\n  var classes = cx('label', className);\n  var rest = getUnhandledProps(StatisticLabel, props);\n  var ElementType = getElementType(StatisticLabel, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nStatisticLabel.handledProps = [\"as\", \"children\", \"className\", \"content\"];\nStatisticLabel.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand\n} : {};\nStatisticLabel.create = createShorthandFactory(StatisticLabel, function (content) {\n  return {\n    content: content\n  };\n});\nexport default StatisticLabel;","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport cx from 'clsx';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from '../../lib';\n/**\n * A statistic can contain a numeric, icon, image, or text value.\n */\n\nfunction StatisticValue(props) {\n  var children = props.children,\n      className = props.className,\n      content = props.content,\n      text = props.text;\n  var classes = cx(useKeyOnly(text, 'text'), 'value', className);\n  var rest = getUnhandledProps(StatisticValue, props);\n  var ElementType = getElementType(StatisticValue, props);\n  return /*#__PURE__*/React.createElement(ElementType, _extends({}, rest, {\n    className: classes\n  }), childrenUtils.isNil(children) ? content : children);\n}\n\nStatisticValue.handledProps = [\"as\", \"children\", \"className\", \"content\", \"text\"];\nStatisticValue.propTypes = process.env.NODE_ENV !== \"production\" ? {\n  /** An element type to render as (string or function). */\n  as: PropTypes.elementType,\n\n  /** Primary content. */\n  children: PropTypes.node,\n\n  /** Additional classes. */\n  className: PropTypes.string,\n\n  /** Shorthand for primary content. */\n  content: customPropTypes.contentShorthand,\n\n  /** Format the value with smaller font size to fit nicely beside number values. */\n  text: PropTypes.bool\n} : {};\nStatisticValue.create = createShorthandFactory(StatisticValue, function (content) {\n  return {\n    content: content\n  };\n});\nexport default StatisticValue;","import _default from './Statistic';\nexport { _default as default };","//\n\nmodule.exports = function shallowEqual(objA, objB, compare, compareContext) {\n  var ret = compare ? compare.call(compareContext, objA, objB) : void 0;\n\n  if (ret !== void 0) {\n    return !!ret;\n  }\n\n  if (objA === objB) {\n    return true;\n  }\n\n  if (typeof objA !== \"object\" || !objA || typeof objB !== \"object\" || !objB) {\n    return false;\n  }\n\n  var keysA = Object.keys(objA);\n  var keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);\n\n  // Test for A's keys different from B.\n  for (var idx = 0; idx < keysA.length; idx++) {\n    var key = keysA[idx];\n\n    if (!bHasOwnProperty(key)) {\n      return false;\n    }\n\n    var valueA = objA[key];\n    var valueB = objB[key];\n\n    ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;\n\n    if (ret === false || (ret === void 0 && valueA !== valueB)) {\n      return false;\n    }\n  }\n\n  return true;\n};\n","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n  var memo;\n  return function memorize() {\n    if (typeof memo === 'undefined') {\n      // Test for IE <= 9 as proposed by Browserhacks\n      // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n      // Tests for existence of standard globals is to allow style-loader\n      // to operate correctly into non-standard environments\n      // @see https://github.com/webpack-contrib/style-loader/issues/177\n      memo = Boolean(window && document && document.all && !window.atob);\n    }\n\n    return memo;\n  };\n}();\n\nvar getTarget = function getTarget() {\n  var memo = {};\n  return function memorize(target) {\n    if (typeof memo[target] === 'undefined') {\n      var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n      if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n        try {\n          // This will throw an exception if access to iframe is blocked\n          // due to cross-origin restrictions\n          styleTarget = styleTarget.contentDocument.head;\n        } catch (e) {\n          // istanbul ignore next\n          styleTarget = null;\n        }\n      }\n\n      memo[target] = styleTarget;\n    }\n\n    return memo[target];\n  };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n  var result = -1;\n\n  for (var i = 0; i < stylesInDom.length; i++) {\n    if (stylesInDom[i].identifier === identifier) {\n      result = i;\n      break;\n    }\n  }\n\n  return result;\n}\n\nfunction modulesToDom(list, options) {\n  var idCountMap = {};\n  var identifiers = [];\n\n  for (var i = 0; i < list.length; i++) {\n    var item = list[i];\n    var id = options.base ? item[0] + options.base : item[0];\n    var count = idCountMap[id] || 0;\n    var identifier = \"\".concat(id, \" \").concat(count);\n    idCountMap[id] = count + 1;\n    var index = getIndexByIdentifier(identifier);\n    var obj = {\n      css: item[1],\n      media: item[2],\n      sourceMap: item[3]\n    };\n\n    if (index !== -1) {\n      stylesInDom[index].references++;\n      stylesInDom[index].updater(obj);\n    } else {\n      stylesInDom.push({\n        identifier: identifier,\n        updater: addStyle(obj, options),\n        references: 1\n      });\n    }\n\n    identifiers.push(identifier);\n  }\n\n  return identifiers;\n}\n\nfunction insertStyleElement(options) {\n  var style = document.createElement('style');\n  var attributes = options.attributes || {};\n\n  if (typeof attributes.nonce === 'undefined') {\n    var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n    if (nonce) {\n      attributes.nonce = nonce;\n    }\n  }\n\n  Object.keys(attributes).forEach(function (key) {\n    style.setAttribute(key, attributes[key]);\n  });\n\n  if (typeof options.insert === 'function') {\n    options.insert(style);\n  } else {\n    var target = getTarget(options.insert || 'head');\n\n    if (!target) {\n      throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n    }\n\n    target.appendChild(style);\n  }\n\n  return style;\n}\n\nfunction removeStyleElement(style) {\n  // istanbul ignore if\n  if (style.parentNode === null) {\n    return false;\n  }\n\n  style.parentNode.removeChild(style);\n}\n/* istanbul ignore next  */\n\n\nvar replaceText = function replaceText() {\n  var textStore = [];\n  return function replace(index, replacement) {\n    textStore[index] = replacement;\n    return textStore.filter(Boolean).join('\\n');\n  };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n  var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n  /* istanbul ignore if  */\n\n  if (style.styleSheet) {\n    style.styleSheet.cssText = replaceText(index, css);\n  } else {\n    var cssNode = document.createTextNode(css);\n    var childNodes = style.childNodes;\n\n    if (childNodes[index]) {\n      style.removeChild(childNodes[index]);\n    }\n\n    if (childNodes.length) {\n      style.insertBefore(cssNode, childNodes[index]);\n    } else {\n      style.appendChild(cssNode);\n    }\n  }\n}\n\nfunction applyToTag(style, options, obj) {\n  var css = obj.css;\n  var media = obj.media;\n  var sourceMap = obj.sourceMap;\n\n  if (media) {\n    style.setAttribute('media', media);\n  } else {\n    style.removeAttribute('media');\n  }\n\n  if (sourceMap && btoa) {\n    css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n  } // For old IE\n\n  /* istanbul ignore if  */\n\n\n  if (style.styleSheet) {\n    style.styleSheet.cssText = css;\n  } else {\n    while (style.firstChild) {\n      style.removeChild(style.firstChild);\n    }\n\n    style.appendChild(document.createTextNode(css));\n  }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n  var style;\n  var update;\n  var remove;\n\n  if (options.singleton) {\n    var styleIndex = singletonCounter++;\n    style = singleton || (singleton = insertStyleElement(options));\n    update = applyToSingletonTag.bind(null, style, styleIndex, false);\n    remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n  } else {\n    style = insertStyleElement(options);\n    update = applyToTag.bind(null, style, options);\n\n    remove = function remove() {\n      removeStyleElement(style);\n    };\n  }\n\n  update(obj);\n  return function updateStyle(newObj) {\n    if (newObj) {\n      if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n        return;\n      }\n\n      update(obj = newObj);\n    } else {\n      remove();\n    }\n  };\n}\n\nmodule.exports = function (list, options) {\n  options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n  // tags it will allow on a page\n\n  if (!options.singleton && typeof options.singleton !== 'boolean') {\n    options.singleton = isOldIE();\n  }\n\n  list = list || [];\n  var lastIdentifiers = modulesToDom(list, options);\n  return function update(newList) {\n    newList = newList || [];\n\n    if (Object.prototype.toString.call(newList) !== '[object Array]') {\n      return;\n    }\n\n    for (var i = 0; i < lastIdentifiers.length; i++) {\n      var identifier = lastIdentifiers[i];\n      var index = getIndexByIdentifier(identifier);\n      stylesInDom[index].references--;\n    }\n\n    var newLastIdentifiers = modulesToDom(newList, options);\n\n    for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n      var _identifier = lastIdentifiers[_i];\n\n      var _index = getIndexByIdentifier(_identifier);\n\n      if (stylesInDom[_index].references === 0) {\n        stylesInDom[_index].updater();\n\n        stylesInDom.splice(_index, 1);\n      }\n    }\n\n    lastIdentifiers = newLastIdentifiers;\n  };\n};","var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n    if (condition) {\n        return;\n    }\n    if (isProduction) {\n        throw new Error(prefix);\n    }\n    throw new Error(prefix + \": \" + (message || ''));\n}\n\nexport default invariant;\n","var isProduction = process.env.NODE_ENV === 'production';\nfunction warning(condition, message) {\n  if (!isProduction) {\n    if (condition) {\n      return;\n    }\n\n    var text = \"Warning: \" + message;\n\n    if (typeof console !== 'undefined') {\n      console.warn(text);\n    }\n\n    try {\n      throw Error(text);\n    } catch (x) {}\n  }\n}\n\nexport default warning;\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n    for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n};\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n    result.default = mod;\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to get private field on non-instance\");\r\n    }\r\n    return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to set private field on non-instance\");\r\n    }\r\n    privateMap.set(receiver, value);\r\n    return value;\r\n}\r\n","function valueOf(obj) {\n  return obj.valueOf ? obj.valueOf() : Object.prototype.valueOf.call(obj);\n}\n\nfunction valueEqual(a, b) {\n  // Test for strict equality first.\n  if (a === b) return true;\n\n  // Otherwise, if either of them == null they are not equal.\n  if (a == null || b == null) return false;\n\n  if (Array.isArray(a)) {\n    return (\n      Array.isArray(b) &&\n      a.length === b.length &&\n      a.every(function(item, index) {\n        return valueEqual(item, b[index]);\n      })\n    );\n  }\n\n  if (typeof a === 'object' || typeof b === 'object') {\n    var aValue = valueOf(a);\n    var bValue = valueOf(b);\n\n    if (aValue !== a || bValue !== b) return valueEqual(aValue, bValue);\n\n    return Object.keys(Object.assign({}, a, b)).every(function(key) {\n      return valueEqual(a[key], b[key]);\n    });\n  }\n\n  return false;\n}\n\nexport default valueEqual;\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar __DEV__ = process.env.NODE_ENV !== 'production';\n\nvar warning = function() {};\n\nif (__DEV__) {\n  var printWarning = function printWarning(format, args) {\n    var len = arguments.length;\n    args = new Array(len > 1 ? len - 1 : 0);\n    for (var key = 1; key < len; key++) {\n      args[key - 1] = arguments[key];\n    }\n    var argIndex = 0;\n    var message = 'Warning: ' +\n      format.replace(/%s/g, function() {\n        return args[argIndex++];\n      });\n    if (typeof console !== 'undefined') {\n      console.error(message);\n    }\n    try {\n      // --- Welcome to debugging React ---\n      // This error was thrown as a convenience so that you can use this stack\n      // to find the callsite that caused this warning to fire.\n      throw new Error(message);\n    } catch (x) {}\n  }\n\n  warning = function(condition, format, args) {\n    var len = arguments.length;\n    args = new Array(len > 2 ? len - 2 : 0);\n    for (var key = 2; key < len; key++) {\n      args[key - 2] = arguments[key];\n    }\n    if (format === undefined) {\n      throw new Error(\n          '`warning(condition, format, ...args)` requires a warning ' +\n          'message argument'\n      );\n    }\n    if (!condition) {\n      printWarning.apply(null, [format].concat(args));\n    }\n  };\n}\n\nmodule.exports = warning;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACRA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAUA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAjCA;;;;;;;;;;;;;;;;;;;;;ACpEA;AACA;AAAA;AACA;AAAA;;;;;;;;;;;;;;;ACFA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAxDA;AAgEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;AClUA;AAEA;AACA;AACA;AAFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACFA;;;;;;;;;;;;;;;;AAiBA;AAEA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClEA;;;;;;;;;;;;;;;;AAyBA;;;;;;;AAOA;AAOA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AAEA;;;;;;AAMA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AAMA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AAIA;AACA;AACA;ACnIA;;;;;;;;;;;;;;;;AAmBA;AACA;ACpBA;;;;;;;;;;;;;;;;AAkCA;;;;;;;;AAQA;;;;;;AAKA;;AAAA;;;;;AAMA;;;AAIA;AACA;;AAEA;AACA;AACA;;;;;AACA;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAIA;;AAMA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AACA;;AAEA;AACA;AACA;AAAA;;;;AAIA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AAAA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AAIA;AAEA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;AAIA;AACA;AACA;AACA;AAEA;;;;;;;;;AASA;;AASA;AAAA;AAAA;AAAA;;;AAEA;AACA;;AAGA;AAEA;;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3NA;;;;;;;;;;;;;;;;;AA+BA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAQA;AACA;ACjEA;;;;;;;;;;;;;;;;AA+CA;;;AAGA;AAEA;;;AAGA;AAEA;;;AAGA;AAEA;;;;AAIA;AAEA;;;;AAIA;AAEA;;;;AAIA;AAEA;;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAGA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;AAKA;AACA;AACA;AACA;AAEA;AAKA;AACA;AAEA;AACA;;AAEA;AAMA;AACA;AACA;AACA;AAMA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;;;;ACzJA;;;AAGA;AAEA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AAIA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAcA;;;;;;;;;AASA;;;;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAGA;;AAAA;AACA;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AFvIA;;;;;;;;;;;;;;;;;AA4BA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAIA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AJ7CA;;;;;;;;;;;;;;;;;AAiBA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AE9CA;;;;;;;;;;;;;;;;AAmBA;AACA;AKpBA;;;;;;;;;;;;;;;;AAsCA;;;;AAIA;AAOA;;AAAA;AAGA;AAPA;AASA;AACA;AACA;AACA;AACA;;AAGA;;;AAEA;AAAA;AACA;AACA;;;;;;;;;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;AALA;AAOA;AAAA;AACA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AAgBA;AAEA;AAEA;;AAGA;AACA;AACA;AACA;;;;;;;;;;;AAWA;AAEA;;AAGA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;;;ACtLA;;;;;;;;;;;;;;;;AA4CA;;;;;;;AAOA;AAGA;;AAEA;;AAGA;;;;AAIA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AAaA;;AAGA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AASA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAMA;AAEA;AACA;;;;AAKA;;AAEA;AACA;AAEA;;AAGA;AACA;AACA;AAIA;;AAEA;AACA;AACA;AAEA;;AAGA;;AAEA;AACA;;AAGA;;;AAGA;AACA;AACA;AACA;;;AAIA;AACA;;AAGA;AACA;AACA;;AAGA;;;AAIA;;;;AAIA;AAAA;AAAA;AAAA;;AACA;AACA;AAIA;AACA;;;AAGA;AAAA;AACA;AACA;;;;;;;;;AAEA;;AAEA;AACA;AACA;AAEA;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAIA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;ACtTA;;;;;;;;;;;;;;;;AAuBA;;;;;;;AAOA;AACA;AACA;AAGA;AACA;AACA;AACA;;;;;;AAQA;AACA;AACA;AAEA;AACA;AAEA;AACA;ACtDA;;;;;;;;;;;;;;;;AAwBA;AACA;AAAA;AAAA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;;;;;;;;AAQA;AAGA;AACA;AACA;AACA;AC3DA;;;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;AAAA;;AALA;AAKA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAQA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;ACpFA;;;;;;;;;;;;;;;;AAmBA;;;;;;AAMA;AAAA;AACA;AAqBA;AACA;AApBA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAAA;AACA;ACjDA;;;;;;;;;;;;;;;;AAsBA;;;;;;;;;AASA;AAGA;;;AAGA;AAEA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;;;AAIA;AACA;AAEA;AACA;AAEA;AACA;AACA;AC3DA;;;;;;;;;;;;;;;;AAiCA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AAEA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;;AAIA;AAEA;;;;;AAKA;AAEA;;;;;AAKA;AAIA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AAGA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAEA;;;;AAIA;;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAaA;;;;;AAKA;AACA;AAEA;AACA;AACA;AAEA;AAEA;;;AAGA;AACA;AACA;AACA;AAAA;;;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;;AAEA;AAAA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;;;;AAKA;AACA;AACA;AAEA;;;;AAIA;AAEA;;;;AAIA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;;;AAKA;AAIA;AACA;AACA;AAAA;AACA;AAGA;AACA;AAEA;;;;AAIA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;;AAMA;AAIA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAeA;;;;;;;AAOA;AACA;AAEA;AAEA;AACA;;;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AAEA;AACA;AACA;AAEA;AAEA;;;;AAIA;;AAEA;AACA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;;AAIA;AACA;AACA;AAEA;;;;;AAKA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;AAAA;;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAqBA;;;AAGA;AACA;AAEA;AACA;AACA;;;;;AAMA;AAKA;AAiBA;;;;;;;;;AASA;AAIA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;ACtqBA;;;;;;;;;;;;;;;;AAmBA;;;;;AAMA;;;;;;AAkBA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AA5BA;;;;;;AAAA;AACA;AACA;;;AAAA;AA4BA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;AAQA;AAAA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;;;;;;;;;;AAUA;;;;;AAUA;AAAA;;AAEA;;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;;AAAA;AACA;AACA;;;AAAA;AAGA;;AAAA;AACA;AACA;;;AAAA;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACnXA;;;;;;;;;;;;;;;;AAiBA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;ACpCA;;;;;;;;;;;;;;;;AAsBA;;;;;AAKA;;;;;;;;AAYA;AAKA;AACA;AAJA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAAA;AACA;ACnIA;;;;;;;;;;;;;;;;AAqBA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;;AACA;AACA;AACA;AACA;;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;;;;AACA;AACA;AAEA;;;;;AAKA;AAGA;AAGA;AACA;AAEA;AACA;AAEA;;AAGA;AAEA;AAEA;AAGA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAEA;;;;;AAKA;;AAaA;;AAOA;;AAKA;;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9MA;;;;;;;;;;;;;;;;AA4BA;;;;;AAKA;AAEA;;;;;;AAMA;AAEA;;;;;AAKA;AAEA;;;;AAIA;AACA;AAGA;AAEA;;;;AAIA;AACA;AAEA;AACA;AAEA;AAEA;;;;AAIA;AACA;;AAEA;AACA;AAEA;AACA;AAEA;;;;AAIA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AAEA;AAEA;;;;;;;;;AASA;AAOA;AACA;AACA;AAEA;AAKA;AAEA;;;;;;;AAOA;AAKA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;;AAGA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;;AAMA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;;;;;;;;;AAUA;AAOA;AACA;AACA;AAEA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAMA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAMA;;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAmBA;AAMA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;ACveA;;;;;;;;;;;;;;;;AA8BA;;;;;;;;AAQA;AAAA;AAAA;AAAA;;;;;AAMA;AACA;AACA;AACA;AACA;AAIA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AAOA;AACA;AAEA;AACA;AAMA;AACA;;;;;;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAAA;AACA;ACnKA;;;;;;;;;;;;;;;;AAoBA;;;;;;;;AAQA;AAAA;AAAA;AAAA;;;AAIA;AACA;AACA;AACA;AACA;AAAA;AACA;ACrCA;;;;;;;;;;;;;;;;AAmBA;;;;;;;;;;;;;;AAcA;;AAEA;;;AAKA;;;;;AAMA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;ACpFA;;;;;;;;;;;;;;;;AAyJA;;;;;;;AAOA;AACA;AAAA;AAAA;AAAA;;;;;;;AAQA;AACA;AACA;AACA;AAAA;AACA;AC7KA;;;;;;;;;;;;;;;;AAqBA;;;;AAIA;AAAA;AA8DA;;;;;AA5CA;AACA;AACA;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;;;;;AAMA;;AAEA;AACA;AAmBA;AAAA;AACA;ACxFA;;;;;;;;;;;;;;;;AAuBA;AAEA;AAAA;AAAA;;AAqEA;AApEA;AAAA;AACA;AACA;AAEA;AACA;AACA;;;AAJA;;;;AASA;AACA;AACA;;;;AAKA;;;AAGA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;;AAEA;AACA;;;;AAKA;;;AAGA;AACA;;;;;;AAOA;AACA;;AAKA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AAEA;AACA;ACjGA;;;;;;;;;;;;;;;;AAuBA;AAEA;AACA;AACA;AAEA;;;;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAAA;AACA;AAIA;;AAEA;AAIA;AACA;ACnEA;;;;;;;;;;;;;;;;AA0BA;AAEA;;;;;AAKA;;;;;;;AAyBA;AAEA;AADA;AACA;AAVA;AAYA;AAKA;AACA;AAlCA;AAIA;AACA;AACA;AANA;AACA;AACA;;;AAAA;;AAmCA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAIA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAKA;AAOA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;;;;AAIA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;;;;;;;AAtPA;AAuPA;AAtQA;AACA;AClCA;;;;;;;;;;;;;;;;AAsBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;AAKA;AAAA;AAAA;;AA4DA;;;;AAxDA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;;AAEA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AAEA;AACA;ACrGA;;;;;;;;;;;;;;;;AAuCA;;;AAGA;;;;;;;;;AAcA;AAKA;AADA;AACA;;;;AAfA;AAiBA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAEA;;;AAGA;;;;;;;;;AAaA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAeA;AAOA;AAOA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;;;;;AAWA;AACA;AAEA;AACA;AAEA;;;;;;;;;AAUA;AACA;AAEA;AACA;AAEA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAOA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AArTA;AACA;AAqTA;AAjVA;AAmVA;;;AAGA;AAAA;AAgHA;;;;;;AApGA;AAOA;AACA;;;;;;;;;AAUA;AACA;AACA;;;;;;;;AASA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;;;;AAUA;AACA;AACA;;;;;;;;;AAUA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAAA;AAEA;;;;AAIA;;;;;;AAYA;AAEA;AADA;AACA;AAGA;;;;;;;;;AAUA;AACA;AAGA;AACA;AAEA;;;;;;;AAQA;AACA;AAGA;AACA;AAEA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;;;;;AAWA;AACA;AACA;;;;;;;;;AAUA;AACA;AACA;;;;;;;AAQA;AAGA;AAOA;AAEA;AAIA;AAOA;AAEA;AAIA;AAOA;AAEA;AAGA;AAOA;;;;;AApNA;AAqNA;AA1NA;AACA;AC/lBA;;;;;;;;;;;;;;;;AAqBA;AAEA;;;AAGA;;;;AAQA;AACA;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAEA;;;;;;;;;;;;;;;AAeA;AAMA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAOA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;ACxKA;;;;;;;;;;;;;;;;AA0BA;AAEA;AAEA;AAkBA;AACA;AAGA;AACA;AAnBA;;;;AAAA;AACA;AAIA;AACA;AACA;AAIA;AACA;;;AAAA;AASA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAAA;AAIA;AAGA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AAIA;AAGA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;ACrLA;;;;;;;;;;;;;;;;AAoBA;AACA;AACA;AAEA;AACA;AACA;AACA;AC3BA;;;;;;;;;;;;;;;;AA0CA;AAEA;AAEA;;;;;;;;AAQA;;;;;;;;AAqBA;AACA;AACA;AACA;AAvBA;;;;;;AA8BA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAtCA;AAAA;AACA;AAEA;AAMA;;;AAAA;;AAgCA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;;AAGA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAIA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAIA;AAIA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AASA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AAKA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AAGA;AACA;;;;;;;AAQA;AAIA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AAGA;AAIA;;;;;;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;AACA;;;;AAKA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AAIA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAvUA;AAwUA;AA3dA;AA6dA;;;;;AAKA;AAAA;AACA;AACA;AAKA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;;;;;AAKA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AC5lBA;;;;;;;;;;;;;;;;AA8BA;AAEA;;;;;;;AAOA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAIA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAMA;AACA;AAIA;AAQA;AAAA;AACA;AAKA;AACA;AAAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;ACtIA;;;;;;;;;;;;;;;;AAsBA;;;;;AAKA;AAAA;AAAA;;AA2DA;;;;AAvDA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;;AAEA;AACA;;;;AAKA;;AAEA;AACA;;;;;;AAOA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AAEA;AACA;ACzFA;;;;;;;;;;;;;;;;AAyBA;;;;;AAKA;AAAA;AACA;AAAA;AAAA;AAGA;;AAIA;;;;;;AAOA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AAIA;AACA;;;;AAKA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACjGA;;;;;;;;;;;;;;;;AA0BA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;;AAIA;;AAEA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;;;;;;AAQA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AAKA;;;;;;;AAQA;AACA;AACA;AAEA;AACA;AACA;;;;;;AAOA;AACA;;AAGA;AACA;;;;;;;;;AAUA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;;AAEA;AACA;AAGA;AACA;;;;;AAMA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;;;;;AAMA;AACA;AAEA;AACA;;;;AAKA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AACA;AClMA;;;;;;;;;;;;;;;;AAuDA;;;;AAIA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACzJA;;;;;;;;;;;;;;;;AAgFA;;;AAGA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AAKA;;;;AAKA;AACA;AACA;AACA;AAIA;AACA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AAAA;AACA;AAGA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AAEA;;;;;;;;;AASA;;;;;;AAMA;AACA;AAGA;AACA;AACA;;;;AAKA;AACA;AAEA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AAMA;;;;AAKA;AACA;AACA;AACA;AAIA;AACA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;;;;AAKA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;;AAEA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AClTA;;;;;;;;;;;;;;;;AAkDA;AAMA;;;;;;;AAgBA;AACA;AACA;AACA;AACA;AACA;AAdA;AAIA;AACA;AACA;AACA;AAPA;AACA;AACA;;;AAAA;;;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AAAA;AACA;AAEA;AAGA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;;;;;;AAOA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;;;;AAIA;AACA;;;;;;;;AASA;AAMA;AACA;AACA;AAEA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAKA;AAKA;AACA;;;;;;;AAQA;AAKA;AAKA;AACA;;;;;;AAOA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;AAAA;AAMA;AACA;AACA;AAEA;;;;;AAUA;AACA;;AAGA;AAEA;;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AAMA;;;;;;AAOA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AAMA;;;;;;AAOA;AACA;AACA;AACA;AAGA;AAAA;AACA;AAGA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;;;;AAKA;AACA;AAEA;AACA;;;AAIA;;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAGA;AACA;;;;;;;;;AAUA;AAKA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;;AAEA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AACA;ACnqBA;;;;;;;;;;;;;;;;AAwCA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;;;;;AAKA;AAKA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AAEA;;;;;;;;;AASA;AAMA;AAKA;AAEA;;;;;;;;AAQA;AAKA;AAKA;AAEA;AAKA;AAMA;AAKA;AAEA;AACA;AACA;AAKA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9PA;;;;;;;;;;;;;;;;AAqBA;;;AAGA;AAAA;AACA;AAEA;AA0HA;;;;;;;AAlHA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACtJA;;;;;;;;;;;;;;;;AAoBA;;;;AAIA;AAAA;AACA;AACA;AACA;AACA;AACA;AA4BA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;AAKA;AACA;AAGA;;;;;AAOA;AAEA;AAEA;;;;;AAOA;AACA;AAEA;AAEA;AAEA;AACA;AA3CA;AACA;ACjEA;;;;;;;;;;;;;;;;AAsBA;;;;;;;AAaA;AACA;AACA;AACA;AAFA;AACA;AACA;;AAdA;;AAGA;AAYA;;;;AAKA;AACA;AACA;AAIA;AAKA;AAAA;AACA;;AAKA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACpEA;;;;;;;;;;;;;;;;AAqBA;AAEA;;;;;;AAMA;AACA;AACA;AAGA;AACA;AACA;AAEA;;;AAGA;;;;;;AAsBA;AAEA;AADA;AACA;AAIA;;;;;;AAnBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAmBA;AACA;AACA;;;;;;;;;;;;;AAcA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAGA;AACA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;AACA;AACA;;;;;;;;;AAUA;AAIA;AACA;AAEA;AACA;AAEA;AACA;;;;;;;;AASA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAIA;AACA;AAEA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;;AAhWA;AAiWA;AAnWA;AACA;AC1CA;;;;;;;;;;;;;;;;AAoBA;;;;;;AAMA;AAIA;AAAA;AAAA;;AAFA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;ACxCA;;;;;;;;;;;;;;;;AAqBA;;;;;;;AAOA;AAIA;AACA;AACA;AACA;;AALA;AAMA;AAEA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AClDA;;;;;;;;;;;;;;;;AAwBA;;;;;;;AAOA;AAIA;AACA;AACA;AACA;AAFA;AACA;AACA;;AALA;AAMA;;;;AAKA;AACA;AACA;AACA;;AAEA;AACA;AAAA;;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;;;;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;ACjFA;;;;;;;;;;;;;;;;AAoBA;;;;;;AAMA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;AAMA;AACA;AAGA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACpFA;;;;;;;;;;;;;;;;AAqBA;;;;;;;AAOA;;;;;;AAMA;AACA;AACA;AACA;;;;;;;AAyBA;AAKA;AAIA;;;;;;;AAQA;AAKA;AAIA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;;;;AA7EA;AAGA;AACA;AAIA;AACA;AAqEA;AA7FA;AACA;AC7BA;;;;;;;;;;;;;;;;AAmBA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;;AAOA;AACA;AACA;;;;;;AAOA;AACA;AACA;;;;;;;AAQA;AAKA;AACA;;;;;;AAOA;AACA;AACA;;;AAIA;;AAGA;;AAGA;;AAGA;;AAGA;AACA;AAzEA;AACA;AC7BA;;;;;;;;;;;;;;;;AA4BA;;;;;;;AAOA;AACA;AAAA;AAAA;AAEA;AAQA;AAIA;;AAEA;;;;AAMA;;;;AAKA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AAAA;AACA;AAIA;AACA;AAAA;AACA;AAGA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;;;;AAKA;AAKA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACvKA;;;;;;;;;;;;;;;;AAoBA;AAAA;AACA;AA4EA;AA1EA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAQA;AAAA;AAEA;AAEA;AACA;AAAA;AAEA;AAEA;AAIA;AAAA;AAEA;AAEA;AAIA;AAAA;AAEA;AAEA;AAQA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AClGA;;;;;;;;;;;;;;;;AAmDA;;;;;;;AAOA;AACA;AAAA;AAkBA;;;;AAdA;AACA;AACA;;;;AAKA;AAKA;AACA;AACA;AAAA;AAEA;;;;;AAKA;AAEA;;;;;;;AAOA;;;;;;AAMA;AAGA;AAFA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;AAKA;AAKA;AAEA;AACA;AACA;AAOA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;ACnJA;;;;;;;;;;;;;;;;AAsCA;;;;AAIA;;;;;AAKA;AACA;AACA;AACA;AACA;AAAA;AAEA;;;AAGA;;;;AAIA;AAAA;AAAA;;;;AAKA;AACA;AAIA;AAIA;;;;;;;;AASA;AAMA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AASA;AACA;AAAA;AACA;AACA;AACA;AAQA;AAAA;AACA;;AAEA;AACA;AACA;AASA;AACA;AAAA;AACA;AACA;AACA;AAQA;AAAA;AACA;AAOA;AACA;AAAA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAGA;AACA;AACA;;;;;;;;;;AAWA;AAOA;AACA;;AAEA;AACA;AAAA;AACA;AACA;;AAEA;AAIA;;;;AAIA;AACA;AAEA;AACA;AACA;AAGA;AAKA;AAAA;AACA;AAGA;AAKA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;;AAEA;AAKA;AACA;AAIA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;AAQA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;;;;;;;;;;;;AAaA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;;AAEA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AAEA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAAA;AACA;AAQA;AACA;AACA;AAKA;AAKA;AAOA;;;;;;;;;;;AAYA;AAQA;AACA;AACA;AAKA;AACA;AAKA;AAKA;AAAA;AACA;AACA;AACA;AAIA;AAKA;AAAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;AAIA;AACA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAQA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAIA;AACA;;;;;;;;;;;AAYA;AAAA;;;;;;;AAcA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AAaA;AAAA;;;AAWA;AAEA;AAEA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AAEA;AACA;;;;;;;;;;;AAYA;AAQA;AACA;AACA;;AAGA;;;AAIA;AACA;;AAEA;AAEA;AAEA;AASA;AAAA;;;AAGA;AACA;AACA;AACA;AACA;AASA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AASA;AACA;;;;;;;;;AAUA;AAMA;AACA;AAKA;AAOA;;;;;;;;;;AAWA;AAOA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AAIA;AAGA;AACA;AACA;AAKA;AAAA;AACA;AACA;AAIA;AAEA;AAEA;AACA;AACA;AACA;AAQA;AAAA;;AAEA;AAQA;AAAA;AACA;AACA;AACA;AAEA;;AAGA;AAGA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAAA;AACA;ACz5BA;;;;;;;;;;;;;;;;AAyBA;;;;;;;AAOA;;;;;AAOA;AAAA;;;;;AAKA;AACA;;;;;;;;;;;;;;;AAgBA;AAAA;AAKA;AACA;AAEA;AACA;AAEA;AAKA;AAMA;AACA;AAEA;AAOA;AAOA;AAOA;AAOA;AAQA;AACA;;;;;;;;;;;AAYA;AAAA;AAOA;AAEA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AAAA;AACA;;AAEA;AAIA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACnMA;;;;;;;;;;;;;;;;AAkCA;;;;;;;;;;AAUA;;;;;;AAWA;AAAA;AARA;AASA;AAEA;AACA;;;;;AAMA;AAEA;AACA;;AAGA;AAKA;AAKA;AAKA;;;;;AAUA;;;;;AAMA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AACA;;;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AAIA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;AAKA;AAEA;AAEA;AAIA;AAIA;AAEA;AACA;AAMA;AAEA;AAEA;AAIA;AAEA;AAKA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;;;;;;;;AASA;AAKA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;ACpSA;;;;;;;;;;;;;;;;AA+BA;AAEA;;;;;;;;;;AAUA;AAAA;;;;;;;AAoBA;AAuMA;AA1NA;AAQA;AACA;AACA;AACA;AAXA;AACA;AAIA;AACA;;;AAAA;AAeA;AACA;AACA;AAEA;;AAKA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;;AAEA;AAAA;AACA;AAGA;;;;;;;;;AAEA;AACA;AACA;;;;;;;;;;;AAYA;AAOA;AACA;AACA;;AAEA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAKA;AAKA;AACA;AACA;;AAGA;AACA;AACA;;;;;;;;;;;;AAaA;;AAKA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AACA;AACA;;;;;;;;;AACA;AAAA;;AAEA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AAGA;AAEA;AACA;AAEA;;AACA;;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AACA;AACA;;;;;AAMA;;AACA;;AACA;AAAA;AACA;AACA;;;;;;;;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AACA;AACA;AACA;AAAA;AACA;ACvQA;;;;;;;;;;;;;;;;AAyBA;;;;;;AAMA;AACA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;AAEA;AACA;AAGA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AAnIA;AAoIA;AAvIA;AAyIA;AAKA;;AAEA;AACA;AAAA;AACA;AACA;AACA;;;AAGA;AAIA;AACA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;ACtMA;;;;;;;;;;;;;;;;AAwCA;;;;;;;AAOA;AAAA;;;;;;;;AAQA;;;;;;;;;AAUA;AAEA;AAghBA;;;;;;;AAxgBA;AACA;AACA;;;;;;;;;AAUA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AAKA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;;;;;AAAA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;;AAGA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AAGA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;;;;;;;;;;;AAYA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAEA;;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;AAIA;AACA;AACA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AAGA;AACA;AACA;AACA;AAIA;;AAGA;AACA;AAIA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AAsBA;AAMA;AAIA;AACA;;;AAGA;AACA;AAAA;;AAEA;AACA;;AAEA;AACA;AAAA;;;;;;;AAOA;AACA;AACA;AACA;;;;;;;;;;AAWA;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;;;;;AAMA;AAQA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AAKA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AAIA;AAAA;AACA;AACA;AACA;AAIA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;;;;;;AAMA;;;;;AA4BA;AACA;AACA;AACA;;;;;;;;;;;AAYA;AAKA;AAMA;;;;;;;;AASA;AAGA;AAIA;;;;;;;;;;;;;;;;;;;;AAqBA;AAKA;AAMA;;;;;;;;;AAUA;AACA;AACA;;;;;;;;;;;;AAaA;AAOA;AAQA;;;;;;;;;AAUA;AAIA;AAKA;;;;;;;AAQA;AACA;AACA;AACA;AAAA;AACA;ACxwBA;;;;;;;;;;;;;;;;AA0DA;;;;;;;;;;;;;;;;;;;;;;AAsBA;;;;;AAkBA;AAAA;;;;AAdA;;;;AAKA;AAEA;AACA;AAMA;;;;;;AAOA;;AAOA;AAEA;AACA;AACA;AAAA;AACA;AAGA;AACA;;;;;;AAOA;;AAMA;AAEA;AAEA;AAGA;;;;;;;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;;;;;;AAOA;AACA;AAGA;;;;;;AAOA;AAIA;AAEA;AAGA;;;;;;AAOA;AACA;AAGA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAAA;;AAEA;AACA;AACA;;;;;;AAOA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAAA;;AAEA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAAA;;AAEA;AACA;AACA;;;;;;AAOA;AAIA;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAYA;AAAA;;AAMA;AACA;AACA;;;;AAIA;AAEA;AACA;;;;AAKA;AAKA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAEA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;;;AAGA;;AAEA;;AAGA;AACA;AAEA;AACA;AAMA;AAGA;AACA;;;;AAIA;;;AAGA;;AAEA;AACA;AAIA;AAAA;AACA;AACA;AAGA;AAIA;AACA;AACA;;AAEA;AAGA;AACA;AACA;;;;;;;;;;;;AAaA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;;;;;AAMA;AAGA;AAEA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AAEA;;;;AAKA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AAEA;AAOA;;;AAGA;AACA;AAIA;AAAA;;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AAEA;AAGA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AAGA;AACA;AAIA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;;;;AAUA;AACA;AACA;;;;AAKA;AAIA;AACA;AACA;AACA;AAGA;AAEA;;;;;;;;;;;;;;AAeA;AACA;AAGA;AAGA;;;;AAKA;AAMA;AACA;AAMA;AAAA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAEA;AACA;AAGA;AAEA;AACA;AACA;;;;AAKA;AAAA;AAMA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAGA;AAEA;AACA;;;;AA/IA;AAgJA;AA7vBA;AACA;ACjFA;;;;;;;;;;;;;;;;AAqBA;;;;;AAKA;AAAA;AACA;AASA;AAPA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;ACrCA;;;;;;;;;;;;;;;;AAmBA;;;;;AAKA;AAAA;AACA;AAaA;AAXA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;ACvCA;;;;;;;;;;;;;;;;AAoBA;AAAA;AA0BA;AAtBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AAEA;AACA;AAxBA;AACA;AAwBA;AA1BA;AACA;ACrBA;;;;;;;;;;;;;;;;AAoBA;;;;;;AAMA;AAGA;AAAA;AAFA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AC7CA;;;;;;;;;;;;;;;;AAuBA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;AAGA;;;;;AAQA;AAAA;AANA;AAOA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AAIA;AACA;AAAA;AACA;AC/EA;;;;;;;;;;;;;;;;AAqBA;;;;;;;;;;;;;;AAcA;AAAA;;;;;AAKA;;;;;;AAOA;AAyFA;;;;AApFA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAWA;AACA;AACA;AACA;AAAA;AAEA;;;;;;;;;;AAWA;AACA;AAEA;AACA;AACA;AACA;;;;;AAMA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;;;;AAIA;AAOA;AAAA;;;;;AAFA;AAEA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACtLA;;;;;;;;;;;;;;;;AAmBA;;;;AAIA;;;;AAWA;AAAA;AAVA;AAWA;AAIA;;;;;;AAgBA;AAAA;AAAA;AAAA;;AACA;;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAGA;AACA;AAAA;AACA;ACpGA;;;;;;;;;;;;;;;;AAsBA;;;AAGA;AAAA;AAOA;AAAA;AAEA;AACA;AACA;AAEA;AAEA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;AAMA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;;AACA;AA/CA;AACA;AACA;;;;;AAmDA;AACA;AACA;AACA;AACA;AAAA;AACA;ACtFA;;;;;;;;;;;;;;;;AAoBA;;;;;;;;;AASA;AAAA;AAOA;AAAA;AANA;;;;;AAaA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAIA;AAGA;AACA;AACA;AACA;AACA;AAGA;;AACA;AAtCA;AACA;AACA;;;;;AA0CA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;ACxFA;;;;;;;;;;;;;;;;AAmBA;;;;;AAKA;;;;AASA;AAAA;AARA;AACA;AACA;AACA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AAAA;AACA;;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AALA;AAAA;AAMA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAnBA;;;;AAoBA;AACA;AACA;AAAA;AACA;AC5EA;;;;;;;;;;;;;;;;AA6CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AAEA;;;;;AAKA;AAEA;;;;;;AAMA;;;;;;;;;;AA0BA;AACA;AACA;AACA;AACA;AACA;AA9BA;AACA;AAUA;AAqBA;AACA;AACA;AACA;AAAA;AACA;;;;;;AAOA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;AAEA;;AAGA;AACA;AACA;AACA;;AAGA;AACA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;;;AAGA;;;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAEA;AACA;;;AAMA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;;;;AAOA;AACA;AACA;;;;AAOA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;;;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;;;;;AAMA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;AAGA;;;AAIA;;;AAIA;AACA;AAKA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAOA;;;;AAIA;;;;;;;AAiCA;AAGA;AACA;;;AAlCA;;AAGA;;;;;;AAOA;;;AAIA;AAsBA;;;;;AAKA;AACA;AAGA;;AAKA;;AAGA;;;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;;AAGA;AACA;AACA;;;;AAIA;AACA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;;AAGA;AACA;AACA;AAAA;AACA;;AAEA;AAAA;;AAEA;AACA;AAEA;AACA;;;;AAKA;AAAA;;AAEA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;;AAGA;AACA;;;;;;;;AASA;;;;AAIA;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;;;;;;;AAQA;;AAEA;;;AAIA;AACA;AACA;AACA;;;;;;;AAQA;AAAA;;AAEA;AAEA;AACA;AACA;AACA;;;AAIA;AAKA;;AAEA;;AAGA;AACA;AAEA;AACA;;;;;;AAOA;AAAA;AACA;;AAEA;AACA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AChvBA;;;;;;;;;;;;;;;;AAiBA;AACA;AAEA;AACA;AACA;AACA;AACA;ACxBA;;;;;;;;;;;;;;;;AA6CA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAMA;;;;;AAKA;;;;;;;;;AAuBA;AACA;AAEA;AAzBA;AACA;AACA;AACA;AACA;AAyBA;AACA;AACA;AAKA;;;;;;;;;AAUA;AAKA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AAAA;AACA;AACA;AAEA;AAEA;;AAEA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;;;;;AAkBA;;;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;;;;AAQA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AAEA;AACA;AACA;;;AAKA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;AAQA;;;;AAIA;AACA;AACA;AAAA;AACA;AAKA;AACA;AACA;;;;;AAjMA;;;;;AAMA;AA4LA;AA9XA;AACA;ACjEA;;;;;;;;;;;;;;;;AAuBA;;;;;;;;AAQA;;;;AAcA;AACA;AACA;AATA;;;;;AAAA;AACA;AACA;;;AAAA;;;;;AAaA;;AACA;AAEA;AAGA;AACA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;ACzGA;;;;;;;;;;;;;;;;AA+BA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;;;;;;AAMA;;;;;;;;;;;AA2BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlCA;AACA;AAWA;AAwBA;AACA;AACA;AACA;AACA;;;;;AAMA;AAAA;AACA;AACA;;;AAUA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AAEA;AACA;;;AAIA;AAAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;;AAEA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;;AAEA;;AAEA;AACA;;;AAIA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AAAA;;AAEA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;AAOA;AAMA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;;;AAQA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;AAQA;AACA;;;AAIA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AAEA;AACA;AACA;AACA;;;AAIA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACrkBA;;;;;;;;;;;;;;;;AAmBA;;;;;;AAMA;AAAA;AAyFA;;;;;;;AA7DA;;;;;;;AAaA;;;;;AAWA;;;;;;AAOA;;;;;;AAWA;;;;;AAUA;;;;AAQA;AACA;AAAA;AACA;ACnHA;;;;;;;;;;;;;;;;AA4CA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAyBA;;;;;;AAMA;AAAA;;;;;;;AAsDA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;;AAhEA;AACA;AAEA;;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;;AAGA;AACA;AAEA;AAKA;AACA;AACA;AAEA;AACA;AACA;AA+BA;AACA;AAGA;AACA;AAEA;AAEA;AACA;AACA;;AACA;AAEA;AAKA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;;;;AAKA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;;AAGA;AAEA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;AAGA;AACA;AACA;AAGA;AACA;AACA;;;;;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AACA;AACA;AAEA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAMA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AAKA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;;;;AAKA;AAMA;AACA;;;;AAKA;AAMA;AACA;AAEA;AAOA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;;;;AAKA;AAAA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AAGA;AAAA;AACA;AAGA;AAGA;AAAA;AACA;AAIA;AAAA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAKA;AACA;AACA;;;AAKA;AACA;AACA;;AAEA;AACA;AAEA;;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAGA;;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAIA;AAEA;AACA;;AAGA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;;AAEA;;;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AAEA;;;AAEA;;;;AAIA;AAAA;;AACA;AAAA;AACA;AACA;;;;;;;;;AACA;;;;;;;;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;;;;AAKA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAx1BA;;;;AAKA;AAo1BA;AAAA;AACA;ACt9BA;;;;;;;;;;;;;;;;AAyBA;;;;;AAKA;AAAA;;;;;;;AAwCA;AAAA;AACA;AACA;AAMA;;AA1CA;;;;;;;AAQA;;AAqCA;AAlDA;AACA;AACA;;;;;;;AAmBA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;;AAsBA;AAAA;AAMA;AACA;;AAKA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;;AAGA;AACA;AACA;AACA;;AAGA;;AAEA;;;;;;;;;;AAWA;AAAA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AC/NA;;;;;;;;;;;;;;;;AAkDA;AAEA;;;AAGA;AA0BA;AAAA;AACA;AAEA;AA5BA;AAKA;AACA;AACA;AAOA;;AAMA;;AAGA;AAQA;AAEA;AACA;;AAOA;AACA;AAAA;AACA;;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAUA;AACA;AAEA;AACA;AACA;;;AAIA;AAKA;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AAGA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AAGA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;;;AAKA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAKA;AAAA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AAMA;AACA;AACA;AACA;AACA;;;AAIA;AACA;AACA;AACA;AAMA;AACA;AAMA;AACA;AAIA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AAEA;AAAA;AAKA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AAEA;AACA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;AAKA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAKA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAMA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAKA;AACA;AAGA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAIA;AAAA;AACA;AAIA;AACA;AACA;AAEA;;;AAMA;AACA;AACA;AAIA;AAAA;AACA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AACA;ACpoBA;;;;;;;;;;;;;;;;AA4BA;;;;;;AAMA;;;;AAgCA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AAEA;AAEA;;;;AAKA;AAQA;AACA;AACA;AACA;AAQA;;;;AAKA;AAKA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;;;;AAKA;;AAEA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AC/MA;;;;;;;;;;;;;;;;AA8BA;;;;;;AAMA;;;;AAgCA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAQA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AAQA;AAAA;AACA;AAOA;AACA;;;;AAKA;AAKA;AACA;;AAEA;AACA;AAAA;AACA;AAEA;;AAGA;;AAEA;AACA;AACA;AAIA;AAAA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAAA;;AAEA;;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;;AAEA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;;;;;AAWA;;AAQA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAEA;;;;AAKA;AAKA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AAIA;AAEA;AACA;AACA;AAGA;AACA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;ACpWA;;;;;;;;;;;;;;;;AA6BA;;;;;;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAwXA;;;;AAzUA;AACA;AACA;;;;AAKA;AACA;;;;;AAKA;AACA;AAAA;AACA;AAGA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;;;;;;;AA/WA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AA8UA;AAtYA;AACA;ACpCA;;;;;;;;;;;;;;;;;AA6CA;;;;;;;;;;;;AAeA;AAAA;AACA;AACA;AAGA;;AAGA;;AACA;;AAGA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;;;;;;AAOA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAGA;AACA;;;;;;AAOA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AAKA;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AAOA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAMA;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AACA;;;AAGA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;;;;;;AAOA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AAEA;;;;;;AAMA;AACA;AACA;AChZA;;;;;;;;;;;;;;;;AAsBA;;;AAGA;AAAA;;;AAGA;AACA;AACA;AACA;AAAA;AAAA;AAEA;;;;;AAKA;;;;;;;AAOA;AACA;AACA;AACA;AAFA;AACA;AACA;AACA;;;;;;;AAQA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;AAWA;AAKA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;;AAUA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AAEA;AACA;AAEA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC1PA;;;;;;;;;;;;;;;;AAiCA;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;;;;AAIA;;;AAIA;;;AAIA;;;AAIA;;AAGA;AACA;AAEA;;;;;;;AAOA;AACA;AAmCA;;;;AAIA;AACA;;;;;;;AAOA;AACA;AAaA;;;;;;;;AAQA;AAMA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;;AAGA;;AAGA;;AAGA;;AAGA;;AAGA;;AAGA;AAEA;AAEA;AAEA;AAEA;AACA;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AAKA;AACA;AACA;AAAA;AACA;;AAOA;AACA;AACA;AACA;AAEA;;;;AAKA;AACA;AAEA;AACA;;AAGA;AACA;AAGA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAMA;AAEA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AAIA;AAEA;AAEA;AAEA;;;;;;;;;;AAUA;AACA;AAAA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AACA;AAAA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;;AAEA;AAIA;AAEA;AACA;;AAGA;AAIA;AACA;AACA;AACA;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;;AAGA;;AAIA;AAEA;;AAGA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;;;;;;;;;;;;AAYA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAEA;;;;;;;AAOA;AACA;AAIA;AACA;AACA;;;AAIA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AAGA;AAAA;;AAEA;AACA;AACA;AACA;AAGA;AAAA;;AAEA;AAIA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;;AAEA;AACA;AAQA;AAGA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;AAIA;AACA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;;AAGA;;AAGA;AACA;AACA;;AAGA;AACA;AAEA;;;;;;;;AAQA;AACA;AAGA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;;;;;AAOA;AACA;;AAIA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AAEA;;;;;AAKA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;;;;;;;AAQA;AACA;AAAA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;;;;;;AAMA;AACA;AAGA;AACA;;;AAGA;;;AAIA;AACA;AACA;AACA;AAEA;AACA;AAIA;;AAEA;AACA;AACA;AAAA;AACA;;AAKA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AAAA;;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AC9xBA;;;;;;;;;;;;;;;;AAiCA;;;AAGA;AAEA;AAAA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAkBA;AAfA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AAEA;AAEA;AAhBA;AAiBA;AAlBA;AACA;ACpHA;;;;;;;;;;;;;;;;AAkCA;AACA;AAEA;;;;;;;;AAQA;AAEA;AAEA;;;AAGA;AAAA;;;;AAIA;;;;;AAUA;AA2IA;AAzIA;AACA;AACA;AACA;AACA;AACA;;AAGA;;;AACA;AAAA;;AACA;AAAA;AACA;AACA;;;;;;;;;AACA;;;;;;;;;AACA;AAEA;;;AACA;AAAA;;AACA;AAAA;AACA;AACA;;;;;;;;;AACA;;;;;;;;;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;;;;;;AAOA;AACA;;AAEA;AACA;AAGA;AACA;AACA;AACA;;;;;;;;;AAUA;AAKA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;;;;;AAMA;AACA;AACA;AACA;AAAA;AACA;AC9MA;;;;;;;;;;;;;;;;AA8BA;;;;;;;;;AAyBA;AAAA;AACA;AACA;AAGA;;AAGA;AAEA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAcA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;;;;;;AASA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AA5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAkGA;AAjHA;AAmHA;;AAEA;AAAA;AAAA;;AAGA;;;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;;;AACA;AACA;AAAA;AACA;ACvKA;;;;;;;;;;;;;;;;AAqBA;;;;;;;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;AAKA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AACA;;;;;;;;;;;;;ACrEA;;;;;;;;;;;;;;;;AAuBA;AAEA;;;;AAIA;AACA;AAIA;AACA;AAEA;;;;AAIA;AACA;AAIA;AACA;AAEA;AACA;AAEA;;;;AAIA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAEA;;;;AAIA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;;;;;;;;;;;;;;AjK/FA;;;;;;;;;;;;;;;;AAmCA;AAEA;;AAEA;;AAGA;;;AAMA;AACA;AAEA;AAKA;AAGA;;AAEA;AACA;AACA;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AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;AAGA;AAKA;;AAGA;AAEA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAIA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AAEA;;;;AAIA;AACA;AAEA;AACA;AACA;AC7IA;;;AAGA;AAGA;AAAA;AAFA;AACA;AAKA;AACA;AACA;AACA;AAEA;AACA;;AAIA;AAEA;AAEA;AACA;;AAIA;AAEA;AACA;AAEA;;;;;;AACA;AACA;AACA;;;;AAGA;;AAAA;AACA;AACA;AACA;AACA;;;;AAGA;;;;;AAEA;AAEA;;;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;;;;AAKA;AACA;;;;AACA;AAEA;;;;;AACA;;AAAA;AACA;;AAAA;AACA;;;;AACA;AACA;AAAA;AACA;AChHA;;;;;;;;;;;;;;;;AAiBA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAiEA;;;AA9DA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAIA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAAA;AACA;ACrGA;;;;;;;;;;;;;;;;AAsDA;;;;;;AAMA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;;;;;;AAYA;AAAA;AAIA;AAHA;AAGA;AAdA;AACA;AA4BA;AACA;AACA;AACA;AACA;AAjBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;;;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AACA;AACA;;;;;AAMA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;AASA;;;;;;AAKA;;;;AAIA;AACA;AACA;AACA;AACA;;AAJA;;;;;;;;AAUA;AACA;AACA;AACA;;AAEA;;;;AAEA;;AAAA;;;;;AAIA;AACA;AACA;AACA;;;;AACA;;;;;;AAOA;;;;;;AAKA;;AAGA;AACA;AAGA;AACA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;;AAJA;;AAOA;AACA;AAIA;AAGA;AAKA;AACA;AACA;AAEA;AACA;AAIA;AAEA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AAGA;AAEA;;;;AACA;AACA;AAAA;AAEA;;;;;AAIA;;AAAA;;AAEA;AACA;;;;;;AJ5RA;;;;;;;;;;;;;;;;AAyBA;;;AAGA;AAEA;;AAEA;AACA;AACA;;AAGA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;;;;ApQnDA;;;;;;;;;;;;;;;;AAuBA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AyQxBA;;;;;;;;;;;;;;;;AAmBA;AAEA;AACA;AAEA;AAGA;AAEA;AACA;AACA;AC/BA;;;;;;;;;;;;;;;;;AA6BA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAYA;AAcA;AACA;AACA;AAEA;AAEA;AACA;ACxEA;;;;;;;;;;;;;;;;AA+BA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAIA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAUA;;;;;AAKA;;;;;AAGA;;AAAA;AAEA;;AAEA;AACA;AAEA;;;;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AC/GA;;;;;;;;;;;;;;;;AAiCA;AAEA;;;;;;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;AAAA;AACA;AACA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;;;;;;AChEA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;ACvBA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;AACA;ACrBA;;;;;;;;;;;;;;;;AAmBA;AACA;AAEA;;;;AAIA;AACA;;;AAGA;AACA;AAEA;;AAGA;AAEA;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AACA;AACA;;;AAIA;AACA;AACA;ACvDA;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AACA;AACA;ACvBA;;;;;;;;;;;;;;;;AAqBA;AAEA;;;;AAIA;AACA;AAEA;AACA;AACA;AAEA;;;AAMA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AAEA;;AACA;AACA;AACA;AACA;;AAEA;AAAA;AACA;AACA;;;;;;;;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AC9GA;;;;;;;;;;;;;;;;AAuBA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;;;;;;AAIA;AACA;;AAAA;AACA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AAEA;AACA;AACA;AAEA;;;;AACA;AAEA;AACA;;;;;;AACA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;;;;;AACA;AAEA;;;;;;AAMA;;;;;;AAIA;AACA;;AAAA;AACA;AACA;AACA;;AAAA;AACA;AAEA;AA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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AhSzEA;;;;;;;;;;;;;;;;;AAsCA;;;AAGA;AAEA;;;;;;;;;;;AAWA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAaA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAAA;AACA;AAGA;AACA;;;;;;;;AASA;AAAA;;;;AAUA;;;;;AAsBA;;;;AAcA;;;;AA1CA;AACA;AAOA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAPA;;AAUA;AACA;AACA;AAOA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AANA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;;;AAHA;;;;AASA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;;AACA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAGA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA1CA;AAAA;AAAA;AA2CA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A8Q5QA;;;;;;;;;;;;;;;;;AAuCA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAYA;AACA;ADzFA;;;;;;;;;;;;;;;;AAiBA;AACA;AAEA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AoBlCA;;;;;;;;;;;;;;AAoDA;AAAA;AACA;AACA;AACA;AACA;ACxDA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;ACrCA;;;;;;;;;;;;;;;;AA6DA;AACA;;;;AAIA;AACA;AAEA;;;;;;;AAGA;AAGA;;AAAA;AAGA;AAEA;;AAEA;AACA;;;AAGA;AAEA;;;;;;AACA;;AAEA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;;AAAA;AACA;;AAAA;AAEA;;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AACA;;AAtEA;AAuEA;;AAGA;;;AAAA;AACA;;AAAA;AACA;;AAAA;AAEA;;;;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AbjMA;;;;;;;;;;;;;;;;AAuBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAGA;AACA;;AAAA;AACA;AACA;AACA;AACA;;AAHA;AAKA;AACA;AAGA;;AAAA;AAGA;AACA;;AAAA;AACA;;;;;AAGA;AAEA;AACA;;;;;;AAIA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;;;AACA;AAEA;AACA;;;;;;AAGA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;;;;;AACA;AAWA;AAAA;AACA;AACA;AACA;Ac1GA;;;;;;;;;;;;;;;;AAsCA;;;;;AAIA;;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;AAIA;;AAAA;AAIA;;AAAA;;;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;AACA;AAEA;;;;;AAIA;;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;AAIA;;AAAA;AAIA;;AAAA;;;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;AACA;AAEA;;;;;AAIA;;AAAA;AAEA;AACA;AACA;AACA;;;;AAGA;;AAAA;AAIA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAEA;AACA;AACA;;;;;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AACA;;;;;AAGA;;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AC1LA;;;;;;;;;;;;;;;;AA4BA;AACA;AAEA;;;;;;AAKA;AACA;AACA;AAIA;;AAAA;AACA;;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;;AAEA;;;;AAIA;;AAAA;;;;;AAGA;;AAGA;;AACA;;AAEA;AAEA;AACA;AACA;AACA;AAIA;AAAA;;AAEA;AACA;;;;;AACA;AAEA;;;;AAIA;;;;;AAIA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;;AAIA;;AAAA;AACA;AACA;AACA;;AAGA;;;;AACA;AAEA;;;;;;;AAMA;;AAAA;AAKA;AAMA;;AAAA;AACA;;;AAEA;;AAAA;AACA;;;;;AAEA;AAEA;;;;;AAIA;;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;;AAAA;AACA;;;;AACA;AAEA;;;AAGA;;;;;AAIA;;AAAA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;;AACA;AAEA;;;AAGA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;ACxLA;;;;;;;;;;;;;;;;AAoBA;AAGA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AAEA;AAIA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AC9FA;;;;;;;;;;;;;;;;AAoBA;;AAEA;AACA;AACA;ACxBA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;ACvBA;;;;;;;;;;;;;;;;AAyCA;AAaA;AAAA;AACA;;;;;AATA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;;;;;;;;;;;;;;;;AAiBA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;;;AAIA;;;;;;;AACA;AAIA;;AAAA;AACA;;AAIA;;;;AAKA;;;AAIA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;AAYA;;;;;;AACA;AACA;AACA;AAEA;AAEA;AACA;AAGA;;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;;AAAA;AACA;;;;;AAKA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AACA;AAEA;;;;;;;AACA;AACA;;AAEA;;;AAAA;AACA;AAGA;;AAAA;AACA;;AAAA;AACA;;AAAA;;;;;AAKA;AAEA;;;;;;;AACA;AAGA;AACA;AACA;AAAA;;;AAGA;AACA;;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;;AAAA;AACA;AAEA;;;AAAA;;;AAGA;;;;AAAA;;AAEA;;AAAA;;;AAGA;;AAEA;AACA;AAEA;AACA;AACA;;;;AACA;AACA;AAAA;AAEA;;AAGA;;;;AAOA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;;;;AAIA;;;;;;;AAGA;AAEA;;AAAA;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAEA;;;;AACA;AAEA;;;;AAIA;AACA;AAEA;;;AAGA;AAAA;AAEA;AAEA;;AAIA;AACA;;AAEA;AAAA;AACA;AACA;;;;;;;;;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AAEA;;;;AAKA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AAEA;;;AAEA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AC3YA;;;;;;;;;;;;;;;;AAyCA;AAKA;AAAA;AACA;AALA;AAEA;AAKA;AACA;AAAA;AAEA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;;;;;;AACA;AAEA;AACA;AACA;;;;AAKA;AAEA;AAEA;AACA;AAGA;AAAA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAEA;;AAAA;;;;;;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;AAIA;AACA;;AAAA;;;AAGA;AACA;AACA;AAEA;;AAAA;AACA;;AAAA;AAEA;;;;AAKA;AAEA;;;AACA;AACA;AACA;AAAA;AACA;AACA;;;;AACA;AAEA;;;;;AAGA;AACA;;AAAA;;;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;AACA;AAEA;;;;;;;AAEA;AAAA;AAGA;AACA;;AAJA;;;;;;AAYA;;AAEA;;;;AAEA;AACA;AACA;;;;;AAEA;AAEA;;;;;AACA;AACA;;AAAA;;AAGA;;;;AACA;;;;;;;;;AAUA;;;;;;AACA;AACA;AACA;AAEA;;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;;;;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;;;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;AAEA;;;;;;AAIA;AACA;;AAAA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AX1SA;;;;;;;;;;;;;;;;AAuBA;;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AC7DA;;;;;;;;;;;;;;;;AAqCA;AACA;;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAuBA;AACA;;AAEA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AlSrIA;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AAGA;AACA;AACA;A6S1CA;;;;;;;;;;;;;;;;;AAoCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAEA;AAUA;AACA;AClEA;;;;;;;;;;;;;;;;AA0BA;AACA;AAUA;;;;AAIA;AAUA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;ACnJA;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;ACnCA;;;;;;;;;;;;;;;;AAsBA;AAEA;AAAA;;AAEA;;AAGA;;AAGA;;AAEA;AACA;;AAGA;;;AAIA;AAKA;;AAGA;;AAGA;AACA;;AAGA;AAiDA;AA3CA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC3GA;;;;;;;;;;;;;;;;AAkBA;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AAEA;AACA;AACA;AACA;AC3CA;;;;;;;;;;;;;;;;AA2BA;AAAA;AACA;AACA;AACA;AACA;AAuBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;ACrHA;;;;;;;;;;;;;;;;AAoBA;AACA;AACA;ACtBA;;;;;;;;;;;;;;;;AA6BA;AAWA;AACA;AACA;AACA;AACA;AAoBA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AAGA;AAEA;AAGA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAGA;;AAGA;AACA;AAGA;AAEA;AACA;AAMA;AACA;AACA;AAMA;;AAEA;AAGA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;ACzOA;;;;;;;;;;;;;;;;AA2BA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AC7EA;;;;;;;;;;;;;;;;AAqBA;AACA;AACA;AACA;AACA;AA6BA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;;AAEA;AACA;;;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAIA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9LA;;;;;;;;;;;;;;;;AAqFA;AAEA;AAIA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAAA;;;AAGA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;;;AAIA;;;AAIA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClPA;;;;;;;;;;;;;;;;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AChEA;;;;;;;;;;;;;;;;AA6CA;;;;;;;;AAmBA;AAEA;AADA;AACA;AApBA;AAGA;AACA;AACA;AACA;AAiBA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;;;;;;;;AASA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AASA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;;;;;;;AAQA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AAIA;AAIA;AAIA;AAEA;AACA;AACA;AACA;AAGA;AACA;AAIA;AACA;AAGA;AACA;AAIA;AAEA;AACA;AAIA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;ACzUA;;;;;;;;;;;;;;;;AAgDA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AC7EA;;;;;;;;;;;;;;;;AAsBA;AAEA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;;;AAGA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AAAA;AACA;AACA;;AAEA;AACA;AAEA;AACA;;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AC7FA;;;;;;;;;;;;;;;;AA0BA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AACA;AACA;AALA;AACA;AACA;;;AAAA;AAKA;AAGA;AACA;AACA;AALA;AACA;AACA;;;AAAA;AAIA;AAAA;AACA;AtTxDA;;;;;;;;;;;;;;;;AA+BA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;;;AAMA;;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;AuTzEA;;;;;;;;;;;;;;;;AA0BA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAWA;;AAKA;AACA;AACA;AACA;;AAGA;AAEA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;;AANA;;AASA;AAEA;AAKA;AACA;;;AAIA;AACA;AAGA;;AAAA;AAIA;;AAEA;AACA;AAEA;;AAEA;AAGA;AAEA;;AAAA;AAEA;;;;AACA;AACA;AAAA;AACA;AzT3HA;;;;;;;;;;;;;;;;;AAmCA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAoBA;AAMA;AACA;AACA;AACA;AACA;A0TjGA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;AASA;AACA;AAEA;;AAEA;;;AAGA;;AAEA;AACA;AACA;ACtCA;;;;;;;;;;;;;;;;AA8CA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAWA;;;;;AACA;AACA;AACA;AACA;;AAHA;AAKA;AAEA;AAEA;AAEA;AACA;AACA;;;AAGA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;;AAIA;;AAAA;AACA;;AAAA;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AAGA;AAOA;AACA;;;;AAEA;;AAAA;;;;AAEA;AACA;AACA;;AAEA;AACA;;;;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AAEA;;;;AACA;AACA;AAAA;AACA;AChLA;;;;;;;;;;;;;;;;AA2CA;;;;;;;;AAQA;AAAA;AACA;AAOA;AANA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC5DA;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AADA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;ACzDA;;;;;;;;;;;;;;;;AAmCA;AACA;AAEA;;;;;AAKA;AAqCA;;AAEA;;;;AAIA;AAJA;AAIA;AACA;AACA;AACA;;AA5CA;AAKA;AACA;AACA;AACA;AAEA;AAmCA;;;AA/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAcA;;;;;AACA;AACA;AACA;AACA;;AAHA;AAIA;AAEA;AACA;AACA;;;AAIA;AACA;AACA;AACA;AACA;AACA;;AAHA;AAIA;;;;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;;;;;;;AAWA;AAEA;;;AAEA;;;AACA;;;;AAIA;AACA;AACA;AACA;;AAHA;AAKA;;AAAA;;;;AAEA;AACA;AACA;AACA;;AAAA;AACA;;;;;AAEA;AAEA;;;;AACA;;AAAA;AACA;;;;AACA;AAEA;AAAA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAEA;;;AAGA;AAAA;AAAA;AACA;AACA;AACA;AC3NA;;;;;;;;;;;;;;;;AAyBA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;AAUA;AAEA;AACA;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;;;;;;AAMA;AAIA;AAHA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;AAIA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;;AACA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAEA;AACA;;;;AACA;AAEA;;;;;;AACA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAEA;AACA;;;;AACA;AAEA;;;;;;AACA;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAEA;AACA;;;;AACA;;AAGA;AACA;AACA;AACA;AAAA;AACA;ACpQA;;;;;;;;;;;;;;;;AAqBA;;;AAGA;AACA;AAAA;AAAA;;;;AAYA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;AAKA;;;;;;AACA;AACA;AACA;AAQA;;AAAA;AACA;AACA;AACA;AAEA;;AAAA;AACA;AACA;AACA;AAEA;;AAAA;AACA;AACA;AACA;;;;;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;ACnGA;;;;;;;;;;;;;;;;AAiBA;;;AAGA;AAEA;;;;AAIA;AAEA;;;;;AAKA;AAEA;;;;;;;;AAQA;AAEA;;;;;AAKA;;;;AAIA;;;AAKA;;;AAGA;AACA;;;AAGA;AACA;;AAIA;AACA;AACA;ACzEA;;;;;;;;;;;;;;;;AA4BA;;;;;;;;;;;;AAYA;AAIA;;AAEA;AAEA;;AAGA;AACA;;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;;AAGA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;AAEA;;;;;AACA;;AAAA;AACA;AACA;AACA;AAEA;;;;AACA;;;;;;AAOA;AAEA;;;;;;;;;AAKA;;;;;AAAA;;;;AAGA;;AAAA;;AAGA;;;AAAA;AAEA;;;AAEA;AACA;AACA;AAGA;AACA;AAEA;AACA;;AAGA;;;AAAA;AAEA;;;;;AAEA;AACA;AAAA;AACA;;;;AhUhJA;;;;;;;;;;;;;;;;AA8CA;AAGA;AAQA;AAEA;;;AAMA;;AAEA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;AAIA;AAEA;;AAGA;AAMA;AACA;AAOA;;;AAUA;AAEA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;AiUlIA;;;;;;;;;;;;;;;;AAgBA;;;AAIA;;;AAGA;AAEA;;;AAGA;AAEA;;;;;AAKA;AAEA;;;;;AAKA;AACA;AC3CA;;;;;;;;;;;;;;;;AAkBA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AAQA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAIA;AAgBA;AACA;AAGA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AAIA;AAmBA;AACA;AAIA;AASA;AACA;AAIA;AAEA;AACA;AAIA;AAYA;AACA;AAIA;AAEA;AACA;AAIA;AAEA;AACA;AAIA;AAEA;AAKA;AAIA;AAEA;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAIA;AAEA;;;AAGA;AACA;AAGA;AACA;AACA;AAEA;AAEA;;;;AAIA;AAIA;AAIA;AAEA;;;AAGA;AACA;AAIA;AACA;ACpUA;;;;;;;;;;;;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;;AAGA;AAGA;AAAA;AACA;AACA;AACA;AAAA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;;AAEA;AAEA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AAAA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAKA;AAJA;AACA;AAIA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AC1OA;;;;;;;;;;;;;;;;AA0BA;;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;ACrFA;;;;;;;;;;;;;;;;AAiBA;;;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AC/DA;;;;;;;;;;;;;;;;AAoDA;;;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AC5DA;;;;;;;;;;;;;;;;AAoBA;;;;AAIA;AAMA;AAAA;AAFA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AAGA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AAGA;AACA;AACA;;;;;AAMA;AACA;AACA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACpJA;;;;;;;;;;;;;;;;AAuBA;;;AAGA;AAAA;AAIA;AAHA;AACA;AACA;AACA;AAAA;AACA;AC/BA;;;;;;;;;;;;;;;;AAuBA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AC3EA;;;;;;;;;;;;;;;;AA0BA;;;;;AAKA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;ACpIA;;;;;;;;;;;;;;;;AAwBA;;;AAGA;AAGA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACvIA;;;;;;;;;;;;;;;;AAkBA;;;;AAIA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;ACrCA;;;;;;;;;;;;;;;;AAiBA;;;AAIA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AC9DA;;;;;;;;;;;;;;;;AAuBA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AC1CA;;;;;;;;;;;;;;;;AA8BA;AACA;AACA;AAEA;;;AAGA;AAKA;AACA;AAKA;AACA;AACA;AACA;AACA;AAAA;AAKA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;;;;AAKA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnOA;;;;;;;;;;;;;;;;AA6CA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AChGA;AAiBA;;;;;;;;AAUA;AATA;AACA;AAQA;AACA;AA3BA;AACA;AACA;AAEA;;;;;AAQA;AACA;AACA;AAcA;AACA;AAAA;AACA;ACtDA;;;;;;;;;;;;;;;;AA2CA;;;AAGA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAIA;AACA;AACA;AAEA;AAGA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AAOA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAEA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;AAQA;AAIA;AACA;AACA;AAIA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AAEA;;;;;;;;;AASA;;;AAYA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzhBA;;;;;;;;;;;;;;;;AAoCA;;;AAGA;AAKA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC/BA;;;;;;;;;;;;;;;;AAqBA;;;;;;AAMA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAIA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrKA;;;;;;;;;;;;;;;;AAiBA;;;;;AAKA;AACA;AAAA;AAAA;AAAA;;;AAEA;AACA;AACA;AACA;AC5BA;;;;;;;;;;;;;;;;AAuDA;;;;AAIA;;;;;;AA4BA;AAAA;AAMA;AA3BA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAIA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAIA;AAAA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;;AAMA;AACA;AACA;AACA;AACA;AAUA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAIA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AAAA;AACA;AACA;AAQA;;;AAAA;;;;;AAMA;AASA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;;AAQA;;;AAMA;AAIA;;;;AAKA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC7qBA;;;;;;;;;;;;;;;;AA4CA;;;;;;;;;;;AAWA;AAGA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AAMA;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAMA;;;;;AAAA;AACA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;;;;;;;AAQA;AAEA;AAEA;AACA;AACA;AAQA;;;;;;;;AASA;AAEA;AAGA;AAKA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAQA;;;;;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAIA;;AAEA;AACA;AACA;;AAAA;AACA;AACA;AACA;AACA;;AAAA;;;;;;AAEA;;;;;;;;;;;;;;;;;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AAGA;AAIA;AACA;AACA;;;;;;AAOA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;;;;;;;;;;AAWA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;;;;;AAMA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AChVA;;;;;AAKA;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AAAA;AACA;AAAA;AACA;ACvCA;;;;;;;;;;;;;;;;AAyBA;;;;;;AAMA;;;AAOA;;;;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AACA;AACA;AACA;ACzIA;;;;;;;;;;;;;;;;AAqDA;;;;AAIA;AAsBA;AAAA;AAfA;AACA;AACA;AACA;AACA;AACA;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAKA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;AAMA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;;;;;AAKA;AAMA;AACA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AC7TA;;;;;;;;;;;;;;;;AA+BA;;;;;;AAMA;AAYA;;AAVA;AAGA;AAGA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AACA;AACA;AACA;;AAAA;AACA;AACA;AACA;;AAEA;;;;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AAEA;AAAA;AAIA;AACA;AAMA;;AAEA;AAIA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AAKA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AAKA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AAEA;;;AAGA;AAGA;AACA;AACA;;;;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;;;;A5VxOA;;;;;;;;;;;;;;;;AAkCA;;;AAGA;AAEA;;AAKA;AACA;AAEA;AAMA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;AN1EA;;;;;;;;;;;;;;;;AAiBA;;;AAIA;;;;AAIA;;;;AAIA;;;;AAKA;;;AmWlCA;;;;;;;;;;;;;;;;AAmBA;;;AAGA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;ACvCA;;;;;;;;;;;;;;;;AAiBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAkBA;AACA;AACA;AACA;;;;AAIA;;;;AAKA;;;;;AAMA;;;;;AAMA;;;;;AAMA;;;;AAMA;AACA;AACA;;;;AAKA;AACA;AACA;;;;;;;;AASA;;;;;;;;;;AAWA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAMA;AAEA;AACA;;;;;;;;;AAUA;;;AAGA;AACA;AACA;AACA;AACA;;;;;;;;;AAUA;;;AAGA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AAiBA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;AAEA;;;;;;;;;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;ACxWA;;;;;;;;;;;;;;;;AAiBA;;;AAGA;AACA;AACA;AAEA;;;;;;;;;;;;AAYA;AACA;AACA;AACA;AAEA;AACA;;;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AC3EA;;;;;;;;;;;;;;;;;AAqBA;AAAA;AAFA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;AAOA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;;AAGA;;;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AC1DA;;;;;;;;;;;;;;;;AAmBA;;;;AAIA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AACA;;;AAIA;AACA;AAEA;AAEA;;;;;AAKA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;;;;AAIA;AACA;AACA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AnW5LA;;;;;;;;;;;;;;;;AA6DA;AAwBA;AACA;;AACA;AAGA;AAAA;AAAA;AAFA;;;AAOA;;;AAIA;AACA;AACA;;AACA;AACA;AAAA;;AAMA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAAA;;AAEA;AACA;AACA;AAEA;;AAEA;AAEA;;;;AAKA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AoW3JA;;;;;;;;;;;;;;;;AAiBA;;;;;;AAMA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;ACnCA;;;;;;;;;;;;;;;;AA+BA;;;;;;;AAOA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;;;;;;;;AAQA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAEA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAOA;AACA;AAGA;AACA;AAEA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AClJA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AAEA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtDA;;;;;;;;;;;;;;;;AAiBA;;;;;AAKA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;;AATA;AAAA;AAAA;AAUA;AACA;AACA;AAEA;;;;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxDA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;;;;AAgBA;;;;;;;;;AA+CA;;;;;;AAjCA;;;;;AAMA;;;;;;AAOA;;;;;AAMA;;;;AAKA;;;;AAKA;AAKA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;AAQA;AACA;AACA;AACA;AAEA;;AAGA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;AAGA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AAAA;AACA;AACA;;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;ACtOA;;;;;;;;AAQA;AAIA;AACA;AACA;AAEA;;;;AAIA;;;;;;AAeA;AAAA;AAdA;AACA;AAEA;;AAEA;AACA;AASA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAQA;AAAA;AAKA;AAEA;AAEA;AACA;AAEA;AACA;;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;AAKA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;;;AAIA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;;AAIA;AACA;AACA;AACA;;;;AAKA;AAAA;;;AAGA;AACA;AACA;AACA;AACA;AAAA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAIA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AACA;AC5SA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;AASA;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;AAQA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AAEA;;;;;;AAMA;AAMA;AACA;AACA;AACA;;AAEA;AAEA;AAEA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;ACnJA;;;;;;;;;;;;;;;;AAmBA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpEA;AAm4BA;AAsYA;AA2BA;AAmCA;AAmBA;AAiDA;AAuDA;AAiBA;AAEA;AAIA;AAGA;AAMA;AAgCA;AA+BA;AA6CA;AAwSA;ACh3DA;AA2BA;AAyEA;AAoCA;AAOA;AAPA;AAyFA;AAEA;AACA;AC5KA;AAeA;AAOA;AAAA;AA0EA;AAkTA;AACA;AAoBA;AAGA;AACA;AAAA;AAGA;AAAA;AA1BA;AAuSA;AA0BA;AAQA;AACA;AAHA;AAOA;AC9tBA;AAeA;AAkLA;AAwFA;AC9TA;AA5BA;AACA;AACA;AACA;AACA;AACA;AAAA;AAHA;AAMA;AAAA;;ACTA;AAEA;AAwcA;AAGA;AA4DA;AAwBA;AAIA;AACA;AACA;AASA;AACA;AAhBA;AC5fA;AAUA;AAiDA;ACAA;AA+WA;AAYA;AA3EA;AAKA;AAiCA;AAGA;AAGA;AAIA;AAKA;AA9CA;AAIA;AAMA;AACA;AACA;AAAA;AARA;AAYA;AAAA;AA8EA;AAAA;AAiBA;AJrOA;AAGA;AAKA;AACA;AAGA;AAIA;AACA;AAEA;AACA;AAYA;AAMA;AACA;AA3BA;AAbA;AI0OA;AAoDA;AACA;AAGA;AACA;AAHA;;AAFA;AAAA;ACpjBA;AAoEA;AAUA;AAEA;AAAA;ACpEA;AA0DA;ACpCA;AACA;AAoBA;AA0CA;AAMA;AAoCA;AAmBA;AAKA;AAMA;AAEA;AAkEA;AAUA;AAGA;AAEA;AAMA;AJnNA;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAEA;AI6MA;AAAA;AADA;AALA;;AC7OA;ADuPA;AAMA;AAEA;AA2BA;AAGA;AAEA;AACA;AACA;AACA;AAtIA;AAwIA;AACA;AAEA;AACA;AAtRA;AAAA;AA6IA;AAgDA;AA8JA;AAgCA;AA5BA;AAGA;AAcA;AACA;AAEA;AAAA;AE7XA;AC5BA;AAqFA;ACrFA;AAyDA;AAmEA;AAMA;AZ8fA;AY7fA;AAPA;AAkIA;AAGA;AACA;AAGA;AAGA;ACzNA;AAkFA;AAEA;AAIA;AACA;AAFA;AAOA;AAmCA;AAEA;AACA;AAGA;AAEA;AAIA;AAQA;AACA;AAKA;AAKA;AACA;AAGA;AACA;AAEA;AACA;AAGA;AAEA;AAMA;AAMA;AACA;AAMA;;AAEA;AAhEA;AAAA;AA4EA;AAcA;AA+BA;AAGA;AACA;AAFA;AAOA;AAqDA;AAEA;AACA;;AAQA;AAmCA;AAYA;AACA;ACrNA;ADqNA;AAIA;AAEA;AASA;AApBA;AARA;AAuOA;AAuEA;AAyEA;AAEA;AAMA;Af7EA;AACA;AACA;AAGA;AACA;AAAA;AAGA;AAAA;AesEA;AAAA;AA6CA;AAMA;AAgFA;AAaA;AAYA;AAIA;ACz5BA;AA2BA;AJjBA;AIuEA;AAAA;AAwBA;AAOA;AAOA;AACA;AAyKA;AACA;AAKA;AALA;AACA;AACA;AACA;AAKA;AAIA;AAEA;AACA;AAMA;AASA;AAEA;AAvLA;AAiDA;AFnEA;AAGA;AAEA;AAEA;AACA;AEwDA;AA1CA;AAKA;AAUA;AAmCA;AAQA;AAMA;AAEA;AACA;AAGA;AAGA;AAVA;AAcA;ACzGA;ACnJA;AAYA;ACbA;AAEA;AAEA;AAEA;AAGA;AAEA;AAMA;AAAA;AAvBA;AAAA;AD4BA;AAkBA;AAsCA;AAcA;AAQA;AEhGA;ACHA;AAAA;AAkBA;AAkDA;AAuBA;AAIA;AACA;AACA;AAAA;AACA;AFlEA;AAAA;AACA;AACA;AEsEA;ACrGA;AAoCA;AAgCA;AAAA;AA4BA;AAgCA;AAEA;AACA;AAHA;AAuCA;AA0BA;AAUA;AA4BA;AAEA;AAGA;AAEA;;AAEA;AClHA;AAjIA;AAAA;AAQA;AAAA;AAOA;AAOA;AAOA;AAOA;AAgBA;;AAUA;AAAA;AA6CA;AA3GA;AAAA;ACwCA;AAaA;AAWA;AAkEA;AAUA;AAIA;AAIA;AAIA;AArBA;AA0RA;AAgBA;AAUA;ACrbA;AA+CA;AA+KA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AATA;AALA;AAAA;;AACA;;AAJA;AAzJA;AAeA;AAcA;AA+BA;AA8BA;AAEA;AAIA;AAIA;AACA;AACA;AACA;AACA;AAmBA;AAGA;AACA;AAOA;AACA;AAEA;AACA;AAfA;AApBA;AAMA;AAAA;AACA;AAAA;AAEA;AAtBA;AChJA;AAOA;AAqCA;AASA;AASA;AAmHA;AAUA;AAgBA;AAyBA;AAmBA;AAgFA;AAEA;AChWA;ACAA;ACIA;AAQA;AAaA;ACSA;AAsSA;AA4BA;AAIA;AAgFA;AAIA;ACrbA;AAiIA;AAGA;AAdA;ACzFA;AAyNA;AAuIA;AAAA;AA8CA;AAqCA;AAgDA;AAoBA;AAGA;AACA;AA4BA;AACA;AAOA;AAnCA;AAyDA;AAEA;AACA;AACA;AAQA;AAEA;AAvEA;AAgGA;AA2EA;AACA;AACA;ACqkBA;ADlkBA;AAAA;AAJA;AAQA;AAAA;AAlFA;AAAA;AACA;AAnGA;AAyGA;AAzGA;AA2GA;AACA;AAKA;AACA;AACA;AAnBA;AAhGA;AAAA;AAmIA;AAIA;AA5DA;;AACA;AAjDA;AA7BA;AAQA;AAAA;AAUA;AArBA;AAqNA;AAKA;AACA;ADvpBA;AC8pBA;AAPA;AAAA;AAUA;AACA;AACA;AACA;AAEA;AALA;AAAA;;AAQA;ADzqBA;AC4sBA;AAIA;AAEA;AANA;AA8CA;AAIA;AAMA;AAKA;AA4DA;AA6BA;AAYA;AAGA;AAYA;AAeA;AAmDA;AAeA;AA8GA;AACA;AACA;AEvtBA;AAisCA;AAIA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAoDA;AA+BA;AAKA;AAGA;AAEA;AAIA;;AAGA;AAEA;AACA;AAfA;AApCA;;AAMA;AAhCA;AAEA;AA3BA;AA6BA;AAAA;AA7BA;AAFA;AAAA;;AAKA;AAdA;AAsBA;AAqVA;AAIA;AAHA;AAIA;AAxVA;AA0VA;AAEA;AACA;AAKA;AACA;AAMA;AACA;AAEA;AACA;AACA;AAGA;AAAA;AApEA;AACA;AACA;AAEA;AACA;AC/2DA;ADk3DA;AAAA;AACA;ADnsBA;ACqsBA;AAVA;AA9SA;AAAA;AAoXA;AAIA;AAMA;AAAA;AAmDA;AAGA;AAEA;AACA;AFtqCA;AAIA;AEmqCA;AAJA;;AAMA;AA1DA;AAxCA;;AA2CA;;AAIA;AFv4BA;AACA;AAAA;AALA;AI7nCA;AAEA;AAGA;AAKA;AACA;AAJA;A/B8IA;AAGA;A+BjCA;AAEA;AACA;AACA;AACA;AAlGA;AACA;AAkGA;AApGA;AAQA;AACA;AACA;AAEA;AAJA;;A/BsIA;AACA;A+B1CA;AACA;AACA;AACA;AAVA;ACtIA;AAsCA;AACA;AAEA;AACA;AALA;AAOA;AAyOA;AAEA;AA1OA;;AA8OA;AA9OA;AAiBA;AAAA;AAMA;AAUA;AAyHA;AAKA;AACA;AACA;AAGA;AAEA;AAAA;AAGA;AAMA;AAEA;AAEA;AAOA;AAhCA;AA8CA;AAcA;AAqCA;AAGA;AAEA;AALA;AAiHA;ACtQA;AA0ZA;AAIA;AACA;AACA;AAGA;AACA;AACA;AAFA;;AAIA;AAEA;AAdA;AADA;AC5gBA;AA0DA;AAEA;AA0PA;AAxPA;AACA;AA6VA;AAgFA;AAu3BA;AACA;AACA;AApyCA;AA+gBA;AAvhBA;;AAUA;AAgCA;AAaA;AAoBA;AAqHA;AAqBA;AAsEA;AA6BA;AAIA;AACA;AACA;AAEA;AALA;;AAOA;AA6DA;AA2EA;AA4GA;AA8FA;AAqBA;AA+FA;AA0BA;AAqBA;AAuBA;AAqEA;AAqCA;AAqFA;AAAA;AAoBA;AAwCA;AA6BA;AAeA;AAQA;AACA;AAcA;AAIA;AAGA;AAEA;AACA;AACA;AAGA;AAWA;AA6BA;AAEA;AAaA;AAeA;AAEA;AAIA;AAUA;AAEA;AACA;AACA;AAGA;AAGA;AAXA;AAeA;AA6DA;AAeA;ACn5CA;ALrBA;AAsDA;AAqDA;AAwBA;AAiBA;AAkBA;AAeA;AAkBA;;AAEA;AAEA;AACA;AAKA;;AACA;AAAA;AACA;;;;;;;;;;AAEA;AAdA;AAAA;AAgCA;;AACA;AACA;AAGA;AACA;;AACA;AAAA;AACA;;;;;;;;;;AAHA;AAQA;AAAA;AAbA;AM9NA;AAkBA;AAMA;AC9BA;AAwBA;AAGA;AAOA;AAAA;AAMA;AAhBA;AC2CA;AAIA;AACA;AAGA;AAGA;AAGA;AAIA;AAEA;AAGA;AApBA;;AAuBA;AAcA;AAIA;AAEA;AAAA;ACxEA;AXNA;AAqJA;AAUA;AAoRA;AAAA;AAEA;AACA;AAKA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAIA;AAeA;AAEA;AAGA;AAAA;AAGA;AAHA;AAUA;AAAA;AAEA;AAGA;AAQA;AAGA;A/BEA;AAAA;A+BWA;AAIA;AAMA;AAQA;AACA;AAqBA;AAAA;AAEA;AA3HA;AAAA;AA+IA;AAaA;AAuBA;AAqBA;AAmBA;AAcA;AAoBA;AA2BA;AAuBA;AAWA;AACA;AAyBA;AAEA;AAIA;AAMA;AAEA;AA6IA;AYj4BA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AZu3BA;AAAA;AAAA;AACA;AAAA;AKlrBA;AACA;AACA;AACA;AL+qBA;AAAA;AAAA;AAAA;AA7IA;AAAA;AACA;AACA;AACA;AACA;AAqMA;AACA;AAGA;AAAA;AAEA;AA1MA;AAAA;AAEA;AAVA;AAAA;AAYA;AACA;AAlBA;AAnCA;AAAA;AA6GA;AAGA;AAIA;AAKA;AACA;AAEA;AAIA;AAKA;AACA;AAAA;AAzBA;AAyCA;AAsDA;AAaA;AAOA;AAGA;AAAA;AACA;AAXA;AAoDA;AAEA;AACA;AAAA;AAOA;AAVA;AAsEA;AAKA;AACA;AAIA;AAVA;AAmLA;AASA;Aa7wCA;AAkCA;AzCmPA;AACA;AAAA;AAEA;AAAA;AyCpPA;AZ5BA;AAuBA;AAYA;AAOA;AAMA;AA2EA;AAoBA;AAMA;AAiCA;AAOA;AAmBA;AAqBA;AASA;AAQA;AAQA;AAQA;AAOA;AAWA;AAuBA;AACA;AAMA;AAMA;AAOA;AAOA;AAOA;AAIA;AAIA;AAWA;AAUA;AAYA;AAOA;AAOA;AAhXA;AA4XA;AAAA;AA0BA;AA0LA;AAMA;AAEA;AACA;AACA;AAGA;AFqhBA;AA9SA;AACA;AAEA;AAEA;AAMA;AAMA;AAMA;AACA;AExPA;AA+BA;AAaA;AAmOA;AA4JA;AA2BA;AAMA;AAQA;AAOA;AAmBA;AAGA;AAgBA;AACA;AAfA;AAyDA;AACA;AAKA;AASA;AAMA;AA9EA;AAiIA;AAEA;AMluCA;ANmuCA;AMxwCA;AAyCA;AAAA;AAJA;AAAA;ANquCA;AAAA;AACA;AAEA;AA1uBA;AA6uBA;AAAA;AAGA;AAAA;AAEA;AAAA;AAdA;AAkBA;AAAA;AAvEA;;AAxrBA;AAsrBA;AAKA;AACA;AAGA;AAIA;AAMA;AAEA;AAKA;AAEA;AAKA;AAzFA;AALA;AADA;;AAOA;AAzBA;AAmKA;AAmDA;AAqBA;AQvzCA;AAGA;AAUA;AAEA;AAEA;AACA;AAEA;;AAIA;AACA;AACA;AAAA;ARoyCA;AQhzCA;AAkBA;AAAA;AACA;AAAA;AAlCA;ARi0CA;AAsBA;AA2BA;AAQA;AAkBA;AAoBA;AACA;AAEA;AAvBA;AAgCA;AAwCA;AAaA;AA6PA;AAeA;AA2BA;AAKA;AACA;AACA;AACA;AAJA;AAKA;AACA;;AAQA;AAMA;AACA;AACA;AAEA;AACA;ARnlDA;AACA;AQmlDA;AALA;;AAQA;AAMA;AAkCA;AACA;AACA;;AF5mDA;AE+mDA;;AFpnDA;AEunDA;;AAGA;AApFA;AA+FA;AAkMA;AAKA;AACA;AAGA;AShmEA;AAUA;AT+kEA;;AASA;AAWA;AA8CA;AAMA;AAUA;AATA;AAPA;AA2DA;AAKA;AAKA;AACA;AAUA;AAGA;AAyBA;AAEA;AAuCA;AA8BA;AAAA;AASA;AAoBA;AAcA;AAyCA;Aap6EA;AAEA;AAcA;AAmBA;AACA;AAKA;AAMA;AAYA;AAGA;AAGA;AbwqBA;Aa1pBA;AAEA;AAYA;AbiqBA;AarpBA;AAEA;AAUA;AAMA;AAIA;AAiBA;AA7GA;AA+GA;AAOA;AAAA;AAWA;AAWA;AAYA;AAqBA;AAMA;AACA;AACA;AAHA;;AAIA;AAaA;AAmBA;A1C1IA;AACA;AACA;AAAA;AAFA;AAAA;A0CiJA;AAAA;AAFA;;AAQA;AAGA;AAcA;AAaA;AAcA;AASA;AAMA;AAWA;AAWA;AAaA;AACA;;;;;;;;;;;;;;;AC/WA;AAEA;AAEA;AAEA;AAKA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AAOA;;;;;;;;;;;;;;;;;;;;;;ACjFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACrjBA;AACA;AACA;AACA;AACA;AACA,aAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACZA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACPA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC9EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC5DA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACLA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACTA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA,UAEA;AACA;;;;;;;;;;;;;ACnDA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACNA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACTA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACv1BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/FA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/GA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtFA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1DA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9aA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpNA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtPA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/GA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChFA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1GA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1FA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5FA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACpMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3SA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtHA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjDA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpFA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACVA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpJA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC99CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACriBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjSA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7DA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC39BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA,UAIA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;A7pBvCA;;;;;;;;;;;;;;;;AAoBA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A8pBrBA;;;;;;;;;;;;;;;;AAoBA;AACA;;;;AlYrBA;;;;;;;;;;;;;;;;AAiBA;AAkCA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AApDA;AAAA;;;;;;;;;;;;;AmYAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACt5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtGA;AACA;AACA,WACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC3TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClWA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;;;;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;;;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxjBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AClJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChBA;AACA;ACCA;AACA;AACA;AACA;AACA;;;AAGA;AAPA;AACA;AASA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AADA;AALA;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;;AADA;;AAHA;;;AAWA;AACA;;;;;;;;;;AAWA;AACA;ACpDA;;;;;;;AAOA;AACA;AAEA;;;ACVA;;;;;;;AAOA;AACA;AACA;;;AAGA;AACA;AACA;;;ACdA;;;;;;;AAOA;AACA;AACA;;AAEA;;;ACRA;;;;;;;AAOA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;AAIA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;;;AAGA;;;AC9BA;;;;;;;AAOA;AACA;;;ACNA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;;AAEA;AACA;;AAEA;;;ACjBA;;;;;;;AAOA;AACA;AACA;;;AAGA;AACA;;AAEA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;;;;AAMA;AAGA;;;AAGA;;;ACpCA;AACA;AACA;AAAA;AACA;;AAGA;;;ACRA;;;;;;;AAOA;AACA;AACA;;;AAGA;;;ACRA;;;;;;;;AAQA;;AAEA;AACA;;;;AAIA;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AAIA;AACA;;;AAGA;;;;AAIA;AACA;AACA;AADA;AAGA;;;;ACjDA;;;;;;;;AAQA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;AChBA;;;;;;;;;AASA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACnBA;;;;;;;;;;AAUA;AACA;AACA;AACA;AAEA;;;ACbA;AACA;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBA;;;;;;;AAOA;AAEA;AACA;AACA;;;;ACJA;;;;;;;AAOA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AAUA;;AAXA;AACA;AAeA;AACA;AACA;AACA;AACA;AAJA;AACA;;AAOA;AACA;AAEA;AACA;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;ACzDA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAIA;AAIA;;;AAGA;;;ACtDA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;;AAAA;AACA;AAMA;;;ACjBA;;;;;;;;AAQA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;;ACrBA;;;;;;;;AAQA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;;ACTA;;;;;;;;;;;AAWA;AAKA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AADA;;AAMA;AACA;AACA;AACA;AACA;;AAHA;AAMA;AADA;AAGA;;;AAGA;AACA;;AAMA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AALA;;AAQA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7EA;AAAA;AAAA;AACA;AAAA;;;;;;;;;;;;AAYA;AAMA;AACA;AACA;AACA;;;AAGA;AACA;AAMA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AAPA;AASA;AACA;AACA;AAXA;AAaA;AACA;AACA;;AAfA;AACA;AAkBA;;;AAGA;AACA;;AAJA;AAMA;AANA;AACA;AAOA;AACA;AAAA;AACA;AAFA;AACA;AAIA;AACA;AAGA;AACA;AACA;;;ACnEA;;;;;;;;;;AAUA;AAAA;AACA;AAAA;AACA;;;ACjBA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AChBA;;;;;;;AAOA;AACA;AACA;AAAA;AAAA;;;ACNA;;;;;;;;;;AAUA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AAFA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AADA;AAIA;;;AAIA;;;AC5CA;;;;;;;;;AASA;;AAEA;AACA;;;;AAIA;;;ACdA;;;;;;;;;AASA;;AAEA;AACA;AAAA;AAAA;;;;AAIA;AAAA;AAAA;AACA;;;ACfA;;;;;;;;;;AAUA;AACA;AACA;AAGA;AACA;;AACA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;;AAZA;AACA;AAeA;;;AC9BA;;;;;;;AAOA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;;AASA;AACA;;;;AASA;AACA;;AASA;AACA;AACA;AACA;;AAEA;AACA;AAKA;AACA;;AAIA;AACA;;;AAGA;AACA;AACA;AAFA;AAIA;;;;ACxEA;;;;;;AAMA;AACA;AACA;AAAA;AAAA;AADA;;;ACPA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;ACfA;;;;;AAKA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;;AAEA;;;AC9BA;;;;;AAKA;AACA;AACA;;;ACJA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAMA;;;;;;;;;AASA;;AAOA;AACA;AACA;;AAEA;AAEA;AAKA;AACA;AACA;AACA;;;AC5CA;;;;;;AAMA;AACA;AACA;;;;ACRA;;;;;;AAMA;;AAEA;AACA;;AAEA;AACA;AADA;AACA;;AAIA;AACA;AACA;AACA;AACA;;;ACpBA;;;;;;;AAOA;AACA;AACA;AACA;;;;ACZA;;;;;;;AAOA;AACA;;;ACNA;;;;;;;;AAQA;AACA;AACA;;AAGA;AAIA;;AAEA;AAVA;;;ACXA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AADA;AAGA;;AALA;;;ACJA;;;;;;;;;AASA;;;;;AAKA;AACA;;;AAGA;AACA;;AAEA;AACA;;;AAGA;;;;;;;;;;;;;AAaA;;AAQA;AACA;;;;AAIA;AACA;AAQA;AACA;;;AAGA;AACA;AACA;;;ACvEA;;;;;;;;;;;;;;;;;;;AAmBA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAKA;AACA;AACA;AARA;;;AChCA;AACA;;;;;;;;AAQA;AACA;AAAA;AACA;AACA;;;AAEA;AAEA;AAFA;AAIA;AACA;;AAIA;AACA;AAIA;AACA;AACA;;AAEA;AACA;AADA;AACA;AAGA;AACA;AAIA;AACA;AACA;;;;AAIA;AACA;;;;;;;;;;AAUA;AAAA;AACA;;;AAGA;AACA;AADA;AAGA;;AANA;AASA;;AAEA;AACA;AACA;AADA;AAGA;;AAJA;AAOA;;AAEA;AACA;AACA;AACA;AACA;AAJA;;AAOA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AADA;AACA;;AAIA;AACA;AACA;AACA;AACA;;;AC5GA;;;;;;;;;;AAUA;AAKA;AAAA;AAAA;AAAA;AACA;AACA;AAIA;AAFA;AACA;AAOA;AACA;AACA;AACA;;AAIA;;;AC/BA;;;;;;;AAOA;;;;AAEA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AALA;;;AAUA;AACA;AAGA;;;;AAIA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;;;AAIA;AACA;;AAGA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAIA;;;ACvFA;;;;;;;AAOA;AACA;AACA;AADA;AAGA;;AAEA;;;ACbA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA;AACA;AC9BA;AACA;AACA;;;;;;;;;;;AAWA;AAAA;AACA;AAAA;AACA;AAGA;;;ACZA;AACA;AACA;AACA;AAHA;AACA;;;;;;;;AAYA;;AAEA;AACA;;;AAGA;;AAEA;;;AAGA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAMA;AACA;;AAEA;AACA;;AAOA;AACA;AAMA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;AAGA;AACA;AAQA;;AAjFA;AAoFA;;;AChJA;;;;;;;AAOA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;;;AAGA;;;ACpBA;;;;;;;;;;;;AAYA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;AAbA;;AAgBA;AACA;AACA;AADA;AAMA;;AAKA;AAdA;;;AAkBA;;;;;;;;;;;;;;;AAeA;AAMA;AACA;;;;AAIA;AACA;;;AAGA;AAAA;AAAA;AACA;;;AAGA;AACA;AAAA;AACA;AAEA;AACA;;;;;AAOA;AACA;AACA;;AAWA;;AAEA;AAGA;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AAHA;AAKA;;AAbA;;AAiBA;AAAA;AAjBA;AAPA;AACA;;AA4BA;AACA;AACA;AACA;;AAFA;AADA;AAOA;;;;;;;;;;;;AAYA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AADA;AAGA;;;AAGA;AACA;AACA;AAFA;AAIA;AACA;AAFA;AAIA;AACA;AAFA;AAIA;AACA;;;AAGA;AACA;;;AC5LA;;;;;;;AAOA;AACA;AACA;;;;AAKA;AACA;;;;;;AAMA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAEA;AAGA;;AAEA;AATA;AAAA;AAYA;AACA;AAEA;AAGA;;AAMA;;AAxBA;AACA;AA2BA;AACA;AAEA;AAHA;AACA;AAKA;AACA;AACA;;;ACvFA;;;;;;;AAOA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAHA;AACA;AAMA;;;AAGA;;;AC1BA;;;;;;;AAOA;AACA;AACA;;;AAGA;AACA;AAEA;AAFA;AACA;AAKA;;AAMA;AACA;;;AAGA;AACA;AAZA;;AAeA;AACA;;;AAGA;AACA;;;AAGA;;;ACzCA;;;;;;;AAOA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;;;ACdA;;;;;;;;;;;;;;;;;;;;;AAqBA;;;;;;;;;AASA;;AAEA;;AAEA;;AAEA;AAfA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA;;AAEA;;AAEA;;AAEA;;;;AAIA;AAlEA;AACA;;;;;;;;;;;;;;;;;;AAqFA;;AAEA;;AAEA;;AAEA;;;;;;AAMA;;;;;;;AAOA;;;;;;AAMA;AA/GA;AACA;;;;;;;;;;AA0HA;;AAEA;;AAEA;;AAEA;AAjIA;AACA;;;;;;;;;;;AA6IA;;AAEA;;AAEA;;AAEA;;AAEA;AAtJA;AACA;;;;;;;;;;;;AAmKA;;AAEA;;AAEA;;AAEA;;;;;;;AAOA;;;;;AAKA;;;;;;;AAOA;;;;;;;;AAQA;;;;;;;;AAQA;AA7MA;AACA;;;;;;;;AAsNA;;AAEA;;AAEA;;AAEA;AA7NA;AACA;;;;;;;;;;;AAyOA;;AAEA;;AAEA;;AAEA;AAhPA;AACA;;;;;;;;;;;;;;;;AAiQA;;AAEA;;AAEA;;AAEA;;;;;;AAMA;;;;;;AAMA;;;;;;AAMA;AA1RA;AACA;;;;;;;;;;;;;;;;AA2SA;;AAEA;;AAEA;;AAEA;;AAEA;;;;;;;AAOA;;AA3TA;AACA;;;;;;;;;;;;;;;;;;;;AC/BA;;;;;;;;;;;;;;;;AAgBA;;;;;AAKA;AACA;;;;;AAKA;AACA;;;;;AAKA;AACA;;;;;;AAMA;AACA;;;;;;;AAOA;AACA;;;;;;;;;AASA;AACA;;;;;;;AA3CA;AACA;;;;;;;;;;;ACnBA;AACA;AAIA;;;;;;;;;AAgBA;;;AAAA;;;AAyFA;AAAA;AAzFA;AACA;;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAHA;AACA;;AAMA;AACA;AACA;;AAEA;AACA;AAIA;AAJA;AACA;;AAYA;;;AAGA;AAHA;;AAMA;AAAA;AANA;AACA;;;;;AAWA;AACA;AACA;;AAFA;AACA;;AAYA;AACA;AACA;AACA;;AAEA;;;AAGA;;;;;;;;;AAKA;AACA;;;;AAEA;AACA;;;;AAEA;AACA;;;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA1FA;AAAA;AAAA;AACA;;;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACvLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACrGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9kBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAIA;;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACn7wBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAKA;AACA;AACA;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrIA;AACA;AA2BA;AAAA;AAyDA;AAAA;AA6BA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAvGA;AACA;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAkFA;AACA;AAOA;AAEA;AACA;AAAA;AACA;AAAA;AAEA;AAOA;AAGA;AA3LA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAsIA;AAAA;AA7LA;;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACpLA;AACA;AACA,aAEA;AACA;AACA;;;;;;;;;;;;;ACNA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1MA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClDA;;;;AAGA;;;;;;;;;;;;;AACA;;;;;;AAEA;AACA;AAAA;AAAA;AAAA;;;;AAJA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AACA;AAOA;AACA;AADA;;;ACpBA;;;;AAGA;;;;;;;;;;;;;AACA;;;;;;AAEA;AACA;AAAA;AAAA;AAAA;;;;AAJA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AADA;;;ACvBA;AACA;AADA;AAGA;AACA;AADA;AACA;ACIA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;AAGA;AACA;;;AAGA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AADA;AAGA;AACA;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAjBA;AACA;AACA;AAqBA;AACA;AADA;AAGA;;;;;AAIA;AA1CA;AACA;AA6CA;AACA;;;;;;;AAMA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAEA;AAEA;AAKA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;;AAPA;AACA;AACA;AAUA;AACA;AADA;AAGA;;;AAGA;AA9BA;AAZA;AACA;AAgDA;AACA;AAKA;AAGA;AAAA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AALA;;;AC7HA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;AAGA;AAAA;AAAA;;;AACA;AAAA;AAAA;;;;;;;AAMA;AAGA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAEA;AACA;AAIA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAJA;AAOA;AAIA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AADA;AAGA;;;AAGA;AA9CA;AApBA;AACA;AAwEA;AACA;AAEA;AASA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxHA;AACA;AAEA;AACA;AACA;AAEA;AAJA;AACA;ACFA;;AAAA;AACA;ACHA;AACA;AAEA;AACA;AACA;AAEA;AAJA;AACA;AAMA;;AAAA;AACA;ACJA;;;;AAGA;;;;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;;;AACA;AAEA;AACA;AADA;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AADA;AAGA;;AAJA;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;;AAIA;AACA;;;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AAVA;;;;AA7CA;AACA;AA6DA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AADA;;;ACxEA;;;;AAGA;;;;;;;;;;;;;AACA;;;;;;AAEA;AACA;AAAA;AAAA;AAAA;;;;AAJA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AACA;AAOA;AACA;AADA;;;ACzBA;;;;;;;;;;;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;;AAdA;AACA;ACIA;;;;AAGA;AAAA;AAAA;AAAA;AAEA;AAEA;AAEA;AAEA;AAGA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;;AAPA;AAUA;AACA;AAXA;AAaA;AAdA;AARA;;;AA8BA;AACA;AAEA;AACA;AACA;AAFA;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;;;;;;AAMA;AAAA;AAAA;;;AAAA;AAAA;;;AACA;AAAA;AAAA;;;ACdA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAEA;AAAA;AAEA;AACA;AAMA;AALA;;;AAYA;AACA;AACA;;;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AAEA;AAHA;AAMA;;AAZA;AAeA;AAhBA;AAzBA;;;AAiDA;AACA;AACA;AACA;AACA;AAHA;;;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;AAGA;;;;;;;AAMA;AAAA;AAAA;;;AACA;AACA;AAAA;AAAA;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAAA;AAAA;AACA;AAIA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AACA;;AACA;;AACA;;AACA;AACA;AACA;AAFA;AAJA;AAlBA;;;AC3BA;AACA;;;AAGA;AACA;AAEA;AAOA;;;;;;;AAMA;;;;;;;;;;;AACA;;;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;;;AAIA;AACA;;;AAIA;AAAA;AACA;AAvBA;;;;AAHA;AACA;AAkDA;AACA;AACA;AACA;AACA;AACA;;AAJA;AASA;AACA;AACA;AAIA;AACA;AACA;AAjBA;AACA;AAmBA;AACA;AASA;AASA;AAnBA;AACA;AAwBA;AACA;AAKA;AANA;;;ACtHA;AACA;;;AAGA;AACA;AAGA;AACA;;;;AAIA;AACA;AAEA;AAEA;AAGA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AADA;;;AAKA;;;;;;;;;AAQA;;;;;;;;;;;;;;AAQA;AAAA;;;AACA;AAAA;;;AACA;AAAA;;;AACA;AAAA;;;;;;;;AAVA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;;AAQA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AADA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AAaA;AAAA;AAAA;AAAA;;;;AA7BA;AACA;AAgCA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AADA;;;ACpFA;;;;AAGA;;;;;;;;;;;AACA;;;AAEA;AAEA;AAEA;AAEA;;;;;AAMA;AACA;AACA;AAEA;AAEA;AACA;AADA;;AANA;AAYA;AACA;AAAA;AAAA;AAzBA;;;;AAHA;AACA;AAmCA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AAKA;AANA;;;AC9CA;;;;AAGA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAEA;AAGA;AAIA;AAGA;AAJA;AANA;AAJA;AACA;AAqBA;AACA;AACA;AACA;AACA;AACA;AADA;;;AASA;;;ACxCA;AAEA;AACA;AAEA;;;AAKA;;AAGA;AACA;AAEA;;;AAKA;;AAGA;AACA;AAEA;;;AAKA;AACA;;AAGA;AACA;AAEA;;;AAKA;AACA;AAEA;;;ACtDA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;AAIA;;;AAOA;;;;;;;;;;;;;;;;ACnBA;AACA;AACA;;;;;;;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/DA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AAEA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AAAA;AAGA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAEA;AAAA;AACA;AAAA;AADA;AAGA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AADA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/FA;;;;;;;;AAQA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AACA;AADA;AAEA;AACA;AACA;AACA;AACA;AACA;AAPA;AAQA;AAEA;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;;;;;;;AAMA;AACA;AACA;AACA;AC5CA;;;AAAA;;;;AACA;AACA;AADA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAZA;AACA;AAiCA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAKA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;;AAwBA;AACA;;;AA7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AAAA;AAAA;AACA;AACA;AAGA;AACA;AACA;AAAA;AAGA;AAFA;AADA;AAJA;AAYA;AACA;;AAlFA;AACA;ACFA;;;AAAA;;;;;AACA;AACA;AAAA;AAGA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASA;AACA;;;AATA;AACA;AAGA;AAFA;AAKA;AACA;;AA7BA;AACA;ACMA;;;AAAA;;;;AAQA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AAAA;AAGA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAZA;AAcA;AACA;AACA;AAAA;AAGA;AAFA;AADA;AACA;;AAiCA;AACA;AACA;;;AAtGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAkEA;;;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAEA;AAIA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AAGA;AACA;AAHA;AADA;AAaA;AACA;;AA1HA;AACA;AAGA;AACA;AADA;AACA;ACbA;AAAA;AAAA;AACA;AADA;AACA;AAAA;AAAA;AAAA;AADA;AACA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACTA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AADA;AAaA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AApBA;AACA;AAuBA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;AC/BA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AADA;AAaA;AACA;AACA;AACA;AACA;AACA;AAlBA;AACA;;;;ACYA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAFA;AAKA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AAAA;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA;AACA;AADA;AADA;AAOA;AACA;AAAA;AAAA;AAFA;AAIA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAMA;AAAA;AAIA;AAAA;AAIA;AACA;AACA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAMA;AAAA;AACA;AAEA;AACA;AAFA;AADA;AAQA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AALA;AAUA;AAvBA;AApDA;AAqFA;AADA;AAjHA;AACA;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAJA;AAOA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;ACrCA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AAfA;AAmBA;AACA;AC5BA;AACA;AACA;AAFA;AAIA;AACA;AA2CA;;;AAAA;;;;AAkCA;AACA;AA+EA;AAEA;AACA;AAGA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AADA;AAGA;AACA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AADA;AAGA;AACA;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;AAMA;AAJA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA0DA;AACA;;;AAnXA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AA8SA;;;AAOA;AALA;AACA;AACA;AACA;AACA;AASA;AANA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AALA;AAOA;AAKA;AACA;AACA;AANA;AADA;AAaA;AAGA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AAeA;AACA;;;;AArWA;AACA;;;;AAGA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;;;;AAGA;AACA;;;;AAGA;AACA;AAGA;AAEA;AAFA;AAIA;;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAGA;AACA;AAEA;AACA;;;;AAhHA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3BA;AACA;;;;;;;;;;;;;;ACxEA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACTA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACv1BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/FA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AAAA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACJA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/GA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtFA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1DA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9aA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpNA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtPA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/GA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChFA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1GA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1FA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5FA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACpMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3SA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtHA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjDA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpFA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACVA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpJA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC99CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACriBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjSA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrFA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7DA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACv3DA;AACA;AACA,aAEA;AACA;AACA;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzBA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC5VA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACz1BA;AACA;AACA,aAEA;AACA;AACA;;;;;;;;;;;;;ACNA;AACA;AACA,aAEA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvEA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrIA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7BA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChLA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1YA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtKA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/LA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpeA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9DA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9IA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1KA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3FA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnEA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9LA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClLA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3QA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/DA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7JA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1PA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnDA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3KA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5DA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5DA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5DA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/FA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AChVA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC1LA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpJA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7VA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;ACDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnLA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7IA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACpCA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACRA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9CA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACRA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtTA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9IA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACz5CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/DA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrLA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzYA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1GA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5XA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1MA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9KA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrHA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClpBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1LA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1WA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3DA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClPA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxJA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvHA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChDA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1FA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9FA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3DA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC5QA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACZA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACzNA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;A","sourceRoot":""}